????xvid_20020412/0040755000100600001440000000000007455522552012334 5ustar michaelusersxvid_20020412/vfw/0040755000100600001440000000000007455522456013141 5ustar michaelusersxvid_20020412/vfw/CVS/0040755000100600001440000000000007455522456013574 5ustar michaelusersxvid_20020412/vfw/CVS/Root0100644000100600001440000000004607455522455014436 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/vfw/CVS/Repository0100644000100600001440000000000407455522455015664 0ustar michaelusersvfw xvid_20020412/vfw/CVS/Entries.Log0100644000100600001440000000003007455522456015636 0ustar michaelusersA D/bin//// A D/src//// xvid_20020412/vfw/CVS/Entries0100644000100600001440000000041007455522456015120 0ustar michaelusers/authors.txt/1.1.1.1/Fri Mar 8 02:46:02 2002// /gpl.txt/1.1.1.1/Fri Mar 8 02:46:03 2002// /help.txt/1.1.1.1/Fri Mar 8 02:46:03 2002// /todo.txt/1.2/Sat Mar 16 11:41:38 2002// /vfw.dsp/1.3/Fri Apr 5 14:42:35 2002// /vfw.dsw/1.1.1.1/Fri Mar 8 02:46:03 2002// D xvid_20020412/vfw/bin/0040755000100600001440000000000007455522456013711 5ustar michaelusersxvid_20020412/vfw/bin/CVS/0040755000100600001440000000000007455522456014344 5ustar michaelusersxvid_20020412/vfw/bin/CVS/Root0100644000100600001440000000004607455522456015207 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/vfw/bin/CVS/Repository0100644000100600001440000000001007455522456016432 0ustar michaelusersvfw/bin xvid_20020412/vfw/bin/CVS/Entries0100644000100600001440000000022707455522456015676 0ustar michaelusers/XviD_Options_Explained.pdf/1.2/Tue Mar 12 02:44:19 2002// /alt_curve.gif/1.1/Sat Mar 23 06:59:37 2002/-kb/ /xvid.inf/1.2/Tue Mar 12 01:57:04 2002// D xvid_20020412/vfw/bin/xvid.inf0100644000100600001440000000470407443260160015347 0ustar michaelusers; XviD MPEG-4 Video Codec install [Version] Signature = "$CHICAGO$" Class = MEDIA [SourceDisksNames] 1="XviD MPEG-4 Video Codec Install Disk",, 0001 [SourceDisksFiles] xvid.dll=1 xvid.inf=1 [Installable.Drivers] XVID = 1:xvid.dll, "vidc.XVID", "XviD MPEG-4 Video Codec" , , , [DefaultInstall] CopyFiles=MPEG4.Copy,MPEG4.Copy.Inf Updateinis = MPEG4.Updateini addreg = MPEG4.AddReg,MPEG4.AddReg9x,MPEG4.DoReg MediaType = SOFTWARE [DefaultInstall.ntx86] CopyFiles=MPEG4.Copy,MPEG4.Copy.Inf addreg = MPEG4.AddReg,MPEG4.AddRegNT,MPEG4.DoReg MediaType = SOFTWARE [Remove_XviD] AddReg = MPEG4.Unregister DelReg = MPEG4.DelReg DelFiles = MPEG4.Copy,MPEG4.Copy.Inf UpdateInis = MPEG4.DelIni [MPEG4.Copy] xvid.dll [MPEG4.Copy.Inf] xvid.inf [MPEG4.UpdateIni] system.ini, drivers32,,"vidc.XVID=xvid.dll" [MPEG4.DelIni] system.ini, drivers32,"vidc.XVID=xvid.dll", [MPEG4.AddReg] [MPEG4.AddReg9x] HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\vidc.XVID,Description,,%XviD% HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\vidc.XVID,Driver,,xvid.dll HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\vidc.XVID,FriendlyName,,"XVID" HKLM,%UnInstallPath%,DisplayName,,%UninstallDispName% HKLM,%UnInstallPath%,UninstallString,,"%10%\rundll.exe setupx.dll,InstallHinfSection Remove_XviD 132 %17%\%InfFile%" [MPEG4.AddRegNT] HKLM,SOFTWARE\Microsoft\Windows NT\CurrentVersion\drivers.desc,xvid.dll,,%XviD% HKLM,SOFTWARE\Microsoft\Windows NT\CurrentVersion\drivers32,vidc.XVID,,xvid.dll HKLM,%UnInstallPath%,DisplayName,,%UninstallDispName% HKLM,%UnInstallPath%,UninstallString,,"%11%\rundll32.exe setupapi,InstallHinfSection Remove_XviD 132 %17%\%InfFile%" [MPEG4.DoReg] ;HKLM,Software\Microsoft\Windows\CurrentVersion\RunOnce\Setup,"Registering XviD Direct Show ;Decoder...",,"%11%\regsvr32.exe /s %11%\xvid.ax" [MPEG4.DelReg] HKLM,SYSTEM\CurrentControlSet\Control\MediaResources\icm\vidc.XVID HKLM,SOFTWARE\Microsoft\Windows NT\CurrentVersion\drivers.desc,xvid.dll,,"" HKLM,%UnInstallPath% [MPEG4.Unregister] ;HKLM,Software\Microsoft\Windows\CurrentVersion\RunOnce\Setup,"Unregistering XviD Direct Show ;Decoder...",,"%11%\regsvr32.exe /s /u %11%\xvid.ax" [DestinationDirs] DefaultDestDir = 11 ; LDID_SYS MPEG4.Copy = 11 MPEG4.Copy.Inf = 17 [Strings] XviD="XviD MPEG-4 Video Codec" InfFile="xvid.inf" UninstallDispName="XVID MPEG-4 CODEC" UnInstallPath="Software\Microsoft\Windows\CurrentVersion\Uninstall\xvid" MediaClassName="Media Devices" mfgname="www.videocoding.de" xvid_20020412/vfw/bin/XviD_Options_Explained.pdf0100644000100600001440000001235007443265603020753 0ustar michaelusers%PDF-1.3 % 126 0 obj << /Linearized 1 /O 129 /H [ 1745 420 ] /L 571395 /E 123840 /N 8 /T 568756 >> endobj xref 126 46 0000000016 00000 n 0000001271 00000 n 0000001608 00000 n 0000002165 00000 n 0000002644 00000 n 0000002699 00000 n 0000002860 00000 n 0000003020 00000 n 0000003180 00000 n 0000003340 00000 n 0000003381 00000 n 0000003919 00000 n 0000004155 00000 n 0000004644 00000 n 0000004874 00000 n 0000004904 00000 n 0000004926 00000 n 0000005029 00000 n 0000005137 00000 n 0000005673 00000 n 0000005695 00000 n 0000006243 00000 n 0000006265 00000 n 0000006849 00000 n 0000006871 00000 n 0000007405 00000 n 0000007427 00000 n 0000008024 00000 n 0000008046 00000 n 0000008564 00000 n 0000008586 00000 n 0000009125 00000 n 0000009147 00000 n 0000043384 00000 n 0000043446 00000 n 0000069640 00000 n 0000069708 00000 n 0000069779 00000 n 0000072457 00000 n 0000072522 00000 n 0000072729 00000 n 0000072808 00000 n 0000073272 00000 n 0000076188 00000 n 0000001745 00000 n 0000002143 00000 n trailer << /Size 172 /Info 123 0 R /Root 127 0 R /Prev 568745 /ID[<2db14fc5e72bf8577194ac33572dcad4><71a2948838fb226b8a2cf44d4ddb0c95>] >> startxref 0 %%EOF 127 0 obj << /Type /Catalog /Pages 125 0 R /Metadata 124 0 R /OpenAction [ 129 0 R /XYZ null null null ] /PageMode /UseNone /PageLabels 122 0 R /StructTreeRoot 128 0 R /PieceInfo << /MarkedPDF << /LastModified (D:20020308105335)>> >> /LastModified (D:20020308105335) /MarkInfo << /Marked true /LetterspaceFlags 0 >> >> endobj 128 0 obj << /Type /StructTreeRoot /ClassMap 41 0 R /RoleMap 43 0 R /K 81 0 R /ParentTree 94 0 R /ParentTreeNextKey 13 >> endobj 170 0 obj << /S 218 /L 340 /C 356 /Filter /FlateDecode /Length 171 0 R >> stream Hb```a``0)AX, S#%aQm|^J h!i7^> /ExtGState << /GS2 166 0 R /GS3 165 0 R >> /Font << /TT2 138 0 R /TT3 136 0 R /T1_2 143 0 R /T1_3 142 0 R >> /XObject << /Im2 168 0 R /Im3 169 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> /Contents [ 144 0 R 146 0 R 148 0 R 150 0 R 152 0 R 154 0 R 156 0 R 167 0 R ] /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 /StructParents 0 /Annots 130 0 R >> endobj 130 0 obj [ 131 0 R 132 0 R 133 0 R 134 0 R ] endobj 131 0 obj << /Type /Annot /Subtype /Link /Rect [ 267.35992 412.61688 402.05725 428.38464 ] /Border [ 0 0 0 ] /H /I /A 161 0 R /StructParent 1 >> endobj 132 0 obj << /Type /Annot /Subtype /Link /Rect [ 344.34003 385.01654 497.58484 400.7843 ] /Border [ 0 0 0 ] /H /I /A 162 0 R /StructParent 2 >> endobj 133 0 obj << /Type /Annot /Subtype /Link /Rect [ 212.0999 371.21649 327.43091 386.98425 ] /Border [ 0 0 0 ] /H /I /A 164 0 R /StructParent 3 >> endobj 134 0 obj << /Type /Annot /Subtype /Link /Rect [ 350.70001 371.2164 452.08771 386.98416 ] /Border [ 0 0 0 ] /H /I /A 159 0 R /StructParent 4 >> endobj 135 0 obj [ /ICCBased 163 0 R ] endobj 136 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 126 /Widths [ 250 333 408 0 0 833 0 180 333 333 0 564 250 333 250 278 500 500 500 500 500 500 500 500 500 500 278 278 0 564 0 0 921 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722 556 0 667 556 611 722 722 944 722 722 0 0 0 0 0 500 0 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500 500 500 333 389 278 500 500 722 500 500 444 0 0 0 541 ] /Encoding /WinAnsiEncoding /BaseFont /MOIFBD+TimesNewRoman /FontDescriptor 139 0 R >> endobj 137 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 656 /Descent -216 /Flags 34 /FontBBox [ -558 -307 2034 1026 ] /FontName /MOIEPD+TimesNewRoman,Bold /ItalicAngle 0 /StemV 160 /XHeight 0 /FontFile2 160 0 R >> endobj 138 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 122 /Widths [ 250 0 555 0 0 0 0 278 333 333 0 0 0 333 250 278 0 500 500 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 667 722 722 667 611 0 0 389 0 778 667 944 0 778 611 778 722 556 667 722 722 1000 722 0 0 0 0 0 0 0 0 500 556 444 556 444 333 500 556 278 0 556 278 833 556 500 556 556 444 389 333 556 500 722 500 500 444 ] /Encoding /WinAnsiEncoding /BaseFont /MOIEPD+TimesNewRoman,Bold /FontDescriptor 137 0 R >> endobj 139 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 656 /Descent -216 /Flags 34 /FontBBox [ -568 -307 2028 1007 ] /FontName /MOIFBD+TimesNewRoman /ItalicAngle 0 /StemV 94 /XHeight 0 /FontFile2 158 0 R >> endobj 140 0 obj /DeviceGray endobj 141 0 obj 456 endobj 142 0 obj << /Type /Font /Subtype /Type1 /Encoding /WinAnsiEncoding /BaseFont /Courier >> endobj 143 0 obj << /Type /Font /Subtype /Type1 /Encoding /WinAnsiEncoding /BaseFont /Courier-Bold >> endobj 144 0 obj << /Filter /FlateDecode /Length 141 0 R >> stream HAo0C{ 6rv9"q MmUH6̓y(eq]J-A;u8`l{(w_հNM'ɋ ~E(hD)%Z TΚ(KH!tħ~q}dY6(ʠh$ AYh*mxvid_20020412/vfw/bin/alt_curve.gif0100644000100600001440000002351207447023731016355 0ustar michaelusersGIF89a,!!!)))111999BBBJJJRRRZZZccckkksss{{{,,H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ6A#P$kA >l p z<0hM><Ȍ7W 0dx@>$80oNk8hiqAZ5P@Daz/wZ]zx┫En'lC:)0yK@gbĂ M#FB! Ɇ6ՑnN#.SB#7H=D(Da!{@hrĉpLmo"(BiyZ`D"^5D㊨XHqnBE+%G,(icFAb̅.>&ux#8VH6%Il v0&GdEJRJ?|!b'Zb&ʉ첓$/MA B$(ҙ,t3Si8L)?MnR 8IrL:m3|} ?*Ђl8t}6fͨF/h` H;Q0ҕpiLa*Ӛ4N_әTN}JTPZH 0 .pQ`H t^ ֲլh=X+ֶcu\J׸un+^ZWD =4; `. DM+#H,[Yʲʳ1b0dP,c7p $`g,Gb^V#ed܆V(-DTpvZĶmo[.TD\`+Oo[Yķ-n *Z2 0@lyYoh9!=&P7읭yk>^p b`v .`b5qQhq0H+]@XZ@7$py/ FڅH6qxYaWD>r"PJ$W*n%xCNn<"fNrCL&cQֲY*Y4s8@Bm4 b@ RX΍6@0< W泄ٜk^ڭt([!.IU Y{b,`rn'į8Bmf/33phv~=k'dJ!J,UfH4!&"t<vu=]{qwY tcxE`0Uq<5 aODsHi@qШ"r5nd j7Ct%W}KDcb^7ch pHp9rjr kW\.ݢ^>p2hy;u2=Տ P,4_ ̃q ty `#s+!9j/Y yjn+k䝀9 V{0p[5-aB. 0KR|an| #v0 pgw!sW0;zyrbPt @O )xPT{guVǂXWm0AgmrMSM7BFm0 m B=w"P!UXTCTp1WhTXxTHR$x͕zYsl5U{U UzWwVP2e~ffA`*(0n'P1cc1}Ye aWbd oTB^AbVZ؂`z扳~A^ 88XGFdhhl e\\@(uqbUB׍'HIxb|H(qV‰dq"ƆjʦtYJ(Vgxg吓va!y^~PU1Vi kWfb=Hr5n79 .`qf)*H`:a^4]b17pF;wn.9, iNJ:  !?7QG.W35w?sspsB3cw?Ht} 1؍I oEa16ugw0] t MBv`vz0i$mz#w@wwwyw*P_vuȪ_ua$w?wy5(/|Gyizw|bznw\dnd 0׊XnW: |ʱo||%$'/w}7}+Oa`KGGIߺr!q *zmqu'Q 8 .5^֌6˝ʳj+*40W1,9pj=0ʟycwdLha1?g){J,fTQ PE'S8nڪ{k}L|Lтi. 0(C\g*훴Asچa\^Rѡt[ Љ(%V؇{e6"{M'^cn'\ ĺ\ P UƏ Ofڏb۽Oͤn5+FOsc>3>gBxmn~⍽bX{a=T&g\1a+\$&V>wp]MV=`|@Q cmQr/s6Ȫ¬?W1"| Z5U:3r^AdM]y.:C(*vpm{x%5^n ]TnjyCF y#z5(Fwz? o /:(T@Jp0?"/J'|hw]?GyM|P .RK}/o-{sZu _?F?V iPP1eS? EQZ e>w䳷krۀȸwic?0?pU9[Z7Wڇ~ x~Ut2ۘnő}˩!˧VsysD\/y PZ: $ sځe8>%4@YfT4xG㳀e1X 6SW|jlJӂȠ ʼn%0>-1 i(`-hLWc@z p>X\Vu_Mx$V%1M=E@O>`?=>T |K n{m@'\O [jDY=I%3CYb ~-.-mv]T_;"NK hw7/Ɓ1Z` 5<>('(@Hݠd;iV6Z}"Y $'jF:П! gp]eOr&Q5)Q@_b5mo%~OuxaDY.:͍ xE p  ?{k_` QIdD(S"(*fъZw-RdNJd`7g5<$ly2 \yܣG>{ HDR9C.2h$7H>Ґ'1x`p0FQ̊*Yٖ-mYK\R,wK^ f1ip`X^)LaΌM90R]H !`$y^L&$f;rō"KgrjbYaOwԛ)07V|ɠ5y!hA5iO!,м!]+TG҅T#@N26s(5#*BͣOug3 tB@eTt2@,)$V՝MXiԂL0%U}SUk_du"A] " x1XVUlEa+U6]I57PJLO*d'VsF6œPZ 䔱4!kZ골jqAb3 Eq`$ROH.xKɒQRjjH2 hR`͖F2Z8sirX$8i^Gvc@rzj gwnqh\0L!dޤوVQvNotǻwiׅ0r}HЧ8x X`MMSSpG=j yyyԐ{-Lh; Ѐ 0L;a5Ҿ{x ؀Z=)a ^+c}?)O  U4]%ӡO a dQy5b@5۱{ցM~T U-t/B-W`@"%Su]qW %lgi ?A9فQU@񀔥kSӑtΠMn1 T Ȁ` T wm ¡ ػ H31! ۷˜[)Ccl=[&B= =8YK X (. I p$?\C@\ NH\C]S]>>ã#ם]?ڀ֕]@]#Pt}# 3P0&a:^ X]^D_ҥ`}@ M^\;xvid_20020412/vfw/src/0040755000100600001440000000000007455522456013730 5ustar michaelusersxvid_20020412/vfw/src/CVS/0040755000100600001440000000000007455522456014363 5ustar michaelusersxvid_20020412/vfw/src/CVS/Root0100644000100600001440000000004607455522456015226 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/vfw/src/CVS/Repository0100644000100600001440000000001007455522456016451 0ustar michaelusersvfw/src xvid_20020412/vfw/src/CVS/Entries0100644000100600001440000000100307455522456015706 0ustar michaelusers/2pass.c/1.3/Mon Apr 8 12:51:41 2002// /2pass.h/1.2/Sat Apr 6 06:21:29 2002// /XviD_logo.bmp/1.1.1.1/Fri Mar 8 02:46:11 2002// /codec.c/1.10/Mon Apr 8 12:51:41 2002// /codec.h/1.8/Mon Apr 8 12:51:41 2002// /config.c/1.7/Mon Apr 8 12:51:41 2002// /config.h/1.5/Mon Apr 8 12:51:41 2002// /config.rc/1.7/Mon Apr 8 12:51:41 2002// /driverproc.c/1.3/Sat Mar 23 06:58:56 2002// /driverproc.def/1.1.1.1/Fri Mar 8 02:46:10 2002// /resource.h/1.5/Mon Apr 8 12:51:41 2002// /xvid.h/1.2/Fri Apr 5 14:42:37 2002// D xvid_20020412/vfw/src/codec.c0100644000100600001440000004530507454311135015142 0ustar michaelusers/************************************************************************** * * XVID VFW FRONTEND * codec * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 04.04.2002 separated 2-pass code to 2pass.c * interlacing support * hinted ME support * 23.03.2002 daniel smith * changed inter4v to only be in modes 5 or 6 * fixed null mode crash ? * merged foxer's alternative 2-pass code * added DEBUGERR output on errors instead of returning * 16.03.2002 daniel smith * changed BITMAPV4HEADER to BITMAPINFOHEADER * - prevents memcpy crash in compress_get_format() * credits are processed in external 2pass mode * motion search precision = 0 now effective in 2-pass * modulated quantization * added DX50 fourcc * 01.12.2001 inital version; (c)2001 peter ross * *************************************************************************/ #include #include #include "codec.h" #include "2pass.h" int pmvfast_presets[7] = { 0, PMV_QUICKSTOP16, PMV_EARLYSTOP16, PMV_EARLYSTOP16 | PMV_EARLYSTOP8, PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8, PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8, PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 | PMV_EARLYSTOP8 | PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8 }; /* return xvid compatbile colorspace, or XVID_CSP_NULL if failure */ int get_colorspace(BITMAPINFOHEADER * hdr) { if (hdr->biHeight < 0) { DEBUGERR("colorspace: inverted input format not supported"); return XVID_CSP_NULL; } switch(hdr->biCompression) { case BI_RGB : if (hdr->biBitCount == 16) { DEBUG("RGB16 (RGB555)"); return XVID_CSP_VFLIP | XVID_CSP_RGB555; } if (hdr->biBitCount == 24) { DEBUG("RGB24"); return XVID_CSP_VFLIP | XVID_CSP_RGB24; } if (hdr->biBitCount == 32) { DEBUG("RGB32"); return XVID_CSP_VFLIP | XVID_CSP_RGB32; } DEBUG1("BI_RGB unsupported", hdr->biBitCount); return XVID_CSP_NULL; // how do these work in BITMAPINFOHEADER ??? /* case BI_BITFIELDS : if (hdr->biBitCount == 16 if(hdr->biBitCount == 16 && hdr->bV4RedMask == 0x7c00 && hdr->bV4GreenMask == 0x3e0 && hdr->bV4BlueMask == 0x1f) { DEBUG("RGB555"); return XVID_CSP_VFLIP | XVID_CSP_RGB555; } if(hdr->bV4BitCount == 16 && hdr->bV4RedMask == 0xf800 && hdr->bV4GreenMask == 0x7e0 && hdr->bV4BlueMask == 0x1f) { DEBUG("RGB565"); return XVID_CSP_VFLIP | XVID_CSP_RGB565; } DEBUG1("BI_FIELDS unsupported", hdr->bV4BitCount); return XVID_CSP_NULL; */ case FOURCC_I420: case FOURCC_IYUV: DEBUG("IYUY"); return XVID_CSP_I420; case FOURCC_YV12 : DEBUG("YV12"); return XVID_CSP_YV12; case FOURCC_YUYV : case FOURCC_YUY2 : case FOURCC_V422 : DEBUG("YUY2"); return XVID_CSP_YUY2; case FOURCC_YVYU: DEBUG("YVYU"); return XVID_CSP_YVYU; case FOURCC_UYVY: DEBUG("UYVY"); return XVID_CSP_UYVY; } DEBUGFOURCC("colorspace: unknown", hdr->biCompression); return XVID_CSP_NULL; } /* compressor */ /* test the output format */ LRESULT compress_query(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) { BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader; BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader; if (get_colorspace(inhdr) == XVID_CSP_NULL) { return ICERR_BADFORMAT; } if (lpbiOutput == NULL) { return ICERR_OK; } if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight || (outhdr->biCompression != FOURCC_XVID && outhdr->biCompression != FOURCC_DIVX)) { return ICERR_BADFORMAT; } return ICERR_OK; } LRESULT compress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) { BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader; BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader; if (get_colorspace(inhdr) == XVID_CSP_NULL) { return ICERR_BADFORMAT; } if (lpbiOutput == NULL) { return sizeof(BITMAPV4HEADER); } memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER)); outhdr->biSize = sizeof(BITMAPINFOHEADER); outhdr->biBitCount = 24; // or 16 outhdr->biSizeImage = compress_get_size(codec, lpbiInput, lpbiOutput); outhdr->biXPelsPerMeter = 0; outhdr->biYPelsPerMeter = 0; outhdr->biClrUsed = 0; outhdr->biClrImportant = 0; if (codec->config.fourcc_used == 0) { outhdr->biCompression = FOURCC_XVID; } else if (codec->config.fourcc_used == 1) { outhdr->biCompression = FOURCC_DIVX; } else { outhdr->biCompression = FOURCC_DX50; } return ICERR_OK; } LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) { return lpbiOutput->bmiHeader.biWidth * lpbiOutput->bmiHeader.biHeight * 3; } LRESULT compress_frames_info(CODEC * codec, ICCOMPRESSFRAMES * icf) { // DEBUG2("frate fscale", codec->frate, codec->fscale); codec->fincr = icf->dwScale; codec->fbase = icf->dwRate; return ICERR_OK; } LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) { XVID_ENC_PARAM param; XVID_INIT_PARAM init_param; switch (codec->config.mode) { case DLG_MODE_CBR : param.bitrate = codec->config.bitrate; param.rc_buffersize = codec->config.rc_buffersize; break; case DLG_MODE_VBR_QUAL : codec->config.fquant = 0; param.bitrate = 0; break; case DLG_MODE_VBR_QUANT : codec->config.fquant = (float) codec->config.quant; param.bitrate = 0; break; case DLG_MODE_2PASS_1 : case DLG_MODE_2PASS_2_INT : case DLG_MODE_2PASS_2_EXT : param.bitrate = 0; codec->twopass.max_framesize = (int)((double)codec->config.twopass_max_bitrate / 8.0 / ((double)codec->fbase / (double)codec->fincr)); break; case DLG_MODE_NULL : return ICERR_OK; default : break; } if(codec->ehandle) { xvid_encore(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL); codec->ehandle = NULL; } init_param.cpu_flags = codec->config.cpu; xvid_init(0, 0, &init_param, NULL); if((codec->config.cpu & XVID_CPU_FORCE) <= 0) codec->config.cpu = init_param.cpu_flags; param.width = lpbiInput->bmiHeader.biWidth; param.height = lpbiInput->bmiHeader.biHeight; param.fincr = codec->fincr; param.fbase = codec->fbase; param.rc_buffersize = codec->config.rc_buffersize; param.min_quantizer = codec->config.min_pquant; param.max_quantizer = codec->config.max_pquant; param.max_key_interval = codec->config.max_key_interval; switch(xvid_encore(0, XVID_ENC_CREATE, ¶m, NULL)) { case XVID_ERR_FAIL : return ICERR_ERROR; case XVID_ERR_MEMORY : return ICERR_MEMORY; case XVID_ERR_FORMAT : return ICERR_BADFORMAT; } codec->ehandle = param.handle; codec->framenum = 0; codec->keyspacing = 0; codec->twopass.hints = codec->twopass.stats1 = codec->twopass.stats2 = INVALID_HANDLE_VALUE; codec->twopass.hintstream = NULL; return ICERR_OK; } LRESULT compress_end(CODEC * codec) { if (codec->ehandle != NULL) { xvid_encore(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL); if (codec->twopass.hints != INVALID_HANDLE_VALUE) { CloseHandle(codec->twopass.hints); } if (codec->twopass.stats1 != INVALID_HANDLE_VALUE) { CloseHandle(codec->twopass.stats1); } if (codec->twopass.stats2 != INVALID_HANDLE_VALUE) { CloseHandle(codec->twopass.stats2); } if (codec->twopass.hintstream != NULL) { free(codec->twopass.hintstream); } codec->ehandle = NULL; codec_2pass_finish(codec); } return ICERR_OK; } LRESULT compress(CODEC * codec, ICCOMPRESS * icc) { BITMAPINFOHEADER * inhdr = icc->lpbiInput; BITMAPINFOHEADER * outhdr = icc->lpbiOutput; XVID_ENC_FRAME frame; XVID_ENC_STATS stats; // mpeg2avi yuv bug workaround (2 instances of CODEC) if (codec->twopass.stats1 == INVALID_HANDLE_VALUE) { if (codec_2pass_init(codec) == ICERR_ERROR) { return ICERR_ERROR; } } frame.general = 0; frame.motion = 0; frame.intra = -1; frame.general |= XVID_HALFPEL; if(codec->config.motion_search > 4) frame.general |= XVID_INTER4V; if(((codec->config.mode == DLG_MODE_2PASS_1) ? 0 : codec->config.lum_masking) == 1) frame.general |= XVID_LUMIMASKING; if (codec->config.interlacing) frame.general |= XVID_INTERLACING; if (codec->config.hinted_me && codec->config.mode == DLG_MODE_2PASS_1) { frame.hint.hintstream = codec->twopass.hintstream; frame.hint.rawhints = 0; frame.general |= XVID_HINTEDME_GET; } else if (codec->config.hinted_me && (codec->config.mode == DLG_MODE_2PASS_2_EXT || codec->config.mode == DLG_MODE_2PASS_2_INT)) { DWORD read; DWORD blocksize; frame.hint.hintstream = codec->twopass.hintstream; frame.hint.rawhints = 0; frame.general |= XVID_HINTEDME_SET; if (codec->twopass.hints == INVALID_HANDLE_VALUE) { codec->twopass.hints = CreateFile(codec->config.hintfile, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); if (codec->twopass.hints == INVALID_HANDLE_VALUE) { DEBUGERR("couldn't open hints file"); return ICERR_ERROR; } } if (!ReadFile(codec->twopass.hints, &blocksize, sizeof(DWORD), &read, 0) || read != sizeof(DWORD) || !ReadFile(codec->twopass.hints, frame.hint.hintstream, blocksize, &read, 0) || read != blocksize) { DEBUGERR("couldn't read from hints file"); return ICERR_ERROR; } } frame.motion = pmvfast_presets[codec->config.motion_search]; frame.image = icc->lpInput; if ((frame.colorspace = get_colorspace(inhdr)) == XVID_CSP_NULL) return ICERR_BADFORMAT; frame.bitstream = icc->lpOutput; frame.length = icc->lpbiOutput->biSizeImage; switch (codec->config.mode) { case DLG_MODE_CBR : frame.quant = 0; break; case DLG_MODE_VBR_QUAL : case DLG_MODE_VBR_QUANT : case DLG_MODE_2PASS_1 : if (codec_get_quant(codec, &frame) == ICERR_ERROR) { return ICERR_ERROR; } break; case DLG_MODE_2PASS_2_EXT : case DLG_MODE_2PASS_2_INT : if (codec_2pass_get_quant(codec, &frame) == ICERR_ERROR) { return ICERR_ERROR; } if (codec->config.dummy2pass) { outhdr->biSizeImage = codec->twopass.bytes2; *icc->lpdwFlags = (codec->twopass.nns1.quant & NNSTATS_KEYFRAME) ? AVIIF_KEYFRAME : 0; return ICERR_OK; } break; case DLG_MODE_NULL : outhdr->biSizeImage = 0; *icc->lpdwFlags = AVIIF_KEYFRAME; return ICERR_OK; default : DEBUGERR("Invalid encoding mode"); return ICERR_ERROR; } if (codec->config.quant_type == QUANT_MODE_H263) { frame.general |= XVID_H263QUANT; } else { frame.general |= XVID_MPEGQUANT; // we actually need "default/custom" selectbox for both inter/intra // this will do for now if (codec->config.quant_type == QUANT_MODE_CUSTOM) { frame.general |= XVID_CUSTOM_QMATRIX; frame.quant_intra_matrix = codec->config.qmatrix_intra; frame.quant_inter_matrix = codec->config.qmatrix_inter; } else { frame.quant_intra_matrix = NULL; frame.quant_inter_matrix = NULL; } } // force keyframe spacing in 2-pass 1st pass if (codec->config.motion_search == 0) { frame.intra = 1; } else if (codec->keyspacing < codec->config.min_key_interval && codec->framenum) { DEBUG("current frame forced to p-frame"); frame.intra = 0; } switch (xvid_encore(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats)) { case XVID_ERR_FAIL : return ICERR_ERROR; case XVID_ERR_MEMORY : return ICERR_MEMORY; case XVID_ERR_FORMAT : return ICERR_BADFORMAT; } if (frame.intra) { codec->keyspacing = 0; *icc->lpdwFlags = AVIIF_KEYFRAME; } else { *icc->lpdwFlags = 0; } outhdr->biSizeImage = frame.length; if (codec->config.mode == DLG_MODE_2PASS_1 && codec->config.discard1pass) { outhdr->biSizeImage = 0; } if (frame.general & XVID_HINTEDME_GET) { DWORD wrote; DWORD blocksize = frame.hint.hintlength; if (codec->twopass.hints == INVALID_HANDLE_VALUE) { codec->twopass.hints = CreateFile(codec->config.hintfile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); if (codec->twopass.hints == INVALID_HANDLE_VALUE) { DEBUGERR("couldn't create hints file"); return ICERR_ERROR; } } if (!WriteFile(codec->twopass.hints, &frame.hint.hintlength, sizeof(int), &wrote, 0) || wrote != sizeof(int) || !WriteFile(codec->twopass.hints, frame.hint.hintstream, blocksize, &wrote, 0) || wrote != blocksize) { DEBUGERR("couldn't write to hints file"); return ICERR_ERROR; } } codec_2pass_update(codec, &frame, &stats); ++codec->framenum; ++codec->keyspacing; return ICERR_OK; } /* decompressor */ LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput) { BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader; BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader; if (lpbiInput == NULL) { return ICERR_ERROR; } if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX) { return ICERR_BADFORMAT; } if (lpbiOutput == NULL) { return ICERR_OK; } if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight || get_colorspace(outhdr) == XVID_CSP_NULL) { return ICERR_BADFORMAT; } return ICERR_OK; } LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) { BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader; BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader; LRESULT result; if (lpbiOutput == NULL) { return sizeof(BITMAPINFOHEADER); } result = decompress_query(codec, lpbiInput, lpbiOutput); if (result != ICERR_OK) { return result; } memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER)); outhdr->biSize = sizeof(BITMAPINFOHEADER); outhdr->biCompression = FOURCC_YUY2; outhdr->biSizeImage = outhdr->biWidth * outhdr->biHeight * outhdr->biBitCount; outhdr->biXPelsPerMeter = 0; outhdr->biYPelsPerMeter = 0; outhdr->biClrUsed = 0; outhdr->biClrImportant = 0; return ICERR_OK; } LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) { XVID_DEC_PARAM param; XVID_INIT_PARAM init_param; init_param.cpu_flags = codec->config.cpu; xvid_init(0, 0, &init_param, NULL); if((codec->config.cpu & XVID_CPU_FORCE) <= 0) { codec->config.cpu = init_param.cpu_flags; } param.width = lpbiInput->bmiHeader.biWidth; param.height = lpbiInput->bmiHeader.biHeight; switch(xvid_decore(0, XVID_DEC_CREATE, ¶m, NULL)) { case XVID_ERR_FAIL : return ICERR_ERROR; case XVID_ERR_MEMORY : return ICERR_MEMORY; case XVID_ERR_FORMAT : return ICERR_BADFORMAT; } codec->dhandle = param.handle; return ICERR_OK; } LRESULT decompress_end(CODEC * codec) { if (codec->dhandle != NULL) { xvid_decore(codec->dhandle, XVID_DEC_DESTROY, NULL, NULL); codec->dhandle = NULL; } return ICERR_OK; } LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd) { XVID_DEC_FRAME frame; frame.bitstream = icd->lpInput; frame.length = icd->lpbiInput->biSizeImage; frame.image = icd->lpOutput; frame.stride = icd->lpbiOutput->biWidth; if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE))) { if ((frame.colorspace = get_colorspace(icd->lpbiOutput)) == XVID_CSP_NULL) { return ICERR_BADFORMAT; } } else { frame.colorspace = XVID_CSP_NULL; } switch (xvid_decore(codec->dhandle, XVID_DEC_DECODE, &frame, NULL)) { case XVID_ERR_FAIL : return ICERR_ERROR; case XVID_ERR_MEMORY : return ICERR_MEMORY; case XVID_ERR_FORMAT : return ICERR_BADFORMAT; } return ICERR_OK; } int codec_get_quant(CODEC* codec, XVID_ENC_FRAME* frame) { switch (codec->config.mode) { case DLG_MODE_VBR_QUAL : if (codec_is_in_credits(&codec->config, codec->framenum)) { switch (codec->config.credits_mode) { case CREDITS_MODE_RATE : frame->quant = codec_get_vbr_quant(&codec->config, codec->config.quality * codec->config.credits_rate / 100); break; case CREDITS_MODE_QUANT : frame->quant = codec->config.credits_quant_p; break; default : DEBUGERR("Can't use credits size mode in quality mode"); return ICERR_ERROR; } } else { frame->quant = codec_get_vbr_quant(&codec->config, codec->config.quality); } return ICERR_OK; case DLG_MODE_VBR_QUANT : if (codec_is_in_credits(&codec->config, codec->framenum)) { switch (codec->config.credits_mode) { case CREDITS_MODE_RATE : frame->quant = codec->config.max_pquant - ((codec->config.max_pquant - codec->config.quant) * codec->config.credits_rate / 100); break; case CREDITS_MODE_QUANT : frame->quant = codec->config.credits_quant_p; break; default : DEBUGERR("Can't use credits size mode in quantizer mode"); return ICERR_ERROR; } } else { frame->quant = codec->config.quant; } return ICERR_OK; case DLG_MODE_2PASS_1 : if (codec->config.credits_mode == CREDITS_MODE_QUANT) { if (codec_is_in_credits(&codec->config, codec->framenum)) { frame->quant = codec->config.credits_quant_p; } else { frame->quant = 2; } } else { frame->quant = 2; } return ICERR_OK; default: DEBUGERR("get quant: invalid mode"); return ICERR_ERROR; } } int codec_is_in_credits(CONFIG* config, int framenum) { if (config->credits_start) { if (framenum >= config->credits_start_begin && framenum <= config->credits_start_end) { return CREDITS_START; } } if (config->credits_end) { if (framenum >= config->credits_end_begin && framenum <= config->credits_end_end) { return CREDITS_END; } } return 0; } int codec_get_vbr_quant(CONFIG* config, int quality) { static float fquant_running = 0; static int my_quality = -1; int quant; // if quality changes, recalculate fquant (credits) if (quality != my_quality) { config->fquant = 0; } my_quality = quality; // desired quantiser = (maxQ-minQ)/100 * (100-qual) + minQ if (!config->fquant) { config->fquant = ((float) (config->max_pquant - config->min_pquant) / 100) * (100 - quality) + (float) config->min_pquant; fquant_running = config->fquant; } if (fquant_running < config->min_pquant) { fquant_running = (float) config->min_pquant; } else if(fquant_running > config->max_pquant) { fquant_running = (float) config->max_pquant; } quant = (int) fquant_running; // add error between fquant and quant to fquant_running fquant_running += config->fquant - quant; return quant; } xvid_20020412/vfw/src/codec.h0100644000100600001440000001073707454311135015150 0ustar michaelusers#ifndef _CODEC_H_ #define _CODEC_H_ #include #include #include "config.h" #include "xvid.h" #define DEBUG(X) // OutputDebugString(X) #define DEBUG1(X,A) { char tmp[120]; wsprintf(tmp, "%s %i", (X), (A)); OutputDebugString(tmp); } #define DEBUG2(X,A,B) // { char tmp[120]; wsprintf(tmp, "%s %i %i", (X), (A), (B)); OutputDebugString(tmp); } #define DEBUG3(X,A,B,C) // { char tmp[120]; wsprintf(tmp, "%s %i %i %i", (X), (A), (B), (C)); OutputDebugString(tmp); } #define DEBUG4(X,A,B,C,D) // { char tmp[120]; wsprintf(tmp, "%s %i %i %i %i", (X), (A), (B), (C), (D)); OutputDebugString(tmp); } #define DEBUG5(X,A,B,C,D,E) // { char tmp[120]; wsprintf(tmp, "%s %i %i %i %i %i", (X), (A), (B), (C), (D), (E)); OutputDebugString(tmp); } #define DEBUGFOURCC(X,Y) // { char tmp[120]; wsprintf(tmp, "%s %c %c %c %c", (X), (Y)&0xff, ((Y)>>8)&0xff, ((Y)>>16)&0xff, ((Y)>>24)&0xff); OutputDebugString(tmp); } #define DEBUGERR(X) OutputDebugString(X) #define DEBUG2P(X) OutputDebugString(X) #define DEBUG1ST(A,B,C,D,E,F,G) { char tmp[120]; wsprintf(tmp, "1st-pass: size:%d total-kbytes:%d %s quant:%d %s kblocks:%d mblocks:%d", (A), (B), (C) ? "intra" : "inter", (D), (E), (F), (G)); OutputDebugString(tmp); } #define DEBUG2ND(A,B,C,D,E,F,G,H) { char tmp[120]; wsprintf(tmp, "2nd-pass: quant:%d %s %s stats1:%d scaled:%d actual:%d overflow:%d %s", (A), (B), (C) ? "intra" : "inter", (D), (E), (F), (G), (H) ? "credits" : "movie"); OutputDebugString(tmp); } #define FOURCC_XVID mmioFOURCC('X','V','I','D') #define FOURCC_DIVX mmioFOURCC('D','I','V','X') #define FOURCC_DX50 mmioFOURCC('D','X','5','0') //#define FOURCC_DIV3 mmioFOURCC('D','I','V','3') //#define FOURCC_DIV4 mmioFOURCC('D','I','V','4') /* yuyu 4:2:2 16bit, y-u-y-v, packed*/ #define FOURCC_YUYV mmioFOURCC('Y','U','Y','V') #define FOURCC_YUY2 mmioFOURCC('Y','U','Y','2') #define FOURCC_V422 mmioFOURCC('V','4','2','2') /* yvyu 4:2:2 16bit, y-v-y-u, packed*/ #define FOURCC_YVYU mmioFOURCC('Y','V','Y','U') /* uyvy 4:2:2 16bit, u-y-v-y, packed */ #define FOURCC_UYVY mmioFOURCC('U','Y','V','Y') /* i420 y-u-v, planar */ #define FOURCC_I420 mmioFOURCC('I','4','2','0') #define FOURCC_IYUV mmioFOURCC('I','Y','U','V') /* yv12 y-v-u, planar */ #define FOURCC_YV12 mmioFOURCC('Y','V','1','2') #define XVID_NAME_L L"XVID" #define XVID_DESC_L L"XviD MPEG-4 Codec" #define NNSTATS_KEYFRAME (1<<31) typedef struct { /* frame length (bytes) */ DWORD bytes; /* ignored & zero'd by gk xvid specific: dk_v = frame header bytes */ int dk_v, dk_u, dk_y; int dd_v, dd_u, dd_y; int mk_u, mk_y; int md_u, md_y; /* q used for this frame set bit 31 for keyframe */ int quant; /* key, motion, not-coded macroblocks */ int kblk, mblk, ublk; /* lum_noise is actually a double (as 8 bytes) for some reason msvc6.0 stores doubles as 12 bytes!? lum_noise is not used so it doesnt matter */ float lum_noise[2]; } NNSTATS; typedef struct { HANDLE hints; HANDLE stats1; HANDLE stats2; void * hintstream; int bytes1; int bytes2; int desired_bytes2; int max_framesize; double movie_curve; double credits_start_curve; double credits_end_curve; double average_frame; double curve_comp_scale; double curve_bias_bonus; double alt_curve_low; double alt_curve_high; double alt_curve_low_diff; double alt_curve_high_diff; double alt_curve_mid_qual; double alt_curve_qual_dev; int overflow; int quant_count[32]; NNSTATS nns1; NNSTATS nns2; } TWOPASS; typedef struct { // config CONFIG config; // encore void * ehandle; int fincr; int fbase; int framenum; int keyspacing; // encore 2pass TWOPASS twopass; // decore void * dhandle; int dopt; // DEC_OPT_DECODE, DEC_OPT_DECODE_MS } CODEC; int get_colorspace(BITMAPINFOHEADER *); LRESULT compress_query(CODEC *, BITMAPINFO *, BITMAPINFO *); LRESULT compress_get_format(CODEC *, BITMAPINFO *, BITMAPINFO *); LRESULT compress_get_size(CODEC *, BITMAPINFO *, BITMAPINFO *); LRESULT compress_frames_info(CODEC *, ICCOMPRESSFRAMES *); LRESULT compress_begin(CODEC *, BITMAPINFO *, BITMAPINFO *); LRESULT compress_end(CODEC *); LRESULT compress(CODEC *, ICCOMPRESS *); LRESULT decompress_query(CODEC *, BITMAPINFO *, BITMAPINFO *); LRESULT decompress_get_format(CODEC *, BITMAPINFO *, BITMAPINFO *); LRESULT decompress_begin(CODEC *, BITMAPINFO *, BITMAPINFO *); LRESULT decompress_end(CODEC *); LRESULT decompress(CODEC *, ICDECOMPRESS *); int codec_get_quant(CODEC *, XVID_ENC_FRAME *); int codec_is_in_credits(CONFIG *, int); int codec_get_vbr_quant(CONFIG *, int); #endif /* _CODEC_H_ */xvid_20020412/vfw/src/driverproc.def0100644000100600001440000000011007442022762016543 0ustar michaelusersEXPORTS DriverProc decore encore xvid_init xvid_decore xvid_encorexvid_20020412/vfw/src/resource.h0100644000100600001440000002372407454311135015722 0ustar michaelusers//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by config.rc // #define IDD_MAIN 100 #define IDD_GLOBAL 101 #define IDD_QUANT 102 #define IDD_2PASS 103 #define IDD_CREDITS 104 #define IDD_CPU 105 #define IDD_QUANTMATRIX 106 #define IDD_ABOUT 107 #define IDD_2PASSALT 108 #define IDC_MODE 1000 #define IDC_SLIDER 1001 #define IDC_VALUE 1002 #define IDC_SLIDER_STATIC 1003 #define IDC_VALUE_STATIC 1004 #define IDC_CBRBUFFER 1005 #define IDC_CBRBUFFER_STATIC 1006 #define IDC_ADVANCED 1007 #define IDC_STATIC_HELP 1008 #define IDC_MOTION 1009 #define IDC_QUANTTYPE 1010 #define IDC_FOURCC 1011 #define IDC_MAXKEY 1012 #define IDC_LUMMASK 1013 #define IDC_MINIQUANT 1014 #define IDC_MAXIQUANT 1015 #define IDC_MINPQUANT 1016 #define IDC_MAXPQUANT 1017 #define IDC_MINBQUANT 1018 #define IDC_MAXBQUANT 1019 #define IDC_QUANTMATRIX 1020 #define IDC_KFBOOST 1021 #define IDC_MINKEY 1022 #define IDC_DISCARD1PASS 1023 #define IDC_DUMMY2PASS 1024 #define IDC_CURVECOMPH 1025 #define IDC_CURVECOMPL 1026 #define IDC_PAYBACK 1027 #define IDC_PAYBACKBIAS 1028 #define IDC_PAYBACKPROP 1029 #define IDC_STATS1 1030 #define IDC_STATS2 1031 #define IDC_STATS1_BROWSE 1032 #define IDC_STATS2_BROWSE 1033 #define IDC_CREDITS_START 1034 #define IDC_CREDITS_START_BEGIN 1035 #define IDC_CREDITS_START_END 1036 #define IDC_CREDITS_END 1037 #define IDC_CREDITS_END_START 1038 #define IDC_CREDITS_END_BEGIN 1039 #define IDC_CREDITS_END_END 1040 #define IDC_CREDITS_RATE_RADIO 1041 #define IDC_CREDITS_RATE 1042 #define IDC_CREDITS_QUANT_RADIO 1043 #define IDC_CREDITS_QUANTI 1044 #define IDC_CREDITS_QUANT_STATIC 1045 #define IDC_CREDITS_QUANTP 1046 #define IDC_CREDITS_SIZE_RADIO 1047 #define IDC_CREDITS_START_SIZE 1048 #define IDC_CREDITS_END_STATIC 1049 #define IDC_CREDITS_END_SIZE 1050 #define IDC_CPU_AUTO 1051 #define IDC_CPU_FORCE 1052 #define IDC_CPU_MMX 1053 #define IDC_CPU_MMXEXT 1054 #define IDC_CPU_SSE 1055 #define IDC_CPU_SSE2 1056 #define IDC_CPU_3DNOW 1057 #define IDC_CPU_3DNOWEXT 1058 #define IDC_LOAD 1059 #define IDC_SAVE 1060 #define IDC_WEBSITE 1061 #define IDC_BUILD 1062 #define IDC_CORE 1063 #define IDC_QINTRA00 1064 #define IDC_QINTRA01 1065 #define IDC_QINTRA02 1066 #define IDC_QINTRA03 1067 #define IDC_QINTRA04 1068 #define IDC_QINTRA05 1069 #define IDC_QINTRA06 1070 #define IDC_QINTRA07 1071 #define IDC_QINTRA08 1072 #define IDC_QINTRA09 1073 #define IDC_QINTRA10 1074 #define IDC_QINTRA11 1075 #define IDC_QINTRA12 1076 #define IDC_QINTRA13 1077 #define IDC_QINTRA14 1078 #define IDC_QINTRA15 1079 #define IDC_QINTRA16 1080 #define IDC_QINTRA17 1081 #define IDC_QINTRA18 1082 #define IDC_QINTRA19 1083 #define IDC_QINTRA20 1084 #define IDC_QINTRA21 1085 #define IDC_QINTRA22 1086 #define IDC_QINTRA23 1087 #define IDC_QINTRA24 1088 #define IDC_QINTRA25 1089 #define IDC_QINTRA26 1090 #define IDC_QINTRA27 1091 #define IDC_QINTRA28 1092 #define IDC_QINTRA29 1093 #define IDC_QINTRA30 1094 #define IDC_QINTRA31 1095 #define IDC_QINTRA32 1096 #define IDC_QINTRA33 1097 #define IDC_QINTRA34 1098 #define IDC_QINTRA35 1099 #define IDC_QINTRA36 1100 #define IDC_QINTRA37 1101 #define IDC_QINTRA38 1102 #define IDC_QINTRA39 1103 #define IDC_QINTRA40 1104 #define IDC_QINTRA41 1105 #define IDC_QINTRA42 1106 #define IDC_QINTRA43 1107 #define IDC_QINTRA44 1108 #define IDC_QINTRA45 1109 #define IDC_QINTRA46 1110 #define IDC_QINTRA47 1111 #define IDC_QINTRA48 1112 #define IDC_QINTRA49 1113 #define IDC_QINTRA50 1114 #define IDC_QINTRA51 1115 #define IDC_QINTRA52 1116 #define IDC_QINTRA53 1117 #define IDC_QINTRA54 1118 #define IDC_QINTRA55 1119 #define IDC_QINTRA56 1120 #define IDC_QINTRA57 1121 #define IDC_QINTRA58 1122 #define IDC_QINTRA59 1123 #define IDC_QINTRA60 1124 #define IDC_QINTRA61 1125 #define IDC_QINTRA62 1126 #define IDC_QINTRA63 1127 #define IDC_QINTER00 1128 #define IDC_QINTER01 1129 #define IDC_QINTER02 1130 #define IDC_QINTER03 1131 #define IDC_QINTER04 1132 #define IDC_QINTER05 1133 #define IDC_QINTER06 1134 #define IDC_QINTER07 1135 #define IDC_QINTER08 1136 #define IDC_QINTER09 1137 #define IDC_QINTER10 1138 #define IDC_QINTER11 1139 #define IDC_QINTER12 1140 #define IDC_QINTER13 1141 #define IDC_QINTER14 1142 #define IDC_QINTER15 1143 #define IDC_QINTER16 1144 #define IDC_QINTER17 1145 #define IDC_QINTER18 1146 #define IDC_QINTER19 1147 #define IDC_QINTER20 1148 #define IDC_QINTER21 1149 #define IDC_QINTER22 1150 #define IDC_QINTER23 1151 #define IDC_QINTER24 1152 #define IDC_QINTER25 1153 #define IDC_QINTER26 1154 #define IDC_QINTER27 1155 #define IDC_QINTER28 1156 #define IDC_QINTER29 1157 #define IDC_QINTER30 1158 #define IDC_QINTER31 1159 #define IDC_QINTER32 1160 #define IDC_QINTER33 1161 #define IDC_QINTER34 1162 #define IDC_QINTER35 1163 #define IDC_QINTER36 1164 #define IDC_QINTER37 1165 #define IDC_QINTER38 1166 #define IDC_QINTER39 1167 #define IDC_QINTER40 1168 #define IDC_QINTER41 1169 #define IDC_QINTER42 1170 #define IDC_QINTER43 1171 #define IDC_QINTER44 1172 #define IDC_QINTER45 1173 #define IDC_QINTER46 1174 #define IDC_QINTER47 1175 #define IDC_QINTER48 1176 #define IDC_QINTER49 1177 #define IDC_QINTER50 1178 #define IDC_QINTER51 1179 #define IDC_QINTER52 1180 #define IDC_QINTER53 1181 #define IDC_QINTER54 1182 #define IDC_QINTER55 1183 #define IDC_QINTER56 1184 #define IDC_QINTER57 1185 #define IDC_QINTER58 1186 #define IDC_QINTER59 1187 #define IDC_QINTER60 1188 #define IDC_QINTER61 1189 #define IDC_QINTER62 1190 #define IDC_QINTER63 1191 #define IDC_DEFAULTS 1192 #define IDC_USEALT 1193 #define IDC_USEAUTO 1194 #define IDC_AUTOSTR 1195 #define IDC_USEAUTOBONUS 1196 #define IDC_BONUSBIAS 1197 #define IDC_CURVETYPE 1198 #define IDC_ALTCURVEHIGH 1199 #define IDC_ALTCURVELOW 1201 #define IDC_MINQUAL 1202 #define IDC_INTERLACING 1203 #define IDC_OVERDEG 1204 #define IDC_HINTFILE 1205 #define IDC_HINT_BROWSE 1206 #define IDC_HINTEDME 1207 #define IDC_OVERIMP 1208 #define IDC_MAXBITRATE 1209 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 109 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1203 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif xvid_20020412/vfw/src/config.rc0100644000100600001440000010605207454311135015511 0ustar michaelusers//Microsoft Developer Studio generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // German (Germany) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) #ifdef _WIN32 LANGUAGE LANG_GERMAN, SUBLANG_GERMAN #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Bitmap // IDB_LOGO BITMAP DISCARDABLE "XviD_logo.bmp" #endif // German (Germany) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // English (Australia) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_MAIN DIALOG DISCARDABLE 0, 0, 184, 145 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "XviD Configuration" FONT 8, "MS Sans Serif" BEGIN LTEXT "Encoding Mode:",IDC_STATIC,12,16,80,12,SS_CENTERIMAGE COMBOBOX IDC_MODE,96,16,76,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Slider1",IDC_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,96,32,76,12 EDITTEXT IDC_VALUE,96,48,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "",IDC_SLIDER_STATIC,12,32,80,12,SS_CENTERIMAGE LTEXT "",IDC_VALUE_STATIC,12,48,80,12,SS_CENTERIMAGE GROUPBOX "Encoding options",IDC_STATIC,4,4,176,80 EDITTEXT IDC_CBRBUFFER,96,64,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Reaction Delay Factor:",IDC_CBRBUFFER_STATIC,12,64,80, 12,SS_CENTERIMAGE PUSHBUTTON "Advanced options...",IDC_ADVANCED,52,92,80,12 PUSHBUTTON "Load Defaults...",IDC_DEFAULTS,52,108,80,12 DEFPUSHBUTTON "OK",IDOK,52,124,80,12 END IDD_GLOBAL DIALOG DISCARDABLE 0, 0, 200, 217 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Global" FONT 8, "MS Sans Serif" BEGIN LTEXT "Motion search precision:",IDC_STATIC,12,16,80,12, SS_CENTERIMAGE COMBOBOX IDC_MOTION,112,16,76,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP GROUPBOX "Global settings",IDC_STATIC,4,4,192,120 LTEXT "Quantization type:",IDC_STATIC,12,32,80,12, SS_CENTERIMAGE COMBOBOX IDC_QUANTTYPE,112,32,76,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "FourCC used:",IDC_STATIC,12,48,80,12,SS_CENTERIMAGE COMBOBOX IDC_FOURCC,112,48,76,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP EDITTEXT IDC_MAXKEY,112,64,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Maximum I-frame interval:",IDC_STATIC,12,64,80,12, SS_CENTERIMAGE CONTROL "Enable lumi masking",IDC_LUMMASK,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,16,96,80,10 CONTROL "Enable interlacing",IDC_INTERLACING,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,16,108,72,10 LTEXT "Minimum I-frame interval:",IDC_STATIC,12,80,100,12, SS_CENTERIMAGE EDITTEXT IDC_MINKEY,112,80,76,12,ES_AUTOHSCROLL | ES_NUMBER END IDD_QUANT DIALOG DISCARDABLE 0, 0, 200, 217 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Quantization" FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Quantizer restrictions",IDC_STATIC,4,4,192,112 EDITTEXT IDC_MINIQUANT,112,16,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Min I-frame quantizer:",IDC_STATIC,12,16,76,12, SS_CENTERIMAGE EDITTEXT IDC_MAXIQUANT,112,32,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Max I-frame quantizer:",IDC_STATIC,12,32,76,12, SS_CENTERIMAGE EDITTEXT IDC_MINPQUANT,112,48,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Min P-frame quantizer:",IDC_STATIC,12,48,76,12, SS_CENTERIMAGE EDITTEXT IDC_MAXPQUANT,112,64,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Max P-frame quantizer:",IDC_STATIC,12,64,76,12, SS_CENTERIMAGE EDITTEXT IDC_MINBQUANT,112,80,76,12,ES_AUTOHSCROLL | ES_NUMBER | WS_DISABLED LTEXT "Min B-frame quantizer:",IDC_STATIC,12,80,76,12, SS_CENTERIMAGE EDITTEXT IDC_MAXBQUANT,112,96,76,12,ES_AUTOHSCROLL | ES_NUMBER | WS_DISABLED LTEXT "Max B-frame quantizer:",IDC_STATIC,12,96,76,12, SS_CENTERIMAGE PUSHBUTTON "Edit Quantizer Matrix...",IDC_QUANTMATRIX,60,124,80,12 END IDD_2PASS DIALOG DISCARDABLE 0, 0, 200, 217 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Two Pass" FONT 8, "MS Sans Serif" BEGIN GROUPBOX "Two-pass tuning",IDC_STATIC,4,4,192,60 LTEXT "Bitrate payback delay (frames):",IDC_STATIC,12,112,100, 12,SS_CENTERIMAGE EDITTEXT IDC_PAYBACK,112,112,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "High bitrate scenes %:",IDC_STATIC,12,80,100,12, SS_CENTERIMAGE EDITTEXT IDC_CURVECOMPH,112,80,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Low bitrate scenes %:",IDC_STATIC,12,96,100,12, SS_CENTERIMAGE EDITTEXT IDC_CURVECOMPL,112,96,76,12,ES_AUTOHSCROLL | ES_NUMBER GROUPBOX "Curve compression",IDC_STATIC,4,68,192,88 LTEXT "I-frame boost %:",IDC_STATIC,12,16,100,12, SS_CENTERIMAGE EDITTEXT IDC_KFBOOST,112,16,76,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Payback with bias",IDC_PAYBACKBIAS,"Button", BS_AUTORADIOBUTTON | WS_GROUP,16,128,96,12 CONTROL "Payback proportionally",IDC_PAYBACKPROP,"Button", BS_AUTORADIOBUTTON,16,139,96,12 CONTROL "Discard first pass",IDC_DISCARD1PASS,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,16,48,69,10 CONTROL "Dummy 2nd pass",IDC_DUMMY2PASS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,48,70,10 EDITTEXT IDC_STATS2,64,196,112,12,ES_AUTOHSCROLL PUSHBUTTON "...",IDC_STATS2_BROWSE,180,196,16,11 LTEXT "2nd pass stats:",IDC_STATIC,4,196,52,12,SS_CENTERIMAGE LTEXT "1st pass stats:",IDC_STATIC,4,180,52,12,SS_CENTERIMAGE EDITTEXT IDC_STATS1,64,180,112,12,ES_AUTOHSCROLL PUSHBUTTON "...",IDC_STATS1_BROWSE,180,180,16,11 EDITTEXT IDC_HINTFILE,64,164,112,12,ES_AUTOHSCROLL PUSHBUTTON "...",IDC_HINT_BROWSE,180,164,16,11 CONTROL "Hinted ME:",IDC_HINTEDME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,164,52,12 END IDD_CREDITS DIALOG DISCARDABLE 0, 0, 200, 217 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Credits" FONT 8, "MS Sans Serif" BEGIN LTEXT "Credits start at frame no.:",IDC_STATIC,12,16,88,12, SS_CENTERIMAGE EDITTEXT IDC_CREDITS_START_BEGIN,112,16,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Credits end at frame no.:",IDC_STATIC,12,88,88,12, SS_CENTERIMAGE EDITTEXT IDC_CREDITS_END_END,112,88,76,12,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_CREDITS_RATE,112,128,76,12,ES_AUTOHSCROLL | ES_NUMBER GROUPBOX "",IDC_STATIC,4,4,192,48 GROUPBOX "",IDC_STATIC,4,60,192,48 LTEXT "Credits end at frame no.:",IDC_STATIC,12,32,88,12, SS_CENTERIMAGE EDITTEXT IDC_CREDITS_START_END,112,32,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Credits begin at frame no.:",IDC_STATIC,12,72,88,12, SS_CENTERIMAGE EDITTEXT IDC_CREDITS_END_BEGIN,112,72,76,12,ES_AUTOHSCROLL | ES_NUMBER GROUPBOX "Credits rate reduction",IDC_STATIC,4,116,192,96 CONTROL "Desired % rate:",IDC_CREDITS_RATE_RADIO,"Button", BS_AUTORADIOBUTTON | WS_GROUP,12,128,88,12 CONTROL "I-frame quantizer:",IDC_CREDITS_QUANT_RADIO,"Button", BS_AUTORADIOBUTTON,12,144,88,12 EDITTEXT IDC_CREDITS_QUANTI,112,144,76,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Starting size (KBytes):",IDC_CREDITS_SIZE_RADIO,"Button", BS_AUTORADIOBUTTON,12,176,88,12 EDITTEXT IDC_CREDITS_START_SIZE,112,176,76,12,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_CREDITS_END_SIZE,112,192,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Ending size (KBytes):",IDC_CREDITS_END_STATIC,24,192,76, 12,SS_CENTERIMAGE EDITTEXT IDC_CREDITS_QUANTP,112,160,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "P-frame quantizer:",IDC_CREDITS_QUANT_STATIC,24,160,76, 12,SS_CENTERIMAGE CONTROL "Credits at start of movie",IDC_CREDITS_START,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,12,4,88,10 CONTROL "Credits at end of movie",IDC_CREDITS_END,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,12,60,88,10 END IDD_CPU DIALOG DISCARDABLE 0, 0, 200, 217 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "CPU" FONT 8, "MS Sans Serif" BEGIN CONTROL "Automatically detect optimizations",IDC_CPU_AUTO,"Button", BS_AUTORADIOBUTTON | WS_GROUP,8,16,121,10 CONTROL "Force optimizations",IDC_CPU_FORCE,"Button", BS_AUTORADIOBUTTON,8,28,76,10 CONTROL "MMX",IDC_CPU_MMX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 20,40,33,10 CONTROL "Integer SSE",IDC_CPU_MMXEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,52,54,10 CONTROL "SSE",IDC_CPU_SSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 20,64,30,10 CONTROL "SSE2",IDC_CPU_SSE2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,76,34,10 CONTROL "3DNow!",IDC_CPU_3DNOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,88,42,10 CONTROL "3DNow! 2",IDC_CPU_3DNOWEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,100,48,10 GROUPBOX "Performance optimizations",IDC_STATIC,4,4,192,112 END IDD_QUANTMATRIX DIALOG DISCARDABLE 0, 0, 288, 149 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Custom quantization matrix" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,172,128,47,13 EDITTEXT IDC_QINTRA00,8,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | WS_DISABLED | NOT WS_BORDER EDITTEXT IDC_QINTRA01,24,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA02,40,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA03,56,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA04,72,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA05,88,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA06,104,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA07,120,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA08,8,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA09,24,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA10,40,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA11,56,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA12,72,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA13,88,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA14,104,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA15,120,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA16,8,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA17,24,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA18,40,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA19,56,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA20,72,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA21,88,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA22,104,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA23,120,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA24,8,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA25,24,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA26,40,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA27,56,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA28,72,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA29,88,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA30,104,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA31,120,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA32,8,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA33,24,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA34,40,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA35,56,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA36,72,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA37,88,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA38,104,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA39,120,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA40,8,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA41,24,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA42,40,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA43,56,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA44,72,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA45,88,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA46,104,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA47,120,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA48,8,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA49,24,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA50,40,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA51,56,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA52,72,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA53,88,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA54,104,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA55,120,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA56,8,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA57,24,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA58,40,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA59,56,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA60,72,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA61,88,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA62,104,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTRA63,120,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER GROUPBOX "Intra matrix",IDC_STATIC,4,4,136,112 EDITTEXT IDC_QINTER00,152,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER01,168,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER02,184,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER03,200,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER04,216,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER05,232,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER06,248,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER07,264,16,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER08,152,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER09,168,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER10,184,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER11,200,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER12,216,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER13,232,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER14,248,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER15,264,28,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER16,152,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER17,168,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER18,184,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER19,200,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER20,216,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER21,232,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER22,248,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER23,264,40,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER24,152,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER25,168,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER26,184,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER27,200,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER28,216,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER29,232,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER30,248,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER31,264,52,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER32,152,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER33,168,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER34,184,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER35,200,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER36,216,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER37,232,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER38,248,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER39,264,64,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER40,152,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER41,168,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER42,184,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER43,200,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER44,216,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER45,232,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER46,248,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER47,264,76,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER48,152,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER49,168,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER50,184,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER51,200,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER52,216,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER53,232,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER54,248,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER55,264,88,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER56,152,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER57,168,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER58,184,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER59,200,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER60,216,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER61,232,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER62,248,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER EDITTEXT IDC_QINTER63,264,100,15,11,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_BORDER GROUPBOX "Inter matrix",IDC_STATIC,148,4,136,112 PUSHBUTTON "&Load matrix...",IDC_LOAD,68,128,47,13 PUSHBUTTON "&Save matrix...",IDC_SAVE,120,128,47,13 END IDD_ABOUT DIALOG DISCARDABLE 0, 0, 192, 165 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "XviD MPEG4 Video Codec" FONT 8, "MS Sans Serif" BEGIN CTEXT "GPL'ed MPEG4 video codec demonstration.\nFor educational purposes only.", IDC_STATIC,12,112,168,20 CTEXT "WEBSITE",IDC_WEBSITE,64,92,64,8,SS_NOTIFY | SS_CENTERIMAGE CTEXT "BUILD",IDC_BUILD,8,28,176,8,SS_CENTERIMAGE CONTROL "IDB_LOGO",IDC_STATIC,"Static",SS_BITMAP,24,56,15,13 CTEXT "XviD MPEG4 video codec",IDC_STATIC,8,16,176,12 GROUPBOX "About",IDC_STATIC,4,4,184,132 DEFPUSHBUTTON "OK",IDOK,56,144,80,12 CTEXT "CORE",IDC_CORE,8,40,176,8,SS_CENTERIMAGE END IDD_2PASSALT DIALOG DISCARDABLE 0, 0, 200, 217 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Alt. Curve" FONT 8, "MS Sans Serif" BEGIN GROUPBOX "",IDC_STATIC,4,4,192,152 LTEXT "Minimum relative quality %:",IDC_STATIC,16,100,96,12, SS_CENTERIMAGE EDITTEXT IDC_MINQUAL,112,100,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "High distance from average %:",IDC_STATIC,12,36,100,12, SS_CENTERIMAGE EDITTEXT IDC_ALTCURVEHIGH,112,36,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Low distance from average %:",IDC_STATIC,12,52,100,12, SS_CENTERIMAGE EDITTEXT IDC_ALTCURVELOW,112,52,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Strength %:",IDC_STATIC,16,84,96,12,SS_CENTERIMAGE EDITTEXT IDC_AUTOSTR,112,84,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Manually set bonus bias:",IDC_STATIC,16,136,96,12, SS_CENTERIMAGE EDITTEXT IDC_BONUSBIAS,112,136,76,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Use Alternative curve system",IDC_USEALT,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,12,4,107,10 CONTROL "Enable automatic minimum relative quality",IDC_USEAUTO, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,72,146,10 CONTROL "Enable automatic bonus bias calculation", IDC_USEAUTOBONUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 12,124,143,10 LTEXT "Curve aggression:",IDC_STATIC,12,20,80,12, SS_CENTERIMAGE COMBOBOX IDC_CURVETYPE,112,20,76,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Max bitrate (Kilobit/s):",IDC_STATIC,12,164,100,12, SS_CENTERIMAGE EDITTEXT IDC_MAXBITRATE,112,164,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Max overflow improvement %:",IDC_STATIC,12,180,100,12, SS_CENTERIMAGE EDITTEXT IDC_OVERIMP,112,180,76,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Max overflow degradation %:",IDC_STATIC,12,196,100,12, SS_CENTERIMAGE EDITTEXT IDC_OVERDEG,112,196,76,12,ES_AUTOHSCROLL | ES_NUMBER END ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD_MAIN, DIALOG BEGIN LEFTMARGIN, 7 TOPMARGIN, 7 BOTTOMMARGIN, 122 END IDD_GLOBAL, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 193 TOPMARGIN, 7 END IDD_QUANT, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 177 TOPMARGIN, 7 END IDD_2PASS, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 193 TOPMARGIN, 7 END IDD_CREDITS, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 193 TOPMARGIN, 7 END IDD_CPU, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 193 TOPMARGIN, 7 END IDD_QUANTMATRIX, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 281 TOPMARGIN, 7 BOTTOMMARGIN, 142 END IDD_ABOUT, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 185 TOPMARGIN, 7 BOTTOMMARGIN, 158 END IDD_2PASSALT, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 193 TOPMARGIN, 7 END END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // String Table // STRINGTABLE DISCARDABLE BEGIN IDC_MODE "1-pass CBR encodes to your specified bitrate.\n1-pass quality and quantizer encodes every frame at the same quality.\n2-pass 1st pass gathers statistics for the 2nd pass.\n2-pass internal scales the 2nd pass to your desired file size.\n2-pass external relies on GKnot to scale the .stats file." IDC_CBRBUFFER "Governs how quickly the rate control system reacts to changes in scene intensity - lower values respond faster" END STRINGTABLE DISCARDABLE BEGIN IDC_MOTION "Higher settings give higher-quality results, at the cost of slower encoding. 5 (default) should suffice for most jobs." IDC_QUANTTYPE "H.263 smooths the image whereas MPEG (slightly slower) sharpens.\nModulated varies between the two.\nCustom lets you define your own matrix via the Quantization tab." IDC_FOURCC "Choose what you would like the avi to identify itself as" IDC_MAXKEY "Maximum number of frames allowed between I-frames" IDC_LUMMASK "Turns on Lumi masking - applies more compression to dark/light areas that the eye can't notice easily" IDC_MINIQUANT "Minimum quantizer allowed for I-frames. Only functional in 2-pass second pass." IDC_MAXIQUANT "Maximum quantizer allowed for I-frames. Only functional in 2-pass second pass." IDC_MINPQUANT "Minimum quantizer allowed for P-frames." IDC_MAXPQUANT "Maximum quantizer allowed for P-frames." IDC_QUANTMATRIX "Define your own MPEG quantization matrices. Quantization type must be set to ""Custom"" to affect encoding." IDC_KFBOOST "A value of 20 will give 20% more bits to every I-frame" IDC_MINKEY "Minimum space between I-frames - should be less than 10, set to 1 to disable forced I-frame spacing" IDC_DISCARD1PASS "Check this if you would like to skip the storage of the 1st pass output. It is often very large." END STRINGTABLE DISCARDABLE BEGIN IDC_DUMMY2PASS "Performs a dummy 2nd pass - doesn't output any video data" IDC_CURVECOMPH "The higher this value, the more bits get taken from frames larger than the average size, and redistributed to others" IDC_CURVECOMPL "The higher this value, the more bits get assigned to frames below the average frame size" IDC_PAYBACK "The higher this value, the longer the codec has to smooth out bit allocation" IDC_PAYBACKBIAS "Payback with bias to small frames" IDC_PAYBACKPROP "Payback proportionally (all frames treated equally)" IDC_STATS1 "Location for 1st pass stats file to be saved to" IDC_STATS2 "Location for 2nd pass curve stats to be loaded from - External mode only" IDC_CREDITS_START_BEGIN "Credits begin at this frame" IDC_CREDITS_START_END "Credits end at this frame" IDC_CREDITS_END_START "Credits start at this frame" END STRINGTABLE DISCARDABLE BEGIN IDC_CREDITS_END_END "Credits end at this frame" IDC_CREDITS_RATE "Encode credits at this % rate of the rest of the movie" IDC_CREDITS_QUANTI "Encode credits I-frames with this quantizer" IDC_CREDITS_QUANTP "Encode credits P-frames with this quantizer" IDC_CREDITS_START_SIZE "Encode starting credits to fit into this many kbytes" IDC_CREDITS_END_SIZE "Encode ending credits to fit into this many kbytes" IDC_CPU_AUTO "Enable XviD's internal CPU detection" IDC_CPU_FORCE "Override XviD's internal CPU detection (not recommended)" END STRINGTABLE DISCARDABLE BEGIN IDC_LOAD "Load a pair of custom intra/inter matrices" IDC_SAVE "Save the current intra/inter matrices to a file" END STRINGTABLE DISCARDABLE BEGIN IDC_USEALT "Use Foxer's alternative 2-pass curve system (still uses bias and boost information from other 2-pass tab)" IDC_AUTOSTR "How much influence a poor desired quality (file size) has on minimum relative quality" IDC_BONUSBIAS "The percentage of the bonus that will be applied with bias (the rest is proportionally distributed)" IDC_CURVETYPE "How aggressively the curve affects bitrate distribution" IDC_ALTCURVEHIGH "Distance from the average framesize where the minimum relative quality will be applied" END STRINGTABLE DISCARDABLE BEGIN IDC_ALTCURVELOW "Distance from the average framesize where the best quality will be applied" IDC_MINQUAL "The minimum produced quality in relation to the best produced quality" IDC_OVERDEG "How much of the overflow the codec can eat into during oversized sections - larger values will bridge the gap faster" IDC_OVERIMP "How much of the overflow the codec can eat into during undersized sections - larger values will bridge the gap faster" IDC_MAXBITRATE "Constrains 2-pass encodes to the specified maximum bitrate" END #endif // English (Australia) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED xvid_20020412/vfw/src/config.c0100644000100600001440000011750207454311135015331 0ustar michaelusers/************************************************************************** * * XVID VFW FRONTEND * config * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 07.04.2002 min keyframe interval checkbox * 2-pass max bitrate and overflow customization * 04.04.2002 interlacing support * hinted ME support * 24.03.2002 daniel smith * added Foxer's new CBR engine * - cbr_buffer is being used as reaction delay (quick hack) * 23.03.2002 daniel smith * added load defaults button * merged foxer's alternative 2-pass code (2-pass alt tab) * added proper tooltips * moved registry data into reg_ints/reg_strs arrays * added DEBUGERR output on errors instead of returning * 16.03.2002 daniel smith * rewrote/restructured most of file * added tooltips (kind of - dirty message hook method) * split tabs into a main dialog / advanced prop sheet * advanced controls are now enabled/disabled by mode * added modulated quantization, DX50 fourcc * 11.03.2002 Min Chen * now get Core Version use xvid_init() * 05.03.2002 Min Chen * Add Core version display to about box * 01.12.2001 inital version; (c)2001 peter ross * *************************************************************************/ #include #include #include #include #include "codec.h" #include "config.h" #include "xvid.h" // cpu masks #include "resource.h" /* registry info structs */ CONFIG reg; REG_INT const reg_ints[] = { {"mode", ®.mode, DLG_MODE_CBR}, {"bitrate", ®.bitrate, 900000}, {"quality", ®.quality, 85}, {"quant", ®.quant, 5}, {"rc_buffersize", ®.rc_buffersize, 16}, {"motion_search", ®.motion_search, 5}, {"quant_type", ®.quant_type, 0}, {"fourcc_used", ®.fourcc_used, 0}, {"max_key_interval", ®.max_key_interval, 300}, {"min_key_interval", ®.min_key_interval, 1}, {"lum_masking", ®.lum_masking, 0}, {"interlacing", ®.interlacing, 0}, {"min_iquant", ®.min_iquant, 1}, {"max_iquant", ®.max_iquant, 31}, {"min_pquant", ®.min_pquant, 1}, {"max_pquant", ®.max_pquant, 31}, {"desired_size", ®.desired_size, 570000}, {"keyframe_boost", ®.keyframe_boost, 20}, {"discard1pass", ®.discard1pass, 1}, {"dummy2pass", ®.dummy2pass, 0}, {"curve_compression_high", ®.curve_compression_high, 25}, {"curve_compression_low", ®.curve_compression_low, 10}, {"use_alt_curve", ®.use_alt_curve, 0}, {"alt_curve_use_auto", ®.alt_curve_use_auto, 1}, {"alt_curve_auto_str", ®.alt_curve_auto_str, 50}, {"alt_curve_use_auto_bonus_bias", ®.alt_curve_use_auto_bonus_bias, 1}, {"alt_curve_bonus_bias", ®.alt_curve_bonus_bias, 50}, {"alt_curve_type", ®.alt_curve_type, 1}, {"alt_curve_high_dist", ®.alt_curve_high_dist, 300}, {"alt_curve_low_dist", ®.alt_curve_low_dist, 300}, {"alt_curve_min_rel_qual", ®.alt_curve_min_rel_qual, 50}, {"bitrate_payback_delay", ®.bitrate_payback_delay, 240}, {"bitrate_payback_method", ®.bitrate_payback_method, 0}, {"twopass_max_bitrate", ®.twopass_max_bitrate, 10000 * CONFIG_KBPS}, {"twopass_max_overflow_improvement", ®.twopass_max_overflow_improvement, 60}, {"twopass_max_overflow_degradation", ®.twopass_max_overflow_degradation, 60}, {"hinted_me", ®.hinted_me, 0}, {"credits_start", ®.credits_start, 0}, {"credits_start_begin", ®.credits_start_begin, 0}, {"credits_start_end", ®.credits_start_end, 0}, {"credits_end", ®.credits_end, 0}, {"credits_end_begin", ®.credits_end_begin, 0}, {"credits_end_end", ®.credits_end_end, 0}, {"credits_mode", ®.credits_mode, 0}, {"credits_rate", ®.credits_rate, 20}, {"credits_quant_i", ®.credits_quant_i, 20}, {"credits_quant_p", ®.credits_quant_p, 20}, {"credits_start_size", ®.credits_start_size, 10000}, {"credits_end_size", ®.credits_end_size, 10000} }; REG_STR const reg_strs[] = { {"hintfile", reg.hintfile, CONFIG_HINTFILE}, {"stats1", reg.stats1, CONFIG_2PASS_1_FILE}, {"stats2", reg.stats2, CONFIG_2PASS_2_FILE} // {"build", reg.build, XVID_BUILD} }; /* get config settings from registry */ #define REG_GET_B(X, Y, Z) size=sizeof((Z));if(RegQueryValueEx(hKey, X, 0, 0, Y, &size) != ERROR_SUCCESS) {memcpy(Y, Z, sizeof((Z)));} void config_reg_get(CONFIG * config) { HKEY hKey; DWORD size; XVID_INIT_PARAM init_param; int i; init_param.cpu_flags = 0; xvid_init(0, 0, &init_param, NULL); config->cpu = init_param.cpu_flags; RegOpenKeyEx(XVID_REG_KEY, XVID_REG_PARENT "\\" XVID_REG_CHILD, 0, KEY_READ, &hKey); for (i=0 ; imode) { default : case DLG_MODE_CBR : config->bitrate = config_get_int(hDlg, IDC_VALUE, config->bitrate) * CONFIG_KBPS; break; case DLG_MODE_VBR_QUAL : config->quality = config_get_int(hDlg, IDC_VALUE, config->quality); break; case DLG_MODE_VBR_QUANT : config->quant = config_get_int(hDlg, IDC_VALUE, config->quant); break; case DLG_MODE_2PASS_2_INT : config->desired_size = config_get_int(hDlg, IDC_VALUE, config->desired_size); break; } config->mode = SendDlgItemMessage(hDlg, IDC_MODE, CB_GETCURSEL, 0, 0); config->rc_buffersize = config_get_int(hDlg, IDC_CBRBUFFER, config->rc_buffersize); } /* updates the edit box */ void main_value(HWND hDlg, CONFIG* config) { char* text; int value; int enabled = TRUE; switch (config->mode) { default : enabled = FALSE; case DLG_MODE_CBR : text = "Bitrate (Kbps):"; value = config->bitrate / CONFIG_KBPS; break; case DLG_MODE_VBR_QUAL : text = "Quality:"; value = config->quality; break; case DLG_MODE_VBR_QUANT : text = "Quantizer:"; value = config->quant; break; case DLG_MODE_2PASS_2_INT : text = "Desired size (Kbtyes):"; value = config->desired_size; break; } SetDlgItemText(hDlg, IDC_VALUE_STATIC, text); SetDlgItemInt(hDlg, IDC_VALUE, value, FALSE); EnableWindow(GetDlgItem(hDlg, IDC_VALUE_STATIC), enabled); EnableWindow(GetDlgItem(hDlg, IDC_VALUE), enabled); EnableWindow(GetDlgItem(hDlg, IDC_CBRBUFFER_STATIC), (config->mode == DLG_MODE_CBR)); EnableWindow(GetDlgItem(hDlg, IDC_CBRBUFFER), (config->mode == DLG_MODE_CBR)); } /* updates the slider */ void main_slider(HWND hDlg, CONFIG * config) { char* text; long range; int pos; int enabled = TRUE; switch (config->mode) { default : enabled = FALSE; case DLG_MODE_CBR : text = "Bitrate (Kbps):"; range = MAKELONG(0,10000); pos = config->bitrate / CONFIG_KBPS; break; case DLG_MODE_VBR_QUAL : text = "Quality:"; range = MAKELONG(0,100); pos = config->quality; break; case DLG_MODE_VBR_QUANT : text = "Quantizer:"; range = MAKELONG(1,31); pos = config->quant; break; } SetDlgItemText(hDlg, IDC_SLIDER_STATIC, text); SendDlgItemMessage(hDlg, IDC_SLIDER, TBM_SETRANGE, TRUE, range); SendDlgItemMessage(hDlg, IDC_SLIDER, TBM_SETPOS, TRUE, pos); EnableWindow(GetDlgItem(hDlg, IDC_SLIDER_STATIC), enabled); EnableWindow(GetDlgItem(hDlg, IDC_SLIDER), enabled); } /* load advanced options property sheet */ void adv_dialog(HWND hParent, CONFIG * config) { PROPSHEETINFO psi[DLG_COUNT]; PROPSHEETPAGE psp[DLG_COUNT]; PROPSHEETHEADER psh; CONFIG temp; int i; config->save = FALSE; memcpy(&temp, config, sizeof(CONFIG)); for (i=0 ; imode const int* modes[] = { cbr_disable, qual_disable, quant_disable, twopass1_disable, twopass2_ext_disable, twopass2_int_disable }; // ditto modes[] const int lengths[] = { sizeof(cbr_disable)/sizeof(int), sizeof(qual_disable)/sizeof(int), sizeof(quant_disable)/sizeof(int), sizeof(twopass1_disable)/sizeof(int), sizeof(twopass2_ext_disable)/sizeof(int), sizeof(twopass2_int_disable)/sizeof(int) }; int i; // first perform checkbox-based enable/disable CONTROLDLG(IDC_HINTFILE, ISDLGSET(IDC_HINTEDME)); CONTROLDLG(IDC_HINT_BROWSE, ISDLGSET(IDC_HINTEDME)); CONTROLDLG(IDC_USEAUTO, ISDLGSET(IDC_USEALT)); CONTROLDLG(IDC_AUTOSTR, ISDLGSET(IDC_USEALT) && ISDLGSET(IDC_USEAUTO)); CONTROLDLG(IDC_USEAUTOBONUS, ISDLGSET(IDC_USEALT)); CONTROLDLG(IDC_BONUSBIAS, (ISDLGSET(IDC_USEALT) && !(ISDLGSET(IDC_USEAUTOBONUS)))); CONTROLDLG(IDC_CURVETYPE, ISDLGSET(IDC_USEALT)); CONTROLDLG(IDC_ALTCURVEHIGH, ISDLGSET(IDC_USEALT)); CONTROLDLG(IDC_ALTCURVELOW, ISDLGSET(IDC_USEALT)); CONTROLDLG(IDC_MINQUAL, ISDLGSET(IDC_USEALT) && !(ISDLGSET(IDC_USEAUTO))); CONTROLDLG(IDC_CREDITS_START_BEGIN, ISDLGSET(IDC_CREDITS_START)); CONTROLDLG(IDC_CREDITS_START_END, ISDLGSET(IDC_CREDITS_START)); CONTROLDLG(IDC_CREDITS_END_BEGIN, ISDLGSET(IDC_CREDITS_END)); CONTROLDLG(IDC_CREDITS_END_END, ISDLGSET(IDC_CREDITS_END)); CONTROLDLG(IDC_CREDITS_RATE, ISDLGSET(IDC_CREDITS_RATE_RADIO)); CONTROLDLG(IDC_CREDITS_QUANTI, ISDLGSET(IDC_CREDITS_QUANT_RADIO)); CONTROLDLG(IDC_CREDITS_QUANTP, ISDLGSET(IDC_CREDITS_QUANT_RADIO)); CONTROLDLG(IDC_CREDITS_START_SIZE, ISDLGSET(IDC_CREDITS_SIZE_RADIO)); CONTROLDLG(IDC_CREDITS_END_SIZE, ISDLGSET(IDC_CREDITS_SIZE_RADIO)); CONTROLDLG(IDC_CPU_MMX, ISDLGSET(IDC_CPU_FORCE)); CONTROLDLG(IDC_CPU_MMXEXT, ISDLGSET(IDC_CPU_FORCE)); CONTROLDLG(IDC_CPU_SSE, ISDLGSET(IDC_CPU_FORCE)); CONTROLDLG(IDC_CPU_SSE2, ISDLGSET(IDC_CPU_FORCE)); CONTROLDLG(IDC_CPU_3DNOW, ISDLGSET(IDC_CPU_FORCE)); CONTROLDLG(IDC_CPU_3DNOWEXT, ISDLGSET(IDC_CPU_FORCE)); // now perform codec mode enable/disable for (i=0 ; imotion_search, 0); SendDlgItemMessage(hDlg, IDC_QUANTTYPE, CB_SETCURSEL, config->quant_type, 0); SendDlgItemMessage(hDlg, IDC_FOURCC, CB_SETCURSEL, config->fourcc_used, 0); SetDlgItemInt(hDlg, IDC_MAXKEY, config->max_key_interval, FALSE); SetDlgItemInt(hDlg, IDC_MINKEY, config->min_key_interval, FALSE); CheckDlgButton(hDlg, IDC_LUMMASK, config->lum_masking ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hDlg, IDC_INTERLACING, config->interlacing ? BST_CHECKED : BST_UNCHECKED); break; case DLG_QUANT : SetDlgItemInt(hDlg, IDC_MINIQUANT, config->min_iquant, FALSE); SetDlgItemInt(hDlg, IDC_MAXIQUANT, config->max_iquant, FALSE); SetDlgItemInt(hDlg, IDC_MINPQUANT, config->min_pquant, FALSE); SetDlgItemInt(hDlg, IDC_MAXPQUANT, config->max_pquant, FALSE); break; case DLG_2PASS : SetDlgItemInt(hDlg, IDC_KFBOOST, config->keyframe_boost, FALSE); CheckDlgButton(hDlg, IDC_DISCARD1PASS, config->discard1pass ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hDlg, IDC_DUMMY2PASS, config->dummy2pass ? BST_CHECKED : BST_UNCHECKED); SetDlgItemInt(hDlg, IDC_CURVECOMPH, config->curve_compression_high, FALSE); SetDlgItemInt(hDlg, IDC_CURVECOMPL, config->curve_compression_low, FALSE); SetDlgItemInt(hDlg, IDC_PAYBACK, config->bitrate_payback_delay, FALSE); CheckDlgButton(hDlg, IDC_PAYBACKBIAS, (config->bitrate_payback_method == 0)); CheckDlgButton(hDlg, IDC_PAYBACKPROP, (config->bitrate_payback_method == 1)); CheckDlgButton(hDlg, IDC_HINTEDME, config->hinted_me ? BST_CHECKED : BST_UNCHECKED); SetDlgItemText(hDlg, IDC_HINTFILE, config->hintfile); SetDlgItemText(hDlg, IDC_STATS1, config->stats1); SetDlgItemText(hDlg, IDC_STATS2, config->stats2); break; case DLG_2PASSALT : CheckDlgButton(hDlg, IDC_USEALT, config->use_alt_curve ? BST_CHECKED : BST_UNCHECKED); SendDlgItemMessage(hDlg, IDC_CURVETYPE, CB_SETCURSEL, config->alt_curve_type, 0); SetDlgItemInt(hDlg, IDC_ALTCURVEHIGH, config->alt_curve_high_dist, FALSE); SetDlgItemInt(hDlg, IDC_ALTCURVELOW, config->alt_curve_low_dist, FALSE); SetDlgItemInt(hDlg, IDC_MINQUAL, config->alt_curve_min_rel_qual, FALSE); CheckDlgButton(hDlg, IDC_USEAUTO, config->alt_curve_use_auto ? BST_CHECKED : BST_UNCHECKED); SetDlgItemInt(hDlg, IDC_AUTOSTR, config->alt_curve_auto_str, FALSE); CheckDlgButton(hDlg, IDC_USEAUTOBONUS, config->alt_curve_use_auto_bonus_bias ? BST_CHECKED : BST_UNCHECKED); SetDlgItemInt(hDlg, IDC_BONUSBIAS, config->alt_curve_bonus_bias, FALSE); SetDlgItemInt(hDlg, IDC_MAXBITRATE, config->twopass_max_bitrate / CONFIG_KBPS, FALSE); SetDlgItemInt(hDlg, IDC_OVERIMP, config->twopass_max_overflow_improvement, FALSE); SetDlgItemInt(hDlg, IDC_OVERDEG, config->twopass_max_overflow_degradation, FALSE); break; case DLG_CREDITS : CheckDlgButton(hDlg, IDC_CREDITS_START, config->credits_start ? BST_CHECKED : BST_UNCHECKED); SetDlgItemInt(hDlg, IDC_CREDITS_START_BEGIN, config->credits_start_begin, FALSE); SetDlgItemInt(hDlg, IDC_CREDITS_START_END, config->credits_start_end, FALSE); CheckDlgButton(hDlg, IDC_CREDITS_END, config->credits_end ? BST_CHECKED : BST_UNCHECKED); SetDlgItemInt(hDlg, IDC_CREDITS_END_BEGIN, config->credits_end_begin, FALSE); SetDlgItemInt(hDlg, IDC_CREDITS_END_END, config->credits_end_end, FALSE); SetDlgItemInt(hDlg, IDC_CREDITS_RATE, config->credits_rate, FALSE); SetDlgItemInt(hDlg, IDC_CREDITS_QUANTI, config->credits_quant_i, FALSE); SetDlgItemInt(hDlg, IDC_CREDITS_QUANTP, config->credits_quant_p, FALSE); SetDlgItemInt(hDlg, IDC_CREDITS_START_SIZE, config->credits_start_size, FALSE); SetDlgItemInt(hDlg, IDC_CREDITS_END_SIZE, config->credits_end_size, FALSE); if (config->credits_mode == CREDITS_MODE_RATE) { CheckDlgButton(hDlg, IDC_CREDITS_RATE_RADIO, BST_CHECKED); } else if (config->credits_mode == CREDITS_MODE_QUANT) { CheckDlgButton(hDlg, IDC_CREDITS_QUANT_RADIO, BST_CHECKED); } else // CREDITS_MODE_SIZE { CheckDlgButton(hDlg, IDC_CREDITS_SIZE_RADIO, BST_CHECKED); } break; case DLG_CPU : CheckDlgButton(hDlg, IDC_CPU_MMX, (config->cpu & XVID_CPU_MMX) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CPU_MMXEXT, (config->cpu & XVID_CPU_MMXEXT) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CPU_SSE, (config->cpu & XVID_CPU_SSE) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CPU_SSE2, (config->cpu & XVID_CPU_SSE2) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CPU_3DNOW, (config->cpu & XVID_CPU_3DNOW) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hDlg, IDC_CPU_3DNOWEXT, (config->cpu & XVID_CPU_3DNOWEXT) ? BST_CHECKED : BST_UNCHECKED); CheckRadioButton(hDlg, IDC_CPU_AUTO, IDC_CPU_FORCE, config->cpu & XVID_CPU_FORCE ? IDC_CPU_FORCE : IDC_CPU_AUTO ); break; } } /* download config data from dialog replaces invalid values instead of alerting user for now */ #define CONSTRAINVAL(X,Y,Z) if((X)<(Y)) X=Y; if((X)>(Z)) X=Z; void adv_download(HWND hDlg, int page, CONFIG * config) { switch (page) { case DLG_GLOBAL : config->motion_search = SendDlgItemMessage(hDlg, IDC_MOTION, CB_GETCURSEL, 0, 0); config->quant_type = SendDlgItemMessage(hDlg, IDC_QUANTTYPE, CB_GETCURSEL, 0, 0); config->fourcc_used = SendDlgItemMessage(hDlg, IDC_FOURCC, CB_GETCURSEL, 0, 0); config->max_key_interval = config_get_int(hDlg, IDC_MAXKEY, config->max_key_interval); config->min_key_interval = config_get_int(hDlg, IDC_MINKEY, config->min_key_interval); config->lum_masking = ISDLGSET(IDC_LUMMASK); config->interlacing = ISDLGSET(IDC_INTERLACING); break; case DLG_QUANT : config->min_iquant = config_get_int(hDlg, IDC_MINIQUANT, config->min_iquant); config->max_iquant = config_get_int(hDlg, IDC_MAXIQUANT, config->max_iquant); config->min_pquant = config_get_int(hDlg, IDC_MINPQUANT, config->min_pquant); config->max_pquant = config_get_int(hDlg, IDC_MAXPQUANT, config->max_pquant); CONSTRAINVAL(config->min_iquant, 1, 31); CONSTRAINVAL(config->max_iquant, config->min_iquant, 31); CONSTRAINVAL(config->min_pquant, 1, 31); CONSTRAINVAL(config->max_pquant, config->min_pquant, 31); break; case DLG_2PASS : config->keyframe_boost = GetDlgItemInt(hDlg, IDC_KFBOOST, NULL, FALSE); config->discard1pass = ISDLGSET(IDC_DISCARD1PASS); config->dummy2pass = ISDLGSET(IDC_DUMMY2PASS); config->curve_compression_high = GetDlgItemInt(hDlg, IDC_CURVECOMPH, NULL, FALSE); config->curve_compression_low = GetDlgItemInt(hDlg, IDC_CURVECOMPL, NULL, FALSE); config->bitrate_payback_delay = config_get_int(hDlg, IDC_PAYBACK, config->bitrate_payback_delay); config->bitrate_payback_method = ISDLGSET(IDC_PAYBACKPROP); config->hinted_me = ISDLGSET(IDC_HINTEDME); if (GetDlgItemText(hDlg, IDC_HINTFILE, config->hintfile, MAX_PATH) == 0) { lstrcpy(config->hintfile, CONFIG_HINTFILE); } if (GetDlgItemText(hDlg, IDC_STATS1, config->stats1, MAX_PATH) == 0) { lstrcpy(config->stats1, CONFIG_2PASS_1_FILE); } if (GetDlgItemText(hDlg, IDC_STATS2, config->stats2, MAX_PATH) == 0) { lstrcpy(config->stats2, CONFIG_2PASS_2_FILE); } CONSTRAINVAL(config->bitrate_payback_delay, 1, 10000); CONSTRAINVAL(config->keyframe_boost, 0, 1000); CONSTRAINVAL(config->curve_compression_high, 0, 100); CONSTRAINVAL(config->curve_compression_low, 0, 100); break; case DLG_2PASSALT : config->use_alt_curve = ISDLGSET(IDC_USEALT); config->alt_curve_use_auto = ISDLGSET(IDC_USEAUTO); config->alt_curve_auto_str = config_get_int(hDlg, IDC_AUTOSTR, config->alt_curve_auto_str); config->alt_curve_use_auto_bonus_bias = ISDLGSET(IDC_USEAUTOBONUS); config->alt_curve_bonus_bias = config_get_int(hDlg, IDC_BONUSBIAS, config->alt_curve_bonus_bias); config->alt_curve_type = SendDlgItemMessage(hDlg, IDC_CURVETYPE, CB_GETCURSEL, 0, 0); config->alt_curve_high_dist = config_get_int(hDlg, IDC_ALTCURVEHIGH, config->alt_curve_high_dist); config->alt_curve_low_dist = config_get_int(hDlg, IDC_ALTCURVELOW, config->alt_curve_low_dist); config->alt_curve_min_rel_qual = config_get_int(hDlg, IDC_MINQUAL, config->alt_curve_min_rel_qual); config->twopass_max_bitrate /= CONFIG_KBPS; config->twopass_max_bitrate = config_get_int(hDlg, IDC_MAXBITRATE, config->twopass_max_bitrate); config->twopass_max_bitrate *= CONFIG_KBPS; config->twopass_max_overflow_improvement = config_get_int(hDlg, IDC_OVERIMP, config->twopass_max_overflow_improvement); config->twopass_max_overflow_degradation = config_get_int(hDlg, IDC_OVERDEG, config->twopass_max_overflow_degradation); CONSTRAINVAL(config->twopass_max_overflow_improvement, 1, 80); CONSTRAINVAL(config->twopass_max_overflow_degradation, 1, 80); break; case DLG_CREDITS : config->credits_start = ISDLGSET(IDC_CREDITS_START); config->credits_start_begin = GetDlgItemInt(hDlg, IDC_CREDITS_START_BEGIN, NULL, FALSE); config->credits_start_end = config_get_int(hDlg, IDC_CREDITS_START_END, config->credits_start_end); config->credits_end = ISDLGSET(IDC_CREDITS_END); config->credits_end_begin = config_get_int(hDlg, IDC_CREDITS_END_BEGIN, config->credits_end_begin); config->credits_end_end = config_get_int(hDlg, IDC_CREDITS_END_END, config->credits_end_end); config->credits_rate = config_get_int(hDlg, IDC_CREDITS_RATE, config->credits_rate); config->credits_quant_i = config_get_int(hDlg, IDC_CREDITS_QUANTI, config->credits_quant_i); config->credits_quant_p = config_get_int(hDlg, IDC_CREDITS_QUANTP, config->credits_quant_p); config->credits_start_size = config_get_int(hDlg, IDC_CREDITS_START_SIZE, config->credits_start_size); config->credits_end_size = config_get_int(hDlg, IDC_CREDITS_END_SIZE, config->credits_end_size); config->credits_mode = 0; config->credits_mode = ISDLGSET(IDC_CREDITS_RATE_RADIO) ? CREDITS_MODE_RATE : config->credits_mode; config->credits_mode = ISDLGSET(IDC_CREDITS_QUANT_RADIO) ? CREDITS_MODE_QUANT : config->credits_mode; config->credits_mode = ISDLGSET(IDC_CREDITS_SIZE_RADIO) ? CREDITS_MODE_SIZE : config->credits_mode; CONSTRAINVAL(config->credits_rate, 1, 100); CONSTRAINVAL(config->credits_quant_i, 1, 31); CONSTRAINVAL(config->credits_quant_p, 1, 31); if (config->credits_start_begin > config->credits_start_end) { config->credits_start_begin = config->credits_start_end; config->credits_start = 0; } if (config->credits_end_begin > config->credits_end_end) { config->credits_end_begin = config->credits_end_end; config->credits_end = 0; } break; case DLG_CPU : config->cpu = 0; config->cpu |= ISDLGSET(IDC_CPU_MMX) ? XVID_CPU_MMX : 0; config->cpu |= ISDLGSET(IDC_CPU_MMXEXT) ? XVID_CPU_MMXEXT: 0; config->cpu |= ISDLGSET(IDC_CPU_SSE) ? XVID_CPU_SSE: 0; config->cpu |= ISDLGSET(IDC_CPU_SSE2) ? XVID_CPU_SSE2: 0; config->cpu |= ISDLGSET(IDC_CPU_3DNOW) ? XVID_CPU_3DNOW: 0; config->cpu |= ISDLGSET(IDC_CPU_3DNOWEXT) ? XVID_CPU_3DNOWEXT: 0; config->cpu |= ISDLGSET(IDC_CPU_FORCE) ? XVID_CPU_FORCE : 0; break; } } void quant_upload(HWND hDlg, CONFIG* config) { int i; for (i=0 ; i<64 ; ++i) { SetDlgItemInt(hDlg, IDC_QINTRA00 + i, config->qmatrix_intra[i], FALSE); SetDlgItemInt(hDlg, IDC_QINTER00 + i, config->qmatrix_inter[i], FALSE); } } void quant_download(HWND hDlg, CONFIG* config) { int i; for (i=0 ; i<64 ; ++i) { int temp; temp = config_get_int(hDlg, i + IDC_QINTRA00, config->qmatrix_intra[i]); CONSTRAINVAL(temp, 1, 255); temp = config->qmatrix_intra[i]; temp = config_get_int(hDlg, i + IDC_QINTER00, config->qmatrix_inter[i]); CONSTRAINVAL(temp, 1, 255); temp = config->qmatrix_inter[i]; } } /* enumerates child windows, assigns tooltips */ BOOL CALLBACK enum_tooltips(HWND hWnd, LPARAM lParam) { char help[500]; if (LoadString(hInst, GetDlgCtrlID(hWnd), help, 500)) { TOOLINFO ti; ti.cbSize = sizeof(TOOLINFO); ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND; ti.hwnd = GetParent(hWnd); ti.uId = (LPARAM)hWnd; ti.lpszText = help; SendMessage(hTooltip, TTM_ADDTOOL, 0, (LPARAM)&ti); } return TRUE; } /* main dialog proc */ BOOL CALLBACK main_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CONFIG* config = (CONFIG*)GetWindowLong(hDlg, GWL_USERDATA); switch (uMsg) { case WM_INITDIALOG : SetWindowLong(hDlg, GWL_USERDATA, lParam); config = (CONFIG*)lParam; SendDlgItemMessage(hDlg, IDC_MODE, CB_ADDSTRING, 0, (LPARAM)"1 Pass - CBR"); SendDlgItemMessage(hDlg, IDC_MODE, CB_ADDSTRING, 0, (LPARAM)"1 Pass - quality"); SendDlgItemMessage(hDlg, IDC_MODE, CB_ADDSTRING, 0, (LPARAM)"1 Pass - quantizer"); SendDlgItemMessage(hDlg, IDC_MODE, CB_ADDSTRING, 0, (LPARAM)"2 Pass - 1st pass"); SendDlgItemMessage(hDlg, IDC_MODE, CB_ADDSTRING, 0, (LPARAM)"2 Pass - 2nd pass Ext."); SendDlgItemMessage(hDlg, IDC_MODE, CB_ADDSTRING, 0, (LPARAM)"2 Pass - 2nd pass Int."); SendDlgItemMessage(hDlg, IDC_MODE, CB_ADDSTRING, 0, (LPARAM)"Null - test speed"); SendDlgItemMessage(hDlg, IDC_MODE, CB_SETCURSEL, config->mode, 0); SetDlgItemInt(hDlg, IDC_CBRBUFFER, config->rc_buffersize, FALSE); InitCommonControls(); if (hTooltip = CreateWindow(TOOLTIPS_CLASS, NULL, TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL)) { SetWindowPos(hTooltip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); SendMessage(hTooltip, TTM_SETDELAYTIME, TTDT_AUTOMATIC, MAKELONG(1500, 0)); SendMessage(hTooltip, TTM_SETMAXTIPWIDTH, 0, 400); EnumChildWindows(hDlg, enum_tooltips, 0); } main_slider(hDlg, config); main_value(hDlg, config); break; case WM_HSCROLL : if((HWND)lParam == GetDlgItem(hDlg, IDC_SLIDER)) { SetDlgItemInt(hDlg, IDC_VALUE, SendMessage((HWND)lParam, TBM_GETPOS, 0, 0), FALSE); } else { return 0; } break; case WM_COMMAND : if (LOWORD(wParam) == IDC_MODE && HIWORD(wParam) == LBN_SELCHANGE) { main_download(hDlg, config); main_slider(hDlg, config); main_value(hDlg, config); } else if (LOWORD(wParam) == IDC_ADVANCED && HIWORD(wParam) == BN_CLICKED) { adv_dialog(hDlg, config); if (config->save) { config_reg_set(config); } } else if (LOWORD(wParam) == IDC_DEFAULTS && HIWORD(wParam) == BN_CLICKED) { config_reg_default(config); SendDlgItemMessage(hDlg, IDC_MODE, CB_SETCURSEL, config->mode, 0); SetDlgItemInt(hDlg, IDC_CBRBUFFER, config->rc_buffersize, FALSE); main_slider(hDlg, config); main_value(hDlg, config); } else if (HIWORD(wParam) == EN_UPDATE && LOWORD(wParam) == IDC_VALUE) { int value = config_get_int(hDlg, IDC_VALUE, 1); int max = 1; max = (config->mode == DLG_MODE_CBR) ? 10000 : ((config->mode == DLG_MODE_VBR_QUAL) ? 100 : ((config->mode == DLG_MODE_VBR_QUANT) ? 31 : 1<<30)); if (value < 1) { value = 1; } if (value > max) { value = max; SetDlgItemInt(hDlg, IDC_VALUE, value, FALSE); } if (config->mode != DLG_MODE_2PASS_2_INT) { SendDlgItemMessage(hDlg, IDC_SLIDER, TBM_SETPOS, TRUE, value); } } else if (LOWORD(wParam) == IDOK && HIWORD(wParam) == BN_CLICKED) { main_download(hDlg, config); config->save = TRUE; EndDialog(hDlg, IDOK); } else if (LOWORD(wParam) == IDCANCEL) { config->save = FALSE; EndDialog(hDlg, IDCANCEL); } break; default : return 0; } return 1; } /* advanced dialog proc */ BOOL CALLBACK adv_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { PROPSHEETINFO *psi; psi = (PROPSHEETINFO*)GetWindowLong(hDlg, GWL_USERDATA); switch (uMsg) { case WM_INITDIALOG : psi = (PROPSHEETINFO*) ((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLong(hDlg, GWL_USERDATA, (LPARAM)psi); if (psi->page == DLG_GLOBAL) { SendDlgItemMessage(hDlg, IDC_MOTION, CB_ADDSTRING, 0, (LPARAM)"0 - None"); SendDlgItemMessage(hDlg, IDC_MOTION, CB_ADDSTRING, 0, (LPARAM)"1 - Very Low"); SendDlgItemMessage(hDlg, IDC_MOTION, CB_ADDSTRING, 0, (LPARAM)"2 - Low"); SendDlgItemMessage(hDlg, IDC_MOTION, CB_ADDSTRING, 0, (LPARAM)"3 - Medium"); SendDlgItemMessage(hDlg, IDC_MOTION, CB_ADDSTRING, 0, (LPARAM)"4 - High"); SendDlgItemMessage(hDlg, IDC_MOTION, CB_ADDSTRING, 0, (LPARAM)"5 - Very High"); SendDlgItemMessage(hDlg, IDC_MOTION, CB_ADDSTRING, 0, (LPARAM)"6 - Ultra High"); SendDlgItemMessage(hDlg, IDC_QUANTTYPE, CB_ADDSTRING, 0, (LPARAM)"H.263"); SendDlgItemMessage(hDlg, IDC_QUANTTYPE, CB_ADDSTRING, 0, (LPARAM)"MPEG"); SendDlgItemMessage(hDlg, IDC_QUANTTYPE, CB_ADDSTRING, 0, (LPARAM)"MPEG-Custom"); SendDlgItemMessage(hDlg, IDC_QUANTTYPE, CB_ADDSTRING, 0, (LPARAM)"Modulated"); SendDlgItemMessage(hDlg, IDC_FOURCC, CB_ADDSTRING, 0, (LPARAM)"XVID"); SendDlgItemMessage(hDlg, IDC_FOURCC, CB_ADDSTRING, 0, (LPARAM)"DIVX"); SendDlgItemMessage(hDlg, IDC_FOURCC, CB_ADDSTRING, 0, (LPARAM)"DX50"); } else if (psi->page == DLG_2PASSALT) { SendDlgItemMessage(hDlg, IDC_CURVETYPE, CB_ADDSTRING, 0, (LPARAM)"Low"); SendDlgItemMessage(hDlg, IDC_CURVETYPE, CB_ADDSTRING, 0, (LPARAM)"Medium"); SendDlgItemMessage(hDlg, IDC_CURVETYPE, CB_ADDSTRING, 0, (LPARAM)"High"); } if (hTooltip) { EnumChildWindows(hDlg, enum_tooltips, 0); } adv_upload(hDlg, psi->page, psi->config); adv_mode(hDlg, psi->config->mode); break; case WM_COMMAND : if (HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case IDC_HINTEDME : case IDC_USEALT : case IDC_USEAUTO : case IDC_USEAUTOBONUS : case IDC_CREDITS_START : case IDC_CREDITS_END : case IDC_CREDITS_RATE_RADIO : case IDC_CREDITS_QUANT_RADIO : case IDC_CREDITS_SIZE_RADIO : case IDC_CPU_AUTO : case IDC_CPU_FORCE : adv_mode(hDlg, psi->config->mode); break; } } if ((LOWORD(wParam) == IDC_HINT_BROWSE || LOWORD(wParam) == IDC_STATS1_BROWSE || LOWORD(wParam) == IDC_STATS2_BROWSE) && HIWORD(wParam) == BN_CLICKED) { OPENFILENAME ofn; char tmp[MAX_PATH]; int hComponent = (LOWORD(wParam) == IDC_STATS1_BROWSE ? IDC_STATS1 : IDC_STATS2); GetDlgItemText(hDlg, hComponent, tmp, MAX_PATH); memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.lpstrFilter = "bitrate curve (*.stats)\0*.stats\0All files (*.*)\0*.*\0\0"; ofn.lpstrFile = tmp; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_PATHMUSTEXIST; if (LOWORD(wParam) == IDC_HINT_BROWSE) { ofn.lpstrFilter = "motion hints (*.mvh)\0*.mvh\0All files (*.*)\0*.*\0\0"; if (GetOpenFileName(&ofn)) { SetDlgItemText(hDlg, IDC_HINTFILE, tmp); } } else if (LOWORD(wParam) == IDC_STATS1_BROWSE && psi->config->mode == DLG_MODE_2PASS_1) { ofn.Flags |= OFN_OVERWRITEPROMPT; if (GetSaveFileName(&ofn)) { SetDlgItemText(hDlg, hComponent, tmp); } } else { ofn.Flags |= OFN_FILEMUSTEXIST; if (GetOpenFileName(&ofn)) { SetDlgItemText(hDlg, hComponent, tmp); } } } else if (LOWORD(wParam) == IDC_QUANTMATRIX && HIWORD(wParam) == BN_CLICKED) { DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_QUANTMATRIX), hDlg, quantmatrix_proc, (LPARAM)psi->config); } break; case WM_NOTIFY : switch (((NMHDR *)lParam)->code) { case PSN_KILLACTIVE : /* validate */ adv_download(hDlg, psi->page, psi->config); SetWindowLong(hDlg, DWL_MSGRESULT, FALSE); break; case PSN_APPLY : /* apply */ adv_download(hDlg, psi->page, psi->config); SetWindowLong(hDlg, DWL_MSGRESULT, FALSE); psi->config->save = TRUE; break; } break; default : return 0; } return 1; } /* quantization matrix dialog proc */ BOOL CALLBACK quantmatrix_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CONFIG* config = (CONFIG*)GetWindowLong(hDlg, GWL_USERDATA); switch (uMsg) { case WM_INITDIALOG : SetWindowLong(hDlg, GWL_USERDATA, lParam); config = (CONFIG*)lParam; quant_upload(hDlg, config); if (hTooltip) { EnumChildWindows(hDlg, enum_tooltips, 0); } break; case WM_COMMAND : if (LOWORD(wParam) == IDOK && HIWORD(wParam) == BN_CLICKED) { quant_download(hDlg, config); EndDialog(hDlg, IDOK); } else if (LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, IDCANCEL); } else if ((LOWORD(wParam) == IDC_LOAD || LOWORD(wParam) == IDC_SAVE) && HIWORD(wParam) == BN_CLICKED) { OPENFILENAME ofn; char file[MAX_PATH]; HANDLE hFile; DWORD read=128, wrote=0; BYTE quant_data[128]; strcpy(file, "\\matrix"); memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.lpstrFilter = "All files (*.*)\0*.*\0\0"; ofn.lpstrFile = file; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_PATHMUSTEXIST; if (LOWORD(wParam) == IDC_SAVE) { ofn.Flags |= OFN_OVERWRITEPROMPT; if (GetSaveFileName(&ofn)) { hFile = CreateFile(file, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); quant_download(hDlg, config); memcpy(quant_data, config->qmatrix_intra, 64); memcpy(quant_data+64, config->qmatrix_inter, 64); if (hFile == INVALID_HANDLE_VALUE) { DEBUGERR("Couldn't save quant matrix"); } else { if (!WriteFile(hFile, quant_data, 128, &wrote, 0)) { DEBUGERR("Couldnt write quant matrix"); } } CloseHandle(hFile); } } else { ofn.Flags |= OFN_FILEMUSTEXIST; if (GetOpenFileName(&ofn)) { hFile = CreateFile(file, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == INVALID_HANDLE_VALUE) { DEBUGERR("Couldn't load quant matrix"); } else { if (!ReadFile(hFile, quant_data, 128, &read, 0)) { DEBUGERR("Couldnt read quant matrix"); } else { memcpy(config->qmatrix_intra, quant_data, 64); memcpy(config->qmatrix_inter, quant_data+64, 64); quant_upload(hDlg, config); } } CloseHandle(hFile); } } } break; default : return 0; } return 1; } /* about dialog proc */ BOOL CALLBACK about_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG : { XVID_INIT_PARAM init_param; char core[100]; HFONT hFont; LOGFONT lfData; SetDlgItemText(hDlg, IDC_BUILD, XVID_BUILD); xvid_init(NULL, 0, &init_param, 0); wsprintf(core, "Core Version %d.%d", (init_param.api_version>>16),(init_param.api_version&0xFFFFU)); SetDlgItemText(hDlg, IDC_CORE, core); hFont = (HFONT)SendDlgItemMessage(hDlg, IDC_WEBSITE, WM_GETFONT, 0, 0L); if (GetObject(hFont, sizeof(LOGFONT), &lfData)) { lfData.lfUnderline = 1; hFont = CreateFontIndirect(&lfData); if (hFont) { SendDlgItemMessage(hDlg, IDC_WEBSITE, WM_SETFONT, (WPARAM)hFont, 1L); } } SetClassLong(GetDlgItem(hDlg, IDC_WEBSITE), GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_HAND)); SetDlgItemText(hDlg, IDC_WEBSITE, XVID_WEBSITE); } break; case WM_CTLCOLORSTATIC : if ((HWND)lParam == GetDlgItem(hDlg, IDC_WEBSITE)) { SetBkMode((HDC)wParam, TRANSPARENT) ; SetTextColor((HDC)wParam, RGB(0x00,0x00,0xc0)); return (BOOL)GetStockObject(NULL_BRUSH); } return 0; case WM_COMMAND : if (LOWORD(wParam) == IDC_WEBSITE && HIWORD(wParam) == STN_CLICKED) { ShellExecute(hDlg, "open", XVID_WEBSITE, NULL, NULL, SW_SHOWNORMAL); } else if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); } break; default : return 0; } return 1; } xvid_20020412/vfw/src/config.h0100644000100600001440000000721407454311135015334 0ustar michaelusers#ifndef _CONFIG_H_ #define _CONFIG_H_ #include HINSTANCE hInst; HWND hTooltip; /* small hack */ #ifndef IDC_HAND #define IDC_HAND MAKEINTRESOURCE(32649) #endif /* one kilobit */ #define CONFIG_KBPS 1000 /* registry stuff */ #define XVID_REG_KEY HKEY_CURRENT_USER #define XVID_REG_PARENT "Software\\GNU" #define XVID_REG_CHILD "XviD" #define XVID_REG_CLASS "config" #define XVID_BUILD __TIME__ ", " __DATE__ #define XVID_WEBSITE "http://www.xvid.org" /* constants */ #define CONFIG_HINTFILE "\\hintfile.mvh" #define CONFIG_2PASS_1_FILE "\\video.stats" #define CONFIG_2PASS_2_FILE "\\videogk.stats" /* property sheets - sheets can be reordered here */ #define DLG_COUNT 6 #define DLG_GLOBAL 0 #define DLG_QUANT 1 #define DLG_2PASS 2 #define DLG_2PASSALT 3 #define DLG_CREDITS 4 #define DLG_CPU 5 /* codec modes */ #define DLG_MODE_CBR 0 #define DLG_MODE_VBR_QUAL 1 #define DLG_MODE_VBR_QUANT 2 #define DLG_MODE_2PASS_1 3 #define DLG_MODE_2PASS_2_EXT 4 #define DLG_MODE_2PASS_2_INT 5 #define DLG_MODE_NULL 6 /* quantizer modes */ #define QUANT_MODE_H263 0 #define QUANT_MODE_MPEG 1 #define QUANT_MODE_CUSTOM 2 #define QUANT_MODE_MOD 3 /* credits modes */ #define CREDITS_MODE_RATE 0 #define CREDITS_MODE_QUANT 1 #define CREDITS_MODE_SIZE 2 #define CREDITS_START 1 #define CREDITS_END 2 #define RAD2DEG 57.295779513082320876798154814105 #define DEG2RAD 0.017453292519943295769236907684886 typedef struct { int mode; int bitrate; int quality; int quant; int rc_buffersize; int motion_search; int quant_type; int fourcc_used; int max_key_interval; int min_key_interval; int lum_masking; int interlacing; int min_iquant; int max_iquant; int min_pquant; int max_pquant; BYTE qmatrix_intra[64]; BYTE qmatrix_inter[64]; int desired_size; int keyframe_boost; int discard1pass; int dummy2pass; int curve_compression_high; int curve_compression_low; int use_alt_curve; int alt_curve_use_auto; int alt_curve_auto_str; int alt_curve_use_auto_bonus_bias; int alt_curve_bonus_bias; int alt_curve_type; int alt_curve_high_dist; int alt_curve_low_dist; int alt_curve_min_rel_qual; int twopass_max_bitrate; int twopass_max_overflow_improvement; int twopass_max_overflow_degradation; int bitrate_payback_delay; int bitrate_payback_method; int hinted_me; char hintfile[MAX_PATH]; char stats1[MAX_PATH]; char stats2[MAX_PATH]; int credits_start; int credits_start_begin; int credits_start_end; int credits_end; int credits_end_begin; int credits_end_end; int credits_mode; int credits_rate; int credits_quant_i; int credits_quant_p; int credits_start_size; int credits_end_size; // char build[50]; DWORD cpu; float fquant; BOOL save; } CONFIG; typedef struct PROPSHEETINFO { int page; CONFIG * config; } PROPSHEETINFO; typedef struct REG_INT { char* reg_value; int* config_int; int def; } REG_INT; typedef struct REG_STR { char* reg_value; char* config_str; char* def; } REG_STR; void config_reg_get(CONFIG *); void config_reg_set(CONFIG *); void config_reg_default(CONFIG *); int config_get_int(HWND, UINT, int); void main_download(HWND, CONFIG *); void main_slider(HWND, CONFIG *); void main_value(HWND, CONFIG *); void adv_dialog(HWND, CONFIG *); void adv_mode(HWND, int); void adv_upload(HWND, int, CONFIG *); void adv_download(HWND, int, CONFIG *); void quant_upload(HWND, CONFIG *); void quant_download(HWND, CONFIG *); BOOL CALLBACK enum_tooltips(HWND, LPARAM); BOOL CALLBACK main_proc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK adv_proc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK quantmatrix_proc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK about_proc(HWND, UINT, WPARAM, LPARAM); #endif /* _CONFIG_H_ */xvid_20020412/vfw/src/driverproc.c0100644000100600001440000001436107447023660016247 0ustar michaelusers/************************************************************************** * * XVID VFW FRONTEND * driverproc main * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 01.12.2001 inital version; (c)2001 peter ross * *************************************************************************/ #include #include #include "codec.h" #include "config.h" #include "resource.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { hInst = (HINSTANCE) hModule; return TRUE; } __declspec(dllexport) LRESULT WINAPI DriverProc( DWORD dwDriverId, HDRVR hDriver, UINT uMsg, LPARAM lParam1, LPARAM lParam2) { CODEC * codec = (CODEC *)dwDriverId; switch(uMsg) { /* driver primitives */ case DRV_LOAD : case DRV_FREE : DRV_OK; case DRV_OPEN : DEBUG("DRV_OPEN"); { ICOPEN * icopen = (ICOPEN *)lParam2; if (icopen != NULL && icopen->fccType != ICTYPE_VIDEO) { return DRV_CANCEL; } codec = malloc(sizeof(CODEC)); if (codec == NULL) { if (icopen != NULL) { icopen->dwError = ICERR_MEMORY; } return 0; } codec->ehandle = codec->dhandle = NULL; config_reg_get(&codec->config); /* bad things happen if this is uncommented if (lstrcmp(XVID_BUILD, codec->config.build)) { config_reg_default(&codec->config); } */ if (icopen != NULL) { icopen->dwError = ICERR_OK; } return (LRESULT)codec; } case DRV_CLOSE : DEBUG("DRV_CLOSE"); // compress_end/decompress_end don't always get called compress_end(codec); decompress_end(codec); free(codec); return DRV_OK; case DRV_DISABLE : case DRV_ENABLE : return DRV_OK; case DRV_INSTALL : case DRV_REMOVE : return DRV_OK; case DRV_QUERYCONFIGURE : case DRV_CONFIGURE : return DRV_CANCEL; /* info */ case ICM_GETINFO : DEBUG("ICM_GETINFO"); { ICINFO *icinfo = (ICINFO *)lParam1; icinfo->fccType = ICTYPE_VIDEO; icinfo->fccHandler = FOURCC_XVID; icinfo->dwFlags = VIDCF_FASTTEMPORALC | VIDCF_FASTTEMPORALD | VIDCF_COMPRESSFRAMES; icinfo->dwVersion = 0; icinfo->dwVersionICM = ICVERSION; wcscpy(icinfo->szName, XVID_NAME_L); wcscpy(icinfo->szDescription, XVID_DESC_L); return lParam2; /* size of struct */ } DEBUG("ICM_GETINFO end"); /* state control */ case ICM_ABOUT : DEBUG("ICM_ABOUT"); DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ABOUT), (HWND)lParam1, about_proc, 0); return ICERR_OK; case ICM_CONFIGURE : DEBUG("ICM_CONFIGURE"); if (lParam1 != -1) { CONFIG temp; codec->config.save = FALSE; memcpy(&temp, &codec->config, sizeof(CONFIG)); DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_MAIN), (HWND)lParam1, main_proc, (LPARAM)&temp); if (temp.save) { memcpy(&codec->config, &temp, sizeof(CONFIG)); config_reg_set(&codec->config); } } return ICERR_OK; case ICM_GETSTATE : DEBUG("ICM_GETSTATE"); if ((void*)lParam1 == NULL) { return sizeof(CONFIG); } memcpy((void*)lParam1, &codec->config, sizeof(CONFIG)); return ICERR_OK; case ICM_SETSTATE : DEBUG("ICM_SETSTATE"); if ((void*)lParam1 == NULL) { DEBUG("ICM_SETSTATE : DEFAULT"); config_reg_get(&codec->config); return 0; } memcpy(&codec->config,(void*)lParam1, sizeof(CONFIG)); return 0; // sizeof(CONFIG); /* not sure the difference, private/public data? */ case ICM_GET : case ICM_SET : return ICERR_OK; /* older-stype config */ case ICM_GETDEFAULTQUALITY : case ICM_GETQUALITY : case ICM_SETQUALITY : case ICM_GETBUFFERSWANTED : case ICM_GETDEFAULTKEYFRAMERATE : return ICERR_UNSUPPORTED; /* compressor */ case ICM_COMPRESS_QUERY : DEBUG("ICM_COMPRESS_QUERY"); return compress_query(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_GET_FORMAT : DEBUG("ICM_COMPRESS_GET_FORMAT"); return compress_get_format(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_GET_SIZE : DEBUG("ICM_COMPRESS_GET_SIZE"); return compress_get_size(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_FRAMES_INFO : DEBUG("ICM_COMPRESS_FRAMES_INFO"); return compress_frames_info(codec, (ICCOMPRESSFRAMES *)lParam1); case ICM_COMPRESS_BEGIN : DEBUG("ICM_COMPRESS_BEGIN"); return compress_begin(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_END : DEBUG("ICM_COMPRESS_END"); return compress_end(codec); case ICM_COMPRESS : DEBUG("ICM_COMPRESS"); return compress(codec, (ICCOMPRESS *)lParam1); /* decompressor */ case ICM_DECOMPRESS_QUERY : DEBUG("ICM_DECOMPRESS_QUERY"); return decompress_query(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_DECOMPRESS_GET_FORMAT : DEBUG("ICM_DECOMPRESS_GET_FORMAT"); return decompress_get_format(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_DECOMPRESS_BEGIN : DEBUG("ICM_DECOMPRESS_BEGIN"); return decompress_begin(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_DECOMPRESS_END : DEBUG("ICM_DECOMPRESS_END"); return decompress_end(codec); case ICM_DECOMPRESS : DEBUG("ICM_DECOMPRESS"); return decompress(codec, (ICDECOMPRESS *)lParam1); case ICM_DECOMPRESS_GET_PALETTE : case ICM_DECOMPRESS_SET_PALETTE : case ICM_DECOMPRESSEX_QUERY: case ICM_DECOMPRESSEX_BEGIN: case ICM_DECOMPRESSEX_END: case ICM_DECOMPRESSEX: return ICERR_UNSUPPORTED; default: return DefDriverProc(dwDriverId, hDriver, uMsg, lParam1, lParam2); } } xvid_20020412/vfw/src/xvid.h0100644000100600001440000001345307453333735015054 0ustar michaelusers#ifndef _XVID_H_ #define _XVID_H_ #ifdef __cplusplus extern "C" { #endif // ========================================== // global // ========================================== // API Version: 2.0 #define API_VERSION ((2 << 16) | (0)) // cpu features #define XVID_CPU_MMX 0x00000001 #define XVID_CPU_MMXEXT 0x00000002 #define XVID_CPU_SSE 0x00000004 #define XVID_CPU_SSE2 0x00000008 #define XVID_CPU_3DNOW 0x00000010 #define XVID_CPU_3DNOWEXT 0x00000020 #define XVID_CPU_TSC 0x00000040 #define XVID_CPU_FORCE 0x80000000 // colorspaces #define XVID_CSP_RGB24 0 #define XVID_CSP_YV12 1 #define XVID_CSP_YUY2 2 #define XVID_CSP_UYVY 3 #define XVID_CSP_I420 4 #define XVID_CSP_RGB555 10 #define XVID_CSP_RGB565 11 #define XVID_CSP_USER 12 #define XVID_CSP_YVYU 1002 #define XVID_CSP_RGB32 1000 #define XVID_CSP_NULL 9999 #define XVID_CSP_VFLIP 0x80000000 // flip mask // error #define XVID_ERR_FAIL -1 #define XVID_ERR_OK 0 #define XVID_ERR_MEMORY 1 #define XVID_ERR_FORMAT 2 typedef struct { int cpu_flags; int api_version; int core_build; } XVID_INIT_PARAM; int xvid_init(void *handle, int opt, void *param1, void *param2); // ========================================== // decoder // ========================================== #define XVID_QUICK_DECODE 0x00000010 /* increases decoding speed but reduces quality */ typedef struct { int width; int height; void *handle; } XVID_DEC_PARAM; typedef struct { int general; void * bitstream; int length; void * image; int stride; int colorspace; } XVID_DEC_FRAME; // decoder options #define XVID_DEC_DECODE 0 #define XVID_DEC_CREATE 1 #define XVID_DEC_DESTROY 2 int xvid_decore(void * handle, int opt, void * param1, void * param2); // ========================================== // encoder // ========================================== /* Do not rely on the VALUES of these constants, they may be changed at any time */ #define XVID_VALID_FLAGS 0x80000000 #define XVID_CUSTOM_QMATRIX 0x00000004 /* use custom quant matrix */ #define XVID_H263QUANT 0x00000010 #define XVID_MPEGQUANT 0x00000020 #define XVID_HALFPEL 0x00000040 /* use halfpel interpolation */ #define XVID_ADAPTIVEQUANT 0x00000080 #define XVID_LUMIMASKING 0x00000100 #define XVID_LATEINTRA 0x00000200 #define XVID_INTERLACING 0x00000400 /* enable interlaced encoding */ #define XVID_TOPFIELDFIRST 0x00000800 /* set top-field-first flag (cosmetic only) */ #define XVID_ALTERNATESCAN 0x00001000 /* ?? sets alternate vertical scan flag */ #define XVID_HINTEDME_GET 0x00002000 /* receive mv hint data from core (1st pass) */ #define XVID_HINTEDME_SET 0x00004000 /* send mv hint data to core (2nd pass) */ #define XVID_INTER4V 0x00008000 #define XVID_ME_ZERO 0x00010000 #define XVID_ME_LOGARITHMIC 0x00020000 #define XVID_ME_FULLSEARCH 0x00040000 #define XVID_ME_PMVFAST 0x00080000 #define XVID_ME_EPZS 0x00100000 #define PMV_HALFPELDIAMOND16 0x00010000 #define PMV_HALFPELREFINE16 0x00020000 #define PMV_EXTSEARCH16 0x00040000 /* extend PMV by more searches */ #define PMV_EARLYSTOP16 0x00080000 #define PMV_QUICKSTOP16 0x00100000 /* like early, but without any more refinement */ #define PMV_UNRESTRICTED16 0x00200000 /* unrestricted ME, not implemented */ #define PMV_OVERLAPPING16 0x00400000 /* overlapping ME, not implemented */ #define PMV_USESQUARES16 0x00800000 #define PMV_HALFPELDIAMOND8 0x01000000 #define PMV_HALFPELREFINE8 0x02000000 #define PMV_EXTSEARCH8 0x04000000 /* extend PMV by more searches */ #define PMV_EARLYSTOP8 0x08000000 #define PMV_QUICKSTOP8 0x10000000 /* like early, but without any more refinement */ #define PMV_UNRESTRICTED8 0x20000000 /* unrestricted ME, not implemented */ #define PMV_OVERLAPPING8 0x40000000 /* overlapping ME, not implemented */ #define PMV_USESQUARES8 0x80000000 typedef struct { int width, height; int fincr, fbase; // frame increment, fbase. each frame = "fincr/fbase" seconds int bitrate; // the bitrate of the target encoded stream, in bits/second int rc_buffersize; // the rate control buffersize / max. allowed deviation int max_quantizer; // the upper limit of the quantizer int min_quantizer; // the lower limit of the quantizer int max_key_interval; // the maximum interval between key frames void * handle; // [out] encoder instance handle } XVID_ENC_PARAM; typedef struct { int x; int y; } VECTOR; typedef struct { int mode; // macroblock mode VECTOR mvs[4]; } MVBLOCKHINT; typedef struct { int intra; // frame intra choice int fcode; // frame fcode MVBLOCKHINT * block; // caller-allocated array of block hints (mb_width * mb_height) } MVFRAMEHINT; typedef struct { int rawhints; // if set, use MVFRAMEHINT, else use compressed buffer MVFRAMEHINT mvhint; void * hintstream; // compressed hint buffer int hintlength; // length of buffer (bytes) } HINTINFO; typedef struct { int general; // [in] general options int motion; // [in] ME options void * bitstream; // [in] bitstream ptr int length; // [out] bitstream length (bytes) void * image; // [in] image ptr int colorspace; // [in] source colorspace unsigned char *quant_intra_matrix; // [in] custom intra qmatrix unsigned char *quant_inter_matrix; // [in] custom inter qmatrix int quant; // [in] frame quantizer (vbr) int intra; // [in] force intra frame (vbr only) // [out] intra state HINTINFO hint; // [in/out] mv hint information } XVID_ENC_FRAME; typedef struct { int quant; // [out] frame quantizer int hlength; // [out] header length (bytes) int kblks, mblks, ublks; // [out] } XVID_ENC_STATS; #define XVID_ENC_ENCODE 0 #define XVID_ENC_CREATE 1 #define XVID_ENC_DESTROY 2 int xvid_encore(void * handle, int opt, void * param1, void * param2); #ifdef __cplusplus } #endif #endif /* _XVID_H_ */ xvid_20020412/vfw/src/2pass.c0100644000100600001440000010300307454311135015103 0ustar michaelusers/************************************************************************** * * XVID 2PASS CODE * codec * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 07.04.2002 added max bitrate constraint, overflow controls (foxer) * 31.03.2002 inital version; * *************************************************************************/ #include #include #include "2pass.h" int codec_2pass_init(CODEC* codec) { TWOPASS *twopass = &codec->twopass; DWORD version = -20; DWORD read, wrote; int frames = 0, credits_frames = 0, i_frames = 0; __int64 total_ext = 0, total = 0, i_total = 0, i_boost_total = 0, start = 0, end = 0, start_curved = 0, end_curved = 0; __int64 desired = (__int64)codec->config.desired_size * 1024; double total1 = 0.0; double total2 = 0.0; if (codec->config.hinted_me) { codec->twopass.hintstream = malloc(100000); if (codec->twopass.hintstream == NULL) { DEBUGERR("couldn't allocate memory for mv hints"); return ICERR_ERROR; } } switch (codec->config.mode) { case DLG_MODE_2PASS_1 : twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (twopass->stats1 == INVALID_HANDLE_VALUE) { DEBUGERR("2pass init error - couldn't create stats1"); return ICERR_ERROR; } if (WriteFile(twopass->stats1, &version, sizeof(DWORD), &wrote, 0) == 0 || wrote != sizeof(DWORD)) { CloseHandle(twopass->stats1); twopass->stats1 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - couldn't write to stats1"); return ICERR_ERROR; } break; case DLG_MODE_2PASS_2_INT : case DLG_MODE_2PASS_2_EXT : twopass->stats1 = CreateFile(codec->config.stats1, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (twopass->stats1 == INVALID_HANDLE_VALUE) { DEBUGERR("2pass init error - couldn't open stats1"); return ICERR_ERROR; } if (ReadFile(twopass->stats1, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD)) { CloseHandle(twopass->stats1); twopass->stats1 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - couldn't read from stats1"); return ICERR_ERROR; } if (version != -20) { CloseHandle(twopass->stats1); twopass->stats1 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - wrong .stats version"); return ICERR_ERROR; } if (codec->config.mode == DLG_MODE_2PASS_2_EXT) { if (twopass->stats2 != INVALID_HANDLE_VALUE) { CloseHandle(twopass->stats2); } twopass->stats2 = CreateFile(codec->config.stats2, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (twopass->stats2 == INVALID_HANDLE_VALUE) { CloseHandle(twopass->stats1); twopass->stats1 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - couldn't open stats2"); return ICERR_ERROR; } if (ReadFile(twopass->stats2, &version, sizeof(DWORD), &read, 0) == 0 || read != sizeof(DWORD)) { CloseHandle(twopass->stats1); twopass->stats1 = INVALID_HANDLE_VALUE; CloseHandle(twopass->stats2); twopass->stats2 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - couldn't read from stats2"); return ICERR_ERROR; } if (version != -20) { CloseHandle(twopass->stats1); twopass->stats1 = INVALID_HANDLE_VALUE; CloseHandle(twopass->stats2); twopass->stats2 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - wrong .stats version"); return ICERR_ERROR; } while (1) { if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) || !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS)) { DWORD err = GetLastError(); if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS) { break; } else { CloseHandle(twopass->stats1); CloseHandle(twopass->stats2); twopass->stats1 = INVALID_HANDLE_VALUE; twopass->stats2 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - incomplete stats1/stats2 record?"); return ICERR_ERROR; } } if (!codec_is_in_credits(&codec->config, frames)) { if (twopass->nns1.quant & NNSTATS_KEYFRAME) { i_boost_total = twopass->nns2.bytes * codec->config.keyframe_boost / 100; i_total += twopass->nns2.bytes; ++i_frames; } total += twopass->nns1.bytes; total_ext += twopass->nns2.bytes; } else ++credits_frames; ++frames; } twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext); twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve); SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN); SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN); // perform prepass to compensate for over/undersizing frames = 0; if (codec->config.use_alt_curve) { twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0; twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low; twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0; twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame; if (codec->config.alt_curve_use_auto) { if (total > total_ext) { codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / ((double)total / (double)total_ext)) * (double)codec->config.alt_curve_auto_str / 100.0); if (codec->config.alt_curve_min_rel_qual < 20) codec->config.alt_curve_min_rel_qual = 20; } else codec->config.alt_curve_min_rel_qual = 100; } twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0; twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual; if (codec->config.alt_curve_low_dist > 100) { switch(codec->config.alt_curve_type) { case 2: // Sine Curve (high aggressiveness) twopass->alt_curve_qual_dev *= 2.0 / (1.0 + sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))); twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev * sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)); break; case 1: // Linear (medium aggressiveness) twopass->alt_curve_qual_dev *= 2.0 / (1.0 + twopass->average_frame / twopass->alt_curve_low_diff); twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev * twopass->average_frame / twopass->alt_curve_low_diff; break; case 0: // Cosine Curve (low aggressiveness) twopass->alt_curve_qual_dev *= 2.0 / (1.0 + (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)))); twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))); } } } while (1) { if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS) || !ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS)) { DWORD err = GetLastError(); if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS) { break; } else { CloseHandle(twopass->stats1); CloseHandle(twopass->stats2); twopass->stats1 = INVALID_HANDLE_VALUE; twopass->stats2 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - incomplete stats1/stats2 record?"); return ICERR_ERROR; } } if (!codec_is_in_credits(&codec->config, frames) && !(twopass->nns1.quant & NNSTATS_KEYFRAME)) { double dbytes = twopass->nns2.bytes / twopass->movie_curve; total1 += dbytes; if (codec->config.use_alt_curve) { if (dbytes > twopass->average_frame) { if (dbytes >= twopass->alt_curve_high) total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev); else { switch(codec->config.alt_curve_type) { case 2: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))); break; case 1: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff); break; case 0: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)))); } } } else { if (dbytes <= twopass->alt_curve_low) total2 += dbytes; else { switch(codec->config.alt_curve_type) { case 2: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))); break; case 1: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff); break; case 0: total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)))); } } } } else { if (dbytes > twopass->average_frame) { total2 += ((double)dbytes + (twopass->average_frame - dbytes) * codec->config.curve_compression_high / 100.0); } else { total2 += ((double)dbytes + (twopass->average_frame - dbytes) * codec->config.curve_compression_low / 100.0); } } } ++frames; } twopass->curve_comp_scale = total1 / total2; if (!codec->config.use_alt_curve) { int asymmetric_average_frame; char s[100]; asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale); wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame); DEBUG2P(s); } SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN); SetFilePointer(twopass->stats2, sizeof(DWORD), 0, FILE_BEGIN); } else // DLG_MODE_2PASS_2_INT { while (1) { if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS)) { DWORD err = GetLastError(); if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS) { break; } else { CloseHandle(twopass->stats1); twopass->stats1 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - incomplete stats2 record?"); return ICERR_ERROR; } } if (codec_is_in_credits(&codec->config, frames) == CREDITS_START) { start += twopass->nns1.bytes; ++credits_frames; } else if (codec_is_in_credits(&codec->config, frames) == CREDITS_END) { end += twopass->nns1.bytes; ++credits_frames; } else if (twopass->nns1.quant & NNSTATS_KEYFRAME) { i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100; total += twopass->nns1.bytes * codec->config.keyframe_boost / 100; ++i_frames; } total += twopass->nns1.bytes; ++frames; } // compensate for avi frame overhead desired -= frames * 24; switch (codec->config.credits_mode) { case CREDITS_MODE_RATE : // credits curve = (total / desired_size) * (100 / credits_rate) twopass->credits_start_curve = twopass->credits_end_curve = ((double)total / desired) * ((double)100 / codec->config.credits_rate); start_curved = (__int64)(start / twopass->credits_start_curve); end_curved = (__int64)(end / twopass->credits_end_curve); // movie curve = (total - credits) / (desired_size - curved credits) twopass->movie_curve = (double) (total - start - end) / (desired - start_curved - end_curved); break; case CREDITS_MODE_QUANT : // movie curve = (total - credits) / (desired_size - credits) twopass->movie_curve = (double) (total - start - end) / (desired - start - end); // aid the average asymmetric frame calculation below start_curved = start; end_curved = end; break; case CREDITS_MODE_SIZE : // start curve = (start / start desired size) twopass->credits_start_curve = (double) (start / 1024) / codec->config.credits_start_size; // end curve = (end / end desired size) twopass->credits_end_curve = (double) (end / 1024) / codec->config.credits_end_size; start_curved = (__int64)(start / twopass->credits_start_curve); end_curved = (__int64)(end / twopass->credits_end_curve); // movie curve = (total - credits) / (desired_size - curved credits) twopass->movie_curve = (double) (total - start - end) / (desired - start_curved - end_curved); break; } // average frame size = (desired - curved credits - curved keyframes) / // (frames - credits frames - keyframes) twopass->average_frame = (double) (desired - start_curved - end_curved - (i_total / twopass->movie_curve)) / (frames - credits_frames - i_frames); SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN); // perform prepass to compensate for over/undersizing frames = 0; if (codec->config.use_alt_curve) { twopass->alt_curve_low = twopass->average_frame - twopass->average_frame * (double)codec->config.alt_curve_low_dist / 100.0; twopass->alt_curve_low_diff = twopass->average_frame - twopass->alt_curve_low; twopass->alt_curve_high = twopass->average_frame + twopass->average_frame * (double)codec->config.alt_curve_high_dist / 100.0; twopass->alt_curve_high_diff = twopass->alt_curve_high - twopass->average_frame; if (codec->config.alt_curve_use_auto) { if (twopass->movie_curve > 1.0) { codec->config.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / twopass->movie_curve) * (double)codec->config.alt_curve_auto_str / 100.0); if (codec->config.alt_curve_min_rel_qual < 20) codec->config.alt_curve_min_rel_qual = 20; } else codec->config.alt_curve_min_rel_qual = 100; } twopass->alt_curve_mid_qual = (1.0 + (double)codec->config.alt_curve_min_rel_qual / 100.0) / 2.0; twopass->alt_curve_qual_dev = 1.0 - twopass->alt_curve_mid_qual; if (codec->config.alt_curve_low_dist > 100) { switch(codec->config.alt_curve_type) { case 2: // Sine Curve (high aggressiveness) twopass->alt_curve_qual_dev *= 2.0 / (1.0 + sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))); twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev * sin(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)); break; case 1: // Linear (medium aggressiveness) twopass->alt_curve_qual_dev *= 2.0 / (1.0 + twopass->average_frame / twopass->alt_curve_low_diff); twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev * twopass->average_frame / twopass->alt_curve_low_diff; break; case 0: // Cosine Curve (low aggressiveness) twopass->alt_curve_qual_dev *= 2.0 / (1.0 + (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff)))); twopass->alt_curve_mid_qual = 1.0 - twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * (twopass->average_frame * 90.0 / twopass->alt_curve_low_diff))); } } } while (1) { if (!ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, NULL) || read != sizeof(NNSTATS)) { DWORD err = GetLastError(); if (err == ERROR_HANDLE_EOF || err == ERROR_SUCCESS) { break; } else { CloseHandle(twopass->stats1); twopass->stats1 = INVALID_HANDLE_VALUE; DEBUGERR("2pass init error - incomplete stats2 record?"); return ICERR_ERROR; } } if (!codec_is_in_credits(&codec->config, frames) && !(twopass->nns1.quant & NNSTATS_KEYFRAME)) { double dbytes = twopass->nns1.bytes / twopass->movie_curve; total1 += dbytes; if (codec->config.use_alt_curve) { if (dbytes > twopass->average_frame) { if (dbytes >= twopass->alt_curve_high) total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev); else { switch(codec->config.alt_curve_type) { case 2: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))); break; case 1: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff); break; case 0: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)))); } } } else { if (dbytes <= twopass->alt_curve_low) total2 += dbytes; else { switch(codec->config.alt_curve_type) { case 2: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))); break; case 1: total2 += dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff); break; case 0: total2 += dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)))); } } } } else { if (dbytes > twopass->average_frame) { total2 += ((double)dbytes + (twopass->average_frame - dbytes) * codec->config.curve_compression_high / 100.0); } else { total2 += ((double)dbytes + (twopass->average_frame - dbytes) * codec->config.curve_compression_low / 100.0); } } } ++frames; } twopass->curve_comp_scale = total1 / total2; if (!codec->config.use_alt_curve) { int asymmetric_average_frame; char s[100]; asymmetric_average_frame = (int)(twopass->average_frame * twopass->curve_comp_scale); wsprintf(s, "middle frame size for asymmetric curve compression: %i", asymmetric_average_frame); DEBUG2P(s); } SetFilePointer(twopass->stats1, sizeof(DWORD), 0, FILE_BEGIN); } if (codec->config.use_alt_curve) { if (codec->config.alt_curve_use_auto_bonus_bias) codec->config.alt_curve_bonus_bias = codec->config.alt_curve_min_rel_qual; twopass->curve_bias_bonus = (total1 - total2) * (double)codec->config.alt_curve_bonus_bias / 100.0 / (double)(frames - credits_frames - i_frames); twopass->curve_comp_scale = ((total1 - total2) * (1.0 - (double)codec->config.alt_curve_bonus_bias / 100.0) + total2) / total2; // special info for alt curve: bias bonus and quantizer thresholds, { double curve_temp, dbytes; char s[100]; int i, newquant, percent; int oldquant = 1; wsprintf(s, "avg scaled framesize:%i", (int)(twopass->average_frame)); DEBUG2P(s); wsprintf(s, "bias bonus:%i bytes", (int)(twopass->curve_bias_bonus)); DEBUG2P(s); for (i=1; i <= (int)(twopass->alt_curve_high*2)+1; i++) { dbytes = i; if (dbytes > twopass->average_frame) { if (dbytes >= twopass->alt_curve_high) curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev); else { switch(codec->config.alt_curve_type) { case 2: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))); break; case 1: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff); break; case 0: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)))); } } } else { if (dbytes <= twopass->alt_curve_low) curve_temp = dbytes; else { switch(codec->config.alt_curve_type) { case 2: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))); break; case 1: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff); break; case 0: curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)))); } } } if (twopass->movie_curve > 1.0) dbytes *= twopass->movie_curve; newquant = (int)(dbytes * 2.0 / (curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus)); if (newquant > 1) { if (newquant != oldquant) { oldquant = newquant; percent = (int)((i - twopass->average_frame) * 100.0 / twopass->average_frame); wsprintf(s, "quant:%i threshold at %i : %i percent", newquant, i, percent); DEBUG2P(s); } } } } } twopass->overflow = 0; break; } return ICERR_OK; } int codec_2pass_get_quant(CODEC* codec, XVID_ENC_FRAME* frame) { static double quant_error[32]; static double curve_comp_error; static int last_quant; TWOPASS * twopass = &codec->twopass; DWORD read; int bytes1, bytes2; int overflow; int credits_pos; int capped_to_max_framesize = 0; if (codec->framenum == 0) { int i; for (i=0 ; i<32 ; ++i) { quant_error[i] = 0.0; twopass->quant_count[i] = 0; } curve_comp_error = 0.0; last_quant = 0; } if (ReadFile(twopass->stats1, &twopass->nns1, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS)) { DEBUGERR("2ndpass quant: couldn't read from stats1"); return ICERR_ERROR; } if (codec->config.mode == DLG_MODE_2PASS_2_EXT) { if (ReadFile(twopass->stats2, &twopass->nns2, sizeof(NNSTATS), &read, 0) == 0 || read != sizeof(NNSTATS)) { DEBUGERR("2ndpass quant: couldn't read from stats2"); return ICERR_ERROR; } } bytes1 = twopass->nns1.bytes; overflow = twopass->overflow / 8; // override codec i-frame choice (reenable in credits) frame->intra = (twopass->nns1.quant & NNSTATS_KEYFRAME); if (frame->intra) { overflow = 0; } credits_pos = codec_is_in_credits(&codec->config, codec->framenum); if (credits_pos) { if (codec->config.mode == DLG_MODE_2PASS_2_INT) { switch (codec->config.credits_mode) { case CREDITS_MODE_RATE : case CREDITS_MODE_SIZE : if (credits_pos == CREDITS_START) { bytes2 = (int)(bytes1 / twopass->credits_start_curve); } else // CREDITS_END { bytes2 = (int)(bytes1 / twopass->credits_end_curve); } frame->intra = -1; break; case CREDITS_MODE_QUANT : if (codec->config.credits_quant_i != codec->config.credits_quant_p) { frame->quant = frame->intra ? codec->config.credits_quant_i : codec->config.credits_quant_p; } else { frame->quant = codec->config.credits_quant_p; frame->intra = -1; } twopass->bytes1 = bytes1; twopass->bytes2 = bytes1; twopass->desired_bytes2 = bytes1; return ICERR_OK; } } else // DLG_MODE_2PASS_2_EXT { bytes2 = twopass->nns2.bytes; } } else // Foxer: apply curve compression outside credits { double dbytes, curve_temp; bytes2 = (codec->config.mode == DLG_MODE_2PASS_2_INT) ? bytes1 : twopass->nns2.bytes; if (frame->intra) { dbytes = ((int)(bytes2 + bytes2 * codec->config.keyframe_boost / 100)) / twopass->movie_curve; } else { dbytes = bytes2 / twopass->movie_curve; } // spread the compression error across payback_delay frames if (codec->config.bitrate_payback_method == 0) { bytes2 = (int)(curve_comp_error / codec->config.bitrate_payback_delay); } else { bytes2 = (int)(curve_comp_error * dbytes / twopass->average_frame / codec->config.bitrate_payback_delay); if (labs(bytes2) > fabs(curve_comp_error)) { bytes2 = (int)curve_comp_error; } } curve_comp_error -= bytes2; if (codec->config.use_alt_curve) { if (!frame->intra) { if (dbytes > twopass->average_frame) { if (dbytes >= twopass->alt_curve_high) curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev); else { switch(codec->config.alt_curve_type) { case 2: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff))); break; case 1: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (dbytes - twopass->average_frame) / twopass->alt_curve_high_diff); break; case 0: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_high_diff)))); } } } else { if (dbytes <= twopass->alt_curve_low) curve_temp = dbytes; else { switch(codec->config.alt_curve_type) { case 2: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff))); break; case 1: curve_temp = dbytes * (twopass->alt_curve_mid_qual - twopass->alt_curve_qual_dev * (dbytes - twopass->average_frame) / twopass->alt_curve_low_diff); break; case 0: curve_temp = dbytes * (twopass->alt_curve_mid_qual + twopass->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass->average_frame) * 90.0 / twopass->alt_curve_low_diff)))); } } } curve_temp = curve_temp * twopass->curve_comp_scale + twopass->curve_bias_bonus; bytes2 += ((int)curve_temp); curve_comp_error += curve_temp - ((int)curve_temp); } else { curve_comp_error += dbytes - ((int)dbytes); bytes2 += ((int)dbytes); } } else if ((codec->config.curve_compression_high + codec->config.curve_compression_low) && !frame->intra) { if (dbytes > twopass->average_frame) { curve_temp = twopass->curve_comp_scale * ((double)dbytes + (twopass->average_frame - dbytes) * codec->config.curve_compression_high / 100.0); } else { curve_temp = twopass->curve_comp_scale * ((double)dbytes + (twopass->average_frame - dbytes) * codec->config.curve_compression_low / 100.0); } bytes2 += ((int)curve_temp); curve_comp_error += curve_temp - ((int)curve_temp); } else { curve_comp_error += dbytes - ((int)dbytes); bytes2 += ((int)dbytes); } // cap bytes2 to first pass size, lowers number of quant=1 frames if (bytes2 > bytes1) { curve_comp_error += bytes2 - bytes1; bytes2 = bytes1; } else if (bytes2 < 1) { curve_comp_error += --bytes2; bytes2 = 1; } } twopass->desired_bytes2 = bytes2; // Foxer: scale overflow in relation to average size, so smaller frames don't get // too much/little bitrate overflow = (int)((double)overflow * bytes2 / twopass->average_frame); // Foxer: reign in overflow with huge frames if (labs(overflow) > labs(twopass->overflow)) { overflow = twopass->overflow; } // Foxer: make sure overflow doesn't run away if (overflow > bytes2 * codec->config.twopass_max_overflow_improvement / 100) { bytes2 += (overflow <= bytes2) ? bytes2 * codec->config.twopass_max_overflow_improvement / 100 : overflow * codec->config.twopass_max_overflow_improvement / 100; } else if (overflow < bytes2 * codec->config.twopass_max_overflow_degradation / -100) { bytes2 += bytes2 * codec->config.twopass_max_overflow_degradation / -100; } else { bytes2 += overflow; } if (bytes2 > twopass->max_framesize) { capped_to_max_framesize = 1; bytes2 = twopass->max_framesize; } if (bytes2 < 1) { bytes2 = 1; } twopass->bytes1 = bytes1; twopass->bytes2 = bytes2; // very 'simple' quant<->filesize relationship frame->quant = ((twopass->nns1.quant & ~NNSTATS_KEYFRAME) * bytes1) / bytes2; if (frame->quant < 1) { frame->quant = 1; } else if (frame->quant > 31) { frame->quant = 31; } else if (!frame->intra) { // Foxer: aid desired quantizer precision by accumulating decision error quant_error[frame->quant] += ((double)((twopass->nns1.quant & ~NNSTATS_KEYFRAME) * bytes1) / bytes2) - frame->quant; if (quant_error[frame->quant] >= 1.0) { quant_error[frame->quant] -= 1.0; ++frame->quant; } } // we're done with credits if (codec_is_in_credits(&codec->config, codec->framenum)) { return ICERR_OK; } if (frame->intra) { if (frame->quant < codec->config.min_iquant) { frame->quant = codec->config.min_iquant; DEBUG2P("I-frame quantizer raised"); } if (frame->quant > codec->config.max_iquant) { frame->quant = codec->config.max_iquant; DEBUG2P("I-frame quantizer lowered"); } } else { if (frame->quant > codec->config.max_pquant) { frame->quant = codec->config.max_pquant; } if (frame->quant < codec->config.min_pquant) { frame->quant = codec->config.min_pquant; } // subsequent frame quants can only be +- 2 if (last_quant && capped_to_max_framesize == 0) { if (frame->quant > last_quant + 2) { frame->quant = last_quant + 2; DEBUG2P("P-frame quantizer prevented from rising too steeply"); } if (frame->quant < last_quant - 2) { frame->quant = last_quant - 2; DEBUG2P("P-frame quantizer prevented from falling too steeply"); } } } if (capped_to_max_framesize == 0) last_quant = frame->quant; if (codec->config.quant_type == QUANT_MODE_MOD) { frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT; frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT; } return ICERR_OK; } int codec_2pass_update(CODEC* codec, XVID_ENC_FRAME* frame, XVID_ENC_STATS* stats) { static __int64 total_size; NNSTATS nns1; DWORD wrote; int credits_pos; char* quant_type; if (codec->framenum == 0) { total_size = 0; } quant_type = (frame->general & XVID_H263QUANT) ? "H.263" : ((frame->general & XVID_MPEGQUANT) && (frame->general & XVID_CUSTOM_QMATRIX)) ? "Cust" : "MPEG"; switch (codec->config.mode) { case DLG_MODE_2PASS_1 : nns1.bytes = frame->length; // total bytes nns1.dd_v = stats->hlength; // header bytes nns1.dd_u = nns1.dd_y = 0; nns1.dk_v = nns1.dk_u = nns1.dk_y = 0; nns1.md_u = nns1.md_y = 0; nns1.mk_u = nns1.mk_y = 0; nns1.quant = stats->quant; if (frame->intra) { nns1.quant |= NNSTATS_KEYFRAME; } nns1.kblk = stats->kblks; nns1.mblk = stats->mblks; nns1.ublk = stats->ublks; nns1.lum_noise[0] = nns1.lum_noise[1] = 1; total_size += frame->length; DEBUG1ST(frame->length, (int)total_size/1024, frame->intra, frame->quant, quant_type, stats->kblks, stats->mblks) if (WriteFile(codec->twopass.stats1, &nns1, sizeof(NNSTATS), &wrote, 0) == 0 || wrote != sizeof(NNSTATS)) { DEBUGERR("stats1: WriteFile error"); return ICERR_ERROR; } break; case DLG_MODE_2PASS_2_INT : case DLG_MODE_2PASS_2_EXT : codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length; credits_pos = codec_is_in_credits(&codec->config, codec->framenum); if (!credits_pos) codec->twopass.quant_count[frame->quant]++; DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos) break; default: break; } return ICERR_OK; } void codec_2pass_finish(CODEC* codec) { int i; char s[100]; if (codec->config.mode == DLG_MODE_2PASS_2_EXT || codec->config.mode == DLG_MODE_2PASS_2_INT) { // output the quantizer distribution for this encode. OutputDebugString("Quantizer distribution for 2nd pass:"); for (i=1; i<=31; i++) { if (codec->twopass.quant_count[i]) { wsprintf(s, "Q:%i:%i", i, codec->twopass.quant_count[i]); OutputDebugString(s); } } return; } }xvid_20020412/vfw/src/2pass.h0100644000100600001440000000041107453511751015114 0ustar michaelusers#ifndef _2PASS_H_ #define _2PASS_H_ #include "codec.h" int codec_2pass_init(CODEC *); int codec_2pass_get_quant(CODEC *, XVID_ENC_FRAME *); int codec_2pass_update(CODEC *, XVID_ENC_FRAME *, XVID_ENC_STATS *); void codec_2pass_finish(CODEC *); #endif // _2PASS_H_xvid_20020412/vfw/src/XviD_logo.bmp0100644000100600001440000001140607442022763016311 0ustar michaelusersBMv(, 1F`"++W00mMM333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333DEUDC33333333333334DETDC334DUDD333333333333333333DEUUUUUUUUUUUUUUUUTD334DEUDC334DEUUUTDC333333333333303333DVffeTC333333333333DVfffTC3EfffeD33333333333333334VffffffffffffffffffeD3DVfffTC3EVffffffTC33333333333303334EgffwfTC3333333333DVwiwfDDVvvTC333333333333333EgiveDFgivTDVvwfTC3333333333303334WvTC333333334VwgdEfeC333333333333333FhDDDDDDDDDDDDDDDDvUfHeEfDDDHfT3333333333303335fC34vTC3333334Eg334vUh34fT333333333333334VD33333333333333333HfhC34vVh333334eD33333333330333EkB"#4vTC33333Egx3""#Vz2#HT33DD33333333334Wfz2"#Hf2""""#4weD3333333330333El˩B#4vTC333DVyC234Hf{24dDDUUDC333333334V̻f{3"4f23HveC3333333303335kܻ3HfTC34Fg3HVkeDVgvfTC33333333Ff{v|̻C4HvTC333333303334V˻4HfTDEgxCHͶUj˪vVvfT33333333EjݹUj˪vj̻DvTC33333303334Ez̻DfUfyHەDi˺vfeD33333334VgeEi˺vf˺HfT33333303333DV{̻HwwHݧdDg̻iweD3333333DVfffffffwwwwvfffffeTDg̻Uf˻DeD33333033333Ef{˻weD4W˻z̺veC3333333DDDDDDEVgwwwvUDDDDDC4W˻TEfffw˻weD33330333334Ef{̻vTC3V̻y˹vTC3333333333334FvTC333333V̻T4DUUVg̻vdC33303333334Ef{˨dC33F̻w̸vTC333333333334VdC333333F˻d3334DVz̻vT333033333334Ef{˩޷eD333F}˻fgܨfT333333333334WuC333333F}˻d33333DV{̺eC330333333334Ef{ܻvT3333E|̻fVzܨeD33333333334WvC333333E|̻e333333Ef|̺T3303333333334EgwdC33335k˺vDV{ۘweD3333333334V˺S3333335kuC333334Eg̺d33033333333334EgwTC33334j˻vDEf|ۉveC333333333V˩T3333334juC3333334Vw̻d33033333333333DVgܺweD33334g̻vC4EgڙvTC333DDDDDW|ܺeDDDDDC4WuC3333334Fwe3303333333333DUVfwܩweD3334WܻS34EgʙvTC3DUffffg{캗vffffeUDVeC3333334Vyd330333333333DVfwwww칙weD333VܻT334VgfDDVgwwwwwywwwwwwveUjd3333333EgT330333333334UgwwveD33F˷d333DVzeEi˙vUV{ۖTC33333DfyvD33033333334Egfg쩙veD3F~ܹd3333DV{vVܩeEfwwwfUDDDDDEVweC3303333333DVyfVg멙veDE|e33333Ef|f캙eDVgwwvfffffffwvD33303333334VwvDVg۩veEke333334EgfݕDVwwwwwwwwwwwydC33303333334gݦCDVgۙvUid3333334EgfEieD33330333333EiC3DVgۙeVd33333334VjUjeFyvT333330333333EeC33DVg۩vUgܦT33333333DVzeDV{ܶTFeC333330333333FT3333DVg˻DVfwfeC333333333DVfvfTCEfgwwwwwwwwwwwwwwwwveDFvT3333330333333EfD33333DVwDDEUUD33333333333DUUTC34DUUUUUUUUUUUUUUUUUUDCFdC3333330333333ElvTC333333DVzC34DC33333333333334D33333DDDDDDDDDDDDDDDDDD33EleD333333303333334VeC33333333DVzeC333333333333333333333333333333333333333333334WvT3333333303333334EgܷeD3333333333DVzܶd3333333333333333333333333333333333333333333334EiܷeC3333333303333333DUfwveT333333333333DVfwveD3333333333333333333333333333333333333333333333DVfwwwwwwwwwwwwveD333333333033333333DEUUDC3333333333333DEUUD333333333333333333333333333333333333333333333333DEUUUUUUUUUUUUUDC33333333303333333334DC33333333333333334DC333333333333333333333333333333333333333333333333334DDDDDDDDDDDDC333333333330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330xvid_20020412/vfw/authors.txt0100644000100600001440000000012707442022752015352 0ustar michaelusersauthors Peter Ross Daniel Smith xvid_20020412/vfw/todo.txt0100644000100600001440000000123507444627562014647 0ustar michaeluserstodo *** codec *** - cosmetics friendlier error boxes - about screen display core version/build info [Done] - add proper tooltips - add 'load default settings' button (config_reg_default() already exists) - update cpu checkboxes with xvid_init() results, when auto option enabled - figure out what to do with bitfield colorspace stuff in BITMAPINFOHEADER - track down 2-pass bug where frame struct somehow isn't initialized when sent - use multicolumn list box instead of edit boxes in custom quant matrix screen *** documentation *** - windows help, plain text or maybe just plain html? (since the quicktime frontend will have an identical interface) xvid_20020412/vfw/gpl.txt0100644000100600001440000004310307442022753014451 0ustar michaelusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. xvid_20020412/vfw/vfw.dsp0100644000100600001440000001126707453333733014453 0ustar michaelusers# Microsoft Developer Studio Project File - Name="vfw" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=vfw - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "vfw.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "vfw.mak" CFG="vfw - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "vfw - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "vfw - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=xicl6.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "vfw - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0xc09 /d "NDEBUG" # ADD RSC /l 0xc09 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=xilink6.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 user32.lib comdlg32.lib comctl32.lib advapi32.lib gdi32.lib shell32.lib winmm.lib ..\xvidcore\build\win32\bin\core.lib /nologo /dll /machine:I386 /out:"bin\xvid.dll" !ELSEIF "$(CFG)" == "vfw - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0xc09 /d "_DEBUG" # ADD RSC /l 0xc09 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=xilink6.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 user32.lib comdlg32.lib comctl32.lib advapi32.lib gdi32.lib shell32.lib winmm.lib ..\xvidcore\build\win32\bin\core.lib /nologo /dll /debug /machine:I386 /out:"bin\xvid.dll" /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "vfw - Win32 Release" # Name "vfw - Win32 Debug" # Begin Group "doc" # PROP Default_Filter "" # Begin Source File SOURCE=.\authors.txt # End Source File # Begin Source File SOURCE=.\gpl.txt # End Source File # Begin Source File SOURCE=.\help.txt # End Source File # Begin Source File SOURCE=.\todo.txt # End Source File # End Group # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\src\2pass.c # End Source File # Begin Source File SOURCE=.\src\codec.c # End Source File # Begin Source File SOURCE=.\src\config.c # End Source File # Begin Source File SOURCE=.\src\driverproc.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\src\2pass.h # End Source File # Begin Source File SOURCE=.\src\codec.h # End Source File # Begin Source File SOURCE=.\src\config.h # End Source File # Begin Source File SOURCE=.\src\xvid.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # Begin Source File SOURCE=.\src\config.rc # End Source File # Begin Source File SOURCE=.\src\XviD_logo.bmp # End Source File # End Group # Begin Group "Linker Defs" # PROP Default_Filter "def" # Begin Source File SOURCE=.\src\driverproc.def # End Source File # End Group # End Target # End Project xvid_20020412/vfw/vfw.dsw0100644000100600001440000000076407442022753014455 0ustar michaelusersMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "vfw"=.\vfw.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### xvid_20020412/vfw/help.txt0100644000100600001440000000602407442022753014620 0ustar michaelusersxvid vfw help 20/jan/02 *** rate control *** xvid offers a number of different rate control modes - 1pass-cbr: constant-bitrate use the bitrate slider to select the desired bitrate; refer to 'cbr constants' for advanced options. note: we actually use an average-bitrate algorithm, so the instaneous bitrate will fluxuate. - 1pass-quality use the quality slider to select a desired quality percentile. the quality% is then used to calculate an average-quantizer. - 1pass-quantizer force the codec to use a fixed quantizer for all frames. valid range: [1,31]. - 2pass a detailed explaination of 2pass can be found here: http://www.research.ibm.com/journal/rd/434/westerink.html our implementation of two pass encoding requires three steps 1) 1stpass: collect compression statisics to a stats file. 2) process the stats using gordian knot, xihprom, etc. 3) 2ndpass: compress the video using both the original 1stpass stats file, and the normalized stats file. *** encoder tuning *** - max keyframe interval the maximum interval between keyframes. - motion search precision controls the speed/quality of the motion search algorithm. range [0,6]. lower values are faster but reduce compressibility. higher values are slower but increase compressibility. - quantization type quantization is the process of removing detail. there are two types: h.263: used by divx4.x and h263 encoders. mpeg: used by the microsoft mpeg-4 encoder, mpeg-1/2. mpeg quantization gives sharper looking images, but can introduce grain/noise. while h.263 gives softer looking images, removes noise (but sometimes too much) and is slightly faster. *** cbr constants *** these apply only to 1pass-cbr mode. - average peroid the number of frames over which the average bitrate is maintained. - reaction peroid (?) the number of frames inwhich we react to sudden change in bitrate. - up/down ratio (?) a percentile representing how fast/much we react. *** debug *** - min/max quantizer. lets you limit the flexibility of the encoder. a minquant=1 can sometimes cause problems with 1pass-cbr and 2pass. - luminance masking enabled per-macroblock quantizer decision. very experimental - discard encoded bitstream on 1st-pass by default xvid discards the compressed bitstream during the the 1st pass of a two pass encoding session. example: in windows you end up with an empty .avi file. if this box is unchecked the bitstream is kept. note: the 1st compressed bitstream can large. this can be used to perform a 'fast 2pass' encoding. 1) perform 1st pass encoding of your source material with discard unchecked. 2) process the stats file 3) open the bitstream created in the first pass, and perform the 2nd pass on it. note: there is some quality loss. judge it for yourself. - perform dummy 2nd-pass this can be used to check the accuracy of your stats file processor/calculator. it instructs xvid to create a dummy/junk bitstream exactly to the size described in the processed stats file. *** cpu *** provides auto/manual control over cpu-feature optimizations. *** about *** build timestamp, etc.xvid_20020412/xvidcore/0040755000100600001440000000000007455522443014156 5ustar michaelusersxvid_20020412/xvidcore/CVS/0040755000100600001440000000000007455522442014610 5ustar michaelusersxvid_20020412/xvidcore/CVS/Root0100644000100600001440000000004607455522442015453 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/CVS/Repository0100644000100600001440000000001107455522442016677 0ustar michaelusersxvidcore xvid_20020412/xvidcore/CVS/Entries.Log0100644000100600001440000000006707455522443016665 0ustar michaelusersA D/build//// A D/doc//// A D/examples//// A D/src//// xvid_20020412/xvidcore/CVS/Entries0100644000100600001440000000027107455522442016141 0ustar michaelusers/authors.txt/1.1.1.1/Fri Mar 8 02:44:23 2002// /changelog.txt/1.2/Fri Mar 8 19:15:56 2002// /gpl.txt/1.1.1.1/Fri Mar 8 02:44:24 2002// /todo.txt/1.1.1.1/Fri Mar 8 02:44:25 2002// D xvid_20020412/xvidcore/doc/0040755000100600001440000000000007455522443014723 5ustar michaelusersxvid_20020412/xvidcore/doc/CVS/0040755000100600001440000000000007455522443015356 5ustar michaelusersxvid_20020412/xvidcore/doc/CVS/Root0100644000100600001440000000004607455522443016221 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/doc/CVS/Repository0100644000100600001440000000001507455522443017451 0ustar michaelusersxvidcore/doc xvid_20020412/xvidcore/doc/CVS/Entries0100644000100600001440000000023007455522443016702 0ustar michaelusers/README/1.1.1.1/Fri Mar 8 02:44:26 2002// /xvid-decoding.txt/1.1.1.1/Fri Mar 8 02:44:26 2002// /xvid-encoder.txt/1.1.1.1/Fri Mar 8 02:44:26 2002// D xvid_20020412/xvidcore/doc/README0100644000100600001440000000061207442022612015564 0ustar michaelusersDocumentation of XviD ----------------------- xvid-decoding.txt ================= A short overview of routine(s) and data structures needed for decoding with XviD-API. xvid-encoder.txt ================ A short overview of routine(s) and data structure needed for encoding with XviD-API. Questions and suggestions to the forums at http://www.xvid.org (C) Christoph Lampert (gruel@web.de) xvid_20020412/xvidcore/doc/xvid-decoding.txt0100644000100600001440000000650207442022612020175 0ustar michaelusers/************************************************************* * Short explanation for the XviD data strutures and routines * * decoding part * * if you have further questions, visit http://www.xvid.org * **************************************************************/ /* these are are structures/routines from xvid.h needed for decoding */ -------------------------------------------------------------------------- #define API_VERSION ((1 << 16) | (0)) This is the revision of the xvid.h file that you have in front of you. Check it against the library's version. -------------------------------------------------------------------------- typedef struct { int cpu_flags; [in/out] int api_version; [out] int core_build; [out] } XVID_INIT_PARAM; This is filled by xvid_init with the correct CPU flags for initialization (auto-detect), unless you pass flag to it (cpu_flags!=0). Do not use that unless you really know what you are doing. api_version can (should) be checked against API_VERSION, to see if you have the right core library. Used in: xvid_init(NULL, 0, &xinit, NULL); -------------------------------------------------------------------------- typedef struct { int width; [in] (should be a multiple of 16, max is ) int height; [in] (should be a multiple of 16, max is ) void *handle; [out] } XVID_DEC_PARAM; When creating decoder, you have to provide it with height and width of the image to decode (this is _not_ in the bytestream itself!). In handle a unique handle is given back, that has to be used to identify this instance of decoding. Used in: xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL); -------------------------------------------------------------------------- typedef struct { void * bitstream; [in] int length; [in] void * image; [in] int stride; [in] int colorspace; [in] } XVID_DEC_FRAME; This is the main structure for decoding itself. You provide the MPEG4-bitstream and it's length, image is the position where the decoded picture should be stored. stride is the difference between the memory address of the first pixel of a row in the image and the first pixel of the next row. If the image is going to be one big block, then stride=width, but by making it larger you can create an "edged" picture. By colorspace the output format for the image is given, XVID_CSP_RGB24 or XVID_CSP_YV12 might be might common. A special case is XVID_CSP_USER. If you use this, then *image will not filled with the image but with a structure that contains pointers to the decoder's internal representation of it. That's faster, because no memcopy is involved, but don't use it, if you don't know what you're doing. Used in: xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, NULL); -------------------------------------------------------------------------- int xvid_decore(void * handle, [in/out] int opt, [in] void * param1, [in] void * param2); [in] XviD uses a single-function API, so everything you want to do is done by this routine. The opt parameter chooses the behaviour of the routine: XVID_DEC_CREATE: create a new decoder, XVID_DEC_PARAM in param1, a handle to the new decoder is returned in handle XVID_DEC_DECODE: decode one frame, XVID_DEC_FRAME-structure in param1 XVID_DEC_DESTROY: shut down this decoder, do not use handle afterwards xvid_20020412/xvidcore/doc/xvid-encoder.txt0100644000100600001440000001546307442022612020046 0ustar michaelusers/************************************************************* * Short explanation for the XviD data strutures and routines * * encoding part * * if you have further questions, visit http://www.xvid.org * **************************************************************/ /* these are are structures/routines from xvid.h needed for encoding */ -------------------------------------------------------------------------- #define API_VERSION ((1 << 16) | (0)) This is the revision of the xvid.h file that you have in front of you. Check it against the library's version. -------------------------------------------------------------------------- typedef struct { int cpu_flags; [in/out] int api_version; [out] int core_build; [out] } XVID_INIT_PARAM; This is filled by xvid_init with the correct CPU flags for initialization (auto-detect), unless you pass flag to it (cpu_flags!=0). Do not use that unless you really know what you are doing. api_version can (should) be checked against API_VERSION, to see if you have the right core library. Used in: xvid_init(NULL, 0, &xinit, NULL); -------------------------------------------------------------------------- typedef struct { int width, height; int fincr; // frame increment is relative to fbase int fbase; // so each frame takes "fincr/fbase" seconds int bitrate; // the bitrate of the target encoded stream, in bits/second int rc_period; // the intended rate control averaging period int rc_reaction_period; // the reaction period for rate control int rc_reaction_ratio; // the ratio for down/up rate control int max_quantizer; // the upper limit of the quantizer int min_quantizer; // the lower limit of the quantizer int max_key_interval; // the maximum interval between key frames int motion_search; // the quality of compression ( 1=fastest, 6=best ) int lum_masking; // lum masking on/off int quant_type; // 0=h.263, 1=mpeg4 void * handle; // [out] encoder instance handle } XVID_ENC_PARAM; This structure has to be filled to create a new encoding instance: width and height are the size of the image to be encoded. fincr and fbase are the MPEG-way of defining the framerate. If you have an integer framerate, say 24, 25 or 30fps, use fincr=1, fbase=framerate. However, if framerate is non-integer, like 23.996fps you can e.g. multiply with 1000, getting fincr=1000 and fbase=23996, giving you integer values again. rc-parameters are for ratecontrol, you don't have to change them, good defaults are rc_period = 2000 rc_reacton_period = 10 rc_reaction_ratio = 20 min_quantizer, max_quantizer limit the range of allowed quantizers. normally quantizers range is [1..31], so min=1 and max=31. !!! the HIGHER the quantizer, the LOWER the quality !!! !!! the HIGHER the quantizer, the HIGHER the compression ratio !!! min_quant=1 is somewhat overkill, min_quant=2 is good enough max_quant depends on what you encode, leave it with 31 or lower it to something like 15 or 10 for better quality (but encoding with very low bitrate might fail then). max_key_interval is the maximum value of frames between two keyframe (I-frames). Keyframes are also inserted dynamically at scene breaks. It is important to have some keyframes, even in longer scenes, if you want to skip position in the resulting file, because skipping is only possible from one keyframe to the next. However, keyframes are much larger than non-keyframes, so do not use too many of them. A value of framerate*10 is a good choice normally. motion_search determines the quality of motion search done by the codec. The better the search, the smaller the files (or the better the quality). Since low modes (1-3) are hardly faster than high modes (4,5) a value of 5 is a good choice normally. 6 is possible, but a little slower. If you want absolutely highest quality, use 6. lum_masking stand for "luminance masking" which is an experimental feature. It tries to compress better by using facts about the human eye. You might try to switch it on and decide yourself, if you gain anything from it. quant_type is technical, is changes the way coefficient are quantized. Both values are okay, though a value of 0 might be faster. Used in: xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xparam, NULL); -------------------------------------------------------------------------- typedef struct { void * bitstream; // [in] bitstream ptr int length; // [out] bitstream length (bytes) void * image; // [in] image ptr int colorspace; // [in] source colorspace int quant; // [in] frame quantizer (vbr) int intra; // [in] force intra frame (vbr only) // [out] intra state } XVID_ENC_FRAME; The main structure to encode a frame: image points to the picture, in a format that is given by colorspace, e.g. XVID_CSP_RGB24 or XVID_CSP_YV12. If you set quant=0, then the ratecontrol chooses quantizer for you. If quant!=0, then this value is used as quantizer, so make 1<=quant<=31. intra decides where the frame is going to be a keyframe or not. intra=1 means: make it a keyframe intra=0 means: don't make it a keyframe intra=-1 means: let encoder decide (based on contents and max_key_interval) So for an ordinary encoding step, you would set quant=0 and intra=-1. The length of the MPEG4-bitstream is returned in length, and if you set intra to -1, it now contains the encoder's decision: 0 for non-keyframe, 1 for keyframe because of a scene change, 2 for keyframe because max_key_interval was reached. Used in: xerr = xvid_encore(enchandle, XVID_ENC_ENCODE, &xframe, &xstats); -------------------------------------------------------------------------- typedef struct { int quant; // [out] frame quantizer int hlength; // [out] header length (bytes) int kblks, mblks, ublks; // [out] } XVID_ENC_STATS; In this structure the encoder return statistical data about the encoding process, e.g. to be saved for two-pass-encoding. quant is the quantizer chosen for this frame (if you let ratecontrol do it) hlength is the length of the frame's header, including motion information etc. kblks, mblks, ublks are unused at the moment. Used in: xerr = xvid_encore(enchandle, XVID_ENC_ENCODE, &xframe, &xstats); -------------------------------------------------------------------------- int xvid_encore(void * handle, int opt, void * param1, void * param2); XviD uses a single-function API, so everything you want to do is done by this routine. The opt parameter chooses the behaviour of the routine: XVID_ENC_CREATE: create a new encoder, XVID_ENC_PARAM in param1, a handle to the new encoder is returned in handle XVID_ENC_ENCODE: encode one frame, XVID_ENC_FRAME-structure in param1, XVID_ENC_STATS in param2 (or NULL, if you are not interested in statistical data). XVID_DEC_DESTROY: shut down this encoder, do not use handle afterwards xvid_20020412/xvidcore/src/0040755000100600001440000000000007455522447014751 5ustar michaelusersxvid_20020412/xvidcore/src/CVS/0040755000100600001440000000000007455522444015401 5ustar michaelusersxvid_20020412/xvidcore/src/CVS/Root0100644000100600001440000000004607455522443016243 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/CVS/Repository0100644000100600001440000000001507455522443017473 0ustar michaelusersxvidcore/src xvid_20020412/xvidcore/src/CVS/Entries.Log0100644000100600001440000000015207455522447017453 0ustar michaelusersA D/bitstream//// A D/dct//// A D/image//// A D/motion//// A D/prediction//// A D/quant//// A D/utils//// xvid_20020412/xvidcore/src/CVS/Entries0100644000100600001440000000064207455522444016734 0ustar michaelusers/decoder.c/1.10/Mon Apr 8 23:50:15 2002// /decoder.h/1.2/Tue Mar 26 11:16:08 2002// /divx4.c/1.5/Sun Mar 24 21:30:34 2002// /divx4.h/1.1.1.1/Fri Mar 8 02:44:30 2002// /encoder.c/1.23/Wed Apr 10 07:40:51 2002// /encoder.h/1.4/Wed Apr 10 07:40:44 2002// /global.h/1.4/Fri Apr 5 14:40:36 2002// /portab.h/1.14/Sun Apr 7 11:57:47 2002// /xvid.c/1.10/Thu Apr 11 10:18:39 2002// /xvid.h/1.4/Fri Apr 5 14:40:36 2002// D xvid_20020412/xvidcore/src/dct/0040755000100600001440000000000007455522446015522 5ustar michaelusersxvid_20020412/xvidcore/src/dct/CVS/0040755000100600001440000000000007455522445016154 5ustar michaelusersxvid_20020412/xvidcore/src/dct/CVS/Root0100644000100600001440000000004607455522445017017 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/dct/CVS/Repository0100644000100600001440000000002107455522445020244 0ustar michaelusersxvidcore/src/dct xvid_20020412/xvidcore/src/dct/CVS/Entries.Log0100644000100600001440000000004007455522446020220 0ustar michaelusersA D/ppc_asm//// A D/x86_asm//// xvid_20020412/xvidcore/src/dct/CVS/Entries0100644000100600001440000000024607455522445017507 0ustar michaelusers/fdct.c/1.1.1.1/Fri Mar 8 02:44:39 2002// /fdct.h/1.2/Thu Mar 28 15:52:46 2002// /idct.c/1.1.1.1/Fri Mar 8 02:44:39 2002// /idct.h/1.2/Thu Mar 28 15:52:46 2002// D xvid_20020412/xvidcore/src/dct/x86_asm/0040755000100600001440000000000007455522446017007 5ustar michaelusersxvid_20020412/xvidcore/src/dct/x86_asm/CVS/0040755000100600001440000000000007455522446017442 5ustar michaelusersxvid_20020412/xvidcore/src/dct/x86_asm/CVS/Root0100644000100600001440000000004607455522446020305 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/dct/x86_asm/CVS/Repository0100644000100600001440000000003107455522446021533 0ustar michaelusersxvidcore/src/dct/x86_asm xvid_20020412/xvidcore/src/dct/x86_asm/CVS/Entries0100644000100600001440000000014407455522446020772 0ustar michaelusers/fdct_mmx.asm/1.1.1.1/Fri Mar 8 02:44:42 2002// /idct_mmx.asm/1.1.1.1/Fri Mar 8 02:44:43 2002// D xvid_20020412/xvidcore/src/dct/x86_asm/fdct_mmx.asm0100644000100600001440000011641107442022632021277 0ustar michaelusers;/****************************************************************************** ; * * ; * This file is part of XviD, a free MPEG-4 video encoder/decoder * ; * * ; * XviD is an implementation of a part of one or more MPEG-4 Video tools * ; * as specified in ISO/IEC 14496-2 standard. Those intending to use this * ; * software module in hardware or software products are advised that its * ; * use may infringe existing patents or copyrights, and any such use * ; * would be at such party's own risk. The original developer of this * ; * software module and his/her company, and subsequent editors and their * ; * companies, will have no liability for use of this software or * ; * modifications or derivatives thereof. * ; * * ; * XviD is free software; you can redistribute it and/or modify it * ; * under the terms of the GNU General Public License as published by * ; * the Free Software Foundation; either version 2 of the License, or * ; * (at your option) any later version. * ; * * ; * XviD is distributed in the hope that it will be useful, but * ; * WITHOUT ANY WARRANTY; without even the implied warranty of * ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ; * GNU General Public License for more details. * ; * * ; * You should have received a copy of the GNU General Public License * ; * along with this program; if not, write to the Free Software * ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * fdct_mmx.asm, MMX optimized forward DCT * ; * * ; * Initial, but incomplete version provided by Intel at AppNote AP-922 * ; * http://developer.intel.com/vtune/cbts/strmsimd/922down.htm * ; * Copyright (C) 1999 Intel Corporation, * ; * * ; * completed and corrected in fdctmm32.c/fdctmm32.doc, * ; * http://members.tripod.com/~liaor * ; * Copyright (C) 2000 - Royce Shih-Wea Liao , * ; * * ; * ported to NASM and some minor changes * ; * Copyright (C) 2001 - Michael Militzer * ; * * ; * For more information visit the XviD homepage: http://www.xvid.org * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * Revision history: * ; * * ; * 04.11.2001 loop unrolled (Isibaar) * ; * 02.11.2001 initial version (Isibaar) * ; * * ; ******************************************************************************/ BITS 32 %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro %define INP eax %define TABLE ebx %define TABLEF ebx %define OUT ecx %define round_frw_row edx %define INP_1 eax + 16 %define INP_2 eax + 32 %define INP_3 eax + 48 %define INP_4 eax + 64 %define INP_5 eax + 80 %define INP_6 eax + 96 %define INP_7 eax + 112 %define OUT_1 ecx + 16 %define OUT_2 ecx + 32 %define OUT_3 ecx + 48 %define OUT_4 ecx + 64 %define OUT_5 ecx + 80 %define OUT_6 ecx + 96 %define OUT_7 ecx + 112 %define OUT_8 ecx + 128 %define TABLE_1 ebx + 64 %define TABLE_2 ebx + 128 %define TABLE_3 ebx + 192 %define TABLE_4 ebx + 256 %define TABLE_5 ebx + 320 %define TABLE_6 ebx + 384 %define TABLE_7 ebx + 448 %define x0 INP + 0*16 %define x1 INP + 1*16 %define x2 INP + 2*16 %define x3 INP + 3*16 %define x4 INP + 4*16 %define x5 INP + 5*16 %define x6 INP + 6*16 %define x7 INP + 7*16 %define y0 OUT + 0*16 %define y1 OUT + 1*16 %define y2 OUT + 2*16 %define y3 OUT + 3*16 %define y4 OUT + 4*16 %define y5 OUT + 5*16 %define y6 OUT + 6*16 %define y7 OUT + 7*16 %define tg_1_16 (TABLEF + 0) %define tg_2_16 (TABLEF + 8) %define tg_3_16 (TABLEF + 16) %define cos_4_16 (TABLEF + 24) %define ocos_4_16 (TABLEF + 32) SECTION .data ALIGN 16 BITS_FRW_ACC equ 3 ; 2 or 3 for accuracy SHIFT_FRW_COL equ BITS_FRW_ACC SHIFT_FRW_ROW equ (BITS_FRW_ACC + 17) RND_FRW_ROW equ (1 << (SHIFT_FRW_ROW-1)) SHIFT_FRW_ROW_CLIP2 equ (4) SHIFT_FRW_ROW_CLIP1 equ (SHIFT_FRW_ROW - SHIFT_FRW_ROW_CLIP2) one_corr dw 1, 1, 1, 1 r_frw_row dd RND_FRW_ROW, RND_FRW_ROW tg_all_16 dw 13036, 13036, 13036, 13036, ; tg * (2<<16) + 0.5 dw 27146, 27146, 27146, 27146, ; tg * (2<<16) + 0.5 dw -21746, -21746, -21746, -21746, ; tg * (2<<16) + 0.5 dw -19195, -19195, -19195, -19195, ; cos * (2<<16) + 0.5 dw 23170, 23170, 23170, 23170 ; cos * (2<<15) + 0.5 tab_frw_01234567 ; row0 dw 16384, 16384, 21407, -8867, ; w09 w01 w08 w00 dw 16384, 16384, 8867, -21407, ; w13 w05 w12 w04 dw 16384, -16384, 8867, 21407, ; w11 w03 w10 w02 dw -16384, 16384, -21407, -8867, ; w15 w07 w14 w06 dw 22725, 12873, 19266, -22725, ; w22 w20 w18 w16 dw 19266, 4520, -4520, -12873, ; w23 w21 w19 w17 dw 12873, 4520, 4520, 19266, ; w30 w28 w26 w24 dw -22725, 19266, -12873, -22725, ; w31 w29 w27 w25 ; row1 dw 22725, 22725, 29692, -12299, ; w09 w01 w08 w00 dw 22725, 22725, 12299, -29692, ; w13 w05 w12 w04 dw 22725, -22725, 12299, 29692, ; w11 w03 w10 w02 dw -22725, 22725, -29692, -12299, ; w15 w07 w14 w06 dw 31521, 17855, 26722, -31521, ; w22 w20 w18 w16 dw 26722, 6270, -6270, -17855, ; w23 w21 w19 w17 dw 17855, 6270, 6270, 26722, ; w30 w28 w26 w24 dw -31521, 26722, -17855, -31521, ; w31 w29 w27 w25 ; row2 dw 21407, 21407, 27969, -11585, ; w09 w01 w08 w00 dw 21407, 21407, 11585, -27969, ; w13 w05 w12 w04 dw 21407, -21407, 11585, 27969, ; w11 w03 w10 w02 dw -21407, 21407, -27969, -11585, ; w15 w07 w14 w06 dw 29692, 16819, 25172, -29692, ; w22 w20 w18 w16 dw 25172, 5906, -5906, -16819, ; w23 w21 w19 w17 dw 16819, 5906, 5906, 25172, ; w30 w28 w26 w24 dw -29692, 25172, -16819, -29692, ; w31 w29 w27 w25 ; row3 dw 19266, 19266, 25172, -10426, ; w09 w01 w08 w00 dw 19266, 19266, 10426, -25172, ; w13 w05 w12 w04 dw 19266, -19266, 10426, 25172, ; w11 w03 w10 w02 dw -19266, 19266, -25172, -10426, ; w15 w07 w14 w06 dw 26722, 15137, 22654, -26722, ; w22 w20 w18 w16 dw 22654, 5315, -5315, -15137, ; w23 w21 w19 w17 dw 15137, 5315, 5315, 22654, ; w30 w28 w26 w24 dw -26722, 22654, -15137, -26722, ; w31 w29 w27 w25 ; row4 dw 16384, 16384, 21407, -8867, ; w09 w01 w08 w00 dw 16384, 16384, 8867, -21407, ; w13 w05 w12 w04 dw 16384, -16384, 8867, 21407, ; w11 w03 w10 w02 dw -16384, 16384, -21407, -8867, ; w15 w07 w14 w06 dw 22725, 12873, 19266, -22725, ; w22 w20 w18 w16 dw 19266, 4520, -4520, -12873, ; w23 w21 w19 w17 dw 12873, 4520, 4520, 19266, ; w30 w28 w26 w24 dw -22725, 19266, -12873, -22725, ; w31 w29 w27 w25 ; row5 dw 19266, 19266, 25172, -10426, ; w09 w01 w08 w00 dw 19266, 19266, 10426, -25172, ; w13 w05 w12 w04 dw 19266, -19266, 10426, 25172, ; w11 w03 w10 w02 dw -19266, 19266, -25172, -10426, ; w15 w07 w14 w06 dw 26722, 15137, 22654, -26722, ; w22 w20 w18 w16 dw 22654, 5315, -5315, -15137, ; w23 w21 w19 w17 dw 15137, 5315, 5315, 22654, ; w30 w28 w26 w24 dw -26722, 22654, -15137, -26722, ; w31 w29 w27 w25 ; row6 dw 21407, 21407, 27969, -11585, ; w09 w01 w08 w00 dw 21407, 21407, 11585, -27969, ; w13 w05 w12 w04 dw 21407, -21407, 11585, 27969, ; w11 w03 w10 w02 dw -21407, 21407, -27969, -11585, ; w15 w07 w14 w06 dw 29692, 16819, 25172, -29692, ; w22 w20 w18 w16 dw 25172, 5906, -5906, -16819, ; w23 w21 w19 w17 dw 16819, 5906, 5906, 25172, ; w30 w28 w26 w24 dw -29692, 25172, -16819, -29692, ; w31 w29 w27 w25 ; row7 dw 22725, 22725, 29692, -12299, ; w09 w01 w08 w00 dw 22725, 22725, 12299, -29692, ; w13 w05 w12 w04 dw 22725, -22725, 12299, 29692, ; w11 w03 w10 w02 dw -22725, 22725, -29692, -12299, ; w15 w07 w14 w06 dw 31521, 17855, 26722, -31521, ; w22 w20 w18 w16 dw 26722, 6270, -6270, -17855, ; w23 w21 w19 w17 dw 17855, 6270, 6270, 26722, ; w30 w28 w26 w24 dw -31521, 26722, -17855, -31521 ; w31 w29 w27 w25 SECTION .text ALIGN 16 cglobal fdct_mmx ;;void fdct_mmx(short *block); fdct_mmx: push ebx mov INP, dword [esp + 8] ; block mov TABLEF, tg_all_16 mov OUT, INP movq mm0, [x1] ; 0 ; x1 movq mm1, [x6] ; 1 ; x6 movq mm2, mm0 ; 2 ; x1 movq mm3, [x2] ; 3 ; x2 paddsw mm0, mm1 ; t1 = x[1] + x[6] movq mm4, [x5] ; 4 ; x5 psllw mm0, SHIFT_FRW_COL ; t1 movq mm5, [x0] ; 5 ; x0 paddsw mm4, mm3 ; t2 = x[2] + x[5] paddsw mm5, [x7] ; t0 = x[0] + x[7] psllw mm4, SHIFT_FRW_COL ; t2 movq mm6, mm0 ; 6 ; t1 psubsw mm2, mm1 ; 1 ; t6 = x[1] - x[6] movq mm1, [tg_2_16] ; 1 ; tg_2_16 psubsw mm0, mm4 ; tm12 = t1 - t2 movq mm7, [x3] ; 7 ; x3 pmulhw mm1, mm0 ; tm12*tg_2_16 paddsw mm7, [x4] ; t3 = x[3] + x[4] psllw mm5, SHIFT_FRW_COL ; t0 paddsw mm6, mm4 ; 4 ; tp12 = t1 + t2 psllw mm7, SHIFT_FRW_COL ; t3 movq mm4, mm5 ; 4 ; t0 psubsw mm5, mm7 ; tm03 = t0 - t3 paddsw mm1, mm5 ; y2 = tm03 + tm12*tg_2_16 paddsw mm4, mm7 ; 7 ; tp03 = t0 + t3 por mm1, qword [one_corr] ; correction y2 +0.5 psllw mm2, SHIFT_FRW_COL+1 ; t6 pmulhw mm5, [tg_2_16] ; tm03*tg_2_16 movq mm7, mm4 ; 7 ; tp03 psubsw mm3, [x5] ; t5 = x[2] - x[5] psubsw mm4, mm6 ; y4 = tp03 - tp12 movq [y2], mm1 ; 1 ; save y2 paddsw mm7, mm6 ; 6 ; y0 = tp03 + tp12 movq mm1, [x3] ; 1 ; x3 psllw mm3, SHIFT_FRW_COL+1 ; t5 psubsw mm1, [x4] ; t4 = x[3] - x[4] movq mm6, mm2 ; 6 ; t6 movq [y4], mm4 ; 4 ; save y4 paddsw mm2, mm3 ; t6 + t5 pmulhw mm2, [ocos_4_16] ; tp65 = (t6 + t5)*cos_4_16 psubsw mm6, mm3 ; 3 ; t6 - t5 pmulhw mm6, [ocos_4_16] ; tm65 = (t6 - t5)*cos_4_16 psubsw mm5, mm0 ; 0 ; y6 = tm03*tg_2_16 - tm12 por mm5, qword [one_corr] ; correction y6 +0.5 psllw mm1, SHIFT_FRW_COL ; t4 por mm2, qword [one_corr] ; correction tp65 +0.5 movq mm4, mm1 ; 4 ; t4 movq mm3, [x0] ; 3 ; x0 paddsw mm1, mm6 ; tp465 = t4 + tm65 psubsw mm3, [x7] ; t7 = x[0] - x[7] psubsw mm4, mm6 ; 6 ; tm465 = t4 - tm65 movq mm0, [tg_1_16] ; 0 ; tg_1_16 psllw mm3, SHIFT_FRW_COL ; t7 movq mm6, [tg_3_16] ; 6 ; tg_3_16 pmulhw mm0, mm1 ; tp465*tg_1_16 movq [y0], mm7 ; 7 ; save y0 pmulhw mm6, mm4 ; tm465*tg_3_16 movq [y6], mm5 ; 5 ; save y6 movq mm7, mm3 ; 7 ; t7 movq mm5, [tg_3_16] ; 5 ; tg_3_16 psubsw mm7, mm2 ; tm765 = t7 - tp65 paddsw mm3, mm2 ; 2 ; tp765 = t7 + tp65 pmulhw mm5, mm7 ; tm765*tg_3_16 paddsw mm0, mm3 ; y1 = tp765 + tp465*tg_1_16 paddsw mm6, mm4 ; tm465*tg_3_16 pmulhw mm3, [tg_1_16] ; tp765*tg_1_16 por mm0, qword [one_corr] ; correction y1 +0.5 paddsw mm5, mm7 ; tm765*tg_3_16 psubsw mm7, mm6 ; 6 ; y3 = tm765 - tm465*tg_3_16 add INP, 0x08 movq [y1], mm0 ; 0 ; save y1 paddsw mm5, mm4 ; 4 ; y5 = tm765*tg_3_16 + tm465 movq [y3], mm7 ; 7 ; save y3 psubsw mm3, mm1 ; 1 ; y7 = tp765*tg_1_16 - tp465 movq [y5], mm5 ; 5 ; save y5 movq mm0, [x1] ; 0 ; x1 movq [y7], mm3 ; 3 ; save y7 (columns 0-4) movq mm1, [x6] ; 1 ; x6 movq mm2, mm0 ; 2 ; x1 movq mm3, [x2] ; 3 ; x2 paddsw mm0, mm1 ; t1 = x[1] + x[6] movq mm4, [x5] ; 4 ; x5 psllw mm0, SHIFT_FRW_COL ; t1 movq mm5, [x0] ; 5 ; x0 paddsw mm4, mm3 ; t2 = x[2] + x[5] paddsw mm5, [x7] ; t0 = x[0] + x[7] psllw mm4, SHIFT_FRW_COL ; t2 movq mm6, mm0 ; 6 ; t1 psubsw mm2, mm1 ; 1 ; t6 = x[1] - x[6] movq mm1, [tg_2_16] ; 1 ; tg_2_16 psubsw mm0, mm4 ; tm12 = t1 - t2 movq mm7, [x3] ; 7 ; x3 pmulhw mm1, mm0 ; tm12*tg_2_16 paddsw mm7, [x4] ; t3 = x[3] + x[4] psllw mm5, SHIFT_FRW_COL ; t0 paddsw mm6, mm4 ; 4 ; tp12 = t1 + t2 psllw mm7, SHIFT_FRW_COL ; t3 movq mm4, mm5 ; 4 ; t0 psubsw mm5, mm7 ; tm03 = t0 - t3 paddsw mm1, mm5 ; y2 = tm03 + tm12*tg_2_16 paddsw mm4, mm7 ; 7 ; tp03 = t0 + t3 por mm1, qword [one_corr] ; correction y2 +0.5 psllw mm2, SHIFT_FRW_COL+1 ; t6 pmulhw mm5, [tg_2_16] ; tm03*tg_2_16 movq mm7, mm4 ; 7 ; tp03 psubsw mm3, [x5] ; t5 = x[2] - x[5] psubsw mm4, mm6 ; y4 = tp03 - tp12 movq [y2+8], mm1 ; 1 ; save y2 paddsw mm7, mm6 ; 6 ; y0 = tp03 + tp12 movq mm1, [x3] ; 1 ; x3 psllw mm3, SHIFT_FRW_COL+1 ; t5 psubsw mm1, [x4] ; t4 = x[3] - x[4] movq mm6, mm2 ; 6 ; t6 movq [y4+8], mm4 ; 4 ; save y4 paddsw mm2, mm3 ; t6 + t5 pmulhw mm2, [ocos_4_16] ; tp65 = (t6 + t5)*cos_4_16 psubsw mm6, mm3 ; 3 ; t6 - t5 pmulhw mm6, [ocos_4_16] ; tm65 = (t6 - t5)*cos_4_16 psubsw mm5, mm0 ; 0 ; y6 = tm03*tg_2_16 - tm12 por mm5, qword [one_corr] ; correction y6 +0.5 psllw mm1, SHIFT_FRW_COL ; t4 por mm2, qword [one_corr] ; correction tp65 +0.5 movq mm4, mm1 ; 4 ; t4 movq mm3, [x0] ; 3 ; x0 paddsw mm1, mm6 ; tp465 = t4 + tm65 psubsw mm3, [x7] ; t7 = x[0] - x[7] psubsw mm4, mm6 ; 6 ; tm465 = t4 - tm65 movq mm0, [tg_1_16] ; 0 ; tg_1_16 psllw mm3, SHIFT_FRW_COL ; t7 movq mm6, [tg_3_16] ; 6 ; tg_3_16 pmulhw mm0, mm1 ; tp465*tg_1_16 movq [y0+8], mm7 ; 7 ; save y0 pmulhw mm6, mm4 ; tm465*tg_3_16 movq [y6+8], mm5 ; 5 ; save y6 movq mm7, mm3 ; 7 ; t7 movq mm5, [tg_3_16] ; 5 ; tg_3_16 psubsw mm7, mm2 ; tm765 = t7 - tp65 paddsw mm3, mm2 ; 2 ; tp765 = t7 + tp65 pmulhw mm5, mm7 ; tm765*tg_3_16 paddsw mm0, mm3 ; y1 = tp765 + tp465*tg_1_16 paddsw mm6, mm4 ; tm465*tg_3_16 pmulhw mm3, [tg_1_16] ; tp765*tg_1_16 por mm0, qword [one_corr] ; correction y1 +0.5 paddsw mm5, mm7 ; tm765*tg_3_16 psubsw mm7, mm6 ; 6 ; y3 = tm765 - tm465*tg_3_16 movq [y1+8], mm0 ; 0 ; save y1 paddsw mm5, mm4 ; 4 ; y5 = tm765*tg_3_16 + tm465 movq [y3+8], mm7 ; 7 ; save y3 psubsw mm3, mm1 ; 1 ; y7 = tp765*tg_1_16 - tp465 movq [y5+8], mm5 ; 5 ; save y5 movq [y7+8], mm3 ; 3 ; save y7 mov INP, [esp + 8] ; row 0 mov TABLEF, tab_frw_01234567 ; row 0 mov OUT, INP mov round_frw_row, r_frw_row movd mm5, [INP+12] ; mm5 = 7 6 punpcklwd mm5, [INP+8] movq mm2, mm5 ; mm2 = 5 7 4 6 psrlq mm5, 32 ; mm5 = _ _ 5 7 movq mm0, [INP] ; mm0 = 3 2 1 0 punpcklwd mm5, mm2 ; mm5 = 4 5 6 7 movq mm1, mm0 ; mm1 = 3 2 1 0 paddsw mm0, mm5 ; mm0 = [3+4, 2+5, 1+6, 0+7] (xt3, xt2, xt1, xt0) psubsw mm1, mm5 ; mm1 = [3-4, 2-5, 1-6, 0-7] (xt7, xt6, xt5, xt4) movq mm2, mm0 ; mm2 = [ xt3 xt2 xt1 xt0 ] punpcklwd mm0, mm1 ; mm0 = [ xt5 xt1 xt4 xt0 ] punpckhwd mm2, mm1 ; mm2 = [ xt7 xt3 xt6 xt2 ] movq mm1, mm2 ; mm1 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [TABLE] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 [ xt2 xt0 xt2 xt0 ] movq mm4, [TABLE+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [TABLE+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 [ xt3 xt1 xt3 xt1 ] pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 [ xt6 xt4 xt6 xt4 ] pmaddwd mm0, [TABLE+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 [ xt7 xt5 xt7 xt5 ] movq mm7, [TABLE+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [round_frw_row] ; +rounder (y2,y0) pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [TABLE+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [TABLE+48] ; x5*w30+x1*w28 x5*w26+x1*w24 pmaddwd mm6, [TABLE+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [round_frw_row] ; +rounder (y6,y4) psrad mm3, SHIFT_FRW_ROW_CLIP1 ; (y2, y0) paddd mm1, [round_frw_row] ; +rounder (y3,y1) paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) paddd mm5, [round_frw_row] ; +rounder (y7,y5) psrad mm1, SHIFT_FRW_ROW_CLIP1 ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) psrad mm0, SHIFT_FRW_ROW_CLIP1 ; y3=a3+b3 y2=a2+b2 psrad mm5, SHIFT_FRW_ROW_CLIP1 ; y4=a3-b3 y5=a2-b2 packssdw mm3, mm0 ; 0 ; y6 y4 y2 y0, saturate {-32768,+32767} packssdw mm1, mm5 ; 3 ; y7 y5 y3 y1, saturate {-32768,+32767} movq mm6, mm3 ; mm0 = y6 y4 y2 y0 punpcklwd mm3, mm1 ; y3 y2 y1 y0 punpckhwd mm6, mm1 ; y7 y6 y5 y4 psraw mm3, SHIFT_FRW_ROW_CLIP2 ; descale [y3 y2 y1 y0] to {-2048,+2047} psraw mm6, SHIFT_FRW_ROW_CLIP2 ; descale [y7 y6 y5 y4] to {-2048,+2047} movq [OUT_1-16], mm3 ; 1 ; save y3 y2 y1 y0 movq [OUT_1-8], mm6 ; 7 ; save y7 y6 y5 y4 movd mm5, [INP_1+12] ; mm5 = 7 6 punpcklwd mm5, [INP_1+8] movq mm2, mm5 ; mm2 = 5 7 4 6 psrlq mm5, 32 ; mm5 = _ _ 5 7 movq mm0, [INP_1] ; mm0 = 3 2 1 0 punpcklwd mm5, mm2 ; mm5 = 4 5 6 7 movq mm1, mm0 ; mm1 = 3 2 1 0 paddsw mm0, mm5 ; mm0 = [3+4, 2+5, 1+6, 0+7] (xt3, xt2, xt1, xt0) psubsw mm1, mm5 ; mm1 = [3-4, 2-5, 1-6, 0-7] (xt7, xt6, xt5, xt4) movq mm2, mm0 ; mm2 = [ xt3 xt2 xt1 xt0 ] punpcklwd mm0, mm1 ; mm0 = [ xt5 xt1 xt4 xt0 ] punpckhwd mm2, mm1 ; mm2 = [ xt7 xt3 xt6 xt2 ] movq mm1, mm2 ; mm1 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [TABLE_1] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 [ xt2 xt0 xt2 xt0 ] movq mm4, [TABLE_1+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [TABLE_1+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 [ xt3 xt1 xt3 xt1 ] pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 [ xt6 xt4 xt6 xt4 ] pmaddwd mm0, [TABLE_1+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 [ xt7 xt5 xt7 xt5 ] movq mm7, [TABLE_1+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [round_frw_row] ; +rounder (y2,y0) pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [TABLE_1+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [TABLE_1+48] ; x5*w30+x1*w28 x5*w26+x1*w24 pmaddwd mm6, [TABLE_1+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [round_frw_row] ; +rounder (y6,y4) psrad mm3, SHIFT_FRW_ROW_CLIP1 ; (y2, y0) paddd mm1, [round_frw_row] ; +rounder (y3,y1) paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) paddd mm5, [round_frw_row] ; +rounder (y7,y5) psrad mm1, SHIFT_FRW_ROW_CLIP1 ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) psrad mm0, SHIFT_FRW_ROW_CLIP1 ; y3=a3+b3 y2=a2+b2 psrad mm5, SHIFT_FRW_ROW_CLIP1 ; y4=a3-b3 y5=a2-b2 packssdw mm3, mm0 ; 0 ; y6 y4 y2 y0, saturate {-32768,+32767} packssdw mm1, mm5 ; 3 ; y7 y5 y3 y1, saturate {-32768,+32767} movq mm6, mm3 ; mm0 = y6 y4 y2 y0 punpcklwd mm3, mm1 ; y3 y2 y1 y0 punpckhwd mm6, mm1 ; y7 y6 y5 y4 psraw mm3, SHIFT_FRW_ROW_CLIP2 ; descale [y3 y2 y1 y0] to {-2048,+2047} psraw mm6, SHIFT_FRW_ROW_CLIP2 ; descale [y7 y6 y5 y4] to {-2048,+2047} movq [OUT_2-16], mm3 ; 1 ; save y3 y2 y1 y0 movq [OUT_2-8], mm6 ; 7 ; save y7 y6 y5 y4 movd mm5, [INP_2+12] ; mm5 = 7 6 punpcklwd mm5, [INP_2+8] movq mm2, mm5 ; mm2 = 5 7 4 6 psrlq mm5, 32 ; mm5 = _ _ 5 7 movq mm0, [INP_2] ; mm0 = 3 2 1 0 punpcklwd mm5, mm2 ; mm5 = 4 5 6 7 movq mm1, mm0 ; mm1 = 3 2 1 0 paddsw mm0, mm5 ; mm0 = [3+4, 2+5, 1+6, 0+7] (xt3, xt2, xt1, xt0) psubsw mm1, mm5 ; mm1 = [3-4, 2-5, 1-6, 0-7] (xt7, xt6, xt5, xt4) movq mm2, mm0 ; mm2 = [ xt3 xt2 xt1 xt0 ] punpcklwd mm0, mm1 ; mm0 = [ xt5 xt1 xt4 xt0 ] punpckhwd mm2, mm1 ; mm2 = [ xt7 xt3 xt6 xt2 ] movq mm1, mm2 ; mm1 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [TABLE_2] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 [ xt2 xt0 xt2 xt0 ] movq mm4, [TABLE_2+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [TABLE_2+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 [ xt3 xt1 xt3 xt1 ] pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 [ xt6 xt4 xt6 xt4 ] pmaddwd mm0, [TABLE_2+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 [ xt7 xt5 xt7 xt5 ] movq mm7, [TABLE_2+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [round_frw_row] ; +rounder (y2,y0) pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [TABLE_2+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [TABLE_2+48] ; x5*w30+x1*w28 x5*w26+x1*w24 pmaddwd mm6, [TABLE_2+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [round_frw_row] ; +rounder (y6,y4) psrad mm3, SHIFT_FRW_ROW_CLIP1 ; (y2, y0) paddd mm1, [round_frw_row] ; +rounder (y3,y1) paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) paddd mm5, [round_frw_row] ; +rounder (y7,y5) psrad mm1, SHIFT_FRW_ROW_CLIP1 ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) psrad mm0, SHIFT_FRW_ROW_CLIP1 ; y3=a3+b3 y2=a2+b2 psrad mm5, SHIFT_FRW_ROW_CLIP1 ; y4=a3-b3 y5=a2-b2 packssdw mm3, mm0 ; 0 ; y6 y4 y2 y0, saturate {-32768,+32767} packssdw mm1, mm5 ; 3 ; y7 y5 y3 y1, saturate {-32768,+32767} movq mm6, mm3 ; mm0 = y6 y4 y2 y0 punpcklwd mm3, mm1 ; y3 y2 y1 y0 punpckhwd mm6, mm1 ; y7 y6 y5 y4 psraw mm3, SHIFT_FRW_ROW_CLIP2 ; descale [y3 y2 y1 y0] to {-2048,+2047} psraw mm6, SHIFT_FRW_ROW_CLIP2 ; descale [y7 y6 y5 y4] to {-2048,+2047} movq [OUT_3-16], mm3 ; 1 ; save y3 y2 y1 y0 movq [OUT_3-8], mm6 ; 7 ; save y7 y6 y5 y4 movd mm5, [INP_3+12] ; mm5 = 7 6 punpcklwd mm5, [INP_3+8] movq mm2, mm5 ; mm2 = 5 7 4 6 psrlq mm5, 32 ; mm5 = _ _ 5 7 movq mm0, [INP_3] ; mm0 = 3 2 1 0 punpcklwd mm5, mm2 ; mm5 = 4 5 6 7 movq mm1, mm0 ; mm1 = 3 2 1 0 paddsw mm0, mm5 ; mm0 = [3+4, 2+5, 1+6, 0+7] (xt3, xt2, xt1, xt0) psubsw mm1, mm5 ; mm1 = [3-4, 2-5, 1-6, 0-7] (xt7, xt6, xt5, xt4) movq mm2, mm0 ; mm2 = [ xt3 xt2 xt1 xt0 ] punpcklwd mm0, mm1 ; mm0 = [ xt5 xt1 xt4 xt0 ] punpckhwd mm2, mm1 ; mm2 = [ xt7 xt3 xt6 xt2 ] movq mm1, mm2 ; mm1 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [TABLE_3] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 [ xt2 xt0 xt2 xt0 ] movq mm4, [TABLE_3+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [TABLE_3+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 [ xt3 xt1 xt3 xt1 ] pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 [ xt6 xt4 xt6 xt4 ] pmaddwd mm0, [TABLE_3+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 [ xt7 xt5 xt7 xt5 ] movq mm7, [TABLE_3+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [round_frw_row] ; +rounder (y2,y0) pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [TABLE_3+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [TABLE_3+48] ; x5*w30+x1*w28 x5*w26+x1*w24 pmaddwd mm6, [TABLE_3+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [round_frw_row] ; +rounder (y6,y4) psrad mm3, SHIFT_FRW_ROW_CLIP1 ; (y2, y0) paddd mm1, [round_frw_row] ; +rounder (y3,y1) paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) paddd mm5, [round_frw_row] ; +rounder (y7,y5) psrad mm1, SHIFT_FRW_ROW_CLIP1 ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) psrad mm0, SHIFT_FRW_ROW_CLIP1 ; y3=a3+b3 y2=a2+b2 psrad mm5, SHIFT_FRW_ROW_CLIP1 ; y4=a3-b3 y5=a2-b2 packssdw mm3, mm0 ; 0 ; y6 y4 y2 y0, saturate {-32768,+32767} packssdw mm1, mm5 ; 3 ; y7 y5 y3 y1, saturate {-32768,+32767} movq mm6, mm3 ; mm0 = y6 y4 y2 y0 punpcklwd mm3, mm1 ; y3 y2 y1 y0 punpckhwd mm6, mm1 ; y7 y6 y5 y4 psraw mm3, SHIFT_FRW_ROW_CLIP2 ; descale [y3 y2 y1 y0] to {-2048,+2047} psraw mm6, SHIFT_FRW_ROW_CLIP2 ; descale [y7 y6 y5 y4] to {-2048,+2047} movq [OUT_4-16], mm3 ; 1 ; save y3 y2 y1 y0 movq [OUT_4-8], mm6 ; 7 ; save y7 y6 y5 y4 movd mm5, [INP_4+12] ; mm5 = 7 6 punpcklwd mm5, [INP_4+8] movq mm2, mm5 ; mm2 = 5 7 4 6 psrlq mm5, 32 ; mm5 = _ _ 5 7 movq mm0, [INP_4] ; mm0 = 3 2 1 0 punpcklwd mm5, mm2 ; mm5 = 4 5 6 7 movq mm1, mm0 ; mm1 = 3 2 1 0 paddsw mm0, mm5 ; mm0 = [3+4, 2+5, 1+6, 0+7] (xt3, xt2, xt1, xt0) psubsw mm1, mm5 ; mm1 = [3-4, 2-5, 1-6, 0-7] (xt7, xt6, xt5, xt4) movq mm2, mm0 ; mm2 = [ xt3 xt2 xt1 xt0 ] punpcklwd mm0, mm1 ; mm0 = [ xt5 xt1 xt4 xt0 ] punpckhwd mm2, mm1 ; mm2 = [ xt7 xt3 xt6 xt2 ] movq mm1, mm2 ; mm1 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [TABLE_4] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 [ xt2 xt0 xt2 xt0 ] movq mm4, [TABLE_4+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [TABLE_4+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 [ xt3 xt1 xt3 xt1 ] pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 [ xt6 xt4 xt6 xt4 ] pmaddwd mm0, [TABLE_4+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 [ xt7 xt5 xt7 xt5 ] movq mm7, [TABLE_4+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [round_frw_row] ; +rounder (y2,y0) pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [TABLE_4+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [TABLE_4+48] ; x5*w30+x1*w28 x5*w26+x1*w24 pmaddwd mm6, [TABLE_4+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [round_frw_row] ; +rounder (y6,y4) psrad mm3, SHIFT_FRW_ROW_CLIP1 ; (y2, y0) paddd mm1, [round_frw_row] ; +rounder (y3,y1) paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) paddd mm5, [round_frw_row] ; +rounder (y7,y5) psrad mm1, SHIFT_FRW_ROW_CLIP1 ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) psrad mm0, SHIFT_FRW_ROW_CLIP1 ; y3=a3+b3 y2=a2+b2 psrad mm5, SHIFT_FRW_ROW_CLIP1 ; y4=a3-b3 y5=a2-b2 packssdw mm3, mm0 ; 0 ; y6 y4 y2 y0, saturate {-32768,+32767} packssdw mm1, mm5 ; 3 ; y7 y5 y3 y1, saturate {-32768,+32767} movq mm6, mm3 ; mm0 = y6 y4 y2 y0 punpcklwd mm3, mm1 ; y3 y2 y1 y0 punpckhwd mm6, mm1 ; y7 y6 y5 y4 psraw mm3, SHIFT_FRW_ROW_CLIP2 ; descale [y3 y2 y1 y0] to {-2048,+2047} psraw mm6, SHIFT_FRW_ROW_CLIP2 ; descale [y7 y6 y5 y4] to {-2048,+2047} movq [OUT_5-16], mm3 ; 1 ; save y3 y2 y1 y0 movq [OUT_5-8], mm6 ; 7 ; save y7 y6 y5 y4 movd mm5, [INP_5+12] ; mm5 = 7 6 punpcklwd mm5, [INP_5+8] movq mm2, mm5 ; mm2 = 5 7 4 6 psrlq mm5, 32 ; mm5 = _ _ 5 7 movq mm0, [INP_5] ; mm0 = 3 2 1 0 punpcklwd mm5, mm2 ; mm5 = 4 5 6 7 movq mm1, mm0 ; mm1 = 3 2 1 0 paddsw mm0, mm5 ; mm0 = [3+4, 2+5, 1+6, 0+7] (xt3, xt2, xt1, xt0) psubsw mm1, mm5 ; mm1 = [3-4, 2-5, 1-6, 0-7] (xt7, xt6, xt5, xt4) movq mm2, mm0 ; mm2 = [ xt3 xt2 xt1 xt0 ] punpcklwd mm0, mm1 ; mm0 = [ xt5 xt1 xt4 xt0 ] punpckhwd mm2, mm1 ; mm2 = [ xt7 xt3 xt6 xt2 ] movq mm1, mm2 ; mm1 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [TABLE_5] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 [ xt2 xt0 xt2 xt0 ] movq mm4, [TABLE_5+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [TABLE_5+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 [ xt3 xt1 xt3 xt1 ] pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 [ xt6 xt4 xt6 xt4 ] pmaddwd mm0, [TABLE_5+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 [ xt7 xt5 xt7 xt5 ] movq mm7, [TABLE_5+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [round_frw_row] ; +rounder (y2,y0) pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [TABLE_5+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [TABLE_5+48] ; x5*w30+x1*w28 x5*w26+x1*w24 pmaddwd mm6, [TABLE_5+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [round_frw_row] ; +rounder (y6,y4) psrad mm3, SHIFT_FRW_ROW_CLIP1 ; (y2, y0) paddd mm1, [round_frw_row] ; +rounder (y3,y1) paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) paddd mm5, [round_frw_row] ; +rounder (y7,y5) psrad mm1, SHIFT_FRW_ROW_CLIP1 ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) psrad mm0, SHIFT_FRW_ROW_CLIP1 ; y3=a3+b3 y2=a2+b2 psrad mm5, SHIFT_FRW_ROW_CLIP1 ; y4=a3-b3 y5=a2-b2 packssdw mm3, mm0 ; 0 ; y6 y4 y2 y0, saturate {-32768,+32767} packssdw mm1, mm5 ; 3 ; y7 y5 y3 y1, saturate {-32768,+32767} movq mm6, mm3 ; mm0 = y6 y4 y2 y0 punpcklwd mm3, mm1 ; y3 y2 y1 y0 punpckhwd mm6, mm1 ; y7 y6 y5 y4 psraw mm3, SHIFT_FRW_ROW_CLIP2 ; descale [y3 y2 y1 y0] to {-2048,+2047} psraw mm6, SHIFT_FRW_ROW_CLIP2 ; descale [y7 y6 y5 y4] to {-2048,+2047} movq [OUT_6-16], mm3 ; 1 ; save y3 y2 y1 y0 movq [OUT_6-8], mm6 ; 7 ; save y7 y6 y5 y4 movd mm5, [INP_6+12] ; mm5 = 7 6 punpcklwd mm5, [INP_6+8] movq mm2, mm5 ; mm2 = 5 7 4 6 psrlq mm5, 32 ; mm5 = _ _ 5 7 movq mm0, [INP_6] ; mm0 = 3 2 1 0 punpcklwd mm5, mm2 ; mm5 = 4 5 6 7 movq mm1, mm0 ; mm1 = 3 2 1 0 paddsw mm0, mm5 ; mm0 = [3+4, 2+5, 1+6, 0+7] (xt3, xt2, xt1, xt0) psubsw mm1, mm5 ; mm1 = [3-4, 2-5, 1-6, 0-7] (xt7, xt6, xt5, xt4) movq mm2, mm0 ; mm2 = [ xt3 xt2 xt1 xt0 ] punpcklwd mm0, mm1 ; mm0 = [ xt5 xt1 xt4 xt0 ] punpckhwd mm2, mm1 ; mm2 = [ xt7 xt3 xt6 xt2 ] movq mm1, mm2 ; mm1 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [TABLE_6] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 [ xt2 xt0 xt2 xt0 ] movq mm4, [TABLE_6+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [TABLE_6+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 [ xt3 xt1 xt3 xt1 ] pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 [ xt6 xt4 xt6 xt4 ] pmaddwd mm0, [TABLE_6+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 [ xt7 xt5 xt7 xt5 ] movq mm7, [TABLE_6+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [round_frw_row] ; +rounder (y2,y0) pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [TABLE_6+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [TABLE_6+48] ; x5*w30+x1*w28 x5*w26+x1*w24 pmaddwd mm6, [TABLE_6+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [round_frw_row] ; +rounder (y6,y4) psrad mm3, SHIFT_FRW_ROW_CLIP1 ; (y2, y0) paddd mm1, [round_frw_row] ; +rounder (y3,y1) paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) paddd mm5, [round_frw_row] ; +rounder (y7,y5) psrad mm1, SHIFT_FRW_ROW_CLIP1 ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) psrad mm0, SHIFT_FRW_ROW_CLIP1 ; y3=a3+b3 y2=a2+b2 psrad mm5, SHIFT_FRW_ROW_CLIP1 ; y4=a3-b3 y5=a2-b2 packssdw mm3, mm0 ; 0 ; y6 y4 y2 y0, saturate {-32768,+32767} packssdw mm1, mm5 ; 3 ; y7 y5 y3 y1, saturate {-32768,+32767} movq mm6, mm3 ; mm0 = y6 y4 y2 y0 punpcklwd mm3, mm1 ; y3 y2 y1 y0 punpckhwd mm6, mm1 ; y7 y6 y5 y4 psraw mm3, SHIFT_FRW_ROW_CLIP2 ; descale [y3 y2 y1 y0] to {-2048,+2047} psraw mm6, SHIFT_FRW_ROW_CLIP2 ; descale [y7 y6 y5 y4] to {-2048,+2047} movq [OUT_7-16], mm3 ; 1 ; save y3 y2 y1 y0 movq [OUT_7-8], mm6 ; 7 ; save y7 y6 y5 y4 movd mm5, [INP_7+12] ; mm5 = 7 6 punpcklwd mm5, [INP_7+8] movq mm2, mm5 ; mm2 = 5 7 4 6 psrlq mm5, 32 ; mm5 = _ _ 5 7 movq mm0, [INP_7] ; mm0 = 3 2 1 0 punpcklwd mm5, mm2 ; mm5 = 4 5 6 7 movq mm1, mm0 ; mm1 = 3 2 1 0 paddsw mm0, mm5 ; mm0 = [3+4, 2+5, 1+6, 0+7] (xt3, xt2, xt1, xt0) psubsw mm1, mm5 ; mm1 = [3-4, 2-5, 1-6, 0-7] (xt7, xt6, xt5, xt4) movq mm2, mm0 ; mm2 = [ xt3 xt2 xt1 xt0 ] punpcklwd mm0, mm1 ; mm0 = [ xt5 xt1 xt4 xt0 ] punpckhwd mm2, mm1 ; mm2 = [ xt7 xt3 xt6 xt2 ] movq mm1, mm2 ; mm1 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [TABLE_7] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 [ xt2 xt0 xt2 xt0 ] movq mm4, [TABLE_7+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [TABLE_7+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 [ xt3 xt1 xt3 xt1 ] pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 [ xt6 xt4 xt6 xt4 ] pmaddwd mm0, [TABLE_7+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 [ xt7 xt5 xt7 xt5 ] movq mm7, [TABLE_7+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [round_frw_row] ; +rounder (y2,y0) pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [TABLE_7+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [TABLE_7+48] ; x5*w30+x1*w28 x5*w26+x1*w24 pmaddwd mm6, [TABLE_7+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [round_frw_row] ; +rounder (y6,y4) psrad mm3, SHIFT_FRW_ROW_CLIP1 ; (y2, y0) paddd mm1, [round_frw_row] ; +rounder (y3,y1) paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) paddd mm5, [round_frw_row] ; +rounder (y7,y5) psrad mm1, SHIFT_FRW_ROW_CLIP1 ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) psrad mm0, SHIFT_FRW_ROW_CLIP1 ; y3=a3+b3 y2=a2+b2 psrad mm5, SHIFT_FRW_ROW_CLIP1 ; y4=a3-b3 y5=a2-b2 packssdw mm3, mm0 ; 0 ; y6 y4 y2 y0, saturate {-32768,+32767} packssdw mm1, mm5 ; 3 ; y7 y5 y3 y1, saturate {-32768,+32767} movq mm6, mm3 ; mm0 = y6 y4 y2 y0 punpcklwd mm3, mm1 ; y3 y2 y1 y0 punpckhwd mm6, mm1 ; y7 y6 y5 y4 psraw mm3, SHIFT_FRW_ROW_CLIP2 ; descale [y3 y2 y1 y0] to {-2048,+2047} psraw mm6, SHIFT_FRW_ROW_CLIP2 ; descale [y7 y6 y5 y4] to {-2048,+2047} movq [OUT_8-16], mm3 ; 1 ; save y3 y2 y1 y0 movq [OUT_8-8], mm6 ; 7 ; save y7 y6 y5 y4 pop ebx emms ret xvid_20020412/xvidcore/src/dct/x86_asm/idct_mmx.asm0100644000100600001440000006140107442022633021301 0ustar michaelusers; Originally provided by Intel at AP-922 ; http://developer.intel.com/vtune/cbts/strmsimd/922down.htm ; (See more app notes at http://developer.intel.com/vtune/cbts/strmsimd/appnotes.htm) ; but in a limited edition. ; New macro implements a column part for precise iDCT ; The routine precision now satisfies IEEE standard 1180-1990. ; ; Copyright (c) 2000-2001 Peter Gubanov ; Rounding trick Copyright (c) 2000 Michel Lespinasse ; ; http://www.elecard.com/peter/idct.html ; http://www.linuxvideo.org/mpeg2dec/ ; ;============================================================================= ; ; These examples contain code fragments for first stage iDCT 8x8 ; (for rows) and first stage DCT 8x8 (for columns) ; ;============================================================================= ; ; 04.11.2001 nasm conversion; peter ross ; bits 32 %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro %define BITS_INV_ACC 5 ; 4 or 5 for IEEE %define SHIFT_INV_ROW 16 - BITS_INV_ACC %define SHIFT_INV_COL 1 + BITS_INV_ACC %define RND_INV_ROW 1024 * (6 - BITS_INV_ACC) ; 1 << (SHIFT_INV_ROW-1) %define RND_INV_COL 16 * (BITS_INV_ACC - 3) ; 1 << (SHIFT_INV_COL-1) %define RND_INV_CORR RND_INV_COL - 1 ; correction -1.0 and round %define BITS_FRW_ACC 3 ; 2 or 3 for accuracy %define SHIFT_FRW_COL BITS_FRW_ACC %define SHIFT_FRW_ROW BITS_FRW_ACC + 17 %define RND_FRW_ROW 262144 * (BITS_FRW_ACC - 1) ; 1 << (SHIFT_FRW_ROW-1) section .data align 16 one_corr dw 1, 1, 1, 1 round_inv_row dd RND_INV_ROW, RND_INV_ROW round_inv_col dw RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL round_inv_corr dw RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR round_frw_row dd RND_FRW_ROW, RND_FRW_ROW tg_1_16 dw 13036, 13036, 13036, 13036 ; tg * (2<<16) + 0.5 tg_2_16 dw 27146, 27146, 27146, 27146 ; tg * (2<<16) + 0.5 tg_3_16 dw -21746, -21746, -21746, -21746 ; tg * (2<<16) + 0.5 cos_4_16 dw -19195, -19195, -19195, -19195 ; cos * (2<<16) + 0.5 ocos_4_16 dw 23170, 23170, 23170, 23170 ; cos * (2<<15) + 0.5 otg_3_16 dw 21895, 21895, 21895, 21895 ; tg * (2<<16) + 0.5 %if SHIFT_INV_ROW == 12 ; assume SHIFT_INV_ROW == 12 rounder_0 dd 65536, 65536 rounder_4 dd 0, 0 rounder_1 dd 7195, 7195 rounder_7 dd 1024, 1024 rounder_2 dd 4520, 4520 rounder_6 dd 1024, 1024 rounder_3 dd 2407, 2407 rounder_5 dd 240, 240 %elif SHIFT_INV_ROW == 11 ; assume SHIFT_INV_ROW == 11 rounder_0 dd 65536, 65536 rounder_4 dd 0, 0 rounder_1 dd 3597, 3597 rounder_7 dd 512, 512 rounder_2 dd 2260, 2260 rounder_6 dd 512, 512 rounder_3 dd 1203, 1203 rounder_5 dd 120, 120 %else %error invalid _SHIFT_INV_ROW_ %endif ;============================================================================= ; ; The first stage iDCT 8x8 - inverse DCTs of rows ; ;----------------------------------------------------------------------------- ; The 8-point inverse DCT direct algorithm ;----------------------------------------------------------------------------- ; ; static const short w[32] = { ; FIX(cos_4_16), FIX(cos_2_16), FIX(cos_4_16), FIX(cos_6_16), ; FIX(cos_4_16), FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16), ; FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16), FIX(cos_2_16), ; FIX(cos_4_16), -FIX(cos_2_16), FIX(cos_4_16), -FIX(cos_6_16), ; FIX(cos_1_16), FIX(cos_3_16), FIX(cos_5_16), FIX(cos_7_16), ; FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16), ; FIX(cos_5_16), -FIX(cos_1_16), FIX(cos_7_16), FIX(cos_3_16), ; FIX(cos_7_16), -FIX(cos_5_16), FIX(cos_3_16), -FIX(cos_1_16) }; ; ; #define DCT_8_INV_ROW(x, y) ; { ; int a0, a1, a2, a3, b0, b1, b2, b3; ; ; a0 =x[0]*w[0]+x[2]*w[1]+x[4]*w[2]+x[6]*w[3]; ; a1 =x[0]*w[4]+x[2]*w[5]+x[4]*w[6]+x[6]*w[7]; ; a2 = x[0] * w[ 8] + x[2] * w[ 9] + x[4] * w[10] + x[6] * w[11]; ; a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15]; ; b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19]; ; b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23]; ; b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27]; ; b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31]; ; ; y[0] = SHIFT_ROUND ( a0 + b0 ); ; y[1] = SHIFT_ROUND ( a1 + b1 ); ; y[2] = SHIFT_ROUND ( a2 + b2 ); ; y[3] = SHIFT_ROUND ( a3 + b3 ); ; y[4] = SHIFT_ROUND ( a3 - b3 ); ; y[5] = SHIFT_ROUND ( a2 - b2 ); ; y[6] = SHIFT_ROUND ( a1 - b1 ); ; y[7] = SHIFT_ROUND ( a0 - b0 ); ; } ; ;----------------------------------------------------------------------------- ; ; In this implementation the outputs of the iDCT-1D are multiplied ; for rows 0,4 - by cos_4_16, ; for rows 1,7 - by cos_1_16, ; for rows 2,6 - by cos_2_16, ; for rows 3,5 - by cos_3_16 ; and are shifted to the left for better accuracy ; ; For the constants used, ; FIX(float_const) = (short) (float_const * (1<<15) + 0.5) ; ;============================================================================= ;============================================================================= ; MMX code ;============================================================================= ; Table for rows 0,4 - constants are multiplied by cos_4_16 tab_i_04 dw 16384, 16384, 16384, -16384 ; movq-> w06 w04 w02 w00 dw 21407, 8867, 8867, -21407 ; w07 w05 w03 w01 dw 16384, -16384, 16384, 16384 ; w14 w12 w10 w08 dw -8867, 21407, -21407, -8867 ; w15 w13 w11 w09 dw 22725, 12873, 19266, -22725 ; w22 w20 w18 w16 dw 19266, 4520, -4520, -12873 ; w23 w21 w19 w17 dw 12873, 4520, 4520, 19266 ; w30 w28 w26 w24 dw -22725, 19266, -12873, -22725 ; w31 w29 w27 w25 ; Table for rows 1,7 - constants are multiplied by cos_1_16 tab_i_17 dw 22725, 22725, 22725, -22725 ; movq-> w06 w04 w02 w00 dw 29692, 12299, 12299, -29692 ; w07 w05 w03 w01 dw 22725, -22725, 22725, 22725 ; w14 w12 w10 w08 dw -12299, 29692, -29692, -12299 ; w15 w13 w11 w09 dw 31521, 17855, 26722, -31521 ; w22 w20 w18 w16 dw 26722, 6270, -6270, -17855 ; w23 w21 w19 w17 dw 17855, 6270, 6270, 26722 ; w30 w28 w26 w24 dw -31521, 26722, -17855, -31521 ; w31 w29 w27 w25 ; Table for rows 2,6 - constants are multiplied by cos_2_16 tab_i_26 dw 21407, 21407, 21407, -21407 ; movq-> w06 w04 w02 w00 dw 27969, 11585, 11585, -27969 ; w07 w05 w03 w01 dw 21407, -21407, 21407, 21407 ; w14 w12 w10 w08 dw -11585, 27969, -27969, -11585 ; w15 w13 w11 w09 dw 29692, 16819, 25172, -29692 ; w22 w20 w18 w16 dw 25172, 5906, -5906, -16819 ; w23 w21 w19 w17 dw 16819, 5906, 5906, 25172 ; w30 w28 w26 w24 dw -29692, 25172, -16819, -29692 ; w31 w29 w27 w25 ; Table for rows 3,5 - constants are multiplied by cos_3_16 tab_i_35 dw 19266, 19266, 19266, -19266 ; movq-> w06 w04 w02 w00 dw 25172, 10426, 10426, -25172 ; w07 w05 w03 w01 dw 19266, -19266, 19266, 19266 ; w14 w12 w10 w08 dw -10426, 25172, -25172, -10426 ; w15 w13 w11 w09 dw 26722, 15137, 22654, -26722 ; w22 w20 w18 w16 dw 22654, 5315, -5315, -15137 ; w23 w21 w19 w17 dw 15137, 5315, 5315, 22654 ; w30 w28 w26 w24 dw -26722, 22654, -15137, -26722 ; w31 w29 w27 w25 ;----------------------------------------------------------------------------- ; ; DCT_8_INV_ROW_1 INP, OUT, TABLE, ROUNDER ; %macro DCT_8_INV_ROW_1 4 movq mm0, [%1] ; 0 ; x3 x2 x1 x0 movq mm1, [%1+8] ; 1 ; x7 x6 x5 x4 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [%3] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 movq mm4, [%3+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [%3+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 pmaddwd mm0, [%3+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 movq mm7, [%3+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [%4] ; +%4 pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [%3+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [%3+48] ; x5*w30+x1*w28 x5*w26+x1*w24 movq mm4, mm3 ; 4 ; a1 a0 pmaddwd mm6, [%3+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [%4] ; +%4 psubd mm3, mm1 ; a1-b1 a0-b0 psrad mm3, SHIFT_INV_ROW ; y6=a1-b1 y7=a0-b0 paddd mm1, mm4 ; 4 ; a1+b1 a0+b0 paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) psrad mm1, SHIFT_INV_ROW ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) movq mm4, mm0 ; 4 ; a3 a2 paddd mm0, mm5 ; a3+b3 a2+b2 psubd mm4, mm5 ; 5 ; a3-b3 a2-b2 psrad mm0, SHIFT_INV_ROW ; y3=a3+b3 y2=a2+b2 psrad mm4, SHIFT_INV_ROW ; y4=a3-b3 y5=a2-b2 packssdw mm1, mm0 ; 0 ; y3 y2 y1 y0 packssdw mm4, mm3 ; 3 ; y6 y7 y4 y5 movq mm7, mm4 ; 7 ; y6 y7 y4 y5 psrld mm4, 16 ; 0 y6 0 y4 pslld mm7, 16 ; y7 0 y5 0 movq [%2], mm1 ; 1 ; save y3 y2 y1 y0 por mm7, mm4 ; 4 ; y7 y6 y5 y4 movq [%2+8], mm7 ; 7 ; save y7 y6 y5 y4 %endmacro ;============================================================================= ; code for Pentium III ;============================================================================= ; %3 for rows 0,4 - constants are multiplied by cos_4_16 tab_i_04_sse dw 16384, 21407, 16384, 8867 ; movq-> w05 w04 w01 w00 dw 16384, 8867, -16384, -21407 ; w07 w06 w03 w02 dw 16384, -8867, 16384, -21407 ; w13 w12 w09 w08 dw -16384, 21407, 16384, -8867 ; w15 w14 w11 w10 dw 22725, 19266, 19266, -4520 ; w21 w20 w17 w16 dw 12873, 4520, -22725, -12873 ; w23 w22 w19 w18 dw 12873, -22725, 4520, -12873 ; w29 w28 w25 w24 dw 4520, 19266, 19266, -22725 ; w31 w30 w27 w26 ; %3 for rows 1,7 - constants are multiplied by cos_1_16 tab_i_17_sse dw 22725, 29692, 22725, 12299 ; movq-> w05 w04 w01 w00 dw 22725, 12299, -22725, -29692 ; w07 w06 w03 w02 dw 22725, -12299, 22725, -29692 ; w13 w12 w09 w08 dw -22725, 29692, 22725, -12299 ; w15 w14 w11 w10 dw 31521, 26722, 26722, -6270 ; w21 w20 w17 w16 dw 17855, 6270, -31521, -17855 ; w23 w22 w19 w18 dw 17855, -31521, 6270, -17855 ; w29 w28 w25 w24 dw 6270, 26722, 26722, -31521 ; w31 w30 w27 w26 ; %3 for rows 2,6 - constants are multiplied by cos_2_16 tab_i_26_sse dw 21407, 27969, 21407, 11585 ; movq-> w05 w04 w01 w00 dw 21407, 11585, -21407, -27969 ; w07 w06 w03 w02 dw 21407, -11585, 21407, -27969 ; w13 w12 w09 w08 dw -21407, 27969, 21407, -11585 ; w15 w14 w11 w10 dw 29692, 25172, 25172, -5906 ; w21 w20 w17 w16 dw 16819, 5906, -29692, -16819 ; w23 w22 w19 w18 dw 16819, -29692, 5906, -16819 ; w29 w28 w25 w24 dw 5906, 25172, 25172, -29692 ; w31 w30 w27 w26 ; %3 for rows 3,5 - constants are multiplied by cos_3_16 tab_i_35_sse dw 19266, 25172, 19266, 10426 ; movq-> w05 w04 w01 w00 dw 19266, 10426, -19266, -25172 ; w07 w06 w03 w02 dw 19266, -10426, 19266, -25172 ; w13 w12 w09 w08 dw -19266, 25172, 19266, -10426 ; w15 w14 w11 w10 dw 26722, 22654, 22654, -5315 ; w21 w20 w17 w16 dw 15137, 5315, -26722, -15137 ; w23 w22 w19 w18 dw 15137, -26722, 5315, -15137 ; w29 w28 w25 w24 dw 5315, 22654, 22654, -26722 ; w31 w30 w27 w26 ;----------------------------------------------------------------------------- ; ; DCT_8_INV_ROW_1_sse INP, OUT, TABLE, ROUNDER ; %macro DCT_8_INV_ROW_1_sse 4 movq mm0, [%1] ; 0 ; x3 x2 x1 x0 movq mm1, [%1+8] ; 1 ; x7 x6 x5 x4 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [%3] ; 3 ; w05 w04 w01 w00 pshufw mm0, mm0, 10001000b ; x2 x0 x2 x0 movq mm4, [%3+8] ; 4 ; w07 w06 w03 w02 movq mm5, mm1 ; 5 ; x7 x6 x5 x4 pmaddwd mm3, mm0 ; x2*w05+x0*w04 x2*w01+x0*w00 movq mm6, [%3+32] ; 6 ; w21 w20 w17 w16 pshufw mm1, mm1, 10001000b ; x6 x4 x6 x4 pmaddwd mm4, mm1 ; x6*w07+x4*w06 x6*w03+x4*w02 movq mm7, [%3+40] ; 7 ; w23 w22 w19 w18 pshufw mm2, mm2, 11011101b ; x3 x1 x3 x1 pmaddwd mm6, mm2 ; x3*w21+x1*w20 x3*w17+x1*w16 pshufw mm5, mm5, 11011101b ; x7 x5 x7 x5 pmaddwd mm7, mm5 ; x7*w23+x5*w22 x7*w19+x5*w18 paddd mm3, [%4] ; +%4 pmaddwd mm0, [%3+16] ; x2*w13+x0*w12 x2*w09+x0*w08 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm1, [%3+24] ; x6*w15+x4*w14 x6*w11+x4*w10 movq mm4, mm3 ; 4 ; a1 a0 pmaddwd mm2, [%3+48] ; x3*w29+x1*w28 x3*w25+x1*w24 paddd mm6, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) pmaddwd mm5, [%3+56] ; x7*w31+x5*w30 x7*w27+x5*w26 paddd mm3, mm6 ; a1+b1 a0+b0 paddd mm0, [%4] ; +%4 psrad mm3, SHIFT_INV_ROW ; y1=a1+b1 y0=a0+b0 paddd mm0, mm1 ; 1 ; a3=sum(even3) a2=sum(even2) psubd mm4, mm6 ; 6 ; a1-b1 a0-b0 movq mm7, mm0 ; 7 ; a3 a2 paddd mm2, mm5 ; 5 ; b3=sum(odd3) b2=sum(odd2) paddd mm0, mm2 ; a3+b3 a2+b2 psrad mm4, SHIFT_INV_ROW ; y6=a1-b1 y7=a0-b0 psubd mm7, mm2 ; 2 ; a3-b3 a2-b2 psrad mm0, SHIFT_INV_ROW ; y3=a3+b3 y2=a2+b2 psrad mm7, SHIFT_INV_ROW ; y4=a3-b3 y5=a2-b2 packssdw mm3, mm0 ; 0 ; y3 y2 y1 y0 packssdw mm7, mm4 ; 4 ; y6 y7 y4 y5 movq [%2], mm3 ; 3 ; save y3 y2 y1 y0 pshufw mm7, mm7, 10110001b ; y7 y6 y5 y4 movq [%2+8], mm7 ; 7 ; save y7 y6 y5 y4 %endmacro ;============================================================================= ; ;============================================================================= ;============================================================================= ; ; The first stage DCT 8x8 - forward DCTs of columns ; ; The %2puts are multiplied ; for rows 0,4 - on cos_4_16, ; for rows 1,7 - on cos_1_16, ; for rows 2,6 - on cos_2_16, ; for rows 3,5 - on cos_3_16 ; and are shifted to the left for rise of accuracy ; ;----------------------------------------------------------------------------- ; ; The 8-point scaled forward DCT algorithm (26a8m) ; ;----------------------------------------------------------------------------- ; ; #define DCT_8_FRW_COL(x, y) ;{ ; short t0, t1, t2, t3, t4, t5, t6, t7; ; short tp03, tm03, tp12, tm12, tp65, tm65; ; short tp465, tm465, tp765, tm765; ; ; t0 = LEFT_SHIFT ( x[0] + x[7] ); ; t1 = LEFT_SHIFT ( x[1] + x[6] ); ; t2 = LEFT_SHIFT ( x[2] + x[5] ); ; t3 = LEFT_SHIFT ( x[3] + x[4] ); ; t4 = LEFT_SHIFT ( x[3] - x[4] ); ; t5 = LEFT_SHIFT ( x[2] - x[5] ); ; t6 = LEFT_SHIFT ( x[1] - x[6] ); ; t7 = LEFT_SHIFT ( x[0] - x[7] ); ; ; tp03 = t0 + t3; ; tm03 = t0 - t3; ; tp12 = t1 + t2; ; tm12 = t1 - t2; ; ; y[0] = tp03 + tp12; ; y[4] = tp03 - tp12; ; ; y[2] = tm03 + tm12 * tg_2_16; ; y[6] = tm03 * tg_2_16 - tm12; ; ; tp65 =(t6 +t5 )*cos_4_16; ; tm65 =(t6 -t5 )*cos_4_16; ; ; tp765 = t7 + tp65; ; tm765 = t7 - tp65; ; tp465 = t4 + tm65; ; tm465 = t4 - tm65; ; ; y[1] = tp765 + tp465 * tg_1_16; ; y[7] = tp765 * tg_1_16 - tp465; ; y[5] = tm765 * tg_3_16 + tm465; ; y[3] = tm765 - tm465 * tg_3_16; ;} ; ;============================================================================= ; ; DCT_8_FRW_COL_4 INP, OUT ; %macro DCT_8_FRW_COL_4 2 LOCAL x0, x1, x2, x3, x4, x5, x6, x7 LOCAL y0, y1, y2, y3, y4, y5, y6, y7 x0 equ [%1 + 0*16] x1 equ [%1 + 1*16] x2 equ [%1 + 2*16] x3 equ [%1 + 3*16] x4 equ [%1 + 4*16] x5 equ [%1 + 5*16] x6 equ [%1 + 6*16] x7 equ [%1 + 7*16] y0 equ [%2 + 0*16] y1 equ [%2 + 1*16] y2 equ [%2 + 2*16] y3 equ [%2 + 3*16] y4 equ [%2 + 4*16] y5 equ [%2 + 5*16] y6 equ [%2 + 6*16] y7 equ [%2 + 7*16] movq mm0, x1 ; 0 ; x1 movq mm1, x6 ; 1 ; x6 movq mm2, mm0 ; 2 ; x1 movq mm3, x2 ; 3 ; x2 paddsw mm0, mm1 ; t1 = x[1] + x[6] movq mm4, x5 ; 4 ; x5 psllw mm0, SHIFT_FRW_COL ; t1 movq mm5, x0 ; 5 ; x0 paddsw mm4, mm3 ; t2 = x[2] + x[5] paddsw mm5, x7 ; t0 = x[0] + x[7] psllw mm4, SHIFT_FRW_COL ; t2 movq mm6, mm0 ; 6 ; t1 psubsw mm2, mm1 ; 1 ; t6 = x[1] - x[6] movq mm1, [tg_2_16] ; 1 ; tg_2_16 psubsw mm0, mm4 ; tm12 = t1 - t2 movq mm7, x3 ; 7 ; x3 pmulhw mm1, mm0 ; tm12*tg_2_16 paddsw mm7, x4 ; t3 = x[3] + x[4] psllw mm5, SHIFT_FRW_COL ; t0 paddsw mm6, mm4 ; 4 ; tp12 = t1 + t2 psllw mm7, SHIFT_FRW_COL ; t3 movq mm4, mm5 ; 4 ; t0 psubsw mm5, mm7 ; tm03 = t0 - t3 paddsw mm1, mm5 ; y2 = tm03 + tm12*tg_2_16 paddsw mm4, mm7 ; 7 ; tp03 = t0 + t3 por mm1, [one_corr] ; correction y2 +0.5 psllw mm2, SHIFT_FRW_COL+1 ; t6 pmulhw mm5, [tg_2_16] ; tm03*tg_2_16 movq mm7, mm4 ; 7 ; tp03 psubsw mm3, x5 ; t5 = x[2] - x[5] psubsw mm4, mm6 ; y4 = tp03 - tp12 movq y2, mm1 ; 1 ; save y2 paddsw mm7, mm6 ; 6 ; y0 = tp03 + tp12 movq mm1, x3 ; 1 ; x3 psllw mm3, SHIFT_FRW_COL+1 ; t5 psubsw mm1, x4 ; t4 = x[3] - x[4] movq mm6, mm2 ; 6 ; t6 movq y4, mm4 ; 4 ; save y4 paddsw mm2, mm3 ; t6 + t5 pmulhw mm2, [ocos_4_16] ; tp65 = (t6 + t5)*cos_4_16 psubsw mm6, mm3 ; 3 ; t6 - t5 pmulhw mm6, [ocos_4_16] ; tm65 = (t6 - t5)*cos_4_16 psubsw mm5, mm0 ; 0 ; y6 = tm03*tg_2_16 - tm12 por mm5, [one_corr] ; correction y6 +0.5 psllw mm1, SHIFT_FRW_COL ; t4 por mm2, [one_corr] ; correction tp65 +0.5 movq mm4, mm1 ; 4 ; t4 movq mm3, x0 ; 3 ; x0 paddsw mm1, mm6 ; tp465 = t4 + tm65 psubsw mm3, x7 ; t7 = x[0] - x[7] psubsw mm4, mm6 ; 6 ; tm465 = t4 - tm65 movq mm0, [tg_1_16] ; 0 ; tg_1_16 psllw mm3, SHIFT_FRW_COL ; t7 movq mm6, [tg_3_16] ; 6 ; tg_3_16 pmulhw mm0, mm1 ; tp465*tg_1_16 movq y0, mm7 ; 7 ; save y0 pmulhw mm6, mm4 ; tm465*tg_3_16 movq y6, mm5 ; 5 ; save y6 movq mm7, mm3 ; 7 ; t7 movq mm5, [tg_3_16] ; 5 ; tg_3_16 psubsw mm7, mm2 ; tm765 = t7 - tp65 paddsw mm3, mm2 ; 2 ; tp765 = t7 + tp65 pmulhw mm5, mm7 ; tm765*tg_3_16 paddsw mm0, mm3 ; y1 = tp765 + tp465*tg_1_16 paddsw mm6, mm4 ; tm465*tg_3_16 pmulhw mm3, [tg_1_16] ; tp765*tg_1_16 por mm0, [one_corr] ; correction y1 +0.5 paddsw mm5, mm7 ; tm765*tg_3_16 psubsw mm7, mm6 ; 6 ; y3 = tm765 - tm465*tg_3_16 movq y1, mm0 ; 0 ; save y1 paddsw mm5, mm4 ; 4 ; y5 = tm765*tg_3_16 + tm465 movq y3, mm7 ; 7 ; save y3 psubsw mm3, mm1 ; 1 ; y7 = tp765*tg_1_16 - tp465 movq y5, mm5 ; 5 ; save y5 movq y7, mm3 ; 3 ; save y7 %endmacro ; ; DCT_8_INV_COL_4 INP,OUT ; %macro DCT_8_INV_COL_4 2 movq mm0, [tg_3_16] movq mm3, [%1+16*3] movq mm1, mm0 ; tg_3_16 movq mm5, [%1+16*5] pmulhw mm0, mm3 ; x3*(tg_3_16-1) movq mm4, [tg_1_16] pmulhw mm1, mm5 ; x5*(tg_3_16-1) movq mm7, [%1+16*7] movq mm2, mm4 ; tg_1_16 movq mm6, [%1+16*1] pmulhw mm4, mm7 ; x7*tg_1_16 paddsw mm0, mm3 ; x3*tg_3_16 pmulhw mm2, mm6 ; x1*tg_1_16 paddsw mm1, mm3 ; x3+x5*(tg_3_16-1) psubsw mm0, mm5 ; x3*tg_3_16-x5 = tm35 movq mm3, [ocos_4_16] paddsw mm1, mm5 ; x3+x5*tg_3_16 = tp35 paddsw mm4, mm6 ; x1+tg_1_16*x7 = tp17 psubsw mm2, mm7 ; x1*tg_1_16-x7 = tm17 movq mm5, mm4 ; tp17 movq mm6, mm2 ; tm17 paddsw mm5, mm1 ; tp17+tp35 = b0 psubsw mm6, mm0 ; tm17-tm35 = b3 psubsw mm4, mm1 ; tp17-tp35 = t1 paddsw mm2, mm0 ; tm17+tm35 = t2 movq mm7, [tg_2_16] movq mm1, mm4 ; t1 ; movq [SCRATCH+0], mm5 ; save b0 movq [%2+3*16], mm5 ; save b0 paddsw mm1, mm2 ; t1+t2 ; movq [SCRATCH+8], mm6 ; save b3 movq [%2+5*16], mm6 ; save b3 psubsw mm4, mm2 ; t1-t2 movq mm5, [%1+2*16] movq mm0, mm7 ; tg_2_16 movq mm6, [%1+6*16] pmulhw mm0, mm5 ; x2*tg_2_16 pmulhw mm7, mm6 ; x6*tg_2_16 ; slot pmulhw mm1, mm3 ; ocos_4_16*(t1+t2) = b1/2 ; slot movq mm2, [%1+0*16] pmulhw mm4, mm3 ; ocos_4_16*(t1-t2) = b2/2 psubsw mm0, mm6 ; t2*tg_2_16-x6 = tm26 movq mm3, mm2 ; x0 movq mm6, [%1+4*16] paddsw mm7, mm5 ; x2+x6*tg_2_16 = tp26 paddsw mm2, mm6 ; x0+x4 = tp04 psubsw mm3, mm6 ; x0-x4 = tm04 movq mm5, mm2 ; tp04 movq mm6, mm3 ; tm04 psubsw mm2, mm7 ; tp04-tp26 = a3 paddsw mm3, mm0 ; tm04+tm26 = a1 paddsw mm1, mm1 ; b1 paddsw mm4, mm4 ; b2 paddsw mm5, mm7 ; tp04+tp26 = a0 psubsw mm6, mm0 ; tm04-tm26 = a2 movq mm7, mm3 ; a1 movq mm0, mm6 ; a2 paddsw mm3, mm1 ; a1+b1 paddsw mm6, mm4 ; a2+b2 psraw mm3, SHIFT_INV_COL ; dst1 psubsw mm7, mm1 ; a1-b1 psraw mm6, SHIFT_INV_COL ; dst2 psubsw mm0, mm4 ; a2-b2 ; movq mm1, [SCRATCH+0] ; load b0 movq mm1, [%2+3*16] ; load b0 psraw mm7, SHIFT_INV_COL ; dst6 movq mm4, mm5 ; a0 psraw mm0, SHIFT_INV_COL ; dst5 movq [%2+1*16], mm3 paddsw mm5, mm1 ; a0+b0 movq [%2+2*16], mm6 psubsw mm4, mm1 ; a0-b0 ; movq mm3, [SCRATCH+8] ; load b3 movq mm3, [%2+5*16] ; load b3 psraw mm5, SHIFT_INV_COL ; dst0 movq mm6, mm2 ; a3 psraw mm4, SHIFT_INV_COL ; dst7 movq [%2+5*16], mm0 paddsw mm2, mm3 ; a3+b3 movq [%2+6*16], mm7 psubsw mm6, mm3 ; a3-b3 movq [%2+0*16], mm5 psraw mm2, SHIFT_INV_COL ; dst3 movq [%2+7*16], mm4 psraw mm6, SHIFT_INV_COL ; dst4 movq [%2+3*16], mm2 movq [%2+4*16], mm6 %endmacro section .text ;============================================================================= ; ; void idct_mmx (short * const src_result); ; ;============================================================================= align 16 cglobal idct_mmx idct_mmx mov eax, dword [esp + 4] DCT_8_INV_ROW_1 eax+0, eax+0, tab_i_04, rounder_0 DCT_8_INV_ROW_1 eax+16, eax+16, tab_i_17, rounder_1 DCT_8_INV_ROW_1 eax+32, eax+32, tab_i_26, rounder_2 DCT_8_INV_ROW_1 eax+48, eax+48, tab_i_35, rounder_3 DCT_8_INV_ROW_1 eax+64, eax+64, tab_i_04, rounder_4 DCT_8_INV_ROW_1 eax+80, eax+80, tab_i_35, rounder_5 DCT_8_INV_ROW_1 eax+96, eax+96, tab_i_26, rounder_6 DCT_8_INV_ROW_1 eax+112, eax+112, tab_i_17, rounder_7 DCT_8_INV_COL_4 eax+0,eax+0 DCT_8_INV_COL_4 eax+8,eax+8 ret ;============================================================================= ; ; void idct_sse (short * const src_result); ; ;============================================================================= align 16 cglobal idct_xmm idct_xmm mov eax, dword [esp + 4] DCT_8_INV_ROW_1_sse eax+0, eax+0, tab_i_04_sse, rounder_0 DCT_8_INV_ROW_1_sse eax+16, eax+16, tab_i_17_sse, rounder_1 DCT_8_INV_ROW_1_sse eax+32, eax+32, tab_i_26_sse, rounder_2 DCT_8_INV_ROW_1_sse eax+48, eax+48, tab_i_35_sse, rounder_3 DCT_8_INV_ROW_1_sse eax+64, eax+64, tab_i_04_sse, rounder_4 DCT_8_INV_ROW_1_sse eax+80, eax+80, tab_i_35_sse, rounder_5 DCT_8_INV_ROW_1_sse eax+96, eax+96, tab_i_26_sse, rounder_6 DCT_8_INV_ROW_1_sse eax+112, eax+112, tab_i_17_sse, rounder_7 DCT_8_INV_COL_4 eax+0, eax+0 DCT_8_INV_COL_4 eax+8, eax+8 retxvid_20020412/xvidcore/src/dct/fdct.c0100644000100600001440000002334307442022627016600 0ustar michaelusers/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ /* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose. In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * */ /* This routine is a slow-but-accurate integer implementation of the * forward DCT (Discrete Cosine Transform). Taken from the IJG software * * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT * on each column. Direct algorithms are also available, but they are * much more complex and seem not to be any faster when reduced to code. * * This implementation is based on an algorithm described in * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. * The primary algorithm described there uses 11 multiplies and 29 adds. * We use their alternate method with 12 multiplies and 32 adds. * The advantage of this method is that no data path contains more than one * multiplication; this allows a very simple and accurate implementation in * scaled fixed-point arithmetic, with a minimal number of shifts. * * The poop on this scaling stuff is as follows: * * Each 1-D DCT step produces outputs which are a factor of sqrt(N) * larger than the true DCT outputs. The final outputs are therefore * a factor of N larger than desired; since N=8 this can be cured by * a simple right shift at the end of the algorithm. The advantage of * this arrangement is that we save two multiplications per 1-D DCT, * because the y0 and y4 outputs need not be divided by sqrt(N). * In the IJG code, this factor of 8 is removed by the quantization step * (in jcdctmgr.c), here it is removed. * * We have to do addition and subtraction of the integer inputs, which * is no problem, and multiplication by fractional constants, which is * a problem to do in integer arithmetic. We multiply all the constants * by CONST_SCALE and convert them to integer constants (thus retaining * CONST_BITS bits of precision in the constants). After doing a * multiplication we have to divide the product by CONST_SCALE, with proper * rounding, to produce the correct output. This division can be done * cheaply as a right shift of CONST_BITS bits. We postpone shifting * as long as possible so that partial sums can be added together with * full fractional precision. * * The outputs of the first pass are scaled up by PASS1_BITS bits so that * they are represented to better-than-integral precision. These outputs * require 8 + PASS1_BITS + 3 bits; this fits in a 16-bit word * with the recommended scaling. (For 12-bit sample data, the intermediate * array is INT32 anyway.) * * To avoid overflow of the 32-bit intermediate results in pass 2, we must * have 8 + CONST_BITS + PASS1_BITS <= 26. Error analysis * shows that the values given below are the most effective. * * We can gain a little more speed, with a further compromise in accuracy, * by omitting the addition in a descaling shift. This yields an incorrectly * rounded result half the time... */ #include "fdct.h" #define USE_ACCURATE_ROUNDING #define RIGHT_SHIFT(x, shft) ((x) >> (shft)) #ifdef USE_ACCURATE_ROUNDING #define ONE ((int) 1) #define DESCALE(x, n) RIGHT_SHIFT((x) + (ONE << ((n) - 1)), n) #else #define DESCALE(x, n) RIGHT_SHIFT(x, n) #endif #define CONST_BITS 13 #define PASS1_BITS 2 #define FIX_0_298631336 ((int) 2446) /* FIX(0.298631336) */ #define FIX_0_390180644 ((int) 3196) /* FIX(0.390180644) */ #define FIX_0_541196100 ((int) 4433) /* FIX(0.541196100) */ #define FIX_0_765366865 ((int) 6270) /* FIX(0.765366865) */ #define FIX_0_899976223 ((int) 7373) /* FIX(0.899976223) */ #define FIX_1_175875602 ((int) 9633) /* FIX(1.175875602) */ #define FIX_1_501321110 ((int) 12299) /* FIX(1.501321110) */ #define FIX_1_847759065 ((int) 15137) /* FIX(1.847759065) */ #define FIX_1_961570560 ((int) 16069) /* FIX(1.961570560) */ #define FIX_2_053119869 ((int) 16819) /* FIX(2.053119869) */ #define FIX_2_562915447 ((int) 20995) /* FIX(2.562915447) */ #define FIX_3_072711026 ((int) 25172) /* FIX(3.072711026) */ // function pointer fdctFuncPtr fdct; /* * Perform an integer forward DCT on one block of samples. */ void fdct_int32(short * const block) { int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; int tmp10, tmp11, tmp12, tmp13; int z1, z2, z3, z4, z5; short *blkptr; int *dataptr; int data[64]; int i; /* Pass 1: process rows. */ /* Note results are scaled up by sqrt(8) compared to a true DCT; */ /* furthermore, we scale the results by 2**PASS1_BITS. */ dataptr = data; blkptr = block; for (i = 0; i < 8; i++) { tmp0 = blkptr[0] + blkptr[7]; tmp7 = blkptr[0] - blkptr[7]; tmp1 = blkptr[1] + blkptr[6]; tmp6 = blkptr[1] - blkptr[6]; tmp2 = blkptr[2] + blkptr[5]; tmp5 = blkptr[2] - blkptr[5]; tmp3 = blkptr[3] + blkptr[4]; tmp4 = blkptr[3] - blkptr[4]; /* Even part per LL&M figure 1 --- note that published figure is faulty; * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". */ tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[0] = (tmp10 + tmp11) << PASS1_BITS; dataptr[4] = (tmp10 - tmp11) << PASS1_BITS; z1 = (tmp12 + tmp13) * FIX_0_541196100; dataptr[2] = DESCALE(z1 + tmp13 * FIX_0_765366865, CONST_BITS - PASS1_BITS); dataptr[6] = DESCALE(z1 + tmp12 * (-FIX_1_847759065), CONST_BITS - PASS1_BITS); /* Odd part per figure 8 --- note paper omits factor of sqrt(2). * cK represents cos(K*pi/16). * i0..i3 in the paper are tmp4..tmp7 here. */ z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */ tmp4 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */ tmp5 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */ tmp6 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */ tmp7 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */ z1 *= -FIX_0_899976223; /* sqrt(2) * (c7-c3) */ z2 *= -FIX_2_562915447; /* sqrt(2) * (-c1-c3) */ z3 *= -FIX_1_961570560; /* sqrt(2) * (-c3-c5) */ z4 *= -FIX_0_390180644; /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; dataptr[7] = DESCALE(tmp4 + z1 + z3, CONST_BITS - PASS1_BITS); dataptr[5] = DESCALE(tmp5 + z2 + z4, CONST_BITS - PASS1_BITS); dataptr[3] = DESCALE(tmp6 + z2 + z3, CONST_BITS - PASS1_BITS); dataptr[1] = DESCALE(tmp7 + z1 + z4, CONST_BITS - PASS1_BITS); dataptr += 8; /* advance pointer to next row */ blkptr += 8; } /* Pass 2: process columns. * We remove the PASS1_BITS scaling, but leave the results scaled up * by an overall factor of 8. */ dataptr = data; for (i = 0; i < 8; i++) { tmp0 = dataptr[0] + dataptr[56]; tmp7 = dataptr[0] - dataptr[56]; tmp1 = dataptr[8] + dataptr[48]; tmp6 = dataptr[8] - dataptr[48]; tmp2 = dataptr[16] + dataptr[40]; tmp5 = dataptr[16] - dataptr[40]; tmp3 = dataptr[24] + dataptr[32]; tmp4 = dataptr[24] - dataptr[32]; /* Even part per LL&M figure 1 --- note that published figure is faulty; * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". */ tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[0] = DESCALE(tmp10 + tmp11, PASS1_BITS); dataptr[32] = DESCALE(tmp10 - tmp11, PASS1_BITS); z1 = (tmp12 + tmp13) * FIX_0_541196100; dataptr[16] = DESCALE(z1 + tmp13 * FIX_0_765366865, CONST_BITS + PASS1_BITS); dataptr[48] = DESCALE(z1 + tmp12 * (-FIX_1_847759065), CONST_BITS + PASS1_BITS); /* Odd part per figure 8 --- note paper omits factor of sqrt(2). * cK represents cos(K*pi/16). * i0..i3 in the paper are tmp4..tmp7 here. */ z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */ tmp4 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */ tmp5 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */ tmp6 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */ tmp7 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */ z1 *= -FIX_0_899976223; /* sqrt(2) * (c7-c3) */ z2 *= -FIX_2_562915447; /* sqrt(2) * (-c1-c3) */ z3 *= -FIX_1_961570560; /* sqrt(2) * (-c3-c5) */ z4 *= -FIX_0_390180644; /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; dataptr[56] = DESCALE(tmp4 + z1 + z3, CONST_BITS + PASS1_BITS); dataptr[40] = DESCALE(tmp5 + z2 + z4, CONST_BITS + PASS1_BITS); dataptr[24] = DESCALE(tmp6 + z2 + z3, CONST_BITS + PASS1_BITS); dataptr[8] = DESCALE(tmp7 + z1 + z4, CONST_BITS + PASS1_BITS); dataptr++; /* advance pointer to next column */ } /* descale */ for (i = 0; i < 64; i++) block[i] = (short int) DESCALE(data[i], 3); } xvid_20020412/xvidcore/src/dct/fdct.h0100644000100600001440000000034207450636116016602 0ustar michaelusers#ifndef _FDCT_H_ #define _FDCT_H_ typedef void (fdctFunc)(short * const block); typedef fdctFunc* fdctFuncPtr; extern fdctFuncPtr fdct; fdctFunc fdct_int32; fdctFunc fdct_mmx; fdctFunc fdct_altivec; #endif /* _FDCT_H_ */ xvid_20020412/xvidcore/src/dct/idct.c0100644000100600001440000002112707442022627016601 0ustar michaelusers/* idct.c, inverse fast discrete cosine transform */ /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ /* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose. In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * * MPEG2AVI * -------- * v0.16B33 renamed the initialization function to init_idct_int32() * v0.16B32 removed the unused idct_row() and idct_col() functions * v0.16B3 changed var declarations to static, to enforce data align * v0.16B22 idct_FAST() renamed to idct_int32() * also merged idct_FAST() into a single function, to help VC++ * optimize it. * * v0.14 changed int to long, to avoid confusion when compiling on x86 * platform ( in VC++ "int" -> 32bits ) */ /**********************************************************/ /* inverse two dimensional DCT, Chen-Wang algorithm */ /* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */ /* 32-bit integer arithmetic (8 bit coefficients) */ /* 11 mults, 29 adds per DCT */ /* sE, 18.8.91 */ /**********************************************************/ /* coefficients extended to 12 bit for IEEE1180-1990 */ /* compliance sE, 2.1.94 */ /**********************************************************/ /* this code assumes >> to be a two's-complement arithmetic */ /* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ //#include #include "idct.h" #define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */ #define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */ #define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */ #define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */ #define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */ #define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */ /* global declarations */ //void init_idct_int32 (void); //void idct_int32 (short *block); /* private data */ static short iclip[1024]; /* clipping table */ static short *iclp; /* private prototypes */ //static void idctrow _ANSI_ARGS_((short *blk)); //static void idctcol _ANSI_ARGS_((short *blk)); /* row (horizontal) IDCT * * 7 pi 1 * dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l ) * l=0 8 2 * * where: c[0] = 128 * c[1..7] = 128*sqrt(2) */ /* static void idctrow(blk) short *blk; { int X0, X1, X2, X3, X4, X5, X6, X7, X8; // shortcut if (!((X1 = blk[4]<<11) | (X2 = blk[6]) | (X3 = blk[2]) | (X4 = blk[1]) | (X5 = blk[7]) | (X6 = blk[5]) | (X7 = blk[3]))) { blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3; return; } X0 = (blk[0]<<11) + 128; // for proper rounding in the fourth stage // first stage X8 = W7*(X4+X5); X4 = X8 + (W1-W7)*X4; X5 = X8 - (W1+W7)*X5; X8 = W3*(X6+X7); X6 = X8 - (W3-W5)*X6; X7 = X8 - (W3+W5)*X7; // second stage X8 = X0 + X1; X0 -= X1; X1 = W6*(X3+X2); X2 = X1 - (W2+W6)*X2; X3 = X1 + (W2-W6)*X3; X1 = X4 + X6; X4 -= X6; X6 = X5 + X7; X5 -= X7; // third stage X7 = X8 + X3; X8 -= X3; X3 = X0 + X2; X0 -= X2; X2 = (181*(X4+X5)+128)>>8; X4 = (181*(X4-X5)+128)>>8; // fourth stage blk[0] = (X7+X1)>>8; blk[1] = (X3+X2)>>8; blk[2] = (X0+X4)>>8; blk[3] = (X8+X6)>>8; blk[4] = (X8-X6)>>8; blk[5] = (X0-X4)>>8; blk[6] = (X3-X2)>>8; blk[7] = (X7-X1)>>8; }*/ /* column (vertical) IDCT * * 7 pi 1 * dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l ) * l=0 8 2 * * where: c[0] = 1/1024 * c[1..7] = (1/1024)*sqrt(2) */ /* static void idctcol(blk) short *blk; { int X0, X1, X2, X3, X4, X5, X6, X7, X8; // shortcut if (!((X1 = (blk[8*4]<<8)) | (X2 = blk[8*6]) | (X3 = blk[8*2]) | (X4 = blk[8*1]) | (X5 = blk[8*7]) | (X6 = blk[8*5]) | (X7 = blk[8*3]))) { blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]= iclp[(blk[8*0]+32)>>6]; return; } X0 = (blk[8*0]<<8) + 8192; // first stage X8 = W7*(X4+X5) + 4; X4 = (X8+(W1-W7)*X4)>>3; X5 = (X8-(W1+W7)*X5)>>3; X8 = W3*(X6+X7) + 4; X6 = (X8-(W3-W5)*X6)>>3; X7 = (X8-(W3+W5)*X7)>>3; // second stage X8 = X0 + X1; X0 -= X1; X1 = W6*(X3+X2) + 4; X2 = (X1-(W2+W6)*X2)>>3; X3 = (X1+(W2-W6)*X3)>>3; X1 = X4 + X6; X4 -= X6; X6 = X5 + X7; X5 -= X7; // third stage X7 = X8 + X3; X8 -= X3; X3 = X0 + X2; X0 -= X2; X2 = (181*(X4+X5)+128)>>8; X4 = (181*(X4-X5)+128)>>8; // fourth stage blk[8*0] = iclp[(X7+X1)>>14]; blk[8*1] = iclp[(X3+X2)>>14]; blk[8*2] = iclp[(X0+X4)>>14]; blk[8*3] = iclp[(X8+X6)>>14]; blk[8*4] = iclp[(X8-X6)>>14]; blk[8*5] = iclp[(X0-X4)>>14]; blk[8*6] = iclp[(X3-X2)>>14]; blk[8*7] = iclp[(X7-X1)>>14]; }*/ // function pointer idctFuncPtr idct; /* two dimensional inverse discrete cosine transform */ //void j_rev_dct(block) //short *block; void idct_int32(short * const block) { // idct_int32_init() must be called before the first call to this function! /*int i; long i; for (i=0; i<8; i++) idctrow(block+8*i); for (i=0; i<8; i++) idctcol(block+i);*/ static short *blk; static long i; static long X0, X1, X2, X3, X4, X5, X6, X7, X8; for (i=0; i<8; i++) // idct rows { blk = block+(i<<3); if (!((X1 = blk[4]<<11) | (X2 = blk[6]) | (X3 = blk[2]) | (X4 = blk[1]) | (X5 = blk[7]) | (X6 = blk[5]) | (X7 = blk[3]))) { blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3; continue; } X0 = (blk[0]<<11) + 128; // for proper rounding in the fourth stage // first stage X8 = W7*(X4+X5); X4 = X8 + (W1-W7)*X4; X5 = X8 - (W1+W7)*X5; X8 = W3*(X6+X7); X6 = X8 - (W3-W5)*X6; X7 = X8 - (W3+W5)*X7; // second stage X8 = X0 + X1; X0 -= X1; X1 = W6*(X3+X2); X2 = X1 - (W2+W6)*X2; X3 = X1 + (W2-W6)*X3; X1 = X4 + X6; X4 -= X6; X6 = X5 + X7; X5 -= X7; // third stage X7 = X8 + X3; X8 -= X3; X3 = X0 + X2; X0 -= X2; X2 = (181*(X4+X5)+128)>>8; X4 = (181*(X4-X5)+128)>>8; // fourth stage blk[0] = (short)((X7+X1)>>8); blk[1] = (short)((X3+X2)>>8); blk[2] = (short)((X0+X4)>>8); blk[3] = (short)((X8+X6)>>8); blk[4] = (short)((X8-X6)>>8); blk[5] = (short)((X0-X4)>>8); blk[6] = (short)((X3-X2)>>8); blk[7] = (short)((X7-X1)>>8); } // end for ( i = 0; i < 8; ++i ) IDCT-rows for (i=0; i<8; i++) // idct columns { blk = block + i; // shortcut if (!((X1 = (blk[8*4]<<8)) | (X2 = blk[8*6]) | (X3 = blk[8*2]) | (X4 = blk[8*1]) | (X5 = blk[8*7]) | (X6 = blk[8*5]) | (X7 = blk[8*3]))) { blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]= blk[8*5]=blk[8*6]=blk[8*7]=iclp[(blk[8*0]+32)>>6]; continue; } X0 = (blk[8*0]<<8) + 8192; // first stage X8 = W7*(X4+X5) + 4; X4 = (X8+(W1-W7)*X4)>>3; X5 = (X8-(W1+W7)*X5)>>3; X8 = W3*(X6+X7) + 4; X6 = (X8-(W3-W5)*X6)>>3; X7 = (X8-(W3+W5)*X7)>>3; // second stage X8 = X0 + X1; X0 -= X1; X1 = W6*(X3+X2) + 4; X2 = (X1-(W2+W6)*X2)>>3; X3 = (X1+(W2-W6)*X3)>>3; X1 = X4 + X6; X4 -= X6; X6 = X5 + X7; X5 -= X7; // third stage X7 = X8 + X3; X8 -= X3; X3 = X0 + X2; X0 -= X2; X2 = (181*(X4+X5)+128)>>8; X4 = (181*(X4-X5)+128)>>8; // fourth stage blk[8*0] = iclp[(X7+X1)>>14]; blk[8*1] = iclp[(X3+X2)>>14]; blk[8*2] = iclp[(X0+X4)>>14]; blk[8*3] = iclp[(X8+X6)>>14]; blk[8*4] = iclp[(X8-X6)>>14]; blk[8*5] = iclp[(X0-X4)>>14]; blk[8*6] = iclp[(X3-X2)>>14]; blk[8*7] = iclp[(X7-X1)>>14]; } } // end function idct_int32(block) //void //idct_int32_init() void idct_int32_init() { int i; iclp = iclip+512; for (i= -512; i<512; i++) iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i); } xvid_20020412/xvidcore/src/dct/idct.h0100644000100600001440000000041607450636116016607 0ustar michaelusers#ifndef _IDCT_H_ #define _IDCT_H_ void idct_int32_init(); typedef void (idctFunc)(short * const block); typedef idctFunc* idctFuncPtr; extern idctFuncPtr idct; idctFunc idct_int32; idctFunc idct_mmx; idctFunc idct_xmm; idctFunc idct_altivec; #endif /* _IDCT_H_ */ xvid_20020412/xvidcore/src/dct/ppc_asm/0040755000100600001440000000000007455522446017144 5ustar michaelusersxvid_20020412/xvidcore/src/dct/ppc_asm/CVS/0040755000100600001440000000000007455522446017577 5ustar michaelusersxvid_20020412/xvidcore/src/dct/ppc_asm/CVS/Root0100644000100600001440000000004607455522445020441 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/dct/ppc_asm/CVS/Repository0100644000100600001440000000003107455522445021667 0ustar michaelusersxvidcore/src/dct/ppc_asm xvid_20020412/xvidcore/src/dct/ppc_asm/CVS/Entries0100644000100600001440000000014007455522446021123 0ustar michaelusers/fdct_altivec.s/1.2/Tue Apr 2 15:53:03 2002// /idct_altivec.s/1.3/Tue Apr 2 15:53:03 2002// D xvid_20020412/xvidcore/src/dct/ppc_asm/fdct_altivec.s0100644000100600001440000001352507452351737021762 0ustar michaelusers .file "dct_vec_tmpl.c" gcc2_compiled.: .globl PostScale .section ".data" .align 4 .type PostScale,@object .size PostScale,128 PostScale: .long 268375601 .long 350687952 .long 268374736 .long 350688817 .long 372317896 .long 486414872 .long 372316696 .long 486416072 .long 350690558 .long 458234004 .long 350689428 .long 458235134 .long 315628056 .long 412358175 .long 315627039 .long 412359192 .long 268375601 .long 350687952 .long 268374736 .long 350688817 .long 315628056 .long 412358175 .long 315627039 .long 412359192 .long 350690558 .long 458234004 .long 350689428 .long 458235134 .long 372317896 .long 486414872 .long 372316696 .long 486416072 .section ".rodata" .align 4 .LC0: .long 1518492290 .long 1518492290 .long 1518492290 .long 1518492290 .align 4 .LC1: .long 889533701 .long 889533701 .long 889533701 .long 889533701 .align 4 .LC2: .long 427170166 .long 427170166 .long 427170166 .long 427170166 .align 4 .LC3: .long 1434932615 .long 1434932615 .long 1434932615 .long 1434932615 .align 4 .LC4: .long -1518426754 .long -1518426754 .long -1518426754 .long -1518426754 .align 4 .LC5: .long -1434867079 .long -1434867079 .long -1434867079 .long -1434867079 .section ".text" .align 2 .globl fdct_altivec .type fdct_altivec,@function fdct_altivec: stwu 1,-368(1) mflr 0 stw 14,296(1) stw 15,300(1) stw 16,304(1) stw 17,308(1) stw 18,312(1) stw 19,316(1) stw 20,320(1) stw 21,324(1) stw 22,328(1) stw 23,332(1) stw 24,336(1) stw 25,340(1) stw 26,344(1) stw 27,348(1) stw 28,352(1) stw 29,356(1) stw 30,360(1) stw 31,364(1) stw 0,372(1) addi 0,0,272 stvx 31,1,0 lvx 0,0,3 addi 23,1,16 vxor %v3,%v3,%v3 addi 18,3,16 stvx 0,0,23 lvx 1,0,18 addi 24,1,32 addi 17,3,32 stvx 1,0,24 lvx 0,0,17 addi 25,1,48 addi 20,3,48 stvx 0,0,25 lvx 1,0,20 addi 26,1,64 addi 19,3,64 stvx 1,0,26 lvx 0,0,19 addi 28,1,80 addi 21,3,80 stvx 0,0,28 lvx 1,0,21 addi 27,1,96 addi 22,3,96 stvx 1,0,27 lvx 0,0,22 addi 7,1,112 stvx 0,0,7 addi 16,3,112 lvx 1,0,16 addi 14,1,128 stvx 1,0,14 lvx 0,0,23 lis 11,.LC0@ha lvx 12,0,26 la 11,.LC0@l(11) lvx 13,0,28 lis 8,.LC1@ha lvx 11,0,7 la 8,.LC1@l(8) lvx 9,0,24 vaddshs 6,0,1 lis 10,.LC4@ha vsubshs 5,0,1 lvx 10,0,25 la 10,.LC4@l(10) lvx 0,0,27 vaddshs 7,12,13 lis 9,.LC2@ha vsubshs 31,12,13 lvx 15,0,11 addi 29,1,144 vaddshs 13,9,11 lvx 19,0,8 la 9,.LC2@l(9) vsubshs 9,9,11 lvx 16,0,10 addi 4,1,208 vaddshs 12,10,0 lvx 2,0,9 lis 11,.LC3@ha vsubshs 4,6,7 la 11,.LC3@l(11) vaddshs 11,6,7 lis 9,.LC5@ha lvx 14,0,11 vsubshs 10,10,0 addi 6,1,176 vsubshs 6,13,12 la 9,.LC5@l(9) vaddshs 7,13,12 lvx 17,0,9 addi 5,1,240 vaddshs 12,9,10 addi 10,1,160 vsubshs 1,11,7 addi 8,1,256 vaddshs 0,11,7 lis 9,PostScale@ha vmhraddshs 11,12,15,5 stvx 0,0,29 vsubshs 13,9,10 stvx 1,0,4 vmhraddshs 1,4,19,3 la 9,PostScale@l(9) vmhraddshs 10,13,15,31 addi 11,1,224 vmhraddshs 7,12,16,5 addi 15,1,192 vmhraddshs 5,11,2,3 addi 0,9,16 vmhraddshs 9,13,16,31 mtctr 0 addi 30,9,32 vmhraddshs 0,6,19,4 addi 0,9,48 vmhraddshs 13,10,2,11 addi 31,9,64 vsubshs 1,1,6 stvx 0,0,6 mtlr 31 stvx 1,0,5 vsubshs 0,5,10 stvx 13,0,10 vmhraddshs 12,7,14,9 stvx 0,0,8 vmhraddshs 6,9,17,7 lvx 18,0,9 addi 12,9,80 stvx 12,0,11 stvx 6,0,15 lvx 13,0,4 addi 31,9,96 lvx 12,0,29 addi 9,9,112 lvx 0,0,11 lvx 4,0,5 lvx 5,0,8 lvx 11,0,10 vmrghh 1,12,13 lvx 9,0,6 vmrglh 12,12,13 vmrghh 8,6,5 vmrghh 10,11,0 vmrghh 13,9,4 vmrglh 11,11,0 vmrghh 7,10,8 vmrghh 0,1,13 vmrglh 1,1,13 vmrghh 13,0,7 stvx 13,0,23 vmrglh 9,9,4 vmrglh 6,6,5 vmrglh 10,10,8 vmrglh 0,0,7 stvx 0,0,24 vmrghh 8,11,6 vmrghh 13,12,9 vmrghh 0,1,10 stvx 0,0,25 vmrglh 1,1,10 stvx 1,0,26 vmrglh 11,11,6 vmrghh 0,13,8 vmrglh 12,12,9 stvx 0,0,28 vmrglh 13,13,8 stvx 13,0,27 vmrghh 0,12,11 stvx 0,0,7 vmrglh 12,12,11 stvx 12,0,14 lvx 0,0,23 lvx 11,0,26 lvx 13,0,28 lvx 8,0,24 lvx 9,0,7 vaddshs 6,0,12 lvx 1,0,27 vsubshs 5,0,12 mfctr 7 lvx 10,0,25 vaddshs 7,11,13 vsubshs 31,11,13 vaddshs 13,8,9 vsubshs 4,6,7 vaddshs 12,10,1 vaddshs 11,6,7 vsubshs 9,8,9 vsubshs 10,10,1 vsubshs 6,13,12 vaddshs 7,13,12 vaddshs 12,9,10 vsubshs 1,11,7 vaddshs 0,11,7 vmhraddshs 11,12,15,5 stvx 0,0,29 vsubshs 13,9,10 stvx 1,0,4 vmhraddshs 1,4,19,3 vmhraddshs 10,13,15,31 vmhraddshs 7,12,16,5 vmhraddshs 9,13,16,31 vmhraddshs 5,11,2,3 vmhraddshs 19,6,19,4 vsubshs 0,1,6 stvx 19,0,6 vmhraddshs 2,10,2,11 stvx 0,0,5 vmhraddshs 14,7,14,9 stvx 2,0,10 vsubshs 0,5,10 vmhraddshs 17,9,17,7 stvx 0,0,8 stvx 14,0,11 stvx 17,0,15 lvx 0,0,29 vmhraddshs 18,18,0,3 stvx 18,0,3 lvx 1,0,7 lvx 0,0,10 mflr 7 lvx 11,0,11 lvx 13,0,6 mr 11,0 lvx 12,0,4 vmhraddshs 1,1,0,3 lvx 10,0,5 lvx 9,0,8 stvx 1,0,18 lvx 0,0,30 vmhraddshs 0,0,13,3 stvx 0,0,17 lvx 1,0,11 vmhraddshs 1,1,17,3 stvx 1,0,20 lvx 0,0,7 vmhraddshs 0,0,12,3 stvx 0,0,19 lvx 1,0,12 vmhraddshs 1,1,11,3 stvx 1,0,21 lvx 0,0,31 vmhraddshs 0,0,10,3 stvx 0,0,22 lvx 12,0,9 vmhraddshs 12,12,9,3 stvx 12,0,16 lvx 0,0,19 lvx 11,0,3 lvx 1,0,21 lvx 10,0,18 lvx 6,0,17 lvx 4,0,22 vmrghh 13,11,0 lvx 8,0,20 vmrglh 11,11,0 vmrghh 9,10,1 vmrglh 10,10,1 vmrghh 0,6,4 vmrghh 7,8,12 vmrghh 1,13,0 vmrghh 5,9,7 vmrglh 13,13,0 vmrghh 0,1,5 stvx 0,0,3 vmrglh 8,8,12 vmrglh 6,6,4 vmrglh 9,9,7 vmrglh 1,1,5 stvx 1,0,18 vmrghh 12,11,6 vmrghh 1,10,8 vmrghh 0,13,9 stvx 0,0,17 vmrglh 13,13,9 stvx 13,0,20 vmrghh 0,12,1 vmrglh 11,11,6 stvx 0,0,19 vmrglh 10,10,8 vmrglh 12,12,1 stvx 12,0,21 vmrghh 0,11,10 stvx 0,0,22 vmrglh 11,11,10 stvx 11,0,16 lwz 0,372(1) mtlr 0 lwz 14,296(1) lwz 15,300(1) lwz 16,304(1) lwz 17,308(1) lwz 18,312(1) lwz 19,316(1) lwz 20,320(1) lwz 21,324(1) lwz 22,328(1) lwz 23,332(1) lwz 24,336(1) lwz 25,340(1) lwz 26,344(1) lwz 27,348(1) lwz 28,352(1) lwz 29,356(1) lwz 30,360(1) lwz 31,364(1) addi 0,0,272 lvx 31,1,0 la 1,368(1) blr xvid_20020412/xvidcore/src/dct/ppc_asm/idct_altivec.s0100755000100600001440000001235007452351737021763 0ustar michaelusers .file "idct_vec_tmpl.c" gcc2_compiled.: .section ".data" .align 4 .type PreScale,@object .size PreScale,128 PreScale: .long 268375601 .long 350687952 .long 268374736 .long 350688817 .long 372317896 .long 486414872 .long 372316696 .long 486416072 .long 350690558 .long 458234004 .long 350689428 .long 458235134 .long 315628056 .long 412358175 .long 315627039 .long 412359192 .long 268375601 .long 350687952 .long 268374736 .long 350688817 .long 315628056 .long 412358175 .long 315627039 .long 412359192 .long 350690558 .long 458234004 .long 350689428 .long 458235134 .long 372317896 .long 486414872 .long 372316696 .long 486416072 .section ".rodata" .align 4 .LC0: .long 1518482693 .long 427185543 .long -1518425479 .long 0 .section ".text" .align 2 .globl idct_altivec .type idct_altivec,@function idct_altivec: stwu 1,-368(1) stw 15,300(1) stw 16,304(1) stw 17,308(1) stw 18,312(1) stw 19,316(1) stw 20,320(1) stw 21,324(1) stw 22,328(1) stw 23,332(1) stw 24,336(1) stw 25,340(1) stw 26,344(1) stw 27,348(1) stw 28,352(1) stw 29,356(1) stw 30,360(1) stw 31,364(1) addi 0,0,272 stvx 31,1,0 lis 11,PreScale@ha lvx 12,0,3 vxor %v3,%v3,%v3 la 11,PreScale@l(11) lvx 0,0,11 addi 9,11,16 lvx 1,0,9 addi 17,3,32 addi 9,11,32 lvx 8,0,17 lvx 7,0,9 addi 15,3,16 vmhraddshs 12,12,0,3 addi 9,11,48 lvx 9,0,15 addi 16,3,48 lvx 0,0,9 lvx 11,0,16 addi 9,11,64 addi 18,3,64 lvx 10,0,9 vmhraddshs 8,8,7,3 lvx 13,0,18 addi 9,11,80 vmhraddshs 9,9,1,3 lvx 7,0,9 addi 19,3,80 vmhraddshs 11,11,0,3 addi 20,3,96 lvx 1,0,19 lvx 0,0,20 addi 4,1,16 addi 9,11,96 vmhraddshs 13,13,10,3 stvx 12,0,4 addi 11,11,112 lvx 10,0,9 vmhraddshs 1,1,7,3 lvx 12,0,11 addi 5,1,32 stvx 9,0,5 addi 21,3,112 lvx 5,0,21 addi 7,1,48 vmhraddshs 0,0,10,3 stvx 8,0,7 addi 8,1,64 stvx 11,0,8 addi 6,1,80 vmhraddshs 5,5,12,3 stvx 13,0,6 addi 11,1,96 stvx 1,0,11 addi 10,1,112 stvx 0,0,10 addi 27,1,128 stvx 5,0,27 lvx 1,0,11 lis 9,.LC0@ha lvx 12,0,5 la 9,.LC0@l(9) lvx 0,0,6 addi 25,1,144 lvx 2,0,10 addi 23,1,256 lvx 11,0,4 addi 26,1,160 lvx 6,0,7 vmrghh 10,12,1 addi 24,1,240 lvx 7,0,8 vmrglh 12,12,1 addi 29,1,176 lvx 4,0,9 addi 28,1,224 vmrghh 13,11,0 addi 9,1,192 vmrghh 1,6,2 addi 22,1,208 vmrghh 9,7,5 vmrglh 11,11,0 vmrghh 8,10,9 vmrghh 0,13,1 vmrglh 13,13,1 vmrghh 1,0,8 vmrglh 6,6,2 stvx 1,0,4 vmrglh 7,7,5 vmrglh 10,10,9 vmrglh 0,0,8 stvx 0,0,5 vmrghh 9,12,7 vmrghh 1,11,6 vmrghh 0,13,10 stvx 0,0,7 vmrglh 13,13,10 stvx 13,0,8 vmrglh 12,12,7 vmrghh 0,1,9 vmrglh 11,11,6 stvx 0,0,6 vmrglh 1,1,9 stvx 1,0,11 vmrghh 0,11,12 stvx 0,0,10 vmrglh 11,11,12 stvx 11,0,27 vsplth 19,4,2 lvx 0,0,5 vsplth 17,4,5 lvx 10,0,11 vsplth 16,4,3 lvx 1,0,8 vsplth 18,4,1 lvx 13,0,7 vsplth 2,4,0 vmhraddshs 15,19,0,3 lvx 9,0,10 vsplth 4,4,4 vmhraddshs 5,19,11,0 lvx 12,0,4 vmhraddshs 8,17,1,10 lvx 0,0,6 vmhraddshs 6,16,10,1 vmhraddshs 14,18,9,13 vsubshs 1,15,11 vmhraddshs 15,18,13,3 vaddshs 31,1,8 vsubshs 8,1,8 vsubshs 1,5,6 vaddshs 7,12,0 vaddshs 5,5,6 vaddshs 6,7,14 vsubshs 11,15,9 vsubshs 10,12,0 vsubshs 14,7,14 vaddshs 7,10,11 vsubshs 10,10,11 vsubshs 11,1,8 vaddshs 8,1,8 vaddshs 0,6,5 stvx 0,0,25 vmhraddshs 13,2,8,7 vsubshs 1,6,5 stvx 1,0,23 vmhraddshs 12,4,8,7 stvx 13,0,26 vmhraddshs 0,2,11,10 stvx 12,0,24 vmhraddshs 13,4,11,10 stvx 0,0,29 vaddshs 1,14,31 stvx 13,0,28 vsubshs 0,14,31 stvx 1,0,9 stvx 0,0,22 lvx 9,0,28 lvx 12,0,26 lvx 8,0,24 lvx 5,0,23 lvx 11,0,25 lvx 6,0,29 vmrghh 10,12,9 lvx 7,0,9 vmrglh 12,12,9 vmrghh 1,11,0 vmrghh 13,6,8 vmrghh 9,7,5 vmrglh 6,6,8 vmrglh 11,11,0 vmrghh 8,10,9 vmrghh 0,1,13 vmrglh 1,1,13 vmrghh 13,0,8 stvx 13,0,4 vmrglh 7,7,5 vmrglh 10,10,9 vmrglh 0,0,8 stvx 0,0,5 vmrghh 9,12,7 vmrghh 13,11,6 vmrghh 0,1,10 stvx 0,0,7 vmrglh 1,1,10 vmrglh 12,12,7 stvx 1,0,8 vmrghh 0,13,9 vmrglh 11,11,6 stvx 0,0,6 vmrglh 13,13,9 stvx 13,0,11 vmrghh 0,11,12 stvx 0,0,10 vmrglh 11,11,12 stvx 11,0,27 lvx 0,0,5 lvx 13,0,11 lvx 1,0,8 lvx 12,0,7 vmhraddshs 15,19,0,3 lvx 9,0,10 vmhraddshs 5,19,11,0 lvx 10,0,4 vmhraddshs 8,17,1,13 lvx 0,0,6 vmhraddshs 6,16,13,1 vmhraddshs 14,18,9,12 vsubshs 1,15,11 vmhraddshs 15,18,12,3 vaddshs 31,1,8 vsubshs 8,1,8 vsubshs 1,5,6 vaddshs 7,10,0 vaddshs 5,5,6 vaddshs 6,7,14 vsubshs 10,10,0 vsubshs 11,15,9 vsubshs 14,7,14 vaddshs 7,10,11 vsubshs 10,10,11 vsubshs 11,1,8 vaddshs 8,1,8 vaddshs 0,6,5 stvx 0,0,25 vmhraddshs 13,2,8,7 vsubshs 1,6,5 stvx 1,0,23 vmhraddshs 0,4,8,7 stvx 13,0,26 vmhraddshs 2,2,11,10 stvx 0,0,24 vmhraddshs 4,4,11,10 stvx 2,0,29 vaddshs 0,14,31 stvx 4,0,28 vsubshs 12,14,31 stvx 0,0,9 stvx 12,0,22 lvx 0,0,25 stvx 0,0,3 lvx 1,0,26 stvx 1,0,15 lvx 0,0,29 stvx 0,0,17 lvx 13,0,28 lvx 1,0,9 stvx 1,0,16 lvx 0,0,23 stvx 12,0,18 lvx 1,0,24 stvx 13,0,19 stvx 1,0,20 stvx 0,0,21 lwz 15,300(1) lwz 16,304(1) lwz 17,308(1) lwz 18,312(1) lwz 19,316(1) lwz 20,320(1) lwz 21,324(1) lwz 22,328(1) lwz 23,332(1) lwz 24,336(1) lwz 25,340(1) lwz 26,344(1) lwz 27,348(1) lwz 28,352(1) lwz 29,356(1) lwz 30,360(1) lwz 31,364(1) addi 0,0,272 lvx 31,1,0 la 1,368(1) blr .Lfe1: .size idct_altivec,.Lfe1-idct_altivec .ident "GCC: (GNU) 2.95.3 20010111 (BLL/AltiVec prerelease/franzo/20010111)" xvid_20020412/xvidcore/src/divx4.c0100644000100600001440000002175607447442572016164 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * opendivx api wrapper * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 26.02.2001 fixed dec_csp bugs * 26.12.2001 xvid_init() support * 22.12.2001 removed some compiler warnings * 16.12.2001 inital version; (c)2001 peter ross * *************************************************************************/ #include #include // memset #include "xvid.h" #include "divx4.h" #include "decoder.h" #include "encoder.h" #define EMULATED_DIVX_VERSION 20011001 // decore typedef struct DINST { unsigned long key; struct DINST * next; void * handle; XVID_DEC_FRAME xframe; } DINST; static DINST * dhead = NULL; DINST * dinst_find(unsigned long key) { DINST * dcur = dhead; while (dcur) { if (dcur->key == key) { return dcur; } dcur = dcur->next; } return NULL; } DINST * dinst_add(unsigned long key) { DINST * dnext = dhead; dhead = malloc(sizeof(DINST)); if (dhead == NULL) { dhead = dnext; return NULL; } dhead->key = key; dhead->next = dnext; return dhead; } void dinst_remove(unsigned long key) { DINST * dcur = dhead; if (dhead == NULL) { return; } if (dcur->key == key) { dhead = dcur->next; free(dcur); return; } while (dcur->next) { if (dcur->next->key == key) { DINST * tmp = dcur->next; dcur->next = tmp->next; free(tmp); return; } dcur = dcur->next; } } int xvid_to_opendivx_dec_csp(int csp) { switch(csp) { case DEC_YV12 : return XVID_CSP_YV12; case DEC_420 : return XVID_CSP_I420; case DEC_YUY2 : return XVID_CSP_YUY2; case DEC_UYVY : return XVID_CSP_UYVY; case DEC_RGB32 : return XVID_CSP_VFLIP | XVID_CSP_RGB32; case DEC_RGB24 : return XVID_CSP_VFLIP | XVID_CSP_RGB24; case DEC_RGB565 : return XVID_CSP_VFLIP | XVID_CSP_RGB565; case DEC_RGB555 : return XVID_CSP_VFLIP | XVID_CSP_RGB555; case DEC_RGB32_INV : return XVID_CSP_RGB32; case DEC_RGB24_INV : return XVID_CSP_RGB24; case DEC_RGB565_INV : return XVID_CSP_RGB565; case DEC_RGB555_INV : return XVID_CSP_RGB555; case DEC_USER : return XVID_CSP_USER; default : return -1; } } int decore(unsigned long key, unsigned long opt, void * param1, void * param2) { int xerr; switch (opt) { case DEC_OPT_MEMORY_REQS : { memset(param2, 0, sizeof(DEC_MEM_REQS)); return DEC_OK; } case DEC_OPT_INIT : { DEC_PARAM * dparam = (DEC_PARAM *)param1; XVID_INIT_PARAM xinit; XVID_DEC_PARAM xparam; DINST * dcur = dinst_find(key); if (dcur == NULL) { dcur = dinst_add(key); } xinit.cpu_flags = 0; xvid_init(NULL, 0, &xinit, NULL); xparam.width = dparam->x_dim; xparam.height = dparam->y_dim; dcur->xframe.colorspace = xvid_to_opendivx_dec_csp(dparam->output_format); xerr = decoder_create(&xparam); dcur->handle = xparam.handle; break; } case DEC_OPT_RELEASE : { DINST * dcur = dinst_find(key); if (dcur == NULL) { return DEC_EXIT; } xerr = decoder_destroy(dcur->handle); dinst_remove(key); break; } case DEC_OPT_SETPP : { // DEC_SET * dset = (DEC_SET *)param1; DINST * dcur = dinst_find(key); if (dcur == NULL) { return DEC_EXIT; } // dcur->xframe.pp = dset->postproc_level; return DEC_OK; } case DEC_OPT_SETOUT : { DEC_PARAM * dparam = (DEC_PARAM *)param1; DINST * dcur = dinst_find(key); if (dcur == NULL) { return DEC_EXIT; } dcur->xframe.colorspace = xvid_to_opendivx_dec_csp(dparam->output_format); return DEC_OK; } case DEC_OPT_FRAME: { int csp_tmp = 0; DEC_FRAME * dframe = (DEC_FRAME *)param1; DINST * dcur = dinst_find(key); if (dcur == NULL) { return DEC_EXIT; } dcur->xframe.bitstream = dframe->bitstream; dcur->xframe.length = dframe->length; dcur->xframe.image = dframe->bmp; dcur->xframe.stride = dframe->stride; if (!dframe->render_flag) { csp_tmp = dcur->xframe.colorspace; dcur->xframe.colorspace = XVID_CSP_NULL; } xerr = decoder_decode(dcur->handle, &dcur->xframe); if (!dframe->render_flag) { dcur->xframe.colorspace = csp_tmp; } break; } case DEC_OPT_FRAME_311 : return DEC_EXIT; case DEC_OPT_VERSION: return EMULATED_DIVX_VERSION; default : return DEC_EXIT; } switch(xerr) { case XVID_ERR_OK : return DEC_OK; case XVID_ERR_MEMORY : return DEC_MEMORY; case XVID_ERR_FORMAT : return DEC_BAD_FORMAT; default : // case XVID_ERR_FAIL : return DEC_EXIT; } } // encore #define FRAMERATE_INCR 1001 int divx4_motion_presets[7] = { 0, PMV_QUICKSTOP16, PMV_EARLYSTOP16, PMV_EARLYSTOP16 | PMV_EARLYSTOP8, PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8, PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8, PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 | PMV_EARLYSTOP8 | PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8 }; int quality; int encore(void * handle, int opt, void * param1, void * param2) { int xerr; switch(opt) { case ENC_OPT_INIT : { ENC_PARAM * eparam = (ENC_PARAM *)param1; XVID_INIT_PARAM xinit; XVID_ENC_PARAM xparam; xinit.cpu_flags = 0; xvid_init(NULL, 0, &xinit, NULL); xparam.width = eparam->x_dim; xparam.height = eparam->y_dim; if ((eparam->framerate - (int)eparam->framerate) == 0) { xparam.fincr = 1; xparam.fbase = (int)eparam->framerate; } else { xparam.fincr = FRAMERATE_INCR; xparam.fbase = (int)(FRAMERATE_INCR * eparam->framerate); } xparam.bitrate = eparam->bitrate; xparam.rc_buffersize = 16; xparam.min_quantizer = eparam->min_quantizer; xparam.max_quantizer = eparam->max_quantizer; xparam.max_key_interval = eparam->max_key_interval; quality = eparam->quality; xerr = encoder_create(&xparam); eparam->handle = xparam.handle; break; } case ENC_OPT_RELEASE : { xerr = encoder_destroy((Encoder *) handle); break; } case ENC_OPT_ENCODE : case ENC_OPT_ENCODE_VBR : { ENC_FRAME * eframe = (ENC_FRAME *)param1; ENC_RESULT * eresult = (ENC_RESULT *)param2; XVID_ENC_FRAME xframe; XVID_ENC_STATS xstats; xframe.bitstream = eframe->bitstream; xframe.length = eframe->length; xframe.general = XVID_HALFPEL | XVID_H263QUANT; if(quality > 3) xframe.general |= XVID_INTER4V; xframe.motion = divx4_motion_presets[quality]; xframe.image = eframe->image; switch (eframe->colorspace) { case ENC_CSP_RGB24 : xframe.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB24; break; case ENC_CSP_YV12 : xframe.colorspace = XVID_CSP_YV12; break; case ENC_CSP_YUY2 : xframe.colorspace = XVID_CSP_YUY2; break; case ENC_CSP_UYVY : xframe.colorspace = XVID_CSP_UYVY; break; case ENC_CSP_I420 : xframe.colorspace = XVID_CSP_I420; break; } if (opt == ENC_OPT_ENCODE_VBR) { xframe.intra = eframe->intra; xframe.quant = eframe->quant; } else { xframe.intra = -1; xframe.quant = 0; } xerr = encoder_encode((Encoder *) handle, &xframe, (eresult ? &xstats : NULL) ); if (eresult) { eresult->is_key_frame = xframe.intra; eresult->quantizer = xstats.quant; eresult->total_bits = xframe.length * 8; eresult->motion_bits = xstats.hlength * 8; eresult->texture_bits = eresult->total_bits - eresult->motion_bits; } eframe->length = xframe.length; break; } default: return ENC_FAIL; } switch(xerr) { case XVID_ERR_OK : return ENC_OK; case XVID_ERR_MEMORY : return ENC_MEMORY; case XVID_ERR_FORMAT : return ENC_BAD_FORMAT; default : // case XVID_ERR_FAIL : return ENC_FAIL; } } xvid_20020412/xvidcore/src/divx4.h0100644000100600001440000001644107442022616016150 0ustar michaelusers#ifndef _DIVX4_H_ #define _DIVX4_H_ #ifdef __cplusplus extern "C" { #endif #if ((! defined(ARCH_IS_BIG_ENDIAN)) && (! defined (WIN32)) && (! defined (LINUX)) ) #define ARCH_IS_BIG_ENDIAN #endif /********************************************************************************* * Decoder part * *********************************************************************************/ /* decore commands */ #define DEC_OPT_MEMORY_REQS 0 #define DEC_OPT_INIT 1 #define DEC_OPT_RELEASE 2 #define DEC_OPT_SETPP 3 #define DEC_OPT_SETOUT 4 #define DEC_OPT_FRAME 5 #define DEC_OPT_FRAME_311 6 #define DEC_OPT_SETPP2 7 #define DEC_OPT_VERSION 8 /* return values */ #define DEC_OK 0 #define DEC_MEMORY 1 #define DEC_BAD_FORMAT 2 #define DEC_EXIT 3 /* yuv colour formats */ #define DEC_YUY2 1 #define DEC_YUV2 DEC_YUY2 #define DEC_UYVY 2 #define DEC_420 3 #define DEC_YV12 13 /* rgb colour formats */ #define DEC_RGB32 4 #define DEC_RGB24 5 #define DEC_RGB555 6 #define DEC_RGB565 7 #define DEC_RGB32_INV 8 #define DEC_RGB24_INV 9 #define DEC_RGB555_INV 10 #define DEC_RGB565_INV 11 /* return pointers to initial buffers equivalent to XVID_CSP_USER */ #define DEC_USER 12 /* output structure for DEC_USER */ typedef struct { void *y; void *u; void *v; int stride_y; int stride_uv; } DEC_PICTURE; typedef struct { unsigned long mp4_edged_ref_buffers_size; unsigned long mp4_edged_for_buffers_size; unsigned long mp4_edged_back_buffers_size; unsigned long mp4_display_buffers_size; unsigned long mp4_state_size; unsigned long mp4_tables_size; unsigned long mp4_stream_size; unsigned long mp4_reference_size; } DEC_MEM_REQS; typedef struct { void * mp4_edged_ref_buffers; void * mp4_edged_for_buffers; void * mp4_edged_back_buffers; void * mp4_display_buffers; void * mp4_state; void * mp4_tables; void * mp4_stream; void * mp4_reference; } DEC_BUFFERS; typedef struct { int x_dim; /* frame width */ int y_dim; /* frame height */ int output_format; int time_incr; DEC_BUFFERS buffers; } DEC_PARAM; typedef struct { void *bmp; /* pointer to output buffer */ void *bitstream; /* input bit stream */ long length; /* length of bitstream */ int render_flag; unsigned int stride; } DEC_FRAME; typedef struct { int intra; int *quant_store; int quant_stride; } DEC_FRAME_INFO; /* configure postprocessing */ typedef struct { int postproc_level; /* ranging from 0 to 100 */ } DEC_SET; int decore( unsigned long handle, unsigned long dec_opt, void* param1, void* param2); /********************************************************************************* * Encoder part * *********************************************************************************/ /** Structure passed as an argument when creating encoder. You have to initialize at least x_dim and y_dim ( valid range: 0 #include "../portab.h" #include "bitstream.h" #include "zigzag.h" #include "vlc_codes.h" #include "mbcoding.h" #include "../utils/mbfunctions.h" #define ABS(X) (((X)>0)?(X):-(X)) #define CLIP(X,A) (X > A) ? (A) : (X) VLC intra_table[65536]; VLC inter_table[65536]; VLC DCT3Dintra[4096]; VLC DCT3Dinter[4096]; static int16_t clip_table[4096]; void init_vlc_tables(void) { int32_t k, l, i, intra, last; VLC *vlc[2]; VLC **coeff_ptr; VLC *vlc1, *vlc2; vlc1 = DCT3Dintra; vlc2 = DCT3Dinter; vlc[0] = intra_table; vlc[1] = inter_table; // initialize the clipping table for(i = -2048; i < 2048; i++) { clip_table[i + 2048] = i; if(i < -255) clip_table[i + 2048] = -255; if(i > 255) clip_table[i + 2048] = 255; } // generate encoding vlc lookup tables for(i = 0; i < 4; i++) { intra = i % 2; last = i / 2; coeff_ptr = coeff_vlc[last + 2 * intra]; for(k = -255; k < 256; k++) { // level int8_t *max_level_ptr = max_level[last + 2 * intra]; int8_t *max_run_ptr = max_run[last + 2 * intra]; for(l = 0; l < 64; l++) { // run int32_t level = k; uint32_t run = l; if((abs(level) <= max_level_ptr[run]) && (run <= max_run_ptr[abs(level)])) { // level < max_level and run < max_run vlc[intra]->code = 0; vlc[intra]->len = 0; goto loop_end; } else { if(level > 0) // correct level level -= max_level_ptr[run]; else level += max_level_ptr[run]; if((abs(level) <= max_level_ptr[run]) && (run <= max_run_ptr[abs(level)])) { vlc[intra]->code = 0x06; vlc[intra]->len = 8; goto loop_end; } if(level > 0) // still here? level += max_level_ptr[run]; // restore level else level -= max_level_ptr[run]; run -= max_run_ptr[abs(level)] + 1; // and change run if((abs(level) <= max_level_ptr[run]) && (run <= max_run_ptr[abs(level)])) { vlc[intra]->code = 0x0e; vlc[intra]->len = 9; goto loop_end; } run += max_run_ptr[abs(level)] + 1; } vlc[intra]->code = (uint32_t) ((l << 14) | (0x1e + last) << 20) | (1 << 13) | ((k & 0xfff) << 1) | 1; vlc[intra]->len = 30; vlc[intra]++; continue; loop_end: if(level != 0) { vlc[intra]->code = (vlc[intra]->code << (coeff_ptr[run][abs(level) - 1].len + 1)) | (coeff_ptr[run][abs(level) - 1].code << 1); vlc[intra]->len = (coeff_ptr[run][abs(level) - 1].len + 1) + vlc[intra]->len; if(level < 0) vlc[intra]->code += 1; } vlc[intra]++; } } } for(i = 0; i < 4096; i++) { if(i >= 512) { *vlc1 = DCT3Dtab3[(i >> 5) - 16]; *vlc2 = DCT3Dtab0[(i >> 5) - 16]; } else if(i >= 128) { *vlc1 = DCT3Dtab4[(i >> 2) - 32]; *vlc2 = DCT3Dtab1[(i >> 2) - 32]; } else if(i >= 8) { *vlc1 = DCT3Dtab5[i - 8]; *vlc2 = DCT3Dtab2[i - 8]; } else { *vlc1 = ERRtab[i]; *vlc2 = ERRtab[i]; } vlc1++; vlc2++; } DCT3D[0] = DCT3Dinter; DCT3D[1] = DCT3Dintra; } static __inline void CodeVector(Bitstream *bs, int16_t value, int16_t f_code, Statistics *pStat) { const int scale_factor = 1 << (f_code - 1); const int cmp = scale_factor << 5; if(value < (-1 * cmp)) value += 64 * scale_factor; if(value > (cmp - 1)) value -= 64 * scale_factor; pStat->iMvSum += value * value; pStat->iMvCount++; if (value == 0) { BitstreamPutBits(bs, mb_motion_table[32].code, mb_motion_table[32].len); } else { uint16_t length, code, mv_res, sign; length = 16 << f_code; f_code--; sign = (value < 0); if(value >= length) value -= 2 * length; else if(value < -length) value += 2 * length; if(sign) value = -value; value--; mv_res = value & ((1 << f_code) - 1); code = ((value - mv_res) >> f_code) + 1; if(sign) code = -code; code += 32; BitstreamPutBits(bs, mb_motion_table[code].code, mb_motion_table[code].len); if(f_code) BitstreamPutBits(bs, mv_res, f_code); } } static __inline void CodeCoeff(Bitstream *bs, int16_t qcoeff[64], VLC *table, const uint16_t *zigzag, uint16_t intra) { uint32_t j, last; short v; VLC *vlc; j = intra; last = intra; while((v = qcoeff[zigzag[j]]) == 0) j++; do { // count zeroes vlc = table + 64*255 + (clip_table[2048+v] << 6) + j - last; last = ++j; while(j < 64 && (v = qcoeff[zigzag[j]]) == 0) j++; // write code if(j != 64) { BitstreamPutBits(bs, vlc->code, vlc->len); } else { vlc += 64*511; BitstreamPutBits(bs, vlc->code, vlc->len); break; } } while(1); } static void CodeBlockIntra(const MBParam * pParam, const MACROBLOCK *pMB, int16_t qcoeff[6*64], Bitstream * bs, Statistics * pStat) { uint32_t i, mcbpc, cbpy, bits; cbpy = pMB->cbp >> 2; // write mcbpc if(pParam->coding_type == I_VOP) { mcbpc = ((pMB->mode >> 1) & 3) | ((pMB->cbp & 3) << 2); BitstreamPutBits(bs, mcbpc_intra_tab[mcbpc].code, mcbpc_intra_tab[mcbpc].len); } else { mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3); BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code, mcbpc_inter_tab[mcbpc].len); } // ac prediction flag if(pMB->acpred_directions[0]) BitstreamPutBits(bs, 1, 1); else BitstreamPutBits(bs, 0, 1); // write cbpy BitstreamPutBits (bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); // write dquant if(pMB->mode == MODE_INTRA_Q) BitstreamPutBits(bs, pMB->dquant, 2); // write interlacing if (pParam->global_flags & XVID_INTERLACING) { BitstreamPutBit(bs, pMB->field_dct); } // code block coeffs for(i = 0; i < 6; i++) { if(i < 4) BitstreamPutBits(bs, dcy_tab[qcoeff[i*64 + 0] + 255].code, dcy_tab[qcoeff[i*64 + 0] + 255].len); else BitstreamPutBits(bs, dcc_tab[qcoeff[i*64 + 0] + 255].code, dcc_tab[qcoeff[i*64 + 0] + 255].len); if(pMB->cbp & (1 << (5 - i))) { bits = BitstreamPos(bs); CodeCoeff(bs, &qcoeff[i*64], intra_table, scan_tables[pMB->acpred_directions[i]], 1); bits = BitstreamPos(bs) - bits; pStat->iTextBits += bits; } } } static void CodeBlockInter(const MBParam * pParam, const MACROBLOCK *pMB, int16_t qcoeff[6*64], Bitstream * bs, Statistics * pStat) { int32_t i; uint32_t bits, mcbpc, cbpy; mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3); cbpy = 15 - (pMB->cbp >> 2); // write mcbpc BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code, mcbpc_inter_tab[mcbpc].len); // write cbpy BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len); // write dquant if(pMB->mode == MODE_INTER_Q) BitstreamPutBits(bs, pMB->dquant, 2); // interlacing if (pParam->global_flags & XVID_INTERLACING) { BitstreamPutBit(bs, pMB->field_dct); DEBUG1("codep: field_dct: ", pMB->field_dct); // if inter block, write field ME flag if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) { BitstreamPutBit(bs, pMB->field_pred); DEBUG1("codep: field_pred: ", pMB->field_pred); // write field prediction references if (pMB->field_pred) { BitstreamPutBit(bs, pMB->field_for_top); BitstreamPutBit(bs, pMB->field_for_bot); } } } // code motion vector(s) for(i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) { CodeVector(bs, pMB->pmvs[i].x, pParam->fixed_code, pStat); CodeVector(bs, pMB->pmvs[i].y, pParam->fixed_code, pStat); } bits = BitstreamPos(bs); // code block coeffs for(i = 0; i < 6; i++) if(pMB->cbp & (1 << (5 - i))) CodeCoeff(bs, &qcoeff[i*64], inter_table, scan_tables[0], 0); bits = BitstreamPos(bs) - bits; pStat->iTextBits += bits; } void MBCoding(const MBParam * pParam, MACROBLOCK *pMB, int16_t qcoeff[6*64], Bitstream * bs, Statistics * pStat) { int intra = (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q); if(pParam->coding_type == P_VOP) { if(pMB->cbp == 0 && pMB->mode == MODE_INTER && pMB->mvs[0].x == 0 && pMB->mvs[0].y == 0) { BitstreamPutBit(bs, 1); // not_coded return; } else BitstreamPutBit(bs, 0); // coded } if(intra) CodeBlockIntra(pParam, pMB, qcoeff, bs, pStat); else CodeBlockInter(pParam, pMB, qcoeff, bs, pStat); } /*************************************************************** * decoding stuff starts here * ***************************************************************/ int get_mcbpc_intra(Bitstream * bs) { uint32_t index; while((index = BitstreamShowBits(bs, 9)) == 1) BitstreamSkip(bs, 9); index >>= 3; BitstreamSkip(bs, mcbpc_intra_table[index].len); return mcbpc_intra_table[index].code; } int get_mcbpc_inter(Bitstream * bs) { uint32_t index; while((index = CLIP(BitstreamShowBits(bs, 9), 256)) == 1) BitstreamSkip(bs, 9); BitstreamSkip(bs, mcbpc_inter_table[index].len); return mcbpc_inter_table[index].code; } int get_cbpy(Bitstream * bs, int intra) { int cbpy; uint32_t index = BitstreamShowBits(bs, 6); BitstreamSkip(bs, cbpy_table[index].len); cbpy = cbpy_table[index].code; if(!intra) cbpy = 15 - cbpy; return cbpy; } int get_mv_data(Bitstream * bs) { uint32_t index; if(BitstreamGetBit(bs)) return 0; index = BitstreamShowBits(bs, 12); if(index >= 512) { index = (index >> 8) - 2; BitstreamSkip(bs, TMNMVtab0[index].len); return TMNMVtab0[index].code; } if(index >= 128) { index = (index >> 2) - 32; BitstreamSkip(bs, TMNMVtab1[index].len); return TMNMVtab1[index].code; } index -= 4; BitstreamSkip(bs, TMNMVtab2[index].len); return TMNMVtab2[index].code; } int get_mv(Bitstream * bs, int fcode) { int data; int res; int mv; int scale_fac = 1 << (fcode - 1); data = get_mv_data(bs); if(scale_fac == 1 || data == 0) return data; res = BitstreamGetBits(bs, fcode - 1); mv = ((ABS(data) - 1) * scale_fac) + res + 1; return data < 0 ? -mv : mv; } int get_dc_dif(Bitstream * bs, uint32_t dc_size) { int code = BitstreamGetBits(bs, dc_size); int msb = code >> (dc_size - 1); if(msb == 0) return (-1 * (code^((1 << dc_size) - 1))); return code; } int get_dc_size_lum(Bitstream * bs) { int code, i; code = BitstreamShowBits(bs, 11); for(i = 11; i > 3; i--) { if(code == 1) { BitstreamSkip(bs, i); return i + 1; } code >>= 1; } BitstreamSkip(bs, dc_lum_tab[code].len); return dc_lum_tab[code].code; } int get_dc_size_chrom(Bitstream * bs) { uint32_t code, i; code = BitstreamShowBits(bs, 12); for(i = 12; i > 2; i--) { if(code == 1) { BitstreamSkip(bs, i); return i; } code >>= 1; } return 3 - BitstreamGetBits(bs, 2); } void get_intra_block(Bitstream * bs, int16_t * block, int direction, int coeff) { const uint16_t * scan = scan_tables[ direction ]; int level; int run; int last; do { level = get_coeff(bs, &run, &last, 1, 0); if (run == -1) { DEBUG("fatal: invalid run"); break; } coeff += run; block[ scan[coeff] ] = level; if (level < -127 || level > 127) { DEBUG1("warning: intra_overflow", level); } coeff++; } while (!last); } void get_inter_block(Bitstream * bs, int16_t * block) { const uint16_t * scan = scan_tables[0]; int p; int level; int run; int last; p = 0; do { level = get_coeff(bs, &run, &last, 0, 0); if (run == -1) { DEBUG("fatal: invalid run"); break; } p += run; block[ scan[p] ] = level; if (level < -127 || level > 127) { DEBUG1("warning: inter_overflow", level); } p++; } while (!last); } xvid_20020412/xvidcore/src/bitstream/mbcoding.h0100644000100600001440000000124607453055764020677 0ustar michaelusers#ifndef _MB_CODING_H_ #define _MB_CODING_H_ #include "../portab.h" #include "../global.h" #include "bitstream.h" void init_vlc_tables(void); int get_mcbpc_intra(Bitstream * bs); int get_mcbpc_inter(Bitstream * bs); int get_cbpy(Bitstream * bs, int intra); int get_mv(Bitstream * bs, int fcode); int get_dc_dif(Bitstream * bs, uint32_t dc_size); int get_dc_size_lum(Bitstream * bs); int get_dc_size_chrom(Bitstream * bs); int get_coeff(Bitstream * bs, int *run, int *last, int intra, int short_video_header); void get_intra_block(Bitstream * bs, int16_t * block, int direction, int coeff); void get_inter_block(Bitstream * bs, int16_t * block); #endif /* _MB_CODING_H_ */ xvid_20020412/xvidcore/src/bitstream/x86_asm/0040755000100600001440000000000007455522445020226 5ustar michaelusersxvid_20020412/xvidcore/src/bitstream/x86_asm/CVS/0040755000100600001440000000000007455522445020661 5ustar michaelusersxvid_20020412/xvidcore/src/bitstream/x86_asm/CVS/Root0100644000100600001440000000004607455522444021523 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/bitstream/x86_asm/CVS/Repository0100644000100600001440000000003707455522444022757 0ustar michaelusersxvidcore/src/bitstream/x86_asm xvid_20020412/xvidcore/src/bitstream/x86_asm/CVS/Entries0100644000100600001440000000005607455522445022213 0ustar michaelusers/cbp_mmx.asm/1.2/Fri Mar 22 04:37:03 2002// D xvid_20020412/xvidcore/src/bitstream/x86_asm/cbp_mmx.asm0100644000100600001440000000754207446532357022365 0ustar michaelusers;/************************************************************************** ; * ; * XVID MPEG-4 VIDEO CODEC ; * mmx cbp calc ; * ; * This program is an implementation of a part of one or more MPEG-4 ; * Video tools as specified in ISO/IEC 14496-2 standard. Those intending ; * to use this software module in hardware or software products are ; * advised that its use may infringe existing patents or copyrights, and ; * any such use would be at such party's own risk. The original ; * developer of this software module and his/her company, and subsequent ; * editors and their companies, will have no liability for use of this ; * software or modifications or derivatives thereof. ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * This program is distributed in the hope that it will be useful, ; * but WITHOUT ANY WARRANTY; without even the implied warranty of ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; * GNU General Public License for more details. ; * ; * You should have received a copy of the GNU General Public License ; * along with this program; if not, write to the Free Software ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; * ; *************************************************************************/ ;/************************************************************************** ; * ; * History: ; * ; * 22.03.2002 0.01 ; Min Chen ; * ; use 386 cpu's 'BTS' to replace 'cbp |= 1 << (edx-1)' ; * 24.11.2001 inital version; (c)2001 peter ross ; * ; *************************************************************************/ bits 32 section .data %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro ignore_dc dw 0, -1, -1, -1 section .text ;=========================================================================== ; ; uint32_t calc_cbp_mmx(const int16_t coeff[6][64]); ; ;=========================================================================== align 16 cglobal calc_cbp_mmx calc_cbp_mmx push ebx push ecx push edx push esi mov esi, [esp + 16 + 4] ; coeff movq mm7, [ignore_dc] xor eax, eax ; cbp = 0 mov edx, 6 .loop movq mm0, [esi] pand mm0, mm7 movq mm1, [esi+8] por mm0, [esi+16] por mm1, [esi+24] por mm0, [esi+32] por mm1, [esi+40] por mm0, [esi+48] por mm1, [esi+56] por mm0, [esi+64] por mm1, [esi+72] por mm0, [esi+80] por mm1, [esi+88] por mm0, [esi+96] por mm1, [esi+104] por mm0, [esi+112] por mm1, [esi+120] por mm0, mm1 movq mm1, mm0 psrlq mm1, 32 por mm0, mm1 movd ebx, mm0 add esi, 128 or ebx, ebx jz .iterate ; cbp |= 1 << (edx-1) ; Change by Chenm001 ;mov ecx, edx ;dec ecx ;mov ebx, 1 ;shl ebx, cl ;or eax, ebx lea ebx,[edx-1] bts eax,ebx .iterate dec edx jnz .loop pop esi pop edx pop ecx pop ebx ret xvid_20020412/xvidcore/src/bitstream/zigzag.h0100644000100600001440000000177407442022626020403 0ustar michaelusers#ifndef _ZIGZAG_H_ #define _ZIGZAG_H_ static const uint16_t scan_tables[3][64] = { { // zig_zag_scan 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }, { // horizontal_scan 0, 1, 2, 3, 8, 9, 16, 17, 10, 11, 4, 5, 6, 7, 15, 14, 13, 12, 19, 18, 24, 25, 32, 33, 26, 27, 20, 21, 22, 23, 28, 29, 30, 31, 34, 35, 40, 41, 48, 49, 42, 43, 36, 37, 38, 39, 44, 45, 46, 47, 50, 51, 56, 57, 58, 59, 52, 53, 54, 55, 60, 61, 62, 63 }, { // vertical_scan 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49, 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43, 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45, 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63 } }; #endif /* _ZIGZAG_H_ */ xvid_20020412/xvidcore/src/bitstream/vlc_codes.h0100644000100600001440000012707507454766430021067 0ustar michaelusers#ifndef _VLC_CODES_H_ #define _VLC_CODES_H_ #include "../portab.h" #include "mbcoding.h" #define VLC_ERROR (-1) #define ESCAPE 7167 typedef struct { uint32_t code; int8_t len; } VLC; static VLC *DCT3D[2]; /****************************************************************** * common tables between encoder/decoder * ******************************************************************/ /* constants taken from momusys/vm_common/inlcude/max_level.h */ static char max_level[4][64] = { { // intra, last = 0 27, 10, 5, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { // intra, last = 1 8, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { // inter, last = 0 12, 6, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { // inter, last = 1 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } }; static char max_run[4][256] = { { // intra, last = 0 0, 14, 9, 7, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { // intra, last = 1 0, 20, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { // inter, last = 0 0, 26, 10, 6, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { // inter, last = 1 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } }; /****************************************************************** * encoder tables * ******************************************************************/ /* DCT coefficients. Four tables, two for last = 0, two for last = 1. the sign bit must be added afterwards. */ /* first part of coeffs for last = 0. Indexed by [run][level-1] */ static VLC coeff_tab0[2][12] = { /* run = 0 */ { {0x02, 2}, {0x0f, 4}, {0x15, 6}, {0x17, 7}, {0x1f, 8}, {0x25, 9}, {0x24, 9}, {0x21, 10}, {0x20, 10}, {0x07, 11}, {0x06, 11}, {0x20, 11} }, /* run = 1 */ { {0x06, 3}, {0x14, 6}, {0x1e, 8}, {0x0f, 10}, {0x21, 11}, {0x50, 12}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0} } }; /* rest of coeffs for last = 0. indexing by [run-2][level-1] */ static VLC coeff_tab1[25][4] = { /* run = 2 */ { {0x0e, 4}, {0x1d, 8}, {0x0e, 10}, {0x51, 12} }, /* run = 3 */ { {0x0d, 5}, {0x23, 9}, {0x0d, 10}, {0x00, 0} }, /* run = 4-26 */ { {0x0c, 5}, {0x22, 9}, {0x52, 12}, {0x00, 0} }, { {0x0b, 5}, {0x0c, 10}, {0x53, 12}, {0x00, 0} }, { {0x13, 6}, {0x0b, 10}, {0x54, 12}, {0x00, 0} }, { {0x12, 6}, {0x0a, 10}, {0x00, 0}, {0x00, 0} }, { {0x11, 6}, {0x09, 10}, {0x00, 0}, {0x00, 0} }, { {0x10, 6}, {0x08, 10}, {0x00, 0}, {0x00, 0} }, { {0x16, 7}, {0x55, 12}, {0x00, 0}, {0x00, 0} }, { {0x15, 7}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x14, 7}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x1c, 8}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x1b, 8}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x21, 9}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x20, 9}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x1f, 9}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x1e, 9}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x1d, 9}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x1c, 9}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x1b, 9}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x1a, 9}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x22, 11}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x23, 11}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x56, 12}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, { {0x57, 12}, {0x00, 0}, {0x00, 0}, {0x00, 0} } }; /* first coeffs of last = 1. indexing by [run][level-1] */ static VLC coeff_tab2[2][3] = { /* run = 0 */ { {0x07, 4}, {0x19, 9}, {0x05, 11} }, /* run = 1 */ { {0x0f, 6}, {0x04, 11}, {0x00, 0} } }; /* rest of coeffs for last = 1. indexing by [run-2] */ static VLC coeff_tab3[40][1] = { {{0x0e, 6}}, {{0x0d, 6}}, {{0x0c, 6}}, {{0x13, 7}}, {{0x12, 7}}, {{0x11, 7}}, {{0x10, 7}}, {{0x1a, 8}}, {{0x19, 8}}, {{0x18, 8}}, {{0x17, 8}}, {{0x16, 8}}, {{0x15, 8}}, {{0x14, 8}}, {{0x13, 8}}, {{0x18, 9}}, {{0x17, 9}}, {{0x16, 9}}, {{0x15, 9}}, {{0x14, 9}}, {{0x13, 9}}, {{0x12, 9}}, {{0x11, 9}}, {{0x07, 10}}, {{0x06, 10}}, {{0x05, 10}}, {{0x04, 10}}, {{0x24, 11}}, {{0x25, 11}}, {{0x26, 11}}, {{0x27, 11}}, {{0x58, 12}}, {{0x59, 12}}, {{0x5a, 12}}, {{0x5b, 12}}, {{0x5c, 12}}, {{0x5d, 12}}, {{0x5e, 12}}, {{0x5f, 12}}, {{0x00, 0}} }; /* New tables for Intra luminance coefficients. Same codewords, different meaning */ /* Coeffs for last = 0, run = 0. Indexed by [level-1] */ static VLC coeff_tab4[27] = { /* run = 0 */ {0x02, 2}, {0x06, 3}, {0x0f, 4}, {0x0d, 5}, {0x0c, 5}, {0x15, 6}, {0x13, 6}, {0x12, 6}, {0x17, 7}, {0x1f, 8}, {0x1e, 8}, {0x1d, 8}, {0x25, 9}, {0x24, 9}, {0x23, 9}, {0x21, 9}, {0x21, 10}, {0x20, 10}, {0x0f, 10}, {0x0e, 10}, {0x07, 11}, {0x06, 11}, {0x20, 11}, {0x21, 11}, {0x50, 12}, {0x51, 12}, {0x52, 12} }; /* Coeffs for last = 0, run = 1. Indexed by [level-1] */ static VLC coeff_tab5[10] = { {0x0e, 4}, {0x14, 6}, {0x16, 7}, {0x1c, 8}, {0x20, 9}, {0x1f, 9}, {0x0d, 10}, {0x22, 11}, {0x53, 12}, {0x55, 12} }; /* Coeffs for last = 0, run = 2 -> 9. Indexed by [run-2][level-1] */ static VLC coeff_tab6[8][5] = { /* run = 2 */ { {0x0b, 5}, {0x15, 7}, {0x1e, 9}, {0x0c, 10}, {0x56, 12} }, /* run = 3 */ { {0x11, 6}, {0x1b, 8}, {0x1d, 9}, {0x0b, 10}, {0x00, 0} }, /* run = 4 */ { {0x10, 6}, {0x22, 9}, {0x0a, 10}, {0x00, 0}, {0x00, 0} }, /* run = 5 */ { {0x0d, 6}, {0x1c, 9}, {0x08, 10}, {0x00, 0}, {0x00, 0} }, /* run = 6 */ { {0x12, 7}, {0x1b, 9}, {0x54, 12}, {0x00, 0}, {0x00, 0} }, /* run = 7 */ { {0x14, 7}, {0x1a, 9}, {0x57, 12}, {0x00, 0}, {0x00, 0} }, /* run = 8 */ { {0x19, 8}, {0x09, 10}, {0x00, 0}, {0x00, 0}, {0x00, 0} }, /* run = 9 */ { {0x18, 8}, {0x23, 11}, {0x00, 0}, {0x00, 0}, {0x00, 0} } }; /* Coeffs for last = 0, run = 10 -> 14. Indexed by [run-10] */ static VLC coeff_tab7[5][1] = { {{0x17, 8}}, {{0x19, 9}}, {{0x18, 9}}, {{0x07, 10}}, {{0x58, 12}} }; /* Coeffs for last = 1, run = 0. Indexed by [level-1] */ static VLC coeff_tab8[8] = { {0x07, 4}, {0x0c, 6}, {0x16, 8}, {0x17, 9}, {0x06, 10}, {0x05, 11}, {0x04, 11}, {0x59, 12} }; /* Coeffs for last = 1, run = 1 -> 6. Indexed by [run-1][level-1] */ static VLC coeff_tab9[6][3] = { /* run = 1 */ { {0x0f, 6}, {0x16, 9}, {0x05, 10} }, /* run = 2 */ { {0x0e, 6}, {0x04, 10}, {0x00, 0} }, /* run = 3 */ { {0x11, 7}, {0x24, 11}, {0x00, 0} }, /* run = 4 */ { {0x10, 7}, {0x25, 11}, {0x00, 0} }, /* run = 5 */ { {0x13, 7}, {0x5a, 12}, {0x00, 0} }, /* run = 6 */ { {0x15, 8}, {0x5b, 12}, {0x00, 0} } }; /* Coeffs for last = 1, run = 7 -> 20. Indexed by [run-7] */ static VLC coeff_tab10[14][1] = { {{0x14, 8}}, {{0x13, 8}}, {{0x1a, 8}}, {{0x15, 9}}, {{0x14, 9}}, {{0x13, 9}}, {{0x12, 9}}, {{0x11, 9}}, {{0x26, 11}}, {{0x27, 11}}, {{0x5c, 12}}, {{0x5d, 12}}, {{0x5e, 12}}, {{0x5f, 12}} }; static VLC *coeff_intra_last0[15] = { coeff_tab4, coeff_tab5, coeff_tab6[0], coeff_tab6[1], coeff_tab6[2], coeff_tab6[3], coeff_tab6[4], coeff_tab6[5], coeff_tab6[6], coeff_tab6[7], coeff_tab7[0], coeff_tab7[1], coeff_tab7[2], coeff_tab7[3], coeff_tab7[4] }; static VLC *coeff_intra_last1[21] = { coeff_tab8, coeff_tab9[0], coeff_tab9[1], coeff_tab9[2], coeff_tab9[3], coeff_tab9[4], coeff_tab9[5], coeff_tab10[0], coeff_tab10[1], coeff_tab10[2], coeff_tab10[3], coeff_tab10[4], coeff_tab10[5], coeff_tab10[6], coeff_tab10[7], coeff_tab10[8], coeff_tab10[9], coeff_tab10[10], coeff_tab10[11], coeff_tab10[12], coeff_tab10[13], }; static VLC *coeff_inter_last0[27] = { coeff_tab0[0], coeff_tab0[1], coeff_tab1[0], coeff_tab1[1], coeff_tab1[2], coeff_tab1[3], coeff_tab1[4], coeff_tab1[5], coeff_tab1[6], coeff_tab1[7], coeff_tab1[8], coeff_tab1[9], coeff_tab1[10], coeff_tab1[11], coeff_tab1[12], coeff_tab1[13], coeff_tab1[14], coeff_tab1[15], coeff_tab1[16], coeff_tab1[17], coeff_tab1[18], coeff_tab1[19], coeff_tab1[20], coeff_tab1[21], coeff_tab1[22], coeff_tab1[23], coeff_tab1[24], }; static VLC *coeff_inter_last1[42] = { coeff_tab2[0], coeff_tab2[1], coeff_tab3[0], coeff_tab3[1], coeff_tab3[2], coeff_tab3[3], coeff_tab3[4], coeff_tab3[5], coeff_tab3[6], coeff_tab3[7], coeff_tab3[8], coeff_tab3[9], coeff_tab3[10], coeff_tab3[11], coeff_tab3[12], coeff_tab3[13], coeff_tab3[14], coeff_tab3[15], coeff_tab3[16], coeff_tab3[17], coeff_tab3[18], coeff_tab3[19], coeff_tab3[20], coeff_tab3[21], coeff_tab3[22], coeff_tab3[23], coeff_tab3[24], coeff_tab3[25], coeff_tab3[26], coeff_tab3[27], coeff_tab3[28], coeff_tab3[29], coeff_tab3[30], coeff_tab3[31], coeff_tab3[32], coeff_tab3[33], coeff_tab3[34], coeff_tab3[35], coeff_tab3[36], coeff_tab3[37], coeff_tab3[38], coeff_tab3[39], }; static VLC **coeff_vlc[4] = { coeff_intra_last0, coeff_intra_last1, coeff_inter_last0, coeff_inter_last1, }; /* MCBPC Indexing by cbpc in first two bits, mode in last two. CBPC as in table 4/H.263, MB type (mode): 3 = 01, 4 = 10. Example: cbpc = 01 and mode = 4 gives index = 0110 = 6. */ static VLC mcbpc_intra_tab[15] = { {0x01, 9}, {0x01, 1}, {0x01, 4}, {0x00, 0}, {0x00, 0}, {0x01, 3}, {0x01, 6}, {0x00, 0}, {0x00, 0}, {0x02, 3}, {0x02, 6}, {0x00, 0}, {0x00, 0}, {0x03, 3}, {0x03, 6} }; /* MCBPC inter. Addressing: 5 bit ccmmm (cc = CBPC, mmm = mode (1-4 binary)) */ static VLC mcbpc_inter_tab[29] = { {1, 1}, {3, 3}, {2, 3}, {3, 5}, {4, 6}, {1, 9}, {0, 0}, {0, 0}, {3, 4}, {7, 7}, {5, 7}, {4, 8}, {4, 9}, {0, 0}, {0, 0}, {0, 0}, {2, 4}, {6, 7}, {4, 7}, {3, 8}, {3, 9}, {0, 0}, {0, 0}, {0, 0}, {5, 6}, {5, 9}, {5, 8}, {3, 7}, {2, 9} }; static const VLC cbpy_tab[16] = { {3,4}, {5,5}, {4,5}, {9,4}, {3,5}, {7,4}, {2,6}, {11,4}, {2,5}, {3,6}, {5,4}, {10,4}, {4,4}, {8,4}, {6,4}, {3,2} }; static const VLC dcy_tab[511] = { {0x100, 15}, {0x101, 15}, {0x102, 15}, {0x103, 15}, {0x104, 15}, {0x105, 15}, {0x106, 15}, {0x107, 15}, {0x108, 15}, {0x109, 15}, {0x10a, 15}, {0x10b, 15}, {0x10c, 15}, {0x10d, 15}, {0x10e, 15}, {0x10f, 15}, {0x110, 15}, {0x111, 15}, {0x112, 15}, {0x113, 15}, {0x114, 15}, {0x115, 15}, {0x116, 15}, {0x117, 15}, {0x118, 15}, {0x119, 15}, {0x11a, 15}, {0x11b, 15}, {0x11c, 15}, {0x11d, 15}, {0x11e, 15}, {0x11f, 15}, {0x120, 15}, {0x121, 15}, {0x122, 15}, {0x123, 15}, {0x124, 15}, {0x125, 15}, {0x126, 15}, {0x127, 15}, {0x128, 15}, {0x129, 15}, {0x12a, 15}, {0x12b, 15}, {0x12c, 15}, {0x12d, 15}, {0x12e, 15}, {0x12f, 15}, {0x130, 15}, {0x131, 15}, {0x132, 15}, {0x133, 15}, {0x134, 15}, {0x135, 15}, {0x136, 15}, {0x137, 15}, {0x138, 15}, {0x139, 15}, {0x13a, 15}, {0x13b, 15}, {0x13c, 15}, {0x13d, 15}, {0x13e, 15}, {0x13f, 15}, {0x140, 15}, {0x141, 15}, {0x142, 15}, {0x143, 15}, {0x144, 15}, {0x145, 15}, {0x146, 15}, {0x147, 15}, {0x148, 15}, {0x149, 15}, {0x14a, 15}, {0x14b, 15}, {0x14c, 15}, {0x14d, 15}, {0x14e, 15}, {0x14f, 15}, {0x150, 15}, {0x151, 15}, {0x152, 15}, {0x153, 15}, {0x154, 15}, {0x155, 15}, {0x156, 15}, {0x157, 15}, {0x158, 15}, {0x159, 15}, {0x15a, 15}, {0x15b, 15}, {0x15c, 15}, {0x15d, 15}, {0x15e, 15}, {0x15f, 15}, {0x160, 15}, {0x161, 15}, {0x162, 15}, {0x163, 15}, {0x164, 15}, {0x165, 15}, {0x166, 15}, {0x167, 15}, {0x168, 15}, {0x169, 15}, {0x16a, 15}, {0x16b, 15}, {0x16c, 15}, {0x16d, 15}, {0x16e, 15}, {0x16f, 15}, {0x170, 15}, {0x171, 15}, {0x172, 15}, {0x173, 15}, {0x174, 15}, {0x175, 15}, {0x176, 15}, {0x177, 15}, {0x178, 15}, {0x179, 15}, {0x17a, 15}, {0x17b, 15}, {0x17c, 15}, {0x17d, 15}, {0x17e, 15}, {0x17f, 15}, {0x80, 13}, {0x81, 13}, {0x82, 13}, {0x83, 13}, {0x84, 13}, {0x85, 13}, {0x86, 13}, {0x87, 13}, {0x88, 13}, {0x89, 13}, {0x8a, 13}, {0x8b, 13}, {0x8c, 13}, {0x8d, 13}, {0x8e, 13}, {0x8f, 13}, {0x90, 13}, {0x91, 13}, {0x92, 13}, {0x93, 13}, {0x94, 13}, {0x95, 13}, {0x96, 13}, {0x97, 13}, {0x98, 13}, {0x99, 13}, {0x9a, 13}, {0x9b, 13}, {0x9c, 13}, {0x9d, 13}, {0x9e, 13}, {0x9f, 13}, {0xa0, 13}, {0xa1, 13}, {0xa2, 13}, {0xa3, 13}, {0xa4, 13}, {0xa5, 13}, {0xa6, 13}, {0xa7, 13}, {0xa8, 13}, {0xa9, 13}, {0xaa, 13}, {0xab, 13}, {0xac, 13}, {0xad, 13}, {0xae, 13}, {0xaf, 13}, {0xb0, 13}, {0xb1, 13}, {0xb2, 13}, {0xb3, 13}, {0xb4, 13}, {0xb5, 13}, {0xb6, 13}, {0xb7, 13}, {0xb8, 13}, {0xb9, 13}, {0xba, 13}, {0xbb, 13}, {0xbc, 13}, {0xbd, 13}, {0xbe, 13}, {0xbf, 13}, {0x40, 11}, {0x41, 11}, {0x42, 11}, {0x43, 11}, {0x44, 11}, {0x45, 11}, {0x46, 11}, {0x47, 11}, {0x48, 11}, {0x49, 11}, {0x4a, 11}, {0x4b, 11}, {0x4c, 11}, {0x4d, 11}, {0x4e, 11}, {0x4f, 11}, {0x50, 11}, {0x51, 11}, {0x52, 11}, {0x53, 11}, {0x54, 11}, {0x55, 11}, {0x56, 11}, {0x57, 11}, {0x58, 11}, {0x59, 11}, {0x5a, 11}, {0x5b, 11}, {0x5c, 11}, {0x5d, 11}, {0x5e, 11}, {0x5f, 11}, {0x20, 9}, {0x21, 9}, {0x22, 9}, {0x23, 9}, {0x24, 9}, {0x25, 9}, {0x26, 9}, {0x27, 9}, {0x28, 9}, {0x29, 9}, {0x2a, 9}, {0x2b, 9}, {0x2c, 9}, {0x2d, 9}, {0x2e, 9}, {0x2f, 9}, {0x10, 7}, {0x11, 7}, {0x12, 7}, {0x13, 7}, {0x14, 7}, {0x15, 7}, {0x16, 7}, {0x17, 7}, {0x10, 6}, {0x11, 6}, {0x12, 6}, {0x13, 6}, {0x08, 4}, {0x09, 4}, {0x06, 3}, {0x03, 3}, {0x07, 3}, {0x0a, 4}, {0x0b, 4}, {0x14, 6}, {0x15, 6}, {0x16, 6}, {0x17, 6}, {0x18, 7}, {0x19, 7}, {0x1a, 7}, {0x1b, 7}, {0x1c, 7}, {0x1d, 7}, {0x1e, 7}, {0x1f, 7}, {0x30, 9}, {0x31, 9}, {0x32, 9}, {0x33, 9}, {0x34, 9}, {0x35, 9}, {0x36, 9}, {0x37, 9}, {0x38, 9}, {0x39, 9}, {0x3a, 9}, {0x3b, 9}, {0x3c, 9}, {0x3d, 9}, {0x3e, 9}, {0x3f, 9}, {0x60, 11}, {0x61, 11}, {0x62, 11}, {0x63, 11}, {0x64, 11}, {0x65, 11}, {0x66, 11}, {0x67, 11}, {0x68, 11}, {0x69, 11}, {0x6a, 11}, {0x6b, 11}, {0x6c, 11}, {0x6d, 11}, {0x6e, 11}, {0x6f, 11}, {0x70, 11}, {0x71, 11}, {0x72, 11}, {0x73, 11}, {0x74, 11}, {0x75, 11}, {0x76, 11}, {0x77, 11}, {0x78, 11}, {0x79, 11}, {0x7a, 11}, {0x7b, 11}, {0x7c, 11}, {0x7d, 11}, {0x7e, 11}, {0x7f, 11}, {0xc0, 13}, {0xc1, 13}, {0xc2, 13}, {0xc3, 13}, {0xc4, 13}, {0xc5, 13}, {0xc6, 13}, {0xc7, 13}, {0xc8, 13}, {0xc9, 13}, {0xca, 13}, {0xcb, 13}, {0xcc, 13}, {0xcd, 13}, {0xce, 13}, {0xcf, 13}, {0xd0, 13}, {0xd1, 13}, {0xd2, 13}, {0xd3, 13}, {0xd4, 13}, {0xd5, 13}, {0xd6, 13}, {0xd7, 13}, {0xd8, 13}, {0xd9, 13}, {0xda, 13}, {0xdb, 13}, {0xdc, 13}, {0xdd, 13}, {0xde, 13}, {0xdf, 13}, {0xe0, 13}, {0xe1, 13}, {0xe2, 13}, {0xe3, 13}, {0xe4, 13}, {0xe5, 13}, {0xe6, 13}, {0xe7, 13}, {0xe8, 13}, {0xe9, 13}, {0xea, 13}, {0xeb, 13}, {0xec, 13}, {0xed, 13}, {0xee, 13}, {0xef, 13}, {0xf0, 13}, {0xf1, 13}, {0xf2, 13}, {0xf3, 13}, {0xf4, 13}, {0xf5, 13}, {0xf6, 13}, {0xf7, 13}, {0xf8, 13}, {0xf9, 13}, {0xfa, 13}, {0xfb, 13}, {0xfc, 13}, {0xfd, 13}, {0xfe, 13}, {0xff, 13}, {0x180, 15}, {0x181, 15}, {0x182, 15}, {0x183, 15}, {0x184, 15}, {0x185, 15}, {0x186, 15}, {0x187, 15}, {0x188, 15}, {0x189, 15}, {0x18a, 15}, {0x18b, 15}, {0x18c, 15}, {0x18d, 15}, {0x18e, 15}, {0x18f, 15}, {0x190, 15}, {0x191, 15}, {0x192, 15}, {0x193, 15}, {0x194, 15}, {0x195, 15}, {0x196, 15}, {0x197, 15}, {0x198, 15}, {0x199, 15}, {0x19a, 15}, {0x19b, 15}, {0x19c, 15}, {0x19d, 15}, {0x19e, 15}, {0x19f, 15}, {0x1a0, 15}, {0x1a1, 15}, {0x1a2, 15}, {0x1a3, 15}, {0x1a4, 15}, {0x1a5, 15}, {0x1a6, 15}, {0x1a7, 15}, {0x1a8, 15}, {0x1a9, 15}, {0x1aa, 15}, {0x1ab, 15}, {0x1ac, 15}, {0x1ad, 15}, {0x1ae, 15}, {0x1af, 15}, {0x1b0, 15}, {0x1b1, 15}, {0x1b2, 15}, {0x1b3, 15}, {0x1b4, 15}, {0x1b5, 15}, {0x1b6, 15}, {0x1b7, 15}, {0x1b8, 15}, {0x1b9, 15}, {0x1ba, 15}, {0x1bb, 15}, {0x1bc, 15}, {0x1bd, 15}, {0x1be, 15}, {0x1bf, 15}, {0x1c0, 15}, {0x1c1, 15}, {0x1c2, 15}, {0x1c3, 15}, {0x1c4, 15}, {0x1c5, 15}, {0x1c6, 15}, {0x1c7, 15}, {0x1c8, 15}, {0x1c9, 15}, {0x1ca, 15}, {0x1cb, 15}, {0x1cc, 15}, {0x1cd, 15}, {0x1ce, 15}, {0x1cf, 15}, {0x1d0, 15}, {0x1d1, 15}, {0x1d2, 15}, {0x1d3, 15}, {0x1d4, 15}, {0x1d5, 15}, {0x1d6, 15}, {0x1d7, 15}, {0x1d8, 15}, {0x1d9, 15}, {0x1da, 15}, {0x1db, 15}, {0x1dc, 15}, {0x1dd, 15}, {0x1de, 15}, {0x1df, 15}, {0x1e0, 15}, {0x1e1, 15}, {0x1e2, 15}, {0x1e3, 15}, {0x1e4, 15}, {0x1e5, 15}, {0x1e6, 15}, {0x1e7, 15}, {0x1e8, 15}, {0x1e9, 15}, {0x1ea, 15}, {0x1eb, 15}, {0x1ec, 15}, {0x1ed, 15}, {0x1ee, 15}, {0x1ef, 15}, {0x1f0, 15}, {0x1f1, 15}, {0x1f2, 15}, {0x1f3, 15}, {0x1f4, 15}, {0x1f5, 15}, {0x1f6, 15}, {0x1f7, 15}, {0x1f8, 15}, {0x1f9, 15}, {0x1fa, 15}, {0x1fb, 15}, {0x1fc, 15}, {0x1fd, 15}, {0x1fe, 15}, {0x1ff, 15}, }; static const VLC dcc_tab[511] = { {0x100, 16}, {0x101, 16}, {0x102, 16}, {0x103, 16}, {0x104, 16}, {0x105, 16}, {0x106, 16}, {0x107, 16}, {0x108, 16}, {0x109, 16}, {0x10a, 16}, {0x10b, 16}, {0x10c, 16}, {0x10d, 16}, {0x10e, 16}, {0x10f, 16}, {0x110, 16}, {0x111, 16}, {0x112, 16}, {0x113, 16}, {0x114, 16}, {0x115, 16}, {0x116, 16}, {0x117, 16}, {0x118, 16}, {0x119, 16}, {0x11a, 16}, {0x11b, 16}, {0x11c, 16}, {0x11d, 16}, {0x11e, 16}, {0x11f, 16}, {0x120, 16}, {0x121, 16}, {0x122, 16}, {0x123, 16}, {0x124, 16}, {0x125, 16}, {0x126, 16}, {0x127, 16}, {0x128, 16}, {0x129, 16}, {0x12a, 16}, {0x12b, 16}, {0x12c, 16}, {0x12d, 16}, {0x12e, 16}, {0x12f, 16}, {0x130, 16}, {0x131, 16}, {0x132, 16}, {0x133, 16}, {0x134, 16}, {0x135, 16}, {0x136, 16}, {0x137, 16}, {0x138, 16}, {0x139, 16}, {0x13a, 16}, {0x13b, 16}, {0x13c, 16}, {0x13d, 16}, {0x13e, 16}, {0x13f, 16}, {0x140, 16}, {0x141, 16}, {0x142, 16}, {0x143, 16}, {0x144, 16}, {0x145, 16}, {0x146, 16}, {0x147, 16}, {0x148, 16}, {0x149, 16}, {0x14a, 16}, {0x14b, 16}, {0x14c, 16}, {0x14d, 16}, {0x14e, 16}, {0x14f, 16}, {0x150, 16}, {0x151, 16}, {0x152, 16}, {0x153, 16}, {0x154, 16}, {0x155, 16}, {0x156, 16}, {0x157, 16}, {0x158, 16}, {0x159, 16}, {0x15a, 16}, {0x15b, 16}, {0x15c, 16}, {0x15d, 16}, {0x15e, 16}, {0x15f, 16}, {0x160, 16}, {0x161, 16}, {0x162, 16}, {0x163, 16}, {0x164, 16}, {0x165, 16}, {0x166, 16}, {0x167, 16}, {0x168, 16}, {0x169, 16}, {0x16a, 16}, {0x16b, 16}, {0x16c, 16}, {0x16d, 16}, {0x16e, 16}, {0x16f, 16}, {0x170, 16}, {0x171, 16}, {0x172, 16}, {0x173, 16}, {0x174, 16}, {0x175, 16}, {0x176, 16}, {0x177, 16}, {0x178, 16}, {0x179, 16}, {0x17a, 16}, {0x17b, 16}, {0x17c, 16}, {0x17d, 16}, {0x17e, 16}, {0x17f, 16}, {0x80, 14}, {0x81, 14}, {0x82, 14}, {0x83, 14}, {0x84, 14}, {0x85, 14}, {0x86, 14}, {0x87, 14}, {0x88, 14}, {0x89, 14}, {0x8a, 14}, {0x8b, 14}, {0x8c, 14}, {0x8d, 14}, {0x8e, 14}, {0x8f, 14}, {0x90, 14}, {0x91, 14}, {0x92, 14}, {0x93, 14}, {0x94, 14}, {0x95, 14}, {0x96, 14}, {0x97, 14}, {0x98, 14}, {0x99, 14}, {0x9a, 14}, {0x9b, 14}, {0x9c, 14}, {0x9d, 14}, {0x9e, 14}, {0x9f, 14}, {0xa0, 14}, {0xa1, 14}, {0xa2, 14}, {0xa3, 14}, {0xa4, 14}, {0xa5, 14}, {0xa6, 14}, {0xa7, 14}, {0xa8, 14}, {0xa9, 14}, {0xaa, 14}, {0xab, 14}, {0xac, 14}, {0xad, 14}, {0xae, 14}, {0xaf, 14}, {0xb0, 14}, {0xb1, 14}, {0xb2, 14}, {0xb3, 14}, {0xb4, 14}, {0xb5, 14}, {0xb6, 14}, {0xb7, 14}, {0xb8, 14}, {0xb9, 14}, {0xba, 14}, {0xbb, 14}, {0xbc, 14}, {0xbd, 14}, {0xbe, 14}, {0xbf, 14}, {0x40, 12}, {0x41, 12}, {0x42, 12}, {0x43, 12}, {0x44, 12}, {0x45, 12}, {0x46, 12}, {0x47, 12}, {0x48, 12}, {0x49, 12}, {0x4a, 12}, {0x4b, 12}, {0x4c, 12}, {0x4d, 12}, {0x4e, 12}, {0x4f, 12}, {0x50, 12}, {0x51, 12}, {0x52, 12}, {0x53, 12}, {0x54, 12}, {0x55, 12}, {0x56, 12}, {0x57, 12}, {0x58, 12}, {0x59, 12}, {0x5a, 12}, {0x5b, 12}, {0x5c, 12}, {0x5d, 12}, {0x5e, 12}, {0x5f, 12}, {0x20, 10}, {0x21, 10}, {0x22, 10}, {0x23, 10}, {0x24, 10}, {0x25, 10}, {0x26, 10}, {0x27, 10}, {0x28, 10}, {0x29, 10}, {0x2a, 10}, {0x2b, 10}, {0x2c, 10}, {0x2d, 10}, {0x2e, 10}, {0x2f, 10}, {0x10, 8}, {0x11, 8}, {0x12, 8}, {0x13, 8}, {0x14, 8}, {0x15, 8}, {0x16, 8}, {0x17, 8}, {0x08, 6}, {0x09, 6}, {0x0a, 6}, {0x0b, 6}, {0x04, 4}, {0x05, 4}, {0x04, 3}, {0x03, 2}, {0x05, 3}, {0x06, 4}, {0x07, 4}, {0x0c, 6}, {0x0d, 6}, {0x0e, 6}, {0x0f, 6}, {0x18, 8}, {0x19, 8}, {0x1a, 8}, {0x1b, 8}, {0x1c, 8}, {0x1d, 8}, {0x1e, 8}, {0x1f, 8}, {0x30, 10}, {0x31, 10}, {0x32, 10}, {0x33, 10}, {0x34, 10}, {0x35, 10}, {0x36, 10}, {0x37, 10}, {0x38, 10}, {0x39, 10}, {0x3a, 10}, {0x3b, 10}, {0x3c, 10}, {0x3d, 10}, {0x3e, 10}, {0x3f, 10}, {0x60, 12}, {0x61, 12}, {0x62, 12}, {0x63, 12}, {0x64, 12}, {0x65, 12}, {0x66, 12}, {0x67, 12}, {0x68, 12}, {0x69, 12}, {0x6a, 12}, {0x6b, 12}, {0x6c, 12}, {0x6d, 12}, {0x6e, 12}, {0x6f, 12}, {0x70, 12}, {0x71, 12}, {0x72, 12}, {0x73, 12}, {0x74, 12}, {0x75, 12}, {0x76, 12}, {0x77, 12}, {0x78, 12}, {0x79, 12}, {0x7a, 12}, {0x7b, 12}, {0x7c, 12}, {0x7d, 12}, {0x7e, 12}, {0x7f, 12}, {0xc0, 14}, {0xc1, 14}, {0xc2, 14}, {0xc3, 14}, {0xc4, 14}, {0xc5, 14}, {0xc6, 14}, {0xc7, 14}, {0xc8, 14}, {0xc9, 14}, {0xca, 14}, {0xcb, 14}, {0xcc, 14}, {0xcd, 14}, {0xce, 14}, {0xcf, 14}, {0xd0, 14}, {0xd1, 14}, {0xd2, 14}, {0xd3, 14}, {0xd4, 14}, {0xd5, 14}, {0xd6, 14}, {0xd7, 14}, {0xd8, 14}, {0xd9, 14}, {0xda, 14}, {0xdb, 14}, {0xdc, 14}, {0xdd, 14}, {0xde, 14}, {0xdf, 14}, {0xe0, 14}, {0xe1, 14}, {0xe2, 14}, {0xe3, 14}, {0xe4, 14}, {0xe5, 14}, {0xe6, 14}, {0xe7, 14}, {0xe8, 14}, {0xe9, 14}, {0xea, 14}, {0xeb, 14}, {0xec, 14}, {0xed, 14}, {0xee, 14}, {0xef, 14}, {0xf0, 14}, {0xf1, 14}, {0xf2, 14}, {0xf3, 14}, {0xf4, 14}, {0xf5, 14}, {0xf6, 14}, {0xf7, 14}, {0xf8, 14}, {0xf9, 14}, {0xfa, 14}, {0xfb, 14}, {0xfc, 14}, {0xfd, 14}, {0xfe, 14}, {0xff, 14}, {0x180, 16}, {0x181, 16}, {0x182, 16}, {0x183, 16}, {0x184, 16}, {0x185, 16}, {0x186, 16}, {0x187, 16}, {0x188, 16}, {0x189, 16}, {0x18a, 16}, {0x18b, 16}, {0x18c, 16}, {0x18d, 16}, {0x18e, 16}, {0x18f, 16}, {0x190, 16}, {0x191, 16}, {0x192, 16}, {0x193, 16}, {0x194, 16}, {0x195, 16}, {0x196, 16}, {0x197, 16}, {0x198, 16}, {0x199, 16}, {0x19a, 16}, {0x19b, 16}, {0x19c, 16}, {0x19d, 16}, {0x19e, 16}, {0x19f, 16}, {0x1a0, 16}, {0x1a1, 16}, {0x1a2, 16}, {0x1a3, 16}, {0x1a4, 16}, {0x1a5, 16}, {0x1a6, 16}, {0x1a7, 16}, {0x1a8, 16}, {0x1a9, 16}, {0x1aa, 16}, {0x1ab, 16}, {0x1ac, 16}, {0x1ad, 16}, {0x1ae, 16}, {0x1af, 16}, {0x1b0, 16}, {0x1b1, 16}, {0x1b2, 16}, {0x1b3, 16}, {0x1b4, 16}, {0x1b5, 16}, {0x1b6, 16}, {0x1b7, 16}, {0x1b8, 16}, {0x1b9, 16}, {0x1ba, 16}, {0x1bb, 16}, {0x1bc, 16}, {0x1bd, 16}, {0x1be, 16}, {0x1bf, 16}, {0x1c0, 16}, {0x1c1, 16}, {0x1c2, 16}, {0x1c3, 16}, {0x1c4, 16}, {0x1c5, 16}, {0x1c6, 16}, {0x1c7, 16}, {0x1c8, 16}, {0x1c9, 16}, {0x1ca, 16}, {0x1cb, 16}, {0x1cc, 16}, {0x1cd, 16}, {0x1ce, 16}, {0x1cf, 16}, {0x1d0, 16}, {0x1d1, 16}, {0x1d2, 16}, {0x1d3, 16}, {0x1d4, 16}, {0x1d5, 16}, {0x1d6, 16}, {0x1d7, 16}, {0x1d8, 16}, {0x1d9, 16}, {0x1da, 16}, {0x1db, 16}, {0x1dc, 16}, {0x1dd, 16}, {0x1de, 16}, {0x1df, 16}, {0x1e0, 16}, {0x1e1, 16}, {0x1e2, 16}, {0x1e3, 16}, {0x1e4, 16}, {0x1e5, 16}, {0x1e6, 16}, {0x1e7, 16}, {0x1e8, 16}, {0x1e9, 16}, {0x1ea, 16}, {0x1eb, 16}, {0x1ec, 16}, {0x1ed, 16}, {0x1ee, 16}, {0x1ef, 16}, {0x1f0, 16}, {0x1f1, 16}, {0x1f2, 16}, {0x1f3, 16}, {0x1f4, 16}, {0x1f5, 16}, {0x1f6, 16}, {0x1f7, 16}, {0x1f8, 16}, {0x1f9, 16}, {0x1fa, 16}, {0x1fb, 16}, {0x1fc, 16}, {0x1fd, 16}, {0x1fe, 16}, {0x1ff, 16}, }; static const VLC mb_motion_table[65] = { {0x05, 13}, {0x07, 13}, {0x05, 12}, {0x07, 12}, {0x09, 12}, {0x0b, 12}, {0x0d, 12}, {0x0f, 12}, {0x09, 11}, {0x0b, 11}, {0x0d, 11}, {0x0f, 11}, {0x11, 11}, {0x13, 11}, {0x15, 11}, {0x17, 11}, {0x19, 11}, {0x1b, 11}, {0x1d, 11}, {0x1f, 11}, {0x21, 11}, {0x23, 11}, {0x13, 10}, {0x15, 10}, {0x17, 10}, {0x07, 8}, {0x09, 8}, {0x0b, 8}, {0x07, 7}, {0x03, 5}, {0x03, 4}, {0x03, 3}, {0x01, 1}, {0x02, 3}, {0x02, 4}, {0x02, 5}, {0x06, 7}, {0x0a, 8}, {0x08, 8}, {0x06, 8}, {0x16, 10}, {0x14, 10}, {0x12, 10}, {0x22, 11}, {0x20, 11}, {0x1e, 11}, {0x1c, 11}, {0x1a, 11}, {0x18, 11}, {0x16, 11}, {0x14, 11}, {0x12, 11}, {0x10, 11}, {0x0e, 11}, {0x0c, 11}, {0x0a, 11}, {0x08, 11}, {0x0e, 12}, {0x0c, 12}, {0x0a, 12}, {0x08, 12}, {0x06, 12}, {0x04, 12}, {0x06, 13}, {0x04, 13} }; /****************************************************************** * decoder tables * ******************************************************************/ static const VLC mcbpc_intra_table[64] = { {-1,0}, {20,6}, {36,6}, {52,6}, {4,4}, {4,4}, {4,4}, {4,4}, {19,3}, {19,3}, {19,3}, {19,3}, {19,3}, {19,3}, {19,3}, {19,3}, {35,3}, {35,3}, {35,3}, {35,3}, {35,3}, {35,3}, {35,3}, {35,3}, {51,3}, {51,3}, {51,3}, {51,3}, {51,3}, {51,3}, {51,3}, {51,3}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1}, {3, 1} }; static const VLC mcbpc_inter_table[257] = { {VLC_ERROR,0}, {255,9}, {52,9}, {36,9}, {20,9}, {49,9}, {35,8}, {35,8}, {19,8}, {19,8}, {50,8}, {50,8}, {51,7}, {51,7}, {51,7}, {51,7}, {34,7}, {34,7}, {34,7}, {34,7}, {18,7}, {18,7}, {18,7}, {18,7}, {33,7}, {33,7}, {33,7}, {33,7}, {17,7}, {17,7}, {17,7}, {17,7}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {48,6}, {48,6}, {48,6}, {48,6}, {48,6}, {48,6}, {48,6}, {48,6}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {3,5}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {32,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {16,4}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {2,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {1,3}, {0,1} }; static const VLC cbpy_table[64] = { {-1,0}, {-1,0}, {6,6}, {9,6}, {8,5}, {8,5}, {4,5}, {4,5}, {2,5}, {2,5}, {1,5}, {1,5}, {0,4}, {0,4}, {0,4}, {0,4}, {12,4}, {12,4}, {12,4}, {12,4}, {10,4}, {10,4}, {10,4}, {10,4}, {14,4}, {14,4}, {14,4}, {14,4}, {5,4}, {5,4}, {5,4}, {5,4}, {13,4}, {13,4}, {13,4}, {13,4}, {3,4}, {3,4}, {3,4}, {3,4}, {11,4}, {11,4}, {11,4}, {11,4}, {7,4}, {7,4}, {7,4}, {7,4}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2} }; VLC TMNMVtab0[] = { {3,4}, {-3,4}, {2,3}, {2,3}, {-2,3}, {-2,3}, {1,2}, {1,2}, {1,2}, {1,2}, {-1,2}, {-1,2}, {-1,2}, {-1,2} }; VLC TMNMVtab1[] = { {12,10}, {-12,10}, {11,10}, {-11,10}, {10,9}, {10,9}, {-10,9}, {-10,9}, {9,9}, {9,9}, {-9,9}, {-9,9}, {8,9}, {8,9}, {-8,9}, {-8,9}, {7,7}, {7,7}, {7,7}, {7,7}, {7,7}, {7,7}, {7,7}, {7,7}, {-7,7}, {-7,7}, {-7,7}, {-7,7}, {-7,7}, {-7,7}, {-7,7}, {-7,7}, {6,7}, {6,7}, {6,7}, {6,7}, {6,7}, {6,7}, {6,7}, {6,7}, {-6,7}, {-6,7}, {-6,7}, {-6,7}, {-6,7}, {-6,7}, {-6,7}, {-6,7}, {5,7}, {5,7}, {5,7}, {5,7}, {5,7}, {5,7}, {5,7}, {5,7}, {-5,7}, {-5,7}, {-5,7}, {-5,7}, {-5,7}, {-5,7}, {-5,7}, {-5,7}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6}, {-4,6} }; VLC TMNMVtab2[] = { {32,12}, {-32,12}, {31,12}, {-31,12}, {30,11}, {30,11}, {-30,11}, {-30,11}, {29,11}, {29,11}, {-29,11}, {-29,11}, {28,11}, {28,11}, {-28,11}, {-28,11}, {27,11}, {27,11}, {-27,11}, {-27,11}, {26,11}, {26,11}, {-26,11}, {-26,11}, {25,11}, {25,11}, {-25,11}, {-25,11}, {24,10}, {24,10}, {24,10}, {24,10}, {-24,10}, {-24,10}, {-24,10}, {-24,10}, {23,10}, {23,10}, {23,10}, {23,10}, {-23,10}, {-23,10}, {-23,10}, {-23,10}, {22,10}, {22,10}, {22,10}, {22,10}, {-22,10}, {-22,10}, {-22,10}, {-22,10}, {21,10}, {21,10}, {21,10}, {21,10}, {-21,10}, {-21,10}, {-21,10}, {-21,10}, {20,10}, {20,10}, {20,10}, {20,10}, {-20,10}, {-20,10}, {-20,10}, {-20,10}, {19,10}, {19,10}, {19,10}, {19,10}, {-19,10}, {-19,10}, {-19,10}, {-19,10}, {18,10}, {18,10}, {18,10}, {18,10}, {-18,10}, {-18,10}, {-18,10}, {-18,10}, {17,10}, {17,10}, {17,10}, {17,10}, {-17,10}, {-17,10}, {-17,10}, {-17,10}, {16,10}, {16,10}, {16,10}, {16,10}, {-16,10}, {-16,10}, {-16,10}, {-16,10}, {15,10}, {15,10}, {15,10}, {15,10}, {-15,10}, {-15,10}, {-15,10}, {-15,10}, {14,10}, {14,10}, {14,10}, {14,10}, {-14,10}, {-14,10}, {-14,10}, {-14,10}, {13,10}, {13,10}, {13,10}, {13,10}, {-13,10}, {-13,10}, {-13,10}, {-13,10} }; VLC DCT3Dtab0[] = { {4225,7}, {4209,7}, {4193,7}, {4177,7}, {193,7}, {177,7}, {161,7}, {4,7}, {4161,6}, {4161,6}, {4145,6}, {4145,6}, {4129,6}, {4129,6}, {4113,6}, {4113,6}, {145,6}, {145,6}, {129,6}, {129,6}, {113,6}, {113,6}, {97,6}, {97,6}, {18,6}, {18,6}, {3,6}, {3,6}, {81,5}, {81,5}, {81,5}, {81,5}, {65,5}, {65,5}, {65,5}, {65,5}, {49,5}, {49,5}, {49,5}, {49,5}, {4097,4}, {4097,4}, {4097,4}, {4097,4}, {4097,4}, {4097,4}, {4097,4}, {4097,4}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {17,3}, {33,4}, {33,4}, {33,4}, {33,4}, {33,4}, {33,4}, {33,4}, {33,4}, {2,4}, {2,4},{2,4},{2,4}, {2,4}, {2,4},{2,4},{2,4} }; VLC DCT3Dtab1[] = { {9,10}, {8,10}, {4481,9}, {4481,9}, {4465,9}, {4465,9}, {4449,9}, {4449,9}, {4433,9}, {4433,9}, {4417,9}, {4417,9}, {4401,9}, {4401,9}, {4385,9}, {4385,9}, {4369,9}, {4369,9}, {4098,9}, {4098,9}, {353,9}, {353,9}, {337,9}, {337,9}, {321,9}, {321,9}, {305,9}, {305,9}, {289,9}, {289,9}, {273,9}, {273,9}, {257,9}, {257,9}, {241,9}, {241,9}, {66,9}, {66,9}, {50,9}, {50,9}, {7,9}, {7,9}, {6,9}, {6,9}, {4353,8}, {4353,8}, {4353,8}, {4353,8}, {4337,8}, {4337,8}, {4337,8}, {4337,8}, {4321,8}, {4321,8}, {4321,8}, {4321,8}, {4305,8}, {4305,8}, {4305,8}, {4305,8}, {4289,8}, {4289,8}, {4289,8}, {4289,8}, {4273,8}, {4273,8}, {4273,8}, {4273,8}, {4257,8}, {4257,8}, {4257,8}, {4257,8}, {4241,8}, {4241,8}, {4241,8}, {4241,8}, {225,8}, {225,8}, {225,8}, {225,8}, {209,8}, {209,8}, {209,8}, {209,8}, {34,8}, {34,8}, {34,8}, {34,8}, {19,8}, {19,8}, {19,8}, {19,8}, {5,8}, {5,8}, {5,8}, {5,8} }; VLC DCT3Dtab2[] = { {4114,11}, {4114,11}, {4099,11}, {4099,11}, {11,11}, {11,11}, {10,11}, {10,11}, {4545,10}, {4545,10}, {4545,10}, {4545,10}, {4529,10}, {4529,10}, {4529,10}, {4529,10}, {4513,10}, {4513,10}, {4513,10}, {4513,10}, {4497,10}, {4497,10}, {4497,10}, {4497,10}, {146,10}, {146,10}, {146,10}, {146,10}, {130,10}, {130,10}, {130,10}, {130,10}, {114,10}, {114,10}, {114,10}, {114,10}, {98,10}, {98,10}, {98,10}, {98,10}, {82,10}, {82,10}, {82,10}, {82,10}, {51,10}, {51,10}, {51,10}, {51,10}, {35,10}, {35,10}, {35,10}, {35,10}, {20,10}, {20,10}, {20,10}, {20,10}, {12,11}, {12,11}, {21,11}, {21,11}, {369,11}, {369,11}, {385,11}, {385,11}, {4561,11}, {4561,11}, {4577,11}, {4577,11}, {4593,11}, {4593,11}, {4609,11}, {4609,11}, {22,12}, {36,12}, {67,12}, {83,12}, {99,12}, {162,12}, {401,12}, {417,12}, {4625,12}, {4641,12}, {4657,12}, {4673,12}, {4689,12}, {4705,12}, {4721,12}, {4737,12}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7}, {7167,7} }; /* New tables for Intra luminance blocks */ VLC DCT3Dtab3[] = { {0x10401, 7}, {0x10301, 7}, {0x00601, 7}, {0x10501, 7}, {0x00701, 7}, {0x00202, 7}, {0x00103, 7}, {0x00009, 7}, {0x10002, 6}, {0x10002, 6}, {0x00501, 6}, {0x00501, 6}, {0x10201, 6}, {0x10201, 6}, {0x10101, 6}, {0x10101, 6}, {0x00401, 6}, {0x00401, 6}, {0x00301, 6}, {0x00301, 6}, {0x00008, 6}, {0x00008, 6}, {0x00007, 6}, {0x00007, 6}, {0x00102, 6}, {0x00102, 6}, {0x00006, 6}, {0x00006, 6}, {0x00201, 5}, {0x00201, 5}, {0x00201, 5}, {0x00201, 5}, {0x00005, 5}, {0x00005, 5}, {0x00005, 5}, {0x00005, 5}, {0x00004, 5}, {0x00004, 5}, {0x00004, 5}, {0x00004, 5}, {0x10001, 4}, {0x10001, 4}, {0x10001, 4}, {0x10001, 4}, {0x10001, 4}, {0x10001, 4}, {0x10001, 4}, {0x10001, 4}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00101, 4}, {0x00101, 4}, {0x00101, 4}, {0x00101, 4}, {0x00101, 4}, {0x00101, 4}, {0x00101, 4}, {0x00101, 4}, {0x00003, 4}, {0x00003, 4}, {0x00003, 4}, {0x00003, 4}, {0x00003, 4}, {0x00003, 4}, {0x00003, 4}, {0x00003, 4} }; VLC DCT3Dtab4[] = { {0x00012,10}, {0x00011,10}, {0x10e01, 9}, {0x10e01, 9}, {0x10d01, 9}, {0x10d01, 9}, {0x10c01, 9}, {0x10c01, 9}, {0x10b01, 9}, {0x10b01, 9}, {0x10a01, 9}, {0x10a01, 9}, {0x10102, 9}, {0x10102, 9}, {0x10004, 9}, {0x10004, 9}, {0x00c01, 9}, {0x00c01, 9}, {0x00b01, 9}, {0x00b01, 9}, {0x00702, 9}, {0x00702, 9}, {0x00602, 9}, {0x00602, 9}, {0x00502, 9}, {0x00502, 9}, {0x00303, 9}, {0x00303, 9}, {0x00203, 9}, {0x00203, 9}, {0x00106, 9}, {0x00106, 9}, {0x00105, 9}, {0x00105, 9}, {0x00010, 9}, {0x00010, 9}, {0x00402, 9}, {0x00402, 9}, {0x0000f, 9}, {0x0000f, 9}, {0x0000e, 9}, {0x0000e, 9}, {0x0000d, 9}, {0x0000d, 9}, {0x10801, 8}, {0x10801, 8}, {0x10801, 8}, {0x10801, 8}, {0x10701, 8}, {0x10701, 8}, {0x10701, 8}, {0x10701, 8}, {0x10601, 8}, {0x10601, 8}, {0x10601, 8}, {0x10601, 8}, {0x10003, 8}, {0x10003, 8}, {0x10003, 8}, {0x10003, 8}, {0x00a01, 8}, {0x00a01, 8}, {0x00a01, 8}, {0x00a01, 8}, {0x00901, 8}, {0x00901, 8}, {0x00901, 8}, {0x00901, 8}, {0x00801, 8}, {0x00801, 8}, {0x00801, 8}, {0x00801, 8}, {0x10901, 8}, {0x10901, 8}, {0x10901, 8}, {0x10901, 8}, {0x00302, 8}, {0x00302, 8}, {0x00302, 8}, {0x00302, 8}, {0x00104, 8}, {0x00104, 8}, {0x00104, 8}, {0x00104, 8}, {0x0000c, 8}, {0x0000c, 8}, {0x0000c, 8}, {0x0000c, 8}, {0x0000b, 8}, {0x0000b, 8}, {0x0000b, 8}, {0x0000b, 8}, {0x0000a, 8}, {0x0000a, 8}, {0x0000a, 8}, {0x0000a, 8} }; VLC DCT3Dtab5[] = { {0x10007,11}, {0x10007,11}, {0x10006,11}, {0x10006,11}, {0x00016,11}, {0x00016,11}, {0x00015,11}, {0x00015,11}, {0x10202,10}, {0x10202,10}, {0x10202,10}, {0x10202,10}, {0x10103,10}, {0x10103,10}, {0x10103,10}, {0x10103,10}, {0x10005,10}, {0x10005,10}, {0x10005,10}, {0x10005,10}, {0x00d01,10}, {0x00d01,10}, {0x00d01,10}, {0x00d01,10}, {0x00503,10}, {0x00503,10}, {0x00503,10}, {0x00503,10}, {0x00802,10}, {0x00802,10}, {0x00802,10}, {0x00802,10}, {0x00403,10}, {0x00403,10}, {0x00403,10}, {0x00403,10}, {0x00304,10}, {0x00304,10}, {0x00304,10}, {0x00304,10}, {0x00204,10}, {0x00204,10}, {0x00204,10}, {0x00204,10}, {0x00107,10}, {0x00107,10}, {0x00107,10}, {0x00107,10}, {0x00014,10}, {0x00014,10}, {0x00014,10}, {0x00014,10}, {0x00013,10}, {0x00013,10}, {0x00013,10}, {0x00013,10}, {0x00017,11}, {0x00017,11}, {0x00018,11}, {0x00018,11}, {0x00108,11}, {0x00108,11}, {0x00902,11}, {0x00902,11}, {0x10302,11}, {0x10302,11}, {0x10402,11}, {0x10402,11}, {0x10f01,11}, {0x10f01,11}, {0x11001,11}, {0x11001,11}, {0x00019,12}, {0x0001a,12}, {0x0001b,12}, {0x00109,12}, {0x00603,12}, {0x0010a,12}, {0x00205,12}, {0x00703,12}, {0x00e01,12}, {0x10008,12}, {0x10502,12}, {0x10602,12}, {0x11101,12}, {0x11201,12}, {0x11301,12}, {0x11401,12}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7} }; VLC ERRtab[] = { {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0}, {VLC_ERROR, 0} }; static const VLC dc_lum_tab[] = { {0, 0}, {4, 3}, {3, 3}, {0, 3}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, }; static __inline int get_coeff(Bitstream * bs, int *run, int *last, int intra, int short_video_header) { uint32_t mode; const VLC *tab; int32_t level; if(short_video_header) // inter-VLCs will be used for both intra and inter blocks intra = 0; tab = &DCT3D[intra][BitstreamShowBits(bs, 12)]; if(tab->code == -1) goto error; BitstreamSkip(bs, tab->len); if(tab->code != ESCAPE) { if(!intra) { *run = (tab->code >> 4) & 255; level = tab->code & 15; *last = (tab->code >> 12) & 1; } else { *run = (tab->code >> 8) & 255; level = tab->code & 255; *last = (tab->code >> 16) & 1; } return BitstreamGetBit(bs) ? -level : level; } if(short_video_header) { // escape mode 4 - H.263 type, only used if short_video_header = 1 *last = BitstreamGetBit(bs); *run = BitstreamGetBits(bs, 6); level = BitstreamGetBits(bs, 8); if (level == 0 || level == 128) DEBUG1("Illegal LEVEL for ESCAPE mode 4:", level); return (level >= 128 ? -(256 - level) : level); } mode = BitstreamShowBits(bs, 2); if(mode < 3) { BitstreamSkip(bs, (mode == 2) ? 2 : 1); tab = &DCT3D[intra][BitstreamShowBits(bs, 12)]; if (tab->code == -1) goto error; BitstreamSkip(bs, tab->len); if (!intra) { *run = (tab->code >> 4) & 255; level = tab->code & 15; *last = (tab->code >> 12) & 1; } else { *run = (tab->code >> 8) & 255; level = tab->code & 255; *last = (tab->code >> 16) & 1; } if(mode < 2) // first escape mode, level is offset level += max_level[*last + (!intra<<1)][*run]; // need to add back the max level else if(mode == 2) // second escape mode, run is offset *run += max_run[*last + (!intra<<1)][level] + 1; return BitstreamGetBit(bs) ? -level : level; } // third escape mode - fixed length codes BitstreamSkip(bs, 2); *last = BitstreamGetBits(bs, 1); *run = BitstreamGetBits(bs, 6); BitstreamSkip(bs, 1); // marker level = BitstreamGetBits(bs, 12); BitstreamSkip(bs, 1); // marker return (level & 0x800) ? (level | (-1 ^ 0xfff)) : level; error: *run = VLC_ERROR; return 0; } #endif /* _VLC_CODES_H */ xvid_20020412/xvidcore/src/bitstream/bitstream.c0100644000100600001440000004632407450606004021072 0ustar michaelusers /****************************************************************************** * * * This file is part of XviD, a free MPEG-4 video encoder/decoder * * * * XviD is an implementation of a part of one or more MPEG-4 Video tools * * as specified in ISO/IEC 14496-2 standard. Those intending to use this * * software module in hardware or software products are advised that its * * use may infringe existing patents or copyrights, and any such use * * would be at such party's own risk. The original developer of this * * software module and his/her company, and subsequent editors and their * * companies, will have no liability for use of this software or * * modifications or derivatives thereof. * * * * XviD is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * XviD is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * ******************************************************************************/ /****************************************************************************** * * * bitstream.c * * * * Copyright (C) 2001 - Peter Ross * * * * For more information visit the XviD homepage: http://www.xvid.org * * * ******************************************************************************/ /****************************************************************************** * * * Revision history: * * * * 26.03.2002 interlacing support * 03.03.2002 qmatrix writing * * 03.03.2002 merged BITREADER and BITWRITER * * 30.02.2002 intra_dc_threshold support * * 04.12.2001 support for additional headers * * 16.12.2001 inital version * * * ******************************************************************************/ #include "bitstream.h" #include "zigzag.h" #include "../quant/quant_matrix.h" static int __inline log2bin(int value) { int n = 0; while (value) { value >>= 1; n++; } return n; } static const uint32_t intra_dc_threshold_table[] = { 32, /* never use */ 13, 15, 17, 19, 21, 23, 1, }; void bs_get_matrix(Bitstream * bs, uint8_t * matrix) { int i = 0; int last, value = 0; do { last = value; value = BitstreamGetBits(bs, 8); matrix[ scan_tables[0][i++] ] = value; } while (value != 0 && i < 64); while (i < 64) { matrix[ scan_tables[0][i++] ] = last; } } /* decode headers returns coding_type, or -1 if error */ int BitstreamReadHeaders(Bitstream * bs, DECODER * dec, uint32_t * rounding, uint32_t * quant, uint32_t * fcode, uint32_t * intra_dc_threshold) { uint32_t vol_ver_id; uint32_t time_inc_resolution; uint32_t coding_type; uint32_t start_code; do { BitstreamByteAlign(bs); start_code = BitstreamShowBits(bs, 32); if (start_code == VISOBJSEQ_START_CODE) { // DEBUG("visual_object_sequence"); BitstreamSkip(bs, 32); // visual_object_sequence_start_code BitstreamSkip(bs, 8); // profile_and_level_indication } else if (start_code == VISOBJSEQ_STOP_CODE) { BitstreamSkip(bs, 32); // visual_object_sequence_stop_code } else if (start_code == VISOBJ_START_CODE) { // DEBUG("visual_object"); BitstreamSkip(bs,32); // visual_object_start_code if (BitstreamGetBit(bs)) // is_visual_object_identified { vol_ver_id = BitstreamGetBits(bs,4); // visual_object_ver_id BitstreamSkip(bs, 3); // visual_object_priority } else { vol_ver_id = 1; } if (BitstreamShowBits(bs, 4) != VISOBJ_TYPE_VIDEO) // visual_object_type { DEBUG("visual_object_type != video"); return -1; } BitstreamSkip(bs, 4); // video_signal_type if (BitstreamGetBit(bs)) // video_signal_type { DEBUG("+ video_signal_type"); BitstreamSkip(bs, 3); // video_format BitstreamSkip(bs, 1); // video_range if (BitstreamGetBit(bs)) // color_description { DEBUG("+ color_description"); BitstreamSkip(bs, 8); // color_primaries BitstreamSkip(bs, 8); // transfer_characteristics BitstreamSkip(bs, 8); // matrix_coefficients } } } else if ((start_code & ~0x1f) == VIDOBJ_START_CODE) { BitstreamSkip(bs, 32); // video_object_start_code } else if ((start_code & ~0xf) == VIDOBJLAY_START_CODE) { // DEBUG("video_object_layer"); BitstreamSkip(bs, 32); // video_object_layer_start_code BitstreamSkip(bs, 1); // random_accessible_vol // video_object_type_indication if (BitstreamShowBits(bs, 8) != VIDOBJLAY_TYPE_SIMPLE && BitstreamShowBits(bs, 8) != VIDOBJLAY_TYPE_CORE && BitstreamShowBits(bs, 8) != VIDOBJLAY_TYPE_MAIN && BitstreamShowBits(bs, 8) != 0) // BUGGY DIVX { DEBUG1("video_object_type_indication not supported", BitstreamShowBits(bs, 8)); return -1; } BitstreamSkip(bs, 8); if (BitstreamGetBit(bs)) // is_object_layer_identifier { DEBUG("+ is_object_layer_identifier"); vol_ver_id = BitstreamGetBits(bs,4); // video_object_layer_verid BitstreamSkip(bs, 3); // video_object_layer_priority } else { vol_ver_id = 1; } //DEBUGI("vol_ver_id", vol_ver_id); if (BitstreamGetBits(bs, 4) == VIDOBJLAY_AR_EXTPAR) // aspect_ratio_info { DEBUG("+ aspect_ratio_info"); BitstreamSkip(bs, 8); // par_width BitstreamSkip(bs, 8); // par_height } if (BitstreamGetBit(bs)) // vol_control_parameters { DEBUG("+ vol_control_parameters"); BitstreamSkip(bs, 2); // chroma_format BitstreamSkip(bs, 1); // low_delay if (BitstreamGetBit(bs)) // vbv_parameters { DEBUG("+ vbv_parameters"); BitstreamSkip(bs, 15); // first_half_bitrate READ_MARKER(); BitstreamSkip(bs, 15); // latter_half_bitrate READ_MARKER(); BitstreamSkip(bs, 15); // first_half_vbv_buffer_size READ_MARKER(); BitstreamSkip(bs, 3); // latter_half_vbv_buffer_size BitstreamSkip(bs, 11); // first_half_vbv_occupancy READ_MARKER(); BitstreamSkip(bs, 15); // latter_half_vbv_occupancy READ_MARKER(); } } dec->shape = BitstreamGetBits(bs, 2); // video_object_layer_shape // DEBUG1("shape", dec->shape); if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE && vol_ver_id != 1) { BitstreamSkip(bs, 4); // video_object_layer_shape_extension } READ_MARKER(); time_inc_resolution = BitstreamGetBits(bs, 16); // vop_time_increment_resolution time_inc_resolution--; if (time_inc_resolution > 0) { dec->time_inc_bits = log2bin(time_inc_resolution); } else { // dec->time_inc_bits = 0; // for "old" xvid compatibility, set time_inc_bits = 1 dec->time_inc_bits = 1; } READ_MARKER(); if (BitstreamGetBit(bs)) // fixed_vop_rate { BitstreamSkip(bs, dec->time_inc_bits); // fixed_vop_time_increment } if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) { if (dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR) { uint32_t width, height; READ_MARKER(); width = BitstreamGetBits(bs, 13); // video_object_layer_width //DEBUGI("width", width); READ_MARKER(); height = BitstreamGetBits(bs, 13); // video_object_layer_height //DEBUGI("height", height); READ_MARKER(); if (width != dec->width || height != dec->height) { DEBUG("FATAL: video dimension discrepancy ***"); DEBUG2("bitstream width/height", width, height); DEBUG2("param width/height", dec->width, dec->height); return -1; } } if ((dec->interlacing = BitstreamGetBit(bs))) { DEBUG("vol: interlacing"); } if (!BitstreamGetBit(bs)) // obmc_disable { DEBUG("IGNORED/TODO: !obmc_disable"); // TODO // fucking divx4.02 has this enabled } if (BitstreamGetBits(bs, (vol_ver_id == 1 ? 1 : 2))) // sprite_enable { DEBUG("sprite_enable; not supported"); return -1; } if (vol_ver_id != 1 && dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) { BitstreamSkip(bs, 1); // sadct_disable } if (BitstreamGetBit(bs)) // not_8_bit { DEBUG("+ not_8_bit [IGNORED/TODO]"); dec->quant_bits = BitstreamGetBits(bs, 4); // quant_precision BitstreamSkip(bs, 4); // bits_per_pixel } else { dec->quant_bits = 5; } if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE) { BitstreamSkip(bs, 1); // no_gray_quant_update BitstreamSkip(bs, 1); // composition_method BitstreamSkip(bs, 1); // linear_composition } dec->quant_type = BitstreamGetBit(bs); // quant_type // DEBUG1("**** quant_type", dec->quant_type); if (dec->quant_type) { if (BitstreamGetBit(bs)) // load_intra_quant_mat { uint8_t matrix[64]; bs_get_matrix(bs, matrix); set_intra_matrix(matrix); } else set_intra_matrix(get_default_intra_matrix()); if (BitstreamGetBit(bs)) // load_inter_quant_mat { uint8_t matrix[64]; bs_get_matrix(bs, matrix); set_inter_matrix(matrix); } else set_inter_matrix(get_default_inter_matrix()); if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE) { // TODO DEBUG("TODO: grayscale matrix stuff"); return -1; } } if (vol_ver_id != 1) { dec->quarterpel = BitstreamGetBit(bs); // quarter_sampe if (dec->quarterpel) { DEBUG("IGNORED/TODO: quarter_sample"); } } else { dec->quarterpel = 0; } if (!BitstreamGetBit(bs)) // complexity_estimation_disable { DEBUG("TODO: complexity_estimation header"); // TODO return -1; } if (!BitstreamGetBit(bs)) // resync_marker_disable { DEBUG("IGNORED/TODO: !resync_marker_disable"); // TODO } if (BitstreamGetBit(bs)) // data_partitioned { DEBUG("+ data_partitioned"); BitstreamSkip(bs, 1); // reversible_vlc } if (vol_ver_id != 1) { if (BitstreamGetBit(bs)) // newpred_enable { DEBUG("+ newpred_enable"); BitstreamSkip(bs, 2); // requested_upstream_message_type BitstreamSkip(bs, 1); // newpred_segment_type } if (BitstreamGetBit(bs)) // reduced_resolution_vop_enable { DEBUG("TODO: reduced_resolution_vop_enable"); // TODO return -1; } } if (BitstreamGetBit(bs)) // scalability { // TODO DEBUG("TODO: scalability"); return -1; } } else // dec->shape == BINARY_ONLY { if (vol_ver_id != 1) { if (BitstreamGetBit(bs)) // scalability { // TODO DEBUG("TODO: scalability"); return -1; } } BitstreamSkip(bs, 1); // resync_marker_disable } } else if (start_code == GRPOFVOP_START_CODE) { // DEBUG("group_of_vop"); BitstreamSkip(bs, 32); { int hours, minutes, seconds; hours = BitstreamGetBits(bs, 5); minutes = BitstreamGetBits(bs, 6); READ_MARKER(); seconds = BitstreamGetBits(bs, 6); // DEBUG3("hms", hours, minutes, seconds); } BitstreamSkip(bs, 1); // closed_gov BitstreamSkip(bs, 1); // broken_link } else if (start_code == VOP_START_CODE) { // DEBUG("vop_start_code"); BitstreamSkip(bs, 32); // vop_start_code coding_type = BitstreamGetBits(bs, 2); // vop_coding_type //DEBUG1("coding_type", coding_type); while (BitstreamGetBit(bs) != 0) ; // time_base READ_MARKER(); //DEBUG1("time_inc_bits", dec->time_inc_bits); //DEBUG1("vop_time_incr", BitstreamShowBits(bs, dec->time_inc_bits)); if (dec->time_inc_bits) { BitstreamSkip(bs, dec->time_inc_bits); // vop_time_increment } READ_MARKER(); if (!BitstreamGetBit(bs)) // vop_coded { return N_VOP; } /* if (newpred_enable) { } */ if (coding_type != I_VOP) { *rounding = BitstreamGetBit(bs); // rounding_type //DEBUG1("rounding", *rounding); } /* if (reduced_resolution_enable) { } */ if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) { uint32_t width, height; uint32_t horiz_mc_ref, vert_mc_ref; width = BitstreamGetBits(bs, 13); READ_MARKER(); height = BitstreamGetBits(bs, 13); READ_MARKER(); horiz_mc_ref = BitstreamGetBits(bs, 13); READ_MARKER(); vert_mc_ref = BitstreamGetBits(bs, 13); READ_MARKER(); // DEBUG2("vop_width/height", width, height); // DEBUG2("ref ", horiz_mc_ref, vert_mc_ref); BitstreamSkip(bs, 1); // change_conv_ratio_disable if (BitstreamGetBit(bs)) // vop_constant_alpha { BitstreamSkip(bs, 8); // vop_constant_alpha_value } } if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) { // intra_dc_vlc_threshold *intra_dc_threshold = intra_dc_threshold_table[ BitstreamGetBits(bs,3) ]; if (dec->interlacing) { if ((dec->top_field_first = BitstreamGetBit(bs))) { DEBUG("vop: top_field_first"); } if ((dec->alternate_vertical_scan = BitstreamGetBit(bs))) { DEBUG("vop: alternate_vertical_scan"); } } } *quant = BitstreamGetBits(bs, dec->quant_bits); // vop_quant //DEBUG1("quant", *quant); if (coding_type != I_VOP) { *fcode = BitstreamGetBits(bs, 3); // fcode_forward } if (coding_type == B_VOP) { // *fcode_backward = BitstreamGetBits(bs, 3); // fcode_backward } return coding_type; } else if (start_code == USERDATA_START_CODE) { // DEBUG("user_data"); BitstreamSkip(bs, 32); // user_data_start_code } else // start_code == ? { if (BitstreamShowBits(bs, 24) == 0x000001) { DEBUG1("*** WARNING: unknown start_code", BitstreamShowBits(bs, 32)); } BitstreamSkip(bs, 8); } } while ((BitstreamPos(bs) >> 3) < bs->length); DEBUG("*** WARNING: no vop_start_code found"); return -1; /* ignore it */ } /* write custom quant matrix */ static void bs_put_matrix(Bitstream * bs, const int16_t *matrix) { int i, j; const int last = matrix[scan_tables[0][63]]; for (j = 63; j >= 0 && matrix[scan_tables[0][j - 1]] == last; j--) ; for (i = 0; i <= j; i++) { BitstreamPutBits(bs, matrix[scan_tables[0][i]], 8); } if (j < 63) { BitstreamPutBits(bs, 0, 8); } } /* write vol header */ void BitstreamWriteVolHeader(Bitstream * const bs, const MBParam * pParam) { // video object_start_code & vo_id BitstreamPad(bs); BitstreamPutBits(bs, VO_START_CODE, 27); BitstreamPutBits(bs, 0, 5); // video_object_layer_start_code & vol_id BitstreamPutBits(bs, VOL_START_CODE, 28); BitstreamPutBits(bs, 0, 4); BitstreamPutBit(bs, 0); // random_accessible_vol BitstreamPutBits(bs, 0, 8); // video_object_type_indication BitstreamPutBit(bs, 0); // is_object_layer_identified (0=not given) BitstreamPutBits(bs, 1, 4); // aspect_ratio_info (1=1:1) BitstreamPutBit(bs, 0); // vol_control_parameters (0=not given) BitstreamPutBits(bs, 0, 2); // video_object_layer_shape (0=rectangular) WRITE_MARKER(); /* time_increment_resolution; ignored by current decore versions eg. 2fps res=2 inc=1 25fps res=25 inc=1 29.97fps res=30000 inc=1001 */ BitstreamPutBits(bs, 2, 16); WRITE_MARKER(); // fixed_vop_rate BitstreamPutBit(bs, 0); // fixed_time_increment: value=nth_of_sec, nbits = log2(resolution) // BitstreamPutBits(bs, 0, 15); WRITE_MARKER(); BitstreamPutBits(bs, pParam->width, 13); // width WRITE_MARKER(); BitstreamPutBits(bs, pParam->height, 13); // height WRITE_MARKER(); BitstreamPutBit(bs, pParam->global_flags & XVID_INTERLACING); // interlace BitstreamPutBit(bs, 1); // obmc_disable (overlapped block motion compensation) BitstreamPutBit(bs, 0); // sprite_enable BitstreamPutBit(bs, 0); // not_in_bit // quant_type 0=h.263 1=mpeg4(quantizer tables) BitstreamPutBit(bs, pParam->quant_type); if (pParam->quant_type) { BitstreamPutBit(bs, get_intra_matrix_status()); // load_intra_quant_mat if (get_intra_matrix_status()) { bs_put_matrix(bs, get_intra_matrix()); } BitstreamPutBit(bs, get_inter_matrix_status()); // load_inter_quant_mat if (get_inter_matrix_status()) { bs_put_matrix(bs, get_inter_matrix()); } } BitstreamPutBit(bs, 1); // complexity_estimation_disable BitstreamPutBit(bs, 1); // resync_marker_disable BitstreamPutBit(bs, 0); // data_partitioned BitstreamPutBit(bs, 0); // scalability } /* write vop header NOTE: doesnt handle bother with time_base & time_inc time_base = n seconds since last resync (eg. last iframe) time_inc = nth of a second since last resync (decoder uses these values to determine precise time since last resync) */ void BitstreamWriteVopHeader(Bitstream * const bs, const MBParam * pParam) { BitstreamPad(bs); BitstreamPutBits(bs, VOP_START_CODE, 32); BitstreamPutBits(bs, pParam->coding_type, 2); // time_base = 0 write n x PutBit(1), PutBit(0) BitstreamPutBits(bs, 0, 1); WRITE_MARKER(); // time_increment: value=nth_of_sec, nbits = log2(resolution) BitstreamPutBits(bs, 1, 1); WRITE_MARKER(); BitstreamPutBits(bs, 1, 1); // vop_coded if (pParam->coding_type != I_VOP) BitstreamPutBits(bs, pParam->rounding_type, 1); BitstreamPutBits(bs, 0, 3); // intra_dc_vlc_threshold if (pParam->global_flags & XVID_INTERLACING) { BitstreamPutBit(bs, 1); // top field first BitstreamPutBit(bs, 0); // alternate vertical scan } BitstreamPutBits(bs, pParam->quant, 5); // quantizer if (pParam->coding_type != I_VOP) BitstreamPutBits(bs, pParam->fixed_code, 3); // fixed_code = [1,4] } xvid_20020412/xvidcore/src/bitstream/bitstream.h0100644000100600001440000002270707453333544021107 0ustar michaelusers /****************************************************************************** * * * This file is part of XviD, a free MPEG-4 video encoder/decoder * * * * XviD is an implementation of a part of one or more MPEG-4 Video tools * * as specified in ISO/IEC 14496-2 standard. Those intending to use this * * software module in hardware or software products are advised that its * * use may infringe existing patents or copyrights, and any such use * * would be at such party's own risk. The original developer of this * * software module and his/her company, and subsequent editors and their * * companies, will have no liability for use of this software or * * modifications or derivatives thereof. * * * * XviD is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * XviD is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * ******************************************************************************/ /****************************************************************************** * * * bitstream.h * * * * Copyright (C) 2001 - Peter Ross * * * * For more information visit the XviD homepage: http://www.xvid.org * * * ******************************************************************************/ /****************************************************************************** * * * Revision history: * * * * 26.03.2002 interlacing support - modified putvol/vopheaders paramters * 04.03.2002 putbits speedup (Isibaar) * * 03.03.2002 merged BITREADER and BITWRITER (Isibaar) * * 16.12.2001 inital version * * * ******************************************************************************/ #ifndef _BITSTREAM_H_ #define _BITSTREAM_H_ #include "../portab.h" #include "../decoder.h" #include "../encoder.h" // comment any #defs we dont use #define VIDOBJ_START_CODE 0x00000100 /* ..0x0000011f */ #define VIDOBJLAY_START_CODE 0x00000120 /* ..0x0000012f */ #define VISOBJSEQ_START_CODE 0x000001b0 #define VISOBJSEQ_STOP_CODE 0x000001b1 /* ??? */ #define USERDATA_START_CODE 0x000001b2 #define GRPOFVOP_START_CODE 0x000001b3 //#define VIDSESERR_ERROR_CODE 0x000001b4 #define VISOBJ_START_CODE 0x000001b5 //#define SLICE_START_CODE 0x000001b7 //#define EXT_START_CODE 0x000001b8 #define VISOBJ_TYPE_VIDEO 1 //#define VISOBJ_TYPE_STILLTEXTURE 2 //#define VISOBJ_TYPE_MESH 3 //#define VISOBJ_TYPE_FBA 4 //#define VISOBJ_TYPE_3DMESH 5 #define VIDOBJLAY_TYPE_SIMPLE 1 //#define VIDOBJLAY_TYPE_SIMPLE_SCALABLE 2 #define VIDOBJLAY_TYPE_CORE 3 #define VIDOBJLAY_TYPE_MAIN 4 //#define VIDOBJLAY_AR_SQUARE 1 //#define VIDOBJLAY_AR_625TYPE_43 2 //#define VIDOBJLAY_AR_525TYPE_43 3 //#define VIDOBJLAY_AR_625TYPE_169 8 //#define VIDOBJLAY_AR_525TYPE_169 9 #define VIDOBJLAY_AR_EXTPAR 15 #define VIDOBJLAY_SHAPE_RECTANGULAR 0 #define VIDOBJLAY_SHAPE_BINARY 1 #define VIDOBJLAY_SHAPE_BINARY_ONLY 2 #define VIDOBJLAY_SHAPE_GRAYSCALE 3 #define VO_START_CODE 0x8 #define VOL_START_CODE 0x12 #define VOP_START_CODE 0x1b6 #define READ_MARKER() BitstreamSkip(bs, 1) #define WRITE_MARKER() BitstreamPutBit(bs, 1) // vop coding types // intra, prediction, backward, sprite, not_coded #define I_VOP 0 #define P_VOP 1 #define B_VOP 2 #define S_VOP 3 #define N_VOP 4 // header stuff int BitstreamReadHeaders(Bitstream * bs, DECODER * dec, uint32_t * rounding, uint32_t * quant, uint32_t * fcode, uint32_t * intra_dc_threshold); void BitstreamWriteVolHeader(Bitstream * const bs, const MBParam * pParam); void BitstreamWriteVopHeader(Bitstream * const bs, const MBParam * pParam); /* initialise bitstream structure */ static void __inline BitstreamInit(Bitstream * const bs, void * const bitstream, uint32_t length) { uint32_t tmp; bs->start = bs->tail = (uint32_t*)bitstream; tmp = *(uint32_t *)bitstream; #ifndef ARCH_IS_BIG_ENDIAN BSWAP(tmp); #endif bs->bufa = tmp; tmp = *((uint32_t *)bitstream + 1); #ifndef ARCH_IS_BIG_ENDIAN BSWAP(tmp); #endif bs->bufb = tmp; bs->buf = 0; bs->pos = 0; bs->length = length; } /* reset bitstream state */ static void __inline BitstreamReset(Bitstream * const bs) { uint32_t tmp; bs->tail = bs->start; tmp = *bs->start; #ifndef ARCH_IS_BIG_ENDIAN BSWAP(tmp); #endif bs->bufa = tmp; tmp = *(bs->start + 1); #ifndef ARCH_IS_BIG_ENDIAN BSWAP(tmp); #endif bs->bufb = tmp; bs->buf = 0; bs->pos = 0; } /* reads n bits from bitstream without changing the stream pos */ static uint32_t __inline BitstreamShowBits(Bitstream * const bs, const uint32_t bits) { int nbit = (bits + bs->pos) - 32; if (nbit > 0) { return ((bs->bufa & (0xffffffff >> bs->pos)) << nbit) | (bs->bufb >> (32 - nbit)); } else { return (bs->bufa & (0xffffffff >> bs->pos)) >> (32 - bs->pos - bits); } } /* skip n bits forward in bitstream */ static __inline void BitstreamSkip(Bitstream * const bs, const uint32_t bits) { bs->pos += bits; if (bs->pos >= 32) { uint32_t tmp; bs->bufa = bs->bufb; tmp = *((uint32_t *)bs->tail + 2); #ifndef ARCH_IS_BIG_ENDIAN BSWAP(tmp); #endif bs->bufb = tmp; bs->tail++; bs->pos -= 32; } } /* move forward to the next byte boundary */ static __inline void BitstreamByteAlign(Bitstream * const bs) { uint32_t remainder = bs->pos % 8; if (remainder) { BitstreamSkip(bs, 8 - remainder); } } /* bitstream length (unit bits) */ static uint32_t __inline BitstreamPos(const Bitstream * const bs) { return 8 * ((uint32_t)bs->tail - (uint32_t)bs->start) + bs->pos; } /* flush the bitstream & return length (unit bytes) NOTE: assumes no futher bitstream functions will be called. */ static uint32_t __inline BitstreamLength(Bitstream * const bs) { uint32_t len = (uint32_t) bs->tail - (uint32_t) bs->start; if (bs->pos) { uint32_t b = bs->buf; #ifndef ARCH_IS_BIG_ENDIAN BSWAP(b); #endif *bs->tail = b; len += (bs->pos + 7) / 8; } return len; } /* move bitstream position forward by n bits and write out buffer if needed */ static void __inline BitstreamForward(Bitstream * const bs, const uint32_t bits) { bs->pos += bits; if (bs->pos >= 32) { uint32_t b = bs->buf; #ifndef ARCH_IS_BIG_ENDIAN BSWAP(b); #endif *bs->tail++ = b; bs->buf = 0; bs->pos -= 32; } } /* pad bitstream to the next byte boundary */ static void __inline BitstreamPad(Bitstream * const bs) { uint32_t remainder = bs->pos % 8; if (remainder) { BitstreamForward(bs, 8 - remainder); } } /* read n bits from bitstream */ static uint32_t __inline BitstreamGetBits(Bitstream * const bs, const uint32_t n) { uint32_t ret = BitstreamShowBits(bs, n); BitstreamSkip(bs, n); return ret; } /* read single bit from bitstream */ static uint32_t __inline BitstreamGetBit(Bitstream * const bs) { return BitstreamGetBits(bs, 1); } /* write single bit to bitstream */ static void __inline BitstreamPutBit(Bitstream * const bs, const uint32_t bit) { if (bit) bs->buf |= (0x80000000 >> bs->pos); BitstreamForward(bs, 1); } /* write n bits to bitstream */ static void __inline BitstreamPutBits(Bitstream * const bs, const uint32_t value, const uint32_t size) { uint32_t shift = 32 - bs->pos - size; if (shift <= 32) { bs->buf |= value << shift; BitstreamForward(bs, size); } else { uint32_t remainder; shift = size - (32 - bs->pos); bs->buf |= value >> shift; BitstreamForward(bs, size - shift); remainder = shift; shift = 32 - shift; bs->buf |= value << shift; BitstreamForward(bs, remainder); } } #endif /* _BITSTREAM_H_ */ xvid_20020412/xvidcore/src/bitstream/ppc_asm/0040755000100600001440000000000007455522444020362 5ustar michaelusersxvid_20020412/xvidcore/src/bitstream/ppc_asm/CVS/0040755000100600001440000000000007455522444021015 5ustar michaelusersxvid_20020412/xvidcore/src/bitstream/ppc_asm/CVS/Root0100644000100600001440000000004607455522444021660 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/bitstream/ppc_asm/CVS/Repository0100644000100600001440000000003707455522444023114 0ustar michaelusersxvidcore/src/bitstream/ppc_asm xvid_20020412/xvidcore/src/bitstream/ppc_asm/CVS/Entries0100644000100600001440000000013207455522444022342 0ustar michaelusers/cbp_altivec.s/1.2/Thu Mar 28 12:29:58 2002// /cbp_ppc.s/1.9/Thu Mar 28 12:29:58 2002// D xvid_20020412/xvidcore/src/bitstream/ppc_asm/cbp_ppc.s0100644000100600001440000000443707450606306022154 0ustar michaelusers# Copyright (C) 2002 Guillaume Morin , Alcve # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # $Id: cbp_ppc.s,v 1.9 2002/03/28 12:29:58 canard Exp $ # $Source: /xvid/xvidcore/src/bitstream/ppc_asm/cbp_ppc.s,v $ # $Date: 2002/03/28 12:29:58 $ # $Author: canard $ # # This is my first PPC ASM attempt. So I might do nasty things. # Please send any comments to # Returns a field of bits that indicates non zero ac blocks # for this macro block # # uint32_t calc_cbp_c(const int16_t codes[6][64]) #{ # uint32_t i, j; # uint32_t cbp = 0; # # for (i = 0; i < 6; i++) { # for (j = 1; j < 61; j+=4) { # if (codes[i][j] |codes[i][j+1]| # codes[i][j+2]|codes[i][j+3]) { # cbp |= 1 << (5 - i); # break; # } # } # # if(codes[i][j]|codes[i][j+1]|codes[i][j+2]) # cbp |= 1 << (5 - i); # # } # # return cbp; # #} .data .skip: .word 0,-1 .align 4 .text .global calc_cbp_ppc calc_cbp_ppc: # r9 will contain coeffs addr mr %r9,%r3 # r8 is the loop counter (rows) li %r8,5 # r3 contains the result, therefore we set it to 0 li %r3,0 .loop: # CTR is the loop2 counter li %r4,16 mtctr %r4 # r6 is coeff pointer for this line mr %r6,%r9 lis %r7,.skip@ha addi %r7,%r7,.skip@l lwz %r7,0(%r7) .loop2: # coeffs is a matrix of 16 bits cells lwz %r4,0(%r6) and %r4,%r4,%r7 li %r7,-1 lwz %r5,4(%r6) # or. updates CR0 or. %r4,%r5,%r4 # testing bit 2 (is zero) of CR0 bf 2,.cbp addi %r6,%r6,8 bdnz .loop2 b .newline .cbp: li %r4,1 slw %r4,%r4,%r8 or %r3,%r3,%r4 .newline: addi %r9,%r9,128 # updates CR0, blabla subic. %r8,%r8,1 bf 0,.loop blr xvid_20020412/xvidcore/src/bitstream/ppc_asm/cbp_altivec.s0100644000100600001440000000505407450606306023015 0ustar michaelusers# Copyright (C) 2002 Guillaume Morin , Alcve # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # $Id: cbp_altivec.s,v 1.2 2002/03/28 12:29:58 canard Exp $ # $Source: /xvid/xvidcore/src/bitstream/ppc_asm/cbp_altivec.s,v $ # $Date: 2002/03/28 12:29:58 $ # $Author: canard $ # # This is my first PPC ASM attempt. So I might do nasty things. # Please send any comments to # Returns a field of bits that indicates non zero ac blocks # for this macro block # # uint32_t calc_cbp_c(const int16_t codes[6][64]) #{ # uint32_t i, j; # uint32_t cbp = 0; # # for (i = 0; i < 6; i++) { # for (j = 1; j < 61; j+=4) { # if (codes[i][j] |codes[i][j+1]| # codes[i][j+2]|codes[i][j+3]) { # cbp |= 1 << (5 - i); # break; # } # } # # if(codes[i][j]|codes[i][j+1]|codes[i][j+2]) # cbp |= 1 << (5 - i); # # } # # return cbp; # #} .data .skip: .quad 0x0000FFFFFFFFFFFF,-1 .align 4 .text .global calc_cbp_altivec calc_cbp_altivec: # Set VRSAVE li %r4,0xFFFFFFFF mtspr 256,%r4 # r9 will contain coeffs addr mr %r9,%r3 # r3 contains the result, therefore we set it to 0 li %r3,0 # CTR is the loop counter (rows) li %r4,6 mtctr %r4 # VR9 contains 0 vxor 9,9,9 # VR10 will help us to remove the first 16 bits of each row lis %r4,.skip@ha addi %r4,4,.skip@l lvx 10,0,%r4 .loop: mr %r6,%r9 lvxl 1,0,%r6 # Set the first 16 bits to 0 vand 1,1,10 addi %r6,%r6,16 lvxl 2,0,6 addi %r6,%r6,16 lvxl 3,0,6 addi %r6,%r6,16 lvxl 4,0,6 addi %r6,%r6,16 lvxl 5,0,6 addi %r6,%r6,16 lvxl 6,0,6 addi %r6,%r6,16 lvxl 7,0,6 addi %r6,%r6,16 lvxl 8,0,6 vor 1,2,1 vor 1,3,1 vor 1,4,1 vor 1,5,1 vor 1,6,1 vor 1,7,1 vor 1,8,1 # is VR1 == 0 vcmpequw. 3,1,9 bt 24,.newline .cbp: # cbp calc mfctr %r5 subi %r5,%r5,1 li %r4,1 slw %r4,%r4,%r5 or %r3,%r3,%r4 .newline: addi %r9,%r9,128 bdnz .loop blr xvid_20020412/xvidcore/src/image/0040755000100600001440000000000007455522446016032 5ustar michaelusersxvid_20020412/xvidcore/src/image/CVS/0040755000100600001440000000000007455522446016465 5ustar michaelusersxvid_20020412/xvidcore/src/image/CVS/Root0100644000100600001440000000004607455522446017330 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/image/CVS/Repository0100644000100600001440000000002307455522446020557 0ustar michaelusersxvidcore/src/image xvid_20020412/xvidcore/src/image/CVS/Entries.Log0100644000100600001440000000002007455522446020526 0ustar michaelusersA D/x86_asm//// xvid_20020412/xvidcore/src/image/CVS/Entries0100644000100600001440000000043607455522446020021 0ustar michaelusers/colorspace.c/1.1.1.1/Fri Mar 8 02:44:45 2002// /colorspace.h/1.1.1.1/Fri Mar 8 02:44:45 2002// /image.c/1.9/Thu Apr 11 23:31:20 2002// /image.h/1.3/Tue Apr 9 13:35:40 2002// /interpolate8x8.c/1.1.1.1/Fri Mar 8 02:44:46 2002// /interpolate8x8.h/1.1.1.1/Fri Mar 8 02:44:46 2002// D xvid_20020412/xvidcore/src/image/colorspace.c0100644000100600001440000006252407442022635020325 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * colorspace conversions * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 30.02.2002 out_yuv dst_stride2 fix * 26.02.2002 rgb555, rgb565 * 24.11.2001 accuracy improvement to yuyv/vyuy conversion * 28.10.2001 total rewrite * **************************************************************************/ #include // memcpy #include "colorspace.h" // function pointers /* input */ color_inputFuncPtr rgb555_to_yv12; color_inputFuncPtr rgb565_to_yv12; color_inputFuncPtr rgb24_to_yv12; color_inputFuncPtr rgb32_to_yv12; color_inputFuncPtr yuv_to_yv12; color_inputFuncPtr yuyv_to_yv12; color_inputFuncPtr uyvy_to_yv12; /* output */ color_outputFuncPtr yv12_to_rgb555; color_outputFuncPtr yv12_to_rgb565; color_outputFuncPtr yv12_to_rgb24; color_outputFuncPtr yv12_to_rgb32; color_outputFuncPtr yv12_to_yuv; color_outputFuncPtr yv12_to_yuyv; color_outputFuncPtr yv12_to_uyvy; #define MIN(A,B) ((A)<(B)?(A):(B)) #define MAX(A,B) ((A)>(B)?(A):(B)) /* rgb -> yuv def's this following constants are "official spec" Video Demystified" (ISBN 1-878707-09-4) rgb<->yuv _is_ lossy, since most programs do the conversion differently SCALEBITS/FIX taken from ffmpeg */ #define Y_R_IN 0.257 #define Y_G_IN 0.504 #define Y_B_IN 0.098 #define Y_ADD_IN 16 #define U_R_IN 0.148 #define U_G_IN 0.291 #define U_B_IN 0.439 #define U_ADD_IN 128 #define V_R_IN 0.439 #define V_G_IN 0.368 #define V_B_IN 0.071 #define V_ADD_IN 128 #define SCALEBITS_IN 8 #define FIX_IN(x) ((uint16_t) ((x) * (1L< yuv 4:2:0 planar */ void rgb555_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, int width, int height, int y_stride) { int32_t src_stride = width * 2; uint32_t y_dif = y_stride - width; uint32_t uv_dif = (y_stride - width) / 2; uint32_t x, y; if (height < 0) { height = -height; src += (height - 1) * src_stride; src_stride = -src_stride; } for (y = height / 2; y; y--) { // process one 2x2 block per iteration for (x = 0; x < (uint32_t)width; x += 2) { int rgb, r, g, b, r4, g4, b4; rgb = *(uint16_t*)(src+x*2); b4 = b = (rgb << 3) & 0xf8; g4 = g = (rgb >> 2) & 0xf8; r4 = r = (rgb >> 7) & 0xf8; y_out[0] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; rgb = *(uint16_t*)(src+x*2+src_stride); b4 += b = (rgb << 3) & 0xf8; g4 += g = (rgb >> 2) & 0xf8; r4 += r = (rgb >> 7) & 0xf8; y_out[y_stride] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; rgb = *(uint16_t*)(src+x*2+2); b4 += b = (rgb << 3) & 0xf8; g4 += g = (rgb >> 2) & 0xf8; r4 += r = (rgb >> 7) & 0xf8; y_out[1] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; rgb = *(uint16_t*)(src+x*2+src_stride+2); b4 += b = (rgb << 3) & 0xf8; g4 += g = (rgb >> 2) & 0xf8; r4 += r = (rgb >> 7) & 0xf8; y_out[y_stride + 1] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; *u_out++ = (uint8_t)(( - FIX_IN(U_R_IN) * r4 - FIX_IN(U_G_IN) * g4 + FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + U_ADD_IN; *v_out++ = (uint8_t)(( FIX_IN(V_R_IN) * r4 - FIX_IN(V_G_IN) * g4 - FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + V_ADD_IN; y_out += 2; } src += src_stride * 2; y_out += y_dif + y_stride; u_out += uv_dif; v_out += uv_dif; } } /* rgb565_to_yuv_c NOTE: identical to rgb555 except for shift/mask not tested */ void rgb565_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, int width, int height, int y_stride) { int32_t src_stride = width * 2; uint32_t y_dif = y_stride - width; uint32_t uv_dif = (y_stride - width) / 2; uint32_t x, y; if (height < 0) { height = -height; src += (height - 1) * src_stride; src_stride = -src_stride; } for (y = height / 2; y; y--) { // process one 2x2 block per iteration for (x = 0; x < (uint32_t)width; x += 2) { int rgb, r, g, b, r4, g4, b4; rgb = *(uint16_t*)(src+x*2); b4 = b = (rgb << 3) & 0xf8; g4 = g = (rgb >> 3) & 0xfc; r4 = r = (rgb >> 8) & 0xf8; y_out[0] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; rgb = *(uint16_t*)(src+x*2+src_stride); b4 += b = (rgb << 3) & 0xf8; g4 += g = (rgb >> 3) & 0xfc; r4 += r = (rgb >> 8) & 0xf8; y_out[y_stride] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; rgb = *(uint16_t*)(src+x*2+2); b4 += b = (rgb << 3) & 0xf8; g4 += g = (rgb >> 3) & 0xfc; r4 += r = (rgb >> 8) & 0xf8; y_out[1] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; rgb = *(uint16_t*)(src+x*2+src_stride+2); b4 += b = (rgb << 3) & 0xf8; g4 += g = (rgb >> 3) & 0xfc; r4 += r = (rgb >> 8) & 0xf8; y_out[y_stride + 1] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; *u_out++ = (uint8_t)(( - FIX_IN(U_R_IN) * r4 - FIX_IN(U_G_IN) * g4 + FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + U_ADD_IN; *v_out++ = (uint8_t)(( FIX_IN(V_R_IN) * r4 - FIX_IN(V_G_IN) * g4 - FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + V_ADD_IN; y_out += 2; } src += src_stride * 2; y_out += y_dif + y_stride; u_out += uv_dif; v_out += uv_dif; } } /* rgb24 -> yuv 4:2:0 planar NOTE: always flips. */ void rgb24_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, int width, int height, int stride) { uint32_t width3 = (width << 1) + width; /* width * 3 */ uint32_t src_dif = (width << 3) + width; /* width3 * 3 */ uint32_t y_dif = (stride << 1) - width; uint32_t uv_dif = (stride - width) >> 1; uint32_t x, y; src += (height - 2) * width3; for(y = height >> 1; y; y--) { for(x = width >> 1; x; x--) { uint32_t r, g, b, r4, g4, b4; b4 = b = src[0]; g4 = g = src[1]; r4 = r = src[2]; y_out[stride + 0] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; b4 += (b = src[3]); g4 += (g = src[4]); r4 += (r = src[5]); y_out[stride + 1] = (uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; b4 += (b = src[width3 + 0]); g4 += (g = src[width3 + 1]); r4 += (r = src[width3 + 2]); y_out[0] = (uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; b4 += (b = src[width3 + 3]); g4 += (g = src[width3 + 4]); r4 += (r = src[width3 + 5]); y_out[1] = (uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; *u_out++ = (uint8_t)(( - FIX_IN(U_R_IN) * r4 - FIX_IN(U_G_IN) * g4 + FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + U_ADD_IN; *v_out++ = (uint8_t)(( FIX_IN(V_R_IN) * r4 - FIX_IN(V_G_IN) * g4 - FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + V_ADD_IN; src += 6; y_out += 2; } src -= src_dif; y_out += y_dif; u_out += uv_dif; v_out += uv_dif; } } /* rgb32 -> yuv 4:2:0 planar NOTE: always flips */ void rgb32_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, int width, int height, int stride) { uint32_t width4 = (width << 2); /* width * 4 */ uint32_t src_dif = 3 * width4; uint32_t y_dif = (stride << 1) - width; uint32_t uv_dif = (stride - width) >> 1; uint32_t x, y; src += (height - 2) * width4; for(y = height >> 1; y; y--) { for(x = width >> 1; x; x--) { uint32_t r, g, b, r4, g4, b4; b4 = b = src[0]; g4 = g = src[1]; r4 = r = src[2]; y_out[stride + 0] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; b4 += (b = src[4]); g4 += (g = src[5]); r4 += (r = src[6]); y_out[stride + 1] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; b4 += (b = src[width4 + 0]); g4 += (g = src[width4 + 1]); r4 += (r = src[width4 + 2]); y_out[0] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; b4 += (b = src[width4 + 4]); g4 += (g = src[width4 + 5]); r4 += (r = src[width4 + 6]); y_out[1] =(uint8_t)(( FIX_IN(Y_R_IN) * r + FIX_IN(Y_G_IN) * g + FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN; *u_out++ = (uint8_t)(( - FIX_IN(U_R_IN) * r4 - FIX_IN(U_G_IN) * g4 + FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + U_ADD_IN; *v_out++ = (uint8_t)(( FIX_IN(V_R_IN) * r4 - FIX_IN(V_G_IN) * g4 - FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + V_ADD_IN; src += 8; y_out += 2; } src -= src_dif; y_out += y_dif; u_out += uv_dif; v_out += uv_dif; } } /* yuv planar -> yuv 4:2:0 planar NOTE: does not flip */ void yuv_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, int width, int height, int stride) { uint32_t stride2 = stride >> 1; uint32_t width2 = width >> 1; uint32_t y; for (y = height; y; y--) { memcpy(y_out, src, width); src += width; y_out += stride; } for (y = height >> 1; y; y--) { memcpy(u_out, src, width2); src += width2; u_out += stride2; } for (y = height >> 1; y; y--) { memcpy(v_out, src, width2); src += width2; v_out+= stride2; } } /* yuyv (yuv2) packed -> yuv 4:2:0 planar NOTE: does not flip */ void yuyv_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, int width, int height, int stride) { uint32_t width2 = width + width; uint32_t y_dif = stride - width; uint32_t uv_dif = y_dif >> 1; uint32_t x, y; for (y = height >> 1; y; y--) { for (x = width >> 1; x; x--) { *y_out++ = *src++; //*u_out++ = *src++; *u_out++ = (*(src+width2) + *src) >> 1; src++; *y_out++ = *src++; //*v_out++ = *src++; *v_out++ = (*(src+width2) + *src) >> 1; src++; } y_out += y_dif; u_out += uv_dif; v_out += uv_dif; for (x = width >> 1; x; x--) { *y_out++ = *src++; src++; *y_out++ = *src++; src++; } y_out += y_dif; } } /* uyvy packed -> yuv 4:2:0 planar NOTE: does not flip */ void uyvy_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, int width, int height, int stride) { uint32_t width2 = width + width; uint32_t y_dif = stride - width; uint32_t uv_dif = y_dif >> 1; uint32_t x, y; for (y = height >> 1; y; y--) { for (x = width >> 1; x; x--) { *u_out++ = *src++; // *u_out++ = (*(src+width2) + *src++) >> 1; *y_out++ = *src++; //*v_out++ = *src++; *v_out++ = (*(src+width2) + *src) >> 1; src++; *y_out++ = *src++; } y_out += y_dif; u_out += uv_dif;; v_out += uv_dif;; for (x = width >> 1; x; x--) { src++; *y_out++ = *src++; src++; *y_out++ = *src++; } y_out += y_dif; } } /* yuv -> rgb def's */ #define RGB_Y_OUT 1.164 #define B_U_OUT 2.018 #define Y_ADD_OUT 16 #define G_U_OUT 0.391 #define G_V_OUT 0.813 #define U_ADD_OUT 128 #define R_V_OUT 1.596 #define V_ADD_OUT 128 #define SCALEBITS_OUT 13 #define FIX_OUT(x) ((uint16_t) ((x) * (1L< rgb555 + very simple error diffusion */ #define MK_RGB555(R,G,B) ((MAX(0,MIN(255, R)) << 7) & 0x7c00) | \ ((MAX(0,MIN(255, G)) << 2) & 0x03e0) | \ ((MAX(0,MIN(255, B)) >> 3) & 0x001f) void yv12_to_rgb555_c(uint8_t *dst, int dst_stride, uint8_t *y_src, uint8_t *u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height) { const uint32_t dst_dif = 4 * dst_stride - 2 * width; int32_t y_dif = 2 * y_stride - width; uint8_t *dst2 = dst + 2 * dst_stride; uint8_t *y_src2 = y_src + y_stride; uint32_t x, y; if (height < 0) { height = -height; y_src += (height - 1) * y_stride; y_src2 = y_src - y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_dif = -width - 2 * y_stride; uv_stride = -uv_stride; } for (y = height / 2; y; y--) { int r, g, b; int r2, g2, b2; r = g = b = 0; r2 = g2 = b2 = 0; // process one 2x2 block per iteration for (x = 0; x < (uint32_t)width / 2; x++) { int u, v; int b_u, g_uv, r_v, rgb_y; u = u_src[x]; v = v_src[x]; b_u = B_U_tab[u]; g_uv = G_U_tab[u] + G_V_tab[v]; r_v = R_V_tab[v]; rgb_y = RGB_Y_tab[*y_src]; b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t*)dst = MK_RGB555(r,g,b); y_src++; rgb_y = RGB_Y_tab[*y_src]; b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t*)(dst+2) = MK_RGB555(r,g,b); y_src++; rgb_y = RGB_Y_tab[*y_src2]; b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t*)(dst2) = MK_RGB555(r2,g2,b2); y_src2++; rgb_y = RGB_Y_tab[*y_src2]; b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t*)(dst2+2) = MK_RGB555(r2,g2,b2); y_src2++; dst += 4; dst2 += 4; } dst += dst_dif; dst2 += dst_dif; y_src += y_dif; y_src2 += y_dif; u_src += uv_stride; v_src += uv_stride; } } /* yuv 4:2:0 planar -> rgb565 + very simple error diffusion NOTE: identical to rgb555 except for shift/mask */ #define MK_RGB565(R,G,B) ((MAX(0,MIN(255, R)) << 8) & 0xf800) | \ ((MAX(0,MIN(255, G)) << 3) & 0x07e0) | \ ((MAX(0,MIN(255, B)) >> 3) & 0x001f) void yv12_to_rgb565_c(uint8_t *dst, int dst_stride, uint8_t *y_src, uint8_t *u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height) { const uint32_t dst_dif = 4 * dst_stride - 2 * width; int32_t y_dif = 2 * y_stride - width; uint8_t *dst2 = dst + 2 * dst_stride; uint8_t *y_src2 = y_src + y_stride; uint32_t x, y; if (height < 0) { // flip image? height = -height; y_src += (height - 1) * y_stride; y_src2 = y_src - y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_dif = -width - 2 * y_stride; uv_stride = -uv_stride; } for (y = height / 2; y; y--) { int r, g, b; int r2, g2, b2; r = g = b = 0; r2 = g2 = b2 = 0; // process one 2x2 block per iteration for (x = 0; x < (uint32_t)width / 2; x++) { int u, v; int b_u, g_uv, r_v, rgb_y; u = u_src[x]; v = v_src[x]; b_u = B_U_tab[u]; g_uv = G_U_tab[u] + G_V_tab[v]; r_v = R_V_tab[v]; rgb_y = RGB_Y_tab[*y_src]; b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t*)dst = MK_RGB565(r,g,b); y_src++; rgb_y = RGB_Y_tab[*y_src]; b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t*)(dst+2) = MK_RGB565(r,g,b); y_src++; rgb_y = RGB_Y_tab[*y_src2]; b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t*)(dst2) = MK_RGB565(r2,g2,b2); y_src2++; rgb_y = RGB_Y_tab[*y_src2]; b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t*)(dst2+2) = MK_RGB565(r2,g2,b2); y_src2++; dst += 4; dst2 += 4; } dst += dst_dif; dst2 += dst_dif; y_src += y_dif; y_src2 += y_dif; u_src += uv_stride; v_src += uv_stride; } } /* yuv 4:2:0 planar -> rgb24 */ void yv12_to_rgb24_c(uint8_t *dst, int dst_stride, uint8_t *y_src, uint8_t *u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height) { const uint32_t dst_dif = 6 * dst_stride - 3 * width; int32_t y_dif = 2 * y_stride - width; uint8_t *dst2 = dst + 3 * dst_stride; uint8_t *y_src2 = y_src + y_stride; uint32_t x, y; if (height < 0) { // flip image? height = -height; y_src += (height - 1) * y_stride; y_src2 = y_src - y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_dif = -width - 2 * y_stride; uv_stride = -uv_stride; } for (y = height / 2; y; y--) { // process one 2x2 block per iteration for (x = 0; x < (uint32_t)width / 2; x++) { int u, v; int b_u, g_uv, r_v, rgb_y; int r, g, b; u = u_src[x]; v = v_src[x]; b_u = B_U_tab[u]; g_uv = G_U_tab[u] + G_V_tab[v]; r_v = R_V_tab[v]; rgb_y = RGB_Y_tab[*y_src]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst[0] = MAX(0,MIN(255, b)); dst[1] = MAX(0,MIN(255, g)); dst[2] = MAX(0,MIN(255, r)); y_src++; rgb_y = RGB_Y_tab[*y_src]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst[3] = MAX(0,MIN(255, b)); dst[4] = MAX(0,MIN(255, g)); dst[5] = MAX(0,MIN(255, r)); y_src++; rgb_y = RGB_Y_tab[*y_src2]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst2[0] = MAX(0,MIN(255, b)); dst2[1] = MAX(0,MIN(255, g)); dst2[2] = MAX(0,MIN(255, r)); y_src2++; rgb_y = RGB_Y_tab[*y_src2]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst2[3] = MAX(0,MIN(255, b)); dst2[4] = MAX(0,MIN(255, g)); dst2[5] = MAX(0,MIN(255, r)); y_src2++; dst += 6; dst2 += 6; } dst += dst_dif; dst2 += dst_dif; y_src += y_dif; y_src2 += y_dif; u_src += uv_stride; v_src += uv_stride; } } /* yuv 4:2:0 planar -> rgb32 */ void yv12_to_rgb32_c(uint8_t *dst, int dst_stride, uint8_t *y_src, uint8_t *v_src, uint8_t * u_src, int y_stride, int uv_stride, int width, int height) { const uint32_t dst_dif = 8 * dst_stride - 4 * width; int32_t y_dif = 2 * y_stride - width; uint8_t *dst2 = dst + 4 * dst_stride; uint8_t *y_src2 = y_src + y_stride; uint32_t x, y; if (height < 0) { // flip image? height = -height; y_src += (height - 1) * y_stride; y_src2 = y_src - y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_dif = -width - 2 * y_stride; uv_stride = -uv_stride; } for (y = height / 2; y; y--) { // process one 2x2 block per iteration for (x = 0; x < (uint32_t)width / 2; x++) { int u, v; int b_u, g_uv, r_v, rgb_y; int r, g, b; u = u_src[x]; v = v_src[x]; b_u = B_U_tab[u]; g_uv = G_U_tab[u] + G_V_tab[v]; r_v = R_V_tab[v]; rgb_y = RGB_Y_tab[*y_src]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst[0] = MAX(0,MIN(255, r)); dst[1] = MAX(0,MIN(255, g)); dst[2] = MAX(0,MIN(255, b)); dst[3] = 0; y_src++; rgb_y = RGB_Y_tab[*y_src]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst[4] = MAX(0,MIN(255, r)); dst[5] = MAX(0,MIN(255, g)); dst[6] = MAX(0,MIN(255, b)); dst[7] = 0; y_src++; rgb_y = RGB_Y_tab[*y_src2]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst2[0] = MAX(0,MIN(255, r)); dst2[1] = MAX(0,MIN(255, g)); dst2[2] = MAX(0,MIN(255, b)); dst2[3] = 0; y_src2++; rgb_y = RGB_Y_tab[*y_src2]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst2[4] = MAX(0,MIN(255, r)); dst2[5] = MAX(0,MIN(255, g)); dst2[6] = MAX(0,MIN(255, b)); dst2[7] = 0; y_src2++; dst += 8; dst2 += 8; } dst += dst_dif; dst2 += dst_dif; y_src += y_dif; y_src2 += y_dif; u_src += uv_stride; v_src += uv_stride; } } /* yuv 4:2:0 planar -> yuv planar */ void yv12_to_yuv_c(uint8_t *dst, int dst_stride, uint8_t *y_src, uint8_t *u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height) { uint32_t dst_stride2 = dst_stride >> 1; uint32_t width2 = width >> 1; uint32_t y; if (height < 0) { height = -height; y_src += (height - 1) * y_stride ; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_stride = -y_stride; uv_stride = -uv_stride; } for (y = height; y; y--) { memcpy(dst, y_src, width); dst += dst_stride; y_src += y_stride; } for (y = height >> 1; y; y--) { memcpy(dst, u_src, width2); dst += dst_stride2; u_src += uv_stride; } for (y = height >> 1; y; y--) { memcpy(dst, v_src, width2); dst += dst_stride2; v_src += uv_stride; } } /* yuv 4:2:0 planar -> yuyv (yuv2) packed */ void yv12_to_yuyv_c(uint8_t *dst, int dst_stride, uint8_t *y_src, uint8_t *u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height) { const uint32_t dst_dif = 2*(dst_stride - width); uint32_t x, y; if (height < 0) { height = -height; y_src += (height - 1) * y_stride ; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_stride = -y_stride; uv_stride = -uv_stride; } for (y = 0; y < (uint32_t)height; y++) { for (x = 0; x < (uint32_t)width / 2; x++) { dst[0] = y_src[2*x]; dst[1] = u_src[x]; dst[2] = y_src[2*x + 1]; dst[3] = v_src[x]; dst += 4; } dst += dst_dif; y_src += y_stride; if (y&1) { u_src += uv_stride; v_src += uv_stride; } } } /* yuv 4:2:0 planar -> uyvy packed */ void yv12_to_uyvy_c(uint8_t *dst, int dst_stride, uint8_t *y_src, uint8_t *u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height) { const uint32_t dst_dif = 2*(dst_stride - width); uint32_t x, y; if (height < 0) { height = -height; y_src += (height - 1) * y_stride ; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_stride = -y_stride; uv_stride = -uv_stride; } for (y = 0; y < (uint32_t)height; y++) { for (x = 0; x < (uint32_t)width / 2; x++) { dst[0] = u_src[x]; dst[1] = y_src[2*x]; dst[2] = v_src[x]; dst[3] = y_src[2*x + 1]; dst += 4; } dst += dst_dif; y_src += y_stride; if (y&1) { u_src += uv_stride; v_src += uv_stride; } } } xvid_20020412/xvidcore/src/image/colorspace.h0100644000100600001440000000416007442022635020322 0ustar michaelusers#ifndef _COLORSPACE_H #define _COLORSPACE_H #include "../portab.h" /* initialize tables */ void colorspace_init(void); /* input color conversion functions (encoder) */ typedef void (color_inputFunc)(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, int width, int height, int stride); typedef color_inputFunc *color_inputFuncPtr; extern color_inputFuncPtr rgb555_to_yv12; extern color_inputFuncPtr rgb565_to_yv12; extern color_inputFuncPtr rgb24_to_yv12; extern color_inputFuncPtr rgb32_to_yv12; extern color_inputFuncPtr yuv_to_yv12; extern color_inputFuncPtr yuyv_to_yv12; extern color_inputFuncPtr uyvy_to_yv12; /* plain c */ color_inputFunc rgb555_to_yv12_c; color_inputFunc rgb565_to_yv12_c; color_inputFunc rgb24_to_yv12_c; color_inputFunc rgb32_to_yv12_c; color_inputFunc yuv_to_yv12_c; color_inputFunc yuyv_to_yv12_c; color_inputFunc uyvy_to_yv12_c; /* mmx */ color_inputFunc rgb24_to_yv12_mmx; color_inputFunc rgb32_to_yv12_mmx; color_inputFunc yuv_to_yv12_mmx; color_inputFunc yuyv_to_yv12_mmx; color_inputFunc uyvy_to_yv12_mmx; /* xmm */ color_inputFunc yuv_to_yv12_xmm; /* output color conversion functions (decoder) */ typedef void (color_outputFunc)(uint8_t *dst, int dst_stride, uint8_t *y_src, uint8_t *v_src, uint8_t * u_src, int y_stride, int uv_stride, int width, int height); typedef color_outputFunc* color_outputFuncPtr; extern color_outputFuncPtr yv12_to_rgb555; extern color_outputFuncPtr yv12_to_rgb565; extern color_outputFuncPtr yv12_to_rgb24; extern color_outputFuncPtr yv12_to_rgb32; extern color_outputFuncPtr yv12_to_yuv; extern color_outputFuncPtr yv12_to_yuyv; extern color_outputFuncPtr yv12_to_uyvy; /* plain c */ void init_yuv_to_rgb(void); color_outputFunc yv12_to_rgb555_c; color_outputFunc yv12_to_rgb565_c; color_outputFunc yv12_to_rgb24_c; color_outputFunc yv12_to_rgb32_c; color_outputFunc yv12_to_yuv_c; color_outputFunc yv12_to_yuyv_c; color_outputFunc yv12_to_uyvy_c; /* mmx */ color_outputFunc yv12_to_rgb24_mmx; color_outputFunc yv12_to_rgb32_mmx; color_outputFunc yv12_to_yuyv_mmx; color_outputFunc yv12_to_uyvy_mmx; #endif /* _COLORSPACE_H_ */ xvid_20020412/xvidcore/src/image/interpolate8x8.c0100644000100600001440000000626507442022636021072 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * 8x8 block-based halfpel interpolation * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 27.12.2001 modified "compensate_halfpel" * 05.11.2001 initial version; (c)2001 peter ross * *************************************************************************/ #include "../portab.h" #include "interpolate8x8.h" // function pointers INTERPOLATE8X8_PTR interpolate8x8_halfpel_h; INTERPOLATE8X8_PTR interpolate8x8_halfpel_v; INTERPOLATE8X8_PTR interpolate8x8_halfpel_hv; // dst = interpolate(src) void interpolate8x8_halfpel_h_c(uint8_t * const dst, const uint8_t * const src, const uint32_t stride, const uint32_t rounding) { uint32_t i, j; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { int16_t tot = (int32_t)src[j * stride + i] + (int32_t)src[j * stride + i + 1]; tot = (int32_t)((tot + 1 - rounding) >> 1); dst[j * stride + i] = (uint8_t)tot; } } } void interpolate8x8_halfpel_v_c(uint8_t * const dst, const uint8_t * const src, const uint32_t stride, const uint32_t rounding) { uint32_t i, j; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { int16_t tot = src[j * stride + i] + src[j * stride + i + stride]; tot = ((tot + 1 - rounding) >> 1); dst[j * stride + i] = (uint8_t)tot; } } } void interpolate8x8_halfpel_hv_c(uint8_t * const dst, const uint8_t * const src, const uint32_t stride, const uint32_t rounding) { uint32_t i, j; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { int16_t tot = src[j * stride + i] + src[j * stride + i + 1] + src[j * stride + i + stride] + src[j * stride + i + stride + 1]; tot = ((tot + 2 - rounding) >> 2); dst[j * stride + i] = (uint8_t)tot; } } } xvid_20020412/xvidcore/src/image/interpolate8x8.h0100644000100600001440000000354307442022636021073 0ustar michaelusers#include "../utils/mem_transfer.h" typedef void (INTERPOLATE8X8)(uint8_t * const dst, const uint8_t * const src, const uint32_t stride, const uint32_t rounding); typedef INTERPOLATE8X8 * INTERPOLATE8X8_PTR; extern INTERPOLATE8X8_PTR interpolate8x8_halfpel_h; extern INTERPOLATE8X8_PTR interpolate8x8_halfpel_v; extern INTERPOLATE8X8_PTR interpolate8x8_halfpel_hv; INTERPOLATE8X8 interpolate8x8_halfpel_h_c; INTERPOLATE8X8 interpolate8x8_halfpel_v_c; INTERPOLATE8X8 interpolate8x8_halfpel_hv_c; INTERPOLATE8X8 interpolate8x8_halfpel_h_mmx; INTERPOLATE8X8 interpolate8x8_halfpel_v_mmx; INTERPOLATE8X8 interpolate8x8_halfpel_hv_mmx; INTERPOLATE8X8 interpolate8x8_halfpel_h_xmm; INTERPOLATE8X8 interpolate8x8_halfpel_v_xmm; INTERPOLATE8X8 interpolate8x8_halfpel_hv_xmm; INTERPOLATE8X8 interpolate8x8_halfpel_h_3dn; INTERPOLATE8X8 interpolate8x8_halfpel_v_3dn; INTERPOLATE8X8 interpolate8x8_halfpel_hv_3dn; static __inline void interpolate8x8_switch(uint8_t * const cur, const uint8_t * const refn, const uint32_t x, const uint32_t y, const int32_t dx, const int dy, const uint32_t stride, const uint32_t rounding) { int32_t ddx, ddy; switch ( ((dx&1)<<1) + (dy&1) ) // ((dx%2)?2:0)+((dy%2)?1:0) { case 0 : ddx = dx/2; ddy = dy/2; transfer8x8_copy(cur + y*stride + x, refn + (y+ddy)*stride + x + ddx, stride); break; case 1 : ddx = dx/2; ddy = (dy-1)/2; interpolate8x8_halfpel_v(cur + y*stride + x, refn + (y+ddy)*stride + x + ddx, stride, rounding); break; case 2 : ddx = (dx-1)/2; ddy = dy/2; interpolate8x8_halfpel_h(cur + y*stride + x, refn + (y+ddy)*stride + x + ddx, stride, rounding); break; default : ddx = (dx-1)/2; ddy = (dy-1)/2; interpolate8x8_halfpel_hv(cur + y*stride + x, refn + (y+ddy)*stride + x + ddx, stride, rounding); break; } } xvid_20020412/xvidcore/src/image/x86_asm/0040755000100600001440000000000007455522446017317 5ustar michaelusersxvid_20020412/xvidcore/src/image/x86_asm/CVS/0040755000100600001440000000000007455522446017752 5ustar michaelusersxvid_20020412/xvidcore/src/image/x86_asm/CVS/Root0100644000100600001440000000004607455522446020615 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/image/x86_asm/CVS/Repository0100644000100600001440000000003307455522446022045 0ustar michaelusersxvidcore/src/image/x86_asm xvid_20020412/xvidcore/src/image/x86_asm/CVS/Entries0100644000100600001440000000061707455522446021307 0ustar michaelusers/interpolate8x8_mmx.asm/1.7/Tue Mar 19 02:16:34 2002// /rgb_to_yv12_mmx.asm/1.1.1.1/Fri Mar 8 02:44:47 2002// /yuv_to_yv12_mmx.asm/1.1.1.1/Fri Mar 8 02:44:48 2002// /yuyv_to_yv12_mmx.asm/1.1.1.1/Fri Mar 8 02:44:48 2002// /yv12_to_rgb24_mmx.asm/1.1.1.1/Fri Mar 8 02:44:49 2002// /yv12_to_rgb32_mmx.asm/1.1.1.1/Fri Mar 8 02:44:50 2002// /yv12_to_yuyv_mmx.asm/1.1.1.1/Fri Mar 8 02:44:50 2002// D xvid_20020412/xvidcore/src/image/x86_asm/rgb_to_yv12_mmx.asm0100644000100600001440000002414207442022637023030 0ustar michaelusers;/************************************************************************** ; * ; * XVID MPEG-4 VIDEO CODEC ; * mmx colorspace conversions ; * ; * This program is an implementation of a part of one or more MPEG-4 ; * Video tools as specified in ISO/IEC 14496-2 standard. Those intending ; * to use this software module in hardware or software products are ; * advised that its use may infringe existing patents or copyrights, and ; * any such use would be at such party's own risk. The original ; * developer of this software module and his/her company, and subsequent ; * editors and their companies, will have no liability for use of this ; * software or modifications or derivatives thereof. ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * This program is distributed in the hope that it will be useful, ; * but WITHOUT ANY WARRANTY; without even the implied warranty of ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; * GNU General Public License for more details. ; * ; * You should have received a copy of the GNU General Public License ; * along with this program; if not, write to the Free Software ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; * ; *************************************************************************/ ;/************************************************************************** ; * ; * History: ; * ; * 24.11.2001 added cglobal macro (Isibaar) ; * 23.11.2001 initial version; (c)2001 peter ross ; * ; *************************************************************************/ bits 32 section .data %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro align 16 ;=========================================================================== ; yuv constants ;=========================================================================== %define Y_R 0.257 %define Y_G 0.504 %define Y_B 0.098 %define Y_ADD 16 %define U_R 0.148 %define U_G 0.291 %define U_B 0.439 %define U_ADD 128 %define V_R 0.439 %define V_G 0.368 %define V_B 0.071 %define V_ADD 128 ;=========================================================================== ; multiplication matrices ;=========================================================================== ; %define SCALEBITS 8 y_mul dw 25 ; FIX(Y_B) dw 129 ; FIX(Y_G) dw 66 ; FIX(Y_R) dw 0 u_mul dw 112 ; FIX(U_B) dw -74 ; FIX(U_G) dw -38 ; FIX(U_R) dw 0 v_mul dw -18 ; FIX(V_B) dw -94 ; FIX(V_G) dw 112 ; FIX(V_R) dw 0 section .text ;=========================================================================== ; ; void rgb24_to_yv12_mmx(uint8_t * const y_out, ; uint8_t * const u_out, ; uint8_t * const v_out, ; const uint8_t * const src, ; const uint32_t width, ; const uint32_t height, ; const uint32_t stride) ; ; always flips ; ;=========================================================================== align 16 cglobal rgb24_to_yv12_mmx rgb24_to_yv12_mmx push ebx push ecx push esi push edi push ebp ; STACK BASE = 20 ; global consants mov eax, [esp + 20 + 28] ; stride mov ecx, [esp + 20 + 20] ; width mov ebx, eax sub ebx, ecx shr ebx, 1 ; ebx = (stride-width) / 2; push ebx ; [esp + 20] = uv_dif ; STACK BASE = 24 add eax, eax sub eax, ecx ; eax = 2*stride - width push eax ; [esp + 16] = y_dif ; STACK BASE = 28 mov ebx, ecx ; shr ebx, 1 ; push ebx ; [esp + 12] = width/2 ; STACK BASE = 32 mov edx, ecx add ecx, edx add ecx, edx ; ecx = 3*width (use 4 for rgb32) push ecx ; [esp + 8] = width3 ; STACK BASE = 36 mov edx, ecx add edx, ecx add edx, ecx ; edx = 3*width3 push edx ; [esp + 4] = src_dif ; STACK BASE = 40 mov esi, [esp + 40 + 16] ; src mov ebp, [esp + 40 + 24] ; eax = height mov eax, ebp sub eax, 2 mul ecx add esi, eax ; src += (height-2) * width3 mov edi, [esp + 40 + 4] ; y_out mov ecx, [esp + 40 + 8] ; u_out mov edx, [esp + 40 + 12] ; v_out movq mm7, [y_mul] shr ebp, 1 ; ebp = height / 2 push ebp ; [esp+0] = tmp ; STACK BASE = 44 .yloop mov ebp, [esp + 12] ; ebp = width /2 .xloop ; y_out mov ebx, [esp + 8] ; ebx = width3 pxor mm4, mm4 pxor mm5, mm5 movd mm0, [esi] ; src[0...] movd mm2, [esi+ebx] ; src[width3...] punpcklbw mm0, mm4 ; [ |b |g |r ] punpcklbw mm2, mm5 ; [ |b |g |r ] movq mm6, mm0 ; = [ |b4|g4|r4] paddw mm6, mm2 ; +[ |b4|g4|r4] pmaddwd mm0, mm7 ; *= Y_MUL pmaddwd mm2, mm7 ; *= Y_MUL movq mm4, mm0 ; [r] movq mm5, mm2 ; [r] psrlq mm4, 32 ; +[g] psrlq mm5, 32 ; +[g] paddd mm0, mm4 ; +[b] paddd mm2, mm5 ; +[b] pxor mm4, mm4 pxor mm5, mm5 movd mm1, [esi+3] ; src[4...] movd mm3, [esi+ebx+3] ; src[width3+4...] punpcklbw mm1, mm4 ; [ |b |g |r ] punpcklbw mm3, mm5 ; [ |b |g |r ] paddw mm6, mm1 ; +[ |b4|g4|r4] paddw mm6, mm3 ; +[ |b4|g4|r4] pmaddwd mm1, mm7 ; *= Y_MUL pmaddwd mm3, mm7 ; *= Y_MUL movq mm4, mm1 ; [r] movq mm5, mm3 ; [r] psrlq mm4, 32 ; +[g] psrlq mm5, 32 ; +[g] paddd mm1, mm4 ; +[b] paddd mm3, mm5 ; +[b] mov ebx, [esp + 44 + 28] ; stride movd eax, mm0 shr eax, 8 add eax, Y_ADD mov [edi + ebx], al movd eax, mm1 shr eax, 8 add eax, Y_ADD mov [edi + ebx + 1], al movd eax, mm2 shr eax, 8 add eax, Y_ADD mov [edi], al movd eax, mm3 shr eax, 8 add eax, Y_ADD mov [edi + 1], al ; u_out, v_out movq mm0, mm6 ; = [ |b4|g4|r4] pmaddwd mm6, [v_mul] ; *= V_MUL pmaddwd mm0, [u_mul] ; *= U_MUL movq mm1, mm0 movq mm2, mm6 psrlq mm1, 32 psrlq mm2, 32 paddd mm0, mm1 paddd mm2, mm6 movd eax, mm0 shr eax, 10 add eax, U_ADD mov [ecx], al movd eax, mm2 shr eax, 10 add eax, V_ADD mov [edx], al add esi, 2 * 3 ; (use 4 for rgb32) add edi, 2 inc ecx inc edx dec ebp jnz near .xloop sub esi, [esp + 4] ; src -= src_dif add edi, [esp + 16] ; y_out += y_dif add ecx, [esp + 20] ; u_out += uv_dif add edx, [esp + 20] ; v_out += uv_dif dec dword [esp+0] jnz near .yloop emms add esp, 24 pop ebp pop edi pop esi pop ecx pop ebx ret ;=========================================================================== ; ; void rgb32_to_yv12mmx(uint8_t * const y_out, ; uint8_t * const u_out, ; uint8_t * const v_out, ; const uint8_t * const src, ; const uint32_t width, ; const uint32_t height, ; const uint32_t stride) ; ; always flips ; ;=========================================================================== align 16 cglobal rgb32_to_yv12_mmx rgb32_to_yv12_mmx push ebx push ecx push esi push edi push ebp ; STACK BASE = 20 ; global consants mov eax, [esp + 20 + 28] ; stride mov ecx, [esp + 20 + 20] ; width mov ebx, eax sub ebx, ecx shr ebx, 1 ; ebx = (stride-width) / 2; push ebx ; [esp + 20] = uv_dif ; STACK BASE = 24 add eax, eax sub eax, ecx ; eax = 2*stride - width push eax ; [esp + 16] = y_dif ; STACK BASE = 28 mov ebx, ecx ; shr ebx, 1 ; push ebx ; [esp + 12] = width/2 ; STACK BASE = 32 mov edx, ecx shl ecx, 2 ; ecx = 4*width (use 4 for rgb32) push ecx ; [esp + 8] = width4 ; STACK BASE = 36 mov edx, ecx add edx, ecx add edx, ecx ; edx = 3*width4 push edx ; [esp + 4] = src_dif ; STACK BASE = 40 mov esi, [esp + 40 + 16] ; src mov ebp, [esp + 40 + 24] ; eax = height mov eax, ebp sub eax, 2 mul ecx add esi, eax ; src += (height-2) * width4 mov edi, [esp + 40 + 4] ; y_out mov ecx, [esp + 40 + 8] ; u_out mov edx, [esp + 40 + 12] ; v_out movq mm7, [y_mul] shr ebp, 1 ; ebp = height / 2 push ebp ; [esp+0] = tmp ; STACK BASE = 44 .yloop mov ebp, [esp + 12] ; ebp = width /2 .xloop ; y_out mov ebx, [esp + 8] ; ebx = width4 pxor mm4, mm4 movq mm0, [esi] ; src[4... |0... ] movq mm2, [esi+ebx] ; src[width4+4...|width4...] movq mm1, mm0 movq mm3, mm2 punpcklbw mm0, mm4 ; [ |b |g |r ] punpcklbw mm2, mm4 ; [ |b |g |r ] punpckhbw mm1, mm4 ; [ |b |g |r ] punpckhbw mm3, mm4 ; [ |b |g |r ] movq mm6, mm0 ; = [ |b4|g4|r4] paddw mm6, mm2 ; +[ |b4|g4|r4] pmaddwd mm0, mm7 ; *= Y_MUL pmaddwd mm2, mm7 ; *= Y_MUL movq mm4, mm0 ; [r] movq mm5, mm2 ; [r] psrlq mm4, 32 ; +[g] psrlq mm5, 32 ; +[g] paddd mm0, mm4 ; +[b] paddd mm2, mm5 ; +[b] paddw mm6, mm1 ; +[ |b4|g4|r4] paddw mm6, mm3 ; +[ |b4|g4|r4] pmaddwd mm1, mm7 ; *= Y_MUL pmaddwd mm3, mm7 ; *= Y_MUL movq mm4, mm1 ; [r] movq mm5, mm3 ; [r] psrlq mm4, 32 ; +[g] psrlq mm5, 32 ; +[g] paddd mm1, mm4 ; +[b] paddd mm3, mm5 ; +[b] mov ebx, [esp + 44 + 28] ; stride movd eax, mm0 shr eax, 8 add eax, Y_ADD mov [edi + ebx], al movd eax, mm1 shr eax, 8 add eax, Y_ADD mov [edi + ebx + 1], al movd eax, mm2 shr eax, 8 add eax, Y_ADD mov [edi], al movd eax, mm3 shr eax, 8 add eax, Y_ADD mov [edi + 1], al ; u_out, v_out movq mm0, mm6 ; = [ |b4|g4|r4] pmaddwd mm6, [v_mul] ; *= V_MUL pmaddwd mm0, [u_mul] ; *= U_MUL movq mm1, mm0 movq mm2, mm6 psrlq mm1, 32 psrlq mm2, 32 paddd mm0, mm1 paddd mm2, mm6 movd eax, mm0 shr eax, 10 add eax, U_ADD mov [ecx], al movd eax, mm2 shr eax, 10 add eax, V_ADD mov [edx], al add esi, 2 * 4 ; (use 4 for rgb32) add edi, 2 inc ecx inc edx dec ebp jnz near .xloop sub esi, [esp + 4] ; src -= src_dif add edi, [esp + 16] ; y_out += y_dif add ecx, [esp + 20] ; u_out += uv_dif add edx, [esp + 20] ; v_out += uv_dif dec dword [esp+0] jnz near .yloop emms add esp, 24 pop ebp pop edi pop esi pop ecx pop ebx ret xvid_20020412/xvidcore/src/image/x86_asm/yv12_to_yuyv_mmx.asm0100644000100600001440000001714607442022642023274 0ustar michaelusers;/************************************************************************** ; * ; * XVID MPEG-4 VIDEO CODEC ; * mmx yuv planar to yuyv/uyvy ; * ; * This program is an implementation of a part of one or more MPEG-4 ; * Video tools as specified in ISO/IEC 14496-2 standard. Those intending ; * to use this software module in hardware or software products are ; * advised that its use may infringe existing patents or copyrights, and ; * any such use would be at such party's own risk. The original ; * developer of this software module and his/her company, and subsequent ; * editors and their companies, will have no liability for use of this ; * software or modifications or derivatives thereof. ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * This program is distributed in the hope that it will be useful, ; * but WITHOUT ANY WARRANTY; without even the implied warranty of ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; * GNU General Public License for more details. ; * ; * You should have received a copy of the GNU General Public License ; * along with this program; if not, write to the Free Software ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; * ; *************************************************************************/ ;/************************************************************************** ; * ; * History: ; * ; * 05.12.2001 initial version; (c)2001 peter ross ; * ; *************************************************************************/ bits 32 section .data %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro align 16 section .text ;=========================================================================== ; ; void yv12_to_uyvy_mmx( ; uint8_t * dst, ; int dst_stride, ; uint8_t * y_src, ; uint8_t * u_src, ; uint8_t * v_src, ; int y_stride, ; int uv_stride, ; int width, ; int height); ; ; width must be multiple of 8 ; ~10% faster than plain c ; ;=========================================================================== align 16 cglobal yv12_to_yuyv_mmx yv12_to_yuyv_mmx push ebx push ecx push esi push edi push ebp ; STACK BASE = 20 ; global constants mov ebx, [esp + 20 + 32] ; width mov eax, [esp + 20 + 8] ; dst_stride sub eax, ebx ; add eax, eax ; eax = 2*(dst_stride - width) push eax ; [esp + 4] = dst_dif ; STACK BASE = 24 shr ebx, 3 ; ebx = width / 8 mov edi, [esp + 24 + 4] ; dst ; --------- flip ------------- mov ebp, [esp + 24 + 36] test ebp, ebp jl .flip mov esi, [esp + 24 + 12] ; y_src mov ecx, [esp + 24 + 16] ; u_src mov edx, [esp + 24 + 20] ; v_src shr ebp, 1 ; y = height / 2 jmp short .yloop .flip neg ebp ; height = -height mov eax, [esp + 24 + 24] ; y_stride lea edx, [ebp - 1] ; edx = height - 1 mul edx mov esi, [esp + 24 + 12] ; y_src add esi, eax ; y_src += (height - 1) * y_stride shr ebp, 1 ; y = height / 2 mov eax, [esp + 24 + 28] ; uv_stride lea edx, [ebp - 1] ; edx = height/2 - 1 mul edx mov ecx, [esp + 24 + 16] ; u_src mov edx, [esp + 24 + 20] ; v_src add ecx, eax ; u_src += (height/2 - 1) * uv_stride add edx, eax ; v_src += (height/2 - 1) * uv_stride neg dword [esp + 24 + 24] ; y_stride = -y_stride neg dword [esp + 24 + 28] ; uv_stride = -uv_stride .yloop xor eax, eax ; x = 0; .xloop1 movd mm0, [ecx+4*eax] ; [ |uuuu] movd mm1, [edx+4*eax] ; [ |vvvv] movq mm2, [esi+8*eax] ; [yyyy|yyyy] punpcklbw mm0, mm1 ; [vuvu|vuvu] movq mm3, mm2 punpcklbw mm2, mm0 ; [vyuy|vyuy] punpckhbw mm3, mm0 ; [vyuy|vyuy] movq [edi], mm2 movq [edi+8], mm3 inc eax add edi, 16 cmp eax, ebx jb .xloop1 add edi, [esp + 0] ; dst += dst_dif add esi, [esp + 24 + 24] ; y_src += y_stride xor eax, eax .xloop2 movd mm0, [ecx+4*eax] ; [ |uuuu] movd mm1, [edx+4*eax] ; [ |vvvv] movq mm2, [esi+8*eax] ; [yyyy|yyyy] punpcklbw mm0, mm1 ; [vuvu|vuvu] movq mm3, mm2 punpcklbw mm2, mm0 ; [vyuy|vyuy] punpckhbw mm3, mm0 ; [vyuy|vyuy] movq [edi], mm2 movq [edi+8], mm3 inc eax add edi, 16 cmp eax, ebx jb .xloop2 add edi, [esp + 0] ; dst += dst_dif add esi, [esp + 24 + 24] ; y_src += y_stride add ecx, [esp + 24 + 28] ; u_src += uv_stride add edx, [esp + 24 + 28] ; v_src += uv_stride dec ebp ; y-- jnz near .yloop emms add esp, 4 pop ebp pop edi pop esi pop ecx pop ebx ret ;=========================================================================== ; ; void yv12_to_uyvy_mmx( ; uint8_t * dst, ; int dst_stride, ; uint8_t * y_src, ; uint8_t * u_src, ; uint8_t * v_src, ; int y_stride, ; int uv_stride, ; int width, ; int height); ; ; width must be multiple of 8 ; ~10% faster than plain c ; ;=========================================================================== align 16 cglobal yv12_to_uyvy_mmx yv12_to_uyvy_mmx push ebx push ecx push esi push edi push ebp ; STACK BASE = 20 ; global constants mov ebx, [esp + 20 + 32] ; width mov eax, [esp + 20 + 8] ; dst_stride sub eax, ebx ; add eax, eax ; eax = 2*(dst_stride - width) push eax ; [esp + 4] = dst_dif ; STACK BASE = 24 shr ebx, 3 ; ebx = width / 8 mov edi, [esp + 24 + 4] ; dst ; --------- flip ------------- mov ebp, [esp + 24 + 36] test ebp, ebp jl .flip mov esi, [esp + 24 + 12] ; y_src mov ecx, [esp + 24 + 16] ; u_src mov edx, [esp + 24 + 20] ; v_src shr ebp, 1 ; y = height / 2 jmp short .yloop .flip neg ebp ; height = -height mov eax, [esp + 24 + 24] ; y_stride lea edx, [ebp - 1] ; edx = height - 1 mul edx mov esi, [esp + 24 + 12] ; y_src add esi, eax ; y_src += (height - 1) * y_stride shr ebp, 1 ; y = height / 2 mov eax, [esp + 24 + 28] ; uv_stride lea edx, [ebp - 1] ; edx = height/2 - 1 mul edx mov ecx, [esp + 24 + 16] ; u_src mov edx, [esp + 24 + 20] ; v_src add ecx, eax ; u_src += (height/2 - 1) * uv_stride add edx, eax ; v_src += (height/2 - 1) * uv_stride neg dword [esp + 24 + 24] ; y_stride = -y_stride neg dword [esp + 24 + 28] ; uv_stride = -uv_stride .yloop xor eax, eax ; x = 0; .xloop1 movd mm0, [ecx+4*eax] ; [ |uuuu] movd mm1, [edx+4*eax] ; [ |vvvv] movq mm2, [esi+8*eax] ; [yyyy|yyyy] punpcklbw mm0, mm1 ; [vuvu|vuvu] movq mm1, mm0 punpcklbw mm0, mm2 ; [yvyu|yvyu] punpckhbw mm1, mm2 ; [yvyu|yvyu] movq [edi], mm0 movq [edi+8], mm1 inc eax add edi, 16 cmp eax, ebx jb .xloop1 add edi, [esp + 0] ; dst += dst_dif add esi, [esp + 24 + 24] ; y_src += y_stride xor eax, eax .xloop2 movd mm0, [ecx+4*eax] ; [ |uuuu] movd mm1, [edx+4*eax] ; [ |vvvv] movq mm2, [esi+8*eax] ; [yyyy|yyyy] punpcklbw mm0, mm1 ; [vuvu|vuvu] movq mm1, mm0 punpcklbw mm0, mm2 ; [yvyu|yvyu] punpckhbw mm1, mm2 ; [yvyu|yvyu] movq [edi], mm0 movq [edi+8], mm1 inc eax add edi, 16 cmp eax, ebx jb .xloop2 add edi, [esp + 0] ; dst += dst_dif add esi, [esp + 24 + 24] ; y_src += y_stride add ecx, [esp + 24 + 28] ; u_src += uv_stride add edx, [esp + 24 + 28] ; v_src += uv_stride dec ebp ; y-- jnz near .yloop emms add esp, 4 pop ebp pop edi pop esi pop ecx pop ebx ret xvid_20020412/xvidcore/src/image/x86_asm/interpolate8x8_mmx.asm0100644000100600001440000004160407445517602023577 0ustar michaelusers;/************************************************************************** ; * ; * XVID MPEG-4 VIDEO CODEC ; * mmx/xmm/3dnow 8x8 block-based halfpel interpolation ; * ; * This program is an implementation of a part of one or more MPEG-4 ; * Video tools as specified in ISO/IEC 14496-2 standard. Those intending ; * to use this software module in hardware or software products are ; * advised that its use may infringe existing patents or copyrights, and ; * any such use would be at such party's own risk. The original ; * developer of this software module and his/her company, and subsequent ; * editors and their companies, will have no liability for use of this ; * software or modifications or derivatives thereof. ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * This program is distributed in the hope that it will be useful, ; * but WITHOUT ANY WARRANTY; without even the implied warranty of ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; * GNU General Public License for more details. ; * ; * You should have received a copy of the GNU General Public License ; * along with this program; if not, write to the Free Software ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; * ; *************************************************************************/ ;/************************************************************************** ; * ; * History: ; * ; * 04.02.2002 added xmm and additional 3dnow optimizations (Isibaar) ; * 27.12.2001 mofified "compensate_halfpel" ; * 22.12.2001 inital version; (c)2001 peter ross ; * ; *************************************************************************/ bits 32 %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro section .data align 16 ;=========================================================================== ; (1 - r) rounding table ;=========================================================================== rounding1_mmx times 4 dw 1 times 4 dw 0 ;=========================================================================== ; (2 - r) rounding table ;=========================================================================== rounding2_mmx times 4 dw 2 times 4 dw 1 mmx_one times 8 db 1 section .text %macro CALC_AVG 6 punpcklbw %3, %6 punpckhbw %4, %6 paddusw %1, %3 ; mm01 += mm23 paddusw %2, %4 paddusw %1, %5 ; mm01 += rounding paddusw %2, %5 psrlw %1, 1 ; mm01 >>= 1 psrlw %2, 1 %endmacro ;=========================================================================== ; ; void interpolate8x8_halfpel_h_xmm(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride, ; const uint32_t rounding); ; ;=========================================================================== align 16 cglobal interpolate8x8_halfpel_h_xmm interpolate8x8_halfpel_h_xmm push esi push edi mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov edx, [esp + 8 + 12] ; stride mov ecx, edx shl edx, 1 mov eax, [esp + 8 + 16] ; rounding or al,al jnz near halfpel_h_xmm_rounding1 ; needs extra hack, still faster than mmx halfpel_h_xmm_rounding0 ; mov eax, 4 ;.loop movq mm0, [esi] movq mm1, [esi + ecx] pavgb mm0, [esi + 1] ; mm0 = avg([src], [src+1]) pavgb mm1, [esi + ecx + 1] ; mm1 = avg([src+stride], [src+stride+1]) movq [edi], mm0 movq [edi + ecx], mm1 add esi, edx ; src += 2*stride add edi, edx ; dst += 2*stride movq mm0, [esi] movq mm1, [esi + ecx] pavgb mm0, [esi + 1] pavgb mm1, [esi + ecx + 1] movq [edi], mm0 movq [edi + ecx], mm1 add esi, edx add edi, edx movq mm0, [esi] movq mm1, [esi + ecx] pavgb mm0, [esi + 1] pavgb mm1, [esi + ecx + 1] movq [edi], mm0 movq [edi + ecx], mm1 add esi, edx add edi, edx movq mm0, [esi] movq mm1, [esi + ecx] pavgb mm0, [esi + 1] pavgb mm1, [esi + ecx + 1] movq [edi], mm0 movq [edi + ecx], mm1 ; dec eax ; jnz .loop pop edi pop esi ret halfpel_h_xmm_rounding1 movq mm7, [mmx_one] mov eax, 4 .loop movq mm0, [esi] movq mm1, [esi + ecx] movq mm2, [esi + 1] movq mm3, [esi + ecx + 1] movq mm4, mm0 ; backup mm01 movq mm5, mm1 pavgb mm0, mm2 ; mm0 = avg([src], [src+1]) pavgb mm1, mm3 ; mm1 = avg([src+stride], [src+stride+1]) paddb mm2, mm4 ; add values, see if lsb is set paddb mm3, mm5 ; (to patch pavgb's (a+b+1)/2 rounding) pand mm2, mm7 ; isolate lsb's pand mm3, mm7 psubusb mm0, mm2 ; mm23 = 0 if lsb wasn't set psubusb mm1, mm3 movq [edi], mm0 movq [edi + ecx], mm1 add esi, edx ; src += 2*stride add edi, edx ; dst += 2*stride dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void interpolate8x8_halfpel_h_3dn(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride, ; const uint32_t rounding); ; ;=========================================================================== align 16 cglobal interpolate8x8_halfpel_h_3dn interpolate8x8_halfpel_h_3dn push esi push edi mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov edx, [esp + 8 + 12] ; stride mov ecx, edx shl edx, 1 mov eax, [esp + 8 + 16] ; rounding or al,al ; perform hack for pavgusb rounding issue jnz near halfpel_h_3dn_rounding1 halfpel_h_3dn_rounding0 ; mov eax, 4 ;.loop movq mm0, [esi] movq mm1, [esi + ecx] pavgusb mm0, [esi + 1] ; mm0 = avg([src], [src+1]) pavgusb mm1, [esi + ecx + 1] ; mm0 = avg([src+stride], [src+stride+1]) movq [edi], mm0 movq [edi + ecx], mm1 add esi, edx ; src += 2*stride add edi, edx ; dst += 2*stride movq mm0, [esi] movq mm1, [esi + ecx] pavgusb mm0, [esi + 1] pavgusb mm1, [esi + ecx + 1] movq [edi], mm0 movq [edi + ecx], mm1 add esi, edx add edi, edx movq mm0, [esi] movq mm1, [esi + ecx] pavgusb mm0, [esi + 1] pavgusb mm1, [esi + ecx + 1] movq [edi], mm0 movq [edi + ecx], mm1 add esi, edx add edi, edx movq mm0, [esi] movq mm1, [esi + ecx] pavgusb mm0, [esi + 1] pavgusb mm1, [esi + ecx + 1] movq [edi], mm0 movq [edi + ecx], mm1 ; dec eax ; jnz .loop pop edi pop esi ret halfpel_h_3dn_rounding1 movq mm7, [mmx_one] mov eax, 4 .loop movq mm0, [esi] movq mm1, [esi + ecx] movq mm2, [esi + 1] movq mm3, [esi + ecx + 1] movq mm4, mm0 ; backup mm01 movq mm5, mm1 pavgusb mm0, mm2 ; mm0 = avg([src], [src+1]) pavgusb mm1, mm3 ; mm1 = avg([src+stride], [src+stride+1]) paddb mm2, mm4 ; add values, see if lsb is set paddb mm3, mm5 ; (to patch pavgb's (a+b+1)/2 rounding) pand mm2, mm7 ; isolate lsb's pand mm3, mm7 psubusb mm0, mm2 ; mm23 = 0 if lsb wasn't set psubusb mm1, mm3 movq [edi], mm0 movq [edi + ecx], mm1 add esi, edx ; src += 2*stride add edi, edx ; dst += 2*stride dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride, ; const uint32_t rounding); ; ;=========================================================================== align 16 cglobal interpolate8x8_halfpel_h_mmx interpolate8x8_halfpel_h_mmx push esi push edi mov eax, [esp + 8 + 16] ; rounding interpolate8x8_halfpel_h_mmx.start movq mm7, [rounding1_mmx + eax * 8] mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov edx, [esp + 8 + 12] ; stride mov eax, 8 pxor mm6, mm6 ; zero .loop movq mm0, [esi] movq mm2, [esi + 1] movq mm1, mm0 movq mm3, mm2 punpcklbw mm0, mm6 ; mm01 = [src] punpckhbw mm1, mm6 ; mm23 = [src + 1] CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6 packuswb mm0, mm1 movq [edi], mm0 ; [dst] = mm01 add esi, edx ; src += stride add edi, edx ; dst += stride dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void interpolate8x8_halfpel_v_xmm(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride, ; const uint32_t rounding); ; ;=========================================================================== align 16 cglobal interpolate8x8_halfpel_v_xmm interpolate8x8_halfpel_v_xmm push esi push edi mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov edx, [esp + 8 + 12] ; stride mov eax, [esp + 8 + 16] ; rounding or al,al jnz near halfpel_v_xmm_rounding1 halfpel_v_xmm_rounding0 ; mov eax, 8 ;.loop movq mm0, [esi] pavgb mm0, [esi + edx] ; mm0 = avg([src], [src+stride]) movq [edi], mm0 add edi, edx ; dst += stride add esi, edx ; src += stride movq mm0, [esi] pavgb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgb mm0, [esi + edx] movq [edi], mm0 ; dec eax ; jnz .loop pop edi pop esi ret halfpel_v_xmm_rounding1 movq mm7, [mmx_one] mov eax, 8 .loop movq mm0, [esi] movq mm1, [esi + edx] movq mm2, mm0 ; backup mm0 pavgb mm0, mm1 ; mm0 = avg([src], [src+stride]) paddb mm1, mm2 ; isolate and subtract lsb's from original values pand mm1, mm7 ; (compensate for pavgb rounding) psubusb mm0, mm1 movq [edi], mm0 add edi, edx ; dst += stride add esi, edx ; src += stride dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void interpolate8x8_halfpel_v_3dn(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride, ; const uint32_t rounding); ; ;=========================================================================== align 16 cglobal interpolate8x8_halfpel_v_3dn interpolate8x8_halfpel_v_3dn push esi push edi mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov edx, [esp + 8 + 12] ; stride mov eax, [esp + 8 + 16] ; rounding or al,al ; hack for pavgusb rounding jnz halfpel_v_3dn_rounding1 halfpel_v_3dn_rounding0 ; mov eax, 8 ;.loop movq mm0, [esi] pavgusb mm0, [esi + edx] ; mm0 = avg([src], [src+stride]) movq [edi], mm0 add edi, edx ; dst += stride add esi, edx ; src += stride movq mm0, [esi] pavgusb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgusb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgusb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgusb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgusb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgusb mm0, [esi + edx] movq [edi], mm0 add edi, edx add esi, edx movq mm0, [esi] pavgusb mm0, [esi + edx] movq [edi], mm0 ; dec eax ; jnz .loop pop edi pop esi ret halfpel_v_3dn_rounding1 movq mm7, [mmx_one] mov eax, 8 .loop movq mm0, [esi] movq mm1, [esi + edx] movq mm2, mm0 ; backup mm0 pavgusb mm0, mm1 ; mm0 = avg([src], [src+stride]) paddb mm1, mm2 ; isolate and subtract lsb's from original values pand mm1, mm7 ; (compensate for pavgb rounding) psubusb mm0, mm1 movq [edi], mm0 add edi, edx ; dst += stride add esi, edx ; src += stride dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride, ; const uint32_t rounding); ; ;=========================================================================== align 16 cglobal interpolate8x8_halfpel_v_mmx interpolate8x8_halfpel_v_mmx push esi push edi mov eax, [esp + 8 + 16] ; rounding interpolate8x8_halfpel_v_mmx.start movq mm7, [rounding1_mmx + eax * 8] mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov edx, [esp + 8 + 12] ; stride mov eax, 8 pxor mm6, mm6 ; zero .loop movq mm0, [esi] movq mm2, [esi + edx] movq mm1, mm0 movq mm3, mm2 punpcklbw mm0, mm6 ; mm01 = [src] punpckhbw mm1, mm6 ; mm23 = [src + 1] CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6 packuswb mm0, mm1 movq [edi], mm0 ; [dst] = mm01 add esi, edx ; src += stride add edi, edx ; dst += stride dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void interpolate8x8_halfpel_hv_xmm(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride, ; const uint32_t rounding); ; ; ;=========================================================================== align 16 cglobal interpolate8x8_halfpel_hv_xmm interpolate8x8_halfpel_hv_xmm push esi push edi mov eax, [esp + 8 + 16] ; rounding or al,al jnz interpolate8x8_halfpel_hv_mmx.start mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov edx, [esp + 8 + 12] ; stride movq mm7, [mmx_one] mov eax, 8 .loop ; current row movq mm0, [esi] movq mm1, [esi + 1] movq mm2, mm0 pavgb mm0, mm1 pxor mm1, mm2 ; next row movq mm2, [esi + edx] movq mm3, [esi + edx + 1] movq mm4, mm2 pavgb mm2, mm3 pxor mm3, mm4 ; add current + next row por mm1, mm3 movq mm3, mm0 pxor mm3, mm2 pand mm1, mm3 pavgb mm0, mm2 pand mm1, mm7 psubusb mm0, mm1 movq [edi], mm0 ; [dst] = mm01 add esi, edx ; src += stride add edi, edx ; dst += stride dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride, ; const uint32_t rounding); ; ; ;=========================================================================== align 16 cglobal interpolate8x8_halfpel_hv_mmx interpolate8x8_halfpel_hv_mmx push esi push edi mov eax, [esp + 8 + 16] ; rounding interpolate8x8_halfpel_hv_mmx.start movq mm7, [rounding2_mmx + eax * 8] mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov eax, 8 pxor mm6, mm6 ; zero mov edx, [esp + 8 + 12] ; stride .loop ; current row movq mm0, [esi] movq mm2, [esi + 1] movq mm1, mm0 movq mm3, mm2 punpcklbw mm0, mm6 ; mm01 = [src] punpcklbw mm2, mm6 ; mm23 = [src + 1] punpckhbw mm1, mm6 punpckhbw mm3, mm6 paddusw mm0, mm2 ; mm01 += mm23 paddusw mm1, mm3 ; next row movq mm4, [esi + edx] movq mm2, [esi + edx + 1] movq mm5, mm4 movq mm3, mm2 punpcklbw mm4, mm6 ; mm45 = [src + stride] punpcklbw mm2, mm6 ; mm23 = [src + stride + 1] punpckhbw mm5, mm6 punpckhbw mm3, mm6 paddusw mm4, mm2 ; mm45 += mm23 paddusw mm5, mm3 ; add current + next row paddusw mm0, mm4 ; mm01 += mm45 paddusw mm1, mm5 paddusw mm0, mm7 ; mm01 += rounding2 paddusw mm1, mm7 psrlw mm0, 2 ; mm01 >>= 2 psrlw mm1, 2 packuswb mm0, mm1 movq [edi], mm0 ; [dst] = mm01 add esi, edx ; src += stride add edi, edx ; dst += stride dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void interpolate8x8_halfpel_hv_3dn(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride, ; const uint32_t rounding); ; ; ;=========================================================================== align 16 cglobal interpolate8x8_halfpel_hv_3dn interpolate8x8_halfpel_hv_3dn push esi push edi mov eax, [esp + 8 + 16] ; rounding or al,al jnz near interpolate8x8_halfpel_hv_mmx.start mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov edx, [esp + 8 + 12] ; stride movq mm7, [mmx_one] mov eax, 8 .loop ; current row movq mm0, [esi] movq mm1, [esi + 1] movq mm2, mm0 pavgusb mm0, mm1 pxor mm1, mm2 ; next row movq mm2, [esi + edx] movq mm3, [esi + edx + 1] movq mm4, mm2 pavgusb mm2, mm3 pxor mm3, mm4 ; add current + next row por mm1, mm3 movq mm3, mm0 pxor mm3, mm2 pand mm1, mm3 pavgusb mm0, mm2 pand mm1, mm7 psubusb mm0, mm1 movq [edi], mm0 ; [dst] = mm01 add esi, edx ; src += stride add edi, edx ; dst += stride dec eax jnz .loop pop edi pop esi ret xvid_20020412/xvidcore/src/image/x86_asm/yuv_to_yv12_mmx.asm0100644000100600001440000003103107442022640023066 0ustar michaelusers;/****************************************************************************** ; * * ; * This file is part of XviD, a free MPEG-4 video encoder/decoder * ; * * ; * XviD is an implementation of a part of one or more MPEG-4 Video tools * ; * as specified in ISO/IEC 14496-2 standard. Those intending to use this * ; * software module in hardware or software products are advised that its * ; * use may infringe existing patents or copyrights, and any such use * ; * would be at such party's own risk. The original developer of this * ; * software module and his/her company, and subsequent editors and their * ; * companies, will have no liability for use of this software or * ; * modifications or derivatives thereof. * ; * * ; * XviD is free software; you can redistribute it and/or modify it * ; * under the terms of the GNU General Public License as published by * ; * the Free Software Foundation; either version 2 of the License, or * ; * (at your option) any later version. * ; * * ; * XviD is distributed in the hope that it will be useful, but * ; * WITHOUT ANY WARRANTY; without even the implied warranty of * ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ; * GNU General Public License for more details. * ; * * ; * You should have received a copy of the GNU General Public License * ; * along with this program; if not, write to the Free Software * ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * yuv_to_yuv.asm, MMX optimized color conversion * ; * * ; * Copyright (C) 2001 - Michael Militzer , * ; * * ; * For more information visit the XviD homepage: http://www.xvid.org * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * Revision history: * ; * * ; * 24.11.2001 initial version (Isibaar) * ; * * ; ******************************************************************************/ BITS 32 %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro SECTION .data remainder dw 0 SECTION .text ALIGN 64 ; Attention: This code assumes that width is a multiple of 16 ; This function probably also runs on PentiumII class cpu's ;;void yuv_to_yv12_xmm(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, ;; int width, int height, int stride); cglobal yuv_to_yv12_xmm yuv_to_yv12_xmm: push ebx push esi push edi push ebp mov eax, [esp + 40] ; height -> eax mov ebx, [esp + 44] ; stride -> ebx mov esi, [esp + 32] ; src -> esi mov edi, [esp + 20] ; y_out -> edi mov ecx, [esp + 36] ; width -> ecx sub ebx, ecx ; stride - width -> ebx mov edx, ecx mov ebp, ecx shr edx, 6 mov ecx, edx ; 64 bytes copied per iteration shl edx, 6 sub ebp, edx ; remainder -> ebp shr ebp, 4 ; 16 bytes per iteration add ebp, 1 mov [remainder], ebp mov edx, ecx .y_inner_loop: prefetchnta [esi + 64] ; non temporal prefetch prefetchnta [esi + 96] movq mm1, [esi] ; read from src movq mm2, [esi + 8] movq mm3, [esi + 16] movq mm4, [esi + 24] movq mm5, [esi + 32] movq mm6, [esi + 40] movq mm7, [esi + 48] movq mm0, [esi + 56] movntq [edi], mm1 ; write to y_out movntq [edi + 8], mm2 movntq [edi + 16], mm3 movntq [edi + 24], mm4 movntq [edi + 32], mm5 movntq [edi + 40], mm6 movntq [edi + 48], mm7 movntq [edi + 56], mm0 add esi, 64 add edi, 64 dec ecx jnz .y_inner_loop dec ebp jz .y_outer_loop .y_remainder_loop: movq mm1, [esi] ; read from src movq mm2, [esi + 8] movntq [edi], mm1 ; write to y_out movntq [edi + 8], mm2 add esi, 16 add edi, 16 dec ebp jnz .y_remainder_loop .y_outer_loop: mov ebp, [remainder] mov ecx, edx add edi, ebx dec eax jnz near .y_inner_loop mov eax, [esp + 40] ; height -> eax mov ebx, [esp + 44] ; stride -> ebx mov ecx, [esp + 36] ; width -> ecx mov edi, [esp + 24] ; u_out -> edi shr ecx, 1 ; width / 2 -> ecx shr ebx, 1 ; stride / 2 -> ebx shr eax, 1 ; height / 2 -> eax sub ebx, ecx ; stride / 2 - width / 2 -> ebx mov edx, ecx mov ebp, ecx shr edx, 6 mov ecx, edx ; 64 bytes copied per iteration shl edx, 6 sub ebp, edx ; remainder -> ebp shr ebp, 3 ; 8 bytes per iteration add ebp, 1 mov [remainder], ebp mov edx, ecx .u_inner_loop: prefetchnta [esi + 64] ; non temporal prefetch prefetchnta [esi + 96] movq mm1, [esi] ; read from src movq mm2, [esi + 8] movq mm3, [esi + 16] movq mm4, [esi + 24] movq mm5, [esi + 32] movq mm6, [esi + 40] movq mm7, [esi + 48] movq mm0, [esi + 56] movntq [edi], mm1 ; write to u_out movntq [edi + 8], mm2 movntq [edi + 16], mm3 movntq [edi + 24], mm4 movntq [edi + 32], mm5 movntq [edi + 40], mm6 movntq [edi + 48], mm7 movntq [edi + 56], mm0 add esi, 64 add edi, 64 dec ecx jnz .u_inner_loop dec ebp jz .u_outer_loop .u_remainder_loop: movq mm1, [esi] ; read from src movntq [edi], mm1 ; write to y_out add esi, 8 add edi, 8 dec ebp jnz .u_remainder_loop .u_outer_loop: mov ebp, [remainder] mov ecx, edx add edi, ebx dec eax jnz .u_inner_loop mov eax, [esp + 40] ; height -> eax mov ecx, [esp + 36] ; width -> ecx mov edi, [esp + 28] ; v_out -> edi shr ecx, 1 ; width / 2 -> ecx shr eax, 1 ; height / 2 -> eax mov edx, ecx mov ebp, ecx shr edx, 6 mov ecx, edx ; 64 bytes copied per iteration shl edx, 6 sub ebp, edx ; remainder -> ebp shr ebp, 3 ; 8 bytes per iteration add ebp, 1 mov [remainder], ebp mov edx, ecx .v_inner_loop: prefetchnta [esi + 64] ; non temporal prefetch prefetchnta [esi + 96] movq mm1, [esi] ; read from src movq mm2, [esi + 8] movq mm3, [esi + 16] movq mm4, [esi + 24] movq mm5, [esi + 32] movq mm6, [esi + 40] movq mm7, [esi + 48] movq mm0, [esi + 56] movntq [edi], mm1 ; write to u_out movntq [edi + 8], mm2 movntq [edi + 16], mm3 movntq [edi + 24], mm4 movntq [edi + 32], mm5 movntq [edi + 40], mm6 movntq [edi + 48], mm7 movntq [edi + 56], mm0 add esi, 64 add edi, 64 dec ecx jnz .v_inner_loop dec ebp jz .v_outer_loop .v_remainder_loop: movq mm1, [esi] ; read from src movntq [edi], mm1 ; write to y_out add esi, 8 add edi, 8 dec ebp jnz .v_remainder_loop .v_outer_loop: mov ebp, [remainder] mov ecx, edx add edi, ebx dec eax jnz .v_inner_loop pop ebp pop edi pop esi pop ebx emms ret ; Attention: This code assumes that width is a multiple of 16 ;;void yuv_to_yv12_mmx(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out, uint8_t *src, ;; int width, int height, int stride); cglobal yuv_to_yv12_mmx yuv_to_yv12_mmx: push ebx push esi push edi push ebp mov eax, [esp + 40] ; height -> eax mov ebx, [esp + 44] ; stride -> ebx mov esi, [esp + 32] ; src -> esi mov edi, [esp + 20] ; y_out -> edi mov ecx, [esp + 36] ; width -> ecx sub ebx, ecx ; stride - width -> ebx mov edx, ecx mov ebp, ecx shr edx, 6 mov ecx, edx ; 64 bytes copied per iteration shl edx, 6 sub ebp, edx ; remainder -> ebp shr ebp, 4 ; 16 bytes per iteration add ebp, 1 mov [remainder], ebp mov edx, ecx .y_inner_loop: movq mm1, [esi] ; read from src movq mm2, [esi + 8] movq mm3, [esi + 16] movq mm4, [esi + 24] movq mm5, [esi + 32] movq mm6, [esi + 40] movq mm7, [esi + 48] movq mm0, [esi + 56] movq [edi], mm1 ; write to y_out movq [edi + 8], mm2 movq [edi + 16], mm3 movq [edi + 24], mm4 movq [edi + 32], mm5 movq [edi + 40], mm6 movq [edi + 48], mm7 movq [edi + 56], mm0 add esi, 64 add edi, 64 dec ecx jnz .y_inner_loop dec ebp jz .y_outer_loop .y_remainder_loop: movq mm1, [esi] ; read from src movq mm2, [esi + 8] movq [edi], mm1 ; write to y_out movq [edi + 8], mm2 add esi, 16 add edi, 16 dec ebp jnz .y_remainder_loop .y_outer_loop: mov ebp, [remainder] mov ecx, edx add edi, ebx dec eax jnz near .y_inner_loop mov eax, [esp + 40] ; height -> eax mov ebx, [esp + 44] ; stride -> ebx mov ecx, [esp + 36] ; width -> ecx mov edi, [esp + 24] ; u_out -> edi shr ecx, 1 ; width / 2 -> ecx shr ebx, 1 ; stride / 2 -> ebx shr eax, 1 ; height / 2 -> eax sub ebx, ecx ; stride / 2 - width / 2 -> ebx mov edx, ecx mov ebp, ecx shr edx, 6 mov ecx, edx ; 64 bytes copied per iteration shl edx, 6 sub ebp, edx ; remainder -> ebp shr ebp, 3 ; 8 bytes per iteration add ebp, 1 mov [remainder], ebp mov edx, ecx .u_inner_loop: movq mm1, [esi] ; read from src movq mm2, [esi + 8] movq mm3, [esi + 16] movq mm4, [esi + 24] movq mm5, [esi + 32] movq mm6, [esi + 40] movq mm7, [esi + 48] movq mm0, [esi + 56] movq [edi], mm1 ; write to u_out movq [edi + 8], mm2 movq [edi + 16], mm3 movq [edi + 24], mm4 movq [edi + 32], mm5 movq [edi + 40], mm6 movq [edi + 48], mm7 movq [edi + 56], mm0 add esi, 64 add edi, 64 dec ecx jnz .u_inner_loop dec ebp jz .u_outer_loop .u_remainder_loop: movq mm1, [esi] ; read from src movq [edi], mm1 ; write to y_out add esi, 8 add edi, 8 dec ebp jnz .u_remainder_loop .u_outer_loop: mov ebp, [remainder] mov ecx, edx add edi, ebx dec eax jnz .u_inner_loop mov eax, [esp + 40] ; height -> eax mov ecx, [esp + 36] ; width -> ecx mov edi, [esp + 28] ; v_out -> edi shr ecx, 1 ; width / 2 -> ecx shr eax, 1 ; height / 2 -> eax mov edx, ecx mov ebp, ecx shr edx, 6 mov ecx, edx ; 64 bytes copied per iteration shl edx, 6 sub ebp, edx ; remainder -> ebp shr ebp, 3 ; 8 bytes per iteration add ebp, 1 mov [remainder], ebp mov edx, ecx .v_inner_loop: movq mm1, [esi] ; read from src movq mm2, [esi + 8] movq mm3, [esi + 16] movq mm4, [esi + 24] movq mm5, [esi + 32] movq mm6, [esi + 40] movq mm7, [esi + 48] movq mm0, [esi + 56] movq [edi], mm1 ; write to u_out movq [edi + 8], mm2 movq [edi + 16], mm3 movq [edi + 24], mm4 movq [edi + 32], mm5 movq [edi + 40], mm6 movq [edi + 48], mm7 movq [edi + 56], mm0 add esi, 64 add edi, 64 dec ecx jnz .v_inner_loop dec ebp jz .v_outer_loop .v_remainder_loop: movq mm1, [esi] ; read from src movq [edi], mm1 ; write to y_out add esi, 8 add edi, 8 dec ebp jnz .v_remainder_loop .v_outer_loop: mov ebp, [remainder] mov ecx, edx add edi, ebx dec eax jnz .v_inner_loop pop ebp pop edi pop esi pop ebx emms retxvid_20020412/xvidcore/src/image/x86_asm/yv12_to_rgb24_mmx.asm0100644000100600001440000002652507442022641023200 0ustar michaelusers;/****************************************************************************** ; * * ; * This file is part of XviD, a free MPEG-4 video encoder/decoder * ; * * ; * XviD is an implementation of a part of one or more MPEG-4 Video tools * ; * as specified in ISO/IEC 14496-2 standard. Those intending to use this * ; * software module in hardware or software products are advised that its * ; * use may infringe existing patents or copyrights, and any such use * ; * would be at such party's own risk. The original developer of this * ; * software module and his/her company, and subsequent editors and their * ; * companies, will have no liability for use of this software or * ; * modifications or derivatives thereof. * ; * * ; * XviD is free software; you can redistribute it and/or modify it * ; * under the terms of the GNU General Public License as published by * ; * the Free Software Foundation; either version 2 of the License, or * ; * (at your option) any later version. * ; * * ; * XviD is distributed in the hope that it will be useful, but * ; * WITHOUT ANY WARRANTY; without even the implied warranty of * ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ; * GNU General Public License for more details. * ; * * ; * You should have received a copy of the GNU General Public License * ; * along with this program; if not, write to the Free Software * ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * yuv_to_rgb24.asm, MMX optimized color conversion * ; * * ; * Copyright (C) 2001 - Michael Militzer , * ; * * ; * For more information visit the XviD homepage: http://www.xvid.org * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * Revision history: * ; * * ; * 13.12.2001 initial version (Isibaar) * ; * * ; ******************************************************************************/ ; //NOTE: In contrary to the c implementation this code does the conversion ; using direct calculations. Input data width must be a multiple of 8 ; and height must be even. ; This implementation is less precise than the c version but is ; more than twice as fast :-) bits 32 %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro %define SCALEBITS 6 ALIGN 16 section .data TEMP_Y1 dd 0,0 TEMP_Y2 dd 0,0 TEMP_G1 dd 0,0 TEMP_G2 dd 0,0 TEMP_B1 dd 0,0 TEMP_B2 dd 0,0 y_dif dd 0 dst_dif dd 0 uv_dif dd 0 height dd 0 width_8 dd 0 height_2 dd 0 Y_SUB dw 16, 16, 16, 16 U_SUB dw 128, 128, 128, 128 V_SUB dw 128, 128, 128, 128 Y_MUL dw 74, 74, 74, 74 UG_MUL dw 25, 25, 25, 25 VG_MUL dw 52, 52, 52, 52 UB_MUL dw 129, 129, 129, 129 VR_MUL dw 102, 102, 102, 102 section .text ;void yv12_to_rgb24_mmx(uint8_t *dst, int dst_stride, ; uint8_t *y_src, uint8_t *u_src, uint8_t * v_src, ; int y_stride, int uv_stride, ; int width, int height) cglobal yv12_to_rgb24_mmx yv12_to_rgb24_mmx: push ebx push esi push edi push ebp mov eax, [esp + 52] ; height -> eax cmp eax, 0x00 jge near dont_flip ; flip? neg eax mov [height], eax mov esi, [esp + 48] ; width -> esi mov ebp, [esp + 40] ; y_stride -> ebp mov ebx, ebp shl ebx, 1 ; 2 * y_stride -> ebx neg ebx sub ebx, esi ; y_dif -> eax mov [y_dif], ebx sub eax, 1 ; height - 1 -> eax mul ebp ; (height - 1) * y_stride -> ebp mov ecx, eax mov eax, [esp + 28] ; y_src -> eax add eax, ecx ; y_src -> eax mov ebx, eax sub ebx, ebp ; y_src2 -> ebx mov ecx, [esp + 24] ; dst_stride -> ecx mov edx, ecx add ecx, edx shl edx, 2 add ecx, edx ; 6 * dst_stride -> ecx mov edx, ecx sub ecx, esi shl esi, 1 sub ecx, esi ; 6 * dst_stride - 3 * width -> ecx mov [dst_dif], ecx mov esi, [esp + 20] ; dst -> esi mov edi, esi shr edx, 1 add edi, edx ; dst2 -> edi mov ebp, [esp + 48] ; width -> ebp mov ecx, ebp ; width -> ecx shr ecx, 1 shr ebp, 3 ; width / 8 -> ebp mov [width_8], ebp mov ebp, [esp + 44] ; uv_stride -> ebp mov edx, ebp neg edx sub edx, ecx mov [uv_dif], edx mov edx, ebp mov ebp, eax mov eax, [height] ; height -> eax shr eax, 1 ; height / 2 -> eax mov ecx, [esp + 32] ; u_src -> ecx sub eax, 1 mul edx add ecx, eax mov edx, [esp + 36] ; v_src -> edx add edx, eax mov eax, ebp mov ebp, [height] ; height -> ebp shr ebp, 1 ; height / 2 -> ebp pxor mm7, mm7 ; clear mm7 jmp y_loop dont_flip: mov esi, [esp + 48] ; width -> esi mov ebp, [esp + 40] ; y_stride -> ebp mov ebx, ebp shl ebx, 1 ; 2 * y_stride -> ebx sub ebx, esi ; y_dif -> ebx mov [y_dif], ebx mov eax, [esp + 28] ; y_src -> eax mov ebx, eax add ebx, ebp ; y_src2 -> ebp mov ecx, [esp + 24] ; dst_stride -> ecx mov edx, ecx add ecx, edx shl edx, 2 add ecx, edx ; 6 * dst_stride -> ecx mov edx, ecx sub ecx, esi shl esi, 1 sub ecx, esi ; 6 * dst_stride - 3 * width -> ecx mov [dst_dif], ecx mov esi, [esp + 20] ; dst -> esi mov edi, esi shr edx, 1 add edi, edx ; dst2 -> edi mov ebp, [esp + 48] ; width -> ebp mov ecx, ebp ; width -> ecx shr ecx, 1 shr ebp, 3 ; width / 8 -> ebp mov [width_8], ebp mov ebp, [esp + 44] ; uv_stride -> ebp sub ebp, ecx mov [uv_dif], ebp mov ecx, [esp + 32] ; u_src -> ecx mov edx, [esp + 36] ; v_src -> edx mov ebp, [esp + 52] ; height -> ebp shr ebp, 1 ; height / 2 -> ebp pxor mm7, mm7 y_loop: mov [height_2], ebp mov ebp, [width_8] x_loop: movd mm2, [ecx] movd mm3, [edx] punpcklbw mm2, mm7 ; u3u2u1u0 -> mm2 punpcklbw mm3, mm7 ; v3v2v1v0 -> mm3 psubsw mm2, [U_SUB] ; U - 128 psubsw mm3, [V_SUB] ; V - 128 movq mm4, mm2 movq mm5, mm3 pmullw mm2, [UG_MUL] pmullw mm3, [VG_MUL] movq mm6, mm2 ; u3u2u1u0 -> mm6 punpckhwd mm2, mm2 ; u3u3u2u2 -> mm2 punpcklwd mm6, mm6 ; u1u1u0u0 -> mm6 pmullw mm4, [UB_MUL] ; B_ADD -> mm4 movq mm0, mm3 punpckhwd mm3, mm3 ; v3v3v2v2 -> mm2 punpcklwd mm0, mm0 ; v1v1v0v0 -> mm6 paddsw mm2, mm3 paddsw mm6, mm0 pmullw mm5, [VR_MUL] ; R_ADD -> mm5 movq mm0, [eax] ; y7y6y5y4y3y2y1y0 -> mm0 movq mm1, mm0 punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1 punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0 psubsw mm0, [Y_SUB] ; Y - Y_SUB psubsw mm1, [Y_SUB] ; Y - Y_SUB pmullw mm1, [Y_MUL] pmullw mm0, [Y_MUL] movq [TEMP_Y2], mm1 ; y7y6y5y4 -> mm3 movq [TEMP_Y1], mm0 ; y3y2y1y0 -> mm7 psubsw mm1, mm2 ; g7g6g5g4 -> mm1 psubsw mm0, mm6 ; g3g2g1g0 -> mm0 psraw mm1, SCALEBITS psraw mm0, SCALEBITS packuswb mm0, mm1 ;g7g6g5g4g3g2g1g0 -> mm0 movq [TEMP_G1], mm0 movq mm0, [ebx] ; y7y6y5y4y3y2y1y0 -> mm0 movq mm1, mm0 punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1 punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0 psubsw mm0, [Y_SUB] ; Y - Y_SUB psubsw mm1, [Y_SUB] ; Y - Y_SUB pmullw mm1, [Y_MUL] pmullw mm0, [Y_MUL] movq mm3, mm1 psubsw mm1, mm2 ; g7g6g5g4 -> mm1 movq mm2, mm0 psubsw mm0, mm6 ; g3g2g1g0 -> mm0 psraw mm1, SCALEBITS psraw mm0, SCALEBITS packuswb mm0, mm1 ; g7g6g5g4g3g2g1g0 -> mm0 movq [TEMP_G2], mm0 movq mm0, mm4 punpckhwd mm4, mm4 ; u3u3u2u2 -> mm2 punpcklwd mm0, mm0 ; u1u1u0u0 -> mm6 movq mm1, mm3 ; y7y6y5y4 -> mm1 paddsw mm3, mm4 ; b7b6b5b4 -> mm3 movq mm7, mm2 ; y3y2y1y0 -> mm7 paddsw mm2, mm0 ; b3b2b1b0 -> mm2 psraw mm3, SCALEBITS psraw mm2, SCALEBITS packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2 movq [TEMP_B2], mm2 movq mm3, [TEMP_Y2] movq mm2, [TEMP_Y1] movq mm6, mm3 ; TEMP_Y2 -> mm6 paddsw mm3, mm4 ; b7b6b5b4 -> mm3 movq mm4, mm2 ; TEMP_Y1 -> mm4 paddsw mm2, mm0 ; b3b2b1b0 -> mm2 psraw mm3, SCALEBITS psraw mm2, SCALEBITS packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2 movq [TEMP_B1], mm2 movq mm0, mm5 punpckhwd mm5, mm5 ; v3v3v2v2 -> mm5 punpcklwd mm0, mm0 ; v1v1v0v0 -> mm0 paddsw mm1, mm5 ; r7r6r5r4 -> mm1 paddsw mm7, mm0 ; r3r2r1r0 -> mm7 psraw mm1, SCALEBITS psraw mm7, SCALEBITS packuswb mm7, mm1 ; r7r6r5r4r3r2r1r0 -> mm7 (TEMP_R2) paddsw mm6, mm5 ; r7r6r5r4 -> mm6 paddsw mm4, mm0 ; r3r2r1r0 -> mm4 psraw mm6, SCALEBITS psraw mm4, SCALEBITS packuswb mm4, mm6 ; r7r6r5r4r3r2r1r0 -> mm4 (TEMP_R1) movq mm0, [TEMP_B1] movq mm1, [TEMP_G1] movq mm6, mm7 movq mm2, mm0 punpcklbw mm2, mm4 ; r3b3r2b2r1b1r0b0 -> mm2 punpckhbw mm0, mm4 ; r7b7r6b6r5b5r4b4 -> mm0 pxor mm7, mm7 movq mm3, mm1 punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1 punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3 movq mm4, mm2 punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2 punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4 movq mm5, mm0 punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0 punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5 movd [esi], mm2 psrlq mm2, 32 movd [esi + 3], mm2 movd [esi + 6], mm4 psrlq mm4, 32 movd [esi + 9], mm4 movd [esi + 12], mm0 psrlq mm0, 32 movd [esi + 15], mm0 movd [esi + 18], mm5 psrlq mm5, 32 movd [esi + 21], mm5 movq mm0, [TEMP_B2] movq mm1, [TEMP_G2] movq mm2, mm0 punpcklbw mm2, mm6 ; r3b3r2b2r1b1r0b0 -> mm2 punpckhbw mm0, mm6 ; r7b7r6b6r5b5r4b4 -> mm0 movq mm3, mm1 punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1 punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3 movq mm4, mm2 punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2 punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4 movq mm5, mm0 punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0 punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5 movd [edi], mm2 psrlq mm2, 32 movd [edi + 3], mm2 movd [edi + 6], mm4 psrlq mm4, 32 movd [edi + 9], mm4 movd [edi + 12], mm0 psrlq mm0, 32 movd [edi + 15], mm0 movd [edi + 18], mm5 psrlq mm5, 32 movd [edi + 21], mm5 add esi, 24 add edi, 24 add eax, 8 add ebx, 8 add ecx, 4 add edx, 4 dec ebp jnz near x_loop add esi, [dst_dif] add edi, [dst_dif] add eax, [y_dif] add ebx, [y_dif] add ecx, [uv_dif] add edx, [uv_dif] mov ebp, [height_2] dec ebp jnz near y_loop emms pop ebp pop edi pop esi pop ebx ret xvid_20020412/xvidcore/src/image/x86_asm/yuyv_to_yv12_mmx.asm0100644000100600001440000001633207442022640023266 0ustar michaelusers;/************************************************************************** ; * ; * XVID MPEG-4 VIDEO CODEC ; * mmx yuyv/uyvy to yuv planar ; * ; * This program is an implementation of a part of one or more MPEG-4 ; * Video tools as specified in ISO/IEC 14496-2 standard. Those intending ; * to use this software module in hardware or software products are ; * advised that its use may infringe existing patents or copyrights, and ; * any such use would be at such party's own risk. The original ; * developer of this software module and his/her company, and subsequent ; * editors and their companies, will have no liability for use of this ; * software or modifications or derivatives thereof. ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * This program is distributed in the hope that it will be useful, ; * but WITHOUT ANY WARRANTY; without even the implied warranty of ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; * GNU General Public License for more details. ; * ; * You should have received a copy of the GNU General Public License ; * along with this program; if not, write to the Free Software ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; * ; *************************************************************************/ ;/************************************************************************** ; * ; * History: ; * ; * 30.11.2001 initial version; (c)2001 peter ross ; * ; *************************************************************************/ bits 32 section .data %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro align 16 section .data ;=========================================================================== ; masks for extracting yuv components ;=========================================================================== ; y u y v y u y v mask1 db 0xff, 0, 0xff, 0, 0xff, 0, 0xff, 0 mask2 db 0, 0xff, 0, 0xff, 0, 0xff, 0, 0xff section .text ;=========================================================================== ; ; void yuyv_to_yv12_mmx(uint8_t * const y_out, ; uint8_t * const u_out, ; uint8_t * const v_out, ; const uint8_t * const src, ; const uint32_t width, ; const uint32_t height, ; const uint32_t stride); ; ; width must be multiple of 8 ; does not flip ; ~30% faster than plain c ; ;=========================================================================== align 16 cglobal yuyv_to_yv12_mmx yuyv_to_yv12_mmx push ebx push ecx push esi push edi push ebp ; STACK BASE = 20 ; some global consants mov ecx, [esp + 20 + 20] ; width mov eax, [esp + 20 + 28] ; stride sub eax, ecx ; eax = stride - width mov edx, eax add edx, [esp + 20 + 28] ; edx = y_dif + stride push edx ; [esp + 12] = y_dif shr eax, 1 push eax ; [esp + 8] = uv_dif shr ecx, 3 push ecx ; [esp + 4] = width/8 sub esp, 4 ; [esp + 0] = tmp_height_counter ; STACK_BASE = 36 movq mm6, [mask1] movq mm7, [mask2] mov edi, [esp + 36 + 4] ; y_out mov ebx, [esp + 36 + 8] ; u_out mov edx, [esp + 36 + 12] ; v_out mov esi, [esp + 36 + 16] ; src mov eax, [esp + 36 + 20] mov ebp, [esp + 36 + 24] mov ecx, [esp + 36 + 28] ; ecx = stride shr ebp, 1 ; ebp = height /= 2 add eax, eax ; eax = 2 * width .yloop mov [esp], ebp mov ebp, [esp + 4] ; width/8 .xloop movq mm2, [esi] ; y 1st row movq mm3, [esi + 8] movq mm0, mm2 movq mm1, mm3 pand mm2, mm6 ; mask1 pand mm3, mm6 ; mask1 pand mm0, mm7 ; mask2 pand mm1, mm7 ; mask2 packuswb mm2, mm3 psrlq mm0, 8 psrlq mm1, 8 movq [edi], mm2 movq mm4, [esi + eax] ; y 2nd row movq mm5, [esi + eax + 8] movq mm2, mm4 movq mm3, mm5 pand mm4, mm6 ; mask1 pand mm5, mm6 ; mask1 pand mm2, mm7 ; mask2 pand mm3, mm7 ; mask2 packuswb mm4, mm5 psrlq mm2, 8 psrlq mm3, 8 movq [edi + ecx], mm4 paddw mm0, mm2 ; uv avg 1st & 2nd paddw mm1, mm3 psrlw mm0, 1 psrlw mm1, 1 packuswb mm0, mm1 movq mm2, mm0 pand mm0, mm6 ; mask1 pand mm2, mm7 ; mask2 packuswb mm0, mm0 psrlq mm2, 8 movd [ebx], mm0 packuswb mm2, mm2 movd [edx], mm2 add esi, 16 add edi, 8 add ebx, 4 add edx, 4 dec ebp jnz near .xloop mov ebp, [esp] add esi, eax ; += width2 add edi, [esp + 12] ; += y_dif + stride add ebx, [esp + 8] ; += uv_dif add edx, [esp + 8] ; += uv_dif dec ebp jnz near .yloop emms add esp, 16 pop ebp pop edi pop esi pop ecx pop ebx ret ;=========================================================================== ; ; void uyvy_to_yv12_mmx(uint8_t * const y_out, ; uint8_t * const u_out, ; uint8_t * const v_out, ; const uint8_t * const src, ; const uint32_t width, ; const uint32_t height, ; const uint32_t stride); ; ; width must be multiple of 8 ; does not flip ; ~30% faster than plain c ; ;=========================================================================== align 16 cglobal uyvy_to_yv12_mmx uyvy_to_yv12_mmx push ebx push ecx push esi push edi push ebp ; STACK BASE = 20 ; some global consants mov ecx, [esp + 20 + 20] ; width mov eax, [esp + 20 + 28] ; stride sub eax, ecx ; eax = stride - width mov edx, eax add edx, [esp + 20 + 28] ; edx = y_dif + stride push edx ; [esp + 12] = y_dif shr eax, 1 push eax ; [esp + 8] = uv_dif shr ecx, 3 push ecx ; [esp + 4] = width/8 sub esp, 4 ; [esp + 0] = tmp_height_counter ; STACK_BASE = 36 movq mm6, [mask1] movq mm7, [mask2] mov edi, [esp + 36 + 4] ; y_out mov ebx, [esp + 36 + 8] ; u_out mov edx, [esp + 36 + 12] ; v_out mov esi, [esp + 36 + 16] ; src mov eax, [esp + 36 + 20] mov ebp, [esp + 36 + 24] mov ecx, [esp + 36 + 28] ; ecx = stride shr ebp, 1 ; ebp = height /= 2 add eax, eax ; eax = 2 * width .yloop mov [esp], ebp mov ebp, [esp + 4] ; width/8 .xloop movq mm2, [esi] ; y 1st row movq mm3, [esi + 8] movq mm0, mm2 movq mm1, mm3 pand mm2, mm7 ; mask2 pand mm3, mm7 ; mask2 psrlq mm2, 8 psrlq mm3, 8 pand mm0, mm6 ; mask1 pand mm1, mm6 ; mask1 packuswb mm2, mm3 movq [edi], mm2 movq mm4, [esi + eax] ; y 2nd row movq mm5, [esi + eax + 8] movq mm2, mm4 movq mm3, mm5 pand mm4, mm7 ; mask2 pand mm5, mm7 ; mask2 psrlq mm4, 8 psrlq mm5, 8 pand mm2, mm6 ; mask1 pand mm3, mm6 ; mask1 packuswb mm4, mm5 movq [edi + ecx], mm4 paddw mm0, mm2 ; uv avg 1st & 2nd paddw mm1, mm3 psrlw mm0, 1 psrlw mm1, 1 packuswb mm0, mm1 movq mm2, mm0 pand mm0, mm6 ; mask1 pand mm2, mm7 ; mask2 packuswb mm0, mm0 psrlq mm2, 8 movd [ebx], mm0 packuswb mm2, mm2 movd [edx], mm2 add esi, 16 add edi, 8 add ebx, 4 add edx, 4 dec ebp jnz near .xloop mov ebp, [esp] add esi, eax ; += width2 add edi, [esp + 12] ; += y_dif + stride add ebx, [esp + 8] ; += uv_dif add edx, [esp + 8] ; += uv_dif dec ebp jnz near .yloop emms add esp, 16 pop ebp pop edi pop esi pop ecx pop ebx ret xvid_20020412/xvidcore/src/image/x86_asm/yv12_to_rgb32_mmx.asm0100644000100600001440000002570407442022642023176 0ustar michaelusers;/****************************************************************************** ; * * ; * This file is part of XviD, a free MPEG-4 video encoder/decoder * ; * * ; * XviD is an implementation of a part of one or more MPEG-4 Video tools * ; * as specified in ISO/IEC 14496-2 standard. Those intending to use this * ; * software module in hardware or software products are advised that its * ; * use may infringe existing patents or copyrights, and any such use * ; * would be at such party's own risk. The original developer of this * ; * software module and his/her company, and subsequent editors and their * ; * companies, will have no liability for use of this software or * ; * modifications or derivatives thereof. * ; * * ; * XviD is free software; you can redistribute it and/or modify it * ; * under the terms of the GNU General Public License as published by * ; * the Free Software Foundation; either version 2 of the License, or * ; * (at your option) any later version. * ; * * ; * XviD is distributed in the hope that it will be useful, but * ; * WITHOUT ANY WARRANTY; without even the implied warranty of * ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ; * GNU General Public License for more details. * ; * * ; * You should have received a copy of the GNU General Public License * ; * along with this program; if not, write to the Free Software * ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * yuv_to_rgb32.asm, MMX optimized color conversion * ; * * ; * Copyright (C) 2001 - Michael Militzer , * ; * * ; * For more information visit the XviD homepage: http://www.xvid.org * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * Revision history: * ; * * ; * 13.12.2001 initial version (Isibaar) * ; * * ; ******************************************************************************/ ; //NOTE: In contrary to the c implementation this code does the conversion ; using direct calculations. Input data width must be a multiple of 8 ; and height must be even. ; This implementation is less precise than the c version but is ; more than twice as fast :-) bits 32 %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro %define SCALEBITS 6 ALIGN 16 section .data TEMP_Y1 dd 0,0 TEMP_Y2 dd 0,0 TEMP_G1 dd 0,0 TEMP_G2 dd 0,0 TEMP_B1 dd 0,0 TEMP_B2 dd 0,0 y_dif dd 0 dst_dif dd 0 uv_dif dd 0 height dd 0 width_8 dd 0 height_2 dd 0 Y_SUB dw 16, 16, 16, 16 U_SUB dw 128, 128, 128, 128 V_SUB dw 128, 128, 128, 128 Y_MUL dw 74, 74, 74, 74 UG_MUL dw 25, 25, 25, 25 VG_MUL dw 52, 52, 52, 52 UB_MUL dw 129, 129, 129, 129 VR_MUL dw 102, 102, 102, 102 section .text ;void yv12_to_rgb32_mmx(uint8_t *dst, int dst_stride, ; uint8_t *y_src, uint8_t *u_src, uint8_t * v_src, ; int y_stride, int uv_stride, ; int width, int height) cglobal yv12_to_rgb32_mmx yv12_to_rgb32_mmx: push ebx push esi push edi push ebp mov eax, [esp + 52] ; height -> eax cmp eax, 0x00 jge near dont_flip ; flip? neg eax ; neg height mov [height], eax mov esi, [esp + 48] ; width -> esi mov ebp, [esp + 40] ; y_stride -> ebp mov ebx, ebp shl ebx, 1 ; 2 * y_stride -> ebx neg ebx sub ebx, esi ; y_dif -> eax mov [y_dif], ebx sub eax, 1 ; height - 1 -> eax mul ebp ; (height - 1) * y_stride -> ebp mov ecx, eax mov eax, [esp + 28] ; y_src -> eax add eax, ecx ; y_src -> eax mov ebx, eax sub ebx, ebp ; y_src2 -> ebx mov ecx, [esp + 24] ; dst_stride -> ecx mov edx, ecx shl edx, 3 mov ecx, edx ; 8 * dst_stride -> ecx shl esi, 2 sub ecx, esi ; 8 * dst_stride - 4 * width -> ecx mov [dst_dif], ecx mov esi, [esp + 20] ; dst -> esi mov edi, esi shr edx, 1 add edi, edx ; dst2 -> edi mov ebp, [esp + 48] ; width -> ebp mov ecx, ebp ; width -> ecx shr ecx, 1 shr ebp, 3 ; width / 8 -> ebp mov [width_8], ebp mov ebp, [esp + 44] ; uv_stride -> ebp mov edx, ebp neg edx sub edx, ecx mov [uv_dif], edx mov edx, ebp mov ebp, eax mov eax, [height] ; height -> eax shr eax, 1 ; height / 2 -> eax mov ecx, [esp + 32] ; u_src -> ecx sub eax, 1 mul edx add ecx, eax mov edx, [esp + 36] ; v_src -> edx add edx, eax mov eax, ebp mov ebp, [height] ; height -> ebp shr ebp, 1 ; height / 2 -> ebp pxor mm7, mm7 jmp y_loop dont_flip: mov esi, [esp + 48] ; width -> esi mov ebp, [esp + 40] ; y_stride -> ebp mov ebx, ebp shl ebx, 1 ; 2 * y_stride -> ebx sub ebx, esi ; y_dif -> ebx mov [y_dif], ebx mov eax, [esp + 28] ; y_src -> eax mov ebx, eax add ebx, ebp ; y_src2 -> ebp mov ecx, [esp + 24] ; dst_stride -> ecx shl ecx, 3 mov edx, ecx ; 8 * dst_stride -> edx shl esi, 2 sub ecx, esi ; 8 * dst_stride - 4 * width -> ecx mov [dst_dif], ecx mov esi, [esp + 20] ; dst -> esi mov edi, esi shr edx, 1 add edi, edx ; dst2 -> edi mov ebp, [esp + 48] ; width -> ebp mov ecx, ebp ; width -> ecx shr ecx, 1 shr ebp, 3 ; width / 8 -> ebp mov [width_8], ebp mov ebp, [esp + 44] ; uv_stride -> ebp sub ebp, ecx mov [uv_dif], ebp mov ecx, [esp + 32] ; u_src -> ecx mov edx, [esp + 36] ; v_src -> edx mov ebp, [esp + 52] ; height -> ebp shr ebp, 1 ; height / 2 -> ebp pxor mm7, mm7 y_loop: mov [height_2], ebp mov ebp, [width_8] x_loop: movd mm2, [ecx] movd mm3, [edx] punpcklbw mm2, mm7 ; u3u2u1u0 -> mm2 punpcklbw mm3, mm7 ; v3v2v1v0 -> mm3 psubsw mm2, [U_SUB] ; U - 128 psubsw mm3, [V_SUB] ; V - 128 movq mm4, mm2 movq mm5, mm3 pmullw mm2, [UG_MUL] pmullw mm3, [VG_MUL] movq mm6, mm2 ; u3u2u1u0 -> mm6 punpckhwd mm2, mm2 ; u3u3u2u2 -> mm2 punpcklwd mm6, mm6 ; u1u1u0u0 -> mm6 pmullw mm4, [UB_MUL] ; B_ADD -> mm4 movq mm0, mm3 punpckhwd mm3, mm3 ; v3v3v2v2 -> mm2 punpcklwd mm0, mm0 ; v1v1v0v0 -> mm6 paddsw mm2, mm3 paddsw mm6, mm0 pmullw mm5, [VR_MUL] ; R_ADD -> mm5 movq mm0, [eax] ; y7y6y5y4y3y2y1y0 -> mm0 movq mm1, mm0 punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1 punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0 psubsw mm0, [Y_SUB] ; Y - Y_SUB psubsw mm1, [Y_SUB] ; Y - Y_SUB pmullw mm1, [Y_MUL] pmullw mm0, [Y_MUL] movq [TEMP_Y2], mm1 ; y7y6y5y4 -> mm3 movq [TEMP_Y1], mm0 ; y3y2y1y0 -> mm7 psubsw mm1, mm2 ; g7g6g5g4 -> mm1 psubsw mm0, mm6 ; g3g2g1g0 -> mm0 psraw mm1, SCALEBITS psraw mm0, SCALEBITS packuswb mm0, mm1 ;g7g6g5g4g3g2g1g0 -> mm0 movq [TEMP_G1], mm0 movq mm0, [ebx] ; y7y6y5y4y3y2y1y0 -> mm0 movq mm1, mm0 punpckhbw mm1, mm7 ; y7y6y5y4 -> mm1 punpcklbw mm0, mm7 ; y3y2y1y0 -> mm0 psubsw mm0, [Y_SUB] ; Y - Y_SUB psubsw mm1, [Y_SUB] ; Y - Y_SUB pmullw mm1, [Y_MUL] pmullw mm0, [Y_MUL] movq mm3, mm1 psubsw mm1, mm2 ; g7g6g5g4 -> mm1 movq mm2, mm0 psubsw mm0, mm6 ; g3g2g1g0 -> mm0 psraw mm1, SCALEBITS psraw mm0, SCALEBITS packuswb mm0, mm1 ; g7g6g5g4g3g2g1g0 -> mm0 movq [TEMP_G2], mm0 movq mm0, mm4 punpckhwd mm4, mm4 ; u3u3u2u2 -> mm2 punpcklwd mm0, mm0 ; u1u1u0u0 -> mm6 movq mm1, mm3 ; y7y6y5y4 -> mm1 paddsw mm3, mm4 ; b7b6b5b4 -> mm3 movq mm7, mm2 ; y3y2y1y0 -> mm7 paddsw mm2, mm0 ; b3b2b1b0 -> mm2 psraw mm3, SCALEBITS psraw mm2, SCALEBITS packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2 movq [TEMP_B2], mm2 movq mm3, [TEMP_Y2] movq mm2, [TEMP_Y1] movq mm6, mm3 ; TEMP_Y2 -> mm6 paddsw mm3, mm4 ; b7b6b5b4 -> mm3 movq mm4, mm2 ; TEMP_Y1 -> mm4 paddsw mm2, mm0 ; b3b2b1b0 -> mm2 psraw mm3, SCALEBITS psraw mm2, SCALEBITS packuswb mm2, mm3 ; b7b6b5b4b3b2b1b0 -> mm2 movq [TEMP_B1], mm2 movq mm0, mm5 punpckhwd mm5, mm5 ; v3v3v2v2 -> mm5 punpcklwd mm0, mm0 ; v1v1v0v0 -> mm0 paddsw mm1, mm5 ; r7r6r5r4 -> mm1 paddsw mm7, mm0 ; r3r2r1r0 -> mm7 psraw mm1, SCALEBITS psraw mm7, SCALEBITS packuswb mm7, mm1 ; r7r6r5r4r3r2r1r0 -> mm7 (TEMP_R2) paddsw mm6, mm5 ; r7r6r5r4 -> mm6 paddsw mm4, mm0 ; r3r2r1r0 -> mm4 psraw mm6, SCALEBITS psraw mm4, SCALEBITS packuswb mm4, mm6 ; r7r6r5r4r3r2r1r0 -> mm4 (TEMP_R1) movq mm0, [TEMP_B1] movq mm1, [TEMP_G1] movq mm6, mm7 movq mm2, mm0 punpcklbw mm2, mm4 ; r3b3r2b2r1b1r0b0 -> mm2 punpckhbw mm0, mm4 ; r7b7r6b6r5b5r4b4 -> mm0 pxor mm7, mm7 movq mm3, mm1 punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1 punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3 movq mm4, mm2 punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2 punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4 movq mm5, mm0 punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0 punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5 movq [esi], mm2 movq [esi + 8], mm4 movq [esi + 16], mm0 movq [esi + 24], mm5 movq mm0, [TEMP_B2] movq mm1, [TEMP_G2] movq mm2, mm0 punpcklbw mm2, mm6 ; r3b3r2b2r1b1r0b0 -> mm2 punpckhbw mm0, mm6 ; r7b7r6b6r5b5r4b4 -> mm0 movq mm3, mm1 punpcklbw mm1, mm7 ; 0g30g20g10g0 -> mm1 punpckhbw mm3, mm7 ; 0g70g60g50g4 -> mm3 movq mm4, mm2 punpcklbw mm2, mm1 ; 0r1g1b10r0g0b0 -> mm2 punpckhbw mm4, mm1 ; 0r3g3b30r2g2b2 -> mm4 movq mm5, mm0 punpcklbw mm0, mm3 ; 0r5g5b50r4g4b4 -> mm0 punpckhbw mm5, mm3 ; 0r7g7b70r6g6b6 -> mm5 movq [edi], mm2 movq [edi + 8], mm4 movq [edi + 16], mm0 movq [edi + 24], mm5 add esi, 32 add edi, 32 add eax, 8 add ebx, 8 add ecx, 4 add edx, 4 dec ebp jnz near x_loop add esi, [dst_dif] add edi, [dst_dif] add eax, [y_dif] add ebx, [y_dif] add ecx, [uv_dif] add edx, [uv_dif] mov ebp, [height_2] dec ebp jnz near y_loop emms pop ebp pop edi pop esi pop ebx ret xvid_20020412/xvidcore/src/image/image.c0100644000100600001440000003447207455416310017257 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * image stuff * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 09.04.2002 PSNR calculations * 06.04.2002 removed interlaced edging from U,V blocks (as per spec) * 26.03.2002 interlacing support (field-based edging in set_edges) * 26.01.2002 rgb555, rgb565 * 07.01.2001 commented u,v interpolation (not required for uv-block-based) * 23.12.2001 removed #ifdefs, added function pointers + init_common() * 22.12.2001 cpu #ifdefs * 19.12.2001 image_dump(); useful for debugging * 6.12.2001 inital version; (c)2001 peter ross * *************************************************************************/ #include #include // memcpy, memset #include #include "../portab.h" #include "../xvid.h" // XVID_CSP_XXX's #include "image.h" #include "colorspace.h" #include "interpolate8x8.h" #include "../divx4.h" #include "../utils/mem_align.h" #define SAFETY 64 #define EDGE_SIZE2 (EDGE_SIZE/2) int32_t image_create(IMAGE * image, uint32_t edged_width, uint32_t edged_height) { const uint32_t edged_width2 = edged_width / 2; const uint32_t edged_height2 = edged_height / 2; uint32_t i; image->y = xvid_malloc(edged_width * (edged_height + 1) + SAFETY, CACHE_LINE); if (image->y == NULL) { return -1; } for (i=0;i < edged_width * edged_height + SAFETY;i++) { image->y[i]=0; } image->u = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE); if (image->u == NULL) { xvid_free(image->y); return -1; } image->v = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE); if (image->v == NULL) { xvid_free(image->u); xvid_free(image->y); return -1; } image->y += EDGE_SIZE * edged_width + EDGE_SIZE; image->u += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2; image->v += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2; return 0; } void image_destroy(IMAGE * image, uint32_t edged_width, uint32_t edged_height) { const uint32_t edged_width2 = edged_width / 2; if (image->y) { xvid_free(image->y - (EDGE_SIZE * edged_width + EDGE_SIZE) ); } if (image->u) { xvid_free(image->u - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2)); } if (image->v) { xvid_free(image->v - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2)); } } void image_swap(IMAGE * image1, IMAGE * image2) { uint8_t * tmp; tmp = image1->y; image1->y = image2->y; image2->y = tmp; tmp = image1->u; image1->u = image2->u; image2->u = tmp; tmp = image1->v; image1->v = image2->v; image2->v = tmp; } void image_copy(IMAGE *image1, IMAGE * image2, uint32_t edged_width, uint32_t height) { memcpy(image1->y, image2->y, edged_width * height); memcpy(image1->u, image2->u, edged_width * height / 4); memcpy(image1->v, image2->v, edged_width * height / 4); } void image_setedges(IMAGE * image, uint32_t edged_width, uint32_t edged_height, uint32_t width, uint32_t height, uint32_t interlacing) { const uint32_t edged_width2 = edged_width / 2; const uint32_t width2 = width / 2; uint32_t i; uint8_t * dst; uint8_t * src; dst = image->y - (EDGE_SIZE + EDGE_SIZE * edged_width); src = image->y; for (i = 0; i < EDGE_SIZE; i++) { // if interlacing, edges contain top-most data from each field if (interlacing && (i & 1)) { memset(dst, *(src + edged_width), EDGE_SIZE); memcpy(dst + EDGE_SIZE, src + edged_width, width); memset(dst + edged_width - EDGE_SIZE, *(src + edged_width + width - 1), EDGE_SIZE); } else { memset(dst, *src, EDGE_SIZE); memcpy(dst + EDGE_SIZE, src, width); memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), EDGE_SIZE); } dst += edged_width; } for (i = 0; i < height; i++) { memset(dst, *src, EDGE_SIZE); memset(dst + edged_width - EDGE_SIZE, src[width - 1], EDGE_SIZE); dst += edged_width; src += edged_width; } src -= edged_width; for (i = 0; i < EDGE_SIZE; i++) { // if interlacing, edges contain bottom-most data from each field if (interlacing && !(i & 1)) { memset(dst, *(src - edged_width), EDGE_SIZE); memcpy(dst + EDGE_SIZE, src - edged_width, width); memset(dst + edged_width - EDGE_SIZE, *(src - edged_width + width - 1), EDGE_SIZE); } else { memset(dst, *src, EDGE_SIZE); memcpy(dst + EDGE_SIZE, src, width); memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), EDGE_SIZE); } dst += edged_width; } //U dst = image->u - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2); src = image->u; for (i = 0; i < EDGE_SIZE2; i++) { memset(dst, *src, EDGE_SIZE2); memcpy(dst + EDGE_SIZE2, src, width2); memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1), EDGE_SIZE2); dst += edged_width2; } for (i = 0; i < height / 2; i++) { memset(dst, *src, EDGE_SIZE2); memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2); dst += edged_width2; src += edged_width2; } src -= edged_width2; for (i = 0; i < EDGE_SIZE2; i++) { memset(dst, *src, EDGE_SIZE2); memcpy(dst + EDGE_SIZE2, src, width2); memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1), EDGE_SIZE2); dst += edged_width2; } // V dst = image->v - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2); src = image->v; for (i = 0; i < EDGE_SIZE2; i++) { memset(dst, *src, EDGE_SIZE2); memcpy(dst + EDGE_SIZE2, src, width2); memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1), EDGE_SIZE2); dst += edged_width2; } for (i = 0; i < height / 2; i++) { memset(dst, *src, EDGE_SIZE2); memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2); dst += edged_width2; src += edged_width2; } src -= edged_width2; for (i = 0; i < EDGE_SIZE2; i++) { memset(dst, *src, EDGE_SIZE2); memcpy(dst + EDGE_SIZE2, src, width2); memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1), EDGE_SIZE2); dst += edged_width2; } } void image_interpolate(const IMAGE * refn, IMAGE * refh, IMAGE * refv, IMAGE * refhv, uint32_t edged_width, uint32_t edged_height, uint32_t rounding) { uint32_t offset; uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr; uint32_t x,y; uint32_t stride_add = 7 * edged_width; offset = EDGE_SIZE * (edged_width + 1); n_ptr = refn->y; h_ptr = refh->y; v_ptr = refv->y; hv_ptr = refhv->y; n_ptr -= offset; h_ptr -= offset; v_ptr -= offset; hv_ptr -= offset; for(y = 0; y < edged_height; y = y + 8) { for(x = 0; x < edged_width; x = x + 8) { interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding); interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding); interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding); n_ptr += 8; h_ptr += 8; v_ptr += 8; hv_ptr += 8; } h_ptr += stride_add; v_ptr += stride_add; hv_ptr += stride_add; n_ptr += stride_add; } /* interpolate_halfpel_h( refh->y - offset, refn->y - offset, edged_width, edged_height, rounding); interpolate_halfpel_v( refv->y - offset, refn->y - offset, edged_width, edged_height, rounding); interpolate_halfpel_hv( refhv->y - offset, refn->y - offset, edged_width, edged_height, rounding); */ /* uv-image-based compensation offset = EDGE_SIZE2 * (edged_width / 2 + 1); interpolate_halfpel_h( refh->u - offset, refn->u - offset, edged_width / 2, edged_height / 2, rounding); interpolate_halfpel_v( refv->u - offset, refn->u - offset, edged_width / 2, edged_height / 2, rounding); interpolate_halfpel_hv( refhv->u - offset, refn->u - offset, edged_width / 2, edged_height / 2, rounding); interpolate_halfpel_h( refh->v - offset, refn->v - offset, edged_width / 2, edged_height / 2, rounding); interpolate_halfpel_v( refv->v - offset, refn->v - offset, edged_width / 2, edged_height / 2, rounding); interpolate_halfpel_hv( refhv->v - offset, refn->v - offset, edged_width / 2, edged_height / 2, rounding); */ } int image_input(IMAGE * image, uint32_t width, int height, uint32_t edged_width, uint8_t * src, int csp) { /* if (csp & XVID_CSP_VFLIP) { height = -height; } */ switch(csp & ~XVID_CSP_VFLIP) { case XVID_CSP_RGB555 : rgb555_to_yv12(image->y, image->u, image->v, src, width, height, edged_width); return 0; case XVID_CSP_RGB565 : rgb565_to_yv12(image->y, image->u, image->v, src, width, height, edged_width); return 0; case XVID_CSP_RGB24 : rgb24_to_yv12(image->y, image->u, image->v, src, width, height, edged_width); return 0; case XVID_CSP_RGB32 : rgb32_to_yv12(image->y, image->u, image->v, src, width, height, edged_width); return 0; case XVID_CSP_I420 : yuv_to_yv12(image->y, image->u, image->v, src, width, height, edged_width); return 0; case XVID_CSP_YV12 : /* u/v swapped */ yuv_to_yv12(image->y, image->v, image->u, src, width, height, edged_width); return 0; case XVID_CSP_YUY2 : yuyv_to_yv12(image->y, image->u, image->v, src, width, height, edged_width); return 0; case XVID_CSP_YVYU : /* u/v swapped */ yuyv_to_yv12(image->y, image->v, image->u, src, width, height, edged_width); return 0; case XVID_CSP_UYVY : uyvy_to_yv12(image->y, image->u, image->v, src, width, height, edged_width); return 0; case XVID_CSP_NULL : break; } return -1; } int image_output(IMAGE * image, uint32_t width, int height, uint32_t edged_width, uint8_t * dst, uint32_t dst_stride, int csp) { if (csp & XVID_CSP_VFLIP) { height = -height; } switch(csp & ~XVID_CSP_VFLIP) { case XVID_CSP_RGB555 : yv12_to_rgb555(dst, dst_stride, image->y, image->u, image->v, edged_width, edged_width / 2, width, height); return 0; case XVID_CSP_RGB565 : yv12_to_rgb565(dst, dst_stride, image->y, image->u, image->v, edged_width, edged_width / 2, width, height); return 0; case XVID_CSP_RGB24 : yv12_to_rgb24(dst, dst_stride, image->y, image->u, image->v, edged_width, edged_width / 2, width, height); return 0; case XVID_CSP_RGB32 : yv12_to_rgb32(dst, dst_stride, image->y, image->u, image->v, edged_width, edged_width / 2, width, height); return 0; case XVID_CSP_I420 : yv12_to_yuv(dst, dst_stride, image->y, image->u, image->v, edged_width, edged_width / 2, width, height); return 0; case XVID_CSP_YV12 : // u,v swapped yv12_to_yuv(dst, dst_stride, image->y, image->v, image->u, edged_width, edged_width / 2, width, height); return 0; case XVID_CSP_YUY2 : yv12_to_yuyv(dst, dst_stride, image->y, image->u, image->v, edged_width, edged_width / 2, width, height); return 0; case XVID_CSP_YVYU : // u,v swapped yv12_to_yuyv(dst, dst_stride, image->y, image->v, image->u, edged_width, edged_width / 2, width, height); return 0; case XVID_CSP_UYVY : yv12_to_uyvy(dst, dst_stride, image->y, image->u, image->v, edged_width, edged_width / 2, width, height); return 0; case XVID_CSP_USER : ((DEC_PICTURE*)dst)->y = image->y; ((DEC_PICTURE*)dst)->u = image->u; ((DEC_PICTURE*)dst)->v = image->v; ((DEC_PICTURE*)dst)->stride_y = edged_width; ((DEC_PICTURE*)dst)->stride_uv = edged_width/2; return 0; case XVID_CSP_NULL : return 0; } return -1; } float image_psnr(IMAGE *orig_image, IMAGE *recon_image, uint16_t stride, uint16_t width, uint16_t height) { int32_t diff, x, y, quad = 0; uint8_t *orig = orig_image->y; uint8_t *recon = recon_image->y; float psnr_y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { diff = *(orig + x) - *(recon + x); quad += diff*diff; } orig += stride; recon += stride; } psnr_y = (float) quad / (float) (width * height); if (psnr_y) { psnr_y = (float) (255 * 255) / psnr_y; psnr_y = 10 * (float) log10 (psnr_y); } else psnr_y = (float) 99.99; return psnr_y; } #include #include int image_dump_pgm(uint8_t * bmp, uint32_t width, uint32_t height, char * filename) { FILE * f; char hdr[1024]; f = fopen(filename, "wb"); if ( f == NULL) { return -1; } sprintf(hdr, "P5\n#xvid\n%i %i\n255\n", width, height); fwrite(hdr, strlen(hdr), 1, f); fwrite(bmp, width, height, f); fclose(f); return 0; } /* dump image+edges to yuv pgm files */ int image_dump(IMAGE * image, uint32_t edged_width, uint32_t edged_height, char * path, int number) { char filename[1024]; sprintf(filename, "%s_%i_%c.pgm", path, number, 'y'); image_dump_pgm( image->y - (EDGE_SIZE * edged_width + EDGE_SIZE), edged_width, edged_height, filename); sprintf(filename, "%s_%i_%c.pgm", path, number, 'u'); image_dump_pgm( image->u - (EDGE_SIZE2 * edged_width / 2 + EDGE_SIZE2), edged_width / 2, edged_height / 2, filename); sprintf(filename, "%s_%i_%c.pgm", path, number, 'v'); image_dump_pgm( image->v - (EDGE_SIZE2 * edged_width / 2 + EDGE_SIZE2), edged_width / 2, edged_height / 2, filename); return 0; } xvid_20020412/xvidcore/src/image/image.h0100644000100600001440000000227007454567054017266 0ustar michaelusers#ifndef _IMAGE_H_ #define _IMAGE_H_ #include "../portab.h" #include "colorspace.h" #define EDGE_SIZE 32 typedef struct { uint8_t * y; uint8_t * u; uint8_t * v; } IMAGE; void init_image(uint32_t cpu_flags); int32_t image_create(IMAGE * image, uint32_t edged_width, uint32_t edged_height); void image_destroy(IMAGE * image, uint32_t edged_width, uint32_t edged_height); void image_swap(IMAGE * image1, IMAGE * image2); void image_copy(IMAGE *image1, IMAGE * image2, uint32_t edged_width, uint32_t height); void image_setedges(IMAGE * image, uint32_t edged_width, uint32_t edged_height, uint32_t width, uint32_t height, uint32_t interlacing); void image_interpolate(const IMAGE * refn, IMAGE * refh, IMAGE * refv, IMAGE * refhv, uint32_t edged_width, uint32_t edged_height, uint32_t rounding); float image_psnr(IMAGE *orig_image, IMAGE *recon_image, uint16_t stride, uint16_t width, uint16_t height); int image_input(IMAGE * image, uint32_t width, int height, uint32_t edged_width, uint8_t * src, int csp); int image_output(IMAGE * image, uint32_t width, int height, uint32_t edged_width, uint8_t * dst, uint32_t dst_stride, int csp); #endif /* _IMAGE_H_ */ xvid_20020412/xvidcore/src/quant/0040755000100600001440000000000007455522447016101 5ustar michaelusersxvid_20020412/xvidcore/src/quant/CVS/0040755000100600001440000000000007455522447016534 5ustar michaelusersxvid_20020412/xvidcore/src/quant/CVS/Root0100644000100600001440000000004607455522447017377 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/quant/CVS/Repository0100644000100600001440000000002307455522447020626 0ustar michaelusersxvidcore/src/quant xvid_20020412/xvidcore/src/quant/CVS/Entries.Log0100644000100600001440000000002007455522447020575 0ustar michaelusersA D/x86_asm//// xvid_20020412/xvidcore/src/quant/CVS/Entries0100644000100600001440000000057207455522447020071 0ustar michaelusers/adapt_quant.c/1.2/Sat Mar 9 16:18:23 2002// /adapt_quant.h/1.2/Thu Mar 28 20:57:25 2002// /quant_h263.c/1.1.1.1/Fri Mar 8 02:44:55 2002// /quant_h263.h/1.1.1.1/Fri Mar 8 02:44:55 2002// /quant_matrix.c/1.4/Sun Mar 10 00:30:55 2002// /quant_matrix.h/1.3/Thu Mar 28 20:57:25 2002// /quant_mpeg4.c/1.2/Fri Mar 8 19:16:41 2002// /quant_mpeg4.h/1.2/Thu Mar 28 20:57:25 2002// D xvid_20020412/xvidcore/src/quant/quant_matrix.c0100644000100600001440000000720607442524477020764 0ustar michaelusers#include "quant_matrix.h" #define FIX(X) (1 << 16) / (X) + 1 uint8_t custom_intra_matrix = 0; uint8_t custom_inter_matrix = 0; uint8_t default_intra_matrix[64] = { 8,17,18,19,21,23,25,27, 17,18,19,21,23,25,27,28, 20,21,22,23,24,26,28,30, 21,22,23,24,26,28,30,32, 22,23,24,26,28,30,32,35, 23,24,26,28,30,32,35,38, 25,26,28,30,32,35,38,41, 27,28,30,32,35,38,41,45 }; int16_t intra_matrix[64] = { 8,17,18,19,21,23,25,27, 17,18,19,21,23,25,27,28, 20,21,22,23,24,26,28,30, 21,22,23,24,26,28,30,32, 22,23,24,26,28,30,32,35, 23,24,26,28,30,32,35,38, 25,26,28,30,32,35,38,41, 27,28,30,32,35,38,41,45 }; int16_t intra_matrix_fix[64] = { FIX(8),FIX(17),FIX(18),FIX(19),FIX(21),FIX(23),FIX(25),FIX(27), FIX(17),FIX(18),FIX(19),FIX(21),FIX(23),FIX(25),FIX(27),FIX(28), FIX(20),FIX(21),FIX(22),FIX(23),FIX(24),FIX(26),FIX(28),FIX(30), FIX(21),FIX(22),FIX(23),FIX(24),FIX(26),FIX(28),FIX(30),FIX(32), FIX(22),FIX(23),FIX(24),FIX(26),FIX(28),FIX(30),FIX(32),FIX(35), FIX(23),FIX(24),FIX(26),FIX(28),FIX(30),FIX(32),FIX(35),FIX(38), FIX(25),FIX(26),FIX(28),FIX(30),FIX(32),FIX(35),FIX(38),FIX(41), FIX(27),FIX(28),FIX(30),FIX(32),FIX(35),FIX(38),FIX(41),FIX(45) }; uint8_t default_inter_matrix[64] = { 16,17,18,19,20,21,22,23, 17,18,19,20,21,22,23,24, 18,19,20,21,22,23,24,25, 19,20,21,22,23,24,26,27, 20,21,22,23,25,26,27,28, 21,22,23,24,26,27,28,30, 22,23,24,26,27,28,30,31, 23,24,25,27,28,30,31,33 }; int16_t inter_matrix[64] = { 16,17,18,19,20,21,22,23, 17,18,19,20,21,22,23,24, 18,19,20,21,22,23,24,25, 19,20,21,22,23,24,26,27, 20,21,22,23,25,26,27,28, 21,22,23,24,26,27,28,30, 22,23,24,26,27,28,30,31, 23,24,25,27,28,30,31,33 }; int16_t inter_matrix_fix[64] = { FIX(16),FIX(17),FIX(18),FIX(19),FIX(20),FIX(21),FIX(22),FIX(23), FIX(17),FIX(18),FIX(19),FIX(20),FIX(21),FIX(22),FIX(23),FIX(24), FIX(18),FIX(19),FIX(20),FIX(21),FIX(22),FIX(23),FIX(24),FIX(25), FIX(19),FIX(20),FIX(21),FIX(22),FIX(23),FIX(24),FIX(26),FIX(27), FIX(20),FIX(21),FIX(22),FIX(23),FIX(25),FIX(26),FIX(27),FIX(28), FIX(21),FIX(22),FIX(23),FIX(24),FIX(26),FIX(27),FIX(28),FIX(30), FIX(22),FIX(23),FIX(24),FIX(26),FIX(27),FIX(28),FIX(30),FIX(31), FIX(23),FIX(24),FIX(25),FIX(27),FIX(28),FIX(30),FIX(31),FIX(33) }; uint8_t get_intra_matrix_status(void) { return custom_intra_matrix; } uint8_t get_inter_matrix_status(void) { return custom_inter_matrix; } void set_intra_matrix_status(uint8_t status) { custom_intra_matrix = status; } void set_inter_matrix_status(uint8_t status) { custom_inter_matrix = status; } int16_t *get_intra_matrix(void) { return intra_matrix; } int16_t *get_inter_matrix(void) { return inter_matrix; } uint8_t *get_default_intra_matrix(void) { return default_intra_matrix; } uint8_t *get_default_inter_matrix(void) { return default_inter_matrix; } uint8_t set_intra_matrix(uint8_t *matrix) { int i, change = 0; custom_intra_matrix = 0; for(i = 0; i < 64; i++) { if((int16_t) default_intra_matrix[i] != matrix[i]) custom_intra_matrix = 1; if(intra_matrix[i] != matrix[i]) change = 1; intra_matrix[i] = (int16_t) matrix[i]; intra_matrix_fix[i] = FIX(intra_matrix[i]); } return custom_intra_matrix | change; } uint8_t set_inter_matrix(uint8_t *matrix) { int i, change = 0; custom_inter_matrix = 0; for(i = 0; i < 64; i++) { if((int16_t) default_inter_matrix[i] != matrix[i]) custom_inter_matrix = 1; if(inter_matrix[i] != matrix[i]) change = 1; inter_matrix[i] = (int16_t) matrix[i]; inter_matrix_fix[i] = FIX(inter_matrix[i]); } return custom_inter_matrix | change; } xvid_20020412/xvidcore/src/quant/quant_matrix.h0100644000100600001440000000100207450701665020750 0ustar michaelusers#ifndef _QUANT_MATRIX_H_ #define _QUANT_MATRIX_H_ #include "../portab.h" uint8_t get_intra_matrix_status(void); uint8_t get_inter_matrix_status(void); void set_intra_matrix_status(uint8_t status); void set_inter_matrix_status(uint8_t status); uint8_t set_intra_matrix(uint8_t *matrix); uint8_t set_inter_matrix(uint8_t *matrix); int16_t *get_intra_matrix(void); int16_t *get_inter_matrix(void); uint8_t *get_default_intra_matrix(void); uint8_t *get_default_inter_matrix(void); #endif /* _QUANT_MATRIX_H_ */ xvid_20020412/xvidcore/src/quant/quant_h263.c0100644000100600001440000001257007442022647020132 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * quantization/dequantization * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 26.12.2001 dequant_inter bug fix * 22.12.2001 clamp dequant output to [-2048,2047] * 19.11.2001 quant_inter now returns sum of abs. coefficient values * 02.11.2001 added const to function args * 28.10.2001 total rewrite * *************************************************************************/ #include "quant_h263.h" /* mutliply+shift division table */ #define SCALEBITS 16 #define FIX(X) ((1L << SCALEBITS) / (X) + 1) static const uint32_t multipliers[32] = { 0, FIX(2), FIX(4), FIX(6), FIX(8), FIX(10), FIX(12), FIX(14), FIX(16), FIX(18), FIX(20), FIX(22), FIX(24), FIX(26), FIX(28), FIX(30), FIX(32), FIX(34), FIX(36), FIX(38), FIX(40), FIX(42), FIX(44), FIX(46), FIX(48), FIX(50), FIX(52), FIX(54), FIX(56), FIX(58), FIX(60), FIX(62) }; #define DIV_DIV(a, b) ((a)>0) ? ((a)+((b)>>1))/(b) : ((a)-((b)>>1))/(b) // function pointers quanth263_intraFuncPtr quant_intra; quanth263_intraFuncPtr dequant_intra; quanth263_interFuncPtr quant_inter; dequanth263_interFuncPtr dequant_inter; /* quantize intra-block */ void quant_intra_c(int16_t * coeff, const int16_t * data, const uint32_t quant, const uint32_t dcscalar) { const uint32_t mult = multipliers[quant]; const uint16_t quant_m_2 = quant << 1; uint32_t i; coeff[0] = DIV_DIV(data[0], (int32_t)dcscalar); for (i = 1; i < 64; i++) { int16_t acLevel = data[i]; if (acLevel < 0) { acLevel = -acLevel; if (acLevel < quant_m_2) { coeff[i] = 0; continue; } acLevel = (acLevel * mult) >> SCALEBITS; coeff[i] = -acLevel; } else { if (acLevel < quant_m_2) { coeff[i] = 0; continue; } acLevel = (acLevel * mult) >> SCALEBITS; coeff[i] = acLevel; } } } /* quantize inter-block */ uint32_t quant_inter_c(int16_t *coeff, const int16_t *data, const uint32_t quant) { const uint32_t mult = multipliers[quant]; const uint16_t quant_m_2 = quant << 1; const uint16_t quant_d_2 = quant >> 1; int sum = 0; uint32_t i; for (i = 0; i < 64; i++) { int16_t acLevel = data[i]; if (acLevel < 0) { acLevel = (-acLevel) - quant_d_2; if (acLevel < quant_m_2) { coeff[i] = 0; continue; } acLevel = (acLevel * mult) >> SCALEBITS; sum += acLevel; // sum += |acLevel| coeff[i] = -acLevel; } else { acLevel -= quant_d_2; if (acLevel < quant_m_2) { coeff[i] = 0; continue; } acLevel = (acLevel * mult) >> SCALEBITS; sum += acLevel; coeff[i] = acLevel; } } return sum; } /* dequantize intra-block & clamp to [-2048,2047] */ void dequant_intra_c(int16_t *data, const int16_t *coeff, const uint32_t quant, const uint32_t dcscalar) { const int32_t quant_m_2 = quant << 1; const int32_t quant_add = (quant & 1 ? quant : quant - 1); uint32_t i; data[0] = coeff[0] * dcscalar; if (data[0] < -2048) { data[0] = -2048; } else if (data[0] > 2047) { data[0] = 2047; } for (i = 1; i < 64; i++) { int32_t acLevel = coeff[i]; if (acLevel == 0) { data[i] = 0; } else if (acLevel < 0) { acLevel = quant_m_2 * -acLevel + quant_add; data[i] = (acLevel <= 2048 ? -acLevel : -2048); } else // if (acLevel > 0) { { acLevel = quant_m_2 * acLevel + quant_add; data[i] = (acLevel <= 2047 ? acLevel : 2047); } } } /* dequantize inter-block & clamp to [-2048,2047] */ void dequant_inter_c(int16_t *data, const int16_t *coeff, const uint32_t quant) { const uint16_t quant_m_2 = quant << 1; const uint16_t quant_add = (quant & 1 ? quant : quant - 1); uint32_t i; for (i = 0; i < 64; i++) { int16_t acLevel = coeff[i]; if (acLevel == 0) { data[i] = 0; } else if (acLevel < 0) { acLevel = acLevel * quant_m_2 - quant_add; data[i] = (acLevel >= -2048 ? acLevel : -2048); } else // if (acLevel > 0) { acLevel = acLevel * quant_m_2 + quant_add; data[i] = (acLevel <= 2047 ? acLevel : 2047); } } } xvid_20020412/xvidcore/src/quant/quant_h263.h0100644000100600001440000000216607442022647020137 0ustar michaelusers#ifndef _QUANT_H263_H_ #define _QUANT_H263_H_ #include "../portab.h" // intra typedef void (quanth263_intraFunc)(int16_t * coeff, const int16_t * data, const uint32_t quant, const uint32_t dcscalar); typedef quanth263_intraFunc* quanth263_intraFuncPtr; extern quanth263_intraFuncPtr quant_intra; extern quanth263_intraFuncPtr dequant_intra; quanth263_intraFunc quant_intra_c; quanth263_intraFunc quant_intra_mmx; quanth263_intraFunc dequant_intra_c; quanth263_intraFunc dequant_intra_mmx; // inter_quant typedef uint32_t (quanth263_interFunc)(int16_t *coeff, const int16_t *data, const uint32_t quant); typedef quanth263_interFunc* quanth263_interFuncPtr; extern quanth263_interFuncPtr quant_inter; quanth263_interFunc quant_inter_c; quanth263_interFunc quant_inter_mmx; //inter_dequant typedef void (dequanth263_interFunc)(int16_t *coeff, const int16_t *data, const uint32_t quant); typedef dequanth263_interFunc* dequanth263_interFuncPtr; extern dequanth263_interFuncPtr dequant_inter; dequanth263_interFunc dequant_inter_c; dequanth263_interFunc dequant_inter_mmx; #endif /* _QUANT_H263_H_ */ xvid_20020412/xvidcore/src/quant/x86_asm/0040755000100600001440000000000007455522447017366 5ustar michaelusersxvid_20020412/xvidcore/src/quant/x86_asm/CVS/0040755000100600001440000000000007455522447020021 5ustar michaelusersxvid_20020412/xvidcore/src/quant/x86_asm/CVS/Root0100644000100600001440000000004607455522447020664 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/quant/x86_asm/CVS/Repository0100644000100600001440000000003307455522447022114 0ustar michaelusersxvidcore/src/quant/x86_asm xvid_20020412/xvidcore/src/quant/x86_asm/CVS/Entries0100644000100600001440000000015107455522447021347 0ustar michaelusers/quantize4_mmx.asm/1.2/Fri Mar 8 19:16:49 2002// /quantize_mmx.asm/1.1.1.1/Fri Mar 8 02:44:58 2002// D xvid_20020412/xvidcore/src/quant/x86_asm/quantize_mmx.asm0100644000100600001440000003165507442022652022605 0ustar michaelusers;/************************************************************************** ; * ; * XVID MPEG-4 VIDEO CODEC ; * mmx quantization/dequantization ; * ; * This program is an implementation of a part of one or more MPEG-4 ; * Video tools as specified in ISO/IEC 14496-2 standard. Those intending ; * to use this software module in hardware or software products are ; * advised that its use may infringe existing patents or copyrights, and ; * any such use would be at such party's own risk. The original ; * developer of this software module and his/her company, and subsequent ; * editors and their companies, will have no liability for use of this ; * software or modifications or derivatives thereof. ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * This program is distributed in the hope that it will be useful, ; * but WITHOUT ANY WARRANTY; without even the implied warranty of ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; * GNU General Public License for more details. ; * ; * You should have received a copy of the GNU General Public License ; * along with this program; if not, write to the Free Software ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; * ; *************************************************************************/ ;/************************************************************************** ; * ; * History: ; * ; * 26.12.2001 minor bug fixes, dequant saturate, further optimization ; * 19.11.2001 quant_inter_mmx now returns sum of abs. coefficient values ; * 04.11.2001 nasm version; (c)2001 peter ross ; * ; *************************************************************************/ ; enable dequant saturate [-2048,2047], test purposes only. %define SATURATE ; data/text alignment %define ALIGN 8 bits 32 section .data %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro plus_one times 4 dw 1 ;=========================================================================== ; ; subtract by Q/2 table ; ;=========================================================================== %macro MMX_SUB 1 times 4 dw %1 / 2 %endmacro align ALIGN mmx_sub MMX_SUB 1 MMX_SUB 2 MMX_SUB 3 MMX_SUB 4 MMX_SUB 5 MMX_SUB 6 MMX_SUB 7 MMX_SUB 8 MMX_SUB 9 MMX_SUB 10 MMX_SUB 11 MMX_SUB 12 MMX_SUB 13 MMX_SUB 14 MMX_SUB 15 MMX_SUB 16 MMX_SUB 17 MMX_SUB 18 MMX_SUB 19 MMX_SUB 20 MMX_SUB 21 MMX_SUB 22 MMX_SUB 23 MMX_SUB 24 MMX_SUB 25 MMX_SUB 26 MMX_SUB 27 MMX_SUB 28 MMX_SUB 29 MMX_SUB 30 MMX_SUB 31 ;=========================================================================== ; ; divide by 2Q table ; ; use a shift of 16 to take full advantage of _pmulhw_ ; for q=1, _pmulhw_ will overflow so it is treated seperately ; (3dnow2 provides _pmulhuw_ which wont cause overflow) ; ;=========================================================================== %macro MMX_DIV 1 times 4 dw (1 << 16) / (%1 * 2) + 1 %endmacro align ALIGN mmx_div MMX_DIV 1 MMX_DIV 2 MMX_DIV 3 MMX_DIV 4 MMX_DIV 5 MMX_DIV 6 MMX_DIV 7 MMX_DIV 8 MMX_DIV 9 MMX_DIV 10 MMX_DIV 11 MMX_DIV 12 MMX_DIV 13 MMX_DIV 14 MMX_DIV 15 MMX_DIV 16 MMX_DIV 17 MMX_DIV 18 MMX_DIV 19 MMX_DIV 20 MMX_DIV 21 MMX_DIV 22 MMX_DIV 23 MMX_DIV 24 MMX_DIV 25 MMX_DIV 26 MMX_DIV 27 MMX_DIV 28 MMX_DIV 29 MMX_DIV 30 MMX_DIV 31 ;=========================================================================== ; ; add by (odd(Q) ? Q : Q - 1) table ; ;=========================================================================== %macro MMX_ADD 1 %if %1 % 2 != 0 times 4 dw %1 %else times 4 dw %1 - 1 %endif %endmacro align ALIGN mmx_add MMX_ADD 1 MMX_ADD 2 MMX_ADD 3 MMX_ADD 4 MMX_ADD 5 MMX_ADD 6 MMX_ADD 7 MMX_ADD 8 MMX_ADD 9 MMX_ADD 10 MMX_ADD 11 MMX_ADD 12 MMX_ADD 13 MMX_ADD 14 MMX_ADD 15 MMX_ADD 16 MMX_ADD 17 MMX_ADD 18 MMX_ADD 19 MMX_ADD 20 MMX_ADD 21 MMX_ADD 22 MMX_ADD 23 MMX_ADD 24 MMX_ADD 25 MMX_ADD 26 MMX_ADD 27 MMX_ADD 28 MMX_ADD 29 MMX_ADD 30 MMX_ADD 31 ;=========================================================================== ; ; multiple by 2Q table ; ;=========================================================================== %macro MMX_MUL 1 times 4 dw %1 * 2 %endmacro align ALIGN mmx_mul MMX_MUL 1 MMX_MUL 2 MMX_MUL 3 MMX_MUL 4 MMX_MUL 5 MMX_MUL 6 MMX_MUL 7 MMX_MUL 8 MMX_MUL 9 MMX_MUL 10 MMX_MUL 11 MMX_MUL 12 MMX_MUL 13 MMX_MUL 14 MMX_MUL 15 MMX_MUL 16 MMX_MUL 17 MMX_MUL 18 MMX_MUL 19 MMX_MUL 20 MMX_MUL 21 MMX_MUL 22 MMX_MUL 23 MMX_MUL 24 MMX_MUL 25 MMX_MUL 26 MMX_MUL 27 MMX_MUL 28 MMX_MUL 29 MMX_MUL 30 MMX_MUL 31 ;=========================================================================== ; ; saturation limits ; ;=========================================================================== align ALIGN mmx_32768_minus_2048 times 4 dw (32768-2048) mmx_32767_minus_2047 times 4 dw (32767-2047) section .text ;=========================================================================== ; ; void quant_intra_mmx(int16_t * coeff, ; const int16_t const * data, ; const uint32_t quant, ; const uint32_t dcscalar); ; ;=========================================================================== align ALIGN cglobal quant_intra_mmx quant_intra_mmx push ecx push esi push edi mov edi, [esp + 12 + 4] ; coeff mov esi, [esp + 12 + 8] ; data mov eax, [esp + 12 + 12] ; quant xor ecx, ecx cmp al, 1 jz .q1loop movq mm7, [mmx_div + eax * 8 - 8] align ALIGN .loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx + 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16 pmulhw mm3, mm7 ; pxor mm0, mm1 ; mm0 *= sign(mm0) pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 ; movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx,2 cmp ecx,16 jnz .loop .done ; caclulate data[0] // (int32_t)dcscalar) mov ecx, [esp + 12 + 16] ; dcscalar mov edx, ecx movsx eax, word [esi] ; data[0] shr edx, 1 ; edx = dcscalar /2 cmp eax, 0 jg .gtzero sub eax, edx jmp short .mul .gtzero add eax, edx .mul cdq ; expand eax -> edx:eax idiv ecx ; eax = edx:eax / dcscalar mov [edi], ax ; coeff[0] = ax pop edi pop esi pop ecx ret align ALIGN .q1loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx + 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; psrlw mm0, 1 ; mm0 >>= 1 (/2) psrlw mm3, 1 ; pxor mm0, mm1 ; mm0 *= sign(mm0) pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 ; movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx,2 cmp ecx,16 jnz .q1loop jmp short .done ;=========================================================================== ; ; uint32_t quant_inter_mmx(int16_t * coeff, ; const int16_t const * data, ; const uint32_t quant); ; ;=========================================================================== align ALIGN cglobal quant_inter_mmx quant_inter_mmx push ecx push esi push edi mov edi, [esp + 12 + 4] ; coeff mov esi, [esp + 12 + 8] ; data mov eax, [esp + 12 + 12] ; quant xor ecx, ecx pxor mm5, mm5 ; sum movq mm6, [mmx_sub + eax * 8 - 8] ; sub cmp al, 1 jz .q1loop movq mm7, [mmx_div + eax * 8 - 8] ; divider align ALIGN .loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx + 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0) psubusw mm3, mm6 ; pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16 pmulhw mm3, mm7 ; paddw mm5, mm0 ; sum += mm0 pxor mm0, mm1 ; mm0 *= sign(mm0) paddw mm5, mm3 ; pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx, 2 cmp ecx, 16 jnz .loop .done pmaddwd mm5, [plus_one] movq mm0, mm5 psrlq mm5, 32 paddd mm0, mm5 movd eax, mm0 ; return sum pop edi pop esi pop ecx ret align ALIGN .q1loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx+ 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; psubusw mm0, mm6 ; mm0 -= sub (unsigned, dont go < 0) psubusw mm3, mm6 ; psrlw mm0, 1 ; mm0 >>= 1 (/2) psrlw mm3, 1 ; paddw mm5, mm0 ; sum += mm0 pxor mm0, mm1 ; mm0 *= sign(mm0) paddw mm5, mm3 ; pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx,2 cmp ecx,16 jnz .q1loop jmp .done ;=========================================================================== ; ; void dequant_intra_mmx(int16_t *data, ; const int16_t const *coeff, ; const uint32_t quant, ; const uint32_t dcscalar); ; ;=========================================================================== align ALIGN cglobal dequant_intra_mmx dequant_intra_mmx push esi push edi mov edi, [esp + 8 + 4] ; data mov esi, [esp + 8 + 8] ; coeff mov eax, [esp + 8 + 12] ; quant movq mm6, [mmx_add + eax * 8 - 8] movq mm7, [mmx_mul + eax * 8 - 8] xor eax, eax align ALIGN .loop movq mm0, [esi + 8*eax] ; mm0 = [coeff] movq mm3, [esi + 8*eax + 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm2, mm2 ; mm2 = 0 pxor mm5, mm5 ; pcmpeqw mm2, mm0 ; mm2 = (0 == mm0) pcmpeqw mm5, mm3 ; pandn mm2, mm6 ; mm2 = (iszero ? 0 : add) pandn mm5, mm6 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; pmullw mm0, mm7 ; mm0 *= 2Q pmullw mm3, mm7 ; paddw mm0, mm2 ; mm0 += mm2 (add) paddw mm3, mm5 ; pxor mm0, mm1 ; mm0 *= sign(mm0) pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 %ifdef SATURATE movq mm2, [mmx_32767_minus_2047] movq mm4, [mmx_32768_minus_2048] paddsw mm0, mm2 paddsw mm3, mm2 psubsw mm0, mm2 psubsw mm3, mm2 psubsw mm0, mm4 psubsw mm3, mm4 paddsw mm0, mm4 paddsw mm3, mm4 %endif movq [edi + 8*eax], mm0 ; [data] = mm0 movq [edi + 8*eax + 8], mm3 add eax, 2 cmp eax, 16 jnz near .loop mov ax, [esi] ; ax = data[0] imul ax, [esp + 8 + 16] ; eax = data[0] * dcscalar %ifdef SATURATE cmp ax, -2048 jl .set_n2048 cmp ax, 2047 jg .set_2047 %endif mov [edi], ax pop edi pop esi ret %ifdef SATURATE align ALIGN .set_n2048 mov word [edi], -2048 pop edi pop esi ret align ALIGN .set_2047 mov word [edi], 2047 pop edi pop esi ret %endif ;=========================================================================== ; ; void dequant_inter_mmx(int16_t * data, ; const int16_t * const coeff, ; const uint32_t quant); ; ;=========================================================================== align ALIGN cglobal dequant_inter_mmx dequant_inter_mmx push esi push edi mov edi, [esp + 8 + 4] ; data mov esi, [esp + 8 + 8] ; coeff mov eax, [esp + 8 + 12] ; quant movq mm6, [mmx_add + eax * 8 - 8] movq mm7, [mmx_mul + eax * 8 - 8] xor eax, eax align ALIGN .loop movq mm0, [esi + 8*eax] ; mm0 = [coeff] movq mm3, [esi + 8*eax + 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm2, mm2 ; mm2 = 0 pxor mm5, mm5 ; pcmpeqw mm2, mm0 ; mm2 = (0 == mm0) pcmpeqw mm5, mm3 ; pandn mm2, mm6 ; mm2 = (iszero ? 0 : add) pandn mm5, mm6 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; pmullw mm0, mm7 ; mm0 *= 2Q pmullw mm3, mm7 ; paddw mm0, mm2 ; mm0 += mm2 (add) paddw mm3, mm5 ; pxor mm0, mm1 ; mm0 *= sign(mm0) pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 %ifdef SATURATE movq mm2, [mmx_32767_minus_2047] movq mm4, [mmx_32768_minus_2048] paddsw mm0, mm2 paddsw mm3, mm2 psubsw mm0, mm2 psubsw mm3, mm2 psubsw mm0, mm4 psubsw mm3, mm4 paddsw mm0, mm4 paddsw mm3, mm4 %endif movq [edi + 8*eax], mm0 movq [edi + 8*eax + 8], mm3 add eax, 2 cmp eax, 16 jnz near .loop pop edi pop esi retxvid_20020412/xvidcore/src/quant/x86_asm/quantize4_mmx.asm0100644000100600001440000005017007442207041022657 0ustar michaelusers;/****************************************************************************** ; * * ; * This file is part of XviD, a free MPEG-4 video encoder/decoder * ; * * ; * XviD is an implementation of a part of one or more MPEG-4 Video tools * ; * as specified in ISO/IEC 14496-2 standard. Those intending to use this * ; * software module in hardware or software products are advised that its * ; * use may infringe existing patents or copyrights, and any such use * ; * would be at such party's own risk. The original developer of this * ; * software module and his/her company, and subsequent editors and their * ; * companies, will have no liability for use of this software or * ; * modifications or derivatives thereof. * ; * * ; * XviD is free software; you can redistribute it and/or modify it * ; * under the terms of the GNU General Public License as published by * ; * the Free Software Foundation; either version 2 of the License, or * ; * (at your option) any later version. * ; * * ; * XviD is distributed in the hope that it will be useful, but * ; * WITHOUT ANY WARRANTY; without even the implied warranty of * ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ; * GNU General Public License for more details. * ; * * ; * You should have received a copy of the GNU General Public License * ; * along with this program; if not, write to the Free Software * ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * quantize4.asm, MMX optimized MPEG quantization/dequantization * ; * * ; * Copyright (C) 2002 - Peter Ross * ; * Copyright (C) 2002 - Michael Militzer * ; * * ; * For more information visit the XviD homepage: http://www.xvid.org * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * Revision history: * ; * * ; * 22.01.2002 initial version * ; * * ; ******************************************************************************/ ; data/text alignment %define ALIGN 8 %define SATURATE bits 32 section .data %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro %macro cextern 1 %ifdef PREFIX extern _%1 %define %1 _%1 %else extern %1 %endif %endmacro mmx_one times 4 dw 1 ;=========================================================================== ; ; divide by 2Q table ; ;=========================================================================== %macro MMX_DIV 1 times 4 dw (1 << 17) / (%1 * 2) + 1 %endmacro align ALIGN mmx_div MMX_DIV 1 MMX_DIV 2 MMX_DIV 3 MMX_DIV 4 MMX_DIV 5 MMX_DIV 6 MMX_DIV 7 MMX_DIV 8 MMX_DIV 9 MMX_DIV 10 MMX_DIV 11 MMX_DIV 12 MMX_DIV 13 MMX_DIV 14 MMX_DIV 15 MMX_DIV 16 MMX_DIV 17 MMX_DIV 18 MMX_DIV 19 MMX_DIV 20 MMX_DIV 21 MMX_DIV 22 MMX_DIV 23 MMX_DIV 24 MMX_DIV 25 MMX_DIV 26 MMX_DIV 27 MMX_DIV 28 MMX_DIV 29 MMX_DIV 30 MMX_DIV 31 ;=========================================================================== ; ; intra matrix ; ;=========================================================================== cextern intra_matrix cextern intra_matrix_fix ;=========================================================================== ; ; inter matrix ; ;=========================================================================== cextern inter_matrix cextern inter_matrix_fix %define VM18P 3 %define VM18Q 4 ;=========================================================================== ; ; quantd table ; ;=========================================================================== %macro MMX_QUANTD 1 times 4 dw ((VM18P*%1) + (VM18Q/2)) / VM18Q %endmacro quantd MMX_QUANTD 1 MMX_QUANTD 2 MMX_QUANTD 3 MMX_QUANTD 4 MMX_QUANTD 5 MMX_QUANTD 6 MMX_QUANTD 7 MMX_QUANTD 8 MMX_QUANTD 9 MMX_QUANTD 10 MMX_QUANTD 11 MMX_QUANTD 12 MMX_QUANTD 13 MMX_QUANTD 14 MMX_QUANTD 15 MMX_QUANTD 16 MMX_QUANTD 17 MMX_QUANTD 18 MMX_QUANTD 19 MMX_QUANTD 20 MMX_QUANTD 21 MMX_QUANTD 22 MMX_QUANTD 23 MMX_QUANTD 24 MMX_QUANTD 25 MMX_QUANTD 26 MMX_QUANTD 27 MMX_QUANTD 28 MMX_QUANTD 29 MMX_QUANTD 30 MMX_QUANTD 31 ;=========================================================================== ; ; multiple by 2Q table ; ;=========================================================================== %macro MMX_MUL_QUANT 1 times 4 dw %1 %endmacro mmx_mul_quant MMX_MUL_QUANT 1 MMX_MUL_QUANT 2 MMX_MUL_QUANT 3 MMX_MUL_QUANT 4 MMX_MUL_QUANT 5 MMX_MUL_QUANT 6 MMX_MUL_QUANT 7 MMX_MUL_QUANT 8 MMX_MUL_QUANT 9 MMX_MUL_QUANT 10 MMX_MUL_QUANT 11 MMX_MUL_QUANT 12 MMX_MUL_QUANT 13 MMX_MUL_QUANT 14 MMX_MUL_QUANT 15 MMX_MUL_QUANT 16 MMX_MUL_QUANT 17 MMX_MUL_QUANT 18 MMX_MUL_QUANT 19 MMX_MUL_QUANT 20 MMX_MUL_QUANT 21 MMX_MUL_QUANT 22 MMX_MUL_QUANT 23 MMX_MUL_QUANT 24 MMX_MUL_QUANT 25 MMX_MUL_QUANT 26 MMX_MUL_QUANT 27 MMX_MUL_QUANT 28 MMX_MUL_QUANT 29 MMX_MUL_QUANT 30 MMX_MUL_QUANT 31 ;=========================================================================== ; ; saturation limits ; ;=========================================================================== align 16 mmx_32768_minus_2048 times 4 dw (32768-2048) mmx_32767_minus_2047 times 4 dw (32767-2047) section .text ;=========================================================================== ; ; void quant_intra4_mmx(int16_t * coeff, ; const int16_t const * data, ; const uint32_t quant, ; const uint32_t dcscalar); ; ;=========================================================================== align ALIGN cglobal quant4_intra_mmx quant4_intra_mmx push ecx push esi push edi mov edi, [esp + 12 + 4] ; coeff mov esi, [esp + 12 + 8] ; data mov eax, [esp + 12 + 12] ; quant movq mm5, [quantd + eax * 8 - 8] ; quantd -> mm5 xor ecx, ecx cmp al, 1 jz near .q1loop cmp al, 2 jz near .q2loop movq mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7 align ALIGN .loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx + 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; psllw mm0, 4 ; level << 4 psllw mm3, 4 ; movq mm2, [intra_matrix + 8*ecx] psrlw mm2, 1 ; intra_matrix[i]>>1 paddw mm0, mm2 movq mm2, [intra_matrix_fix + ecx*8] pmulhw mm0, mm2 ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i] movq mm2, [intra_matrix + 8*ecx + 8] psrlw mm2, 1 paddw mm3, mm2 movq mm2, [intra_matrix_fix + ecx*8 + 8] pmulhw mm3, mm2 paddw mm0, mm5 ; + quantd paddw mm3, mm5 pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16 pmulhw mm3, mm7 ; psrlw mm0, 1 ; additional shift by 1 => 16 + 1 = 17 psrlw mm3, 1 pxor mm0, mm1 ; mm0 *= sign(mm0) pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 ; movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx,2 cmp ecx,16 jnz near .loop .done ; caclulate data[0] // (int32_t)dcscalar) mov ecx, [esp + 12 + 16] ; dcscalar mov edx, ecx movsx eax, word [esi] ; data[0] shr edx, 1 ; edx = dcscalar /2 cmp eax, 0 jg .gtzero sub eax, edx jmp short .mul .gtzero add eax, edx .mul cdq ; expand eax -> edx:eax idiv ecx ; eax = edx:eax / dcscalar mov [edi], ax ; coeff[0] = ax pop edi pop esi pop ecx ret align ALIGN .q1loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx + 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; psllw mm0, 4 psllw mm3, 4 movq mm2, [intra_matrix + 8*ecx] psrlw mm2, 1 paddw mm0, mm2 movq mm2, [intra_matrix_fix + ecx*8] pmulhw mm0, mm2 ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i] movq mm2, [intra_matrix + 8*ecx + 8] psrlw mm2, 1 paddw mm3, mm2 movq mm2, [intra_matrix_fix + ecx*8 + 8] pmulhw mm3, mm2 paddw mm0, mm5 paddw mm3, mm5 psrlw mm0, 1 ; mm0 >>= 1 (/2) psrlw mm3, 1 ; pxor mm0, mm1 ; mm0 *= sign(mm0) pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 ; movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx,2 cmp ecx,16 jnz near .q1loop jmp near .done align ALIGN .q2loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx + 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; psllw mm0, 4 psllw mm3, 4 movq mm2, [intra_matrix + 8*ecx] psrlw mm2, 1 paddw mm0, mm2 movq mm2, [intra_matrix_fix + ecx*8] pmulhw mm0, mm2 ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i] movq mm2, [intra_matrix + 8*ecx + 8] psrlw mm2, 1 paddw mm3, mm2 movq mm2, [intra_matrix_fix + ecx*8 + 8] pmulhw mm3, mm2 paddw mm0, mm5 paddw mm3, mm5 psrlw mm0, 2 ; mm0 >>= 1 (/4) psrlw mm3, 2 ; pxor mm0, mm1 ; mm0 *= sign(mm0) pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 ; movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx,2 cmp ecx,16 jnz near .q2loop jmp near .done ;=========================================================================== ; ; uint32_t quant4_inter_mmx(int16_t * coeff, ; const int16_t const * data, ; const uint32_t quant); ; ;=========================================================================== align ALIGN cglobal quant4_inter_mmx quant4_inter_mmx push ecx push esi push edi mov edi, [esp + 12 + 4] ; coeff mov esi, [esp + 12 + 8] ; data mov eax, [esp + 12 + 12] ; quant xor ecx, ecx pxor mm5, mm5 ; sum cmp al, 1 jz near .q1loop cmp al, 2 jz near .q2loop movq mm7, [mmx_div + eax * 8 - 8] ; divider align ALIGN .loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx + 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; psllw mm0, 4 psllw mm3, 4 movq mm2, [inter_matrix + 8*ecx] psrlw mm2, 1 paddw mm0, mm2 movq mm2, [inter_matrix_fix + ecx*8] pmulhw mm0, mm2 ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i] movq mm2, [inter_matrix + 8*ecx + 8] psrlw mm2, 1 paddw mm3, mm2 movq mm2, [inter_matrix_fix + ecx*8 + 8] pmulhw mm3, mm2 pmulhw mm0, mm7 ; mm0 = (mm0 / 2Q) >> 16 pmulhw mm3, mm7 ; psrlw mm0, 1 ; additional shift by 1 => 16 + 1 = 17 psrlw mm3, 1 paddw mm5, mm0 ; sum += mm0 pxor mm0, mm1 ; mm0 *= sign(mm0) paddw mm5, mm3 ; pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx, 2 cmp ecx, 16 jnz near .loop .done pmaddwd mm5, [mmx_one] movq mm0, mm5 psrlq mm5, 32 paddd mm0, mm5 movd eax, mm0 ; return sum pop edi pop esi pop ecx ret align ALIGN .q1loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx+ 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; psllw mm0, 4 psllw mm3, 4 movq mm2, [inter_matrix + 8*ecx] psrlw mm2, 1 paddw mm0, mm2 movq mm2, [inter_matrix_fix + ecx*8] pmulhw mm0, mm2 ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i] movq mm2, [inter_matrix + 8*ecx + 8] psrlw mm2, 1 paddw mm3, mm2 movq mm2, [inter_matrix_fix + ecx*8 + 8] pmulhw mm3, mm2 psrlw mm0, 1 ; mm0 >>= 1 (/2) psrlw mm3, 1 ; paddw mm5, mm0 ; sum += mm0 pxor mm0, mm1 ; mm0 *= sign(mm0) paddw mm5, mm3 ; pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx,2 cmp ecx,16 jnz near .q1loop jmp .done align ALIGN .q2loop movq mm0, [esi + 8*ecx] ; mm0 = [1st] movq mm3, [esi + 8*ecx+ 8] ; pxor mm1, mm1 ; mm1 = 0 pxor mm4, mm4 ; pcmpgtw mm1, mm0 ; mm1 = (0 > mm0) pcmpgtw mm4, mm3 ; pxor mm0, mm1 ; mm0 = |mm0| pxor mm3, mm4 ; psubw mm0, mm1 ; displace psubw mm3, mm4 ; psllw mm0, 4 psllw mm3, 4 movq mm2, [inter_matrix + 8*ecx] psrlw mm2, 1 paddw mm0, mm2 movq mm2, [inter_matrix_fix + ecx*8] pmulhw mm0, mm2 ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i] movq mm2, [inter_matrix + 8*ecx + 8] psrlw mm2, 1 paddw mm3, mm2 movq mm2, [inter_matrix_fix + ecx*8 + 8] pmulhw mm3, mm2 psrlw mm0, 2 ; mm0 >>= 1 (/2) psrlw mm3, 2 ; paddw mm5, mm0 ; sum += mm0 pxor mm0, mm1 ; mm0 *= sign(mm0) paddw mm5, mm3 ; pxor mm3, mm4 ; psubw mm0, mm1 ; undisplace psubw mm3, mm4 movq [edi + 8*ecx], mm0 movq [edi + 8*ecx + 8], mm3 add ecx,2 cmp ecx,16 jnz near .q2loop jmp .done ;=========================================================================== ; ; void dequant4_intra_mmx(int16_t *data, ; const int16_t const *coeff, ; const uint32_t quant, ; const uint32_t dcscalar); ; ;=========================================================================== align 16 cglobal dequant4_intra_mmx dequant4_intra_mmx push esi push edi mov edi, [esp + 8 + 4] ; data mov esi, [esp + 8 + 8] ; coeff mov eax, [esp + 8 + 12] ; quant movq mm7, [mmx_mul_quant + eax*8 - 8] xor eax, eax align 16 .loop movq mm0, [esi + 8*eax] ; mm0 = [coeff] pxor mm1, mm1 ; mm1 = 0 pcmpeqw mm1, mm0 ; mm1 = (0 == mm0) pxor mm2, mm2 ; mm2 = 0 pcmpgtw mm2, mm0 ; mm2 = (0 > mm0) pxor mm0, mm2 ; mm0 = |mm0| psubw mm0, mm2 ; displace pmullw mm0, mm7 ; mm0 *= quant movq mm3, [intra_matrix + 8*eax] movq mm4, mm0 ; pmullw mm0, mm3 ; mm0 = low(mm0 * mm3) pmulhw mm3, mm4 ; mm3 = high(mm0 * mm3) movq mm4, mm0 ; mm0,mm4 = unpack(mm3, mm0) punpcklwd mm0, mm3 ; punpckhwd mm4, mm3 ; psrld mm0, 3 ; mm0,mm4 /= 8 psrld mm4, 3 ; packssdw mm0, mm4 ; mm0 = pack(mm4, mm0) pxor mm0, mm2 ; mm0 *= sign(mm0) psubw mm0, mm2 ; undisplace pandn mm1, mm0 ; mm1 = ~(iszero) & mm0 %ifdef SATURATE movq mm2, [mmx_32767_minus_2047] movq mm6, [mmx_32768_minus_2048] paddsw mm1, mm2 psubsw mm1, mm2 psubsw mm1, mm6 paddsw mm1, mm6 %endif movq [edi + 8*eax], mm1 ; [data] = mm0 add eax, 1 cmp eax, 16 jnz near .loop mov ax, [esi] ; ax = data[0] imul ax, [esp + 8 + 16] ; eax = data[0] * dcscalar mov [edi], ax ; data[0] = ax %ifdef SATURATE cmp ax, -2048 jl .set_n2048 cmp ax, 2047 jg .set_2047 %endif pop edi pop esi ret %ifdef SATURATE .set_n2048 mov word [edi], -2048 pop edi pop esi ret .set_2047 mov word [edi], 2047 pop edi pop esi ret %endif ;=========================================================================== ; ; void dequant4_inter_mmx(int16_t * data, ; const int16_t * const coeff, ; const uint32_t quant); ; ;=========================================================================== align 16 cglobal dequant4_inter_mmx dequant4_inter_mmx push esi push edi mov edi, [esp + 8 + 4] ; data mov esi, [esp + 8 + 8] ; coeff mov eax, [esp + 8 + 12] ; quant movq mm7, [mmx_mul_quant + eax*8 - 8] movq mm6, [mmx_one] xor eax, eax pxor mm5, mm5 ; mismatch sum align 16 .loop movq mm0, [esi + 8*eax] ; mm0 = [coeff] pxor mm1, mm1 ; mm1 = 0 pcmpeqw mm1, mm0 ; mm1 = (0 == mm0) pxor mm2, mm2 ; mm2 = 0 pcmpgtw mm2, mm0 ; mm2 = (0 > mm0) pxor mm0, mm2 ; mm0 = |mm0| psubw mm0, mm2 ; displace psllw mm0, 1 ; paddsw mm0, mm6 ; mm0 = 2*mm0 + 1 pmullw mm0, mm7 ; mm0 *= quant movq mm3, [inter_matrix + 8*eax] movq mm4, mm0 pmullw mm0, mm3 ; mm0 = low(mm0 * mm3) pmulhw mm3, mm4 ; mm3 = high(mm0 * mm3) movq mm4, mm0 ; mm0,mm4 = unpack(mm3, mm0) punpcklwd mm0, mm3 ; punpckhwd mm4, mm3 ; psrad mm0, 4 ; mm0,mm4 /= 16 psrad mm4, 4 ; packssdw mm0, mm4 ; mm0 = pack(mm4, mm0) pxor mm0, mm2 ; mm0 *= sign(mm0) psubw mm0, mm2 ; undisplace pandn mm1, mm0 ; mm1 = ~(iszero) & mm0 ;%ifdef SATURATE movq mm2, [mmx_32767_minus_2047] movq mm4, [mmx_32768_minus_2048] paddsw mm1, mm2 psubsw mm1, mm2 psubsw mm1, mm4 paddsw mm1, mm4 ;%endif pxor mm5, mm1 ; mismatch movq [edi + 8*eax], mm1 ; [data] = mm0 add eax, 1 cmp eax, 16 jnz near .loop ; mismatch control movq mm0, mm5 movq mm1, mm5 movq mm2, mm5 psrlq mm0, 48 psrlq mm1, 32 psrlq mm2, 16 pxor mm5, mm0 pxor mm5, mm1 pxor mm5, mm2 movd eax, mm5 test eax, 0x1 jnz .done xor word [edi + 2*63], 1 .done pop edi pop esi ret xvid_20020412/xvidcore/src/quant/adapt_quant.c0100644000100600001440000000567207442432717020551 0ustar michaelusers#include "../portab.h" #include "adapt_quant.h" #include /* free, malloc */ #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define RDIFF(a,b) ((int)(a+0.5)-(int)(b+0.5)) int normalize_quantizer_field(float *in, int *out, int num, int min_quant, int max_quant) { int i; int finished; do { finished = 1; for(i = 1; i < num; i++) { if(RDIFF(in[i], in[i-1]) > 2) { in[i] -= (float) 0.5; finished = 0; } else if(RDIFF(in[i], in[i-1]) < -2) { in[i-1] -= (float) 0.5; finished = 0; } if(in[i] > max_quant) { in[i] = (float) max_quant; finished = 0; } if(in[i] < min_quant) { in[i] = (float) min_quant; finished = 0; } if(in[i-1] > max_quant) { in[i-1] = (float) max_quant; finished = 0; } if(in[i-1] < min_quant) { in[i-1] = (float) min_quant; finished = 0; } } } while(!finished); out[0] = 0; for (i = 1; i < num; i++) out[i] = RDIFF(in[i], in[i-1]); return (int) (in[0] + 0.5); } int adaptive_quantization(unsigned char* buf, int stride, int* intquant, int framequant, int min_quant, int max_quant, int mb_width, int mb_height) // no qstride because normalization { int i,j,k,l; static float *quant; unsigned char *ptr; float *val; float global = 0.; uint32_t mid_range = 0; const float DarkAmpl = 14 / 2; const float BrightAmpl = 10 / 2; const float DarkThres = 70; const float BrightThres = 200; const float GlobalDarkThres = 60; const float GlobalBrightThres = 170; const float MidRangeThres = 20; const float UpperLimit = 200; const float LowerLimit = 25; if(!quant) if(!(quant = (float *) malloc(mb_width*mb_height * sizeof(float)))) return -1; val = (float *) malloc(mb_width*mb_height * sizeof(float)); for(k = 0; k < mb_height; k++) { for(l = 0;l < mb_width; l++) // do this for all macroblocks individually { quant[k*mb_width+l] = (float) framequant; // calculate luminance-masking ptr = &buf[16*k*stride+16*l]; // address of MB val[k*mb_width+l] = 0.; for(i = 0; i < 16; i++) for(j = 0; j < 16; j++) val[k*mb_width+l] += ptr[i*stride+j]; val[k*mb_width+l] /= 256.; global += val[k*mb_width+l]; if((val[k*mb_width+l] > LowerLimit) && (val[k*mb_width+l] < UpperLimit)) mid_range++; } } global /= mb_width*mb_height; if(((global < GlobalBrightThres) && (global > GlobalDarkThres)) || (mid_range < MidRangeThres)) { for(k = 0; k < mb_height; k++) { for(l = 0;l < mb_width; l++) // do this for all macroblocks individually { if(val[k*mb_width+l] < DarkThres) quant[k*mb_width+l] += DarkAmpl*(DarkThres-val[k*mb_width+l])/DarkThres; else if (val[k*mb_width+l]>BrightThres) quant[k*mb_width+l] += BrightAmpl*(val[k*mb_width+l]-BrightThres)/(255-BrightThres); } } } free(val); return normalize_quantizer_field(quant, intquant, mb_width*mb_height, min_quant, max_quant); } xvid_20020412/xvidcore/src/quant/adapt_quant.h0100644000100600001440000000042407450701665020544 0ustar michaelusers#ifndef _ADAPT_QUANT_H_ #define _ADAPT_QUANT_H_ int adaptive_quantization(unsigned char* buf, int stride, int* intquant, int framequant, int min_quant, int max_quant, int mb_width, int mb_height); // no qstride because normalization #endif /* _ADAPT_QUANT_H_ */ xvid_20020412/xvidcore/src/quant/quant_mpeg4.c0100644000100600001440000001600007442207031020444 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * mpeg-4 quantization/dequantization * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 26.01.2002 fixed quant4_intra dcscalar signed/unsigned error * 20.01.2002 increased accuracy of >> divide * 26.12.2001 divide-by-multiplication optimization * 22.12.2001 [-127,127] clamping removed; minor tweaks * 19.11.2001 inital version * *************************************************************************/ #include "quant_mpeg4.h" #include "quant_matrix.h" // function pointers quant_intraFuncPtr quant4_intra; quant_intraFuncPtr dequant4_intra; dequant_interFuncPtr dequant4_inter; quant_interFuncPtr quant4_inter; #define DIV_DIV(A,B) ( (A) > 0 ? ((A)+((B)>>1))/(B) : ((A)-((B)>>1))/(B) ) #define SIGN(A) ((A)>0?1:-1) #define VM18P 3 #define VM18Q 4 // divide-by-multiply table // need 17 bit shift (16 causes slight errors when q > 19) #define SCALEBITS 17 #define FIX(X) ((1UL << SCALEBITS) / (X) + 1) static const uint32_t multipliers[32] = { 0, FIX(2), FIX(4), FIX(6), FIX(8), FIX(10), FIX(12), FIX(14), FIX(16), FIX(18), FIX(20), FIX(22), FIX(24), FIX(26), FIX(28), FIX(30), FIX(32), FIX(34), FIX(36), FIX(38), FIX(40), FIX(42), FIX(44), FIX(46), FIX(48), FIX(50), FIX(52), FIX(54), FIX(56), FIX(58), FIX(60), FIX(62) }; /* quantize intra-block // const int32_t quantd = DIV_DIV(VM18P*quant, VM18Q); // // level = DIV_DIV(16 * data[i], default_intra_matrix[i]); // coeff[i] = (level + quantd) / quant2; */ void quant4_intra_c(int16_t * coeff, const int16_t * data, const uint32_t quant, const uint32_t dcscalar) { const uint32_t quantd = ((VM18P*quant) + (VM18Q/2)) / VM18Q; const uint32_t mult = multipliers[quant]; uint32_t i; int16_t *intra_matrix; intra_matrix = get_intra_matrix(); coeff[0] = DIV_DIV(data[0], (int32_t)dcscalar); for (i = 1; i < 64; i++) { if (data[i] < 0) { uint32_t level = -data[i]; level = ((level<<4) + (intra_matrix[i]>>1)) / intra_matrix[i]; level = ((level + quantd) * mult) >> 17; coeff[i] = -(int16_t)level; } else if (data[i] > 0) { uint32_t level = data[i]; level = ((level<<4) + (intra_matrix[i]>>1)) / intra_matrix[i]; level = ((level + quantd) * mult) >> 17; coeff[i] = level; } else { coeff[i] = 0; } } } /* dequantize intra-block & clamp to [-2048,2047] // data[i] = (coeff[i] * default_intra_matrix[i] * quant2) >> 4; */ void dequant4_intra_c(int16_t *data, const int16_t *coeff, const uint32_t quant, const uint32_t dcscalar) { uint32_t i; int16_t *intra_matrix; intra_matrix = get_intra_matrix(); data[0] = coeff[0] * dcscalar; if (data[0] < -2048) { data[0] = -2048; } else if (data[0] > 2047) { data[0] = 2047; } for (i = 1; i < 64; i++) { if (coeff[i] == 0) { data[i] = 0; } else if (coeff[i] < 0) { uint32_t level = -coeff[i]; level = (level * intra_matrix[i] * quant) >> 3; data[i] = (level <= 2048 ? -(int16_t)level : -2048); } else // if (coeff[i] > 0) { uint32_t level = coeff[i]; level = (level * intra_matrix[i] * quant) >> 3; data[i] = (level <= 2047 ? level : 2047); } } } /* quantize inter-block // level = DIV_DIV(16 * data[i], default_intra_matrix[i]); // coeff[i] = (level + quantd) / quant2; // sum += abs(level); */ uint32_t quant4_inter_c(int16_t * coeff, const int16_t * data, const uint32_t quant) { const uint32_t mult = multipliers[quant]; uint32_t sum = 0; uint32_t i; int16_t *inter_matrix; inter_matrix = get_inter_matrix(); for (i = 0; i < 64; i++) { if (data[i] < 0) { uint32_t level = -data[i]; level = ((level<<4) + (inter_matrix[i]>>1)) / inter_matrix[i]; level = (level * mult) >> 17; sum += level; coeff[i] = -(int16_t)level; } else if (data[i] > 0) { uint32_t level = data[i]; level = ((level<<4) + (inter_matrix[i]>>1)) / inter_matrix[i]; level = (level * mult) >> 17; sum += level; coeff[i] = level; } else { coeff[i] = 0; } } return sum; } /* dequantize inter-block & clamp to [-2048,2047] data = ((2 * coeff + SIGN(coeff)) * inter_matrix[i] * quant) / 16 */ void dequant4_inter_c(int16_t *data, const int16_t *coeff, const uint32_t quant) { uint32_t sum = 0; uint32_t i; int16_t *inter_matrix; inter_matrix = get_inter_matrix(); for (i = 0; i < 64; i++) { if (coeff[i] == 0) { data[i] = 0; } else if (coeff[i] < 0) { int32_t level = -coeff[i]; level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4; data[i] = (level <= 2048 ? -level : -2048); } else // if (coeff[i] > 0) { uint32_t level = coeff[i]; level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4; data[i] = (level <= 2047 ? level : 2047); } sum ^= data[i]; } // mismatch control if ((sum & 1) == 0) { data[63] ^= 1; } } xvid_20020412/xvidcore/src/quant/quant_mpeg4.h0100644000100600001440000000206107450701665020466 0ustar michaelusers#ifndef _QUANT_MPEG4_H_ #define _QUANT_MPEG4_H_ #include "../portab.h" // intra typedef void (quant_intraFunc)(int16_t * coeff, const int16_t * data, const uint32_t quant, const uint32_t dcscalar); typedef quant_intraFunc* quant_intraFuncPtr; extern quant_intraFuncPtr quant4_intra; extern quant_intraFuncPtr dequant4_intra; quant_intraFunc quant4_intra_c; quant_intraFunc quant4_intra_mmx; quant_intraFunc dequant4_intra_c; quant_intraFunc dequant4_intra_mmx; // inter_quant typedef uint32_t (quant_interFunc)(int16_t *coeff, const int16_t *data, const uint32_t quant); typedef quant_interFunc* quant_interFuncPtr; extern quant_interFuncPtr quant4_inter; quant_interFunc quant4_inter_c; quant_interFunc quant4_inter_mmx; //inter_dequant typedef void (dequant_interFunc)(int16_t *coeff, const int16_t *data, const uint32_t quant); typedef dequant_interFunc* dequant_interFuncPtr; extern dequant_interFuncPtr dequant4_inter; dequant_interFunc dequant4_inter_c; dequant_interFunc dequant4_inter_mmx; #endif /* _QUANT_MPEG4_H_ */ xvid_20020412/xvidcore/src/utils/0040755000100600001440000000000007455522450016103 5ustar michaelusersxvid_20020412/xvidcore/src/utils/CVS/0040755000100600001440000000000007455522450016536 5ustar michaelusersxvid_20020412/xvidcore/src/utils/CVS/Root0100644000100600001440000000004607455522447017407 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/utils/CVS/Repository0100644000100600001440000000002307455522447020636 0ustar michaelusersxvidcore/src/utils xvid_20020412/xvidcore/src/utils/CVS/Entries.Log0100644000100600001440000000002007455522450020577 0ustar michaelusersA D/x86_asm//// xvid_20020412/xvidcore/src/utils/CVS/Entries0100644000100600001440000000103307455522450020064 0ustar michaelusers/emms.c/1.1.1.1/Fri Mar 8 02:44:58 2002// /emms.h/1.1.1.1/Fri Mar 8 02:44:58 2002// /mbfunctions.h/1.4/Fri Mar 29 00:38:29 2002// /mbtransquant.c/1.4/Fri Mar 29 00:38:29 2002// /mem_align.c/1.4/Sun Mar 24 18:18:40 2002// /mem_align.h/1.2/Wed Mar 20 00:28:02 2002// /mem_transfer.c/1.1.1.1/Fri Mar 8 02:44:59 2002// /mem_transfer.h/1.2/Thu Mar 28 20:57:25 2002// /ratecontrol.c/1.8/Sun Apr 7 11:57:47 2002// /ratecontrol.h/1.2/Sun Mar 24 05:47:23 2002// /timer.c/1.2/Tue Mar 26 11:16:08 2002// /timer.h/1.3/Thu Mar 28 20:57:25 2002// D xvid_20020412/xvidcore/src/utils/x86_asm/0040755000100600001440000000000007455522450017370 5ustar michaelusersxvid_20020412/xvidcore/src/utils/x86_asm/CVS/0040755000100600001440000000000007455522450020023 5ustar michaelusersxvid_20020412/xvidcore/src/utils/x86_asm/CVS/Root0100644000100600001440000000004607455522450020666 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/utils/x86_asm/CVS/Repository0100644000100600001440000000003307455522450022116 0ustar michaelusersxvidcore/src/utils/x86_asm xvid_20020412/xvidcore/src/utils/x86_asm/CVS/Entries0100644000100600001440000000015107455522450021351 0ustar michaelusers/cpuid.asm/1.1.1.1/Fri Mar 8 02:45:00 2002// /mem_transfer_mmx.asm/1.1.1.1/Fri Mar 8 02:45:01 2002// D xvid_20020412/xvidcore/src/utils/x86_asm/mem_transfer_mmx.asm0100644000100600001440000002170507442022655023435 0ustar michaelusers;/************************************************************************** ; * ; * XVID MPEG-4 VIDEO CODEC ; * mmx 8bit<->16bit transfers ; * ; * This program is an implementation of a part of one or more MPEG-4 ; * Video tools as specified in ISO/IEC 14496-2 standard. Those intending ; * to use this software module in hardware or software products are ; * advised that its use may infringe existing patents or copyrights, and ; * any such use would be at such party's own risk. The original ; * developer of this software module and his/her company, and subsequent ; * editors and their companies, will have no liability for use of this ; * software or modifications or derivatives thereof. ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * This program is distributed in the hope that it will be useful, ; * but WITHOUT ANY WARRANTY; without even the implied warranty of ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; * GNU General Public License for more details. ; * ; * You should have received a copy of the GNU General Public License ; * along with this program; if not, write to the Free Software ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; * ; *************************************************************************/ ;/************************************************************************** ; * ; * History: ; * ; * 07.01.2002 merge functions from compensate_mmx; rename functions ; * 07.11.2001 initial version; (c)2001 peter ross ; * ; *************************************************************************/ bits 32 %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro section .text ;=========================================================================== ; ; void transfer_8to16copy_mmx(int16_t * const dst, ; const uint8_t * const src, ; uint32_t stride); ; ;=========================================================================== align 16 cglobal transfer_8to16copy_mmx transfer_8to16copy_mmx push esi push edi mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov ecx, [esp + 8 + 12] ; stride pxor mm7, mm7 ; mm7 = zero mov eax, 8 .loop movq mm0, [esi] movq mm1, mm0 punpcklbw mm0, mm7 ; mm01 = unpack([src]) punpckhbw mm1, mm7 movq [edi], mm0 ; [dst] = mm01 movq [edi + 8], mm1 add edi, 16 add esi, ecx dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void transfer_16to8copy_mmx(uint8_t * const dst, ; const int16_t * const src, ; uint32_t stride); ; ;=========================================================================== align 16 cglobal transfer_16to8copy_mmx transfer_16to8copy_mmx push esi push edi mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov ecx, [esp + 8 + 12] ; stride mov eax, 8 .loop movq mm0, [esi] packuswb mm0, [esi + 8] ; mm0 = pack([src]) movq [edi], mm0 ; [dst] = mm0 add esi, 16 add edi, ecx dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void transfer_8to16sub_mmx(int16_t * const dct, ; uint8_t * const cur, ; const uint8_t * const ref, ; const uint32_t stride); ; ;=========================================================================== ;/************************************************************************** ; * ; * History: ; * ; * 27.12.2001 renamed from 'compensate' to 'transfer_8to16sub' ; * 02.12.2001 loop unrolled, code runs 10% faster now (Isibaar) ; * 30.11.2001 16 pixels are processed per iteration (Isibaar) ; * 30.11.2001 .text missing ; * 06.11.2001 inital version; (c)2001 peter ross ; * ; *************************************************************************/ align 16 cglobal transfer_8to16sub_mmx transfer_8to16sub_mmx push esi push edi push ebx mov edi, [esp + 12 + 4] ; dct [out] mov edx, [esp + 12 + 8] ; cur [in/out] mov esi, [esp + 12 + 12] ; ref [in] mov ecx, [esp + 12 + 16] ; stride [in] mov eax, edx ; cur -> eax mov ebx, esi ; ref -> ebx add eax, ecx ; cur + stride add ebx, ecx ; ref + stride shl ecx, 1 pxor mm7, mm7 ; mm7 = zero movq mm0, [edx] ; mm01 = [cur] movq mm1, mm0 punpcklbw mm0, mm7 punpckhbw mm1, mm7 movq mm4, [eax] movq mm5, mm4 punpcklbw mm4, mm7 punpckhbw mm5, mm7 movq mm2, [esi] ; mm23 = [ref] movq mm3, mm2 movq mm6, [ebx] movq [edx], mm2 ; [cur] = [ref] movq [eax], mm6 punpcklbw mm2, mm7 punpckhbw mm3, mm7 psubsw mm0, mm2 ; mm01 -= mm23 movq mm2, mm6 punpcklbw mm2, mm7 punpckhbw mm6, mm7 psubsw mm1, mm3 psubsw mm4, mm2 psubsw mm5, mm6 movq [edi], mm0 ; dct[] = mm01 movq [edi + 8], mm1 movq [edi + 16], mm4 movq [edi + 24], mm5 add edx, ecx add esi, ecx add eax, ecx add ebx, ecx movq mm0, [edx] ; mm01 = [cur] movq mm1, mm0 punpcklbw mm0, mm7 punpckhbw mm1, mm7 movq mm4, [eax] movq mm5, mm4 punpcklbw mm4, mm7 punpckhbw mm5, mm7 movq mm2, [esi] ; mm23 = [ref] movq mm3, mm2 movq mm6, [ebx] movq [edx], mm2 ; [cur] = [ref] movq [eax], mm6 punpcklbw mm2, mm7 punpckhbw mm3, mm7 psubsw mm0, mm2 ; mm01 -= mm23 movq mm2, mm6 punpcklbw mm2, mm7 punpckhbw mm6, mm7 psubsw mm1, mm3 psubsw mm4, mm2 psubsw mm5, mm6 movq [edi + 32], mm0 ; dct[] = mm01 movq [edi + 40], mm1 movq [edi + 48], mm4 movq [edi + 56], mm5 add edx, ecx add esi, ecx add eax, ecx add ebx, ecx movq mm0, [edx] ; mm01 = [cur] movq mm1, mm0 punpcklbw mm0, mm7 punpckhbw mm1, mm7 movq mm4, [eax] movq mm5, mm4 punpcklbw mm4, mm7 punpckhbw mm5, mm7 movq mm2, [esi] ; mm23 = [ref] movq mm3, mm2 movq mm6, [ebx] movq [edx], mm2 ; [cur] = [ref] movq [eax], mm6 punpcklbw mm2, mm7 punpckhbw mm3, mm7 psubsw mm0, mm2 ; mm01 -= mm23 movq mm2, mm6 punpcklbw mm2, mm7 punpckhbw mm6, mm7 psubsw mm1, mm3 psubsw mm4, mm2 psubsw mm5, mm6 movq [edi + 64], mm0 ; dct[] = mm01 movq [edi + 72], mm1 movq [edi + 80], mm4 movq [edi + 88], mm5 add edx, ecx add esi, ecx add eax, ecx add ebx, ecx movq mm0, [edx] ; mm01 = [cur] movq mm1, mm0 punpcklbw mm0, mm7 punpckhbw mm1, mm7 movq mm4, [eax] movq mm5, mm4 punpcklbw mm4, mm7 punpckhbw mm5, mm7 movq mm2, [esi] ; mm23 = [ref] movq mm3, mm2 movq mm6, [ebx] movq [edx], mm2 ; [cur] = [ref] movq [eax], mm6 punpcklbw mm2, mm7 punpckhbw mm3, mm7 psubsw mm0, mm2 ; mm01 -= mm23 movq mm2, mm6 punpcklbw mm2, mm7 punpckhbw mm6, mm7 psubsw mm1, mm3 psubsw mm4, mm2 psubsw mm5, mm6 movq [edi + 96], mm0 ; dct[] = mm01 movq [edi + 104], mm1 movq [edi + 112], mm4 movq [edi + 120], mm5 pop ebx pop edi pop esi ret ;=========================================================================== ; ; void transfer_16to8add_mmx(uint8_t * const dst, ; const int16_t * const src, ; uint32_t stride); ; ;=========================================================================== align 16 cglobal transfer_16to8add_mmx transfer_16to8add_mmx push esi push edi mov edi, [esp + 8 + 4] ; dst mov esi, [esp + 8 + 8] ; src mov ecx, [esp + 8 + 12] ; stride pxor mm7, mm7 mov eax, 8 .loop movq mm0, [edi] movq mm1, mm0 punpcklbw mm0, mm7 ; mm23 = unpack([dst]) punpckhbw mm1, mm7 movq mm2, [esi] ; mm01 = [src] movq mm3, [esi + 8] paddsw mm0, mm2 ; mm01 += mm23 paddsw mm1, mm3 packuswb mm0, mm1 ; [dst] = pack(mm01) movq [edi], mm0 add esi, 16 add edi, ecx dec eax jnz .loop pop edi pop esi ret ;=========================================================================== ; ; void transfer8x8_copy_mmx(uint8_t * const dst, ; const uint8_t * const src, ; const uint32_t stride); ; ; ;=========================================================================== align 16 cglobal transfer8x8_copy_mmx transfer8x8_copy_mmx push esi push edi mov edi, [esp + 8 + 4] ; dst [out] mov esi, [esp + 8 + 8] ; src [in] mov eax, [esp + 8 + 12] ; stride [in] movq mm0, [esi] movq mm1, [esi+eax] movq [edi], mm0 movq [edi+eax], mm1 add esi, eax add edi, eax add esi, eax add edi, eax movq mm0, [esi] movq mm1, [esi+eax] movq [edi], mm0 movq [edi+eax], mm1 add esi, eax add edi, eax add esi, eax add edi, eax movq mm0, [esi] movq mm1, [esi+eax] movq [edi], mm0 movq [edi+eax], mm1 add esi, eax add edi, eax add esi, eax add edi, eax movq mm0, [esi] movq mm1, [esi+eax] movq [edi], mm0 movq [edi+eax], mm1 add esi, eax add edi, eax add esi, eax add edi, eax pop edi pop esi ret xvid_20020412/xvidcore/src/utils/x86_asm/cpuid.asm0100644000100600001440000001346607442022654021202 0ustar michaelusers;/****************************************************************************** ; * * ; * This file is part of XviD, a free MPEG-4 video encoder/decoder * ; * * ; * XviD is an implementation of a part of one or more MPEG-4 Video tools * ; * as specified in ISO/IEC 14496-2 standard. Those intending to use this * ; * software module in hardware or software products are advised that its * ; * use may infringe existing patents or copyrights, and any such use * ; * would be at such party's own risk. The original developer of this * ; * software module and his/her company, and subsequent editors and their * ; * companies, will have no liability for use of this software or * ; * modifications or derivatives thereof. * ; * * ; * XviD is free software; you can redistribute it and/or modify it * ; * under the terms of the GNU General Public License as published by * ; * the Free Software Foundation; either version 2 of the License, or * ; * (at your option) any later version. * ; * * ; * XviD is distributed in the hope that it will be useful, but * ; * WITHOUT ANY WARRANTY; without even the implied warranty of * ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ; * GNU General Public License for more details. * ; * * ; * You should have received a copy of the GNU General Public License * ; * along with this program; if not, write to the Free Software * ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * cpuid.asm, check cpu features * ; * * ; * Copyright (C) 2001 - Michael Militzer , * ; * * ; * For more information visit the XviD homepage: http://www.xvid.org * ; * * ; ******************************************************************************/ ; ;/****************************************************************************** ; * * ; * Revision history: * ; * * ; * 17.12.2001 initial version (Isibaar) * ; * * ; ******************************************************************************/ bits 32 %define CPUID_TSC 0x00000010 %define CPUID_MMX 0x00800000 %define CPUID_SSE 0x02000000 %define CPUID_SSE2 0x04000000 %define EXT_CPUID_3DNOW 0x80000000 %define EXT_CPUID_AMD_3DNOWEXT 0x40000000 %define EXT_CPUID_AMD_MMXEXT 0x00400000 %define XVID_CPU_MMX 0x00000001 %define XVID_CPU_MMXEXT 0x00000002 %define XVID_CPU_SSE 0x00000004 %define XVID_CPU_SSE2 0x00000008 %define XVID_CPU_3DNOW 0x00000010 %define XVID_CPU_3DNOWEXT 0x00000020 %define XVID_CPU_TSC 0x00000040 %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro ALIGN 32 section .data features dd 0 vendor dd 0,0,0 vendorAMD db "AuthenticAMD" %macro CHECK_FEATURE 3 mov ecx, %1 and ecx, edx neg ecx sbb ecx, ecx and ecx, %2 or [%3], ecx %endmacro section .text ; int check_cpu_feature(void) cglobal check_cpu_features check_cpu_features: pushad pushfd ; CPUID command ? pop eax mov ecx, eax xor eax, 0x200000 push eax popfd pushfd pop eax cmp eax, ecx jz near .cpu_quit ; no CPUID command -> exit ; get vendor string, used later xor eax, eax cpuid mov [vendor], ebx ; vendor string mov [vendor+4], edx mov [vendor+8], ecx test eax, eax jz near .cpu_quit mov eax, 1 cpuid ; RDTSC command ? CHECK_FEATURE CPUID_TSC, XVID_CPU_TSC, features ; MMX support ? CHECK_FEATURE CPUID_MMX, XVID_CPU_MMX, features ; SSE support ? CHECK_FEATURE CPUID_SSE, (XVID_CPU_MMXEXT+XVID_CPU_SSE), features ; SSE2 support? CHECK_FEATURE CPUID_SSE2, XVID_CPU_SSE2, features ; extended functions? mov eax, 0x80000000 cpuid cmp eax, 0x80000000 jbe near .cpu_quit mov eax, 0x80000001 cpuid ; 3DNow! support ? CHECK_FEATURE EXT_CPUID_3DNOW, XVID_CPU_3DNOW, features ; AMD cpu ? lea esi, [vendorAMD] lea edi, [vendor] mov ecx, 12 cld repe cmpsb jnz .cpu_quit ; 3DNOW extended ? CHECK_FEATURE EXT_CPUID_AMD_3DNOWEXT, XVID_CPU_3DNOWEXT, features ; extended MMX ? CHECK_FEATURE EXT_CPUID_AMD_MMXEXT, XVID_CPU_MMXEXT, features .cpu_quit: popad mov eax, [features] ret xvid_20020412/xvidcore/src/utils/timer.c0100644000100600001440000002246607450054170017370 0ustar michaelusers /****************************************************************************** * * * This file is part of XviD, a free MPEG-4 video encoder/decoder * * * * XviD is an implementation of a part of one or more MPEG-4 Video tools * * as specified in ISO/IEC 14496-2 standard. Those intending to use this * * software module in hardware or software products are advised that its * * use may infringe existing patents or copyrights, and any such use * * would be at such party's own risk. The original developer of this * * software module and his/her company, and subsequent editors and their * * companies, will have no liability for use of this software or * * modifications or derivatives thereof. * * * * XviD is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * XviD is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * ******************************************************************************/ /****************************************************************************** * * * timer.c, some timing functions * * * * Copyright (C) 2001 - Michael Militzer * * * * For more information visit the XviD homepage: http://www.xvid.org * * * ******************************************************************************/ /****************************************************************************** * * * Revision history: * * * 26.03.2002 interlacing timer added * 21.12.2001 edges error fixed * 17.11.2001 small clean up (Isibaar) * * 13.11.2001 inlined rdtsc call and moved to portab.h (Isibaar) * * 02.11.2001 initial version (Isibaar) * * * ******************************************************************************/ #include #include #include "timer.h" #if defined(_PROFILING_) struct ts { int64_t current; int64_t global; int64_t overall; int64_t dct; int64_t idct; int64_t quant; int64_t iquant; int64_t motion; int64_t comp; int64_t edges; int64_t inter; int64_t conv; int64_t trans; int64_t prediction; int64_t coding; int64_t interlacing; }; struct ts tim; double frequency = 0.0; /* determine cpu frequency not very precise but sufficient */ double get_freq() { int64_t x,y; int32_t i; i = time(NULL); while(i == time(NULL)); x = read_counter(); i++; while(i == time(NULL)); y = read_counter(); return (double) (y - x) / 1000.; } // set everything to zero // void init_timer() { frequency = get_freq(); count_frames = 0; tim.dct = tim.quant = tim.idct = tim.iquant = tim.motion = tim.conv = tim.edges = tim.inter = tim.interlacing = tim.trans = tim.trans = tim.coding = tim.global = tim.overall = 0; } void start_timer() { tim.current = read_counter(); } void start_global_timer() { tim.global = read_counter(); } void stop_dct_timer() { tim.dct += (read_counter() - tim.current); } void stop_idct_timer() { tim.idct += (read_counter() - tim.current); } void stop_quant_timer() { tim.quant += (read_counter() - tim.current); } void stop_iquant_timer() { tim.iquant += (read_counter() - tim.current); } void stop_motion_timer() { tim.motion += (read_counter() - tim.current); } void stop_comp_timer() { tim.comp += (read_counter() - tim.current); } void stop_edges_timer() { tim.edges += (read_counter() - tim.current); } void stop_inter_timer() { tim.inter += (read_counter() - tim.current); } void stop_conv_timer() { tim.conv += (read_counter() - tim.current); } void stop_transfer_timer() { tim.trans += (read_counter() - tim.current); } void stop_prediction_timer() { tim.prediction += (read_counter() - tim.current); } void stop_coding_timer() { tim.coding += (read_counter() - tim.current); } void stop_interlacing_timer() { tim.interlacing += (read_counter() - tim.current); } void stop_global_timer() { tim.overall += (read_counter() - tim.global); } /* write log file with some timer information */ void write_timer() { float dct_per, quant_per, idct_per, iquant_per, mot_per, comp_per, interlacing_per; float edges_per, inter_per, conv_per, trans_per, pred_per, cod_per, measured; int64_t sum_ticks = 0; count_frames++; // only write log file every 50 processed frames // if(count_frames % 50) { FILE *fp; fp = fopen("encoder.log", "w+"); dct_per = (float) (((float) ((float) tim.dct / (float) tim.overall)) * 100.0); quant_per = (float) (((float) ((float) tim.quant / (float) tim.overall)) * 100.0); idct_per = (float) (((float) ((float) tim.idct / (float) tim.overall)) * 100.0); iquant_per = (float) (((float) ((float) tim.iquant / (float) tim.overall)) * 100.0); mot_per = (float) (((float) ((float) tim.motion / (float) tim.overall)) * 100.0); comp_per = (float) (((float) ((float) tim.comp / (float) tim.overall)) * 100.0); edges_per = (float) (((float) ((float) tim.edges / (float) tim.overall)) * 100.0); inter_per = (float) (((float) ((float) tim.inter / (float) tim.overall)) * 100.0); conv_per = (float) (((float) ((float) tim.conv / (float) tim.overall)) * 100.0); trans_per = (float) (((float) ((float) tim.trans / (float) tim.overall)) * 100.0); pred_per = (float) (((float) ((float) tim.prediction / (float) tim.overall)) * 100.0); cod_per = (float) (((float) ((float) tim.coding / (float) tim.overall)) * 100.0); interlacing_per = (float) (((float) ((float) tim.interlacing / (float) tim.overall)) * 100.0); sum_ticks = tim.coding + tim.conv + tim.dct + tim.idct + tim.interlacing + tim.edges + tim.inter + tim.iquant + tim.motion + tim.trans + tim.quant + tim.trans; measured = (float) (((float) ((float) sum_ticks / (float) tim.overall)) * 100.0); fprintf(fp, "DCT:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "Quant:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "IDCT:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "IQuant:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "Mot estimation:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "Mot compensation:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "Edges:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "Interpolation:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "RGB2YUV:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "Transfer:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "Prediction:\nTotal time: %f ms (%3f percent of total encoding time)\n\n" "Coding:\nTotal time: %f ms (%3f percent of total encoding time)\n\n\n" "Interlacing:\nTotal time: %f ms (%3f percent of total encoding time)\n\n\n" "Overall encoding time: %f ms, we measured %f ms (%3f percent)\n", (float) (tim.dct / frequency), dct_per, (float) (tim.quant / frequency), quant_per, (float) (tim.idct / frequency), idct_per, (float) (tim.iquant / frequency), iquant_per, (float) (tim.motion / frequency), mot_per, (float) (tim.comp / frequency), comp_per, (float) (tim.edges / frequency), edges_per, (float) (tim.inter / frequency), inter_per, (float) (tim.conv / frequency), conv_per, (float) (tim.trans / frequency), trans_per, (float) (tim.prediction / frequency), pred_per, (float) (tim.coding / frequency), cod_per, (float) (tim.interlacing / frequency), interlacing_per, (float) (tim.overall / frequency), (float) (sum_ticks / frequency), measured); fclose(fp); } } #endif xvid_20020412/xvidcore/src/utils/timer.h0100644000100600001440000000274707450701665017405 0ustar michaelusers#ifndef _ENCORE_TIMER_H #define _ENCORE_TIMER_H #if defined(_PROFILING_) #include "../portab.h" uint64_t count_frames; extern void start_timer(); extern void start_global_timer(); extern void stop_dct_timer(); extern void stop_idct_timer(); extern void stop_motion_timer(); extern void stop_comp_timer(); extern void stop_edges_timer(); extern void stop_inter_timer(); extern void stop_quant_timer(); extern void stop_iquant_timer(); extern void stop_conv_timer(); extern void stop_transfer_timer(); extern void stop_coding_timer(); extern void stop_prediction_timer(); extern void stop_interlacing_timer(); extern void stop_global_timer(); extern void init_timer(); extern void write_timer(); #else static __inline void start_timer() {} static __inline void start_global_timer() {} static __inline void stop_dct_timer() {} static __inline void stop_idct_timer() {} static __inline void stop_motion_timer() {} static __inline void stop_comp_timer() {} static __inline void stop_edges_timer() {} static __inline void stop_inter_timer() {} static __inline void stop_quant_timer() {} static __inline void stop_iquant_timer() {} static __inline void stop_conv_timer() {} static __inline void stop_transfer_timer() {} static __inline void init_timer() {} static __inline void write_timer() {} static __inline void stop_coding_timer() {} static __inline void stop_interlacing_timer() {} static __inline void stop_prediction_timer() {} static __inline void stop_global_timer() {} #endif #endif /* _TIMER_H_ */ xvid_20020412/xvidcore/src/utils/emms.c0100644000100600001440000000015107442022652017175 0ustar michaelusers#include "emms.h" #include "../portab.h" emmsFuncPtr emms; void emms_c() {} void emms_mmx() { EMMS(); } xvid_20020412/xvidcore/src/utils/emms.h0100644000100600001440000000023107442022652017201 0ustar michaelusersint check_cpu_features(void); typedef void (emmsFunc)(); typedef emmsFunc* emmsFuncPtr; extern emmsFuncPtr emms; emmsFunc emms_c; emmsFunc emms_mmx; xvid_20020412/xvidcore/src/utils/mbfunctions.h0100644000100600001440000000605007450733605020602 0ustar michaelusers/************************************************************************** * * Modifications: * * 29.03.2002 removed MBFieldToFrame - no longer used (transfers instead) * 26.03.2002 interlacing support * 02.12.2001 motion estimation/compensation split * 16.11.2001 const/uint32_t changes to MBMotionEstComp() * 26.08.2001 added inter4v_mode parameter to MBMotionEstComp() * * Michael Militzer * **************************************************************************/ #ifndef _ENCORE_BLOCK_H #define _ENCORE_BLOCK_H #include "../encoder.h" #include "../bitstream/bitstream.h" /** MotionEstimation **/ bool MotionEstimation( MACROBLOCK * const pMBs, MBParam * const pParam, const IMAGE * const pRef, const IMAGE * const pRefH, const IMAGE * const pRefV, const IMAGE * const pRefHV, IMAGE * const pCurrent, const uint32_t iLimit); /** MBMotionCompensation **/ void MBMotionCompensation( MACROBLOCK * const pMB, const uint32_t j, const uint32_t i, const IMAGE * const pRef, const IMAGE * const pRefH, const IMAGE * const pRefV, const IMAGE * const pRefHV, IMAGE * const pCurrent, int16_t dct_codes[6*64], const uint32_t width, const uint32_t height, const uint32_t edged_width, const uint32_t rounding); /** MBTransQuant.c **/ void MBTransQuantIntra(const MBParam *pParam, MACROBLOCK * pMB, const uint32_t x_pos, /* <-- The x position of the MB to be searched */ const uint32_t y_pos, /* <-- The y position of the MB to be searched */ int16_t data[6*64], /* <-> the data of the MB to be coded */ int16_t qcoeff[6*64], /* <-> the quantized DCT coefficients */ IMAGE * const pCurrent /* <-> the reconstructed image */ /* (function will update one MB in it with data from data[]) */ ); uint8_t MBTransQuantInter(const MBParam *pParam, /* <-- the parameter for DCT transformation and Quantization */ MACROBLOCK * pMB, const uint32_t x_pos, /* <-- The x position of the MB to be searched */ const uint32_t y_pos, /* <-- The y position of the MB to be searched */ int16_t data[6*64], /* <-> the data of the MB to be coded */ int16_t qcoeff[6*64], /* <-> the quantized DCT coefficients */ IMAGE * const pCurrent /* <-> the reconstructed image ( function will update one MB in it with data from data[] ) */ ); /** interlacing **/ uint32_t MBDecideFieldDCT(int16_t data[6*64]); /* <- decide whether to use field-based DCT for interlacing */ void MBFrameToField(int16_t data[6*64]); /* de-interlace vertical Y blocks */ /** MBCoding.c **/ void MBCoding(const MBParam *pParam, /* <-- the parameter for coding of the bitstream */ MACROBLOCK *pMB, /* <-- Info of the MB to be coded */ int16_t qcoeff[6*64], /* <-- the quantized DCT coefficients */ Bitstream * bs, /* <-> the bitstream */ Statistics * pStat /* <-> statistical data collected for current frame */ ); #endif xvid_20020412/xvidcore/src/utils/mem_align.c0100644000100600001440000000275207447414200020174 0ustar michaelusers#include #include #include "mem_align.h" void *xvid_malloc(size_t size, uint8_t alignment) { uint8_t *mem_ptr; if(!alignment) { /* We have not to satisfy any alignment */ if((mem_ptr = (uint8_t *) malloc(size + 1)) != NULL) { /* Store (mem_ptr - "real allocated memory") in *(mem_ptr-1) */ *mem_ptr = 0; /* Return the mem_ptr pointer */ return (void *) mem_ptr++; } } else { uint8_t *tmp; /* * Allocate the required size memory + alignment so we * can realign the data if necessary */ if((tmp = (uint8_t *) malloc(size + alignment)) != NULL) { /* Align the tmp pointer */ mem_ptr = (uint8_t *)((uint32_t)(tmp + alignment - 1)&(~(uint32_t)(alignment - 1))); /* * Special case where malloc have already satisfied the alignment * We must add alignment to mem_ptr because we must store * (mem_ptr - tmp) in *(mem_ptr-1) * If we do not add alignment to mem_ptr then *(mem_ptr-1) points * to a forbidden memory space */ if(mem_ptr == tmp) mem_ptr += alignment; /* * (mem_ptr - tmp) is stored in *(mem_ptr-1) so we are able to retrieve * the real malloc block allocated and free it in xvid_free */ *(mem_ptr - 1) = (uint8_t)(mem_ptr - tmp); /* Return the aligned pointer */ return (void *) mem_ptr; } } return NULL; } void xvid_free(void *mem_ptr) { /* *(mem_ptr - 1) give us the offset to the real malloc block */ free((uint8_t*)mem_ptr - *((uint8_t*)mem_ptr - 1)); } xvid_20020412/xvidcore/src/utils/mem_align.h0100644000100600001440000000026307445753622020210 0ustar michaelusers#ifndef _MEM_ALIGN_H_ #define _MEM_ALIGN_H_ #include "../portab.h" void *xvid_malloc(size_t size, uint8_t alignment); void xvid_free(void *mem_ptr); #endif /* _MEM_ALIGN_H_ */ xvid_20020412/xvidcore/src/utils/mem_transfer.c0100644000100600001440000000721407442022653020726 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * 8bit<->16bit transfer * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 07.01.2002 merge functions from compensate; rename functions * 22.12.2001 transfer_8to8add16 limit fix * 07.11.2001 initial version; (c)2001 peter ross * *************************************************************************/ #include "../global.h" #include "mem_transfer.h" // function pointers TRANSFER_8TO16COPY_PTR transfer_8to16copy; TRANSFER_16TO8COPY_PTR transfer_16to8copy; TRANSFER_8TO16SUB_PTR transfer_8to16sub; TRANSFER_16TO8ADD_PTR transfer_16to8add; TRANSFER8X8_COPY_PTR transfer8x8_copy; void transfer_8to16copy_c(int16_t * const dst, const uint8_t * const src, uint32_t stride) { uint32_t i, j; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { dst[j * 8 + i] = (int16_t)src[j * stride + i]; } } } void transfer_16to8copy_c(uint8_t * const dst, const int16_t * const src, uint32_t stride) { uint32_t i, j; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { int16_t pixel = src[j * 8 + i]; if (pixel < 0) { pixel = 0; } else if (pixel > 255) { pixel = 255; } dst[j * stride + i] = (uint8_t)pixel; } } } /* perform motion compensation (and 8bit->16bit dct transfer) */ void transfer_8to16sub_c(int16_t * const dct, uint8_t * const cur, const uint8_t * ref, const uint32_t stride) { uint32_t i, j; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { uint8_t c = cur[j * stride + i]; uint8_t r = ref[j * stride + i]; cur[j * stride + i] = r; dct[j * 8 + i] = (int16_t)c - (int16_t)r; } } } void transfer_16to8add_c(uint8_t * const dst, const int16_t * const src, uint32_t stride) { uint32_t i, j; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { int16_t pixel = (int16_t)dst[j * stride + i] + src[j * 8 + i]; if (pixel < 0) { pixel = 0; } else if (pixel > 255) { pixel = 255; } dst[j * stride + i] = (uint8_t)pixel; } } } void transfer8x8_copy_c(uint8_t * const dst, const uint8_t * const src, const uint32_t stride) { uint32_t i, j; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { dst[j * stride + i] = src[j * stride + i]; } } } xvid_20020412/xvidcore/src/utils/mem_transfer.h0100644000100600001440000000317007450701665020736 0ustar michaelusers#ifndef _MEM_TRANSFER_H #define _MEM_TRANSFER_H // transfer8to16 typedef void (TRANSFER_8TO16COPY)(int16_t * const dst, const uint8_t * const src, uint32_t stride); typedef TRANSFER_8TO16COPY* TRANSFER_8TO16COPY_PTR; extern TRANSFER_8TO16COPY_PTR transfer_8to16copy; TRANSFER_8TO16COPY transfer_8to16copy_c; TRANSFER_8TO16COPY transfer_8to16copy_mmx; // transfer16to8 typedef void (TRANSFER_16TO8COPY)(uint8_t * const dst, const int16_t * const src, uint32_t stride); typedef TRANSFER_16TO8COPY* TRANSFER_16TO8COPY_PTR; extern TRANSFER_16TO8COPY_PTR transfer_16to8copy; TRANSFER_16TO8COPY transfer_16to8copy_c; TRANSFER_16TO8COPY transfer_16to8copy_mmx; // transfer8to16sub typedef void (TRANSFER_8TO16SUB)(int16_t * const dct, uint8_t * const cur, const uint8_t * ref, const uint32_t stride); typedef TRANSFER_8TO16SUB* TRANSFER_8TO16SUB_PTR; extern TRANSFER_8TO16SUB_PTR transfer_8to16sub; TRANSFER_8TO16SUB transfer_8to16sub_c; TRANSFER_8TO16SUB transfer_8to16sub_mmx; // transfer16to8add typedef void (TRANSFER_16TO8ADD)(uint8_t * const dst, const int16_t * const src, uint32_t stride); typedef TRANSFER_16TO8ADD* TRANSFER_16TO8ADD_PTR; extern TRANSFER_16TO8ADD_PTR transfer_16to8add; TRANSFER_16TO8ADD transfer_16to8add_c; TRANSFER_16TO8ADD transfer_16to8add_mmx; // transfer8x8_copy typedef void (TRANSFER8X8_COPY)(uint8_t * const dst, const uint8_t * const src, const uint32_t stride); typedef TRANSFER8X8_COPY* TRANSFER8X8_COPY_PTR; extern TRANSFER8X8_COPY_PTR transfer8x8_copy; TRANSFER8X8_COPY transfer8x8_copy_c; TRANSFER8X8_COPY transfer8x8_copy_mmx; #endif /* _MEM_TRANSFER_H_ */ xvid_20020412/xvidcore/src/utils/ratecontrol.c0100644000100600001440000000616007454032073020577 0ustar michaelusers#include "ratecontrol.h" #include /* fabs */ #define ABS(X) (X < 0) ? (-X) : (X) typedef struct { int64_t size; int32_t count; } QuantInfo; typedef struct { int32_t rtn_quant; int64_t frames; int64_t total_size; double framerate; int32_t target_rate; int16_t max_quant; int16_t min_quant; int64_t last_change; int64_t quant_sum; double quant_error[32]; double avg_framesize; double target_framesize; int32_t reaction_delay_factor; } RateControl; RateControl rate_control; int get_initial_quant(int bpp) { return 5; } void RateControlInit(uint32_t target_rate, uint32_t reaction_delay_factor, int framerate, int max_quant, int min_quant) { int i; rate_control.frames = 0; rate_control.total_size = 0; rate_control.framerate = framerate / 1000.0; rate_control.target_rate = target_rate; rate_control.rtn_quant = get_initial_quant(0); rate_control.max_quant = max_quant; rate_control.min_quant = min_quant; for (i=0 ; i<32 ; ++i) { rate_control.quant_error[i] = 0.0; } rate_control.target_framesize = target_rate / rate_control.framerate; rate_control.avg_framesize = target_rate / rate_control.framerate; rate_control.reaction_delay_factor = reaction_delay_factor; } int RateControlGetQ(int keyframe) { return rate_control.rtn_quant; } void RateControlUpdate(int16_t quant, int frame_size, int keyframe) { int64_t deviation; double overflow, cur_target; int32_t rtn_quant; rate_control.frames++; rate_control.total_size += frame_size; deviation = (int64_t) ((double) rate_control.total_size - ((double) ((double) rate_control.target_rate / 8.0 / (double) rate_control.framerate) * (double) rate_control.frames)); DEBUGCBR((int32_t)(rate_control.frames - 1), rate_control.rtn_quant, (int32_t)deviation); rate_control.avg_framesize -= rate_control.avg_framesize / (double)rate_control.reaction_delay_factor; rate_control.avg_framesize += frame_size * rate_control.rtn_quant * 0.5 / (double)rate_control.reaction_delay_factor; if (rate_control.target_framesize > rate_control.avg_framesize) cur_target = rate_control.avg_framesize; else cur_target = rate_control.target_framesize; deviation /= -rate_control.reaction_delay_factor; overflow = (double)deviation * rate_control.avg_framesize / rate_control.target_framesize; if (overflow > cur_target) overflow = cur_target; else if (overflow < cur_target * -0.935) overflow = cur_target * -0.935; rtn_quant = (int32_t)(rate_control.avg_framesize * 2.0 / (cur_target + overflow)); if (rtn_quant < 31) { rate_control.quant_error[rtn_quant] += rate_control.avg_framesize * 2.0 / (cur_target + overflow) - rtn_quant; if (rate_control.quant_error[rtn_quant] >= 1.0) { rate_control.quant_error[rtn_quant] -= 1.0; rtn_quant++; } } if (rtn_quant > rate_control.rtn_quant + 1) rtn_quant = rate_control.rtn_quant + 1; else if (rtn_quant < rate_control.rtn_quant - 1) rtn_quant = rate_control.rtn_quant - 1; if (rtn_quant > rate_control.max_quant) rtn_quant = rate_control.max_quant; else if (rtn_quant < rate_control.min_quant) rtn_quant = rate_control.min_quant; rate_control.rtn_quant = rtn_quant; } xvid_20020412/xvidcore/src/utils/ratecontrol.h0100644000100600001440000000055107447264153020612 0ustar michaelusers#ifndef _RATECONTROL_H_ #define _RATECONTROL_H_ #include "../encoder.h" #include "../portab.h" void RateControlInit(uint32_t target_rate, uint32_t reaction_delay_factor, int framerate, int max_quant, int min_quant); int RateControlGetQ(int keyframe); void RateControlUpdate(int16_t quant, int frame_size, int keyframe); #endif /* _RATECONTROL_H_ */ xvid_20020412/xvidcore/src/utils/mbtransquant.c0100644000100600001440000002677407450733605021004 0ustar michaelusers /****************************************************************************** * * * This file is part of XviD, a free MPEG-4 video encoder/decoder * * * * XviD is an implementation of a part of one or more MPEG-4 Video tools * * as specified in ISO/IEC 14496-2 standard. Those intending to use this * * software module in hardware or software products are advised that its * * use may infringe existing patents or copyrights, and any such use * * would be at such party's own risk. The original developer of this * * software module and his/her company, and subsequent editors and their * * companies, will have no liability for use of this software or * * modifications or derivatives thereof. * * * * XviD is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * XviD is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * ******************************************************************************/ /****************************************************************************** * * * mbtransquant.c * * * * Copyright (C) 2001 - Peter Ross * * Copyright (C) 2001 - Michael Militzer * * * * For more information visit the XviD homepage: http://www.xvid.org * * * ******************************************************************************/ /****************************************************************************** * * * Revision history: * * * * 29.03.2002 interlacing speedup - used transfer strides instead of * manual field-to-frame conversion * 26.03.2002 interlacing support - moved transfers outside loops * 22.12.2001 get_dc_scaler() moved to common.h * 19.11.2001 introduced coefficient thresholding (Isibaar) * * 17.11.2001 initial version * * * ******************************************************************************/ #include #include "../portab.h" #include "mbfunctions.h" #include "../global.h" #include "mem_transfer.h" #include "timer.h" #include "../dct/fdct.h" #include "../dct/idct.h" #include "../quant/quant_mpeg4.h" #include "../quant/quant_h263.h" #include "../encoder.h" #define MIN(X, Y) ((X)<(Y)?(X):(Y)) #define MAX(X, Y) ((X)>(Y)?(X):(Y)) #define TOOSMALL_LIMIT 1 /* skip blocks having a coefficient sum below this value */ /* this isnt pretty, but its better than 20 ifdefs */ void MBTransQuantIntra(const MBParam *pParam, MACROBLOCK * pMB, const uint32_t x_pos, const uint32_t y_pos, int16_t data[6*64], int16_t qcoeff[6*64], IMAGE * const pCurrent) { uint32_t stride = pParam->edged_width; uint32_t stride2 = stride / 2; uint32_t next_block = stride * 8; uint32_t i; uint32_t iQuant = pParam->quant; uint8_t *pY_Cur, *pU_Cur, *pV_Cur; pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4); pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3); pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3); start_timer(); transfer_8to16copy(&data[0*64], pY_Cur, stride); transfer_8to16copy(&data[1*64], pY_Cur + 8, stride); transfer_8to16copy(&data[2*64], pY_Cur + next_block, stride); transfer_8to16copy(&data[3*64], pY_Cur + next_block + 8,stride); transfer_8to16copy(&data[4*64], pU_Cur, stride2); transfer_8to16copy(&data[5*64], pV_Cur, stride2); stop_transfer_timer(); start_timer(); pMB->field_dct = 0; if (pParam->global_flags & XVID_INTERLACING) { pMB->field_dct = MBDecideFieldDCT(data); } stop_interlacing_timer(); for(i = 0; i < 6; i++) { uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4); start_timer(); fdct(&data[i*64]); stop_dct_timer(); if (pParam->quant_type == H263_QUANT) { start_timer(); quant_intra(&qcoeff[i*64], &data[i*64], iQuant, iDcScaler); stop_quant_timer(); start_timer(); dequant_intra(&data[i*64], &qcoeff[i*64], iQuant, iDcScaler); stop_iquant_timer(); } else { start_timer(); quant4_intra(&qcoeff[i*64], &data[i*64], iQuant, iDcScaler); stop_quant_timer(); start_timer(); dequant4_intra(&data[i*64], &qcoeff[i*64], iQuant, iDcScaler); stop_iquant_timer(); } start_timer(); idct(&data[i*64]); stop_idct_timer(); } if (pMB->field_dct) { next_block = stride; stride *= 2; } start_timer(); transfer_16to8copy(pY_Cur, &data[0*64], stride); transfer_16to8copy(pY_Cur + 8, &data[1*64], stride); transfer_16to8copy(pY_Cur + next_block, &data[2*64], stride); transfer_16to8copy(pY_Cur + next_block + 8, &data[3*64], stride); transfer_16to8copy(pU_Cur, &data[4*64], stride2); transfer_16to8copy(pV_Cur, &data[5*64], stride2); stop_transfer_timer(); } uint8_t MBTransQuantInter(const MBParam *pParam, MACROBLOCK * pMB, const uint32_t x_pos, const uint32_t y_pos, int16_t data[6*64], int16_t qcoeff[6*64], IMAGE * const pCurrent) { uint32_t stride = pParam->edged_width; uint32_t stride2 = stride / 2; uint32_t next_block = stride * 8; uint32_t i; uint32_t iQuant = pParam->quant; uint8_t *pY_Cur, *pU_Cur, *pV_Cur; uint8_t cbp = 0; uint32_t sum; pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4); pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3); pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3); start_timer(); pMB->field_dct = 0; if (pParam->global_flags & XVID_INTERLACING) { pMB->field_dct = MBDecideFieldDCT(data); } stop_interlacing_timer(); for(i = 0; i < 6; i++) { /* * no need to transfer 8->16-bit * (this is performed already in motion compensation) */ start_timer(); fdct(&data[i*64]); stop_dct_timer(); if (pParam->quant_type == 0) { start_timer(); sum = quant_inter(&qcoeff[i*64], &data[i*64], iQuant); stop_quant_timer(); } else { start_timer(); sum = quant4_inter(&qcoeff[i*64], &data[i*64], iQuant); stop_quant_timer(); } if(sum >= TOOSMALL_LIMIT) { // skip block ? if (pParam->quant_type == H263_QUANT) { start_timer(); dequant_inter(&data[i*64], &qcoeff[i*64], iQuant); stop_iquant_timer(); } else { start_timer(); dequant4_inter(&data[i*64], &qcoeff[i*64], iQuant); stop_iquant_timer(); } cbp |= 1 << (5 - i); start_timer(); idct(&data[i*64]); stop_idct_timer(); } } if (pMB->field_dct) { next_block = stride; stride *= 2; } start_timer(); if (cbp & 32) transfer_16to8add(pY_Cur, &data[0*64], stride); if (cbp & 16) transfer_16to8add(pY_Cur + 8, &data[1*64], stride); if (cbp & 8) transfer_16to8add(pY_Cur + next_block, &data[2*64], stride); if (cbp & 4) transfer_16to8add(pY_Cur + next_block + 8, &data[3*64], stride); if (cbp & 2) transfer_16to8add(pU_Cur, &data[4*64], stride2); if (cbp & 1) transfer_16to8add(pV_Cur, &data[5*64], stride2); stop_transfer_timer(); return cbp; } /* if sum(diff between field lines) < sum(diff between frame lines), use field dct */ #define ABS(X) (X)<0 ? -(X) : (X) uint32_t MBDecideFieldDCT(int16_t data[6*64]) { const uint8_t blocks[] = {0*64, 0*64, 0*64, 0*64, 2*64, 2*64, 2*64, 2*64}; const uint8_t lines[] = {0, 16, 32, 48, 0, 16, 32, 48}; int frame = 0, field = 0; int i, j; for (i=0 ; i<7 ; ++i) { for (j=0 ; j<8 ; ++j) { frame += ABS(data[0*64 + (i+1)*8 + j] - data[0*64 + i*8 + j]); frame += ABS(data[1*64 + (i+1)*8 + j] - data[1*64 + i*8 + j]); frame += ABS(data[2*64 + (i+1)*8 + j] - data[2*64 + i*8 + j]); frame += ABS(data[3*64 + (i+1)*8 + j] - data[3*64 + i*8 + j]); field += ABS(data[blocks[i+1] + lines[i+1] + j] -\ data[blocks[i ] + lines[i ] + j]); field += ABS(data[blocks[i+1] + lines[i+1] + 8 + j] -\ data[blocks[i ] + lines[i ] + 8 + j]); field += ABS(data[blocks[i+1] + 64 + lines[i+1] + j] -\ data[blocks[i ] + 64 + lines[i ] + j]); field += ABS(data[blocks[i+1] + 64 + lines[i+1] + 8 + j] -\ data[blocks[i ] + 64 + lines[i ] + 8 + j]); } } if (frame > field) { MBFrameToField(data); } return (frame > field); } /* deinterlace Y blocks vertically */ #define MOVLINE(X,Y) memcpy(X, Y, sizeof(tmp)) #define LINE(X,Y) &data[X*64 + Y*8] void MBFrameToField(int16_t data[6*64]) { int16_t tmp[8]; /* left blocks */ // 1=2, 2=4, 4=8, 8=1 MOVLINE(tmp, LINE(0,1)); MOVLINE(LINE(0,1), LINE(0,2)); MOVLINE(LINE(0,2), LINE(0,4)); MOVLINE(LINE(0,4), LINE(2,0)); MOVLINE(LINE(2,0), tmp); // 3=6, 6=12, 12=9, 9=3 MOVLINE(tmp, LINE(0,3)); MOVLINE(LINE(0,3), LINE(0,6)); MOVLINE(LINE(0,6), LINE(2,4)); MOVLINE(LINE(2,4), LINE(2,1)); MOVLINE(LINE(2,1), tmp); // 5=10, 10=5 MOVLINE(tmp, LINE(0,5)); MOVLINE(LINE(0,5), LINE(2,2)); MOVLINE(LINE(2,2), tmp); // 7=14, 14=13, 13=11, 11=7 MOVLINE(tmp, LINE(0,7)); MOVLINE(LINE(0,7), LINE(2,6)); MOVLINE(LINE(2,6), LINE(2,5)); MOVLINE(LINE(2,5), LINE(2,3)); MOVLINE(LINE(2,3), tmp); /* right blocks */ // 1=2, 2=4, 4=8, 8=1 MOVLINE(tmp, LINE(1,1)); MOVLINE(LINE(1,1), LINE(1,2)); MOVLINE(LINE(1,2), LINE(1,4)); MOVLINE(LINE(1,4), LINE(3,0)); MOVLINE(LINE(3,0), tmp); // 3=6, 6=12, 12=9, 9=3 MOVLINE(tmp, LINE(1,3)); MOVLINE(LINE(1,3), LINE(1,6)); MOVLINE(LINE(1,6), LINE(3,4)); MOVLINE(LINE(3,4), LINE(3,1)); MOVLINE(LINE(3,1), tmp); // 5=10, 10=5 MOVLINE(tmp, LINE(1,5)); MOVLINE(LINE(1,5), LINE(3,2)); MOVLINE(LINE(3,2), tmp); // 7=14, 14=13, 13=11, 11=7 MOVLINE(tmp, LINE(1,7)); MOVLINE(LINE(1,7), LINE(3,6)); MOVLINE(LINE(3,6), LINE(3,5)); MOVLINE(LINE(3,5), LINE(3,3)); MOVLINE(LINE(3,3), tmp); } xvid_20020412/xvidcore/src/encoder.c0100644000100600001440000005073707454766203016544 0ustar michaelusers#include #include #include #include "encoder.h" #include "prediction/mbprediction.h" #include "global.h" #include "utils/timer.h" #include "image/image.h" #include "bitstream/cbp.h" #include "utils/mbfunctions.h" #include "bitstream/bitstream.h" #include "bitstream/mbcoding.h" #include "utils/ratecontrol.h" #include "utils/emms.h" #include "bitstream/mbcoding.h" #include "quant/adapt_quant.h" #include "quant/quant_matrix.h" #include "utils/mem_align.h" #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits); static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header); static int DQtab[4] = { -1, -2, 1, 2 }; static int iDQtab[5] = { 1, 0, NO_CHANGE, 2, 3 }; int encoder_create(XVID_ENC_PARAM * pParam) { Encoder *pEnc; uint32_t i; pParam->handle = NULL; ENC_CHECK(pParam); ENC_CHECK(pParam->width > 0 && pParam->width <= 1920); ENC_CHECK(pParam->height > 0 && pParam->height <= 1280); ENC_CHECK(!(pParam->width % 2)); ENC_CHECK(!(pParam->height % 2)); if (pParam->fincr <= 0 || pParam->fbase <= 0) { pParam->fincr = 1; pParam->fbase = 25; } // simplify the "fincr/fbase" fraction // (neccessary, since windows supplies us with huge numbers) i = pParam->fincr; while (i > 1) { if (pParam->fincr % i == 0 && pParam->fbase % i == 0) { pParam->fincr /= i; pParam->fbase /= i; i = pParam->fincr; continue; } i--; } if (pParam->fbase > 65535) { float div = (float)pParam->fbase / 65535; pParam->fbase = (int)(pParam->fbase / div); pParam->fincr = (int)(pParam->fincr / div); } if (pParam->bitrate <= 0) pParam->bitrate = 900000; if (pParam->rc_buffersize <= 0) pParam->rc_buffersize = 16; if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31)) pParam->min_quantizer = 1; if ((pParam->max_quantizer <= 0) || (pParam->max_quantizer > 31)) pParam->max_quantizer = 31; if (pParam->max_key_interval == 0) /* 1 keyframe each 10 seconds */ pParam->max_key_interval = 10 * pParam->fincr / pParam->fbase; if (pParam->max_quantizer < pParam->min_quantizer) pParam->max_quantizer = pParam->min_quantizer; if ((pEnc = (Encoder *) xvid_malloc(sizeof(Encoder), CACHE_LINE)) == NULL) return XVID_ERR_MEMORY; /* Fill members of Encoder structure */ pEnc->mbParam.width = pParam->width; pEnc->mbParam.height = pParam->height; pEnc->mbParam.mb_width = (pEnc->mbParam.width + 15) / 16; pEnc->mbParam.mb_height = (pEnc->mbParam.height + 15) / 16; pEnc->mbParam.edged_width = 16 * pEnc->mbParam.mb_width + 2 * EDGE_SIZE; pEnc->mbParam.edged_height = 16 * pEnc->mbParam.mb_height + 2 * EDGE_SIZE; pEnc->sStat.fMvPrevSigma = -1; /* Fill rate control parameters */ pEnc->mbParam.quant = 4; pEnc->bitrate = pParam->bitrate; pEnc->iFrameNum = 0; pEnc->iMaxKeyInterval = pParam->max_key_interval; /* try to allocate memory */ pEnc->sCurrent.y = pEnc->sCurrent.u = pEnc->sCurrent.v = NULL; pEnc->sReference.y = pEnc->sReference.u = pEnc->sReference.v = NULL; pEnc->vInterH.y = pEnc->vInterH.u = pEnc->vInterH.v = NULL; pEnc->vInterV.y = pEnc->vInterV.u = pEnc->vInterV.v = NULL; pEnc->vInterVf.y = pEnc->vInterVf.u = pEnc->vInterVf.v = NULL; pEnc->vInterHV.y = pEnc->vInterHV.u = pEnc->vInterHV.v = NULL; pEnc->vInterHVf.y = pEnc->vInterHVf.u = pEnc->vInterHVf.v = NULL; pEnc->pMBs = NULL; if (image_create(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || image_create(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || image_create(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || image_create(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || image_create(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || image_create(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || #ifdef _DEBUG image_create(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 || #endif (pEnc->pMBs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL) { image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); #ifdef _DEBUG image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); #endif if (pEnc) { xvid_free(pEnc); } return XVID_ERR_MEMORY; } // init macroblock array for (i = 0; i < pEnc->mbParam.mb_width * pEnc->mbParam.mb_height; i++) { pEnc->pMBs[i].dquant = NO_CHANGE; } pParam->handle = (void *)pEnc; if (pParam->bitrate) { RateControlInit(pParam->bitrate, pParam->rc_buffersize, pParam->fbase * 1000 / pParam->fincr, pParam->max_quantizer, pParam->min_quantizer); } init_timer(); return XVID_ERR_OK; } int encoder_destroy(Encoder * pEnc) { ENC_CHECK(pEnc); ENC_CHECK(pEnc->sCurrent.y); ENC_CHECK(pEnc->sReference.y); xvid_free(pEnc->pMBs); image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); #ifdef _DEBUG image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); #endif xvid_free(pEnc); return XVID_ERR_OK; } int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult) { uint16_t x, y; Bitstream bs; uint32_t bits; uint16_t write_vol_header = 0; #ifdef _DEBUG float psnr; uint8_t temp[100]; #endif start_global_timer(); ENC_CHECK(pEnc); ENC_CHECK(pFrame); ENC_CHECK(pFrame->bitstream); ENC_CHECK(pFrame->image); pEnc->mbParam.global_flags = pFrame->general; pEnc->mbParam.motion_flags = pFrame->motion; pEnc->mbParam.hint = &pFrame->hint; start_timer(); if (image_input(&pEnc->sCurrent, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width, pFrame->image, pFrame->colorspace)) { return XVID_ERR_FORMAT; } stop_conv_timer(); EMMS(); #ifdef _DEBUG image_copy(&pEnc->sOriginal, &pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.height); #endif BitstreamInit(&bs, pFrame->bitstream, 0); if (pFrame->quant == 0) { pEnc->mbParam.quant = RateControlGetQ(0); } else { pEnc->mbParam.quant = pFrame->quant; } if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) { int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE); pEnc->mbParam.quant = adaptive_quantization(pEnc->sCurrent.y, pEnc->mbParam.width, temp_dquants, pEnc->mbParam.quant, pEnc->mbParam.quant, 2*pEnc->mbParam.quant, pEnc->mbParam.mb_width, pEnc->mbParam.mb_height); for (y = 0; y < pEnc->mbParam.mb_height; y++) for (x = 0; x < pEnc->mbParam.mb_width; x++) { MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width]; pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)]; } xvid_free(temp_dquants); } if(pEnc->mbParam.global_flags & XVID_H263QUANT) { if(pEnc->mbParam.quant_type != H263_QUANT) write_vol_header = 1; pEnc->mbParam.quant_type = H263_QUANT; } else if(pEnc->mbParam.global_flags & XVID_MPEGQUANT) { int ret1, ret2; ret1 = ret2 = 0; if(pEnc->mbParam.quant_type != MPEG4_QUANT) write_vol_header = 1; pEnc->mbParam.quant_type = MPEG4_QUANT; if ((pEnc->mbParam.global_flags & XVID_CUSTOM_QMATRIX) > 0) { if(pFrame->quant_intra_matrix != NULL) ret1 = set_intra_matrix(pFrame->quant_intra_matrix); if(pFrame->quant_inter_matrix != NULL) ret2 = set_inter_matrix(pFrame->quant_inter_matrix); } else { ret1 = set_intra_matrix(get_default_intra_matrix()); ret2 = set_inter_matrix(get_default_inter_matrix()); } if(write_vol_header == 0) write_vol_header = ret1 | ret2; } if (pFrame->intra < 0) { if ((pEnc->iFrameNum == 0) || ((pEnc->iMaxKeyInterval > 0) && (pEnc->iFrameNum >= pEnc->iMaxKeyInterval))) pFrame->intra = FrameCodeI(pEnc, &bs, &bits); else pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 0, write_vol_header); } else { if (pFrame->intra == 1) pFrame->intra = FrameCodeI(pEnc, &bs, &bits); else pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header); } BitstreamPutBits(&bs, 0xFFFF, 16); BitstreamPutBits(&bs, 0xFFFF, 16); BitstreamPad(&bs); pFrame->length = BitstreamLength(&bs); if (pResult) { pResult->quant = pEnc->mbParam.quant; pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8); pResult->kblks = pEnc->sStat.kblks; pResult->mblks = pEnc->sStat.mblks; pResult->ublks = pEnc->sStat.ublks; } EMMS(); if (pFrame->quant == 0) { RateControlUpdate(pEnc->mbParam.quant, pFrame->length, pFrame->intra); } #ifdef _DEBUG psnr = image_psnr(&pEnc->sOriginal, &pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.width, pEnc->mbParam.height); sprintf(temp, "PSNR: %f\n", psnr); DEBUG(temp); #endif pEnc->iFrameNum++; image_swap(&pEnc->sCurrent, &pEnc->sReference); stop_global_timer(); write_timer(); return XVID_ERR_OK; } static __inline void CodeIntraMB(Encoder *pEnc, MACROBLOCK *pMB) { pMB->mode = MODE_INTRA; if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) { if(pMB->dquant != NO_CHANGE) { pMB->mode = MODE_INTRA_Q; pEnc->mbParam.quant += DQtab[pMB->dquant]; if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31; if (pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1; } } pMB->quant = pEnc->mbParam.quant; } #define FCODEBITS 3 #define MODEBITS 5 void HintedMESet(Encoder * pEnc, int * intra) { HINTINFO * hint; Bitstream bs; int length, high; uint32_t x, y; hint = pEnc->mbParam.hint; if (hint->rawhints) { *intra = hint->mvhint.intra; } else { BitstreamInit(&bs, hint->hintstream, hint->hintlength); *intra = BitstreamGetBit(&bs); } if (*intra) { return; } pEnc->mbParam.fixed_code = (hint->rawhints) ? hint->mvhint.fcode : BitstreamGetBits(&bs, FCODEBITS); length = pEnc->mbParam.fixed_code + 5; high = 1 << (length - 1); for (y=0 ; ymbParam.mb_height ; ++y) { for (x=0 ; xmbParam.mb_width ; ++x) { MACROBLOCK * pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width]; MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width]; VECTOR pred[4]; VECTOR tmp; int dummy[4]; int vec; pMB->mode = (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs, MODEBITS); if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) { tmp.x = (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs, length); tmp.y = (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs, length); tmp.x -= (tmp.x >= high) ? high*2 : 0; tmp.y -= (tmp.y >= high) ? high*2 : 0; get_pmvdata(pEnc->pMBs, x, y, pEnc->mbParam.mb_width, 0, pred, dummy); for (vec=0 ; vec<4 ; ++vec) { pMB->mvs[vec].x = tmp.x; pMB->mvs[vec].y = tmp.y; pMB->pmvs[vec].x = pMB->mvs[0].x - pred[0].x; pMB->pmvs[vec].y = pMB->mvs[0].y - pred[0].y; } } else if (pMB->mode == MODE_INTER4V) { for (vec=0 ; vec<4 ; ++vec) { tmp.x = (hint->rawhints) ? bhint->mvs[vec].x : BitstreamGetBits(&bs, length); tmp.y = (hint->rawhints) ? bhint->mvs[vec].y : BitstreamGetBits(&bs, length); tmp.x -= (tmp.x >= high) ? high*2 : 0; tmp.y -= (tmp.y >= high) ? high*2 : 0; get_pmvdata(pEnc->pMBs, x, y, pEnc->mbParam.mb_width, vec, pred, dummy); pMB->mvs[vec].x = tmp.x; pMB->mvs[vec].y = tmp.y; pMB->pmvs[vec].x = pMB->mvs[vec].x - pred[0].x; pMB->pmvs[vec].y = pMB->mvs[vec].y - pred[0].y; } } else // intra / intra_q / stuffing / not_coded { for (vec=0 ; vec<4 ; ++vec) { pMB->mvs[vec].x = pMB->mvs[vec].y = 0; } } } } } void HintedMEGet(Encoder * pEnc, int intra) { HINTINFO * hint; Bitstream bs; uint32_t x, y; int length, high; hint = pEnc->mbParam.hint; if (hint->rawhints) { hint->mvhint.intra = intra; } else { BitstreamInit(&bs, hint->hintstream, 0); BitstreamPutBit(&bs, intra); } if (intra) { if (!hint->rawhints) { BitstreamPad(&bs); hint->hintlength = BitstreamLength(&bs); } return; } length = pEnc->mbParam.fixed_code + 5; high = 1 << (length - 1); if (hint->rawhints) { hint->mvhint.fcode = pEnc->mbParam.fixed_code; } else { BitstreamPutBits(&bs, pEnc->mbParam.fixed_code, FCODEBITS); } for (y=0 ; ymbParam.mb_height ; ++y) { for (x=0 ; xmbParam.mb_width ; ++x) { MACROBLOCK * pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width]; MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width]; VECTOR tmp; if (hint->rawhints) { bhint->mode = pMB->mode; } else { BitstreamPutBits(&bs, pMB->mode, MODEBITS); } if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) { tmp.x = pMB->mvs[0].x; tmp.y = pMB->mvs[0].y; tmp.x += (tmp.x < 0) ? high*2 : 0; tmp.y += (tmp.y < 0) ? high*2 : 0; if (hint->rawhints) { bhint->mvs[0].x = tmp.x; bhint->mvs[0].y = tmp.y; } else { BitstreamPutBits(&bs, tmp.x, length); BitstreamPutBits(&bs, tmp.y, length); } } else if (pMB->mode == MODE_INTER4V) { int vec; for (vec=0 ; vec<4 ; ++vec) { tmp.x = pMB->mvs[vec].x; tmp.y = pMB->mvs[vec].y; tmp.x += (tmp.x < 0) ? high*2 : 0; tmp.y += (tmp.y < 0) ? high*2 : 0; if (hint->rawhints) { bhint->mvs[vec].x = tmp.x; bhint->mvs[vec].y = tmp.y; } else { BitstreamPutBits(&bs, tmp.x, length); BitstreamPutBits(&bs, tmp.y, length); } } } } } if (!hint->rawhints) { BitstreamPad(&bs); hint->hintlength = BitstreamLength(&bs); } } static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits) { DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE); DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE); uint16_t x, y; pEnc->iFrameNum = 0; pEnc->mbParam.rounding_type = 1; pEnc->mbParam.coding_type = I_VOP; BitstreamWriteVolHeader(bs, &pEnc->mbParam); BitstreamWriteVopHeader(bs, &pEnc->mbParam); *pBits = BitstreamPos(bs); pEnc->sStat.iTextBits = 0; pEnc->sStat.kblks = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height; pEnc->sStat.mblks = pEnc->sStat.ublks = 0; for (y = 0; y < pEnc->mbParam.mb_height; y++) for (x = 0; x < pEnc->mbParam.mb_width; x++) { MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width]; CodeIntraMB(pEnc, pMB); MBTransQuantIntra(&pEnc->mbParam, pMB, x, y, dct_codes, qcoeff, &pEnc->sCurrent); start_timer(); MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs); stop_prediction_timer(); start_timer(); MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat); stop_coding_timer(); } emms(); *pBits = BitstreamPos(bs) - *pBits; pEnc->sStat.fMvPrevSigma = -1; pEnc->sStat.iMvSum = 0; pEnc->sStat.iMvCount = 0; pEnc->mbParam.fixed_code = 2; if (pEnc->mbParam.global_flags & XVID_HINTEDME_GET) { HintedMEGet(pEnc, 1); } return 1; // intra } #define INTRA_THRESHOLD 0.5 static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header) { float fSigma; DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE); DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE); int iLimit; uint32_t x, y; int iSearchRange; bool bIntra; IMAGE *pCurrent = &pEnc->sCurrent; IMAGE *pRef = &pEnc->sReference; start_timer(); image_setedges(pRef, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.global_flags & XVID_INTERLACING); stop_edges_timer(); pEnc->mbParam.rounding_type = 1 - pEnc->mbParam.rounding_type; if (!force_inter) iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD); else iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1; if ((pEnc->mbParam.global_flags & XVID_HALFPEL) > 0) { start_timer(); image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.rounding_type); stop_inter_timer(); } start_timer(); if (pEnc->mbParam.global_flags & XVID_HINTEDME_SET) { HintedMESet(pEnc, &bIntra); } else { bIntra = MotionEstimation(pEnc->pMBs, &pEnc->mbParam, &pEnc->sReference, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV, &pEnc->sCurrent, iLimit); } stop_motion_timer(); if (bIntra == 1) { return FrameCodeI(pEnc, bs, pBits); } pEnc->mbParam.coding_type = P_VOP; if(vol_header) BitstreamWriteVolHeader(bs, &pEnc->mbParam); BitstreamWriteVopHeader(bs, &pEnc->mbParam); *pBits = BitstreamPos(bs); pEnc->sStat.iTextBits = 0; pEnc->sStat.iMvSum = 0; pEnc->sStat.iMvCount = 0; pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0; for(y = 0; y < pEnc->mbParam.mb_height; y++) { for(x = 0; x < pEnc->mbParam.mb_width; x++) { MACROBLOCK * pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width]; bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q); if (!bIntra) { start_timer(); MBMotionCompensation(pMB, x, y, &pEnc->sReference, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV, &pEnc->sCurrent, dct_codes, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width, pEnc->mbParam.rounding_type); stop_comp_timer(); if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) { if(pMB->dquant != NO_CHANGE) { pMB->mode = MODE_INTER_Q; pEnc->mbParam.quant += DQtab[pMB->dquant]; if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31; else if(pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1; } } pMB->quant = pEnc->mbParam.quant; pMB->field_pred = 0; pMB->cbp = MBTransQuantInter(&pEnc->mbParam, pMB, x, y, dct_codes, qcoeff, pCurrent); } else { CodeIntraMB(pEnc, pMB); MBTransQuantIntra(&pEnc->mbParam, pMB, x, y, dct_codes, qcoeff, pCurrent); } start_timer(); MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs); stop_prediction_timer(); if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) { pEnc->sStat.kblks++; } else if (pMB->cbp || pMB->mvs[0].x || pMB->mvs[0].y || pMB->mvs[1].x || pMB->mvs[1].y || pMB->mvs[2].x || pMB->mvs[2].y || pMB->mvs[3].x || pMB->mvs[3].y) { pEnc->sStat.mblks++; } else { pEnc->sStat.ublks++; } start_timer(); MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat); stop_coding_timer(); } } emms(); if (pEnc->mbParam.global_flags & XVID_HINTEDME_GET) { HintedMEGet(pEnc, 0); } if (pEnc->sStat.iMvCount == 0) pEnc->sStat.iMvCount = 1; fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount); iSearchRange = 1 << (3 + pEnc->mbParam.fixed_code); if ((fSigma > iSearchRange / 3) && (pEnc->mbParam.fixed_code <= 3)) // maximum search range 128 { pEnc->mbParam.fixed_code++; iSearchRange *= 2; } else if ((fSigma < iSearchRange / 6) && (pEnc->sStat.fMvPrevSigma >= 0) && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6) && (pEnc->mbParam.fixed_code >= 2)) // minimum search range 16 { pEnc->mbParam.fixed_code--; iSearchRange /= 2; } pEnc->sStat.fMvPrevSigma = fSigma; *pBits = BitstreamPos(bs) - *pBits; return 0; // inter } xvid_20020412/xvidcore/src/encoder.h0100644000100600001440000000453607454766174016554 0ustar michaelusers/************************************************************************** * * Modifications: * * 22.08.2001 added support for EXT_MODE encoding mode * support for EXTENDED API * 22.08.2001 fixed bug in iDQtab * * Michael Militzer * **************************************************************************/ #ifndef _ENCODER_H_ #define _ENCODER_H_ #include "xvid.h" #include "portab.h" #include "global.h" #include "image/image.h" #define H263_QUANT 0 #define MPEG4_QUANT 1 typedef uint32_t bool; typedef enum { I_VOP = 0, P_VOP = 1 } VOP_TYPE; /*********************************** Encoding Parameters ************************************/ typedef struct { uint32_t width; uint32_t height; uint32_t edged_width; uint32_t edged_height; uint32_t mb_width; uint32_t mb_height; VOP_TYPE coding_type; /* rounding type; alternate 0-1 after each interframe */ uint32_t rounding_type; /* 1 <= fixed_code <= 4 automatically adjusted using motion vector statistics inside */ uint32_t fixed_code; uint32_t quant; uint32_t quant_type; uint32_t motion_flags; uint32_t global_flags; HINTINFO * hint; } MBParam; typedef struct { int iTextBits; float fMvPrevSigma; int iMvSum; int iMvCount; int kblks; int mblks; int ublks; } Statistics; typedef struct { MBParam mbParam; int iFrameNum; int iMaxKeyInterval; int lum_masking; int bitrate; // images IMAGE sCurrent; IMAGE sReference; #ifdef _DEBUG IMAGE sOriginal; #endif IMAGE vInterH; IMAGE vInterV; IMAGE vInterVf; IMAGE vInterHV; IMAGE vInterHVf; // macroblock MACROBLOCK * pMBs; Statistics sStat; } Encoder; // indicates no quantizer changes in INTRA_Q/INTER_Q modes #define NO_CHANGE 64 void init_encoder(uint32_t cpu_flags); int encoder_create(XVID_ENC_PARAM * pParam); int encoder_destroy(Encoder * pEnc); int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult); static __inline uint8_t get_fcode(uint16_t sr) { if (sr <= 16) return 1; else if (sr <= 32) return 2; else if (sr <= 64) return 3; else if (sr <= 128) return 4; else if (sr <= 256) return 5; else if (sr <= 512) return 6; else if (sr <= 1024) return 7; else return 0; } #endif /* _ENCODER_H_ */ xvid_20020412/xvidcore/src/decoder.c0100644000100600001440000004124007454426267016522 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * decoder main * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is xvid_free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the xvid_free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the xvid_free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 29.03.2002 interlacing fix - compensated block wasn't being used when * reconstructing blocks, thus artifacts * interlacing speedup - used transfers to re-interlace * interlaced decoding should be as fast as progressive now * 26.03.2002 interlacing support - moved transfers outside decode loop * 26.12.2001 decoder_mbinter: dequant/idct moved within if(coded) block * 22.12.2001 block based interpolation * 01.12.2001 inital version; (c)2001 peter ross * *************************************************************************/ #include #include // memset #include "xvid.h" #include "portab.h" #include "decoder.h" #include "bitstream/bitstream.h" #include "bitstream/mbcoding.h" #include "quant/quant_h263.h" #include "quant/quant_mpeg4.h" #include "dct/idct.h" #include "dct/fdct.h" #include "utils/mem_transfer.h" #include "image/interpolate8x8.h" #include "bitstream/mbcoding.h" #include "prediction/mbprediction.h" #include "utils/timer.h" #include "utils/emms.h" #include "image/image.h" #include "image/colorspace.h" #include "utils/mem_align.h" int decoder_create(XVID_DEC_PARAM * param) { DECODER * dec; dec = xvid_malloc(sizeof(DECODER), CACHE_LINE); if (dec == NULL) { return XVID_ERR_MEMORY; } param->handle = dec; dec->width = param->width; dec->height = param->height; dec->mb_width = (dec->width + 15) / 16; dec->mb_height = (dec->height + 15) / 16; dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE; dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE; if (image_create(&dec->cur, dec->edged_width, dec->edged_height)) { xvid_free(dec); return XVID_ERR_MEMORY; } if (image_create(&dec->refn, dec->edged_width, dec->edged_height)) { image_destroy(&dec->cur, dec->edged_width, dec->edged_height); xvid_free(dec); return XVID_ERR_MEMORY; } dec->mbs = xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height, CACHE_LINE); if (dec->mbs == NULL) { image_destroy(&dec->cur, dec->edged_width, dec->edged_height); xvid_free(dec); return XVID_ERR_MEMORY; } init_timer(); return XVID_ERR_OK; } int decoder_destroy(DECODER * dec) { xvid_free(dec->mbs); image_destroy(&dec->refn, dec->edged_width, dec->edged_height); image_destroy(&dec->cur, dec->edged_width, dec->edged_height); xvid_free(dec); write_timer(); return XVID_ERR_OK; } static const int32_t dquant_table[4] = { -1, -2, 1, 2 }; // decode an intra macroblock void decoder_mbintra(DECODER * dec, MACROBLOCK * pMB, const uint32_t x_pos, const uint32_t y_pos, const uint32_t acpred_flag, const uint32_t cbp, Bitstream * bs, const uint32_t quant, const uint32_t intra_dc_threshold) { DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE); DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE); uint32_t stride = dec->edged_width; uint32_t stride2 = stride / 2; uint32_t next_block = stride * 8; uint32_t i; uint32_t iQuant = pMB->quant; uint8_t *pY_Cur, *pU_Cur, *pV_Cur; pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4); pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3); pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3); memset(block, 0, 6*64*sizeof(int16_t)); // clear for (i = 0; i < 6; i++) { uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4); int16_t predictors[8]; int start_coeff; start_timer(); predict_acdc(dec->mbs, x_pos, y_pos, dec->mb_width, i, &block[i*64], iQuant, iDcScaler, predictors); if (!acpred_flag) { pMB->acpred_directions[i] = 0; } stop_prediction_timer(); if (quant < intra_dc_threshold) { int dc_size; int dc_dif; dc_size = i < 4 ? get_dc_size_lum(bs) : get_dc_size_chrom(bs); dc_dif = dc_size ? get_dc_dif(bs, dc_size) : 0 ; if (dc_size > 8) { BitstreamSkip(bs, 1); // marker } block[i*64 + 0] = dc_dif; start_coeff = 1; } else { start_coeff = 0; } start_timer(); if (cbp & (1 << (5-i))) // coded { get_intra_block(bs, &block[i*64], pMB->acpred_directions[i], start_coeff); } stop_coding_timer(); start_timer(); add_acdc(pMB, i, &block[i*64], iDcScaler, predictors); stop_prediction_timer(); start_timer(); if (dec->quant_type == 0) { dequant_intra(&data[i*64], &block[i*64], iQuant, iDcScaler); } else { dequant4_intra(&data[i*64], &block[i*64], iQuant, iDcScaler); } stop_iquant_timer(); start_timer(); idct(&data[i*64]); stop_idct_timer(); } if (dec->interlacing && pMB->field_dct) { next_block = stride; stride *= 2; } start_timer(); transfer_16to8copy(pY_Cur, &data[0*64], stride); transfer_16to8copy(pY_Cur + 8, &data[1*64], stride); transfer_16to8copy(pY_Cur + next_block, &data[2*64], stride); transfer_16to8copy(pY_Cur + 8 + next_block, &data[3*64], stride); transfer_16to8copy(pU_Cur, &data[4*64], stride2); transfer_16to8copy(pV_Cur, &data[5*64], stride2); stop_transfer_timer(); } #define SIGN(X) (((X)>0)?1:-1) #define ABS(X) (((X)>0)?(X):-(X)) static const uint32_t roundtab[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2 }; // decode an inter macroblock void decoder_mbinter(DECODER * dec, const MACROBLOCK * pMB, const uint32_t x_pos, const uint32_t y_pos, const uint32_t acpred_flag, const uint32_t cbp, Bitstream * bs, const uint32_t quant, const uint32_t rounding) { DECLARE_ALIGNED_MATRIX(block,6, 64, int16_t, CACHE_LINE); DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE); uint32_t stride = dec->edged_width; uint32_t stride2 = stride / 2; uint32_t next_block = stride * 8; uint32_t i; uint32_t iQuant = pMB->quant; uint8_t *pY_Cur, *pU_Cur, *pV_Cur; int uv_dx, uv_dy; pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4); pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3); pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3); if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) { uv_dx = pMB->mvs[0].x; uv_dy = pMB->mvs[0].y; uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2; uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2; } else { int sum; sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x; uv_dx = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) ); sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y; uv_dy = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) ); } start_timer(); interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos, 16*y_pos , pMB->mvs[0].x, pMB->mvs[0].y, stride, rounding); interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos + 8, 16*y_pos , pMB->mvs[1].x, pMB->mvs[1].y, stride, rounding); interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos, 16*y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride, rounding); interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos + 8, 16*y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride, rounding); interpolate8x8_switch(dec->cur.u, dec->refn.u, 8*x_pos, 8*y_pos, uv_dx, uv_dy, stride2, rounding); interpolate8x8_switch(dec->cur.v, dec->refn.v, 8*x_pos, 8*y_pos, uv_dx, uv_dy, stride2, rounding); stop_comp_timer(); for (i = 0; i < 6; i++) { if (cbp & (1 << (5-i))) // coded { memset(&block[i*64], 0, 64 * sizeof(int16_t)); // clear start_timer(); get_inter_block(bs, &block[i*64]); stop_coding_timer(); start_timer(); if (dec->quant_type == 0) { dequant_inter(&data[i*64], &block[i*64], iQuant); } else { dequant4_inter(&data[i*64], &block[i*64], iQuant); } stop_iquant_timer(); start_timer(); idct(&data[i*64]); stop_idct_timer(); } } if (dec->interlacing && pMB->field_dct) { next_block = stride; stride *= 2; } start_timer(); if (cbp & 32) transfer_16to8add(pY_Cur, &data[0*64], stride); if (cbp & 16) transfer_16to8add(pY_Cur + 8, &data[1*64], stride); if (cbp & 8) transfer_16to8add(pY_Cur + next_block, &data[2*64], stride); if (cbp & 4) transfer_16to8add(pY_Cur + 8 + next_block, &data[3*64], stride); if (cbp & 2) transfer_16to8add(pU_Cur, &data[4*64], stride2); if (cbp & 1) transfer_16to8add(pV_Cur, &data[5*64], stride2); stop_transfer_timer(); } void decoder_iframe(DECODER * dec, Bitstream * bs, int quant, int intra_dc_threshold) { uint32_t x, y; for (y = 0; y < dec->mb_height; y++) { for (x = 0; x < dec->mb_width; x++) { MACROBLOCK * mb = &dec->mbs[y*dec->mb_width + x]; uint32_t mcbpc; uint32_t cbpc; uint32_t acpred_flag; uint32_t cbpy; uint32_t cbp; mcbpc = get_mcbpc_intra(bs); mb->mode = mcbpc & 7; cbpc = (mcbpc >> 4); acpred_flag = BitstreamGetBit(bs); if (mb->mode == MODE_STUFFING) { DEBUG("-- STUFFING ?"); continue; } cbpy = get_cbpy(bs, 1); cbp = (cbpy << 2) | cbpc; if (mb->mode == MODE_INTRA_Q) { quant += dquant_table[BitstreamGetBits(bs,2)]; if (quant > 31) { quant = 31; } else if (quant < 1) { quant = 1; } } mb->quant = quant; if (dec->interlacing) { mb->field_dct = BitstreamGetBit(bs); DEBUG1("deci: field_dct: ", mb->field_dct); } decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold); } } } void get_motion_vector(DECODER *dec, Bitstream *bs, int x, int y, int k, VECTOR * mv, int fcode) { int scale_fac = 1 << (fcode - 1); int high = (32 * scale_fac) - 1; int low = ((-32) * scale_fac); int range = (64 * scale_fac); VECTOR pmv[4]; uint32_t psad[4]; int mv_x, mv_y; int pmv_x, pmv_y; get_pmvdata(dec->mbs, x, y, dec->mb_width, k, pmv, psad); pmv_x = pmv[0].x; pmv_y = pmv[0].y; mv_x = get_mv(bs, fcode); mv_y = get_mv(bs, fcode); mv_x += pmv_x; mv_y += pmv_y; if (mv_x < low) { mv_x += range; } else if (mv_x > high) { mv_x -= range; } if (mv_y < low) { mv_y += range; } else if (mv_y > high) { mv_y -= range; } mv->x = mv_x; mv->y = mv_y; } void decoder_pframe(DECODER * dec, Bitstream * bs, int rounding, int quant, int fcode, int intra_dc_threshold) { uint32_t x, y; image_swap(&dec->cur, &dec->refn); start_timer(); image_setedges(&dec->refn, dec->edged_width, dec->edged_height, dec->width, dec->height, dec->interlacing); stop_edges_timer(); for (y = 0; y < dec->mb_height; y++) { for (x = 0; x < dec->mb_width; x++) { MACROBLOCK * mb = &dec->mbs[y*dec->mb_width + x]; if (!BitstreamGetBit(bs)) // not_coded { uint32_t mcbpc; uint32_t cbpc; uint32_t acpred_flag; uint32_t cbpy; uint32_t cbp; uint32_t intra; mcbpc = get_mcbpc_inter(bs); mb->mode = mcbpc & 7; cbpc = (mcbpc >> 4); acpred_flag = 0; intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q); if (intra) { acpred_flag = BitstreamGetBit(bs); } if (mb->mode == MODE_STUFFING) { DEBUG("-- STUFFING ?"); continue; } cbpy = get_cbpy(bs, intra); cbp = (cbpy << 2) | cbpc; if (mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q) { quant += dquant_table[BitstreamGetBits(bs,2)]; if (quant > 31) { quant = 31; } else if (mb->quant < 1) { quant = 1; } } mb->quant = quant; if (dec->interlacing) { mb->field_dct = BitstreamGetBit(bs); DEBUG1("decp: field_dct: ", mb->field_dct); if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) { mb->field_pred = BitstreamGetBit(bs); DEBUG1("decp: field_pred: ", mb->field_pred); if (mb->field_pred) { mb->field_for_top = BitstreamGetBit(bs); DEBUG1("decp: field_for_top: ", mb->field_for_top); mb->field_for_bot = BitstreamGetBit(bs); DEBUG1("decp: field_for_bot: ", mb->field_for_bot); } } } if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) { if (dec->interlacing && mb->field_pred) { get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode); get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1], fcode); } else { get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode); mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = mb->mvs[0].x; mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = mb->mvs[0].y; } } else if (mb->mode == MODE_INTER4V /* || mb->mode == MODE_INTER4V_Q */) { get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode); get_motion_vector(dec, bs, x, y, 1, &mb->mvs[1], fcode); get_motion_vector(dec, bs, x, y, 2, &mb->mvs[2], fcode); get_motion_vector(dec, bs, x, y, 3, &mb->mvs[3], fcode); } else // MODE_INTRA, MODE_INTRA_Q { mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0; mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0; decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold); continue; } decoder_mbinter(dec, mb, x, y, acpred_flag, cbp, bs, quant, rounding); } else // not coded { mb->mode = MODE_NOT_CODED; mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0; mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0; // copy macroblock directly from ref to cur start_timer(); transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x), dec->refn.y + (16*y)*dec->edged_width + (16*x), dec->edged_width); transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x+8), dec->refn.y + (16*y)*dec->edged_width + (16*x+8), dec->edged_width); transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x), dec->refn.y + (16*y+8)*dec->edged_width + (16*x), dec->edged_width); transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x+8), dec->refn.y + (16*y+8)*dec->edged_width + (16*x+8), dec->edged_width); transfer8x8_copy(dec->cur.u + (8*y)*dec->edged_width/2 + (8*x), dec->refn.u + (8*y)*dec->edged_width/2 + (8*x), dec->edged_width/2); transfer8x8_copy(dec->cur.v + (8*y)*dec->edged_width/2 + (8*x), dec->refn.v + (8*y)*dec->edged_width/2 + (8*x), dec->edged_width/2); stop_transfer_timer(); } } } } int decoder_decode(DECODER * dec, XVID_DEC_FRAME * frame) { Bitstream bs; uint32_t rounding; uint32_t quant; uint32_t fcode; uint32_t intra_dc_threshold; start_global_timer(); BitstreamInit(&bs, frame->bitstream, frame->length); switch (BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold)) { case P_VOP : decoder_pframe(dec, &bs, rounding, quant, fcode, intra_dc_threshold); break; case I_VOP : //DEBUG1("",intra_dc_threshold); decoder_iframe(dec, &bs, quant, intra_dc_threshold); break; case B_VOP : // ignore break; case N_VOP : // vop not coded break; default : return XVID_ERR_FAIL; } frame->length = BitstreamPos(&bs) / 8; start_timer(); image_output(&dec->cur, dec->width, dec->height, dec->edged_width, frame->image, frame->stride, frame->colorspace); stop_conv_timer(); emms(); stop_global_timer(); return XVID_ERR_OK; } xvid_20020412/xvidcore/src/decoder.h0100644000100600001440000000145407450054170016514 0ustar michaelusers#ifndef _DECODER_H_ #define _DECODER_H_ #include "xvid.h" #include "portab.h" #include "global.h" #include "image/image.h" typedef struct { // bitstream uint32_t shape; uint32_t time_inc_bits; uint32_t quant_bits; uint32_t quant_type; uint32_t quarterpel; uint32_t interlacing; uint32_t top_field_first; uint32_t alternate_vertical_scan; // image uint32_t width; uint32_t height; uint32_t edged_width; uint32_t edged_height; IMAGE cur; IMAGE refn; IMAGE refh; IMAGE refv; IMAGE refhv; // macroblock uint32_t mb_width; uint32_t mb_height; MACROBLOCK * mbs; } DECODER; void init_decoder(uint32_t cpu_flags); int decoder_create(XVID_DEC_PARAM * param); int decoder_destroy(DECODER * dec); int decoder_decode(DECODER * dec, XVID_DEC_FRAME * frame); #endif /* _DECODER_H_ */ xvid_20020412/xvidcore/src/portab.h0100644000100600001440000001121407454032073016373 0ustar michaelusers#ifndef _PORTAB_H_ #define _PORTAB_H_ #if defined(WIN32) #include #define DEBUGCBR(A,B,C) { char tmp[100]; wsprintf(tmp, "CBR: frame: %i, quant: %i, deviation: %i\n", (A), (B), (C)); OutputDebugString(tmp); } #ifdef _DEBUG #define DEBUG(S) OutputDebugString((S)); #define DEBUG1(S,I) { char tmp[100]; wsprintf(tmp, "%s %i\n", (S), (I)); OutputDebugString(tmp); } #define DEBUG2(X,A,B) { char tmp[100]; wsprintf(tmp, "%s %i %i\n", (X), (A), (B)); OutputDebugString(tmp); } #define DEBUG3(X,A,B,C){ char tmp[1000]; wsprintf(tmp,"%s %i %i %i",(X),(A), (B), (C)); OutputDebugString(tmp); } #define DEBUG8(X,A,B,C,D,E,F,G,H){ char tmp[1000]; wsprintf(tmp,"%s %i %i %i %i %i %i %i %i",(X),(A),(B),(C),(D),(E),(F),(G),(H)); OutputDebugString(tmp); } #else #define DEBUG(S) #define DEBUG1(S,I) #define DEBUG2(X,A,B) #define DEBUG3(X,A,B,C) #define DEBUG8(X,A,B,C,D,E,F,G,H) #endif #define int8_t char #define uint8_t unsigned char #define int16_t short #define uint16_t unsigned short #define int32_t int #define uint32_t unsigned int #define int64_t __int64 #define uint64_t unsigned __int64 #define EMMS() __asm {emms} #define CACHE_LINE 16 #if _MSC_VER <= 1200 #define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \ type name##_storage[(sizex)*(sizey)+(alignment)-1]; \ type * name = (type *) (((int32_t) name##_storage+(alignment - 1)) & ~((int32_t)(alignment)-1)) #else #define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \ __declspec(align(alignment)) type name[(sizex)*(sizey)] #endif // needed for bitstream.h #define BSWAP(a) __asm mov eax,a __asm bswap eax __asm mov a, eax // needed for timer.c static __inline int64_t read_counter() { int64_t ts; uint32_t ts1, ts2; __asm { rdtsc mov ts1, eax mov ts2, edx } ts = ((uint64_t) ts2 << 32) | ((uint64_t) ts1); return ts; } #elif defined(LINUX) || defined(DJGPP) #ifdef _DEBUG #include #define DEBUG_WHERE stdout #define DEBUG(S) fprintf(DEBUG_WHERE, "%s\n", (S)); #define DEBUG1(S,I) fprintf(DEBUG_WHERE, "%s %i\n", (S), (I)) #define DEBUG2(S,A,B) fprintf(DEBUG_WHERE, "%s%i=%i\n", (S), (A), (B)) #define DEBUG3(S,A,B,C) fprintf(DEBUG_WHERE, "%s %i %x %x\n", (S), (A), (B), (C)) #define DEBUG8(S,A,B,C,D,E,F,G,H) #define DEBUGCBR(A,B,C) fprintf(DEBUG_WHERE, "CBR: frame: %i, quant: %i, deviation: %i\n", (A), (B), (C)) #else #define DEBUG(S) #define DEBUG1(S,I) #define DEBUG2(X,A,B) #define DEBUG3(X,A,B,C) #define DEBUG8(X,A,B,C,D,E,F,G,H) #define DEBUGCBR(A,B,C) #endif #define CACHE_LINE 16 #if defined(LINUX) #include #define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \ type name##_storage[(sizex)*(sizey)+(alignment)-1]; \ type * name = (type *) (((int32_t) name##_storage+(alignment - 1)) & ~((int32_t)(alignment)-1)) #else #define #define #define DECLARE_ALIGNED_MATRIX(name,sizex,sizey,type,alignment) \ __attribute__ ((__aligned__(CACHE_LINE))) type name[(sizex)*(sizey)] #define int8_t char #define uint8_t unsigned char #define int16_t short #define uint16_t unsigned short #define int32_t int #define uint32_t unsigned int #define int64_t long long #define uint64_t unsigned long long #endif // needed for bitstream.h #ifdef ARCH_PPC #define BSWAP(a) __asm__ __volatile__ ( "lwbrx %0,0,%1; eieio" : "=r" (a) : \ "r" (&(a)), "m" (a)); #define EMMS() static __inline unsigned long get_tbl(void) { unsigned long tbl; asm volatile("mftb %0" : "=r" (tbl)); return tbl; } static __inline unsigned long get_tbu(void) { unsigned long tbl; asm volatile("mftbu %0" : "=r" (tbl)); return tbl; } static __inline int64_t read_counter() { unsigned long tb, tu; do { tu = get_tbu(); tb = get_tbl(); } while(tb != get_tbl()); return (((int64_t)tu) << 32) | (int64_t)tb; } #else #define BSWAP(a) __asm__ ( "bswapl %0\n" : "=r" (a) : "0" (a) ) #define EMMS() __asm__("emms\n\t") // needed for timer.c static __inline int64_t read_counter() { int64_t ts; uint32_t ts1, ts2; __asm__ __volatile__("rdtsc\n\t":"=a"(ts1), "=d"(ts2)); ts = ((uint64_t) ts2 << 32) | ((uint64_t) ts1); return ts; } #endif #else // OTHER OS #define DEBUG(S) #define DEBUG1(S,I) #define DEBUG2(X,A,B) #define DEBUG3(X,A,B,C) #define DEBUG8(X,A,B,C,D,E,F,G,H) #define DEBUGCBR(A,B,C) #include #define EMMS() // needed for bitstream.h #define BSWAP(a) \ ((a) = ( ((a)&0xff)<<24) | (((a)&0xff00)<<8) | (((a)>>8)&0xff00) | (((a)>>24)&0xff)) // rdtsc command most likely not supported, // so just dummy code here static __inline int64_t read_counter() { return 0; } #define CACHE_LINE 16 #define CACHE_ALIGN #endif #endif // _PORTAB_H_ xvid_20020412/xvidcore/src/global.h0100644000100600001440000000260607453333544016357 0ustar michaelusers#ifndef _GLOBAL_H_ #define _GLOBAL_H_ #include "xvid.h" #include "portab.h" /* --- macroblock stuff --- */ #define MODE_INTER 0 #define MODE_INTER_Q 1 #define MODE_INTER4V 2 #define MODE_INTRA 3 #define MODE_INTRA_Q 4 #define MODE_STUFFING 7 #define MODE_NOT_CODED 16 typedef struct { uint32_t bufa; uint32_t bufb; uint32_t buf; uint32_t pos; uint32_t *tail; uint32_t *start; uint32_t length; } Bitstream; #define MBPRED_SIZE 15 typedef struct { // decoder/encoder VECTOR mvs[4]; uint32_t sad8[4]; // SAD values for inter4v-VECTORs uint32_t sad16; // SAD value for inter-VECTOR short int pred_values[6][MBPRED_SIZE]; int acpred_directions[6]; int mode; int quant; // absolute quant int field_dct; int field_pred; int field_for_top; int field_for_bot; // encoder specific VECTOR pmvs[4]; int dquant; int cbp; } MACROBLOCK; static __inline int8_t get_dc_scaler(int32_t quant, uint32_t lum) { int8_t dc_scaler; if(quant > 0 && quant < 5) { dc_scaler = 8; return dc_scaler; } if(quant < 25 && !lum) { dc_scaler = (quant + 13) >> 1; return dc_scaler; } if(quant < 9) { dc_scaler = quant << 1; return dc_scaler; } if(quant < 25) { dc_scaler = quant + 8; return dc_scaler; } if(lum) dc_scaler = (quant << 1) - 16; else dc_scaler = quant - 6; return dc_scaler; } #endif /* _GLOBAL_H_ */ xvid_20020412/xvidcore/src/motion/0040755000100600001440000000000007455522447016256 5ustar michaelusersxvid_20020412/xvidcore/src/motion/CVS/0040755000100600001440000000000007455522447016711 5ustar michaelusersxvid_20020412/xvidcore/src/motion/CVS/Root0100644000100600001440000000004607455522446017553 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/motion/CVS/Repository0100644000100600001440000000002407455522446021003 0ustar michaelusersxvidcore/src/motion xvid_20020412/xvidcore/src/motion/CVS/Entries.Log0100644000100600001440000000004007455522447020754 0ustar michaelusersA D/ppc_asm//// A D/x86_asm//// xvid_20020412/xvidcore/src/motion/CVS/Entries0100644000100600001440000000025107455522447020240 0ustar michaelusers/motion_comp.c/1.2/Thu Mar 28 20:57:25 2002// /motion_est.c/1.5/Thu Apr 11 15:04:05 2002// /sad.c/1.2/Thu Apr 11 10:18:40 2002// /sad.h/1.4/Thu Apr 11 10:18:40 2002// D xvid_20020412/xvidcore/src/motion/motion_est.c0100644000100600001440000015643607455322745020615 0ustar michaelusers/************************************************************************** * * Modifications: * * 02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between * EPZS and EPZS^2 * 08.02.2002 split up PMVfast into three routines: PMVFast, PMVFast_MainLoop * PMVFast_Refine to support multiple searches with different start points * 07.01.2002 uv-block-based interpolation * 06.01.2002 INTER/INTRA-decision is now done before any SEARCH8 (speedup) * changed INTER_BIAS to 150 (as suggested by suxen_drol) * removed halfpel refinement step in PMVfastSearch8 + quality=5 * added new quality mode = 6 which performs halfpel refinement * filesize difference between quality 5 and 6 is smaller than 1% * (Isibaar) * 31.12.2001 PMVfastSearch16 and PMVfastSearch8 (gruel) * 30.12.2001 get_range/MotionSearchX simplified; blue/green bug fix * 22.12.2001 commented best_point==99 check * 19.12.2001 modified get_range (purple bug fix) * 15.12.2001 moved pmv displacement from mbprediction * 02.12.2001 motion estimation/compensation split (Isibaar) * 16.11.2001 rewrote/tweaked search algorithms; pross@cs.rmit.edu.au * 10.11.2001 support for sad16/sad8 functions * 28.08.2001 reactivated MODE_INTER4V for EXT_MODE * 24.08.2001 removed MODE_INTER4V_Q, disabled MODE_INTER4V for EXT_MODE * 22.08.2001 added MODE_INTER4V_Q * 20.08.2001 added pragma to get rid of internal compiler error with VC6 * idea by Cyril. Thanks. * * Michael Militzer * **************************************************************************/ #include #include #include #include "../encoder.h" #include "../utils/mbfunctions.h" #include "../prediction/mbprediction.h" #include "../global.h" #include "../utils/timer.h" #include "sad.h" // very large value #define MV_MAX_ERROR (4096 * 256) // stop search if sdelta < THRESHOLD #define MV16_THRESHOLD 192 #define MV8_THRESHOLD 56 /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */ /* nb = vop pixels * 2^(bpp-8) */ #define MV16_00_BIAS (128+1) /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */ #define INTER_BIAS 512 /* Parameters which control inter/inter4v decision */ #define IMV16X16 5 /* vector map (vlc delta size) smoother parameters */ #define NEIGH_TEND_16X16 2 #define NEIGH_TEND_8X8 2 // fast ((A)/2)*2 #define EVEN(A) (((A)<0?(A)+1:(A)) & ~1) #define MIN(X, Y) ((X)<(Y)?(X):(Y)) #define MAX(X, Y) ((X)>(Y)?(X):(Y)) #define ABS(X) (((X)>0)?(X):-(X)) #define SIGN(X) (((X)>0)?1:-1) int32_t PMVfastSearch16( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const uint32_t MotionFlags, const MBParam * const pParam, MACROBLOCK * const pMBs, VECTOR * const currMV, VECTOR * const currPMV); int32_t EPZSSearch16( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const uint32_t MotionFlags, const MBParam * const pParam, MACROBLOCK * const pMBs, VECTOR * const currMV, VECTOR * const currPMV); int32_t PMVfastSearch8( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const int start_x, int start_y, const uint32_t MotionFlags, const MBParam * const pParam, MACROBLOCK * const pMBs, VECTOR * const currMV, VECTOR * const currPMV); int32_t EPZSSearch8( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const int start_x, int start_y, const uint32_t MotionFlags, const MBParam * const pParam, MACROBLOCK * const pMBs, VECTOR * const currMV, VECTOR * const currPMV); typedef int32_t (MainSearch16Func)( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const uint8_t * const cur, const int x, const int y, int32_t startx, int32_t starty, int32_t iMinSAD, VECTOR * const currMV, const VECTOR * const pmv, const int32_t min_dx, const int32_t max_dx, const int32_t min_dy, const int32_t max_dy, const int32_t iEdgedWidth, const int32_t iDiamondSize, const int32_t iFcode, const int32_t iQuant, int iFound); typedef MainSearch16Func* MainSearch16FuncPtr; typedef int32_t (MainSearch8Func)( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const uint8_t * const cur, const int x, const int y, int32_t startx, int32_t starty, int32_t iMinSAD, VECTOR * const currMV, const VECTOR * const pmv, const int32_t min_dx, const int32_t max_dx, const int32_t min_dy, const int32_t max_dy, const int32_t iEdgedWidth, const int32_t iDiamondSize, const int32_t iFcode, const int32_t iQuant, int iFound); typedef MainSearch8Func* MainSearch8FuncPtr; // mv.length table static const uint32_t mvtab[33] = { 1, 2, 3, 4, 6, 7, 7, 7, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12 }; static __inline uint32_t mv_bits(int32_t component, const uint32_t iFcode) { if (component == 0) return 1; if (component < 0) component = -component; if (iFcode == 1) { if (component > 32) component = 32; return mvtab[component] + 1; } component += (1 << (iFcode - 1)) - 1; component >>= (iFcode - 1); if (component > 32) component = 32; return mvtab[component] + 1 + iFcode - 1; } static __inline uint32_t calc_delta_16(const int32_t dx, const int32_t dy, const uint32_t iFcode) { return NEIGH_TEND_16X16 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode)); } static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode) { return NEIGH_TEND_8X8 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode)); } /* calculate the min/max range (in halfpixels) relative to the _MACROBLOCK_ position */ static void __inline get_range( int32_t * const min_dx, int32_t * const max_dx, int32_t * const min_dy, int32_t * const max_dy, const uint32_t x, const uint32_t y, const uint32_t block_sz, // block dimension, 8 or 16 const uint32_t width, const uint32_t height, const uint32_t fcode) { const int search_range = 32 << (fcode - 1); const int high = search_range - 1; const int low = -search_range; // convert full-pixel measurements to half pixel const int hp_width = 2 * width; const int hp_height = 2 * height; const int hp_edge = 2 * block_sz; const int hp_x = 2 * (x) * block_sz; // we need _right end_ of block, not x-coordinate const int hp_y = 2 * (y) * block_sz; // same for _bottom end_ *max_dx = MIN(high, hp_width - hp_x); *max_dy = MIN(high, hp_height - hp_y); *min_dx = MAX(low, -(hp_edge + hp_x)); *min_dy = MAX(low, -(hp_edge + hp_y)); } /* * getref: calculate reference image pointer * the decision to use interpolation h/v/hv or the normal image is * based on dx & dy. */ static __inline const uint8_t * get_ref( const uint8_t * const refn, const uint8_t * const refh, const uint8_t * const refv, const uint8_t * const refhv, const uint32_t x, const uint32_t y, const uint32_t block, // block dimension, 8 or 16 const int32_t dx, const int32_t dy, const uint32_t stride) { switch ( ((dx&1)<<1) + (dy&1) ) // ((dx%2)?2:0)+((dy%2)?1:0) { case 0 : return refn + (x*block+dx/2) + (y*block+dy/2)*stride; case 1 : return refv + (x*block+dx/2) + (y*block+(dy-1)/2)*stride; case 2 : return refh + (x*block+(dx-1)/2) + (y*block+dy/2)*stride; default : case 3 : return refhv + (x*block+(dx-1)/2) + (y*block+(dy-1)/2)*stride; } } /* This is somehow a copy of get_ref, but with MV instead of X,Y */ static __inline const uint8_t * get_ref_mv( const uint8_t * const refn, const uint8_t * const refh, const uint8_t * const refv, const uint8_t * const refhv, const uint32_t x, const uint32_t y, const uint32_t block, // block dimension, 8 or 16 const VECTOR* mv, // measured in half-pel! const uint32_t stride) { switch ( (((mv->x)&1)<<1) + ((mv->y)&1) ) { case 0 : return refn + (x*block+(mv->x)/2) + (y*block+(mv->y)/2)*stride; case 1 : return refv + (x*block+(mv->x)/2) + (y*block+((mv->y)-1)/2)*stride; case 2 : return refh + (x*block+((mv->x)-1)/2) + (y*block+(mv->y)/2)*stride; default : case 3 : return refhv + (x*block+((mv->x)-1)/2) + (y*block+((mv->y)-1)/2)*stride; } } #ifndef SEARCH16 #define SEARCH16 PMVfastSearch16 //#define SEARCH16 FullSearch16 //#define SEARCH16 EPZSSearch16 #endif #ifndef SEARCH8 #define SEARCH8 PMVfastSearch8 //#define SEARCH8 EPZSSearch8 #endif bool MotionEstimation( MACROBLOCK * const pMBs, MBParam * const pParam, const IMAGE * const pRef, const IMAGE * const pRefH, const IMAGE * const pRefV, const IMAGE * const pRefHV, IMAGE * const pCurrent, const uint32_t iLimit) { const uint32_t iWcount = pParam->mb_width; const uint32_t iHcount = pParam->mb_height; uint32_t i, j, iIntra = 0; VECTOR mv16; VECTOR pmv16; int32_t sad8 = 0; int32_t sad16; int32_t deviation; if (sadInit) (*sadInit)(); // note: i==horizontal, j==vertical for (i = 0; i < iHcount; i++) for (j = 0; j < iWcount; j++) { MACROBLOCK *pMB = &pMBs[j + i * iWcount]; sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, j, i, pParam->motion_flags, pParam, pMBs, &mv16, &pmv16); pMB->sad16=sad16; /* decide: MODE_INTER or MODE_INTRA if (dev_intra < sad_inter - 2 * nb) use_intra */ deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width); if (deviation < (sad16 - INTER_BIAS)) { pMB->mode = MODE_INTRA; pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0; pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0; iIntra++; if(iIntra >= iLimit) return 1; continue; } if (pParam->global_flags & XVID_INTER4V) { pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, 2 * j, 2 * i, mv16.x, mv16.y, pParam->motion_flags, pParam, pMBs, &pMB->mvs[0], &pMB->pmvs[0]); pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, 2 * j + 1, 2 * i, mv16.x, mv16.y, pParam->motion_flags, pParam, pMBs, &pMB->mvs[1], &pMB->pmvs[1]); pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, 2 * j, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags, pParam, pMBs, &pMB->mvs[2], &pMB->pmvs[2]); pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, 2 * j + 1, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags, pParam, pMBs, &pMB->mvs[3], &pMB->pmvs[3]); sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3]; } /* decide: MODE_INTER or MODE_INTER4V mpeg4: if (sad8 < sad16 - nb/2+1) use_inter4v */ if (pMB->dquant == NO_CHANGE) { if (((pParam->global_flags & XVID_INTER4V)==0) || (sad16 < (sad8 + (int32_t)(IMV16X16 * pParam->quant)))) { sad8 = sad16; pMB->mode = MODE_INTER; pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x; pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y; pMB->pmvs[0].x = pmv16.x; pMB->pmvs[0].y = pmv16.y; } else pMB->mode = MODE_INTER4V; } else { sad8 = sad16; pMB->mode = MODE_INTER; pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x; pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y; pMB->pmvs[0].x = pmv16.x; pMB->pmvs[0].y = pmv16.y; } } return 0; } #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) ) #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) ) #define CHECK_MV16_ZERO {\ if ( (0 <= max_dx) && (0 >= min_dx) \ && (0 <= max_dy) && (0 >= min_dy) ) \ { \ iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \ iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD <= iQuant * 96) \ iSAD -= MV16_00_BIAS; \ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } } \ } #define NOCHECK_MV16_CANDIDATE(X,Y) { \ iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \ } #define CHECK_MV16_CANDIDATE(X,Y) { \ if ( ((X) <= max_dx) && ((X) >= min_dx) \ && ((Y) <= max_dy) && ((Y) >= min_dy) ) \ { \ iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \ } #define CHECK_MV16_CANDIDATE_DIR(X,Y,D) { \ if ( ((X) <= max_dx) && ((X) >= min_dx) \ && ((Y) <= max_dy) && ((Y) >= min_dy) ) \ { \ iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \ } #define CHECK_MV16_CANDIDATE_FOUND(X,Y,D) { \ if ( ((X) <= max_dx) && ((X) >= min_dx) \ && ((Y) <= max_dy) && ((Y) >= min_dy) ) \ { \ iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \ iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \ } #define CHECK_MV8_ZERO {\ iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \ iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \ } #define NOCHECK_MV8_CANDIDATE(X,Y) \ { \ iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \ iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \ } #define CHECK_MV8_CANDIDATE(X,Y) { \ if ( ((X) <= max_dx) && ((X) >= min_dx) \ && ((Y) <= max_dy) && ((Y) >= min_dy) ) \ { \ iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \ iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \ } #define CHECK_MV8_CANDIDATE_DIR(X,Y,D) { \ if ( ((X) <= max_dx) && ((X) >= min_dx) \ && ((Y) <= max_dy) && ((Y) >= min_dy) ) \ { \ iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \ iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \ } #define CHECK_MV8_CANDIDATE_FOUND(X,Y,D) { \ if ( ((X) <= max_dx) && ((X) >= min_dx) \ && ((Y) <= max_dy) && ((Y) >= min_dy) ) \ { \ iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \ iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\ if (iSAD < iMinSAD) \ { iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \ } /* too slow and not fully functional at the moment */ /* int32_t ZeroSearch16( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const uint32_t MotionFlags, MBParam * const pParam, MACROBLOCK * const pMBs, VECTOR * const currMV, VECTOR * const currPMV) { const int32_t iEdgedWidth = pParam->edged_width; const int32_t iQuant = pParam->quant; const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth; int32_t iSAD; int32_t pred_x,pred_y; get_pmv(pMBs, x, y, pParam->mb_width, 0, &pred_x, &pred_y); iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0,0, iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); if (iSAD <= iQuant * 96) iSAD -= MV16_00_BIAS; currMV->x = 0; currMV->y = 0; currPMV->x = -pred_x; currPMV->y = -pred_y; return iSAD; } */ int32_t Diamond16_MainSearch( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const uint8_t * const cur, const int x, const int y, int32_t startx, int32_t starty, int32_t iMinSAD, VECTOR * const currMV, const VECTOR * const pmv, const int32_t min_dx, const int32_t max_dx, const int32_t min_dy, const int32_t max_dy, const int32_t iEdgedWidth, const int32_t iDiamondSize, const int32_t iFcode, const int32_t iQuant, int iFound) { /* Do a diamond search around given starting point, return SAD of best */ int32_t iDirection=0; int32_t iSAD; VECTOR backupMV; backupMV.x = startx; backupMV.y = starty; /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */ CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4); if (iDirection) while (!iFound) { iFound = 1; backupMV=*currMV; if ( iDirection != 2) CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1); if ( iDirection != 1) CHECK_MV16_CANDIDATE_FOUND(backupMV.x+iDiamondSize,backupMV.y,2); if ( iDirection != 4) CHECK_MV16_CANDIDATE_FOUND(backupMV.x,backupMV.y-iDiamondSize,3); if ( iDirection != 3) CHECK_MV16_CANDIDATE_FOUND(backupMV.x,backupMV.y+iDiamondSize,4); } else { currMV->x = startx; currMV->y = starty; } return iMinSAD; } int32_t Square16_MainSearch( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const uint8_t * const cur, const int x, const int y, int32_t startx, int32_t starty, int32_t iMinSAD, VECTOR * const currMV, const VECTOR * const pmv, const int32_t min_dx, const int32_t max_dx, const int32_t min_dy, const int32_t max_dy, const int32_t iEdgedWidth, const int32_t iDiamondSize, const int32_t iFcode, const int32_t iQuant, int iFound) { /* Do a square search around given starting point, return SAD of best */ int32_t iDirection=0; int32_t iSAD; VECTOR backupMV; backupMV.x = startx; backupMV.y = starty; /* It's one search with full square pattern, and new parts for all following diamonds */ /* new direction are extra, so 1-4 is normal diamond 537 1*2 648 */ CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8); if (iDirection) while (!iFound) { iFound = 1; backupMV=*currMV; switch (iDirection) { case 1: CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7); break; case 2: CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8); break; case 3: CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8); break; case 4: CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6); break; case 5: CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7); break; case 6: CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8); break; case 7: CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8); break; case 8: CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8); break; default: CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3); CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5); CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7); CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8); break; } } else { currMV->x = startx; currMV->y = starty; } return iMinSAD; } int32_t Full16_MainSearch( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const uint8_t * const cur, const int x, const int y, int32_t startx, int32_t starty, int32_t iMinSAD, VECTOR * const currMV, const VECTOR * const pmv, const int32_t min_dx, const int32_t max_dx, const int32_t min_dy, const int32_t max_dy, const int32_t iEdgedWidth, const int32_t iDiamondSize, const int32_t iFcode, const int32_t iQuant, int iFound) { int32_t iSAD; int32_t dx,dy; VECTOR backupMV; backupMV.x = startx; backupMV.y = starty; for (dx = min_dx; dx<=max_dx; dx+=iDiamondSize) for (dy = min_dy; dy<= max_dy; dy+=iDiamondSize) NOCHECK_MV16_CANDIDATE(dx,dy); return iMinSAD; } int32_t Full8_MainSearch( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const uint8_t * const cur, const int x, const int y, int32_t startx, int32_t starty, int32_t iMinSAD, VECTOR * const currMV, const VECTOR * const pmv, const int32_t min_dx, const int32_t max_dx, const int32_t min_dy, const int32_t max_dy, const int32_t iEdgedWidth, const int32_t iDiamondSize, const int32_t iFcode, const int32_t iQuant, int iFound) { int32_t iSAD; int32_t dx,dy; VECTOR backupMV; backupMV.x = startx; backupMV.y = starty; for (dx = min_dx; dx<=max_dx; dx+=iDiamondSize) for (dy = min_dy; dy<= max_dy; dy+=iDiamondSize) NOCHECK_MV8_CANDIDATE(dx,dy); return iMinSAD; } int32_t Halfpel16_Refine( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const uint8_t * const cur, const int x, const int y, VECTOR * const currMV, int32_t iMinSAD, const VECTOR * const pmv, const int32_t min_dx, const int32_t max_dx, const int32_t min_dy, const int32_t max_dy, const int32_t iFcode, const int32_t iQuant, const int32_t iEdgedWidth) { /* Do a half-pel refinement (or rather a "smallest possible amount" refinement) */ int32_t iSAD; VECTOR backupMV = *currMV; CHECK_MV16_CANDIDATE(backupMV.x-1,backupMV.y-1); CHECK_MV16_CANDIDATE(backupMV.x ,backupMV.y-1); CHECK_MV16_CANDIDATE(backupMV.x+1,backupMV.y-1); CHECK_MV16_CANDIDATE(backupMV.x-1,backupMV.y); CHECK_MV16_CANDIDATE(backupMV.x+1,backupMV.y); CHECK_MV16_CANDIDATE(backupMV.x-1,backupMV.y+1); CHECK_MV16_CANDIDATE(backupMV.x ,backupMV.y+1); CHECK_MV16_CANDIDATE(backupMV.x+1,backupMV.y+1); return iMinSAD; } #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16) int32_t PMVfastSearch16( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const uint32_t MotionFlags, const MBParam * const pParam, MACROBLOCK * const pMBs, VECTOR * const currMV, VECTOR * const currPMV) { const uint32_t iWcount = pParam->mb_width; const int32_t iFcode = pParam->fixed_code; const int32_t iQuant = pParam->quant; const int32_t iWidth = pParam->width; const int32_t iHeight = pParam->height; const int32_t iEdgedWidth = pParam->edged_width; const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth; int32_t iDiamondSize; int32_t min_dx; int32_t max_dx; int32_t min_dy; int32_t max_dy; int32_t iFound; VECTOR newMV; VECTOR backupMV; /* just for PMVFAST */ VECTOR pmv[4]; int32_t psad[4]; MACROBLOCK * const pMB = pMBs + x + y * iWcount; static int32_t threshA,threshB; int32_t bPredEq; int32_t iMinSAD,iSAD; /* Get maximum range */ get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight, iFcode); /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */ if (!(MotionFlags & PMV_HALFPEL16 )) { min_dx = EVEN(min_dx); max_dx = EVEN(max_dx); min_dy = EVEN(min_dy); max_dy = EVEN(max_dy); } /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */ bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad); if ((x==0) && (y==0) ) { threshA = 512; threshB = 1024; } else { threshA = psad[0]; threshB = threshA+256; if (threshA< 512) threshA = 512; if (threshA>1024) threshA = 1024; if (threshB>1792) threshB = 1792; } iFound=0; /* Step 2: Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion vector of the median. If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2 */ if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[0]) ) ) iFound=2; /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search. Otherwise select large Diamond Search. */ if ( (pmv[0].x != 0) || (pmv[0].y != 0) || (threshB<1536) || (bPredEq) ) iDiamondSize=1; // halfpel! else iDiamondSize=2; // halfpel! if (!(MotionFlags & PMV_HALFPELDIAMOND16) ) iDiamondSize*=2; /* Step 4: Calculate SAD around the Median prediction. MinSAD=SAD If Motion Vector equal to Previous frame motion vector and MinSADx = EVEN(currMV->x); currMV->y = EVEN(currMV->y); } if (currMV->x > max_dx) { currMV->x=max_dx; } if (currMV->x < min_dx) { currMV->x=min_dx; } if (currMV->y > max_dy) { currMV->y=max_dy; } if (currMV->y < min_dy) { currMV->y=min_dy; } iMinSAD = sad16( cur, get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant; if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) ) { if (MotionFlags & PMV_QUICKSTOP16) goto PMVfast16_Terminate_without_Refine; if (MotionFlags & PMV_EARLYSTOP16) goto PMVfast16_Terminate_with_Refine; } /* Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block. Also calculate (0,0) but do not subtract offset. Let MinSAD be the smallest SAD up to this point. If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? *********** */ // (0,0) is always possible CHECK_MV16_ZERO; // previous frame MV is always possible CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y); // left neighbour, if allowed if (x != 0) { if (!(MotionFlags & PMV_HALFPEL16 )) { pmv[1].x = EVEN(pmv[1].x); pmv[1].y = EVEN(pmv[1].y); } CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y); } // top neighbour, if allowed if (y != 0) { if (!(MotionFlags & PMV_HALFPEL16 )) { pmv[2].x = EVEN(pmv[2].x); pmv[2].y = EVEN(pmv[2].y); } CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y); // top right neighbour, if allowed if (x != (iWcount-1)) { if (!(MotionFlags & PMV_HALFPEL16 )) { pmv[3].x = EVEN(pmv[3].x); pmv[3].y = EVEN(pmv[3].y); } CHECK_MV16_CANDIDATE(pmv[3].x,pmv[3].y); } } /* Step 6: If MinSAD <= thresa goto Step 10. If Motion Vector equal to Previous frame motion vector and MinSADmvs[0]) && (iMinSAD < pMB->sad16) ) ) { if (MotionFlags & PMV_QUICKSTOP16) goto PMVfast16_Terminate_without_Refine; if (MotionFlags & PMV_EARLYSTOP16) goto PMVfast16_Terminate_with_Refine; } /************ (Diamond Search) **************/ /* Step 7: Perform Diamond search, with either the small or large diamond. If Found=2 only examine one Diamond pattern, and afterwards goto step 10 Step 8: If small diamond, iterate small diamond search pattern until motion vector lies in the center of the diamond. If center then goto step 10. Step 9: If large diamond, iterate large diamond search pattern until motion vector lies in the center. Refine by using small diamond and goto step 10. */ backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ /* default: use best prediction as starting point for one call of PMVfast_MainSearch */ iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } if (MotionFlags & PMV_EXTSEARCH16) { /* extended: search (up to) two more times: orignal prediction and (0,0) */ if (!(MVequal(pmv[0],backupMV)) ) { iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, x, y, pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } } if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) { iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } } } /* Step 10: The motion vector is chosen according to the block corresponding to MinSAD. */ PMVfast16_Terminate_with_Refine: if (MotionFlags & PMV_HALFPELREFINE16) // perform final half-pel step iMinSAD = Halfpel16_Refine( pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV, iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth); PMVfast16_Terminate_without_Refine: currPMV->x = currMV->x - pmv[0].x; currPMV->y = currMV->y - pmv[0].y; return iMinSAD; } int32_t Diamond8_MainSearch( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const uint8_t * const cur, const int x, const int y, int32_t startx, int32_t starty, int32_t iMinSAD, VECTOR * const currMV, const VECTOR * const pmv, const int32_t min_dx, const int32_t max_dx, const int32_t min_dy, const int32_t max_dy, const int32_t iEdgedWidth, const int32_t iDiamondSize, const int32_t iFcode, const int32_t iQuant, int iFound) { /* Do a diamond search around given starting point, return SAD of best */ int32_t iDirection=0; int32_t iSAD; VECTOR backupMV; backupMV.x = startx; backupMV.y = starty; /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */ CHECK_MV8_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1); CHECK_MV8_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2); CHECK_MV8_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3); CHECK_MV8_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4); if (iDirection) while (!iFound) { iFound = 1; backupMV=*currMV; // since iDirection!=0, this is well defined! if ( iDirection != 2) CHECK_MV8_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1); if ( iDirection != 1) CHECK_MV8_CANDIDATE_FOUND(backupMV.x+iDiamondSize,backupMV.y,2); if ( iDirection != 4) CHECK_MV8_CANDIDATE_FOUND(backupMV.x,backupMV.y-iDiamondSize,3); if ( iDirection != 3) CHECK_MV8_CANDIDATE_FOUND(backupMV.x,backupMV.y+iDiamondSize,4); } else { currMV->x = startx; currMV->y = starty; } return iMinSAD; } int32_t Halfpel8_Refine( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const uint8_t * const cur, const int x, const int y, VECTOR * const currMV, int32_t iMinSAD, const VECTOR * const pmv, const int32_t min_dx, const int32_t max_dx, const int32_t min_dy, const int32_t max_dy, const int32_t iFcode, const int32_t iQuant, const int32_t iEdgedWidth) { /* Do a half-pel refinement (or rather a "smallest possible amount" refinement) */ int32_t iSAD; VECTOR backupMV = *currMV; CHECK_MV8_CANDIDATE(backupMV.x-1,backupMV.y-1); CHECK_MV8_CANDIDATE(backupMV.x ,backupMV.y-1); CHECK_MV8_CANDIDATE(backupMV.x+1,backupMV.y-1); CHECK_MV8_CANDIDATE(backupMV.x-1,backupMV.y); CHECK_MV8_CANDIDATE(backupMV.x+1,backupMV.y); CHECK_MV8_CANDIDATE(backupMV.x-1,backupMV.y+1); CHECK_MV8_CANDIDATE(backupMV.x ,backupMV.y+1); CHECK_MV8_CANDIDATE(backupMV.x+1,backupMV.y+1); return iMinSAD; } #define PMV_HALFPEL8 (PMV_HALFPELDIAMOND8|PMV_HALFPELREFINE8) int32_t PMVfastSearch8( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const int start_x, int start_y, const uint32_t MotionFlags, const MBParam * const pParam, MACROBLOCK * const pMBs, VECTOR * const currMV, VECTOR * const currPMV) { const uint32_t iWcount = pParam->mb_width; const int32_t iFcode = pParam->fixed_code; const int32_t iQuant = pParam->quant; const int32_t iWidth = pParam->width; const int32_t iHeight = pParam->height; const int32_t iEdgedWidth = pParam->edged_width; const uint8_t * cur = pCur->y + x*8 + y*8*iEdgedWidth; int32_t iDiamondSize; int32_t min_dx; int32_t max_dx; int32_t min_dy; int32_t max_dy; VECTOR pmv[4]; int32_t psad[4]; VECTOR newMV; VECTOR backupMV; MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; static int32_t threshA,threshB; int32_t iFound,bPredEq; int32_t iMinSAD,iSAD; int32_t iSubBlock = ((y&1)<<1) + (x&1); /* Get maximum range */ get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 8, iWidth, iHeight, iFcode); /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */ if (!(MotionFlags & PMV_HALFPELDIAMOND8 )) { min_dx = EVEN(min_dx); max_dx = EVEN(max_dx); min_dy = EVEN(min_dy); max_dy = EVEN(max_dy); } /* because we might use IF (dx>max_dx) THEN dx=max_dx; */ bPredEq = get_pmvdata(pMBs, (x>>1), (y>>1), iWcount, iSubBlock, pmv, psad); if ((x==0) && (y==0) ) { threshA = 512/4; threshB = 1024/4; } else { threshA = psad[0]/4; /* good estimate */ threshB = threshA+256/4; if (threshA< 512/4) threshA = 512/4; if (threshA>1024/4) threshA = 1024/4; if (threshB>1792/4) threshB = 1792/4; } iFound=0; /* Step 2: Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion vector of the median. If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2 */ if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[iSubBlock]) ) ) iFound=2; /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search. Otherwise select large Diamond Search. */ if ( (pmv[0].x != 0) || (pmv[0].y != 0) || (threshB<1536/4) || (bPredEq) ) iDiamondSize=1; // 1 halfpel! else iDiamondSize=2; // 2 halfpel = 1 full pixel! if (!(MotionFlags & PMV_HALFPELDIAMOND8) ) iDiamondSize*=2; /* Step 4: Calculate SAD around the Median prediction. MinSAD=SAD If Motion Vector equal to Previous frame motion vector and MinSADx=start_x; /* start with mv16 */ currMV->y=start_y; iMinSAD = sad8( cur, get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth), iEdgedWidth); iMinSAD += calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y, (uint8_t)iFcode) * iQuant; if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && (iMinSAD < pMB->sad8[iSubBlock]) ) ) { if (MotionFlags & PMV_QUICKSTOP16) goto PMVfast8_Terminate_without_Refine; if (MotionFlags & PMV_EARLYSTOP16) goto PMVfast8_Terminate_with_Refine; } /* Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block. Also calculate (0,0) but do not subtract offset. Let MinSAD be the smallest SAD up to this point. If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? *********** */ // the prediction might be even better than mv16 CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y); // (0,0) is always possible CHECK_MV8_ZERO; // previous frame MV is always possible CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y); // left neighbour, if allowed if (psad[1] != MV_MAX_ERROR) { if (!(MotionFlags & PMV_HALFPEL8 )) { pmv[1].x = EVEN(pmv[1].x); pmv[1].y = EVEN(pmv[1].y); } CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y); } // top neighbour, if allowed if (psad[2] != MV_MAX_ERROR) { if (!(MotionFlags & PMV_HALFPEL8 )) { pmv[2].x = EVEN(pmv[2].x); pmv[2].y = EVEN(pmv[2].y); } CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y); // top right neighbour, if allowed if (psad[3] != MV_MAX_ERROR) { if (!(MotionFlags & PMV_HALFPEL8 )) { pmv[3].x = EVEN(pmv[3].x); pmv[3].y = EVEN(pmv[3].y); } CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y); } } /* Step 6: If MinSAD <= thresa goto Step 10. If Motion Vector equal to Previous frame motion vector and MinSADmvs[iSubBlock]) && (iMinSAD < pMB->sad8[iSubBlock]) ) ) { if (MotionFlags & PMV_QUICKSTOP16) goto PMVfast8_Terminate_without_Refine; if (MotionFlags & PMV_EARLYSTOP16) goto PMVfast8_Terminate_with_Refine; } /************ (Diamond Search) **************/ /* Step 7: Perform Diamond search, with either the small or large diamond. If Found=2 only examine one Diamond pattern, and afterwards goto step 10 Step 8: If small diamond, iterate small diamond search pattern until motion vector lies in the center of the diamond. If center then goto step 10. Step 9: If large diamond, iterate large diamond search pattern until motion vector lies in the center. Refine by using small diamond and goto step 10. */ backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ /* default: use best prediction as starting point for one call of PMVfast_MainSearch */ iSAD = Diamond8_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } if (MotionFlags & PMV_EXTSEARCH8) { /* extended: search (up to) two more times: orignal prediction and (0,0) */ if (!(MVequal(pmv[0],backupMV)) ) { iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, x, y, pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } } if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) { iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } } } /* Step 10: The motion vector is chosen according to the block corresponding to MinSAD. By performing an optional local half-pixel search, we can refine this result even further. */ PMVfast8_Terminate_with_Refine: if (MotionFlags & PMV_HALFPELREFINE8) // perform final half-pel step iMinSAD = Halfpel8_Refine( pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV, iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth); PMVfast8_Terminate_without_Refine: currPMV->x = currMV->x - pmv[0].x; currPMV->y = currMV->y - pmv[0].y; return iMinSAD; } int32_t EPZSSearch16( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const uint32_t MotionFlags, const MBParam * const pParam, MACROBLOCK * const pMBs, VECTOR * const currMV, VECTOR * const currPMV) { const uint32_t iWcount = pParam->mb_width; const uint32_t iHcount = pParam->mb_height; const int32_t iFcode = pParam->fixed_code; const int32_t iQuant = pParam->quant; const int32_t iWidth = pParam->width; const int32_t iHeight = pParam->height; const int32_t iEdgedWidth = pParam->edged_width; const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth; int32_t min_dx; int32_t max_dx; int32_t min_dy; int32_t max_dy; VECTOR newMV; VECTOR backupMV; VECTOR pmv[4]; int32_t psad[8]; static MACROBLOCK * oldMBs = NULL; MACROBLOCK * const pMB = pMBs + x + y * iWcount; MACROBLOCK * oldMB = NULL; static int32_t thresh2; int32_t bPredEq; int32_t iMinSAD,iSAD=9999; MainSearch16FuncPtr EPZSMainSearchPtr; if (oldMBs == NULL) { oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK)); fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK)); } oldMB = oldMBs + x + y * iWcount; /* Get maximum range */ get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight, iFcode); /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */ if (!(MotionFlags & PMV_HALFPEL16 )) { min_dx = EVEN(min_dx); max_dx = EVEN(max_dx); min_dy = EVEN(min_dy); max_dy = EVEN(max_dy); } /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */ bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad); /* Step 4: Calculate SAD around the Median prediction. MinSAD=SAD If Motion Vector equal to Previous frame motion vector and MinSADx = EVEN(currMV->x); currMV->y = EVEN(currMV->y); } if (currMV->x > max_dx) currMV->x=max_dx; if (currMV->x < min_dx) currMV->x=min_dx; if (currMV->y > max_dy) currMV->y=max_dy; if (currMV->y < min_dy) currMV->y=min_dy; /***************** This is predictor SET A: only median prediction ******************/ iMinSAD = sad16( cur, get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant; // thresh1 is fixed to 256 if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) ) { if (MotionFlags & PMV_QUICKSTOP16) goto EPZS16_Terminate_without_Refine; if (MotionFlags & PMV_EARLYSTOP16) goto EPZS16_Terminate_with_Refine; } /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/ // previous frame MV CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y); // set threshhold based on Min of Prediction and SAD of collocated block // CHECK_MV16 always uses iSAD for the SAD of last vector to check, so now iSAD is what we want if ((x==0) && (y==0) ) { thresh2 = 512; } else { /* T_k = 1.2 * MIN(SAD_top,SAD_left,SAD_topleft,SAD_coll) +128; [Tourapis, 2002] */ thresh2 = MIN(psad[0],iSAD)*6/5 + 128; } // MV=(0,0) is often a good choice CHECK_MV16_ZERO; // left neighbour, if allowed if (x != 0) { if (!(MotionFlags & PMV_HALFPEL16 )) { pmv[1].x = EVEN(pmv[1].x); pmv[1].y = EVEN(pmv[1].y); } CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y); } // top neighbour, if allowed if (y != 0) { if (!(MotionFlags & PMV_HALFPEL16 )) { pmv[2].x = EVEN(pmv[2].x); pmv[2].y = EVEN(pmv[2].y); } CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y); // top right neighbour, if allowed if (x != (iWcount-1)) { if (!(MotionFlags & PMV_HALFPEL16 )) { pmv[3].x = EVEN(pmv[3].x); pmv[3].y = EVEN(pmv[3].y); } CHECK_MV16_CANDIDATE(pmv[3].x,pmv[3].y); } } /* Terminate if MinSAD <= T_2 Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1] */ if ( (iMinSAD <= thresh2) || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) ) { if (MotionFlags & PMV_QUICKSTOP16) goto EPZS16_Terminate_without_Refine; if (MotionFlags & PMV_EARLYSTOP16) goto EPZS16_Terminate_with_Refine; } /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/ backupMV = pMB->mvs[0]; // last MV backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x ); // acceleration X backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y ); // acceleration Y CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y); // left neighbour if (x != 0) CHECK_MV16_CANDIDATE((oldMB-1)->mvs[0].x,oldMB->mvs[0].y); // top neighbour if (y != 0) CHECK_MV16_CANDIDATE((oldMB-iWcount)->mvs[0].x,oldMB->mvs[0].y); // right neighbour, if allowed (this value is not written yet, so take it from pMB->mvs if (x != iWcount-1) CHECK_MV16_CANDIDATE((pMB+1)->mvs[0].x,oldMB->mvs[0].y); // bottom neighbour, dito if (y != iHcount-1) CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y); /* Terminate if MinSAD <= T_3 (here T_3 = T_2) */ if (iMinSAD <= thresh2) { if (MotionFlags & PMV_QUICKSTOP16) goto EPZS16_Terminate_without_Refine; if (MotionFlags & PMV_EARLYSTOP16) goto EPZS16_Terminate_with_Refine; } /************ (if Diamond Search) **************/ backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ /* default: use best prediction as starting point for one call of PMVfast_MainSearch */ if (MotionFlags & PMV_USESQUARES16) EPZSMainSearchPtr = Square16_MainSearch; else EPZSMainSearchPtr = Diamond16_MainSearch; iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } if (MotionFlags & PMV_EXTSEARCH16) { /* extended mode: search (up to) two more times: orignal prediction and (0,0) */ if (!(MVequal(pmv[0],backupMV)) ) { iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0); } if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) { iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, /*iDiamondSize*/ 2, iFcode, iQuant, 0); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } } } /*************** Choose best MV found **************/ EPZS16_Terminate_with_Refine: if (MotionFlags & PMV_HALFPELREFINE16) // perform final half-pel step iMinSAD = Halfpel16_Refine( pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV, iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth); EPZS16_Terminate_without_Refine: *oldMB = *pMB; currPMV->x = currMV->x - pmv[0].x; currPMV->y = currMV->y - pmv[0].y; return iMinSAD; } int32_t EPZSSearch8( const uint8_t * const pRef, const uint8_t * const pRefH, const uint8_t * const pRefV, const uint8_t * const pRefHV, const IMAGE * const pCur, const int x, const int y, const int start_x, const int start_y, const uint32_t MotionFlags, const MBParam * const pParam, MACROBLOCK * const pMBs, VECTOR * const currMV, VECTOR * const currPMV) { const uint32_t iWcount = pParam->mb_width; const int32_t iFcode = pParam->fixed_code; const int32_t iQuant = pParam->quant; const int32_t iWidth = pParam->width; const int32_t iHeight = pParam->height; const int32_t iEdgedWidth = pParam->edged_width; const uint8_t * cur = pCur->y + x*8 + y*8*iEdgedWidth; int32_t iDiamondSize=1; int32_t min_dx; int32_t max_dx; int32_t min_dy; int32_t max_dy; VECTOR newMV; VECTOR backupMV; VECTOR pmv[4]; int32_t psad[8]; const int32_t iSubBlock = ((y&1)<<1) + (x&1); MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; int32_t bPredEq; int32_t iMinSAD,iSAD=9999; MainSearch8FuncPtr EPZSMainSearchPtr; /* Get maximum range */ get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 8, iWidth, iHeight, iFcode); /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */ if (!(MotionFlags & PMV_HALFPEL8 )) { min_dx = EVEN(min_dx); max_dx = EVEN(max_dx); min_dy = EVEN(min_dy); max_dy = EVEN(max_dy); } /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */ bPredEq = get_pmvdata(pMBs, x>>1, y>>1, iWcount, iSubBlock, pmv, psad); /* Step 4: Calculate SAD around the Median prediction. MinSAD=SAD If Motion Vector equal to Previous frame motion vector and MinSADx = EVEN(currMV->x); currMV->y = EVEN(currMV->y); } if (currMV->x > max_dx) currMV->x=max_dx; if (currMV->x < min_dx) currMV->x=min_dx; if (currMV->y > max_dy) currMV->y=max_dy; if (currMV->y < min_dy) currMV->y=min_dy; /***************** This is predictor SET A: only median prediction ******************/ iMinSAD = sad8( cur, get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth), iEdgedWidth); iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant; // thresh1 is fixed to 256 if (iMinSAD < 256/4 ) { if (MotionFlags & PMV_QUICKSTOP8) goto EPZS8_Terminate_without_Refine; if (MotionFlags & PMV_EARLYSTOP8) goto EPZS8_Terminate_with_Refine; } /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/ // previous frame MV CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y); // MV=(0,0) is often a good choice CHECK_MV8_ZERO; /* Terminate if MinSAD <= T_2 Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1] */ if (iMinSAD < 512/4) /* T_2 == 512/4 hardcoded */ { if (MotionFlags & PMV_QUICKSTOP8) goto EPZS8_Terminate_without_Refine; if (MotionFlags & PMV_EARLYSTOP8) goto EPZS8_Terminate_with_Refine; } /************ (if Diamond Search) **************/ backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ if (!(MotionFlags & PMV_HALFPELDIAMOND8)) iDiamondSize *= 2; /* default: use best prediction as starting point for one call of PMVfast_MainSearch */ // if (MotionFlags & PMV_USESQUARES8) // EPZSMainSearchPtr = Square8_MainSearch; // else EPZSMainSearchPtr = Diamond8_MainSearch; iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 00); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } if (MotionFlags & PMV_EXTSEARCH8) { /* extended mode: search (up to) two more times: orignal prediction and (0,0) */ if (!(MVequal(pmv[0],backupMV)) ) { iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } } if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) { iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0); if (iSAD < iMinSAD) { *currMV = newMV; iMinSAD = iSAD; } } } /*************** Choose best MV found **************/ EPZS8_Terminate_with_Refine: if (MotionFlags & PMV_HALFPELREFINE8) // perform final half-pel step iMinSAD = Halfpel8_Refine( pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV, iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth); EPZS8_Terminate_without_Refine: currPMV->x = currMV->x - pmv[0].x; currPMV->y = currMV->y - pmv[0].y; return iMinSAD; } xvid_20020412/xvidcore/src/motion/sad.c0100644000100600001440000000617107455261400017160 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * sum of absolute difference * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 10.11.2001 initial version; (c)2001 peter ross * *************************************************************************/ #include "../portab.h" #include "sad.h" sad16FuncPtr sad16; sad8FuncPtr sad8; dev16FuncPtr dev16; sadInitFuncPtr sadInit; #define ABS(X) (((X)>0)?(X):-(X)) uint32_t sad16_c(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride, const uint32_t best_sad) { uint32_t sad = 0; uint32_t i,j; uint8_t const *ptr_cur = cur; uint8_t const *ptr_ref = ref; for (j = 0; j < 16; j++) { for (i = 0; i < 16; i++) { sad += ABS(*(ptr_cur + i) - *(ptr_ref + i)); if (sad >= best_sad) { return sad; } } ptr_cur += stride; ptr_ref += stride; } return sad; } uint32_t sad8_c(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride) { uint32_t sad = 0; uint32_t i,j; uint8_t const *ptr_cur = cur; uint8_t const *ptr_ref = ref; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { sad += ABS(*(ptr_cur + i) - *(ptr_ref + i)); } ptr_cur += stride; ptr_ref += stride; } return sad; } /* average deviation from mean */ uint32_t dev16_c(const uint8_t * const cur, const uint32_t stride) { uint32_t mean = 0; uint32_t dev = 0; uint32_t i,j; uint8_t const *ptr_cur = cur; for (j = 0; j < 16; j++) { for (i = 0; i < 16; i++) mean += *(ptr_cur + i); ptr_cur += stride; } mean /= (16 * 16); ptr_cur = cur; for (j = 0; j < 16; j++) { for (i = 0; i < 16; i++) dev += ABS(*(ptr_cur + i) - (int32_t)mean); ptr_cur += stride; } return dev; } xvid_20020412/xvidcore/src/motion/sad.h0100644000100600001440000000374407455261400017170 0ustar michaelusers#ifndef _ENCODER_SAD_H_ #define _ENCODER_SAD_H_ #include "../portab.h" typedef void (sadInitFunc)(void); typedef sadInitFunc* sadInitFuncPtr; extern sadInitFuncPtr sadInit; sadInitFunc sadInit_altivec; typedef uint32_t (sad16Func)(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride, const uint32_t best_sad); typedef sad16Func* sad16FuncPtr; extern sad16FuncPtr sad16; sad16Func sad16_c; sad16Func sad16_mmx; sad16Func sad16_xmm; sad16Func sad16_altivec; typedef uint32_t (sad8Func)(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride); typedef sad8Func* sad8FuncPtr; extern sad8FuncPtr sad8; sad8Func sad8_c; sad8Func sad8_mmx; sad8Func sad8_xmm; sad8Func sad8_altivec; typedef uint32_t (dev16Func)(const uint8_t * const cur, const uint32_t stride); typedef dev16Func *dev16FuncPtr; extern dev16FuncPtr dev16; dev16Func dev16_c; dev16Func dev16_mmx; dev16Func dev16_xmm; dev16Func dev16_altivec; /* plain c */ /* uint32_t sad16(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride, const uint32_t best_sad); uint32_t sad8(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride); uint32_t dev16(const uint8_t * const cur, const uint32_t stride); */ /* mmx */ /* uint32_t sad16_mmx(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride, const uint32_t best_sad); uint32_t sad8_mmx(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride); uint32_t dev16_mmx(const uint8_t * const cur, const uint32_t stride); */ /* xmm */ /* uint32_t sad16_xmm(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride, const uint32_t best_sad); uint32_t sad8_xmm(const uint8_t * const cur, const uint8_t * const ref, const uint32_t stride); uint32_t dev16_xmm(const uint8_t * const cur, const uint32_t stride); */ #endif /* _ENCODER_SAD_H_ */ xvid_20020412/xvidcore/src/motion/motion_comp.c0100644000100600001440000001154007450701665020737 0ustar michaelusers#include "../encoder.h" #include "../utils/mbfunctions.h" #include "../image/interpolate8x8.h" #include "../utils/timer.h" #define ABS(X) (((X)>0)?(X):-(X)) #define SIGN(X) (((X)>0)?1:-1) static __inline void compensate8x8_halfpel( int16_t * const dct_codes, uint8_t * const cur, const uint8_t * const ref, const uint8_t * const refh, const uint8_t * const refv, const uint8_t * const refhv, const uint32_t x, const uint32_t y, const int32_t dx, const int dy, const uint32_t stride) { int32_t ddx,ddy; switch ( ((dx&1)<<1) + (dy&1) ) // ((dx%2)?2:0)+((dy%2)?1:0) { case 0 : ddx = dx/2; ddy = dy/2; transfer_8to16sub(dct_codes, cur + y*stride + x, ref + (y+ddy)*stride + x+ddx, stride); break; case 1 : ddx = dx/2; ddy = (dy-1)/2; transfer_8to16sub(dct_codes, cur + y*stride + x, refv + (y+ddy)*stride + x+ddx, stride); break; case 2 : ddx = (dx-1)/2; ddy = dy/2; transfer_8to16sub(dct_codes, cur + y*stride + x, refh + (y+ddy)*stride + x+ddx, stride); break; default : // case 3: ddx = (dx-1)/2; ddy = (dy-1)/2; transfer_8to16sub(dct_codes, cur + y*stride + x, refhv + (y+ddy)*stride + x+ddx, stride); break; } } void MBMotionCompensation( MACROBLOCK * const mb, const uint32_t i, const uint32_t j, const IMAGE * const ref, const IMAGE * const refh, const IMAGE * const refv, const IMAGE * const refhv, IMAGE * const cur, int16_t *dct_codes, const uint32_t width, const uint32_t height, const uint32_t edged_width, const uint32_t rounding) { static const uint32_t roundtab[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2 }; if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) { int32_t dx = mb->mvs[0].x; int32_t dy = mb->mvs[0].y; compensate8x8_halfpel(&dct_codes[0*64], cur->y, ref->y, refh->y, refv->y, refhv->y, 16*i, 16*j, dx, dy, edged_width); compensate8x8_halfpel(&dct_codes[1*64], cur->y, ref->y, refh->y, refv->y, refhv->y, 16*i + 8, 16*j, dx, dy, edged_width); compensate8x8_halfpel(&dct_codes[2*64], cur->y, ref->y, refh->y, refv->y, refhv->y, 16*i, 16*j + 8, dx, dy, edged_width); compensate8x8_halfpel(&dct_codes[3*64], cur->y, ref->y, refh->y, refv->y, refhv->y, 16*i + 8, 16*j + 8, dx, dy, edged_width); dx = (dx & 3) ? (dx >> 1) | 1 : dx / 2; dy = (dy & 3) ? (dy >> 1) | 1 : dy / 2; /* uv-image-based compensation compensate8x8_halfpel(dct_codes[4], cur->u, ref->u, refh->u, refv->u, refhv->u, 8*i, 8*j, dx, dy, edged_width/2); compensate8x8_halfpel(dct_codes[5], cur->v, ref->v, refh->v, refv->v, refhv->v, 8*i, 8*j, dx, dy, edged_width/2); */ /* uv-block-based compensation */ interpolate8x8_switch(refv->u, ref->u, 8*i, 8*j, dx, dy, edged_width/2, rounding); transfer_8to16sub(&dct_codes[4*64], cur->u + 8*j*edged_width/2 + 8*i, refv->u + 8*j*edged_width/2 + 8*i, edged_width/2); interpolate8x8_switch(refv->v, ref->v, 8*i, 8*j, dx, dy, edged_width/2, rounding); transfer_8to16sub(&dct_codes[5*64], cur->v + 8*j*edged_width/2 + 8*i, refv->v + 8*j*edged_width/2 + 8*i, edged_width/2); } else // mode == MODE_INTER4V { int32_t sum, dx, dy; compensate8x8_halfpel(&dct_codes[0*64], cur->y, ref->y, refh->y, refv->y, refhv->y, 16*i, 16*j, mb->mvs[0].x, mb->mvs[0].y, edged_width); compensate8x8_halfpel(&dct_codes[1*64], cur->y, ref->y, refh->y, refv->y, refhv->y, 16*i + 8, 16*j, mb->mvs[1].x, mb->mvs[1].y, edged_width); compensate8x8_halfpel(&dct_codes[2*64], cur->y, ref->y, refh->y, refv->y, refhv->y, 16*i, 16*j + 8, mb->mvs[2].x, mb->mvs[2].y, edged_width); compensate8x8_halfpel(&dct_codes[3*64], cur->y, ref->y, refh->y, refv->y, refhv->y, 16*i + 8, 16*j + 8, mb->mvs[3].x, mb->mvs[3].y, edged_width); sum = mb->mvs[0].x + mb->mvs[1].x + mb->mvs[2].x + mb->mvs[3].x; dx = (sum ? SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) : 0); sum = mb->mvs[0].y + mb->mvs[1].y + mb->mvs[2].y + mb->mvs[3].y; dy = (sum ? SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2) : 0); /* uv-image-based compensation compensate8x8_halfpel(dct_codes[4], cur->u, ref->u, refh->u, refv->u, refhv->u, 8*i, 8*j, dx, dy, edged_width/2); compensate8x8_halfpel(dct_codes[5], cur->v, ref->v, refh->v, refv->v, refhv->v, 8*i, 8*j, dx, dy, edged_width/2); */ /* uv-block-based compensation */ interpolate8x8_switch(refv->u, ref->u, 8*i, 8*j, dx, dy, edged_width/2, rounding); transfer_8to16sub(&dct_codes[4*64], cur->u + 8*j*edged_width/2 + 8*i, refv->u + 8*j*edged_width/2 + 8*i, edged_width/2); interpolate8x8_switch(refv->v, ref->v, 8*i, 8*j, dx, dy, edged_width/2, rounding); transfer_8to16sub(&dct_codes[5*64], cur->v + 8*j*edged_width/2 + 8*i, refv->v + 8*j*edged_width/2 + 8*i, edged_width/2); } } xvid_20020412/xvidcore/src/motion/x86_asm/0040755000100600001440000000000007455522447017543 5ustar michaelusersxvid_20020412/xvidcore/src/motion/x86_asm/CVS/0040755000100600001440000000000007455522447020176 5ustar michaelusersxvid_20020412/xvidcore/src/motion/x86_asm/CVS/Root0100644000100600001440000000004607455522447021041 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/motion/x86_asm/CVS/Repository0100644000100600001440000000003407455522447022272 0ustar michaelusersxvidcore/src/motion/x86_asm xvid_20020412/xvidcore/src/motion/x86_asm/CVS/Entries0100644000100600001440000000005607455522447021530 0ustar michaelusers/sad_mmx.asm/1.2/Sun Mar 17 08:21:24 2002// D xvid_20020412/xvidcore/src/motion/x86_asm/sad_mmx.asm0100644000100600001440000003724107445051004021662 0ustar michaelusers;/************************************************************************** ; * ; * XVID MPEG-4 VIDEO CODEC ; * mmx/xmm sum of absolute difference ; * ; * This program is an implementation of a part of one or more MPEG-4 ; * Video tools as specified in ISO/IEC 14496-2 standard. Those intending ; * to use this software module in hardware or software products are ; * advised that its use may infringe existing patents or copyrights, and ; * any such use would be at such party's own risk. The original ; * developer of this software module and his/her company, and subsequent ; * editors and their companies, will have no liability for use of this ; * software or modifications or derivatives thereof. ; * ; * This program is free software; you can redistribute it and/or modify ; * it under the terms of the GNU General Public License as published by ; * the Free Software Foundation; either version 2 of the License, or ; * (at your option) any later version. ; * ; * This program is distributed in the hope that it will be useful, ; * but WITHOUT ANY WARRANTY; without even the implied warranty of ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; * GNU General Public License for more details. ; * ; * You should have received a copy of the GNU General Public License ; * along with this program; if not, write to the Free Software ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; * ; *************************************************************************/ ;/************************************************************************** ; * ; * History: ; * ; * 17.11.2001 bugfix and small improvement for dev16_xmm, ; * removed terminate early in sad16_xmm ; * 12.11.2001 inital version; (c)2001 peter ross ; * ; *************************************************************************/ bits 32 %macro cglobal 1 %ifdef PREFIX global _%1 %define %1 _%1 %else global %1 %endif %endmacro section .data align 16 mmx_one times 4 dw 1 section .text ;=========================================================================== ; ; uint32_t sad16_mmx(const uint8_t * const cur, ; const uint8_t * const ref, ; const uint32_t stride, ; const uint32_t best_sad); ; ; (early termination ignore; slows this down) ; ;=========================================================================== align 16 cglobal sad16_mmx sad16_mmx push esi push edi mov esi, [esp + 8 + 4] ; ref mov edi, [esp + 8 + 8] ; cur mov ecx, [esp + 8 + 12] ; stride mov edx, 16 pxor mm6, mm6 ; mm6 = sum = 0 pxor mm7, mm7 ; mm7 = 0 .loop movq mm0, [esi] ; ref movq mm1, [edi] ; cur movq mm2, [esi+8] ; ref2 movq mm3, [edi+8] ; cur2 movq mm4, mm0 movq mm5, mm2 psubusb mm0, mm1 psubusb mm2, mm3 psubusb mm1, mm4 psubusb mm3, mm5 por mm0, mm1 ; mm0 = |ref - cur| por mm2, mm3 ; mm2 = |ref2 - cur2| movq mm1,mm0 movq mm3,mm2 punpcklbw mm0,mm7 punpcklbw mm2,mm7 punpckhbw mm1,mm7 punpckhbw mm3,mm7 paddusw mm0,mm1 paddusw mm2,mm3 paddusw mm6,mm0 ; sum += mm01 paddusw mm6,mm2 ; sum += mm23 add esi, ecx add edi, ecx dec edx jnz .loop pmaddwd mm6, [mmx_one] ; merge sum movq mm7, mm6 psrlq mm7, 32 paddd mm6, mm7 movd eax, mm6 pop edi pop esi ret ;=========================================================================== ; ; uint32_t sad16_xmm(const uint8_t * const cur, ; const uint8_t * const ref, ; const uint32_t stride, ; const uint32_t best_sad); ; ; experimental! ; ;=========================================================================== align 16 cglobal sad16_xmm sad16_xmm push esi push edi push ebx mov esi, [esp + 12 + 4] ; ref mov edi, [esp + 12 + 8] ; cur mov ecx, [esp + 12 + 12] ; stride mov ebx, [esp + 12 + 16] ; best_sad ; mov edx, 16 pxor mm6, mm6 ; mm6 = sum = 0 ;.loop movq mm0, [esi] ; ref movq mm2, [esi+8] ; ref2 psadbw mm0, [edi] ; mm0 = |ref - cur| psadbw mm2, [edi+8] ; mm0 = |ref2 - cur2| paddusw mm6,mm0 ; sum += mm01 paddusw mm6,mm2 ; sum += mm23 add esi, ecx add edi, ecx ; dec edx ; jnz .loop movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 add esi, ecx add edi, ecx movq mm0, [esi] movq mm2, [esi+8] psadbw mm0, [edi] psadbw mm2, [edi+8] paddusw mm6,mm0 paddusw mm6,mm2 movd eax, mm6 .ret pop ebx pop edi pop esi ret ;=========================================================================== ; ; uint32_t sad8_mmx(const uint8_t * const cur, ; const uint8_t * const ref, ; const uint32_t stride); ; ;=========================================================================== align 16 cglobal sad8_mmx sad8_mmx push esi push edi mov esi, [esp + 8 + 4] ; ref mov edi, [esp + 8 + 8] ; cur mov ecx, [esp + 8 + 12] ; stride mov eax, 4 pxor mm6, mm6 ; mm6 = sum = 0 pxor mm7, mm7 ; mm7 = 0 .loop movq mm0, [esi] ; ref movq mm1, [edi] ; cur movq mm2, [esi+ecx] ; ref2 movq mm3, [edi+ecx] ; cur2 movq mm4, mm0 movq mm5, mm2 psubusb mm0, mm1 psubusb mm2, mm3 psubusb mm1, mm4 psubusb mm3, mm5 por mm0, mm1 ; mm0 = |ref - cur| por mm2, mm3 ; mm2 = |ref2 - cur2| movq mm1,mm0 movq mm3,mm2 punpcklbw mm0,mm7 punpcklbw mm2,mm7 punpckhbw mm1,mm7 punpckhbw mm3,mm7 paddusw mm0,mm1 paddusw mm2,mm3 paddusw mm6,mm0 ; sum += mm01 paddusw mm6,mm2 ; sum += mm23 add esi, ecx add edi, ecx add esi, ecx add edi, ecx dec eax jnz .loop pmaddwd mm6, [mmx_one] ; merge sum movq mm7, mm6 psrlq mm7, 32 paddd mm6, mm7 movd eax, mm6 pop edi pop esi ret ;=========================================================================== ; ; uint32_t sad8_xmm(const uint8_t * const cur, ; const uint8_t * const ref, ; const uint32_t stride); ; ; experimental! ; ;=========================================================================== align 16 cglobal sad8_xmm sad8_xmm push esi push edi mov esi, [esp + 8 + 4] ; ref mov edi, [esp + 8 + 8] ; cur mov ecx, [esp + 8 + 12] ; stride mov edx, ecx shl edx, 1 ; mov eax, 4 pxor mm6, mm6 ; mm6 = sum = 0 ;.loop movq mm0, [esi] ; ref movq mm2, [esi+ecx] ; ref2 psadbw mm0, [edi] ; mm0 = |ref - cur| psadbw mm2, [edi+ecx] ; mm0 = |ref2 - cur2| paddusw mm6,mm0 ; sum += mm01 paddusw mm6,mm2 ; sum += mm23 add esi, edx add edi, edx ; dec eax ; jnz .loop movq mm0, [esi] movq mm2, [esi+ecx] psadbw mm0, [edi] psadbw mm2, [edi+ecx] paddusw mm6,mm0 paddusw mm6,mm2 add esi, edx add edi, edx movq mm0, [esi] movq mm2, [esi+ecx] psadbw mm0, [edi] psadbw mm2, [edi+ecx] paddusw mm6,mm0 paddusw mm6,mm2 add esi, edx add edi, edx movq mm0, [esi] movq mm2, [esi+ecx] psadbw mm0, [edi] psadbw mm2, [edi+ecx] paddusw mm6,mm0 paddusw mm6,mm2 movd eax, mm6 pop edi pop esi ret ;=========================================================================== ; ; uint32_t dev16_mmx(const uint8_t * const cur, ; const uint32_t stride); ; ;=========================================================================== align 16 cglobal dev16_mmx dev16_mmx push esi push edi pxor mm4, mm4 ; mm23 = sum = 0 pxor mm5, mm5 mov esi, [esp + 8 + 4] ; cur mov ecx, [esp + 8 + 8] ; stride mov edi, esi mov eax, 16 pxor mm7, mm7 ; mm7 = 0 .loop1 movq mm0, [esi] movq mm2, [esi + 8] movq mm1, mm0 movq mm3, mm2 punpcklbw mm0, mm7 punpcklbw mm2, mm7 punpckhbw mm1, mm7 punpckhbw mm3, mm7 paddw mm0, mm1 paddw mm2, mm3 paddw mm4, mm0 paddw mm5, mm2 add esi, ecx dec eax jnz .loop1 paddusw mm4, mm5 pmaddwd mm4, [mmx_one] ; merge sum movq mm5, mm4 psrlq mm5, 32 paddd mm4, mm5 psllq mm4, 32 ; blank upper dword psrlq mm4, 32 + 8 ; mm4 /= (16*16) punpckldq mm4, mm4 packssdw mm4, mm4 ; mm4 = mean pxor mm6, mm6 ; mm6 = dev = 0 mov eax, 16 .loop2 movq mm0, [edi] movq mm2, [edi + 8] movq mm1, mm0 movq mm3, mm2 punpcklbw mm0, mm7 punpcklbw mm2, mm7 punpckhbw mm1, mm7 ; mm01 = cur punpckhbw mm3, mm7 ; mm23 = cur2 movq mm5, mm4 ; psubusw mm5, mm0 ; psubusw mm0, mm4 ; por mm0, mm5 ; movq mm5, mm4 ; psubusw mm5, mm1 ; psubusw mm1, mm4 ; por mm1, mm5 ; mm01 = |mm01 - mm4| movq mm5, mm4 ; psubusw mm5, mm2 ; psubusw mm2, mm4 ; por mm2, mm5 ; movq mm5, mm4 ; psubusw mm5, mm3 ; psubusw mm3, mm4 ; por mm3, mm5 ; mm23 = |mm23 - mm4| paddw mm0, mm1 paddw mm2, mm3 paddw mm6, mm0 paddw mm6, mm2 ; dev += mm01 + mm23 add edi, ecx dec eax jnz .loop2 pmaddwd mm6, [mmx_one] ; merge dev movq mm7, mm6 psrlq mm7, 32 paddd mm6, mm7 movd eax, mm6 pop edi pop esi ret ;=========================================================================== ; ; uint32_t dev16_xmm(const uint8_t * const cur, ; const uint32_t stride); ; ; experimental! ; ;=========================================================================== align 16 cglobal dev16_xmm dev16_xmm push esi push edi pxor mm4, mm4 ; mm23 = sum = 0 mov esi, [esp + 8 + 4] ; cur mov ecx, [esp + 8 + 8] ; stride mov edi, esi ; mov eax, 16 pxor mm7, mm7 ; mm7 = 0 ;.loop1 movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 ; abs(cur0 - 0) + abs(cur1 - 0) + ... + abs(cur7 - 0) -> mm0 psadbw mm2, mm7 ; abs(cur8 - 0) + abs(cur9 - 0) + ... + abs(cur15 - 0) -> mm2 paddw mm4,mm0 ; mean += mm0 paddw mm4,mm2 ; mean += mm2 add esi, ecx ; dec eax ; jnz .loop1 movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 add esi, ecx movq mm0, [esi] movq mm2, [esi + 8] psadbw mm0, mm7 psadbw mm2, mm7 paddw mm4,mm0 paddw mm4,mm2 movq mm5, mm4 psllq mm5, 32 paddd mm4, mm5 psrld mm4, 8 packssdw mm4, mm4 packuswb mm4, mm4 pxor mm6, mm6 ; mm6 = dev = 0 ; mov eax, 16 ;.loop2 movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 ; mm0 = |cur - mean| psadbw mm2, mm4 ; mm0 = |cur2 - mean| paddw mm6,mm0 ; dev += mm01 paddw mm6,mm2 ; dev += mm23 add edi, ecx ; dec eax ; jnz .loop2 movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 add edi, ecx movq mm0, [edi] movq mm2, [edi + 8] psadbw mm0, mm4 psadbw mm2, mm4 paddw mm6,mm0 paddw mm6,mm2 movq mm7, mm6 psllq mm7, 32 paddd mm6, mm7 movd eax, mm6 pop edi pop esi retxvid_20020412/xvidcore/src/motion/ppc_asm/0040755000100600001440000000000007455522447017700 5ustar michaelusersxvid_20020412/xvidcore/src/motion/ppc_asm/CVS/0040755000100600001440000000000007455522447020333 5ustar michaelusersxvid_20020412/xvidcore/src/motion/ppc_asm/CVS/Root0100644000100600001440000000004607455522447021176 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/motion/ppc_asm/CVS/Repository0100644000100600001440000000003407455522447022427 0ustar michaelusersxvidcore/src/motion/ppc_asm xvid_20020412/xvidcore/src/motion/ppc_asm/CVS/Entries0100644000100600001440000000020507455522447021661 0ustar michaelusers/README/1.1/Wed Apr 3 14:17:05 2002// /sad_altivec.c/1.2/Thu Apr 11 10:18:40 2002// /sad_altivec.s/1.3/Thu Apr 11 10:18:40 2002// D xvid_20020412/xvidcore/src/motion/ppc_asm/README0100644000100600001440000000041407452607341020546 0ustar michaeluserssad_altivec.s has been generated from sad_altivec.c by gcc version 2.95.3 20010111 (BLL/AltiVec prerelease/franzo/20010111) Some hand tweaking has been done. Do not overwrite sad_altivec.s if you are not sure of what you're doing. -- Guillaume xvid_20020412/xvidcore/src/motion/ppc_asm/sad_altivec.c0100644000100600001440000001747107455261400022316 0ustar michaelusers/* Copyright (C) 2002 Benjamin Herrenschmidt This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Id: sad_altivec.c,v 1.2 2002/04/11 10:18:40 canard Exp $ $Source: /xvid/xvidcore/src/motion/ppc_asm/sad_altivec.c,v $ $Date: 2002/04/11 10:18:40 $ $Author: canard $ */ #define G_REG #ifdef G_REG register vector unsigned char perm0 asm ("%v29"); register vector unsigned char perm1 asm ("%v30"); register vector unsigned int zerovec asm ("%v31"); #endif #include #undef DEBUG static const vector unsigned char perms[2] = { (vector unsigned char)( /* Used when cur is aligned */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 ), (vector unsigned char)( /* Used when cur is unaligned */ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f ), }; #ifdef G_REG void sadInit_altivec(void) { perm0 = perms[0]; perm1 = perms[1]; zerovec = (vector unsigned int)(0); } static inline const vector unsigned char get_perm(unsigned long i) { return i ? perm1 : perm0; } #define ZERODEF #define ZEROVEC zerovec #else void sadInit_altivec(void) { } static inline const vector unsigned char get_perm(unsigned long i) { return perms[i]; } #define ZERODEF vector unsigned int zerovec = (vector unsigned int)(0) #define ZEROVEC zerovec #endif #define SAD16() \ t1 = vec_perm(ref[0], ref[1], perm); /* align current vector */ \ t2 = vec_max(t1, *cur); /* find largest of two */ \ t3 = vec_min(t1, *cur); /* find smaller of two */ \ t4 = vec_sub(t2, t3); /* find absolute difference */ \ sad = vec_sum4s(t4, sad); /* accumulate sum of differences */ \ cur += stride; ref += stride; /* * This function assumes cur and stride are 16 bytes aligned and ref is unaligned */ unsigned long sad16_altivec( const vector unsigned char * cur, const vector unsigned char * ref, unsigned long stride, const unsigned long best_sad) { vector unsigned char perm; vector unsigned char t1, t2, t3, t4 ; vector unsigned int sad; vector signed int sumdiffs, best_vec; unsigned long result; ZERODEF; #ifdef DEBUG if (((unsigned long)cur) & 0xf) fprintf(stderr, "sad16_altivec:incorrect align, cur: %x\n", cur); // if (((unsigned long)ref) & 0xf) // fprintf(stderr, "sad16_altivec:incorrect align, ref: %x\n", ref); if (stride & 0xf) fprintf(stderr, "sad16_altivec:incorrect align, stride: %x\n", stride); #endif /* initialization */ sad = (vector unsigned int)(ZEROVEC); stride >>= 4; perm = vec_lvsl(0, (unsigned char *)ref); *((unsigned long *)&best_vec) = best_sad; best_vec = vec_splat(best_vec, 0); /* perform sum of differences between current and previous */ SAD16(); SAD16(); SAD16(); SAD16(); /* Temp sum for exit */ sumdiffs = vec_sums((vector signed int) sad, (vector signed int)ZEROVEC); if (vec_all_ge(sumdiffs, best_vec)) goto bail; SAD16(); SAD16(); SAD16(); SAD16(); sumdiffs = vec_sums((vector signed int) sad, (vector signed int)ZEROVEC); if (vec_all_ge(sumdiffs, best_vec)) goto bail; SAD16(); SAD16(); SAD16(); SAD16(); SAD16(); SAD16(); SAD16(); SAD16(); /* sum all parts of difference into one 32 bit quantity */ sumdiffs = vec_sums((vector signed int) sad, (vector signed int)ZEROVEC); bail: /* copy vector sum into unaligned result */ sumdiffs = vec_splat( sumdiffs, 3 ); vec_ste( sumdiffs, 0, (int *)&result ); return( result ); } #define SAD8() \ t1 = vec_perm(cur[0], cur[stride], perm_cur); /* align current vector */ \ t2 = vec_perm(ref[0], ref[1], perm_ref1); /* align current vector */ \ tp = vec_perm(ref[stride], ref[stride+1], perm_ref1); /* align current vector */ \ t2 = vec_perm(t2,tp,perm_ref2); \ t3 = vec_max(t1, t2); /* find largest of two */ \ t4 = vec_min(t1, t2); /* find smaller of two */ \ t5 = vec_sub(t3, t4); /* find absolute difference */ \ sad = vec_sum4s(t5, sad); /* accumulate sum of differences */ \ cur += stride<<1; ref += stride<<1; /* * This function assumes cur is 8 bytes aligned, stride is 16 bytes * aligned and ref is unaligned */ unsigned long sad8_altivec( const vector unsigned char * cur, const vector unsigned char * ref, unsigned long stride) { vector unsigned char t1, t2, t3, t4, t5, tp ; vector unsigned int sad; vector signed int sumdiffs; vector unsigned char perm_cur; vector unsigned char perm_ref1, perm_ref2; unsigned long result; ZERODEF; #ifdef DEBUG if (((unsigned long)cur) & 0x7) fprintf(stderr, "sad8_altivec:incorrect align, cur: %x\n", cur); // if (((unsigned long)ref) & 0x7) // fprintf(stderr, "sad8_altivec:incorrect align, ref: %x\n", ref); if (stride & 0xf) fprintf(stderr, "sad8_altivec:incorrect align, stride: %x\n", stride); #endif perm_cur = get_perm((((unsigned long)cur)>>3) & 0x01); perm_ref1 = vec_lvsl(0, (unsigned char *)ref); perm_ref2 = get_perm(0); /* initialization */ sad = (vector unsigned int)(ZEROVEC); stride >>= 4; /* perform sum of differences between current and previous */ SAD8(); SAD8(); SAD8(); SAD8(); /* sum all parts of difference into one 32 bit quantity */ sumdiffs = vec_sums((vector signed int) sad, (vector signed int)ZEROVEC); /* copy vector sum into unaligned result */ sumdiffs = vec_splat( sumdiffs, 3 ); vec_ste( sumdiffs, 0, (int *)&result ); return( result ); } #define MEAN16(i)\ c##i=*cur;\ mean = vec_sum4s(c##i,mean);\ cur += stride; #define DEV16(i) \ t2 = vec_max(c##i, mn); /* find largest of two */ \ t3 = vec_min(c##i, mn); /* find smaller of two */ \ t4 = vec_sub(t2, t3); /* find absolute difference */ \ dev = vec_sum4s(t4, dev); unsigned long dev16_altivec( const vector unsigned char * cur, unsigned long stride) { vector unsigned char t2,t3,t4, mn; vector unsigned int mean, dev; vector signed int sumdiffs; vector unsigned char c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15; unsigned long result; ZERODEF; mean = (vector unsigned int)(ZEROVEC); dev = (vector unsigned int)(ZEROVEC); stride >>= 4; MEAN16(0); MEAN16(1); MEAN16(2); MEAN16(3); MEAN16(4); MEAN16(5); MEAN16(6); MEAN16(7); MEAN16(8); MEAN16(9); MEAN16(10); MEAN16(11); MEAN16(12); MEAN16(13); MEAN16(14); MEAN16(15); sumdiffs = vec_sums((vector signed int) mean, (vector signed int) ZEROVEC); mn = vec_perm((vector unsigned char)sumdiffs, (vector unsigned char)sumdiffs, (vector unsigned char)(14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14)); DEV16(0); DEV16(1); DEV16(2); DEV16(3); DEV16(4); DEV16(5); DEV16(6); DEV16(7); DEV16(8); DEV16(9); DEV16(10); DEV16(11); DEV16(12); DEV16(13); DEV16(14); DEV16(15); /* sum all parts of difference into one 32 bit quantity */ sumdiffs = vec_sums((vector signed int) dev, (vector signed int) ZEROVEC); /* copy vector sum into unaligned result */ sumdiffs = vec_splat( sumdiffs, 3 ); vec_ste( sumdiffs, 0, (int *)&result ); return( result ); } xvid_20020412/xvidcore/src/motion/ppc_asm/sad_altivec.s0100644000100600001440000002144007455261400022325 0ustar michaelusers .file "sad_altivec.c" gcc2_compiled.: .section ".rodata" .align 4 .type perms,@object .size perms,32 perms: .long 66051 .long 67438087 .long 269554195 .long 336926231 .long 134810123 .long 202182159 .long 404298267 .long 471670303 .section ".text" .align 2 .globl sad16_altivec .type sad16_altivec,@function sad16_altivec: stwu %r1,-48(%r1) addi %r9,%r4,16 lvx %v13,0,%r4 lvx %v0,0,%r9 rlwinm %r5,%r5,0,0,27 lvx %v1,0,%r3 lvsl %v16,0,%r4 add %r4,%r4,%r5 addi %r9,%r4,16 lvx %v11,0,%r4 vperm %v19,%v13,%v0,%v16 lvx %v12,0,%r9 add %r3,%r3,%r5 lvx %v0,0,%r3 add %r4,%r4,%r5 vminub %v18,%v19,%v1 addi %r9,%r4,16 lvx %v9,0,%r4 vmaxub %v2,%v19,%v1 lvx %v10,0,%r9 add %r3,%r3,%r5 vperm %v19,%v11,%v12,%v16 lvx %v13,0,%r3 add %r4,%r4,%r5 vsububm %v2,%v2,%v18 addi %r9,%r4,16 lvx %v11,0,%r4 vminub %v18,%v19,%v0 lvx %v12,0,%r9 add %r3,%r3,%r5 vsum4ubs %v17,%v2,%v31 lvx %v1,0,%r3 addi %r9,%r1,16 vmaxub %v2,%v19,%v0 stw %r6,16(%r1) vperm %v19,%v9,%v10,%v16 lvx %v0,0,%r9 add %r3,%r3,%r5 vsububm %v2,%v2,%v18 add %r4,%r4,%r5 vminub %v18,%v19,%v13 vsum4ubs %v17,%v2,%v17 vmaxub %v2,%v19,%v13 vspltw %v7,%v0,0 vperm %v19,%v11,%v12,%v16 stvx %v7,0,%r9 vsububm %v2,%v2,%v18 vminub %v18,%v19,%v1 vsum4ubs %v17,%v2,%v17 vmaxub %v2,%v19,%v1 vsububm %v2,%v2,%v18 vsum4ubs %v17,%v2,%v17 vsumsws %v0,%v17,%v31 vcmpgtsw. %v1,%v7,%v0 bc 12,26,.L23 addi %r9,%r4,16 lvx %v1,0,%r4 lvx %v0,0,%r9 add %r4,%r4,%r5 lvx %v13,0,%r3 addi %r9,%r4,16 lvx %v12,0,%r4 add %r3,%r3,%r5 lvx %v11,0,%r9 add %r4,%r4,%r5 vperm %v19,%v1,%v0,%v16 lvx %v10,0,%r3 addi %r9,%r4,16 lvx %v8,0,%r4 add %r3,%r3,%r5 vminub %v18,%v19,%v13 lvx %v9,0,%r9 add %r4,%r4,%r5 vmaxub %v2,%v19,%v13 lvx %v1,0,%r3 addi %r9,%r4,16 vperm %v19,%v12,%v11,%v16 lvx %v13,0,%r9 add %r3,%r3,%r5 vsububm %v2,%v2,%v18 lvx %v12,0,%r4 vminub %v18,%v19,%v10 lvx %v0,0,%r3 add %r4,%r4,%r5 vsum4ubs %v17,%v2,%v17 add %r3,%r3,%r5 vmaxub %v2,%v19,%v10 vperm %v19,%v8,%v9,%v16 vsububm %v2,%v2,%v18 vminub %v18,%v19,%v1 vsum4ubs %v17,%v2,%v17 vmaxub %v2,%v19,%v1 vperm %v19,%v12,%v13,%v16 vsububm %v2,%v2,%v18 vminub %v18,%v19,%v0 vsum4ubs %v17,%v2,%v17 vmaxub %v2,%v19,%v0 vsububm %v2,%v2,%v18 vsum4ubs %v17,%v2,%v17 vsumsws %v0,%v17,%v31 vcmpgtsw. %v7,%v7,%v0 bc 12,26,.L23 addi %r9,%r4,16 lvx %v1,0,%r4 lvx %v0,0,%r9 add %r4,%r4,%r5 lvx %v13,0,%r3 addi %r9,%r4,16 lvx %v11,0,%r9 add %r3,%r3,%r5 lvx %v12,0,%r4 vperm %v19,%v1,%v0,%v16 lvx %v10,0,%r3 add %r4,%r4,%r5 addi %r9,%r4,16 lvx %v9,0,%r4 vminub %v18,%v19,%v13 lvx %v1,0,%r9 add %r3,%r3,%r5 vmaxub %v2,%v19,%v13 lvx %v0,0,%r3 add %r4,%r4,%r5 vperm %v19,%v12,%v11,%v16 addi %r9,%r4,16 vsububm %v2,%v2,%v18 lvx %v11,0,%r4 add %r3,%r3,%r5 vminub %v18,%v19,%v10 lvx %v12,0,%r9 add %r4,%r4,%r5 vsum4ubs %v17,%v2,%v17 lvx %v8,0,%r3 addi %r9,%r4,16 vmaxub %v2,%v19,%v10 lvx %v3,0,%r4 add %r3,%r3,%r5 vperm %v19,%v9,%v1,%v16 lvx %v4,0,%r9 add %r4,%r4,%r5 vsububm %v2,%v2,%v18 lvx %v10,0,%r3 addi %r9,%r4,16 vminub %v18,%v19,%v0 lvx %v5,0,%r4 add %r3,%r3,%r5 vsum4ubs %v17,%v2,%v17 lvx %v6,0,%r9 add %r4,%r4,%r5 vmaxub %v2,%v19,%v0 lvx %v13,0,%r3 addi %r9,%r4,16 vperm %v19,%v11,%v12,%v16 lvx %v7,0,%r4 add %r3,%r3,%r5 vsububm %v2,%v2,%v18 lvx %v9,0,%r9 add %r4,%r4,%r5 vminub %v18,%v19,%v8 lvx %v1,0,%r3 addi %r9,%r4,16 vsum4ubs %v17,%v2,%v17 lvx %v11,0,%r4 vmaxub %v2,%v19,%v8 lvx %v12,0,%r9 vperm %v19,%v3,%v4,%v16 lvx %v0,%r3,%r5 vsububm %v2,%v2,%v18 vminub %v18,%v19,%v10 vsum4ubs %v17,%v2,%v17 vmaxub %v2,%v19,%v10 vperm %v19,%v5,%v6,%v16 vsububm %v2,%v2,%v18 vminub %v18,%v19,%v13 vsum4ubs %v17,%v2,%v17 vmaxub %v2,%v19,%v13 vperm %v19,%v7,%v9,%v16 vsububm %v2,%v2,%v18 vminub %v18,%v19,%v1 vsum4ubs %v17,%v2,%v17 vmaxub %v2,%v19,%v1 vperm %v19,%v11,%v12,%v16 vsububm %v2,%v2,%v18 vminub %v18,%v19,%v0 vsum4ubs %v17,%v2,%v17 vmaxub %v2,%v19,%v0 vsububm %v2,%v2,%v18 vsum4ubs %v17,%v2,%v17 vsumsws %v0,%v17,%v31 .L23: vspltw %v0,%v0,3 addi %r0,%r1,32 stvewx %v0,0,%r0 lwz %r3,32(%r1) la %r1,48(%r1) blr .Lfe1: .size sad16_altivec,.Lfe1-sad16_altivec .align 2 .globl sad8_altivec .type sad8_altivec,@function sad8_altivec: stwu %r1,-16(%r1) andi. %r0,%r3,8 vsldoi %v16,%v30,%v30,0 bc 4,2,.L26 vsldoi %v16,%v29,%v29,0 .L26: srwi %r5,%r5,4 lvx %v8,0,%r4 vsldoi %v6,%v29,%v29,0 slwi %r10,%r5,4 lvx %v11,0,%r3 add %r9,%r10,%r4 lvx %v10,%r10,%r4 addi %r11,%r4,16 lvx %v0,%r10,%r3 addi %r9,%r9,16 lvx %v12,0,%r11 lvx %v13,0,%r9 lvsl %v1,0,%r4 slwi %r0,%r5,5 add %r4,%r4,%r0 vperm %v18,%v11,%v0,%v16 add %r9,%r10,%r4 vperm %v3,%v8,%v12,%v1 lvx %v9,0,%r4 vperm %v17,%v10,%v13,%v1 addi %r11,%r4,16 lvx %v12,%r10,%r4 addi %r9,%r9,16 lvx %v13,0,%r11 lvx %v0,0,%r9 vperm %v3,%v3,%v17,%v6 add %r3,%r3,%r0 add %r4,%r4,%r0 lvx %v10,0,%r3 lvx %v11,%r10,%r3 vminub %v19,%v18,%v3 add %r9,%r10,%r4 vmaxub %v2,%v18,%v3 addi %r11,%r4,16 vperm %v17,%v12,%v0,%v1 addi %r9,%r9,16 lvx %v4,0,%r11 vperm %v3,%v9,%v13,%v1 vsububm %v2,%v2,%v19 lvx %v5,0,%r9 lvx %v9,0,%r4 vperm %v18,%v10,%v11,%v16 add %r3,%r3,%r0 lvx %v13,%r10,%r4 vperm %v3,%v3,%v17,%v6 vsum4ubs %v0,%v2,%v31 add %r4,%r4,%r0 lvx %v12,%r10,%r3 lvx %v8,0,%r3 vminub %v19,%v18,%v3 add %r9,%r10,%r4 vmaxub %v2,%v18,%v3 addi %r9,%r9,16 lvx %v7,%r10,%r4 vperm %v17,%v13,%v5,%v1 addi %r11,%r4,16 lvx %v10,0,%r9 vperm %v3,%v9,%v4,%v1 vsububm %v2,%v2,%v19 lvx %v11,0,%r4 lvx %v9,0,%r11 vperm %v18,%v8,%v12,%v16 add %r3,%r3,%r0 vperm %v3,%v3,%v17,%v6 vsum4ubs %v0,%v2,%v0 lvx %v12,%r10,%r3 lvx %v13,0,%r3 vperm %v17,%v7,%v10,%v1 addi %r8,%r1,8 vminub %v19,%v18,%v3 vmaxub %v2,%v18,%v3 vperm %v3,%v11,%v9,%v1 vsububm %v2,%v2,%v19 vperm %v18,%v13,%v12,%v16 vperm %v3,%v3,%v17,%v6 vsum4ubs %v0,%v2,%v0 vminub %v19,%v18,%v3 vmaxub %v2,%v18,%v3 vsububm %v2,%v2,%v19 vsum4ubs %v0,%v2,%v0 vsumsws %v0,%v0,%v31 vspltw %v0,%v0,3 stvewx %v0,0,%r8 lwz %r3,8(%r1) la %r1,16(%r1) blr .Lfe2: .size sad8_altivec,.Lfe2-sad8_altivec .align 2 .globl dev16_altivec .type dev16_altivec,@function dev16_altivec: stwu %r1,-16(%r1) lvx %v13,0,%r3 rlwinm %r4,%r4,0,0,27 vspltisb %v1,14 add %r3,%r3,%r4 lvx %v12,0,%r3 addi %r0,%r1,8 add %r3,%r3,%r4 vsum4ubs %v0,%v13,%v31 lvx %v11,0,%r3 add %r3,%r3,%r4 lvx %v10,0,%r3 add %r3,%r3,%r4 lvx %v9,0,%r3 vsum4ubs %v0,%v12,%v0 add %r3,%r3,%r4 lvx %v8,0,%r3 add %r3,%r3,%r4 lvx %v7,0,%r3 add %r3,%r3,%r4 vsum4ubs %v0,%v11,%v0 lvx %v6,0,%r3 add %r3,%r3,%r4 lvx %v5,0,%r3 add %r3,%r3,%r4 lvx %v4,0,%r3 vsum4ubs %v0,%v10,%v0 add %r3,%r3,%r4 lvx %v3,0,%r3 add %r3,%r3,%r4 lvx %v2,0,%r3 add %r3,%r3,%r4 vsum4ubs %v0,%v9,%v0 lvx %v19,0,%r3 add %r3,%r3,%r4 lvx %v18,0,%r3 add %r3,%r3,%r4 lvx %v17,0,%r3 vsum4ubs %v0,%v8,%v0 lvx %v16,%r3,%r4 vsum4ubs %v0,%v7,%v0 vsum4ubs %v0,%v6,%v0 vsum4ubs %v0,%v5,%v0 vsum4ubs %v0,%v4,%v0 vsum4ubs %v0,%v3,%v0 vsum4ubs %v0,%v2,%v0 vsum4ubs %v0,%v19,%v0 vsum4ubs %v0,%v18,%v0 vsum4ubs %v0,%v17,%v0 vsum4ubs %v0,%v16,%v0 vsumsws %v0,%v0,%v31 vperm %v1,%v0,%v0,%v1 vminub %v15,%v13,%v1 vmaxub %v13,%v13,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v12,%v1 vsum4ubs %v0,%v13,%v31 vmaxub %v13,%v12,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v11,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v11,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v10,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v10,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v9,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v9,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v8,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v8,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v7,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v7,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v6,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v6,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v5,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v5,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v4,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v4,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v3,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v3,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v2,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v2,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v19,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v19,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v18,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v18,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v17,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v17,%v1 vsububm %v13,%v13,%v15 vminub %v15,%v16,%v1 vsum4ubs %v0,%v13,%v0 vmaxub %v13,%v16,%v1 vsububm %v13,%v13,%v15 vsum4ubs %v0,%v13,%v0 vsumsws %v0,%v0,%v31 vspltw %v0,%v0,3 stvewx %v0,0,%r0 lwz %r3,8(%r1) la %r1,16(%r1) blr .Lfe3: .size dev16_altivec,.Lfe3-dev16_altivec .align 2 .globl sadInit_altivec .type sadInit_altivec,@function sadInit_altivec: lis %r9,perms@ha vspltisw %v31,0 la %r9,perms@l(%r9) addi %r11,%r9,16 lvx %v29,0,%r9 lvx %v30,0,%r11 blr .Lfe4: .size sadInit_altivec,.Lfe4-sadInit_altivec .ident "GCC: (GNU) 2.95.3 20010111 (BLL/AltiVec prerelease/franzo/20010111)" xvid_20020412/xvidcore/src/xvid.c0100644000100600001440000001546707455261377016103 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC * native api * * This program is an implementation of a part of one or more MPEG-4 * Video tools as specified in ISO/IEC 14496-2 standard. Those intending * to use this software module in hardware or software products are * advised that its use may infringe existing patents or copyrights, and * any such use would be at such party's own risk. The original * developer of this software module and his/her company, and subsequent * editors and their companies, will have no liability for use of this * software or modifications or derivatives thereof. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************** * * History: * * 17.03.2002 Added interpolate8x8_halfpel_hv_xmm * 22.12.2001 API change: added xvid_init() - Isibaar * 16.12.2001 inital version; (c)2001 peter ross * *************************************************************************/ #include "xvid.h" #include "decoder.h" #include "encoder.h" #include "bitstream/cbp.h" #include "dct/idct.h" #include "dct/fdct.h" #include "image/colorspace.h" #include "image/interpolate8x8.h" #include "utils/mem_transfer.h" #include "quant/quant_h263.h" #include "quant/quant_mpeg4.h" #include "motion/sad.h" #include "utils/emms.h" #include "utils/timer.h" #include "bitstream/mbcoding.h" int xvid_init(void *handle, int opt, void *param1, void *param2) { int cpu_flags; XVID_INIT_PARAM *init_param; init_param = (XVID_INIT_PARAM *) param1; // force specific cpu settings? if((init_param->cpu_flags & XVID_CPU_FORCE) > 0) cpu_flags = init_param->cpu_flags; else { #ifdef ARCH_X86 cpu_flags = check_cpu_features(); #else cpu_flags = 0; #endif init_param->cpu_flags = cpu_flags; } // initialize the function pointers idct_int32_init(); init_vlc_tables(); fdct = fdct_int32; idct = idct_int32; sadInit = 0; emms = emms_c; quant_intra = quant_intra_c; dequant_intra = dequant_intra_c; quant_inter = quant_inter_c; dequant_inter = dequant_inter_c; quant4_intra = quant4_intra_c; dequant4_intra = dequant4_intra_c; quant4_inter = quant4_inter_c; dequant4_inter = dequant4_inter_c; transfer_8to16copy = transfer_8to16copy_c; transfer_16to8copy = transfer_16to8copy_c; transfer_8to16sub = transfer_8to16sub_c; transfer_16to8add = transfer_16to8add_c; transfer8x8_copy = transfer8x8_copy_c; interpolate8x8_halfpel_h = interpolate8x8_halfpel_h_c; interpolate8x8_halfpel_v = interpolate8x8_halfpel_v_c; interpolate8x8_halfpel_hv = interpolate8x8_halfpel_hv_c; colorspace_init(); rgb555_to_yv12 = rgb555_to_yv12_c; rgb565_to_yv12 = rgb565_to_yv12_c; rgb24_to_yv12 = rgb24_to_yv12_c; rgb32_to_yv12 = rgb32_to_yv12_c; yuv_to_yv12 = yuv_to_yv12_c; yuyv_to_yv12 = yuyv_to_yv12_c; uyvy_to_yv12 = uyvy_to_yv12_c; yv12_to_rgb555 = yv12_to_rgb555_c; yv12_to_rgb565 = yv12_to_rgb565_c; yv12_to_rgb24 = yv12_to_rgb24_c; yv12_to_rgb32 = yv12_to_rgb32_c; yv12_to_yuv = yv12_to_yuv_c; yv12_to_yuyv = yv12_to_yuyv_c; yv12_to_uyvy = yv12_to_uyvy_c; calc_cbp = calc_cbp_c; sad16 = sad16_c; sad8 = sad8_c; dev16 = dev16_c; #ifdef ARCH_X86 if((cpu_flags & XVID_CPU_MMX) > 0) { fdct = fdct_mmx; idct = idct_mmx; emms = emms_mmx; quant_intra = quant_intra_mmx; dequant_intra = dequant_intra_mmx; quant_inter = quant_inter_mmx; dequant_inter = dequant_inter_mmx; quant4_intra = quant4_intra_mmx; dequant4_intra = dequant4_intra_mmx; quant4_inter = quant4_inter_mmx; dequant4_inter = dequant4_inter_mmx; transfer_8to16copy = transfer_8to16copy_mmx; transfer_16to8copy = transfer_16to8copy_mmx; transfer_8to16sub = transfer_8to16sub_mmx; transfer_16to8add = transfer_16to8add_mmx; transfer8x8_copy = transfer8x8_copy_mmx; interpolate8x8_halfpel_h = interpolate8x8_halfpel_h_mmx; interpolate8x8_halfpel_v = interpolate8x8_halfpel_v_mmx; interpolate8x8_halfpel_hv = interpolate8x8_halfpel_hv_mmx; rgb24_to_yv12 = rgb24_to_yv12_mmx; rgb32_to_yv12 = rgb32_to_yv12_mmx; yuv_to_yv12 = yuv_to_yv12_mmx; yuyv_to_yv12 = yuyv_to_yv12_mmx; uyvy_to_yv12 = uyvy_to_yv12_mmx; yv12_to_rgb24 = yv12_to_rgb24_mmx; yv12_to_rgb32 = yv12_to_rgb32_mmx; yv12_to_yuyv = yv12_to_yuyv_mmx; yv12_to_uyvy = yv12_to_uyvy_mmx; calc_cbp = calc_cbp_mmx; sad16 = sad16_mmx; sad8 = sad8_mmx; dev16 = dev16_mmx; } if((cpu_flags & XVID_CPU_MMXEXT) > 0) { idct = idct_xmm; interpolate8x8_halfpel_h = interpolate8x8_halfpel_h_xmm; interpolate8x8_halfpel_v = interpolate8x8_halfpel_v_xmm; interpolate8x8_halfpel_hv = interpolate8x8_halfpel_hv_xmm; yuv_to_yv12 = yuv_to_yv12_xmm; sad16 = sad16_xmm; sad8 = sad8_xmm; dev16 = dev16_xmm; } if((cpu_flags & XVID_CPU_3DNOW) > 0) { interpolate8x8_halfpel_h = interpolate8x8_halfpel_h_3dn; interpolate8x8_halfpel_v = interpolate8x8_halfpel_v_3dn; interpolate8x8_halfpel_hv = interpolate8x8_halfpel_hv_3dn; } #endif #ifdef ARCH_PPC #ifdef ARCH_PPC_ALTIVEC calc_cbp = calc_cbp_altivec; fdct = fdct_altivec; idct = idct_altivec; sadInit = sadInit_altivec; sad16 = sad16_altivec; sad8 = sad8_altivec; dev16 = dev16_altivec; #else calc_cbp = calc_cbp_ppc; #endif #endif // API version init_param->api_version = API_VERSION; // something clever has to be done for this init_param->core_build = 1000; return XVID_ERR_OK; } int xvid_decore(void * handle, int opt, void * param1, void * param2) { switch (opt) { case XVID_DEC_DECODE : return decoder_decode((DECODER *) handle, (XVID_DEC_FRAME *) param1); case XVID_DEC_CREATE : return decoder_create((XVID_DEC_PARAM *) param1); case XVID_DEC_DESTROY : return decoder_destroy((DECODER *) handle); default: return XVID_ERR_FAIL; } } int xvid_encore(void * handle, int opt, void * param1, void * param2) { switch (opt) { case XVID_ENC_ENCODE : return encoder_encode((Encoder *) handle, (XVID_ENC_FRAME *) param1, (XVID_ENC_STATS *) param2); case XVID_ENC_CREATE : return encoder_create((XVID_ENC_PARAM *) param1); case XVID_ENC_DESTROY : return encoder_destroy((Encoder *) handle); default: return XVID_ERR_FAIL; } } xvid_20020412/xvidcore/src/xvid.h0100644000100600001440000001345307453333544016073 0ustar michaelusers#ifndef _XVID_H_ #define _XVID_H_ #ifdef __cplusplus extern "C" { #endif // ========================================== // global // ========================================== // API Version: 2.0 #define API_VERSION ((2 << 16) | (0)) // cpu features #define XVID_CPU_MMX 0x00000001 #define XVID_CPU_MMXEXT 0x00000002 #define XVID_CPU_SSE 0x00000004 #define XVID_CPU_SSE2 0x00000008 #define XVID_CPU_3DNOW 0x00000010 #define XVID_CPU_3DNOWEXT 0x00000020 #define XVID_CPU_TSC 0x00000040 #define XVID_CPU_FORCE 0x80000000 // colorspaces #define XVID_CSP_RGB24 0 #define XVID_CSP_YV12 1 #define XVID_CSP_YUY2 2 #define XVID_CSP_UYVY 3 #define XVID_CSP_I420 4 #define XVID_CSP_RGB555 10 #define XVID_CSP_RGB565 11 #define XVID_CSP_USER 12 #define XVID_CSP_YVYU 1002 #define XVID_CSP_RGB32 1000 #define XVID_CSP_NULL 9999 #define XVID_CSP_VFLIP 0x80000000 // flip mask // error #define XVID_ERR_FAIL -1 #define XVID_ERR_OK 0 #define XVID_ERR_MEMORY 1 #define XVID_ERR_FORMAT 2 typedef struct { int cpu_flags; int api_version; int core_build; } XVID_INIT_PARAM; int xvid_init(void *handle, int opt, void *param1, void *param2); // ========================================== // decoder // ========================================== #define XVID_QUICK_DECODE 0x00000010 /* increases decoding speed but reduces quality */ typedef struct { int width; int height; void *handle; } XVID_DEC_PARAM; typedef struct { int general; void * bitstream; int length; void * image; int stride; int colorspace; } XVID_DEC_FRAME; // decoder options #define XVID_DEC_DECODE 0 #define XVID_DEC_CREATE 1 #define XVID_DEC_DESTROY 2 int xvid_decore(void * handle, int opt, void * param1, void * param2); // ========================================== // encoder // ========================================== /* Do not rely on the VALUES of these constants, they may be changed at any time */ #define XVID_VALID_FLAGS 0x80000000 #define XVID_CUSTOM_QMATRIX 0x00000004 /* use custom quant matrix */ #define XVID_H263QUANT 0x00000010 #define XVID_MPEGQUANT 0x00000020 #define XVID_HALFPEL 0x00000040 /* use halfpel interpolation */ #define XVID_ADAPTIVEQUANT 0x00000080 #define XVID_LUMIMASKING 0x00000100 #define XVID_LATEINTRA 0x00000200 #define XVID_INTERLACING 0x00000400 /* enable interlaced encoding */ #define XVID_TOPFIELDFIRST 0x00000800 /* set top-field-first flag (cosmetic only) */ #define XVID_ALTERNATESCAN 0x00001000 /* ?? sets alternate vertical scan flag */ #define XVID_HINTEDME_GET 0x00002000 /* receive mv hint data from core (1st pass) */ #define XVID_HINTEDME_SET 0x00004000 /* send mv hint data to core (2nd pass) */ #define XVID_INTER4V 0x00008000 #define XVID_ME_ZERO 0x00010000 #define XVID_ME_LOGARITHMIC 0x00020000 #define XVID_ME_FULLSEARCH 0x00040000 #define XVID_ME_PMVFAST 0x00080000 #define XVID_ME_EPZS 0x00100000 #define PMV_HALFPELDIAMOND16 0x00010000 #define PMV_HALFPELREFINE16 0x00020000 #define PMV_EXTSEARCH16 0x00040000 /* extend PMV by more searches */ #define PMV_EARLYSTOP16 0x00080000 #define PMV_QUICKSTOP16 0x00100000 /* like early, but without any more refinement */ #define PMV_UNRESTRICTED16 0x00200000 /* unrestricted ME, not implemented */ #define PMV_OVERLAPPING16 0x00400000 /* overlapping ME, not implemented */ #define PMV_USESQUARES16 0x00800000 #define PMV_HALFPELDIAMOND8 0x01000000 #define PMV_HALFPELREFINE8 0x02000000 #define PMV_EXTSEARCH8 0x04000000 /* extend PMV by more searches */ #define PMV_EARLYSTOP8 0x08000000 #define PMV_QUICKSTOP8 0x10000000 /* like early, but without any more refinement */ #define PMV_UNRESTRICTED8 0x20000000 /* unrestricted ME, not implemented */ #define PMV_OVERLAPPING8 0x40000000 /* overlapping ME, not implemented */ #define PMV_USESQUARES8 0x80000000 typedef struct { int width, height; int fincr, fbase; // frame increment, fbase. each frame = "fincr/fbase" seconds int bitrate; // the bitrate of the target encoded stream, in bits/second int rc_buffersize; // the rate control buffersize / max. allowed deviation int max_quantizer; // the upper limit of the quantizer int min_quantizer; // the lower limit of the quantizer int max_key_interval; // the maximum interval between key frames void * handle; // [out] encoder instance handle } XVID_ENC_PARAM; typedef struct { int x; int y; } VECTOR; typedef struct { int mode; // macroblock mode VECTOR mvs[4]; } MVBLOCKHINT; typedef struct { int intra; // frame intra choice int fcode; // frame fcode MVBLOCKHINT * block; // caller-allocated array of block hints (mb_width * mb_height) } MVFRAMEHINT; typedef struct { int rawhints; // if set, use MVFRAMEHINT, else use compressed buffer MVFRAMEHINT mvhint; void * hintstream; // compressed hint buffer int hintlength; // length of buffer (bytes) } HINTINFO; typedef struct { int general; // [in] general options int motion; // [in] ME options void * bitstream; // [in] bitstream ptr int length; // [out] bitstream length (bytes) void * image; // [in] image ptr int colorspace; // [in] source colorspace unsigned char *quant_intra_matrix; // [in] custom intra qmatrix unsigned char *quant_inter_matrix; // [in] custom inter qmatrix int quant; // [in] frame quantizer (vbr) int intra; // [in] force intra frame (vbr only) // [out] intra state HINTINFO hint; // [in/out] mv hint information } XVID_ENC_FRAME; typedef struct { int quant; // [out] frame quantizer int hlength; // [out] header length (bytes) int kblks, mblks, ublks; // [out] } XVID_ENC_STATS; #define XVID_ENC_ENCODE 0 #define XVID_ENC_CREATE 1 #define XVID_ENC_DESTROY 2 int xvid_encore(void * handle, int opt, void * param1, void * param2); #ifdef __cplusplus } #endif #endif /* _XVID_H_ */ xvid_20020412/xvidcore/src/prediction/0040755000100600001440000000000007455522447017111 5ustar michaelusersxvid_20020412/xvidcore/src/prediction/CVS/0040755000100600001440000000000007455522447017544 5ustar michaelusersxvid_20020412/xvidcore/src/prediction/CVS/Root0100644000100600001440000000004607455522447020407 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/src/prediction/CVS/Repository0100644000100600001440000000003007455522447021634 0ustar michaelusersxvidcore/src/prediction xvid_20020412/xvidcore/src/prediction/CVS/Entries0100644000100600001440000000014007455522447021070 0ustar michaelusers/mbprediction.c/1.2/Thu Mar 28 20:57:25 2002// /mbprediction.h/1.2/Thu Mar 28 20:57:25 2002// D xvid_20020412/xvidcore/src/prediction/mbprediction.c0100644000100600001440000002600407450701665021727 0ustar michaelusers /****************************************************************************** * * * This file is part of XviD, a free MPEG-4 video encoder/decoder * * * * XviD is an implementation of a part of one or more MPEG-4 Video tools * * as specified in ISO/IEC 14496-2 standard. Those intending to use this * * software module in hardware or software products are advised that its * * use may infringe existing patents or copyrights, and any such use * * would be at such party's own risk. The original developer of this * * software module and his/her company, and subsequent editors and their * * companies, will have no liability for use of this software or * * modifications or derivatives thereof. * * * * XviD is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * XviD is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * ******************************************************************************/ /****************************************************************************** * * * mbprediction.c * * * * Copyright (C) 2001 - Michael Militzer * * Copyright (C) 2001 - Peter Ross * * * * For more information visit the XviD homepage: http://www.xvid.org * * * ******************************************************************************/ /****************************************************************************** * * * Revision history: * * * * 12.12.2001 improved calc_acdc_prediction; removed need for memcpy * * 15.12.2001 moved pmv displacement to motion estimation * * 30.11.2001 mmx cbp support * * 17.11.2001 initial version * * * ******************************************************************************/ #include "../encoder.h" #include "mbprediction.h" #include "../utils/mbfunctions.h" #include "../bitstream/cbp.h" #define ABS(X) (((X)>0)?(X):-(X)) #define DIV_DIV(A,B) ( (A) > 0 ? ((A)+((B)>>1))/(B) : ((A)-((B)>>1))/(B) ) static int __inline rescale(int predict_quant, int current_quant, int coeff) { return (coeff != 0) ? DIV_DIV((coeff) * (predict_quant), (current_quant)) : 0; } static const int16_t default_acdc_values[15] = { 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* get dc/ac prediction direction for a single block and place predictor values into MB->pred_values[j][..] */ void predict_acdc(MACROBLOCK *pMBs, uint32_t x, uint32_t y, uint32_t mb_width, uint32_t block, int16_t qcoeff[64], uint32_t current_quant, int32_t iDcScaler, int16_t predictors[8]) { int16_t *left, *top, *diag, *current; int32_t left_quant = current_quant; int32_t top_quant = current_quant; const int16_t *pLeft = default_acdc_values; const int16_t *pTop = default_acdc_values; const int16_t *pDiag = default_acdc_values; uint32_t index = x + y * mb_width; // current macroblock int * acpred_direction = &pMBs[index].acpred_directions[block]; uint32_t i; left = top = diag = current = 0; // grab left,top and diag macroblocks // left macroblock if(x && (pMBs[index - 1].mode == MODE_INTRA || pMBs[index - 1].mode == MODE_INTRA_Q)) { left = pMBs[index - 1].pred_values[0]; left_quant = pMBs[index - 1].quant; //DEBUGI("LEFT", *(left+MBPRED_SIZE)); } // top macroblock if(y && (pMBs[index - mb_width].mode == MODE_INTRA || pMBs[index - mb_width].mode == MODE_INTRA_Q)) { top = pMBs[index - mb_width].pred_values[0]; top_quant = pMBs[index - mb_width].quant; } // diag macroblock if(x && y && (pMBs[index - 1 - mb_width].mode == MODE_INTRA || pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) { diag = pMBs[index - 1 - mb_width].pred_values[0]; } current = pMBs[index].pred_values[0]; // now grab pLeft, pTop, pDiag _blocks_ switch (block) { case 0: if(left) pLeft = left + MBPRED_SIZE; if(top) pTop = top + (MBPRED_SIZE << 1); if(diag) pDiag = diag + 3 * MBPRED_SIZE; break; case 1: pLeft = current; left_quant = current_quant; if(top) { pTop = top + 3 * MBPRED_SIZE; pDiag = top + (MBPRED_SIZE << 1); } break; case 2: if(left) { pLeft = left + 3 * MBPRED_SIZE; pDiag = left + MBPRED_SIZE; } pTop = current; top_quant = current_quant; break; case 3: pLeft = current + (MBPRED_SIZE << 1); left_quant = current_quant; pTop = current + MBPRED_SIZE; top_quant = current_quant; pDiag = current; break; case 4: if(left) pLeft = left + (MBPRED_SIZE << 2); if(top) pTop = top + (MBPRED_SIZE << 2); if(diag) pDiag = diag + (MBPRED_SIZE << 2); break; case 5: if(left) pLeft = left + 5 * MBPRED_SIZE; if(top) pTop = top + 5 * MBPRED_SIZE; if(diag) pDiag = diag + 5 * MBPRED_SIZE; break; } // determine ac prediction direction & ac/dc predictor // place rescaled ac/dc predictions into predictors[] for later use if(ABS(pLeft[0] - pDiag[0]) < ABS(pDiag[0] - pTop[0])) { *acpred_direction = 1; // vertical predictors[0] = DIV_DIV(pTop[0], iDcScaler); for (i = 1; i < 8; i++) { predictors[i] = rescale(top_quant, current_quant, pTop[i]); } } else { *acpred_direction = 2; // horizontal predictors[0] = DIV_DIV(pLeft[0], iDcScaler); for (i = 1; i < 8; i++) { predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]); } } } /* decoder: add predictors to dct_codes[] and store current coeffs to pred_values[] for future prediction */ void add_acdc(MACROBLOCK *pMB, uint32_t block, int16_t dct_codes[64], uint32_t iDcScaler, int16_t predictors[8]) { uint8_t acpred_direction = pMB->acpred_directions[block]; int16_t * pCurrent = pMB->pred_values[block]; uint32_t i; dct_codes[0] += predictors[0]; // dc prediction pCurrent[0] = dct_codes[0] * iDcScaler; if (acpred_direction == 1) { for (i = 1; i < 8; i++) { int level = dct_codes[i] + predictors[i]; dct_codes[i] = level; pCurrent[i] = level; pCurrent[i+7] = dct_codes[i*8]; } } else if (acpred_direction == 2) { for (i = 1; i < 8; i++) { int level = dct_codes[i*8] + predictors[i]; dct_codes[i*8] = level; pCurrent[i+7] = level; pCurrent[i] = dct_codes[i]; } } else { for (i = 1; i < 8; i++) { pCurrent[i] = dct_codes[i]; pCurrent[i+7] = dct_codes[i*8]; } } } // ****************************************************************** // ****************************************************************** /* encoder: subtract predictors from qcoeff[] and calculate S1/S2 todo: perform [-127,127] clamping after prediction clamping must adjust the coeffs, so dequant is done correctly S1/S2 are used to determine if its worth predicting for AC S1 = sum of all (qcoeff - prediction) S2 = sum of all qcoeff */ uint32_t calc_acdc(MACROBLOCK *pMB, uint32_t block, int16_t qcoeff[64], uint32_t iDcScaler, int16_t predictors[8]) { int16_t * pCurrent = pMB->pred_values[block]; uint32_t i; uint32_t S1 = 0, S2 = 0; /* store current coeffs to pred_values[] for future prediction */ pCurrent[0] = qcoeff[0] * iDcScaler; for(i = 1; i < 8; i++) { pCurrent[i] = qcoeff[i]; pCurrent[i + 7] = qcoeff[i * 8]; } /* subtract predictors and store back in predictors[] */ qcoeff[0] = qcoeff[0] - predictors[0]; if (pMB->acpred_directions[block] == 1) { for(i = 1; i < 8; i++) { int16_t level; level = qcoeff[i]; S2 += ABS(level); level -= predictors[i]; S1 += ABS(level); predictors[i] = level; } } else // acpred_direction == 2 { for(i = 1; i < 8; i++) { int16_t level; level = qcoeff[i*8]; S2 += ABS(level); level -= predictors[i]; S1 += ABS(level); predictors[i] = level; } } return S2 - S1; } /* apply predictors[] to qcoeff */ void apply_acdc(MACROBLOCK *pMB, uint32_t block, int16_t qcoeff[64], int16_t predictors[8]) { uint32_t i; if (pMB->acpred_directions[block] == 1) { for(i = 1; i < 8; i++) { qcoeff[i] = predictors[i]; } } else { for(i = 1; i < 8; i++) { qcoeff[i*8] = predictors[i]; } } } void MBPrediction(MBParam *pParam, uint32_t x, uint32_t y, uint32_t mb_width, int16_t qcoeff[6*64], MACROBLOCK *mbs) { int32_t j; int32_t iDcScaler, iQuant = pParam->quant; int32_t S = 0; int16_t predictors[6][8]; MACROBLOCK *pMB = &mbs[x + y * mb_width]; if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) { for(j = 0; j < 6; j++) { iDcScaler = get_dc_scaler(iQuant, (j < 4) ? 1 : 0); predict_acdc(mbs, x, y, mb_width, j, &qcoeff[j*64], iQuant, iDcScaler, predictors[j]); S += calc_acdc(pMB, j, &qcoeff[j*64], iDcScaler, predictors[j]); } if (S < 0) // dont predict { for(j = 0; j < 6; j++) { pMB->acpred_directions[j] = 0; } } else { for(j = 0; j < 6; j++) { apply_acdc(pMB, j, &qcoeff[j*64], predictors[j]); } } pMB->cbp = calc_cbp(qcoeff); } } xvid_20020412/xvidcore/src/prediction/mbprediction.h0100644000100600001440000001074307450701665021737 0ustar michaelusers#ifndef _MBPREDICTION_H_ #define _MBPREDICTION_H_ #include "../portab.h" #include "../decoder.h" #include "../global.h" #define MIN(X, Y) ((X)<(Y)?(X):(Y)) #define MAX(X, Y) ((X)>(Y)?(X):(Y)) // very large value #define MV_MAX_ERROR (4096 * 256) #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) ) void MBPrediction(MBParam *pParam, /* <-- the parameter for ACDC and MV prediction */ uint32_t x_pos, /* <-- The x position of the MB to be searched */ uint32_t y_pos, /* <-- The y position of the MB to be searched */ uint32_t x_dim, /* <-- Number of macroblocks in a row */ int16_t *qcoeff, /* <-> The quantized DCT coefficients */ MACROBLOCK *MB_array /* <-> the array of all the MB Infomations */ ); void add_acdc(MACROBLOCK *pMB, uint32_t block, int16_t dct_codes[64], uint32_t iDcScaler, int16_t predictors[8]); void predict_acdc(MACROBLOCK *pMBs, uint32_t x, uint32_t y, uint32_t mb_width, uint32_t block, int16_t qcoeff[64], uint32_t current_quant, int32_t iDcScaler, int16_t predictors[8]); /* This is somehow a copy of get_pmv, but returning all MVs and Minimum SAD instead of only Median MV */ static __inline int get_pmvdata(const MACROBLOCK * const pMBs, const uint32_t x, const uint32_t y, const uint32_t x_dim, const uint32_t block, VECTOR * const pmv, int32_t * const psad) { /* pmv are filled with: [0]: Median (or whatever is correct in a special case) [1]: left neighbour [2]: top neighbour, [3]: topright neighbour, psad are filled with: [0]: minimum of [1] to [3] [1]: left neighbour's SAD // [1] to [3] are actually not needed [2]: top neighbour's SAD, [3]: topright neighbour's SAD, */ int xin1, xin2, xin3; int yin1, yin2, yin3; int vec1, vec2, vec3; static VECTOR zeroMV; uint32_t index = x + y * x_dim; zeroMV.x = zeroMV.y = 0; // first row (special case) if (y == 0 && (block == 0 || block == 1)) { if ((x == 0) && (block == 0)) // first column, first block { pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV; psad[0] = psad[1] = psad[2] = psad[3] = MV_MAX_ERROR; return 0; } if (block == 1) // second block; has only a left neighbour { pmv[0] = pmv[1] = pMBs[index].mvs[0]; pmv[2] = pmv[3] = zeroMV; psad[0] = psad[1] = pMBs[index].sad8[0]; psad[2] = psad[3] = MV_MAX_ERROR; return 0; } else /* block==0, but x!=0, so again, there is a left neighbour*/ { pmv[0] = pmv[1] = pMBs[index-1].mvs[1]; pmv[2] = pmv[3] = zeroMV; psad[0] = psad[1] = pMBs[index-1].sad8[1]; psad[2] = psad[3] = MV_MAX_ERROR; return 0; } } /* MODE_INTER, vm18 page 48 MODE_INTER4V vm18 page 51 (x,y-1) (x+1,y-1) [ | ] [ | ] [ 2 | 3 ] [ 2 | ] (x-1,y) (x,y) (x+1,y) [ | 1 ] [ 0 | 1 ] [ 0 | ] [ | 3 ] [ 2 | 3 ] [ | ] */ switch (block) { case 0: xin1 = x - 1; yin1 = y; vec1 = 1; /* left */ xin2 = x; yin2 = y - 1; vec2 = 2; /* top */ xin3 = x + 1; yin3 = y - 1; vec3 = 2; /* top right */ break; case 1: xin1 = x; yin1 = y; vec1 = 0; xin2 = x; yin2 = y - 1; vec2 = 3; xin3 = x + 1; yin3 = y - 1; vec3 = 2; break; case 2: xin1 = x - 1; yin1 = y; vec1 = 3; xin2 = x; yin2 = y; vec2 = 0; xin3 = x; yin3 = y; vec3 = 1; break; default: xin1 = x; yin1 = y; vec1 = 2; xin2 = x; yin2 = y; vec2 = 0; xin3 = x; yin3 = y; vec3 = 1; } if (xin1 < 0 || /* yin1 < 0 || */ xin1 >= (int32_t)x_dim) { pmv[1] = zeroMV; psad[1] = MV_MAX_ERROR; } else { pmv[1] = pMBs[xin1 + yin1 * x_dim].mvs[vec1]; psad[1] = pMBs[xin1 + yin1 * x_dim].sad8[vec1]; } if (xin2 < 0 || /* yin2 < 0 || */ xin2 >= (int32_t)x_dim) { pmv[2] = zeroMV; psad[2] = MV_MAX_ERROR; } else { pmv[2] = pMBs[xin2 + yin2 * x_dim].mvs[vec2]; psad[2] = pMBs[xin2 + yin2 * x_dim].sad8[vec2]; } if (xin3 < 0 || /* yin3 < 0 || */ xin3 >= (int32_t)x_dim) { pmv[3] = zeroMV; psad[3] = MV_MAX_ERROR; } else { pmv[3] = pMBs[xin3 + yin3 * x_dim].mvs[vec3]; psad[3] = pMBs[xin2 + yin2 * x_dim].sad8[vec3]; } if ( (MVequal(pmv[1],pmv[2])) && (MVequal(pmv[1],pmv[3])) ) { pmv[0]=pmv[1]; psad[0]=psad[1]; return 1; } // median,minimum pmv[0].x = MIN(MAX(pmv[1].x, pmv[2].x), MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x))); pmv[0].y = MIN(MAX(pmv[1].y, pmv[2].y), MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y))); psad[0]=MIN(MIN(psad[1],psad[2]),psad[3]); return 0; } #endif /* _MBPREDICTION_H_ */ xvid_20020412/xvidcore/build/0040755000100600001440000000000007455522443015255 5ustar michaelusersxvid_20020412/xvidcore/build/CVS/0040755000100600001440000000000007455522442015707 5ustar michaelusersxvid_20020412/xvidcore/build/CVS/Root0100644000100600001440000000004607455522442016552 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/build/CVS/Repository0100644000100600001440000000001707455522442020004 0ustar michaelusersxvidcore/build xvid_20020412/xvidcore/build/CVS/Entries.Log0100644000100600001440000000003607455522443017760 0ustar michaelusersA D/generic//// A D/win32//// xvid_20020412/xvidcore/build/CVS/Entries0100644000100600001440000000000207455522442017230 0ustar michaelusersD xvid_20020412/xvidcore/build/win32/0040755000100600001440000000000007455522443016217 5ustar michaelusersxvid_20020412/xvidcore/build/win32/CVS/0040755000100600001440000000000007455522443016652 5ustar michaelusersxvid_20020412/xvidcore/build/win32/CVS/Root0100644000100600001440000000004607455522443017515 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/build/win32/CVS/Repository0100644000100600001440000000002507455522443020746 0ustar michaelusersxvidcore/build/win32 xvid_20020412/xvidcore/build/win32/CVS/Entries0100644000100600001440000000013007455522443020175 0ustar michaelusers/core.dsp/1.4/Mon Mar 25 20:01:54 2002// /core.dsw/1.1.1.1/Fri Mar 8 02:44:26 2002// D xvid_20020412/xvidcore/build/win32/core.dsp0100644000100600001440000004571407447701062017664 0ustar michaelusers# Microsoft Developer Studio Project File - Name="core" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=core - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "core.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "core.mak" CFG="core - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "core - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "core - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "core - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "ARCH_X86" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD BASE RSC /l 0xc09 /d "NDEBUG" # ADD RSC /l 0xc09 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"bin\core.lib" !ELSEIF "$(CFG)" == "core - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "ARCH_X86" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD BASE RSC /l 0xc09 /d "_DEBUG" # ADD RSC /l 0xc09 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"bin\core.lib" !ENDIF # Begin Target # Name "core - Win32 Release" # Name "core - Win32 Debug" # Begin Group "docs" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\authors.txt # End Source File # Begin Source File SOURCE=..\..\gpl.txt # End Source File # Begin Source File SOURCE=..\..\todo.txt # End Source File # End Group # Begin Group "bitstream" # PROP Default_Filter "" # Begin Group "bitstream_asm" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\bitstream\x86_asm\cbp_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\bitstream\x86_asm\cbp_mmx.asm InputName=cbp_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\bitstream\x86_asm\cbp_mmx.asm InputName=cbp_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # End Group # Begin Group "bitstream_h" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\bitstream\bitstream.h # End Source File # Begin Source File SOURCE=..\..\src\bitstream\cbp.h # End Source File # Begin Source File SOURCE=..\..\src\bitstream\mbcoding.h # End Source File # Begin Source File SOURCE=..\..\src\bitstream\vlc_codes.h # End Source File # Begin Source File SOURCE=..\..\src\bitstream\zigzag.h # End Source File # End Group # Begin Source File SOURCE=..\..\src\bitstream\bitstream.c # End Source File # Begin Source File SOURCE=..\..\src\bitstream\cbp.c # End Source File # Begin Source File SOURCE=..\..\src\bitstream\mbcoding.c # End Source File # End Group # Begin Group "dct" # PROP Default_Filter "" # Begin Group "dct_asm" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\dct\x86_asm\fdct_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\dct\x86_asm\fdct_mmx.asm InputName=fdct_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\dct\x86_asm\fdct_mmx.asm InputName=fdct_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\src\dct\x86_asm\idct_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\dct\x86_asm\idct_mmx.asm InputName=idct_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\dct\x86_asm\idct_mmx.asm InputName=idct_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # End Group # Begin Group "dct_h" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\dct\fdct.h # End Source File # Begin Source File SOURCE=..\..\src\dct\idct.h # End Source File # End Group # Begin Source File SOURCE=..\..\src\dct\fdct.c # End Source File # Begin Source File SOURCE=..\..\src\dct\idct.c # End Source File # End Group # Begin Group "image" # PROP Default_Filter "" # Begin Group "image_asm" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\image\x86_asm\interpolate8x8_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\image\x86_asm\interpolate8x8_mmx.asm InputName=interpolate8x8_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\image\x86_asm\interpolate8x8_mmx.asm InputName=interpolate8x8_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\src\image\x86_asm\rgb_to_yv12_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\image\x86_asm\rgb_to_yv12_mmx.asm InputName=rgb_to_yv12_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\image\x86_asm\rgb_to_yv12_mmx.asm InputName=rgb_to_yv12_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\src\image\x86_asm\yuv_to_yv12_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\image\x86_asm\yuv_to_yv12_mmx.asm InputName=yuv_to_yv12_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\image\x86_asm\yuv_to_yv12_mmx.asm InputName=yuv_to_yv12_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\src\image\x86_asm\yuyv_to_yv12_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\image\x86_asm\yuyv_to_yv12_mmx.asm InputName=yuyv_to_yv12_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\image\x86_asm\yuyv_to_yv12_mmx.asm InputName=yuyv_to_yv12_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\src\image\x86_asm\yv12_to_rgb24_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\image\x86_asm\yv12_to_rgb24_mmx.asm InputName=yv12_to_rgb24_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\image\x86_asm\yv12_to_rgb24_mmx.asm InputName=yv12_to_rgb24_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\src\image\x86_asm\yv12_to_rgb32_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\image\x86_asm\yv12_to_rgb32_mmx.asm InputName=yv12_to_rgb32_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\image\x86_asm\yv12_to_rgb32_mmx.asm InputName=yv12_to_rgb32_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\src\image\x86_asm\yv12_to_yuyv_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\image\x86_asm\yv12_to_yuyv_mmx.asm InputName=yv12_to_yuyv_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\image\x86_asm\yv12_to_yuyv_mmx.asm InputName=yv12_to_yuyv_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # End Group # Begin Group "image_h" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\image\colorspace.h # End Source File # Begin Source File SOURCE=..\..\src\image\image.h # End Source File # Begin Source File SOURCE=..\..\src\image\interpolate8x8.h # End Source File # End Group # Begin Source File SOURCE=..\..\src\image\colorspace.c # End Source File # Begin Source File SOURCE=..\..\src\image\image.c # End Source File # Begin Source File SOURCE=..\..\src\image\interpolate8x8.c # End Source File # End Group # Begin Group "motion" # PROP Default_Filter "" # Begin Group "motion_asm" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\motion\x86_asm\sad_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\motion\x86_asm\sad_mmx.asm InputName=sad_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\motion\x86_asm\sad_mmx.asm InputName=sad_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # End Group # Begin Group "motion_h" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\motion\sad.h # End Source File # End Group # Begin Source File SOURCE=..\..\src\motion\motion_comp.c # End Source File # Begin Source File SOURCE=..\..\src\motion\motion_est.c # End Source File # Begin Source File SOURCE=..\..\src\motion\sad.c # End Source File # End Group # Begin Group "prediction" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\prediction\mbprediction.c # End Source File # Begin Source File SOURCE=..\..\src\prediction\mbprediction.h # End Source File # End Group # Begin Group "quant" # PROP Default_Filter "" # Begin Group "quant_asm" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\quant\x86_asm\quantize4_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\quant\x86_asm\quantize4_mmx.asm InputName=quantize4_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build IntDir=.\Debug InputPath=..\..\src\quant\x86_asm\quantize4_mmx.asm InputName=quantize4_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\src\quant\x86_asm\quantize_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\quant\x86_asm\quantize_mmx.asm InputName=quantize_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build IntDir=.\Debug InputPath=..\..\src\quant\x86_asm\quantize_mmx.asm InputName=quantize_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # End Group # Begin Group "quant_h" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\quant\adapt_quant.h # End Source File # Begin Source File SOURCE=..\..\src\quant\quant_h263.h # End Source File # Begin Source File SOURCE=..\..\src\quant\quant_matrix.h # End Source File # Begin Source File SOURCE=..\..\src\quant\quant_mpeg4.h # End Source File # End Group # Begin Source File SOURCE=..\..\src\quant\adapt_quant.c # End Source File # Begin Source File SOURCE=..\..\src\quant\quant_h263.c # End Source File # Begin Source File SOURCE=..\..\src\quant\quant_matrix.c # End Source File # Begin Source File SOURCE=..\..\src\quant\quant_mpeg4.c # End Source File # End Group # Begin Group "utils" # PROP Default_Filter "" # Begin Group "utils_asm" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\utils\x86_asm\cpuid.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\utils\x86_asm\cpuid.asm InputName=cpuid "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\utils\x86_asm\cpuid.asm InputName=cpuid "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\src\utils\x86_asm\mem_transfer_mmx.asm !IF "$(CFG)" == "core - Win32 Release" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Release InputPath=..\..\src\utils\x86_asm\mem_transfer_mmx.asm InputName=mem_transfer_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "core - Win32 Debug" # Begin Custom Build - Assembling $(InputPath) IntDir=.\Debug InputPath=..\..\src\utils\x86_asm\mem_transfer_mmx.asm InputName=mem_transfer_mmx "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" nasm -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath) # End Custom Build !ENDIF # End Source File # End Group # Begin Group "utils_h" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\utils\emms.h # End Source File # Begin Source File SOURCE=..\..\src\utils\mbfunctions.h # End Source File # Begin Source File SOURCE=..\..\src\utils\mem_align.h # End Source File # Begin Source File SOURCE=..\..\src\utils\mem_transfer.h # End Source File # Begin Source File SOURCE=..\..\src\utils\ratecontrol.h # End Source File # Begin Source File SOURCE=..\..\src\utils\timer.h # End Source File # End Group # Begin Source File SOURCE=..\..\src\utils\emms.c # End Source File # Begin Source File SOURCE=..\..\src\utils\mbtransquant.c # End Source File # Begin Source File SOURCE=..\..\src\utils\mem_align.c # End Source File # Begin Source File SOURCE=..\..\src\utils\mem_transfer.c # End Source File # Begin Source File SOURCE=..\..\src\utils\ratecontrol.c # End Source File # Begin Source File SOURCE=..\..\src\utils\timer.c # End Source File # End Group # Begin Group "xvidcore_h" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\src\decoder.h # End Source File # Begin Source File SOURCE=..\..\src\divx4.h # End Source File # Begin Source File SOURCE=..\..\src\encoder.h # End Source File # Begin Source File SOURCE=..\..\src\global.h # End Source File # Begin Source File SOURCE=..\..\src\portab.h # End Source File # Begin Source File SOURCE=..\..\src\xvid.h # End Source File # End Group # Begin Source File SOURCE=..\..\src\decoder.c # End Source File # Begin Source File SOURCE=..\..\src\divx4.c # End Source File # Begin Source File SOURCE=..\..\src\encoder.c # End Source File # Begin Source File SOURCE=..\..\src\xvid.c # End Source File # End Target # End Project xvid_20020412/xvidcore/build/win32/core.dsw0100644000100600001440000000076607442022612017661 0ustar michaelusersMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "core"=.\core.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### xvid_20020412/xvidcore/build/generic/0040755000100600001440000000000007455522443016671 5ustar michaelusersxvid_20020412/xvidcore/build/generic/CVS/0040755000100600001440000000000007455522443017324 5ustar michaelusersxvid_20020412/xvidcore/build/generic/CVS/Root0100644000100600001440000000004607455522442020166 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/build/generic/CVS/Repository0100644000100600001440000000002707455522442021421 0ustar michaelusersxvidcore/build/generic xvid_20020412/xvidcore/build/generic/CVS/Entries0100644000100600001440000000070307455522443020655 0ustar michaelusers/Makefile/1.1.1.1/Fri Mar 8 02:44:25 2002// /Makefile.cygwin/1.1/Sat Mar 30 11:22:02 2002// /Makefile.dj/1.1.1.1/Fri Mar 8 02:44:25 2002// /Makefile.generic/1.1.1.1/Fri Mar 8 02:44:25 2002// /Makefile.inc/1.6/Sat Mar 30 01:25:29 2002// /Makefile.linux/1.1.1.1/Fri Mar 8 02:44:25 2002// /Makefile.linuxppc/1.6/Sat Mar 30 19:09:17 2002// /Makefile.linuxppc_altivec/1.5/Wed Apr 3 14:19:50 2002// /Makefile.sparc/1.1.1.1/Fri Mar 8 02:44:25 2002// D xvid_20020412/xvidcore/build/generic/Makefile0100644000100600001440000000321507442022611020313 0ustar michaelusers#/************************************************************************** # * # * linux makefile # * # * nasm args: # * -f fmt elf (linux), coff (djgpp) # * -DPREFIX add '_' prefix to symbol names # * # * libso: # * (-lm not neccessary if using -ffast-math) # * # *************************************************************************/ include Makefile.inc CC = gcc #CC=icc #CC = /opt/experimental/bin/gcc # that's where SuSE installs gcc3 CFLAGS = -DARCH_X86 -DLINUX LIBDIR = /usr/local/lib ifeq ($(CC),icc) CFLAGS+= -O3 -ip -tpp6 -xM # -tpp7 might be faster (P4 optmization)... CFLAGS+= -I/opt/intel/compiler50/ia32/include -I/opt/intel/compiler50/ia32/substitute_headers/ else # CFLAGS += -funroll-loops -ffast-math -fstrict-aliasing -fomit-frame-pointer # CFLAGS += -fPIC # CFLAGS += -m486 # CFLAGS += -march=pentium -mcpu=pentium # CFLAGS += -march=pentiumpro -mcpu=pentiumpro CFLAGS += -Wall -O3 -funroll-loops -ffast-math -march=pentiumpro -mcpu=pentiumpro CFLAGS += -fstrict-aliasing -fomit-frame-pointer endif AS = nasm AFLAGS = -f elf %.o: %.asm $(AS) $(AFLAGS) $< -o $@ RM = rm -rf all: $(LIB) $(LIBSO) $(LIB): $(SRC:.c=.o) $(SRC_INTEL:.asm=.o) ar rcs $@ $^ $(LIBSO): $(SRC:.c=.o) $(SRC_INTEL:.asm=.o) $(CC) $(CFLAGS) $^ -shared -lc -lm -o $@ clean: $(RM) `find $(SRCDIR) -name "*.o"` remove-all: $(RM) $(DIRS) $(RM) $(DIRS_INTEL) $(RM) $(LIB) $(RM) $(LIBSO) install: libxvidcore.so cp libxvidcore.so $(LIBDIR) # you have to bee root for this /sbin/ldconfig install-test: libxvidcore.so # if you don't want to overwrite previous compile cp libxvidcore.so $(LIBDIR)/libtestcore.so /sbin/ldconfig xvid_20020412/xvidcore/build/generic/Makefile.cygwin0100644000100600001440000000215507451317732021627 0ustar michaelusers#/************************************************************************** # * # * cygwin makefile (only static library) # * # * nasm args: # * -f fmt elf (linux), coff (djgpp), win32 (cygwin) # * -DPREFIX add '_' prefix to symbol names # * # * # *************************************************************************/ include Makefile.inc CC = gcc #CC = /usr/local/gcc-3.0.4/bin/gcc CFLAGS = -DARCH_X86 -DLINUX -UWIN32 LIBDIR = /usr/local/lib CFLAGS += -O3 -funroll-loops -ffast-math -fstrict-aliasing -fomit-frame-pointer # CFLAGS += -m486 # CFLAGS += -march=pentium -mcpu=pentium CFLAGS += -march=pentiumpro -mcpu=pentiumpro # CFLAGS += -march=athlon -mcpu=athlon CFLAGS += -mno-cygwin AS = nasm AFLAGS = -f win32 -DPREFIX %.o: %.asm $(AS) $(AFLAGS) $< -o $@ RM = rm -rf all: $(LIB) $(LIB): $(SRC:.c=.o) $(SRC_INTEL:.asm=.o) ar rcs $@ $^ clean: $(RM) `find $(SRCDIR) -name "*.o"` remove-all: $(RM) $(DIRS) $(RM) $(DIRS_INTEL) $(RM) $(LIB) install: $(LIB) cp $(LIB) $(LIBDIR)/libxvidcore.a install-test: $(LIB) # if you don't want to overwrite previous compile cp $(LIB) $(LIBDIR)/libtestcore.a xvid_20020412/xvidcore/build/generic/Makefile.linuxppc_altivec0100644000100600001440000000262407452607606023704 0ustar michaelusers#/************************************************************************** # * # * Linux PPC makefile # * # * Adapted from linux x86 Makefile by Guillaume Morin # * # * libso: # * (-lm not neccessary if using -ffast-math) # * # *************************************************************************/ include Makefile.inc CC = gcc CFLAGS = -DLINUX -DARCH_PPC -DARCH_IS_BIG_ENDIAN -DARCH_PPC_ALTIVEC LIBDIR = /usr/local/lib CFLAGS += -Wall -O3 -funroll-loops -ffast-math CFLAGS += -fstrict-aliasing -fomit-frame-pointer ## for profiling, uncomment the next line. #CFLAGS += -D_PROFILING_ ## for debugging, comment the previous lines and uncomment the next one. #CFLAGS += -Wall -g AS = as # if GNU as choke on Altivec instructions, try to comment the previous # line, and uncomment the next one. # AS = as -mvec %.o: %.s $(AS) $< -o $@ RM = rm -rf all: $(LIB) $(LIBSO) $(LIB): $(SRC:.c=.o) $(SRC_ALTIVEC:.s=.o) ar rcs $@ $^ $(LIBSO): $(SRC:.c=.o) $(SRC_ALTIVEC:.s=.o) $(CC) $(CFLAGS) $^ -shared -lc -lm -o $@ clean: $(RM) `find $(SRCDIR) -name "*.o"` remove-all: $(RM) $(DIRS) $(RM) $(DIRS_PPC) $(RM) $(LIB) $(RM) $(LIBSO) install: libxvidcore.so cp libxvidcore.so $(LIBDIR) # you have to be root for this /sbin/ldconfig install-test: libxvidcore.so # if you don't want to overwrite previous compile cp libxvidcore.so $(LIBDIR)/libtestcore.so /sbin/ldconfig xvid_20020412/xvidcore/build/generic/Makefile.dj0100644000100600001440000000167307442022611020715 0ustar michaelusers#/************************************************************************** # * # * djgpp makefile # * # * treat "deltree /y" with care # * # *************************************************************************/ include Makefile.inc CC = gcc CFLAGS = -Wall -DARCH_X86 # CFLAGS += -funroll-loops -ffast-math -fstrict-aliasing -fomit-frame-pointer # CFLAGS += -fPIC # CFLAGS += -m486 # CFLAGS += -march=pentium -mcpu=pentium # CFLAGS += -march=pentiumpro -mcpu=pentiumpro AS = nasm AFLAGS = -f coff -DPREFIX %.o: %.asm $(AS) $(AFLAGS) $< -o $@ RM = deltree /y all: $(LIB) $(LIB): $(SRC:.c=.o) $(SRC_INTEL:.asm=.o) ar rcs $@ $^ clean: $(RM) $(SRCDIR)/*.o $(RM) $(SRCDIR)/common/*.o $(RM) $(SRCDIR)/decoder/*.o $(RM) $(SRCDIR)/encoder/*.o $(RM) $(SRCDIR)/image/*.o $(RM) $(SRCDIR)/common/intel_mmx/*.o $(RM) $(SRCDIR)/decoder/intel_mmx/*.o $(RM) $(SRCDIR)/encoder/intel_mmx/*.o $(RM) $(SRCDIR)/image/intel_mmx/*.o $(RM) $(LIB) xvid_20020412/xvidcore/build/generic/Makefile.linuxppc0100644000100600001440000000237607451406535022176 0ustar michaelusers#/************************************************************************** # * # * Linux PPC makefile # * # * Adapted from linux x86 Makefile by Guillaume Morin # * # * libso: # * (-lm not neccessary if using -ffast-math) # * # *************************************************************************/ include Makefile.inc CC = gcc CFLAGS = -DLINUX -DARCH_PPC -DARCH_IS_BIG_ENDIAN LIBDIR = /usr/local/lib CFLAGS += -Wall -O3 -funroll-loops -ffast-math CFLAGS += -fstrict-aliasing -fomit-frame-pointer ## for profiling, uncomment the next line. #CFLAGS += -D_PROFILING_ ## for debugging, comment the previous lines and uncomment the next one. #CFLAGS += -Wall -g AS = as %.o: %.s $(AS) $< -o $@ RM = rm -rf all: $(LIB) $(LIBSO) $(LIB): $(SRC:.c=.o) $(SRC_PPC:.s=.o) ar rcs $@ $^ $(LIBSO): $(SRC:.c=.o) $(SRC_PPC:.s=.o) $(CC) $(CFLAGS) $^ -shared -lc -lm -o $@ clean: $(RM) `find $(SRCDIR) -name "*.o"` remove-all: $(RM) $(DIRS) $(RM) $(DIRS_PPC) $(RM) $(LIB) $(RM) $(LIBSO) install: libxvidcore.so cp libxvidcore.so $(LIBDIR) # you have to be root for this /sbin/ldconfig install-test: libxvidcore.so # if you don't want to overwrite previous compile cp libxvidcore.so $(LIBDIR)/libtestcore.so /sbin/ldconfig xvid_20020412/xvidcore/build/generic/Makefile.generic0100644000100600001440000000072307442022611021727 0ustar michaelusers#/************************************************************************** # * # * generic makefile # * # * defines: -DLINUX -DBIG_ENDIAN # * # * # *************************************************************************/ include Makefile.inc CC = gcc -Wall CFLAGS = RM = rm -rf all: $(LIB) $(LIBSO) $(LIB): $(SRC:.c=.o) ar rcs $@ $^ $(LIBSO): $(SRC:.c=.o) $(CC) $^ -shared -lc -lm -o $@ remove-all: $(RM) $(DIRS) $(RM) $(LIB) $(RM) $(LIBSO) xvid_20020412/xvidcore/build/generic/Makefile.inc0100644000100600001440000000427407451212011021064 0ustar michaelusersLIB=libcore.a LIBSO=libxvidcore.so SRCDIR = ../../src SRC = \ $(SRCDIR)/decoder.c \ $(SRCDIR)/divx4.c \ $(SRCDIR)/encoder.c \ $(SRCDIR)/xvid.c \ $(SRCDIR)/bitstream/bitstream.c \ $(SRCDIR)/bitstream/cbp.c \ $(SRCDIR)/bitstream/mbcoding.c \ $(SRCDIR)/dct/fdct.c \ $(SRCDIR)/dct/idct.c \ $(SRCDIR)/image/colorspace.c \ $(SRCDIR)/image/image.c \ $(SRCDIR)/image/interpolate8x8.c \ $(SRCDIR)/motion/motion_comp.c \ $(SRCDIR)/motion/motion_est.c \ $(SRCDIR)/motion/sad.c \ $(SRCDIR)/prediction/mbprediction.c \ $(SRCDIR)/quant/adapt_quant.c \ $(SRCDIR)/quant/quant_h263.c \ $(SRCDIR)/quant/quant_matrix.c \ $(SRCDIR)/quant/quant_mpeg4.c \ $(SRCDIR)/utils/emms.c \ $(SRCDIR)/utils/mbtransquant.c \ $(SRCDIR)/utils/mem_align.c \ $(SRCDIR)/utils/mem_transfer.c \ $(SRCDIR)/utils/ratecontrol.c \ $(SRCDIR)/utils/timer.c DIRS = \ $(SRCDIR)/*.o \ $(SRCDIR)/bitstream/*.o \ $(SRCDIR)/dct/*.o \ $(SRCDIR)/image/*.o \ $(SRCDIR)/motion/*.o \ $(SRCDIR)/prediction/*.o \ $(SRCDIR)/quant/*.o \ $(SRCDIR)/utils/*.o SRC_INTEL = \ $(SRCDIR)/bitstream/x86_asm/cbp_mmx.asm \ $(SRCDIR)/dct/x86_asm/fdct_mmx.asm \ $(SRCDIR)/dct/x86_asm/idct_mmx.asm \ $(SRCDIR)/image/x86_asm/interpolate8x8_mmx.asm \ $(SRCDIR)/image/x86_asm/rgb_to_yv12_mmx.asm \ $(SRCDIR)/image/x86_asm/yuv_to_yv12_mmx.asm \ $(SRCDIR)/image/x86_asm/yuyv_to_yv12_mmx.asm \ $(SRCDIR)/image/x86_asm/yv12_to_rgb24_mmx.asm \ $(SRCDIR)/image/x86_asm/yv12_to_rgb32_mmx.asm \ $(SRCDIR)/image/x86_asm/yv12_to_yuyv_mmx.asm \ $(SRCDIR)/motion/x86_asm/sad_mmx.asm \ $(SRCDIR)/quant/x86_asm/quantize4_mmx.asm \ $(SRCDIR)/quant/x86_asm/quantize_mmx.asm \ $(SRCDIR)/utils/x86_asm/cpuid.asm \ $(SRCDIR)/utils/x86_asm/mem_transfer_mmx.asm DIRS_INTEL = \ $(SRCDIR)/bitstream/x86_asm/*.o \ $(SRCDIR)/dct/x86_asm/*.o \ $(SRCDIR)/image/x86_asm/*.o \ $(SRCDIR)/motion/x86_asm/*.o \ $(SRCDIR)/quant/x86_asm/*.o \ $(SRCDIR)/utils/x86_asm/*.o SRC_PPC = \ $(SRCDIR)/bitstream/ppc_asm/cbp_ppc.s SRC_ALTIVEC = \ $(SRCDIR)/bitstream/ppc_asm/cbp_altivec.s \ $(SRCDIR)/dct/ppc_asm/fdct_altivec.s \ $(SRCDIR)/dct/ppc_asm/idct_altivec.s \ $(SRCDIR)/motion/ppc_asm/sad_altivec.s DIRS_PPC = \ $(SRCDIR)/bitstream/ppc_asm/*.o \ $(SRCDIR)/dct/ppc_asm/*.o xvid_20020412/xvidcore/build/generic/Makefile.linux0100644000100600001440000000321507442022611021451 0ustar michaelusers#/************************************************************************** # * # * linux makefile # * # * nasm args: # * -f fmt elf (linux), coff (djgpp) # * -DPREFIX add '_' prefix to symbol names # * # * libso: # * (-lm not neccessary if using -ffast-math) # * # *************************************************************************/ include Makefile.inc CC = gcc #CC=icc #CC = /opt/experimental/bin/gcc # that's where SuSE installs gcc3 CFLAGS = -DARCH_X86 -DLINUX LIBDIR = /usr/local/lib ifeq ($(CC),icc) CFLAGS+= -O3 -ip -tpp6 -xM # -tpp7 might be faster (P4 optmization)... CFLAGS+= -I/opt/intel/compiler50/ia32/include -I/opt/intel/compiler50/ia32/substitute_headers/ else # CFLAGS += -funroll-loops -ffast-math -fstrict-aliasing -fomit-frame-pointer # CFLAGS += -fPIC # CFLAGS += -m486 # CFLAGS += -march=pentium -mcpu=pentium # CFLAGS += -march=pentiumpro -mcpu=pentiumpro CFLAGS += -Wall -O3 -funroll-loops -ffast-math -march=pentiumpro -mcpu=pentiumpro CFLAGS += -fstrict-aliasing -fomit-frame-pointer endif AS = nasm AFLAGS = -f elf %.o: %.asm $(AS) $(AFLAGS) $< -o $@ RM = rm -rf all: $(LIB) $(LIBSO) $(LIB): $(SRC:.c=.o) $(SRC_INTEL:.asm=.o) ar rcs $@ $^ $(LIBSO): $(SRC:.c=.o) $(SRC_INTEL:.asm=.o) $(CC) $(CFLAGS) $^ -shared -lc -lm -o $@ clean: $(RM) `find $(SRCDIR) -name "*.o"` remove-all: $(RM) $(DIRS) $(RM) $(DIRS_INTEL) $(RM) $(LIB) $(RM) $(LIBSO) install: libxvidcore.so cp libxvidcore.so $(LIBDIR) # you have to bee root for this /sbin/ldconfig install-test: libxvidcore.so # if you don't want to overwrite previous compile cp libxvidcore.so $(LIBDIR)/libtestcore.so /sbin/ldconfig xvid_20020412/xvidcore/build/generic/Makefile.sparc0100644000100600001440000000101407442022611021415 0ustar michaelusers#/************************************************************************** # * # * sparc makefile # * # * # * # *************************************************************************/ include Makefile.inc CC = gcc CFLAGS = -fPIC -Wall -DARCH_IS_BIG_ENDIAN -DARCH_SPARC RM = rm -rf all: $(LIB) $(LIBSO) $(LIB): $(SRC:.c=.o) ar rcs $@ $^ $(LIBSO): $(SRC:.c=.o) $(CC) $^ -shared -lc -lm -o $@ clean: $(RM) $(DIRS) $(RM) $(DIRS_INTEL) $(RM) $(LIB) $(RM) $(LIBSO) %.o: %.c $(CC) $(CFLAGS) -o $@ -c $< xvid_20020412/xvidcore/changelog.txt0100644000100600001440000000074007442206754016644 0ustar michaelusers08.03.2002 - added support for custom MPEG4 quant matrices 08.03.2002 - new core structure - mbcoding/mbdecoding rewrite - API change, introduced feature flags - Bitreader/Bitwriter merge - putbits speedup - ratecontrol rewrite (it's total crap, just a 5 minute hack...) - split motion estimation and motion compensation into different files - encoder.c cleanup - NOTE: DivX4 API compatibility is partly broken right now - NOTE: custom MPEG quant matrices are currently ignored xvid_20020412/xvidcore/authors.txt0100644000100600001440000000016107442022607016370 0ustar michaelusersauthors Michael Militzer Peter Ross Christoph Lampert xvid_20020412/xvidcore/todo.txt0100644000100600001440000000503607442022611015651 0ustar michaeluserstodo *** build environment *** - portable makefile [DONE] more testing needed *** api *** - decore/encore2 wrappers; [DONE] - xvid_init() [DONE] handle cpu detection, yuv/dct lookup table init return api version number return core build number [build number should be incremented automatically, how?] *** common *** - mpeg-4 quantizer (quant4) testing [DONE] - consder moving a modified mbprediction/mbdeprediction here [DONE] - add [-2048,2048] to mmx dequant [DONE] - mmx quant4 [DONE] - sse2: convert intel's idct/sad/comp apnotes to nasm [IN PROGRESS] - mlib *** image *** - sort out in/out & conversion func naming issues [DONE] maybe, in_yuv, in_yuyv, in_uyuv, in_rgbXX out_yuv, out_yuyv, out_uyuv, out_rgbXX - input flipping support output flipping support is not 'perfect'. using negative height is bad, best to have seperate vflip parameter - rgb24/32_mmx cause yellow dots to appear on left hand size [DONE] (only visibile with high contrast colors) - rgb16. [DONE] can be done generically using r,g,b masks or just code for the popular 16bit formats 555, 565 - diff between basic-yuv and iso-yuv *** decoder *** - quant=1 encoder material appears "soft" [FIXED] - block based interpolation [DONE] - msmpeg-4 support... dont hold your breath [IN PROGRESS] best to write an entirely new 'decoder' than bolt stuff onto the existing one. - post processing - add basic mpeg4 stuff: - custom mpeg quant matrixes [DONE] - intra_dc_vlc_threshold [DONE] - quarterpel [in progress] - resync? - b-vops [IN PROGRESS] - figure out what todo with time codes, and fatal error *** encoder *** - purple mb block (rare) [FIXED] - coeff range checks need to be verified against mpeg-4 spec [DONE/PARTIAL] - dequants now clamp to [-2048,2047]. [DONE] - fdct_mmx clamps to [-2048,2047], it doesnt have to (but prevents overflows in mmx quantization) - quants _should_ clamp to [-127,127], but this introduces errors at low quant levels so we ignore it - idct _should_ clamp [-256,255], but its really unnessary overhead. - pmvfast bug fixing [DONE] - quater pixel motion search - 'smearing bug' when motion occurs in straight vertical direction ( http://www.videocoding.de/forum/viewtopic.php?topic=71&forum=2&6 ) coefficient thresholding problems? [FIXED/REMOVED] - better luminance masking [DONE] - use N_VOP when a interframe is entirely composed of ublks & frame dropping. eg. simple ublk threshold *** gpl conversion *** mbdecoding.c encoder.c [REPLACED] mbmotionestcomp.c [REPLACED] mbcoding [REPLACED] putvlc.c [REPLACED] ratecontol.cxvid_20020412/xvidcore/gpl.txt0100644000100600001440000004310307442022610015462 0ustar michaelusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. xvid_20020412/xvidcore/examples/0040755000100600001440000000000007455522443015774 5ustar michaelusersxvid_20020412/xvidcore/examples/CVS/0040755000100600001440000000000007455522443016427 5ustar michaelusersxvid_20020412/xvidcore/examples/CVS/Root0100644000100600001440000000004607455522443017272 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/xvidcore/examples/CVS/Repository0100644000100600001440000000002207455522443020520 0ustar michaelusersxvidcore/examples xvid_20020412/xvidcore/examples/CVS/Entries0100644000100600001440000000030207455522443017753 0ustar michaelusers/README/1.1.1.1/Fri Mar 8 02:44:27 2002// /cactus.pgm.bz2/1.2/Fri Mar 22 13:25:24 2002/-kb/ /odivx_enc_dec.c/1.1.1.1/Fri Mar 8 02:44:27 2002// /xvid_enc_dec.c/1.2/Thu Mar 21 23:45:25 2002// D xvid_20020412/xvidcore/examples/README0100644000100600001440000000160107442022613016635 0ustar michaelusersIn this directory can find some examples how to use XviD MPEG4 codec in your own programs. Christoph (gruel@web.de) * xvid_enc_dec.c This is a complete example of the XviD-API for encoding and decoding: The program reads a file of YUV 4:2:0 images (as greyscale picture in PGM-format) and encodes this sequence to a MPEG4 bytestream. Then it decodes right away. * odivx_enc_dec.c Same program, but using the OpenDivX/DivX4 compatibility API. Wit this you can use source written for DivX4 and simply relink with XviD-corelibrary. * cactus.pgm.bz2 Example input file for multi_dec_enc.c. A sequence of 3 images, a szene with a cactus moving from right to left. It bzip2-compressed for size reason (half the size of a ZIP-file). Binaries of bunzip2 are available for all major OSes at http://sources.redhat.com/bzip2/ The original source of the cactus image is unknown... xvid_20020412/xvidcore/examples/cactus.pgm.bz20100644000100600001440000023357107446630304020463 0ustar michaelusersBZh91AY&SYaQ@#芠 7@R *UE ((P@@ @P$@   @PH (U P@ ( (@( @(@@ P  "M Hb0da=ODƧLͪѠ6iSL aѠɠT&hT0 #C ``&h``QQDBdFFM3@h&L4=&&M4 &43< bmFCF F@h  h ɠ!@h&@iѩѡ4OSOM @MFzM1"vh!A %Xfh9 1 .*n~*4 x=#GSDZs +w~QwU}^k4)U4kORm+]0IZˍD? Ҽ>;,$+C)K =;}=)b{T9(t7WDyBT~gbZJWJr RtN%ZaД"D~~ց(Z2u0V^. 3`nUUFר%Ts ]^6Q:xdܝU ؀$h$೩%qY5즚fHA&YRޑ{ְD)q󒔮-VIA)BtM\\W+&*pqGh  F1.!Y$fUQ4i&ҽQT%jz&"giy[4 Xg EfWkBŪVi13*qww tA)J Se)K:LXzr]$7;>۶sC9~{OȝIGs?s1yyN?7J+][n}owo|U'J,t)C&O*7]OՁ9%z_jd%٫NLY,7?jf;N>gektC% LhQ˿'EZs8]KCv ld \̪6(* O }у]x7=ub]&ljlbUA?k_^[v%ba'kտ!Yt [Wǻ"-tsQ`]Sȼڸ1QQ9|3܎3KQKLr(]>&njQQ+UɱqtҘ6CRuO7bVg)Z›[3}%>^Áje`>^_#jqneƞ$⯲CSk*57Pgk;eS*%jR&E"@2cdc$ڏmQOmqUp_ao-aLc~knoYglޓ2I}\q0WbL2̜uIk)vjOU?K;׈*\dSʨ$.3TzoZ~21d^L2$őI2=UFjدLdjObo̳ hM%hu/WĘOΧjJrjJYAEd$1QJTfF*\[=2GjuFJadQ|]I1y la;ɚFEIQYT?IR/T$ŸյD%Eٸ7.O6?ঊQQՑj M # YɹY#^fz$͛US&ne?$L83ŚȥapY&ݟ?إ.\39[ F_5e;VSGu)Qw3 SΆƙI-l}9_))TrSQLXH[S*F,YebqfO)_^2FVVHwYO~u/;S򿡹x/qqxU*}XcuUQqܷ~>G}6'}益u_M/u{o>#Gc+#d{YsWg9qR";7s1-lT̍;bܥFW_e)b.[N{#L䧸G㕕LYl9NZdF,'rAe-snc90S9{m9YdbcN\c=Ǹ29q13m3[-i"a˖Jf-GNR)sO~7{9?/)OAr{y_qocO1鱻ɸeyp/Or}c Æ+!]׈s>V 3yu(.-.$ `)b#&脔H'P:dkHd'a2j)HegP5 e\1&e 0D $Ar Q"QBxpg|ɬrϒBn T Q.Z/ ]a$)#ED2(7Z=1b9 R*0"""LDDDIHAL,l;H1 B=6Q̏!T{Oul[b0[ˊ[-_5Ƴ 66IklYq:0£%6F6EgY'Vfɱ?a&)JfmRIu0욬ee]bfɇTM-/#oF$gz ̣lYhËGV7h4a%mjKEK,tSr?Tac!j3dfu$ 3RPJ}-G'zHћQaŜ*8شR,EE*,n4K?, 0Շչ ԓkslxplIfb,Qu7:rfaۃ{roRNHͫڥ;ʸuţ.NK$ѹ5j˫ͬ,ጵYhՆjrYXյh]Nh)KF{/qǼoqp^w3gKe:éfִ6S{s&ػtY֋6S{k%R 󝢜Y?Qcy#.NT_V/tTm^lfإ63nhE)ߟǿ-FL)PjӒ2I.-$gLI-7Kj~%nIJoYOb.#8O|v9$M.س\UXdf6L)KUSj)Su*Rb]uYK^jKΕhX?ñɓuۜঊmIYKt*_kMSC.x3 jp#oRR5aIJ.&,4e+X>g'cF Z.y;ǏZֵI/b2YS5jͻRvBtss˒ э-ֵjՍ]qqeNJN*V0-'pb tgS%6$4]cILX#f-BKy-&&NK'8ISmhާ;ɫW)F6 :;[F8&YvkE8sbg$f*̖mIK[;Z֫tIUUWg;k6.íL]~sTM}{ZtR]IwwR0hU-\63pfܳMRVzlH{6o/cyg1b ŒZH`U]4w.]e^fv[["ԥZHH)mc)JMqRKK7a6Fg&k5Ijhac99##kXX%,C9M6;rfjfK7*2qg'Kj]4k[rlrS&*nqYNLoT{6L6_IY5Yf*]N,?ÓGY›jшEYeVdսs̗qYQfn.,pY˵rks3f{M#cV]UUVs84maQK&;emnċI$r] sVm.I2HI& ##ARHAOo3_aнW~'}>Cz>4z L$q^)'~N2MC>Jw2F"WswqwNwQH줎HfIƪq>%WUs#W[:ZJU$7ڟR{a*|jA'QSU*zGߎ0=j߶& jjS[SzNjˮ L).ie,v*E?Դ)aJYR.Z)Kl %RL$"l:$E;[#fEQ(dYl)0`uًeKR&΅67K$ IM̘T?Y橋Vcu/h4]wN^8x[ΧceeIJ̘ae:Q}ſ= IRI&HծjQi'rwAR|*RGإObUIuSe;c =w#5dzO+':MǑ̓6M P#vO+z{QmdnM Ӳu9hvmm.MZ2aNckw3ondÚ92YŔuHFL73b/,eIKڥNL/ e;4tS2l;ɢ:ٷwyg[Z80s鵏]1QJRYLu5u7η^V5fËc6?u#ާcu7hYdKfvhU]MFR**3Tau+^.zzjդzaJ ,EG[cT,HK6&3aFS fɣgћijk}ds< 3UәɵULGL]]?;kW07y߲͓%6L'fܲ'k_amh#enu;Nwwy3qn~Gz:z<{.g[{lx..YT޺ѹhb ˽ՖI拹0p}MTSs66Vv<znzQ=Wnav<.ߏ}o7 ct<-rpTTTw#u:\q606#K5TnS 62xٸ='gCg9>Ə+=s2]]:_#ӭݏ}Wf2eS]=cnm|Y-[0/>ݭMv;}{O5ר"^롛Fw~Ϫ<'k~W~FS^w ̥. 06]MчƼzmK7)]g'lfJu.MFngqfs+6l =~zMCWrzcTܻC7}.y}s_%uئk|Gcky^Ww;l;+u6le]o{ YYfգUL9mL3s=GJyhS6l<ͬxɛ594Sܧmd͍MћGykWޣ[YO{nǁW;j \.gWVz^nd~}z:=qlzL6 ^kkH:]}MZE< RS| ;:$6:jlwd ^xۙ6F,a.u5lN*d<]-O=F3bs7&fpYa%Gхo] cFf֌h,M75{޳ 8Sﶳ,7λ]lo{My'a92'v6GpzWwSWf4ar~G;,{N"ʑhyi ˷3dJ,߰0x"R.UaOŇ3/vqg&nmdõQ r{ sG^%ޛScM^jڧ}L4w:VuK6=}a]gxv=lj;]2} :Ի)0Y&=Ǖw=[(<dw9ޓfצnzNv#tXy'3c5>ձj0͆~ckj)heKj,m9Ts2wߙY4Z=6LL$8-)Ņ600ѱ0ػcVq&yIx[u6>GK&Nv8>%׍ټyFMjondodg7]vQvO2̔&=X\]֋769>:]*ddɜ] XjmYQs~tmp}̳vZxW&=$=>'].\pxsrjzVd';wy,:YrwEaalSh&)thK)Yh}-IL4R(ELaLfK7,e.8$Z>eld]gcGy~'䔧Ss7Z4npqzngp}/:W;ФYNvaM]4y'3 񷸽G[c{hZks OVxu:pa{}y\]/ %u?B]ho{w7>fǨ|irvzziw33t9<g$dɽx";ڻkSj<\2fEG$Ss%Eњ)Jod׉:ћVJRRYh)J|ˬaNՙ=%Z$ks %3*Tl;,MSt]s72+mMz.vdn)&Jf}(] ]fnJh2]]ul|o:󷮧ssc n-Y=']ΗZ;];|o.uoI>~ke<;z0ww?CzY}QβUaS x6OMjܓVZ6e]MZ;ӎi5 )%*Gp^/9Iv]xJSd$jRJR%$- *1Y&Jfݯa'SGClz+G$TvO)rdG> M,ӃtZqK)Nut:c񸶮yaN:SVfR,F:#b+-SdSrt8w ;Φo=fm˻_쾆nw6]m·}OI<"n.wI99_7[w<oo,/]'[y^v,ͪiU-5Q~cfVZv*jVon 5rmmRFeh])XJajEdW͔Iu$YLbUad45v80fdOŖIe,hwKrv֋3KYe"*) wc2x^'3F#b'ņL-YwYGT3Ft>M=*)mhqt)D:d͊of$.ш2s4fSzhL>WoZ)YxY+;] y= +6;Vϥ6mWmu<,W<+md,bNkW]t=Ot;nzw63vL߸鋩y%t.w'Wt5m^6?J|˻+83ffLE8TSI%$Z)_ T^3fՒd*SbI{N<\\onlf7E*$4|qi>eudv6>FM6,QJRYhfoesGKfv6'EG f&qwenxXtMgG%2Sۛ9wkYOM֦a7Gsд}^ޫlou97GStOC70\^?f#zmM#ccw;\\^{'9d:66.λ,:2'?z'};+'2;woy>S#=bdNmlj}LhJڬ^0eL6,%nz+(f)&IgZ%0VdZp~ޓz;[fRzfut6)vՖRN/Y]veܦl-:'gcsvSYu7Ĕܧ]wҴmhx#7'ɓy]Z˩멛ڎ70^VoMGNI:ܞF%.RmjՇ4aYfTՆXv94OYN1l]ܺKRe %zZN'3Yĝn-[[e0h[3xZ^.%e ZEE8*>jk*N4a8.92ljIMRZ,R,nu7xWC&ʼhU>^:I,f]&цo#)SSt'鎩ѓsfzN'Cõth=O_xXpKrص):ۺ9 '督`ڷ-xܷգ{ϙ禎þ^6޳{f.69;NufiyGձe h[qpv &"Ye9IfƻVnk%0 II:ԻQfx7986h}L)x޲Mi|6nIR~F_}+FV 2a&$gbo]E}:˵Sʻ4YiNK9?4)dT.qe3If-=U,޻5)M]JRd͵)0)u#F';n|+89޻&.g5j³*N<ƮfOmOh+c?^mMOK6wscI~4v '#8ѵvda\Y?~ 5RMcYՆrrlINKL)J]hi[[$ZE)RIʖ_O}N1KcY P8SKE6)յYvs(n}/UxL5vk2RRdգ]ҦK3dmnhNvY3xjڥ7'ccqt7Jgrlz_Sϥw6~7'=Fg[>'S^pY=='{M]YRU;kUѬb0Vf޺4dvl>;725 m]֊dN.)W^.LR)~l|N~rL>'70|n 9.?uBRw,Gz,7 .,y]*3xRh0fǡŪfٲYNMc]͎'ܛd￶dGmhzn-]mZ:Xhfmuɹ\fh'>W)$wSugvzޛY{{e?ٚ9%=w[0e\\.f茣dS ,)灹dmRGmR)%?qK$h$ˤͫGI 4h1z`ַ$av1gNY,"2^, 1 0FL=Jod~;6M;'CtCnNqs?/M߬9f97~\;_yv=W޻拲tnrsNS&3Gw=}NhpRZ;d7;bW]&LԼ]M<.jf}I2TsV|WIHZYQe)|$?%υQHNu3#kOaY'rJ#zSdɢ]ܿqw=))e$cTTx.4lj|:ldxw9?+E='c{X~u=ghs=mzʳg3uG'yh8XkOgߥltF[';G8n{2z2qj͔S'Kv,ѵK0myeg&"lpSi$ͽx\${T/d(.բK0+TrT]x)xv)Nt6;EV$0RԒ3u9>l8f6ѫ MwyN{ѓjGnŜ^Gk7>:8NikL.Ê\*.6Y]K]K.laSbeRR0ZfwwwI%Rv:s(j|WpϏ s9-z70?MbE)JS IeG]S' Z= K)eRSQYG;%Yɇhak|/6oC>&ڳíԳcyבv=Oei wGe]zgks/lx{ex=Gѽ;Y6]Kxjչposؓ%Fl,f%)QMmS{%*2RYeٯ0-)eٽM.]w,LJt=6qcU&EjFKÔrdYF-Rt.DgS 2#|ola%IQen]~8]ɵunma:E0ի,w ]>Enl^)I2IeޤWw;YL1{Zֵ.lf8E)PSkk}TkQXfE:8I/6:fI4RIu^/Iylag mhɪ.T]eٶ3ma֦INuock|fإ]NT6ks6i[WKk{}#y|'[:^WOt7UP?Q}wf5I:b1wLd6N*o{U}MXj^GcG=GܧU>vK{N-Z6-u,J^,IwKmVRRJ]e)'YR-b)Qۗa&#FC%=VŗSh}'Z$T7ljomS%rlGy|=7&mIe$,EVRs1IgyK4}TͽM0GR,7rΧK8h⧨}fN+ F]cs]Y{ v?jp}j~OϽhc[RUH[vNi7-lw\+sWCcomE9_;pIL>qSYw6t5]KYeYehR푱%4S(r5mY$^̢L8.UUQ#h6.H|껡5Z˹96'%fKœE)gk͚ԲI,jIe.)β3fsZGX2Yy"]mZ2R :)ommx0á'͛w]12aߌZ=KÓa7k. ]Ѽ{vFHeuovoxf>H&e>yi{zO驛zY<츬ںSd9:[6Yw;kgѤf%$h%.{mf)L)Ņk7Y FuJfDYwR*)QOl]uH0ՈRd6'J4SZ-κDyֳZ5Ժh:.[.0aݺ":#TFqS7b;q*d*s2e; '&ԥId—h88:ٴlYJTRYN]JZ*<*]ʼndqZ,:79kqcsVv? 6=72{.MK9[;+;sbMTU$+ipߴ\r[_KSteG>'_766Ǫlmnhړ~d+bOqNFL,YOuVk$ŗaQh$,u%TIvhA$7RNYOiCʂI]OI6Ϸ=wyPD̴ns$RY̢-^t)?͊IEgYQ&R*Tst/MY*5"sjdﱱ[&d񿉣Gly׊V#s*H54royjٷ?Vk<4jSecWg?y~q~g=w߅v˼ ${S'(a)Y I2eS6Bj5x4ufS /õeԺٷ upfۿ%HM|0ݯU~f=&#gK7^ ^w}n~˩WVwLfl]dScV׋jYa#(Ɇ,ZE){aKQI*)u-{2S IڗIu)I)hRB]0]Y)fGR%c͏TSbM/>ϡz#7fSR*; aeK61? $SwסdJIQKE-W]%0,50)I*)'fYHO]L)e9Ś|a 6)hjزͫGE5]davOeMUjF]wo]z\\^Mg{.O}ixZ8y_yI#Oox';y+}]l٤Q.RWZ)BaI)J)Hຖ]u0KFK–aI4y(YG^6Zs]%ԡI)u:\2>6"Jq,s,Y첋Eov2aO"ѱuuRTTw1#%)K)I)JSNMd+E݋7u>b2dKE,/{ l]e>CzͭIi5YJYK0u00͊x[o3y#cltYjL3jhw77;mu2fddIG3h&,޲TţfڦJw>"}8zLؑɵf&KE3q^2R J],شhgRK/)%ԓ'fkR]e7C^Gm8fIDIKHgR|ée6N >Xg%D:dդYK-aŔjmꋻFeERJT2gѣ4L?&YSELYafkeM0vqvȻHɶ0lnag~6 7 i: 4}깧H۽_*VS꽶m菥?;,)uYTTS YM)^yT4dd0)JTT"C f2nx/x~L7ۓ̴٬s\_KVĖTY4Yg^E0ʊIJ1,JTRJfLG값2R͊] 0⥝K0w5}E;Z^38;^*.+\24Th4unh޻ ,׍c&m#=JfjKkU:G93g$t)vřk1$I.;s8> %FSmT .%YJ,,ݎRIhՅ;=Ҝ["Jlhair]e2fjR JIܨ]u$JR[ޮJI;bG%.dld̴YJY0ꏕL$t,f"TN)J)H%1EFL;.^7kk6jZ4s3j%I 4S yu5w &oËe:,?u&6+Fɧev/6wg8nKmQ$j޾=4=ؿMܳlR杫ol|:^칟y8:Kl|2|>NL)g? pgjZ.]tTZ9֏j~5hqE8ՙ0ܹ)eʑQeFIuI%h˩e7'awK4I6S + 3}RJR$d{mQՇ2L3dGT*$R7vYMY)u*)LHN+K*Z;\.-w,)J? ֑eGt2d3I])t93v2YMY%)Ki)dq6GK2Scv,2IŖjv72af㡒ozRrn}ш)gscO,ѽ]N7GVq fݳZd3Ͷ 8OEue;k򽇩,CxxhKSx"sclKu;Z7.Z2p]&qe3R72f2$ܥ&Œmw4v?dɱu$Ieҥ=%M-5..,ʑJnRʅK%אYdy}-UZBJK>>]w.c%7]QRhns͒qraeE3p]m%$&F>E)&,lfʥYK}I5ngRQTRi) 0"-:뷬WmiZ;XaJTIκ쟉}M[b윢9,fLu2:fFY%>e,w֏7-^Faw;͑,74x٬-VqG5YJTToZ2Ss3f_fl,̨1#b2)M$] I*-t)x#,TRYJߴ˒ڳfܩIbK)MVZ6*.E壊1ωNR͍V|#,GrmTIXdG-2P$.ivoyݎ"OM0S7k?"]hޡR$DԲJI&"eTfE,]yFoC{x)%)JRGYR67e6n2dɽL= Y-Ksuax;W\͍MۛGofQɇ7~WrtNqs?x{?sćz~wo||X{OYyǼ70T[y7$f➓nmx\͏is)Jo}]Oh5|.໵&? ц]v= ɔRcH6)uK7 ?g#K4TbGhȺ%E4t)K$YI)Q%*H,.eڬ!L.kaaSɱJRJlSڳ&բHZwcc3IVeF#rqJTSr),l]S϶-dR}/)5ܛd70 TY%I,KHTrYeEE*Hg3j%*FRPo:ǍKH%-$Szw;Y0I.KHK3TYNuF&fѹYS(? a$7Bm}K7?lh]Mj͒zO𹞫~jG G;WWw{.sLT^+gWv ^s)Oq'}/7'g4q}*YOBueha~'{s,rJmTotŒYԺTRR 4dhe)ffYJYe-)K-)JeIauEI6.uZTsFϙflimhGeTTaس(ɹdY&k7f*3Pk$}Yx4+76-k)гW%L3R]&,sfIe$RJIQ%%)fDɓ(G꿦x\4d ƱKE,Ye,YhImc7~륵%Sj*,ɓs63f͊s^=?칝OxVa^l 3lfUU#tZz-cԿaսfvݤtl]7Gg#5>9vlR|ˤQvΡFQЧ]S Si#%"ED'ڮjvԓ .jYJdJ]ܼh5 >I.qxգkV)IL<wyfN KXgRMbYRR,JTR%$Ʌ>lFRTTs׬그?mSs52dШ&.՗hMhd7J]hQu^)Rda ]>nlwy{e=FOkfV7=g,|ˮړb],jaVoYF4I;űk)e,{oj͜RˬI.*yZ3hpmf-xEaN. Z2^6-# zL;W>e$ -$Z,ȳaxOmVzxa6awvHJTIQ$4a9ƺK֤ VR vYdYg0ɒfܳ 1Q( ae$E**>{2^0TRK4^.FYKppmlMomg,J/'V''SFR좖e"K,j2"zmyڶMXz)ѫE]&ܺ}M-\jpjﻧ_qms=g,i6~F[[>}o]DO {}/Vścg'=8=yNk3uYG%'3 2Baw,824RKE*,W'j Χ;5T:ËՄT)K,5RJYeTR)g:SY*3t/F=x Ty]Z5f ,% Dw3m ITqlZ$⤟DXYh.űʣ $j7_GZF&ŢRE,R)%芋*< :ldSbMQfjnSƨܩ3l]J$fY%F^K1'KczN. &Lٸ6#$G.__;?Ȼclے=WƏ{lw>>f^cnd|tɛu=%s}Z)%)I\.&v,MVaQJ̗avVSO SUaQtT+.Z)%* O5ZFQyE-*L0TZD~YO+ͅ-LF,Q%$ȳ8:[u$aڳjj = SvY9}a(KEz-y0£hԨ45He>7ܙ,ԲMUe.aQxՆJu3)JR*)q~o֖l].dR0ц[rh՟%|*lͪruJTx{ktU?v){ y{{͠q|>y,g ~{+{f?䞿}Vija3ks3+MM&礷KLԲmd5fќw,}_u)fإRԲ)eWIeD"aK)Դﱽw> df,nL2I?Qhk’]hj5my;\c{@ldKZg4J|u\LoS{U7S wYu,Yh5]]v))NybuHK-IJRZE)-$rY"Rh՞1vfL7E*.Yuɇ; ? %>7۞ڦN gR2j'r=-ټ/Ѣͯ+g)vfþ޳^,gw'#{v:V$fI'ܽVζӵUxNmjH[WT6]l?zwlwjLZ=ɛUSг5YOm'\ڴRnRISuF]߼Ʌ> gbTYEHR; ,(w͓aڻU)K,í.zWrزZI$4|FqMb+G()I,ؼnbYɆ.eх-*8)inZ4,os,K6r5Yvk*,7.%$b.,\V| nxI\̤ܼjG'Iuv 5^'&fUsGܳܦ$8."Ÿh'ɱ]]qelRE)JIL-"|gcE)j FlxL)\x;baLoY*fѵQ9/ra%3o]L?u)fZ80YK)5:r˵,Y.S< 3SFjY$£ ae)e{K%+,qwv 27(#g%]u ..ձn]ect)vhS76ĨMvՖb0]S{U64nnbpTd,a 6͌5xx_RKOw;Oq./s;gukU'/Vڽ szO4ny\Y<='Y0|oa&'7> YavlYe/YJIJ)W5},5jWEڲyK*,̔ɚ♺lE)gL2u6S%}L)zhUHڻr٬QEy%uYOO[rLԦ9$9mjю4ҴYM)E:9Gr񛵔d.ͲEnSljt}lRgvFjIuJ$IU..Nϵ튎6)6)80qhfu/S -"Yx=6nsWKﶶ;ލVrxI6,knvj)s58]wےhÃ5Fת[WInzceћ6<>壝鿴gwm{iew?Φ'y޴UT'mt~g.r?zZj=vtzO>09=6I>e=Kl۞FRtؒt~'l1>{?y]e)%QQe=F1$GUviOuJYK)%K,z0eg2fl0,YuJ$wS TxVYJKG2Ε2Z7-$IlExJ˰Or]&Jw3Gds9E,YJu2auKؒ'퍩6TRR 2Ydg7*FJoVj#ѓFMr?KkZ73R̜_}kY3 #j"eK;wZGh{,س6#{?syٽ)'ٮrYkcAn8MkX=m[xncSyw?iٽqnscUZ;F]aK/u׊?2Gb2Se .)r.e)ujQfS72l)NRh—RIu.u.F[*0cZ5d675Eg:|~WJ9='9t;)YxYN)s{t?]xY5VŃ=#s:݃zH1r[|yΚݴ]mYkQ>פv+?e7)>6zOOK $F;0]. VeUTY٩0M{Z&lR͑R,+۲.ߖ]N hS ]bFm˹LMYnvk,\]uE (4paLa)eZ5R˲TYJIenZ2Fy]u,h.+њ)p]x8LrlR$Tx\֩,~L4YN/ Iܧ:)afaɫ"I̥xRddIK3R(Ssڳu)%YMK];dus-U-EΥ֑J6g;k6yڥ:"fÓ 68homa00غw ?'ܻsU 6r?дtm ݎ,xU}ﹲ3Y{fش9lpsҹ/E\mQU]]]Kֿ]^NX:6-[E|Qгz5dt=wy7d7v7:aIf=6woUNvOdFrQgzYQ?gszc֏C>7^L}.|/_~~g󷾷wS64R{S|O>v9=瓃d#SrڷTɵkFS&? (,YI-7l,ڥ͒ԲEmR~jͮf]Rf%oj{]jQg%/RJ}K0UK)J]fqu,v;.&Jh;]U$'**F?GާRY$.Ne3Rylc[wdѓdKEJTRIh<]TzK.IUVL~{| ]/_;nfv+';NGx\"S]w&ͅ)M,Igb 3d-dlS/;VQ,Ivŗdz.Lܔ&JQ2RRS(K2rY8Z*$ԲI4]e(~$SU%]uԒ묺n^,R0m2v2s)hں:YJTRA2le۔jS ȺƳ 8GYdхYɵxZfם,ޓ5.JRtE뮼Yh¡0eeY%Ժ$jʳ6ȣWuYwvѣgsd~:Ã%=%Y0$jEޅ^8)%aK/%dt;mh\VfdeSU֑gjmչqu,cj,_9x\v<8:,xgޫNfLGti8;UGuZm{wlmp6 t&olx89Y0ޓVy&m]xţE*pUqSZH,JI]u)N/|s,>rSl1 Z?Qagjc jeuՅ<^hJR]uHygOBdʊVY%$,>U%>YtٱQxʏ#6Iu>ի tdޥڶ2zM#8QbS-0YE2dRԴTaEFňئjSFS%Y&iwwStO*cc80͛6Tu<.uy\{xs'~HYGdy褍`='%渮k݃5epB)wˋM#{-X)x|q)fru081.%njQJR2,L-TYK,YJRTYK8x%Rf]Sh2b=]v]%QuEEFXYQɢ)wʻaL$2yU%#bzGI3RTmRYer]JqlaqSNfl.ŢStspa*7lV̝wmIY"}η&qSNwzuVd-ز񇍜]%ⲣ\b$.rw]K)xT-\ZLͱxͽfk$FCjlɫEE͒'Ye'ͫb͋.޲̗mSW3FŬnN1REE,ʎ-ӷcVjRMk<+規 2mt)vdnfR4S Rʋ*EԲYhRR)I=5Gs-]u9auE.%'dNJg&qҤW5U4Ռadh~*QKOvśɓhy60K,*G:ˤ$䴝JYL.Ոf%)ђYeEFr= IKʍW޺4$a%1IYz3y*ETm^-jZJILI>K G(S't*4oS6$d?ȧܧ5nd)fKxjIqudn|n4tlqq]EܦJMY|wOݞMܻzi"N;Ū||{/಼ߴ#xukX[Izl[ŞM^ _K6ㄚ]%/FњΖ)%3wVKu*6GsGBs2.,JIJa^)Q 9ea~c ػ ,Y%GBS{{%,)I(S ieE*?ʦ&RZ,]KE*)R3Ta/aKE)J]K)f#&ŘIQ#I0Yhͫ %s3do;Tɒ᪩"Ds87fZ]mwNUeۣ7{W;QJthQfJ $dYQN9-3oRt2Z)K)K.ɒ]gZEԩ=f2YSR)Qu**E Y%묽EH)JSgѫ(:h͹M8]Rsv݅5YKƼdߥfr)%s:cfjRۘZ5l)I)Q,Y]Mdhά2uͭQM)JTYwz{Hɤa&nÃdlndY{sszoj*4t4{ldBNO3nhY-x=A:΋|n㹷6ld\DUUD6nqѳ۷^Gkn\뢔=W}fרuwʌ+,]eO5|}nN,\iv ͮo3~W3Yf:gMh͆k)0Z)%).55Sa7;FC6$RTjI-SkUE;]ˮzaww)nZ3n0]xYI*6)R0O|?*Fa%:ԲaKE)M,YҳHJ]QQMT,زK)eReE"%I*EE$R>6Yf%%Emu.üff,]gC.JdѢx.L*/⥔.jXRYu5ss)Ig4h]wWI 0JI76Q3M.vNM\븩c7M:~syY9#(ͲM+WSձzձ?|37MU%T!U>covS=2yܟ[ZvoaFNgrhe'7ȭ4OmSg~$[4QKEE-kٺ:VdͽTqR Yb00T]NIQK2)JS 0JR̙.ht6xe{7}Ldu$K)hmYf喊vladTRߪ䴋GbR,IK)J׊R-ڳwwwJƮCS`dњjFNQR*2T^rT,YJpag}hB̔63s1kSŢ_lj )L,ád~,./ͅɧW3]k2iV#Wܦb, .Rt,$fiaYiY&Jf }+, )dYRJRJRY ܻ&Ƌ3ij:w.ަCNl,dK)Qߴ[Z;I0RMTaaJR3Dj:ReZRYe,E2YaJJRJIH;W.>Rgb0ڼjqu:ZLMvl=޺gJxXRJRRTZ,$,—S wnL #;8RLdj6ѽgZ]ZGqΩ\ %D R7FR)LʎɹMb^:T%)h{eUUMVtKZ/R)NK-F$RRIQQQQI;f YeE*$œT%0T{SҲUUQH*6Ot6ZlqraK$Y-4sfWw̳Y,K)xJRJDG}Qu/Z)i2]Rv^4:ZFbڦYCDKb̖h”ѯ9|fŖ$,٩eS [6I/C\4Z֥wxn+V{jݭi8q1w.FC#ys֫JCvEv8:>^sozNCpփl_En#`lj)3|υt~Fƫ{Foɒjvܳ,3dOlnIO tnt7.d}˴Tm*)fxY)glYQ]xlSYyT,I)wfYdN]uRd8ÒL&.4RMwl;Y,JF-"8:6i4SuǕgb:U.,%H*.QK,EE.3R-$YJTҺ8)JYd-TZ*E)I)ФFۙ2]LYHFmRE֋F%)e,–s00Sg{ jlaQMT]̴*F,H e9JB53RJR%4Yh–]NfZLх)KL.uw2]F8.ѓ&jPTeRIhHWaQCU4xjɛ5y;+&hKIQR0TI5o]gRZ,)HʓUYh’Y%$Z$)JRJI%hu׏e,I,KB.Y#uEiv";YQԴ|fff*0YJfXΪ T]JRab- )eo]I-1쳱ֳ'SյZ83;]me*7e)ggm]3SYl"jo$Z,Yk8ƬY)W;]ħCmxL:ٳqO/鿨Ia^HelgTRR!=g~-6qmoVͩ{-nkmY:FOu>WƳd4]O]s8j8ERbva'3&nBhX&YI,84dҕ,Fu٪:yl]JQuxd.^6F]OFJjpaֻb7ԟȻG3y$XoaeEF4T+6#b*&RI5hˤT6wJf޲Ssk )ҳEYRH52TdiE66jĊR ^0r;:CqY꜔ERζQfL%r^9K'̖SeG[&Y-"IQw%Kg:ˮ"YO IKv$wžEueѷjYIJ';{j}[3boi$}GH[TlTUԺ%%U*W}^O}[iOU[N?CYO}|3f6̻7ħ5d>%Rh6Fں)ldhS;ћG::IK>eqfE3TdʒYKtT)Iy\ɢ_N3},UUwE򣝱u$þ';&]lx~;[^)Y7,>,j^ER:։YQRMbkPKE3ahaedɛ5R˵˺.0SF{6ɛ5{kk-w75qi#G4nt )Ygyi#v.%d,JI%ڵrs2MlNblxW]Rw*$s76:T̲;i&Yw<;Vs0ɔa®سu-JDȻkR55d﵍0f&LٰY(TNlF`R.K%Z.veTTJwZ$BʑJIJT}*ZE.)ҩ"qf]K5E׎mKS%7;#s6\jцIJT)LKʔe0edͪ2c72ƭ$h[M6R )KśU7Z0)c )K,Q,j5wݯ6סumj}2lL۟3{Ψw{ex C5y;5Ckw9ܸ0 0 /OwaX]d:wH[#\gj;r~r?{LSF;9E'ʻb666k?#$UGmef#jQrR6.2Ye-5aF0,dػ6avk")f{ehyRLE6egB*Jj>4pjEgFi;qv)fpSۙ_} M-"ldѷ $بͣV IJINlRhхޥRSUU.hjFL0gj,D vLE,YQū猛ٶ7K*T}Lw-_%sz5 rQ"j9Q=#'r^5I{E0w2{OU3t2}硵kshqd<0xYY k)Ol]t] 2daL%YR06YF#%RtaKYhU,u.ScFKR·c},.du0$L600͕RJRd-*9,hх\޲fhh{wSjѵKg2IJae04.)7(OrpڥڽI_Yt)fu0đ7Z Ë%-#S ]&SdrnY4Z>U,V)eGv7JT/ŗ .aK-TTT.]v0ܥ00IkZ֐YKE5d%£gjћf= TQM-"$Ud.,w&LeGB[ϱQx;2SC~I&HRU;˹FY%.7Z)]uYͱ̦qvRʊS +$a͊]xS̰3nWl_T׫c Jbhەyػ E$heKu='Ѣfl60ɱ[HU*)n5S p4dњ-*JLR·.U;E/9Z4y#l{M,Rs)J.5Iwbv>e ˩JsR̙I{6G[c|s4aj?3c 't|.qxhc]:?]S{Ӓ-Q>}\-ޅJTg;]򛗎G^?]<OYNfK)гgTɹz|3j{k>fm] gB}^6LbR͆l0bRoSE)*)%$زKزTRck XIdɺ7.hKIs EbIe&лgKի!Gڴt)Mu:YvަfWY%*dTTY%$u3񢄙,ܒK)NfK,ܥ,Xֲ!gHڻU0Ye6hahM˲]%)%)':TqTY.ڳ7zsR}tsI2:T s8^0f-&Qe29Z}uz7UUu94u3Y%)K8'YlɒL^2YtFJf5YKEh1vUB#k%19))6}9FEZE)&Ŗu^KdZ ɲbfSlTjMZF<]YeYy$fYwꊊI]K:ٮoI6lps79vʑKe.ڥ)ܯ+{EfMVR˷G05lxn76>Vtoa[O<)f?oz)#y_C~Tu9+f R$| 6o|ko_knǤʻ_dҙ=c C{yѫdY{pY4aIK]uhlfd SlYJSrf# FF#FO޳4zE)J6YaxJ,"]K2SW'cj2]s7FllYM̗]x]y}RV^9RlWxtY&)e)e$⤒YJSË TZ)&LYJRRJS ZUU!#vJ:]fl:bIM_yٵW6t)edLte/K)HHlm2 7;X^6jh}?+Zʦ*1/IIbε7)-n_JRw){(¨̓,ؼn^,['j̓()f$]Ѻ/%[EIseYHv*F )ҦMKEEY]R4RUUeI'M EJ[e"3]w(.w᪭UeR E*E8KIi,Be1Zd]RlQJ)JhJ]vLꏅDt=G[' s ]LUp3 %*,]u/Igɬa)#Hd֌a})bS82j65z5x~׺[]j^)%oi7B쟑UWqluEU=w=V~Fe].heSս4b}h_{N<#UUR$lxSq 7|=vt-CP~gW]{#uGs{:&.+cjv)f՚;l~7&YūmYO[Z)um㥽fJd$NKY,gjYvn+y]x"afR;n^,ܻ6XaKGK. ߩOKYں]hÝdҢNJnTb%ѤRRGRKTj/xxӞ/{I$-L70ͅdN+FjH774nh9[R묺[lQ$T~NnCVRpbr_38+XƮ2xoR/{cYQuUUYMpRfYu]%Ekn]wS fձnHձxM;gVk(JɈd{%UۜkǝQv5TYJu0nSQnSU$Յ/YuԥENkTS6*6*Y5%k0$EE)QK6.RQH,LkIVTPmhb2IJTx׎O56-hYQ̔K0$y0()RѽL5Rͩ/S%]HaJYfKř$e,TxLfᨺHi$nfͣ&kI,—F70ڿqwWN70ؓ_~CG:.,ܮt,u9ߪϡ)OYWx.g;˿pllv0aNs݋>mmf,\{idqUcI#mh'98?#:Y>>W]hYŝF{cqq{MW.^,:c&Ě,kNJ5wfm[$Ye]REG)#$=wuڤ6ȥEE.)RS8YvJ—fq d3IvK͑?7664hFNeF%,޲KɆ$HuoS5HԒˬU,غuD(YeEFmW]LS ÊPGL.YQf2f2dv֎-5=UTW*^/t Skg S0ʕJ;n$YGYgTu=&m IDT*)8hZ0fEHj0 )I,57f t,Nh)ME]%"]eG͒UJI:8wdTZ,)%. Z/v,=:xxQJlZhRJ)REY-u^*9,j dvQ6ƍw]%)%f,s9ͫY<56hcV"fl.js?#kkv mص Cx;Fܴ1ھ+w?'cWCd>|NLR"|M|nuZ58.ձfm6?MrZ5I ͒849^4ps80.,hGk80a%ܷ6ܘnl)xTYJmeRTSYe.sk,tZmY.I0R%.)^Hv:Y0YFQR)O'޳ IT]iJ]LR”¤R,ܩs:،(,Y)uRѹg&dYܣ"$ڲԓ5.Yԩћu,a&guz͂$KF$hަZ2YܧeN 8)gSs 5]w2R04Yi%TGJ)&s*46R̤wU]YfjZGTSWqu77FYY%6q5g4z8Ȧxݮu=)wSc$ѣDzn.f|]e*a(na TZE)f,HOUh:ƍ_gsw6>F壃{pnX ٸ0áeli>qvLfˤ)w2E0,u5fnxZ,M B,س6je%o$£ ׋e/ڬi1Zѱv97SfKE)gܺ 0TYehڥ‘,FI.j}4&KV]eh뤧JϥblQQ#dah.֫ejdU;Y$\4̈YM#U6E$sū%2Z,;[Y4>u84MJjaJ"ao2nj2v]s(ew:gRInfTYK9$mΖ)JȤIҥ YQi0ѱOQL9Z75noɔnSs3SVJIJe6Fy= I̗TREԦGSc&jRsYHQQ&F*9ԒZ2RG6L2IL)gٺ=Ov5h_uͯs{Yw/$o^)鶸FoiOW#E$|*{畣kE;-Rf. .ܻÄlṚ0X3S h5)N E5}J~'mK; )hਿeREKGRZ*);Vd^6a̔T}6ƭb3Rh%*QJRZ)<FJRJVi;q]dd ,EⲤI̻ 2_2Y3b3IQwJTQQuYxt,jUU$$)K,͑u,nlY'hSN9.RBJ]I>殇Gqhύmfƕp]p}MId:\^%97GIMURK$ܥE"v=%E Y|\Ւ䒒a]djRE̘|Nº7/Z]%yQR+MFgVQ뮨TzjaZ0)B,RNHRܦJTtGd$]%YNuGEe)Q2̣0GTգTڧr ;Y8z벍7, ֌R,0*$T]uͬdpRZ/$0ʒ.͵e6jwlhKJaԼn3dLEۗdL,ձ{LޓsN ۛ׋6mql]&F0fl$-SIk/3Skk{6ѓvjrlv6662zˤjK?eۣ'HM"eަdtPfԍͫE*>#Lt6՛c)iE^Z,*.')L$dxɅEE 0Y%؍#5&#%a>3ħd6kdf.eEGVINB'ֳEcijv:E)s/IJj̔DId*8.)%JRi/..˴hDž]M)PLf5YMdhJYh]eFK.f>S&i0g]0Bfe)$ś HIhѭdUJÃ.ݥRNN ':̾Գ5Y%*HQtECsqh4R|(pYhQJY fYMhޥٶ-kFaxaQʌ؉0UUV2Z83)JnuRJv<,FLMhZ)JIvFaQΦh,E٬ɇBad&n]fYezdػ6ʌ1 KSd,***Nufd۝G}hlF3]RTL)%3df0 jm6mg5qh)Jl[2Sj̛FFMhﶲjիGyW2Gfzoe>C?_Kf۹׶]đ_-o6ͳm=`ݻVڼvŻn]cZ7ṷ` 3m}1vN1}QvMt2WM=862YvY]Id׎,z2]/mlmu0b9F՗dšvl68♵tkl\˷3efvT’R 5fw35)N ,IeEZ9u60fLu,ܺ&js9f5h*6F#Yh謁}hѣ%GBavkg}J"RZ)iSUYR9*92rXh0UERDY^(dFej2HS&lR0̶E2Y2]8хS&]JIOUXT^,,]ds.mo8M5fɓhѽk$[s8FٸRs$N,h0͔hSGuԦqe)Orys-t,YQwj<+Ed&aI)Qe)x’]iuZ)K5^7*1rZ,*sœ\VTnahf#5h$js(3Yf7eYJTT]dYEZ-ڱىᳩ{ͭ lYFqM#6ld3YJYQx&kS&Kh:2p(L9m[޳YѪ1ɇe?mձ4lj y# h͛W''#kco{~PjgL~oԸH9G)A?蚧Gt޼V;Ųh4)^Y{nͽWɈ”ɒKRުj*l:t3[mSb)%S9Wd}Q[^,-ekK\v4jL3Z0Ne:ZţUwfjdVJIh^.HYhسjYed6Qqhbb)G&bHdavFXSX*:WL)NfU..f]O͒,r)x%]tKah;T‡35׊zKEG2Ş%.:T xh׉ꌚ)ђn^3Yhʋ$̔loddbjvL/}Ś2Ye5͓6QاsrϼIwSUEԒhVj]u)̘Z8.%;ʌ7} E-*)S5ET%rRdњu,S Sbks,ɆRSUѪ퍮L׍e<\{4hީڦ.K)eWL)R)QhYeIQi%Is;E;t]u)%S(ܼe)í.8;ګjJZL},Vamw*HKrcc~fn:3w)%QSOyh_[rqy3ħw>Y|/#gޫ{Q~OYV+S .MwṂ4j7GSscjlZ4w,M$63agK.Bom] T)e)JW%֋7G͛M0⦱QލHjScERRϥ.{saF#EY2HEEZE**)R)QJK)Ū)%$IJI̦֍TEFEڭjѓ Rfe75q]EZI"Fb12dњ뻛]m6 u)JT/BRS5*)I]śYՄfuԧdTYNvزs2Y.fDiv)M0 ф0LYeܥT|*]d0¢Ju5^))t5p3Xoa8(vl6IuE㩒R^3pZ2"y"u5.OUeԦk0w; )g0F'EFEjz^IJIک]u9t.]wKua1w]\s;[mv,ѫ]&4w3fnje#j븬'gC܏=Ţxf+ERihڥ)u,›ڥdj5]tSM/d;15HR¤6uսeK$IJf໋pt 6xv-bpS&wRͬR2ad<+3hLDZ0E,qhx'WKXz5tj몪+/멓=IQ*5RϾ;Mi*ʍXfхDnavGB4hɆ=̴^< $I.gKRf1RI2Rk6 0JIҳVE80¤4YwB)u2d%,–Yg٩ дܧ}{%Gһ&Ť}9Л9l:"Ηsv#re$sk?ѓ5TRd#̻뾇y';d|JY_a#kӹտ>jfIC#{>gYyd8s>ym~O&uw[tr YYeӭ8tl,]g2̛;|L3Tڳ]b2R:I)KE▊fMR]?$ߕ89_F.]dqefZ.(TRK"#6L1FN"G3lmqfRFRF))'&2DzXѫ%R$]x%Գ¡vţƦJxUGQfEPy3^*u)hуSWh FJlujRww2˵I]N dXđln]bEhGr,zaK85sL\s)85b5ztxyHw꿍o{ZggQv)o~w'Zђ8_a$'@靓tt)4mތmZ7Sbub]ͬxlnnt9=NypTl]MHju0޲J,ђ-tIݒ6IccU}4\T/hɖ3sdhRqZ3lfܲ]vFJRRsE.%2EE.YO64fYeFJomhuaC$뮥.g9plawKijR57**)L)I5Yi1N n^,)LI*,b86QNxbTK:Tɓh4f]h|nv$dJ|ֺ:T 42wySSֲִչu:ܞfLUJunaث/7)ΨSKIuGySgCU>%NiהfdkTZ銌4gSH.˩ue*+HNaMʊRL۱&I*JxYJfFtG:3auڦ2ZHشm9 єYQs62dyu6$YeFqL3b.K606;]4rSzMTEx97gI.:SnM:74mo~Hѫ vSa꽈7qbMΗ&h޳ *)%ԑɺ7>v޼s4aߒ4~9)6l8$yI3trrc&Vhi.mb3d/Tf,RՅ,]|;]vdžz ̎g>s/ ksoRڳbRYJTIi,^R/ur*)hMrrfa&jJz(ܦV)yL]uYKyZ-YI,es\,I3raҧtػGQwd~kZmGJ)0M9ʎɝ/7.E󟩪MhRΨͱfql˜IK,ĥ2^*)ak3]L9Rdͳ{.4fC/Si.Muҙ:Wi]&%噤)x񩱔Y<2G7֎Nu7;vš3a&嚹ٰ87$›d))&Mڵv~e'VT2s9724wFn/H޲'s&r;ﶷ>8"S{Hwh:͒8/ytUTMp[ Ѿ_#nz>jwٽN#?#iYuGԲ0:wSU*E)ܗYaKehjF#Z0)%)w^$Q%IpngtT5dR6*4]u2u}yJSj.G%umT)&m]t[ Z7aQYKFYf˜K*0w})i*@Ie$ɶ)5IJ^2Y7K':[#fLwֺJR *:M c{{FT}4nmN;#jKQ-KQس^0b:]Ε|jmpk:IڨKQyՒ+8:̛U.Nd^e Rt,^6.0S%YQJRK,Y:72x- d$*)iʒ͓i](&uQIyY4bF֊RS 9߁M,/6b,™2b7/-),4Sagھ;Y4Z]nL({qhmwk~Je~ۙ|MV]~7v^Ǒu>w}Iw{ sRGt۪zMl񫺻DtEq<{|.OƯj]:GSv4;Eߴ5zYի{k=wJx&=rErt :c'2>V}g]vYMaJd6x\NvڥEuY%,RJ˳Z,uYi# %0Փs7j1)K)RW,RJSckO&fkck{()K]F2rh¢JwԒԲRE)IQ0f,[*I&cu2dţdËjYw԰D/[֑dTTe$$m]E6,vJglNJkZzmhb7il,VVʴvXoj'},ɹ8BKq*ѪsS bsU:.3REaR˪.NRG%&J^t,y {OM׊7IybGldUUnL7|V~G$_y2G97=Z_2|oOdwԴjS&oy{Ywv\[5֒=9#cs 69[YE"IN)8CdYw)6#(Sf"N75ae63R͏iMy3$)jbދc5}m,V]2sTRùjﳍYKuFkatag֊4Z.FQh2]e*L$5& 6KZLR[UJRTTUI7):"M3YM)!%I}vO:U4R ԧ찳 3wYHɜfC tw4ehNvqm774~ bq6LN.dUETWcȭj:ڹٯk TM^:2bvFɶRI:^b>:[lf:֍y#񳚼\ˮɄIE(YJ)hިRNISL0Z*.N ZEGyxw3즯;VMz,ooYL*74~6I7IuYN8dgY2E7w8,ygg:n&"S]x;Y.b76/)v6,ѱE)M:$޼%3G3O2YF⌝N.d6a9߼hGq6< u<.$m?]WCw~'_${Ss0p~=yps?.y5ӵpg$}RFCл534fњg'ί9Y-ͤjnQfs,/+zR;] crM#&֊j4Z1RJTFxUaJg팈pY5Tx~M[b웗Ya)[ S dZ2R˩e$$"TTIxr TYJʎy[LE%IJ#Ula70IA$ѫcbYJ],,h0KF+#jRRY%'UUt$)ggEI#5m-']v-&rM[fFW߇1j6bK~nZIdTYS&JG$Twtat]&*T0IklW$IZ5.j%E)I)Ƭ6Y˃(VYOYڳjE)xe-5DI$ dŕYeF֋^)I+{xTYSɆ)M/Sδ͇z:"ĔҤyfܧJ٬ř4S'$ROMfhk x͏YWZ3wrjsձ[X]$}mML{m=Fo]-~6^ KW#*-8Qnu~7S #?us?IS)}I=w0B61| I#EZtu,Y'J0⻌t5R]CFmGBh73)JRF,Y=QܴTl| ٶ60,7:/fRLD%5a&:”3S5]ű&"5afQnjQ&NL8DEF, ZH)#jO{V'U{FƬ8mS6ƯOeFsnlSE)c{/ɵkj$me,md~ # ˵a3nIM+5*axhJTgdͤdUUTdчO񛫂cV,)QfDL)uԲ6fk,%튎Jĕ& $[/Ýe2d3^*D93qm2hY$ In5d'֩hh.,E)eHmTsۜ:_lo}{>u ;]eSUUW#r]H2GS Ldb}-]JhגL4RRS%IR)I)e-T{ ;U.f1LI$SK9ԧc4Reؙ2]i GJSRKI$rlh\vxcsU,'3hQ67:-<"u]'a(w .QeIj)xג,f]IJR)I)QMWrRMOcY4EYwfɬ:67ae^,TzL7&mY=#nVĚ0>z{0E,FfE.LRʉZ,U2],ˮÙgɣ%My2bGI>bEM# ]3T|-RbThEŕ]X)QL5TS E/I># x$ś$3$S's6DlPBfDI%6;#.)hM2w)LvI0U.Ԩڳcd͈xܥ /]e,Yu4Rʋ)Jj'%,xR)QeJII8u*.%]hŧHde;"-KŖYڲL.dg%S'CFcjͭe{5׌2fZ6G;h6IfY)Lxٺ.t_лG;ݍv9GS7LَI8)I-II,ae85IR:Z,iu0SRJ)e6FJ[U*2˵KR%$eY%%R)Q90&L]Ne.޲d,Kh,&Ns0s,5 czњ~Ӌj6, ŽhqSfyks&m>K*YxtuSWDߒ4|ϙURCK3gYCy^>'9Lw4ROK;m4mN .=3Wa͵I5SFToSl&M3,.R%YuYR)I.W&zUUfѹK)f"S=7LY%I%EYK)e$ih*H,E)QK"IeFK2k$aC{c G362]K205)R]Q>j]\^8=U8F# RK$)&n22 ?#Fk{2qwٲjU&,޳γ TYfLKED)d_ .YeՅʧ̩RVGe)QER묨Jb.fٱofɄH9^0Yv}ٮxK2#rϝ6LkmqK]Z9>Gv:66)Φ74|q=]뽧}BhOi_No{ IዳRF?C=WzGl9j4hɛVm"KQ.u53YzM̗z☊IhK)QI,ڼh 2}3SȳK4dj{m4|. ˶:+$>,)I*)JZER{물YM~|ȒʑJR̺K6]Ҥ&8e]xw1]%llflpYШjSв[ڮɛ BʊBS dMe Z876jTY)tpt̲LS6865s68 7.,]FJx^a%Hިw# jjՖRNfY%)%E5YJ]Jյz:-TfMW4Ih*]uåIfkFƧ&/voOֿ.<˸5acS&Ou2s6殧_#zmQ?3o,ws<G"OQy7u?ZH>7}mC{K2]%Wu0߅>2'W{O]zm|{#G>WzOa>W:dEOHd]]L=բږdب3}REG4fmu6’]]*avYe,*,M63t3}L6-FkHMZ4Ye5Z7/R,JIJYQNČdRYQҲ2^H8.Ylob4IQ驣ϞTrYb$){&ޣͻbϵ)N;L:&S)df$FjlR6qs;SU93])E$5RzIe)QQDVZ-&0b:̻%>e.L1Lf05얊jx&[#&fju6=Dt5psh';V94mj7r];Yf>>VM_ bnl]{yO„ZGy=ps$;c7{n-L^Wڳ5s?;G.{h/ep| 86S 2aI0dfK0ѣ|MYEI]5m]]h[Ǧ{̣"h2fLE.$ڨ%GD*.4-$ѽtRt*B,3^7dɜ]; .e䓝fȼYeYsk7EE9L)L91lTuSmmRS[]jRFKܻ ])e)I*EFK])QyƖlah1eK*_ jR̳5SbK*)Qf=3s6;ˬ4Yئ.i]5]lj 0mfܜ_dc]W85|nFFG$O]=lj>_Wr<|Yd;]ߌe=͔|_4b9:V{K4,Նk l]򴑪$SFI0u)L׌Y]˭#QQQ&JTll]uR̦l,),K6)&jYxHfJb=NTTR$C7Z8)OR)JY76:Vf**%ojOaht94w? 7$$TRTRavYeҦk;bG%,Òuue,زњ/"㴫Qe)Rq _ 3Rg0Hх)fFy#bMYw:͌ERDN,ھ.|?Ns4]5z[m[}C9Vqfɽ5j[7=Ww#a"<ϵٺ+f_w|$_3^hGKd4rYʥ]&JwS{%Ǵc *>UE$3hOe6]0ּYE2Ytd)d͊ILO62^ER>b1lRJrmz2I fÙԳ ܗE>%YJUHdeNfFc|ƫ4]NL83|t7-4lSQL0]L(jat:͓5ݪyؙ8*6Ou&Moj?i;܏pTCw|m)W;4rq?{ɣ7YvŞ1Ǹ6Y905+fFݏ+nuEE)M7YM]4ovɜjFwl}+,h$JBWuEuۖYu$C5EGgj$bG\|Xb׏ĻG}Ź-Z)Gcc67)e2RNJIZ;hj˩uپVG-Y^,)QI*)PQdcc6#s _Ds<0.]h3s]LF՚floHZ4vFs5d6=Gqu0=w3V'Ls:E,s=I3~̐7?^Hx_3Y>~uI7._8l2]u?Q6Oh ѬSD)OfхDs=m͓R)aQ%Ix-Nvnu٪.*4jrS Uх/a%2a;Y,qNk';kFlmaRJY%lYuY1hRTTRK-EE)IгYj&_%,R̖{FZ6Ն|.n GCkcW9,a.;GSsqqyG2Iܻ&oCF<sIPoVoU?9'sy=_kag=E.fއ3msձՓwdSfME)esz̞HVjz.%*)D Ȳ{6Z2R,%/$M–wZau ]JQJuUfRg3]S "qG0]u,0HGRTS;Ve)QI-Y;Xaoftњħj*)Lfnqz_]{M^יU2n]f歊nqS{YmYh뷶0nfZܺE$SUE*0hXDQ'ZRhյáP^:Ն3cpSj67TLEE)Pdp^>fwnS 3RSkvlG7:h{NKK$s^,SlYeG49Th^fYwlZFMVlaNQJSc&7>SbRFmau5dofhe{mUl|OY'ݮ]5lSzHv)i#سQ?{o~HzoUqn}KDOuyfl0ٰd^&Syvɵ}b)vW6ƏqK+|]滙'ckzWlSE)MWw5l{-ɹdTXYL v#krs0Y(RTTMYEaQR3RTpmd”%IsFN 6F&K-I)Jt#8ZFIK)N08h$6w%T›RQeFm2RGKsFL)JSbafŘRJ"ukaܻ6ֱ{,سbhx-YchյJlf qw6ɜaإ#y-G'Sd޲96hvkjpvrt6:c}a~5t}:$}n$|.'{Olws;qqI.kڳy].Nfb89ԻjI4a(>6)Լml)K3a K3fئEA񛋃c{ FqL5 FǰȚXS%,*Fl.rf$03opfOvqRaxjG%d(MX]'K6M*)&J]u,L0u$$ةTI~LEIWjvs812hozQ sƬ.oi''sWq63b6Gfk?"ΗC'K3rmaf;&&ǤqtvǸwΖ$sEG2$3S'nf{5|oK^DdGw._<V#m]իxWjڦqh7 ζMl۞k7#]N -dvltlx{8>Ƴks{r+;.SJ>'SMK;K/q6]ﺜI?~£AIosGk<^HXi$zu:7>6>w;,:nY'Փd b7mpmo]hWm ixRN 80i]avN TYK0 Ǹԥ$fj*,RJIVIuE(t)hfq~rI3Y뛣r̢dJRKD, ˲hY%,KEp75a˺9)M$䨨\-RZ웚UVYZ0g0g%.䤖TPIYü$RY.TGeTYܳ&N#j$S27hmIړf~fM;ۛnYœkUt)HvG [T$s2zFGD~ݲFRG;m;7}Yx>e6=qutܚ/pCG3tfN&JWS&l6R>Flܜ⳱wM8L,ܴonw97lj񶵍:ۗyZ,KMSK)JN+)PvK)%Ɗ^)J.sIt*)e0+ )śUFOgFLޞ˻{2vF4 E:1Id(,% 09ќd*|u:^c&Qw]s0]2nVtIat?kdlu0W~vNMٮ̻]-:-Z>&j#tMg&LnN XvGGJu7C aN#~0 cG|/$N$|N^'r>76=&rE=Y#HI:}Gڳd7wcz$:vCWKETT˩D]&Ֆd͹wSlSbtGK 2YLX6uƏVܖۖR얉4Tb.՚NzG[F0JIuRヲm986՗RkV)U0vzʑSy$IRNT}sQɹK>W&oHvu&"&3rcH$f3w޺{FM=#kƧ}+7#M>m߸xdsWt4zF$ W3Gչw<˴wsW9.ձWqmlj8I3޳8)S82]JSH䍋=֬ު8F=n SEE$]kFI+Hغ=0s)-bEEHğ%,Y^0ɓ']K3Z)NB}m/$RME$\̘pqY'Xf:kkG8)9f"RRNS&L3Txj66S|kZ ޛbL5ixrdlfѫt6lOe֒<;OzCx z$=8~jyzRG['yE֎#Ʋ< ^uId.ŘzUU)ejL8mTRby^d;c{7St}.M9Y='yHسX$ms,aOU4 l2t6f͈gjj͚ITIY.ڥw<-xڽJyM.4m6|FPG;>=yYTn)9]i#fϹY2:Ee*)f pi#{%6[pYe)͆RE,޻Uz,5sIH[>}7)gkY$hUϡeڿu3)vlj3^$mdͱ]SF#vL݊s4aKլag26E"YS%696XYeܒ/]/ܻj+oaLF|aRE=n"pygzͯ3&K+uI6;6jSdJIRE)Yړ-dyOdrS^'2Lٶ>uޜH}M\[ٳaz6Hs{O<"uu6r?7lꍎձ8d:NZL:qyU${nfnLcsHgޓk7KfՇopY;k|G$ZH_9kmY/]i"xVkv}MZQ$~fl6VmZFGC5mzYHdls<6GcN"d.LԳv$v[7< :v#'̦?L$St^H֧[L$f3f'Ifѣm]fmrH͆n#bǑGC-$lhdW8=&Mefm3pt4lYOs1f&bG_^i#tLpw4y|M'#k"6GG$yLi#ȴ]y#tS]e=9#skmbHɵje#V$pi$^2dJo]u.ɱgK)6mj$Z,RժΕڹI,o.fy3s{rʌ.gClff{ߪسkUV&k74wݮgtZN-׉-Z8=Glj'"x$.fM3ޛ6FHGc79ndH;z<SF#|]2FRFEY:䌢 ͽh;޻Ym޳7jf87674] 8.#s,4qhc7cF'R빟eMu8=gI»QzNǮsOwGx}sozn-CsQe/RH]GI"9w6ޛ)#ksc54))z,2 /Gggck|EԥE,hdV$穀lY]{lm 3)I,&NfQvM"jK83ySVL3xw,qjm3掖+y\[VW"3x:ɹv8FnDmhIeFNMYfr63j[kcF"إܗYhdQv.6dx*0ssGK}|/+lw<.kNwpMw #include #include #include "xvid.h" /* comes with XviD */ #define ARG_FRAMERATE 25 #define ARG_BITRATE 900 int XDIM=0; int YDIM=0; // will be set when reading first image int filenr = 0; int save_m4v_flag = 0; // save MPEG4-bytestream? int save_dec_flag = 0; // save decompressed bytestream? char filepath[256] = "./"; // path where to save output void *enchandle = NULL; void *dechandle = NULL; /*********************************************************************/ /* Routines for file input/output, nothing specific to XviD */ /*********************************************************************/ int read_pgmheader(FILE* handle) { int bytes,xsize,ysize,depth; char dummy[2]; bytes = fread(dummy,1,2,handle); if ( (bytes < 2) || (dummy[0] != 'P') || (dummy[1] != '5' )) return 1; fscanf(handle,"%d %d %d",&xsize,&ysize,&depth); if ( (xsize > 1440) || (ysize > 2880 ) || (depth != 255) ) { fprintf(stderr,"%d %d %d\n",XDIM,YDIM,depth); return 2; } if ( (XDIM==0) || (YDIM==0) ) { XDIM=xsize; YDIM=ysize; } return 0; } int read_pgmdata(FILE* handle, unsigned char *image) { int i; char dummy; unsigned char* buff1_ptr2 = image + XDIM*YDIM; unsigned char* buff1_ptr3 = image + XDIM*YDIM + XDIM/2*YDIM/2; fread(image,XDIM,YDIM,stdin); for (i=0;i xframe.intra = -1; // let the codec decide between I-frame (1) and P-frame (0) xframe.quant = 0; // xframe.quant = QUANTI; // is quant != 0, use a fixed quant (and ignore bitrate) xerr = xvid_encore(enchandle, XVID_ENC_ENCODE, &xframe, &xstats); /* enc_result->is_key_frame = xframe.intra; enc_result->quantizer = xframe.quant; enc_result->total_bits = xframe.length * 8; enc_result->motion_bits = xstats.hlength * 8; enc_result->texture_bits = enc_result->total_bits - enc_result->motion_bits; */ /* This is statictical data, e.g. for 2-pass. If you are not interested in any of this, you can use NULL instead of &xstats */ *streamlength = xframe.length; return xerr; } /*********************************************************************/ /* Routines for decoding: init encoder, frame step, release encoder */ /*********************************************************************/ int dec_init() { int xerr; XVID_INIT_PARAM xinit; XVID_DEC_PARAM xparam; xinit.cpu_flags = 0; xvid_init(NULL, 0, &xinit, NULL); xparam.width = XDIM; xparam.height = YDIM; xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL); dechandle = xparam.handle; return xerr; } int dec_main(unsigned char *m4v_buffer, unsigned char *rgb_buffer, int m4v_size) { int xerr; XVID_DEC_FRAME xframe; xframe.bitstream = m4v_buffer; xframe.length = m4v_size; xframe.image = rgb_buffer; xframe.stride = XDIM; xframe.colorspace = XVID_CSP_RGB24; // XVID_CSP_USER is fastest (no memcopy involved) /* xframe.colorspace = XVID_CSP_NULL; // use this if you want to skip a frame (no output) */ xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, NULL); return xerr; } int dec_stop() { int xerr; xerr = xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL); return xerr; } /*********************************************************************/ /* Main program */ /*********************************************************************/ int main() { unsigned char *divx_buffer = NULL; unsigned char *yuv_buffer = NULL; unsigned char *rgb_buffer = NULL; int status; int frame_size; int m4v_size; char filename[256]; FILE *filehandle; /* read YUV in pgm format from stdin */ if (read_pgmheader(stdin)) { printf("Wrong input format, I want YUV encapsulated in PGM\n"); return 0; } /* now we know the sizes, so allocate memory */ yuv_buffer = (unsigned char *) malloc(XDIM*YDIM); if (!yuv_buffer) goto free_all_memory; // goto is one of the most underestimated instructions in C !!! divx_buffer = (unsigned char *) malloc(XDIM*YDIM*2); // this should really be enough! if (!divx_buffer) goto free_all_memory; // actually, every program should contain at least one goto YDIM = YDIM*2/3; // PGM is YUV 4:2:0 format, so real image height is *2/3 of PGM picture rgb_buffer = (unsigned char *) malloc(XDIM*YDIM*4); if (!rgb_buffer) goto free_all_memory; // but the more, the better! /*********************************************************************/ /* DIVX PART Start */ /*********************************************************************/ status = enc_init(); // if (status) printf("Encore INIT return %d, handle=%lx\n", status, enchandle); status = dec_init(); // if (status) printf("Decore INIT return %d\n", status); /*********************************************************************/ /* Main loop */ /*********************************************************************/ do { status = read_pgmdata(stdin, yuv_buffer); // read PGM data (YUV-format) if (status) { fprintf(stderr, "Couldn't read PGM body: %d\n", status); /* this should not happen */ continue; } /*********************************************************************/ /* encode and decode this frame */ /*********************************************************************/ status = enc_main(yuv_buffer, divx_buffer, &m4v_size); printf("Frame %5d: encore-ENCODE status %d, m4v-stream length=%7d bytes\n", filenr, status, m4v_size); if (save_m4v_flag) { sprintf(filename, "%sframe%05d.m4v", filepath, filenr); filehandle = fopen(filename, "wb"); fwrite(divx_buffer, m4v_size, 1, filehandle); fclose(filehandle); } status = dec_main(divx_buffer, rgb_buffer, m4v_size); if (status) printf("Frame %5d: decore status %d\n",status); if (save_dec_flag) { sprintf(filename, "%sdec%05d.ppm", filepath, filenr); filehandle=fopen(filename,"wb"); if (filehandle) { fprintf(filehandle,"P6\n"); // rgb24 in PPM format fprintf(filehandle,"%d %d 255\n",XDIM,YDIM); fwrite(rgb_buffer,XDIM,YDIM*3,filehandle); fclose(filehandle); } } filenr++; status = read_pgmheader(stdin); // if it was the last PGM, stop after it if (status) { fprintf(stderr, "Couldn't read next PGM header: %d\n", status); /* normally, just end of file */ } } while (!status); /*********************************************************************/ /* DIVX PART Stop */ /*********************************************************************/ dec_stop(); // if (status) printf("Encore RELEASE return %d\n", status); enc_stop(); // if (status) printf("Decore RELEASE return %d\n", status); free_all_memory: if (rgb_buffer) free(rgb_buffer); if (divx_buffer) free(divx_buffer); if (yuv_buffer) free(yuv_buffer); return 0; } xvid_20020412/xvidcore/examples/odivx_enc_dec.c0100644000100600001440000002561307442022613020723 0ustar michaelusers/************************************************************************** * * XVID MPEG-4 VIDEO CODEC - Example for encoding and decoding * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ /************************************************************************ * * Test routine for XviD using the OpenDivX/Divx4-API * (C) Christoph Lampert, 2002/01/19 * * A sequence of YUV pics in PGM file format is encoded and decoded * * The program is plain C and needs no libraries except for libxvidcore, * so with UN*X you simply compile by * * gcc -o odivx_enc_dec odivx_enc_dec.c -lxvidcore * * Run without parameters, then PGM input input is read from stdin. * * PGM/xvid-output is saved, if corresponding flags are set * * input data can be generated e.g. out of MPEG2 with mpeg2dec -o pgmpipe * ************************************************************************/ #include #include #include "encore2.h" #include "decore.h" /* these come with XviD */ #define ARG_FRAMERATE 25 #define ARG_BITRATE 900 int QUALITY =5; int QUANTI = 0; // used for fixed-quantizer encoding int XDIM=0; int YDIM=0; // will be set when reading first image int filenr = 0; int save_m4v_flag = 0; // save MPEG4-bytestream? int save_dec_flag = 0; // save decompressed bytestream? char filepath[256] = "."; // path where to save void *enchandle = NULL; // enchandle is a void*, written by encore const long dechandle = 0x0815; // dechandle is a unique constant!!! /*********************************************************************/ /* Routines for file input/output, nothing specific to XviD */ /*********************************************************************/ int read_pgmheader(FILE* handle) { int bytes,xsize,ysize,depth; char dummy[2]; bytes = fread(dummy,1,2,handle); if ( (bytes < 2) || (dummy[0] != 'P') || (dummy[1] != '5' )) return 1; fscanf(handle,"%d %d %d",&xsize,&ysize,&depth); if ( (xsize > 1440) || (ysize > 2880 ) || (depth != 255) ) { fprintf(stderr,"%d %d %d\n",XDIM,YDIM,depth); return 2; } if ( (XDIM==0) || (YDIM==0) ) { XDIM=xsize; YDIM=ysize; } return 0; } int read_pgmdata(FILE* handle, unsigned char *image) { int i; char dummy; unsigned char* buff1_ptr2 = image + XDIM*YDIM; unsigned char* buff1_ptr3 = image + XDIM*YDIM + XDIM/2*YDIM/2; fread(image,XDIM,YDIM,stdin); for (i=0;i dec_param.time_incr = 20; status = decore(dechandle, DEC_OPT_INIT, &dec_param, NULL); // if (status) printf("Decore INIT return %d\n", status); // We don't do any postprocessing here... /* dec_set.postproc_level = 0; status = decore(dechandle, DEC_OPT_SETPP, &dec_set, NULL); if (status) printf("Decore POSTPROC %d return %d\n", dec_set.postproc_level, status); */ return status; } int dec_main(unsigned char *m4v_buffer, unsigned char *rgb_buffer, int m4v_size) { int status; static DEC_FRAME dec_frame; static DEC_FRAME_INFO dec_frame_info; dec_frame.length = m4v_size; dec_frame.bitstream = m4v_buffer; dec_frame.bmp = rgb_buffer; dec_frame.render_flag = 1; // 0 means: skip this frame dec_frame.stride = XDIM; status = decore(dechandle, DEC_OPT_FRAME, &dec_frame, &dec_frame_info); if (status) printf("Decore Frame status %d!\n", status); return status; } int dec_stop() { int status; status = decore(dechandle, DEC_OPT_RELEASE, NULL, NULL); // if (status) printf("Decore RELEASE return %d\n", status); return status; } /*********************************************************************/ /* Main program */ /*********************************************************************/ int main() { unsigned char *divx_buffer = NULL; unsigned char *yuv_buffer = NULL; unsigned char *rgb_buffer = NULL; int status; int frame_size; int m4v_size; char filename[256]; FILE *filehandle; /* read YUV in pgm format from stdin */ if (read_pgmheader(stdin)) { printf("Wrong input format, I want YUV encapsulated in PGM\n"); return 0; } /* now we know the sizes, so allocate memory */ yuv_buffer = (unsigned char *) malloc(XDIM*YDIM); if (!yuv_buffer) goto free_all_memory; // goto is one of the most underestimated instructions in C !!! divx_buffer = (unsigned char *) malloc(XDIM*YDIM*2); // this should really be enough! if (!divx_buffer) goto free_all_memory; // actually, every program should contain a goto YDIM = YDIM*2/3; // PGM is YUV 4:2:0 format, so height is *3/2 too much rgb_buffer = (unsigned char *) malloc(XDIM*YDIM*4); if (!rgb_buffer) goto free_all_memory; // the more, the better! /*********************************************************************/ /* DIVX PART Start */ /*********************************************************************/ status = enc_init(); // if (status) printf("Encore INIT return %d, handle=%lx\n", status, enchandle); status = dec_init(); // if (status) printf("Decore INIT return %d\n", status); /*********************************************************************/ /* Main loop */ /*********************************************************************/ do { status = read_pgmdata(stdin, yuv_buffer); // read PGM data (YUV-format) if (status) { fprintf(stderr, "PGM-Data-Error: %d\n", status); /* this should not happen */ continue; } /*********************************************************************/ /* encode and decode this frame */ /*********************************************************************/ status = enc_main(yuv_buffer, divx_buffer, &m4v_size); printf("Frame %5d: encore-ENCODE status %d, m4v-stream length=%7d bytes\n", filenr, status, m4v_size); if (save_m4v_flag) { sprintf(filename, "%s/frame%05d.m4v", filepath, filenr); filehandle = fopen(filename, "wb"); fwrite(divx_buffer, m4v_size, 1, filehandle); fclose(filehandle); } status = dec_main(divx_buffer, rgb_buffer, m4v_size); if (status) printf("Frame %5d: decore status %d\n",status); if (save_dec_flag) { sprintf(filename, "%s/dec%05d.ppm", filepath, filenr); filehandle=fopen(filename,"wb"); if (filehandle) { fprintf(filehandle,"P6\n"); // rgb24 in PPM format fprintf(filehandle,"%d %d 255\n",XDIM,YDIM); fwrite(rgb_buffer,XDIM,YDIM*3,filehandle); fclose(filehandle); } } filenr++; status = read_pgmheader(stdin); // if it was the last PGM, stop after it if (status) { fprintf(stderr, "PGM-Header-Error: %d\n", status); /* normally, just end of file */ } } while (!status); /*********************************************************************/ /* DIVX PART Stop */ /*********************************************************************/ /* Stop XviD */ dec_stop(); // if (status) printf("Encore RELEASE return %d\n", status); enc_stop(); // if (status) printf("Decore RELEASE return %d\n", status); free_all_memory: if (rgb_buffer) free(rgb_buffer); if (divx_buffer) free(divx_buffer); if (yuv_buffer) free(yuv_buffer); return 0; } xvid_20020412/dshow/0040755000100600001440000000000007455522462013460 5ustar michaelusersxvid_20020412/dshow/CVS/0040755000100600001440000000000007455522462014113 5ustar michaelusersxvid_20020412/dshow/CVS/Root0100644000100600001440000000004607455522462014756 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/dshow/CVS/Repository0100644000100600001440000000000607455522462016206 0ustar michaelusersdshow xvid_20020412/dshow/CVS/Entries.Log0100644000100600001440000000001407455522462016157 0ustar michaelusersA D/src//// xvid_20020412/dshow/CVS/Entries0100644000100600001440000000034707455522462015450 0ustar michaelusers/authors.txt/1.1.1.1/Fri Mar 8 19:54:01 2002// /dshow.dsp/1.1.1.1/Fri Mar 8 19:54:01 2002// /dshow.dsw/1.1.1.1/Fri Mar 8 19:54:01 2002// /gpl.txt/1.1.1.1/Fri Mar 8 19:54:02 2002// /todo.txt/1.1.1.1/Fri Mar 8 19:54:02 2002// D xvid_20020412/dshow/src/0040755000100600001440000000000007455522462014247 5ustar michaelusersxvid_20020412/dshow/src/CVS/0040755000100600001440000000000007455522462014702 5ustar michaelusersxvid_20020412/dshow/src/CVS/Root0100644000100600001440000000004607455522462015545 0ustar michaelusers:pserver:anonymous@cvs.xvid.org:/xvid xvid_20020412/dshow/src/CVS/Repository0100644000100600001440000000001207455522462016772 0ustar michaelusersdshow/src xvid_20020412/dshow/src/CVS/Entries0100644000100600001440000000074407455522462016240 0ustar michaelusers/CAbout.cpp/1.1.1.1/Fri Mar 8 19:54:02 2002// /CAbout.h/1.1.1.1/Fri Mar 8 19:54:02 2002// /CXvidDecoder.cpp/1.1.1.1/Fri Mar 8 19:54:03 2002// /CXvidDecoder.h/1.1.1.1/Fri Mar 8 19:54:03 2002// /IXvidDecoder.h/1.1.1.1/Fri Mar 8 19:54:03 2002// /XviD_logo.bmp/1.1.1.1/Fri Mar 8 19:54:05 2002// /resource.h/1.1.1.1/Fri Mar 8 19:54:03 2002// /xvid.ax.def/1.1.1.1/Fri Mar 8 19:54:04 2002// /xvid.ax.rc/1.1.1.1/Fri Mar 8 19:54:04 2002// /xvid.h/1.1.1.1/Fri Mar 8 19:54:04 2002// D xvid_20020412/dshow/src/xvid.ax.def0100644000100600001440000000016407442213334016275 0ustar michaelusersEXPORTS DllGetClassObject PRIVATE DllCanUnloadNow PRIVATE DllRegisterServer PRIVATE DllUnregisterServer PRIVATE xvid_20020412/dshow/src/resource.h0100644000100600001440000000147407442213333016240 0ustar michaelusers//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by xvid.ax.rc // #define VERSION_RES_MINOR_VER 0 #define VERSION_RES_BUILD 0 #define VER_DEBUG 0 #define IDS_ABOUT 1 #define VERSION_RES_MAJOR_VER 8 #define IDD_ABOUT 102 #define IDB_LOGO 103 #define VERSION_RES_LANGUAGE 0x409 #define VERSION_RES_CHARSET 1252 #define IDC_STATIC -1 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1002 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif xvid_20020412/dshow/src/IXvidDecoder.h0100644000100600001440000000044107442213333016713 0ustar michaelusers#ifndef _IXVID_H_ #define _IXVID_H_ #ifdef __cplusplus extern "C" { #endif DEFINE_GUID(IID_IXvidDecoder, 0x00000000, 0x4fef, 0x40d3, 0xb3, 0xfa, 0xe0, 0x53, 0x1b, 0x89, 0x7f, 0x98); DECLARE_INTERFACE_(IXvidDecoder, IUnknown) { }; #ifdef __cplusplus } #endif #endif /* _IXVID_H_ */xvid_20020412/dshow/src/CAbout.cpp0100644000100600001440000000110007442213332016102 0ustar michaelusers#include "CAbout.h" #include "resource.h" CUnknown * WINAPI CAbout::CreateInstance(LPUNKNOWN punk, HRESULT *phr) { CAbout * pNewObject = new CAbout(punk, phr); if (pNewObject == NULL) { *phr = E_OUTOFMEMORY; } return pNewObject; } CAbout::CAbout(LPUNKNOWN pUnk, HRESULT * phr) : CBasePropertyPage(NAME("CAbout"), pUnk, IDD_ABOUT, IDS_ABOUT) { ASSERT(phr); } CAbout::~CAbout() { } BOOL CAbout::OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return CBasePropertyPage::OnReceiveMessage(hwnd, uMsg, wParam, lParam); } xvid_20020412/dshow/src/CAbout.h0100644000100600001440000000070207442213332015556 0ustar michaelusers#ifndef _CABOUT_H_ #define _CABOUT_H_ #include DEFINE_GUID(CLSID_CABOUT, 0x00000001, 0x4fef, 0x40d3, 0xb3, 0xfa, 0xe0, 0x53, 0x1b, 0x89, 0x7f, 0x98); class CAbout : public CBasePropertyPage { public: static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT * phr); CAbout(LPUNKNOWN pUnk, HRESULT * phr); ~CAbout(); BOOL OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); }; #endif /* _CABOUT_H_ */xvid_20020412/dshow/src/CXvidDecoder.cpp0100644000100600001440000002775307442213333017257 0ustar michaelusers/* this requires the directx sdk place these paths at the top of the Tools|Options|Directories list headers: C:\DXVCSDK\include C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses libraries (optional): C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses\Release */ #include #include #include #include #if (1100 > _MSC_VER) #include #endif #include // VIDEOINFOHEADER2 #include "xvid.h" #include "IXvidDecoder.h" #include "CXvidDecoder.h" #include "CAbout.h" const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] = { { &MEDIATYPE_Video, &CLSID_XVID }, { &MEDIATYPE_Video, &CLSID_XVID_UC }, { &MEDIATYPE_Video, &CLSID_DIVX }, { &MEDIATYPE_Video, &CLSID_DIVX_UC } }; const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] = { { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL } }; const AMOVIESETUP_PIN psudPins[] = { { L"Input", // String pin name FALSE, // Is it rendered FALSE, // Is it an output FALSE, // Allowed none FALSE, // Allowed many &CLSID_NULL, // Connects to filter L"Output", // Connects to pin sizeof(sudInputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types &sudInputPinTypes[0] // The pin details }, { L"Output", // String pin name FALSE, // Is it rendered TRUE, // Is it an output FALSE, // Allowed none FALSE, // Allowed many &CLSID_NULL, // Connects to filter L"Input", // Connects to pin sizeof(sudOutputPinTypes) / sizeof(AMOVIESETUP_MEDIATYPE), // Number of types sudOutputPinTypes // The pin details } }; const AMOVIESETUP_FILTER sudXvidDecoder = { &CLSID_XVID, // Filter CLSID XVID_NAME_L, // Filter name MERIT_PREFERRED, // Its merit sizeof(psudPins) / sizeof(AMOVIESETUP_PIN), // Number of pins psudPins // Pin details }; // List of class IDs and creator functions for the class factory. This // provides the link between the OLE entry point in the DLL and an object // being created. The class factory will call the static CreateInstance CFactoryTemplate g_Templates[] = { { XVID_NAME_L, &CLSID_XVID, CXvidDecoder::CreateInstance, NULL, &sudXvidDecoder }, { XVID_NAME_L L"About", &CLSID_CABOUT, CAbout::CreateInstance } }; int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate); STDAPI DllRegisterServer() { return AMovieDllRegisterServer2( TRUE ); } STDAPI DllUnregisterServer() { return AMovieDllRegisterServer2( FALSE ); } /* create instance */ CUnknown * WINAPI CXvidDecoder::CreateInstance(LPUNKNOWN punk, HRESULT *phr) { CXvidDecoder * pNewObject = new CXvidDecoder(punk, phr); if (pNewObject == NULL) { *phr = E_OUTOFMEMORY; } return pNewObject; } /* query interfaces */ STDMETHODIMP CXvidDecoder::NonDelegatingQueryInterface(REFIID riid, void **ppv) { CheckPointer(ppv, E_POINTER); if (riid == IID_IXvidDecoder) { return GetInterface((IXvidDecoder *) this, ppv); } if (riid == IID_ISpecifyPropertyPages) { return GetInterface((ISpecifyPropertyPages *) this, ppv); } return CVideoTransformFilter::NonDelegatingQueryInterface(riid, ppv); } /* dummy decore() */ static int dummy_xvid_decore(void * handle, int opt, void * param1, void * param2) { return XVID_ERR_FAIL; } /* constructor */ #define XVID_DLL_NAME "xvid.dll" #define XVID_INIT_NAME "xvid_init" #define XVID_DECORE_NAME "xvid_decore" CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) : CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID) { DEBUG("Constructor"); ASSERT(phr); m_xvid_decore = dummy_xvid_decore; m_hdll = LoadLibrary(XVID_DLL_NAME); if (m_hdll == NULL) { DEBUG("dll load failed"); MessageBox(0, XVID_DLL_NAME " not found","Error", 0); return; } m_xvid_init = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, XVID_INIT_NAME); if (m_xvid_init == NULL) { MessageBox(0, XVID_INIT_NAME "() not found", "Error", 0); return; } m_xvid_decore = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, XVID_DECORE_NAME); if (m_xvid_decore == NULL) { MessageBox(0, XVID_DECORE_NAME "() not found", "Error", 0); return; } XVID_INIT_PARAM init; init.cpu_flags = 0; if (m_xvid_init(0, 0, &init, 0) != XVID_ERR_OK) { MessageBox(0, XVID_INIT_NAME "() failed", "Error", 0); return; } if (init.api_version < API_VERSION) { MessageBox(0, XVID_DLL_NAME " implements an older api version; update your " XVID_DLL_NAME, "Warning", 0); } else if (init.api_version > API_VERSION) { MessageBox(0, XVID_DLL_NAME " implements a newer api version; update your directshow filter", "Error", 0); return; } m_param.handle = NULL; } /* destructor */ CXvidDecoder::~CXvidDecoder() { DEBUG("Destructor"); if (m_param.handle != NULL) { m_xvid_decore(m_param.handle, XVID_DEC_DESTROY, 0, 0); m_param.handle = NULL; } if (m_hdll != NULL) { FreeLibrary(m_hdll); m_hdll = NULL; } } /* check input type */ HRESULT CXvidDecoder::CheckInputType(const CMediaType * mtIn) { DEBUG("CheckInputType"); BITMAPINFOHEADER * hdr; if (*mtIn->Type() != MEDIATYPE_Video) { return VFW_E_TYPE_NOT_ACCEPTED; } if (*mtIn->FormatType() == FORMAT_VideoInfo) { VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format(); hdr = &vih->bmiHeader; } else if (*mtIn->FormatType() == FORMAT_VideoInfo2) { VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format(); hdr = &vih2->bmiHeader; } else { return VFW_E_TYPE_NOT_ACCEPTED; } if (hdr->biHeight < 0) { DEBUG("colorspace: inverted input format not supported"); } m_param.width = hdr->biWidth; m_param.height = hdr->biHeight; switch(hdr->biCompression) { case FOURCC_XVID : // case FOURCC_DIVX : break; default : return VFW_E_TYPE_NOT_ACCEPTED; } return S_OK; } /* get list of supported output colorspaces */ HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut) { DEBUG("GetMediaType"); if (m_pInput->IsConnected() == FALSE) { return E_UNEXPECTED; } VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER)); if (vih == NULL) { return E_OUTOFMEMORY; } ZeroMemory(vih, sizeof (VIDEOINFOHEADER)); vih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); vih->bmiHeader.biWidth = m_param.width; vih->bmiHeader.biHeight = m_param.height; vih->bmiHeader.biPlanes = 1; if (iPosition < 0) { return E_INVALIDARG; } switch(iPosition) { case 0 : vih->bmiHeader.biCompression = MEDIASUBTYPE_YV12.Data1; vih->bmiHeader.biBitCount = 12; mtOut->SetSubtype(&MEDIASUBTYPE_YV12); break; case 1: vih->bmiHeader.biCompression = MEDIASUBTYPE_YUY2.Data1; vih->bmiHeader.biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_YUY2); break; case 2: vih->bmiHeader.biCompression = MEDIASUBTYPE_YVYU.Data1; vih->bmiHeader.biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_YVYU); break; case 3: vih->bmiHeader.biCompression = MEDIASUBTYPE_UYVY.Data1; vih->bmiHeader.biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_UYVY); break; case 4: vih->bmiHeader.biCompression = BI_RGB; vih->bmiHeader.biBitCount = 32; mtOut->SetSubtype(&MEDIASUBTYPE_RGB32); break; case 5: vih->bmiHeader.biCompression = BI_RGB; vih->bmiHeader.biBitCount = 24; mtOut->SetSubtype(&MEDIASUBTYPE_RGB24); break; case 6: vih->bmiHeader.biCompression = BI_RGB; vih->bmiHeader.biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_RGB555); break; case 7: vih->bmiHeader.biCompression = BI_RGB; vih->bmiHeader.biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_RGB565); break; default : return VFW_S_NO_MORE_ITEMS; } vih->bmiHeader.biSizeImage = GetBitmapSize(&vih->bmiHeader); mtOut->SetType(&MEDIATYPE_Video); mtOut->SetFormatType(&FORMAT_VideoInfo); mtOut->SetTemporalCompression(FALSE); mtOut->SetSampleSize(vih->bmiHeader.biSizeImage); return S_OK; } /* (internal function) change colorspace */ HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format) { if (subtype == MEDIASUBTYPE_YV12) { DEBUG("YV12"); m_frame.colorspace = XVID_CSP_YV12; } else if (subtype == MEDIASUBTYPE_YUY2) { DEBUG("YUY2"); m_frame.colorspace = XVID_CSP_YUY2; } else if (subtype == MEDIASUBTYPE_YVYU) { DEBUG("YVYU"); m_frame.colorspace = XVID_CSP_YVYU; } else if (subtype == MEDIASUBTYPE_UYVY) { DEBUG("UYVY"); m_frame.colorspace = XVID_CSP_UYVY; } else if (subtype == MEDIASUBTYPE_RGB32) { DEBUG("RGB32"); m_frame.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB32; } else if (subtype == MEDIASUBTYPE_RGB24) { DEBUG("RGB24"); m_frame.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB24; } else if (subtype == MEDIASUBTYPE_RGB555) { DEBUG("RGB555"); m_frame.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB555; } else if (subtype == MEDIASUBTYPE_RGB565) { DEBUG("RGB565"); m_frame.colorspace = XVID_CSP_VFLIP | XVID_CSP_RGB565; } else if (subtype == GUID_NULL) { m_frame.colorspace = XVID_CSP_NULL; } else { return S_FALSE; } if (formattype == FORMAT_VideoInfo) { VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format; m_frame.stride = vih->bmiHeader.biWidth; } else if (formattype == FORMAT_VideoInfo2) { VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format; m_frame.stride = vih2->bmiHeader.biWidth; } else { return S_FALSE; } return S_OK; } /* set output colorspace */ HRESULT CXvidDecoder::SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt) { DEBUG("SetMediaType"); if (direction == PINDIR_OUTPUT) { return ChangeColorspace(*pmt->Subtype(), *pmt->FormatType(), pmt->Format()); } return S_OK; } /* check input<->output compatiblity */ HRESULT CXvidDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut) { DEBUG("CheckTransform"); return S_OK; } /* alloc output buffer */ HRESULT CXvidDecoder::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) { DEBUG("DecideBufferSize"); HRESULT result; ALLOCATOR_PROPERTIES ppropActual; if (m_pInput->IsConnected() == FALSE) { return E_UNEXPECTED; } ppropInputRequest->cBuffers = 1; ppropInputRequest->cbBuffer = m_param.width * m_param.height * 4; // cbAlign causes problems with the resize filter */ // ppropInputRequest->cbAlign = 16; ppropInputRequest->cbPrefix = 0; result = pAlloc->SetProperties(ppropInputRequest, &ppropActual); if (result != S_OK) { return result; } if (ppropActual.cbBuffer < ppropInputRequest->cbBuffer) { return E_FAIL; } return S_OK; } /* decode frame */ HRESULT CXvidDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut) { DEBUG("Transform"); if (m_param.handle == NULL) { if (m_xvid_decore(0, XVID_DEC_CREATE, &m_param, 0) != XVID_ERR_OK) { return S_FALSE; } } AM_MEDIA_TYPE * mtOut; pOut->GetMediaType(&mtOut); if (mtOut != NULL) { HRESULT result; result = ChangeColorspace(mtOut->subtype, mtOut->formattype, mtOut->pbFormat); DeleteMediaType(mtOut); if (result != S_OK) { return result; } } if (pIn->GetPointer((BYTE**)&m_frame.bitstream) != S_OK) { return S_FALSE; } if (pOut->GetPointer((BYTE**)&m_frame.image) != S_OK) { return S_FALSE; } m_frame.length = pIn->GetSize(); if (pIn->IsPreroll() != S_OK) { if (m_xvid_decore(m_param.handle, XVID_DEC_DECODE, &m_frame, 0) != XVID_ERR_OK) { return S_FALSE; } } else { int tmp = m_frame.colorspace; m_frame.colorspace = XVID_CSP_NULL; if (m_xvid_decore(m_param.handle, XVID_DEC_DECODE, &m_frame, 0) != XVID_ERR_OK) { return S_FALSE; } m_frame.colorspace = tmp; } return S_OK; } /* get property page list */ STDMETHODIMP CXvidDecoder::GetPages(CAUUID * pPages) { DEBUG("GetPages"); pPages->cElems = 1; pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID)); if (pPages->pElems == NULL) { return E_OUTOFMEMORY; } pPages->pElems[0] = CLSID_CABOUT; return S_OK; } /* cleanup pages */ STDMETHODIMP CXvidDecoder::FreePages(CAUUID * pPages) { DEBUG("FreePages"); CoTaskMemFree(pPages->pElems); return S_OK; } xvid_20020412/dshow/src/CXvidDecoder.h0100644000100600001440000000350007442213333016704 0ustar michaelusers#ifndef _FILTER_H_ #define _FILTER_H_ #include "xvid.h" #include "IXvidDecoder.h" #define DEBUG(X) // OutputDebugString(X) #define XVID_NAME_L L"XviD MPEG-4 Video Decoder" /* --- fourcc --- */ #define FOURCC_XVID mmioFOURCC('X','V','I','D') #define FOURCC_DIVX mmioFOURCC('D','I','V','X') /* --- media uids --- */ DEFINE_GUID(CLSID_XVID, 0x64697678, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(CLSID_XVID_UC, 0x44495658, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(CLSID_DIVX, 0x78766964, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(CLSID_DIVX_UC, 0x58564944, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); class CXvidDecoder : public CVideoTransformFilter, public IXvidDecoder, public ISpecifyPropertyPages { public : static CUnknown * WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr); STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); DECLARE_IUNKNOWN; CXvidDecoder(LPUNKNOWN punk, HRESULT *phr); ~CXvidDecoder(); HRESULT CheckInputType(const CMediaType * mtIn); HRESULT GetMediaType(int iPos, CMediaType * pmt); HRESULT SetMediaType(PIN_DIRECTION direction, const CMediaType *pmt); HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut); HRESULT DecideBufferSize(IMemAllocator * pima, ALLOCATOR_PROPERTIES * pProperties); HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut); STDMETHODIMP GetPages(CAUUID * pPages); STDMETHODIMP FreePages(CAUUID * pPages); private : HRESULT ChangeColorspace(GUID subtype, GUID formattype, void * format); // data HINSTANCE m_hdll; int (*m_xvid_init)(void *, int, void *, void *); int (*m_xvid_decore)(void *, int, void *, void *); XVID_DEC_PARAM m_param; XVID_DEC_FRAME m_frame; }; #endif /* _FILTER_H_ */xvid_20020412/dshow/src/xvid.ax.rc0100644000100600001440000000540407442213334016145 0ustar michaelusers//Microsoft Developer Studio generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // Deutsch (Deutschland) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) #ifdef _WIN32 LANGUAGE LANG_GERMAN, SUBLANG_GERMAN #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Bitmap // IDB_LOGO BITMAP DISCARDABLE "XviD_logo.bmp" #endif // Deutsch (Deutschland) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Englisch (Australien) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include \r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD_ABOUT, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 209 TOPMARGIN, 7 BOTTOMMARGIN, 105 END END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_ABOUT DIALOG DISCARDABLE 0, 0, 216, 112 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN CTEXT "XVID MPEG-4 VIDEO CODEC",IDC_STATIC,8,8,200,15, SS_CENTERIMAGE | SS_SUNKEN CONTROL 103,IDC_STATIC,"Static",SS_BITMAP,35,38,142,27 END ///////////////////////////////////////////////////////////////////////////// // // String Table // STRINGTABLE DISCARDABLE BEGIN IDS_ABOUT "About" END #endif // Englisch (Australien) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED xvid_20020412/dshow/src/xvid.h0100644000100600001440000001126607442213334015364 0ustar michaelusers#ifndef _XVID_H_ #define _XVID_H_ #ifdef __cplusplus extern "C" { #endif // ========================================== // global // ========================================== // API Version: 2.0 #define API_VERSION ((2 << 16) | (0)) // cpu features #define XVID_CPU_MMX 0x00000001 #define XVID_CPU_MMXEXT 0x00000002 #define XVID_CPU_SSE 0x00000004 #define XVID_CPU_SSE2 0x00000008 #define XVID_CPU_3DNOW 0x00000010 #define XVID_CPU_3DNOWEXT 0x00000020 #define XVID_CPU_TSC 0x00000040 #define XVID_CPU_FORCE 0x80000000 // colorspaces #define XVID_CSP_RGB24 0 #define XVID_CSP_YV12 1 #define XVID_CSP_YUY2 2 #define XVID_CSP_UYVY 3 #define XVID_CSP_I420 4 #define XVID_CSP_RGB555 10 #define XVID_CSP_RGB565 11 #define XVID_CSP_USER 12 #define XVID_CSP_YVYU 1002 #define XVID_CSP_RGB32 1000 #define XVID_CSP_NULL 9999 #define XVID_CSP_VFLIP 0x80000000 // flip mask // error #define XVID_ERR_FAIL -1 #define XVID_ERR_OK 0 #define XVID_ERR_MEMORY 1 #define XVID_ERR_FORMAT 2 typedef struct { int cpu_flags; int api_version; int core_build; } XVID_INIT_PARAM; int xvid_init(void *handle, int opt, void *param1, void *param2); // ========================================== // decoder // ========================================== #define XVID_QUICK_DECODE 0x00000010 /* increases decoding speed but reduces quality */ typedef struct { int width; int height; void *handle; } XVID_DEC_PARAM; typedef struct { int general; void * bitstream; int length; void * image; int stride; int colorspace; } XVID_DEC_FRAME; // decoder options #define XVID_DEC_DECODE 0 #define XVID_DEC_CREATE 1 #define XVID_DEC_DESTROY 2 int xvid_decore(void * handle, int opt, void * param1, void * param2); // ========================================== // encoder // ========================================== /* Do not rely on the VALUES of these constants, they may be changed at any time */ #define XVID_VALID_FLAGS 0x80000000 #define XVID_CUSTOM_QMATRIX 0x00000004 /* use custom quant matrix */ #define XVID_H263QUANT 0x00000010 #define XVID_MPEGQUANT 0x00000020 #define XVID_HALFPEL 0x00000040 /* use halfpel interpolation */ #define XVID_ADAPTIVEQUANT 0x00000080 #define XVID_LUMIMASKING 0x00000100 #define XVID_INTER4V 0x00000800 #define XVID_ME_ZERO 0x00001000 #define XVID_ME_LOGARITHMIC 0x00002000 #define XVID_ME_FULLSEARCH 0x00004000 #define XVID_ME_PMVFAST 0x00008000 #define PMV_HALFPELDIAMOND16 0x00010000 #define PMV_HALFPELREFINE16 0x00020000 #define PMV_EXTSEARCH16 0x00040000 /* extend PMV by more searches */ #define PMV_EARLYSTOP16 0x00080000 #define PMV_QUICKSTOP16 0x00100000 /* like early, but without any more refinement */ #define PMV_UNRESTRICTED16 0x00200000 /* unrestricted ME, not implemented */ #define PMV_OVERLAPPING16 0x00400000 /* overlapping ME, not implemented */ #define PMV_HALFPELDIAMOND8 0x01000000 #define PMV_HALFPELREFINE8 0x02000000 #define PMV_EXTSEARCH8 0x04000000 /* extend PMV by more searches */ #define PMV_EARLYSTOP8 0x08000000 #define PMV_QUICKSTOP8 0x10000000 /* like early, but without any more refinement */ #define PMV_UNRESTRICTED8 0x20000000 /* unrestricted ME, not implemented */ #define PMV_OVERLAPPING8 0x40000000 /* overlapping ME, not implemented */ typedef struct { int width, height; int fincr, fbase; // frame increment, fbase. each frame = "fincr/fbase" seconds int bitrate; // the bitrate of the target encoded stream, in bits/second int rc_buffersize; // the rate control buffersize / max. allowed deviation int max_quantizer; // the upper limit of the quantizer int min_quantizer; // the lower limit of the quantizer int max_key_interval; // the maximum interval between key frames void * handle; // [out] encoder instance handle } XVID_ENC_PARAM; typedef struct { int general; // [in] general options int motion; // [in] ME options void * bitstream; // [in] bitstream ptr int length; // [out] bitstream length (bytes) void * image; // [in] image ptr int colorspace; // [in] source colorspace unsigned char *quant_intra_matrix; // [in] custom intra qmatrix unsigned char *quant_inter_matrix; // [in] custom inter qmatrix int quant; // [in] frame quantizer (vbr) int intra; // [in] force intra frame (vbr only) // [out] intra state } XVID_ENC_FRAME; typedef struct { int quant; // [out] frame quantizer int hlength; // [out] header length (bytes) int kblks, mblks, ublks; // [out] } XVID_ENC_STATS; #define XVID_ENC_ENCODE 0 #define XVID_ENC_CREATE 1 #define XVID_ENC_DESTROY 2 int xvid_encore(void * handle, int opt, void * param1, void * param2); #ifdef __cplusplus } #endif #endif /* _XVID_H_ */ xvid_20020412/dshow/src/XviD_logo.bmp0100644000100600001440000001140607442213335016630 0ustar michaelusersBMv(, 1F`"++W00mMM333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333DEUDC33333333333334DETDC334DUDD333333333333333333DEUUUUUUUUUUUUUUUUTD334DEUDC334DEUUUTDC333333333333303333DVffeTC333333333333DVfffTC3EfffeD33333333333333334VffffffffffffffffffeD3DVfffTC3EVffffffTC33333333333303334EgffwfTC3333333333DVwiwfDDVvvTC333333333333333EgiveDFgivTDVvwfTC3333333333303334WvTC333333334VwgdEfeC333333333333333FhDDDDDDDDDDDDDDDDvUfHeEfDDDHfT3333333333303335fC34vTC3333334Eg334vUh34fT333333333333334VD33333333333333333HfhC34vVh333334eD33333333330333EkB"#4vTC33333Egx3""#Vz2#HT33DD33333333334Wfz2"#Hf2""""#4weD3333333330333El˩B#4vTC333DVyC234Hf{24dDDUUDC333333334V̻f{3"4f23HveC3333333303335kܻ3HfTC34Fg3HVkeDVgvfTC33333333Ff{v|̻C4HvTC333333303334V˻4HfTDEgxCHͶUj˪vVvfT33333333EjݹUj˪vj̻DvTC33333303334Ez̻DfUfyHەDi˺vfeD33333334VgeEi˺vf˺HfT33333303333DV{̻HwwHݧdDg̻iweD3333333DVfffffffwwwwvfffffeTDg̻Uf˻DeD33333033333Ef{˻weD4W˻z̺veC3333333DDDDDDEVgwwwvUDDDDDC4W˻TEfffw˻weD33330333334Ef{̻vTC3V̻y˹vTC3333333333334FvTC333333V̻T4DUUVg̻vdC33303333334Ef{˨dC33F̻w̸vTC333333333334VdC333333F˻d3334DVz̻vT333033333334Ef{˩޷eD333F}˻fgܨfT333333333334WuC333333F}˻d33333DV{̺eC330333333334Ef{ܻvT3333E|̻fVzܨeD33333333334WvC333333E|̻e333333Ef|̺T3303333333334EgwdC33335k˺vDV{ۘweD3333333334V˺S3333335kuC333334Eg̺d33033333333334EgwTC33334j˻vDEf|ۉveC333333333V˩T3333334juC3333334Vw̻d33033333333333DVgܺweD33334g̻vC4EgڙvTC333DDDDDW|ܺeDDDDDC4WuC3333334Fwe3303333333333DUVfwܩweD3334WܻS34EgʙvTC3DUffffg{캗vffffeUDVeC3333334Vyd330333333333DVfwwww칙weD333VܻT334VgfDDVgwwwwwywwwwwwveUjd3333333EgT330333333334UgwwveD33F˷d333DVzeEi˙vUV{ۖTC33333DfyvD33033333334Egfg쩙veD3F~ܹd3333DV{vVܩeEfwwwfUDDDDDEVweC3303333333DVyfVg멙veDE|e33333Ef|f캙eDVgwwvfffffffwvD33303333334VwvDVg۩veEke333334EgfݕDVwwwwwwwwwwwydC33303333334gݦCDVgۙvUid3333334EgfEieD33330333333EiC3DVgۙeVd33333334VjUjeFyvT333330333333EeC33DVg۩vUgܦT33333333DVzeDV{ܶTFeC333330333333FT3333DVg˻DVfwfeC333333333DVfvfTCEfgwwwwwwwwwwwwwwwwveDFvT3333330333333EfD33333DVwDDEUUD33333333333DUUTC34DUUUUUUUUUUUUUUUUUUDCFdC3333330333333ElvTC333333DVzC34DC33333333333334D33333DDDDDDDDDDDDDDDDDD33EleD333333303333334VeC33333333DVzeC333333333333333333333333333333333333333333334WvT3333333303333334EgܷeD3333333333DVzܶd3333333333333333333333333333333333333333333334EiܷeC3333333303333333DUfwveT333333333333DVfwveD3333333333333333333333333333333333333333333333DVfwwwwwwwwwwwwveD333333333033333333DEUUDC3333333333333DEUUD333333333333333333333333333333333333333333333333DEUUUUUUUUUUUUUDC33333333303333333334DC33333333333333334DC333333333333333333333333333333333333333333333333334DDDDDDDDDDDDC333333333330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330xvid_20020412/dshow/authors.txt0100644000100600001440000000005307442213331015665 0ustar michaelusersauthors Peter Ross xvid_20020412/dshow/dshow.dsp0100644000100600001440000001146507442213331015304 0ustar michaelusers# Microsoft Developer Studio Project File - Name="dshow" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** NICHT BEARBEITEN ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=dshow - Win32 Debug !MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE !MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl !MESSAGE !MESSAGE NMAKE /f "dshow.mak". !MESSAGE !MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben !MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: !MESSAGE !MESSAGE NMAKE /f "dshow.mak" CFG="dshow - Win32 Debug" !MESSAGE !MESSAGE Fr die Konfiguration stehen zur Auswahl: !MESSAGE !MESSAGE "dshow - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library") !MESSAGE "dshow - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=xicl6.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "dshow - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0xc09 /d "NDEBUG" # ADD RSC /l 0xc09 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=xilink6.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib msvcrt.lib advapi32.lib winmm.lib ole32.lib uuid.lib strmbase.lib oleaut32.lib ..\xvidcore\build\win32\bin\core.lib /nologo /entry:"DllEntryPoint@12" /dll /machine:I386 /nodefaultlib /out:"bin\xvid.ax" !ELSEIF "$(CFG)" == "dshow - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0xc09 /d "_DEBUG" # ADD RSC /l 0xc09 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=xilink6.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib msvcrt.lib advapi32.lib winmm.lib ole32.lib uuid.lib strmbase.lib oleaut32.lib ..\xvidcore\build\win32\bin\core.lib /nologo /entry:"DllEntryPoint@12" /dll /debug /machine:I386 /nodefaultlib /out:"bin\xvid.ax" /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "dshow - Win32 Release" # Name "dshow - Win32 Debug" # Begin Group "doc" # PROP Default_Filter "" # Begin Source File SOURCE=.\authors.txt # End Source File # Begin Source File SOURCE=.\gpl.txt # End Source File # Begin Source File SOURCE=.\todo.txt # End Source File # End Group # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\src\CAbout.cpp # End Source File # Begin Source File SOURCE=.\src\CXvidDecoder.cpp # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\src\CAbout.h # End Source File # Begin Source File SOURCE=.\src\CXvidDecoder.h # End Source File # Begin Source File SOURCE=.\src\IXvidDecoder.h # End Source File # Begin Source File SOURCE=.\src\resource.h # End Source File # Begin Source File SOURCE=.\src\xvid.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # Begin Source File SOURCE=.\src\xvid.ax.rc # End Source File # Begin Source File SOURCE=.\src\XviD_logo.bmp # End Source File # End Group # Begin Group "Linker Defs" # PROP Default_Filter "def" # Begin Source File SOURCE=.\src\xvid.ax.def # End Source File # End Group # End Target # End Project xvid_20020412/dshow/dshow.dsw0100644000100600001440000000077007442213331015310 0ustar michaelusersMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "dshow"=.\dshow.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### xvid_20020412/dshow/todo.txt0100644000100600001440000000005507442213332015150 0ustar michaeluserstodo - utilize xvid.dll's configure dialogsxvid_20020412/dshow/gpl.txt0100644000100600001440000004310307442213332014766 0ustar michaelusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.