From 634a14bfa6c41d074d616f288bff251e424b739f Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 22 Mar 2020 14:03:48 +0800 Subject: [PATCH 1/4] For #1659, #307, add opus codec library --- trunk/3rdparty/opus-1.3.1.tar.gz | Bin 0 -> 1040054 bytes trunk/auto/depends.sh | 51 +++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 trunk/3rdparty/opus-1.3.1.tar.gz diff --git a/trunk/3rdparty/opus-1.3.1.tar.gz b/trunk/3rdparty/opus-1.3.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..1119371fc2a6638f8ce6e3393093a95409e3b4d5 GIT binary patch literal 1040054 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

gtmPJ?TYS=K!JZ16C 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ℜN{8 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%0Amdtk7pr1~JZ``fEO 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

    `ODe_%(OnBDU`TPInj!!v0Yce+mgAK396 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 z%0D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

    4)gn#3K!;zy2sGeVzwO-B?hz||fo#;AkaMe&`! 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


    V^=X}Jwcr4-sSQG9$6 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

    Y$2*6cN1G=HM;!huZeuVH41R%MIU+C> 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%0D1701C;t~ATGmt*CiL|bVf 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

    |}_*~%NTbF_?_CK$c9S4a>~#$(x2 zsze*a?-*Y}8@^T4;Rj4g zCFfpUGaC6L#r}80Un}y)C zbNNp#cu(SEv&&`On&^2w#OG3j8?Z|cEX>)<5DO_~!dQLJrp<>rd` zE?es8X8__*7a)F59A>!&mu0aBTl~C+SO?aD@?WaK3QCJ-J)u_FnMS^vOq2sX4^<>T zcYQpR^<>vREF!y<^TOqQ3%rsa8n!)-m?Mh#N=ko;&c7}b5}|5UG>&t#k`0XoK-+{3 zlp_AB;;9i)lZGEh@^aBKI7u!q*J}qHz9dsjEfX9`eB$Z4t2)YA3li}`F_;}fF3r&Z z4zX>cI>yEX1{NG1v>Udt5tEKsrN&FtF~dvG_ElrgqT{4^@wg71iM;Zc?RAY4! zuYepG6@;s74;I%;L1y%2{Hsuu)5s$;&W!9Cxlkk(Y4SoUk~9W1ym?vdKPt6ID57K# zkiIX`R`gUuR+vmrMUH`KOxI@4y3P=<6#(*&%hM4XUdV0Y(O2}V6BiPmw`?IXw6pJ|Fj zZ#|BRl~){!B7Ud@JK#w!*1f<(N_x*|z)YdJaN<;Qu7t#qH23+GzgHTGwB=pYm6D30 zL8EVdfzo$_2%cy5cmZN9@)j*io+;uhD3wI4!z>aSaD;37-$z!kxWY<(MrEO6vK`Z7 zPz*~NZr$UlP}3;*D;5>oRumUg7SRi8|pH22^Y}SG+K1Y8T3r@ z+p6o6Xgj5M;iMm`8b&*kId%T{ zp<~2^fYwUeT6x_8E&MaD^Yc-nN^6wNvBpz@_j^s|Ny2Ib({yg~8u6O8s=Wkjd z750sLLu7JpQV6pnx8p&fZ7^&Vfu7Z+XGbidN_DOm zG#!#t-Ga;X3D1c`4DbhCDd0*x^U3WPCqMrRroCl1k`MmE{{!dTbQbDT3w1<7FH)Va5+rYEyPz&?I<} z=eMWdIwPqHHQv&-gHdk|yu!X;R;Nm%VH$$zjneR(^w;2$O>yV5){5f>M}~Su6wSz9-70(Wd;w@i2CybxB3A)$ahKkswLc z`zC`TLnu^4bR4t*z4HS}B7Xd9Z=#_UZbvO+IHhEgdOORUBz$Mi2w!~#4mTkJZdvxS&QkS9$?xOmf(#G-2ULJ2MW*?Eme zY|#yoKv(53G9!4vZtjUXcv8c#>j#)E24wZJ{m{@n)yg0WnBZ+T*^u9=4QO5dlcQ@+ z#hsnYG>lH;7PO&1ztZsBPd;xubn}eP2}YfhIZD(j4TY>J*vcH{;JwD$nBEIjEFhlK zUo~@QFM#^adv%|bM+!UZf8F*-u0GjDtK_^QzvYLe`pLp~^5-IKlWC7>BTl5ZFVaGB#tkGHUT145xlL@d;#p{Q9&)4@zm24nAw{2eU8 zC~3hAE$iLO=KrFH@rM?A^afw3zsaVlk|{uuq{o%jiKRH*ahZK47Ohz8AVPK?qn{N( zGKl*j$>F>b5}l_G#uDBRF2)~~fJ3ZVS98qvTAA*`O`k6Sb5Y7eZQX^z5@N&R61WzD28ITjHe#)tH_*J8GEb4_o)(jK^)y+`KyrxanSaryELA<$=j2h;V%q5Z zRhQF7QTW?H;QNwiS;S3!S;SrgZG21Nborw#C{rmCL%>GPAVDe77(VHU`weh88pMLh zKv){tpzW62Sb%`9P{KopOHJ%Fjn7mE%*a+D=O8+vN9qx}1R)-j{)cM5m(e41vU4IAVFq6*CLE zJFvY9n(W@m8RYKhXcsc2>60AoBY{z?a%UJ{6(WoeMKr{THMu0svcu%ejll*_x}kj; zl+M}U0gOaq4gGn$IAF9(7;2kKD|`rGk<;{kLJq8dV#;>;gVWLN6tcKPZOihNJ$SZ( zFSj|Tl}~ucLZ?0E3e$(aJD&&zrD0>

    ceUN~3XfQN$V~vI*!;ea%*o0;2%Z9-=yp zmaxGuOFqNUycfnJAsBHYlf>*VPSD|XLu_xFcNb4;vou{1TDEc{H+^OfU`^`A;vpSD z)mqYFny;x&wXBl+k#1n|(L`NUi7qeDE)`xGI!-Mgt98-iPI?m#n=v|;z!fQ};X1mF zwNH-yl0MM7qr=NNgb|9)dxZNGitVZKA?g#WlSx1tA<4Y|+H%J>g|&?W5~f;1%7rW3 znX_OlL@T&rvrK+tc_lLph4{fHV*w2(j4wS2cbsfiZIuEEw!d4%8-fE8O5!Y)N~htE z1YnO-)|YM3%#*wh%I3Q*I2*ar!HgI3@ndOQdCNjLq-gCHPY|bh>gU|YOHyW6R06fOkA5SYEq(ub9Z)R!8$jP&f?!x`H?ru=Y!vq8K zjo67ayb@rfWfUHR7VQ4KxU=IvUXdi5{^mdT4{w%pjj{Myp*=)I5?N%gIR7%&5gbM38$ z+rn`;Wm4f3jtQtWYU&VYL3@gIxe+mgOg|zNlAyr+`JXS6TQ*&UViJbP9ql`a`RS3r zLH9jOG_T)Ao&f~23oiLmmj@{=L%ENR=tlk!kg(8ToiDtalHqu;C4|+$*hDzCBz@`- zIL^6)RiOwSS?oDdbj1Op8GlHF;8cnw{&g*qGuJFO@?|2xScoR!)T)6>s0PUS1%KKt zN2`s{6s3y6!UgAS_=_eLrR=3}5@pPs-6=wnB0{SV9Mjt{6j{b3uzRs3gS#x--kHg| z*$?`(u z7fa#|Fe?d%$fE#XsNhjlYRN{!RhF3dmrGm2RD2^>4`;7hwpQww3lFyjdiZ7)rjH;i znAMl}Fkit_9r&0(cFkYfj=EZ2*aYE_0dc67F3PwPkI2GGB>4`me{s^AE)Q%#`R@GW zx;Vm*m&pY|HvWmbgS4meV0{BF(AMKnSnLY}kA2L-6f;qlf}qpOq%4GdmK3f8 zsBeN^Bi9fn7E{!BO-hwNZ*wpbx*a)*wy=z$^HCg0MF}?z$fVf~H%W$zndMBohaYZC zj{>1ZqT0X*ojIdQOwnIje2Ivoo^x^P1#Ij6_Xs*60yuK`9TWC`o~!oTj_(z3($HeE z(ZPX> zliMr`4cs=)_DPWXhuQB=fTH^PlGtxC)gu(Cg8g=MCjg-3aUn8>os3xslsmEyq6vp*{S$BbYzppxpjmon6Fi$^tIf6SI+;15SoV7l

    q7eFajUysn_Z8=*WAHXEn*9SYudJ=+kK2xkzc zeIXNdN+@0ns{qZ-a{TBY0i2tJ_|eO?#wh1~HR`%kHWH5@Hf2fPH&o5Ui49v1E zQBPhmSLjGCs@I2tVbEaV)G_@f3&~>L|{oZm4ewyNs-{F{pK5qVwMXa_? zN$}>pvvGrOD8fc8GF4o;M5i9I5z}_*bjA=Oe8{m;FTux5%AFSa9N#ga&z2TF>Oky0 zy73Twcg@4ss&9;eZ5^aX3c7XFrPi6-1F60ts^h0f{75$Ru!H4_4^*d)-`eDRhp&Ad z>u8txz#+M;>PSdvZxj+CkNq+;rYt{#qcO_W%!T3dnFbX25NjWDLMIZ>Gbh+V`P&Jj zc0#JPrz&L*88yGmTSe2FErn^KaB-klEaV{$oZGA(zUcx^37UX9ea_RTJx*zqoUD9p zis47MFT^^5&mBU$sAtgof0)e@V6;<^Y>Tr@>0|y zLM*f?GQP|*$92hkwVHK|ztf+Ex<|sMtdm}uZp&KL<2iYb8B&Bf7>}_z*HKTJAY+}4 z_q1g>q(r9#2ui#ax>`#_Vn~Y`vD25#erm-8XkV3@pC&1_E9CuZt)`?S^2JX-8PCxNUz@S)`t(1cxF8|;77)5*Q>%%C{lzZ{ClBuhuQeJ zwo}oMY1*TBvJ(4c_`fMW-8K}1hBG&&Z4+mSdUd>1HoeCWhj~2_5MbqzDC(60ME0&x%r%*aU0n zrL=CjPJYdYmY5>HhZ+IZ9L0-SG;VQWZ&_es7+HpVsNYj3l7z3saVDhLOdJ>@NJ1_w zshrSEpA^_)NCx@4mAHVGON&VfuAdzN+wN$>HlASE*)tbMSkN5TO|E(F7yKOEFr*ez zE27f^zc?haxOW?d^a3U`6qUKTs#5~GcTOHia~Qwg?JD$-Tx>Z{W5@hMRxLQ`(Xi(j z4w}Sr=Gi7=ocW0;6%aTZxIuHv8##TsAxcV5I9d;Bb$S|^yz^?`G(yuuq-x3I|; zT%^+)hW==Y#es1s`N0(Wum^-vg@hiw3tV(3SYh;Cns9n9ptsweS$>#I&n*@c5y>$l zDkn$&kDq`u4y2}OuvO_p7IvY8kaQ!r=b$!4@(a4RE)SA1YJ}wr7buGG*rM6SrJ_(| z=9C0R^*}Opaw2_3(1-#E5VX_wvPY1qCLmb>cf*e*aWm=8hGN0<8Vi?%B+Mlz3=uzD zhP4+VF}Q$7u29$%Ay@+%;&(8%Jg}%HD1~!M3I7^g(nke%O$3B7twu8b44Y!S>U(-6?rd=mK1}dFSZxcoDUMx>(#4LYi%$5!b<8*e8q+=%5I+pt!!7NPk=Q0vR_%5KBo%%?)xAPGq41!M;k;S7VR z@!}FM8*({&Dt2zuWH$>2vdr>`)(8R&8ehj+Ww&9yX4ahOXlB)O+&8W}mXMBRA5uoG zX*Wx4oetg{jI(EL9oxb~(Ht5xCz7m7acrcWrjOaEzH_KEfLxSBoIdk${X+;jtAM$%8Pb{hdU<4|+s*7%^=cUzkC z2ECD%b*7;U#%`~Lw?TVfg)DG=AH|RvVh&a+n?`6ZPOAd|#^)Vx_oy|J_D>^?EK()_ zW=9*BMa%lkK~pAf2~=MFmUYn{{*q$Q1wtmVrLn?X7VKzeft2+;(CNv>1%PI3zE*e+Mwr1>-xulQ}7{n&dt(Y{ynli2tsep$`F zhj!Jww9UJui^V;q>92)s>nxjI02`CG0g^)1I6y;m*eoGdObo9=d)lpzcGZq1Lppnh z4<;K@HNZ)sRj+cILx-{YxQsggP)}JKWT1|mW@n-|%T+29=@ekW-OjvfU{KYn?)YOP zamz`js@}1(jlol^va*IHQ(Z|zFJvP&#=e4bRi!dbo;$f0SRvBDe_S!srH<^W+uOE& z65y24)>&!;S%`(XY@X=D=a z!JfcGew+Yho-C#LJjskfUB)ew9WbR(^^bqcka;ZQh z@bd&pyd-2Z!!gW*LKynorGc2Vh5Igp>_Uh`Bxw9p?e#!Z`N^^%HdG$D(g22$j2NR4 z>{2gI>=%qZ6ANiQbz_MV7AAlQWTR$C1ysP8-14W{IK1M`o0jvU`vbmNOfOnB46aV{ zD`A4%gk|cWLbf44V+~1r_k@Vo12{zvVb%B#CJx=d7R?0a=nh(mF02?~Kuo|?+&3Mq zF_KsT@4vX09VVN48kJd#6SH%~5rka?hcUj7`F1oZ?HU}v>Z%znHO$Qnx&c4f!`f?o zG`q`HI%-4pR~#VUoeCBzC9RaQ#4dQYW=h0^CwUM{Qvr&yQ~ zCTeL7nUJ@Y2!zV68Pk?A4wY)}aVaBAXQghI%Q;!@BAZVdkb$8t8|U!lk`tRS65#Oe zoB2Ig2L!-*Mv6WhXOS^ubUSBWNzu&KgZC3B!$pmBUY$H;fcag~*f%%#D3J$}ouc2R zv6RJQjUuHmZ4NAKJizK}f~0tUXtz;Hz)U2E4VEnxZ={_&2xYFX{h+{$i9j(R5<5CT zs$f3nbLhNcci#|4p}?jsI`%=EYNZkKY*YL<{ocm>^wMgS$wKiY8!*L5X-Ym7Pyu6k@5P4JAQ(%J9W$4orZAV2W=NLk|`rcdXo& zT|}Rt^@|8nZLr#DD6z^HGOO{Wj7d)msAo>ukVgdgJqA&D;Sqn`HTZ5(^tcTKk-4zZ z9K5I$(mK~2?by9aj=NTqnRJ@06ENShuc9D}STKJRCjZG~*za!E zDd1lU*-T1Po?J4VPpwgD;>vva5?tg~$0t&pvL28Ni@#t^fdo``V8 zkM(1-2n`Ks;Iu+hxmxt-YqTAg|Hcu2E7J)x%~v0i=RE1o?V25@Ub@Z(pFbfv?dm;J zw5fY$Uy}&hBW?Tw=Sv!|Fo&bsF78Z#lvh;SEG~n-$1O3BO15mM3qZlJ1&Xo!lzJ*vDcFTVYG_5138i}7MT|~(Y!H6bNB+fGJNMckP^UR)gm}W4zjDDcDINWqYo*igb&)AIg&6;sthkO_O_;>Sws)7iZ zDcj-t={IQFR;TO@@I(CxOO^$7)fhR~#4A(I*sqk+L`O5CXsY(Gv?V;pqcEx> z`@|O5YoJ3fll{ed%zk;JJA;&p8G2x>Aq#qlthOT?O3H|@FESQYnHx?b-HDEI4a>RX z&j~;~j1(T%;k2dVp6$9V7F7(f#hbGhBkj0+(O3tGSd+ftCmqMIyRh#`rOTT9BOiug zL=N51AW8*W$|k`B*NCr>p%}qNJE6;XWmBj4b4o@rzzChQh$ri%S}$wO{tr!gRI~}U z_otc&C)HUi&+V`o8n=QpgpfU$8fEa8ew(Ss_a#%Pc@6GG(&xH}LEDpREdvlVzCk20xyVsaR7O5_FMBcRyxerhoeFFHrCeXc zdv=931EEd6q_eJXa^J*-`ql;b26l}_y$ud#*A^#tpSIp>Deq3M7qf>gfJn6M&E7q| z{jJa6yvyM!gN#RickhH^y1v;vd>7&TIh>E;mEiJH`L#Y@_VnELrN-rE!?v2+TfB3P znWJ(4699%5(P4u7{}BlhHjwFGDb(5?1;LJYfBGYi?zOIOeCz##L8EH~hOe7*-7eEz z@460REyz4fM%!baH2@Y z!@uT#k=&49q3y!bcFV{(|H}F5lV34y{0?z8@YY^%j}rWP8$^Q?#4q?4I$KJ1fnjA- zrQU0wujUDS{`$xkQOp&oVM}-sQ9K`P3e&Od!1Vd}V|RKd^xDYZFY@}W#k?%oO+O#1ObGAnerR<4R#F5``+9_)I2>z$^^)QI2-O zt|d9e6X7k2M9JQZU~_;*1)nN)_y#>L^1JsOV%_+v_o}Z-5IuyGrf2h8d-gXZR_WeB zY$O-xi7_dkjkku7dA$w!CW;F29bU-M<5i%1_@Q@(J^8z(;I(o+4d#O8(tL1%Kb{K5 zsu<1h0846U6SfzK;P<_^e{4E<6v?M{O!27oFwHI;iT)uIxxZ`cH3v?q#ZL~G@ zkxwp^f4aZl%v~I`u=$ieV+td10reCjxvMb>;x^{Ir#oW%)%wTJ@~%8<(o$6;r*0Z7V#*r5;?#m;y6oKivg&v!K$_I{Y-rOYmz;vVSJM4gAzes^$ z4i4O}Z_n~~D>j6ahy=uE{4extVU@jEgNLh@k8jT1h%J>2`G{z0XRI$4H1?I|1_A=K zpw$=86Cv+*`hzl&!&4ivb1|wR2hIhKZ!>jTKQ_3LZu4bbRTSIpxrAb?UD<7~AZCqS zy@Q5Cz)|8vC1|*y*7<^_gJMs`=4C43T$%3w?JEt7W85*i1%5(2x3cC7bkrlJ5597y z4Nfva_6l>)-6Iz6l11J*e>7XNCqo#DUzXsD@r>{MbbhW@U2p3;RKX3sWZ-em<1X%s z{6ukB7;fDiuE8H$HPd~)DAX33(o&fnRXj0g$%@ev#&wzrsdGOBj@%SAiRn&~)kuXl z;DB?Xq8o%p8bP5G7YxWAUc9zWa&wb*d2z7&Esk6@-^Xn!J8w^&ipyX5vs0&~W!?6N z{8lt9NZmp`!I`D9(a+t@9-FV`$r%Tu%4MZK5>509nKs3eXG#X8G6OERyRs*xsI z2GX>g)=^n+hO&GkjqUn7z2d4#5y1czqqNdRQtXLtUlMa9KQfzHRClcwu0rht&pett z{^#^QC0YG%n7mBlm^Fo5!^UH6sc49$N-K<|Go?vNTV-4SVOF6w=hSLT=loFC!vKoK@ldcnZ z6iQSj`5g_lc&<;3;9k5@1Xt{Do>zNLt&SN-L|j7;dF2pLcx~ z*^lgm-0I*USYcW{<)_@zUW3*qXUF$iBcyUB>gh$A)_qXv5xllEB@S2uSLXr&U7`BA zXofu*1F#@RpIIQxt*X@r$-&|8n9dO+^|uj%=f$k`50r#OQ_|P}%8KCNho~mZYU&CE3!Z zR@HeXaV6o7a^OXVw%aj$;&T!Y(yy8KxulBmGEaG)!0ZS^v zMOy?P!Cax89bG}*y^|2w?M~$U#f$iX#Dc@FQ zsX^^mDIZ^Tq)JU|R5^p-c7g3Cd|I;&bhRf?Se5f!UhA~aDoyoVrms&fJA+|cf(UU! z`_7zv){B*5i|cAwL4?zepVo$7wmEZaYD7w}#)U+X_Hn}drG^JA;c4xX?YCRbcFzF` zqZ@_N-*6f(*ywKBWISfxtQ<$p*==!I9-7tN#RCPIauTK==$i#j{i5XkqAXckdv?@* zKSD+RDftvEo37Q-<`;oqep6TEWgUg;N5WKmP*B_N!NQ&rXuTiOUv$G|P8vz#P-H{2 zoESP5VKoXAVPzh_v|HsKSZ!5)uvA#Oyua6zTUy^!(FoMPUrx(co(mqFAOB4Cez68J ztoF5QRVP!W@!Fg`sRG(NIzsMa{Zk6Zg6GP1YGZnI#rNkK-QpM_!!w!_uF+Wc4u?*b zgKA}w^o0KPeR=-vGq6P+H)WMvmhKkbA8frhc_#ThCUg@fp?Kjsxyi+0Y$M7kXVo%& z6_LKK_Pwg`FuX2iEP&Nf&!p&=_!0V&zE6@O(O$u<5%ax=w!ycSED`67=hML=v+7eF zTsmxJuu>Rdn2+3F(NTJ&S%0FmNQcC^vWe7Wgqi+2xDn)m?;_t>V2Ti&;P>JkLJK#>Nqb;62#B_N9qbjh;Z3K7|fOt zTOS%Zgf2Fq&{tsiN(wUUDWKW2}At7R_sQPJf}Wm?ORtvy@R2-Z4_vUr5hkY-eno*}MqjXq6DPJt<~ z1JGbJ*0mkkA!RvnMG!XPh@eH-VeH^oZLVoJb3CspR2jH;_tv3Hysf|RXc?3SW9ZV3 z;M=UBnbJ+f!i~sDrJu!=0(7tJG@?&XXswH&rB@44B zDzsvvumiPVJmSXov4)+6U-F0Uw6Gjfvmj=hjoUF!jghpsr<%>0$ZmONL|{BJ!X|C! zA2GC?dcZv@wN-il5Cnu))z6QHGT~7ayDcWRfE-TnHHu3dqf$?#0R`gh&{i%LI2)!f zTDf+_Y)dWI{p$lovoO^`9$0H`t~zbhG^C05z-Z~Oslk?AxZ8>~RTn97m&mo=!iR!;xN27A=+@35>IiNVu5LAoPwgi~Uqh-8T&Y8#z7EY?1F)qX#}maY&&Nd6V6+9z)KthUd#gS-|T@JPw{ALNLDMX`$F!IKKK@b%_r- ztcDvTb+C3WG(4<*e7XCwqTOvjD08*pg3x{e#Po8a&$VtOh^vQj#;yZVm}P>DR?$6wLE-?99{!6qD(k8zn62)^+Exs?0mP_Q;S?ciJt# zFKgf5hp(#uSaR(mhuSYfqq+r1_goi{FVhU(40(<;t;^f#0`pJE;h4$A1dE#sQ7B%7 zhmOhtrtDmHH95Do@_3ul=#&6Ei}b|2j*`Ih9U55Oh|s%IEv?y=r5PO|ob2qOw~v2{ znDn*K~LcF>xLq33uIMHeIPFhG4srUD-u)`rFP_SBd9P^p%brA~$`;}rQ$(Ju-1O%4i!$yk%%lC>o5 z7_^v+Ok-?-GDTyP$PO35D(zxh1HzU+=9 zyqU2f7FD9a5V?ZuMCh$#D$EcE%I}E_$JOU)o8N=tFa%<=w-y}O@`Hb5%~Pcx#Od|X zbkkY1uMlx#@rd%+SE&sZR5Y(}{U&R`TC2x-INlw#a(d}tx$Q}d*;9!t%_5YKBUl!# ztulM2zlsP!P&+JY`We=Q-x@0vyEU1DR#jSHu;Q84d2obL?_tiff*fMGB_E2eSs>QB zqL$;8XdGl-O31gcz@f;5pK>(+exzb|#uw20=OL!nQEW= zMrSO(hI~h=A6_p0`k?vi=se}o)db(f194IkKuZrnC;l(Wi)*GIikV(*(USIG4gaXg zyf&tzi%2oO4#;HG#tI?Jx#FZ00D%e^vZ+YrBGBu_WMg`>*BEDv&y?rE2ehEuSRygx zxu9C1O>w#4Jfl4`UkmGN+?kalMq3h%MGP*p5xZx$y~}cH^pS%I3D!ioHRJ>&!u^?GXF8Yf@j*K7)jR$s@?GVFbOu>B(Gyg2V{2Tl z$VgVjLyCDTNVDgwIPj1Wbjl7sp93X0#eil|A{OwrvN<}#!(n6bfvk;TGHJ-Z`tm;A zPCLG%gSUn*)xfMn*EkQ|#Z@NC23v3$3)5~pkbDmOn{!Z3W~7{>PFv2W@w4jG$@^*F z-e>oE?c;^=VI~B0hxFtf@5NS(dbRPrPL@=4u)DqA&d3B^lWszgWt#kSxXVPOKI(bN zD0uP!<_9V;899_Ht%swti|L0J{zg(OXa*(5(_ zmBmhBaq#?)p^(6fx1x#@4KWLYjacofmZpLWjrsd1>in>KG1*_gYy=&)e@&gVtA_o= zVa$Dy@EKz?n0`ifz@W5UEtgMe{z1O7fcVoRrvk-c=`C1{1dCvXvL2D!kW+^|mT?d1 z5hMSYme3(i|CF@|MhG681;cg`6k?)_>cDJ z9n<<*W$<@oZey0}xE%f=556zPFX1dP((C@L_k`rFVNw&|i^0@~O$!pM!{=~zJ<0X= z?{V*}>3& z-~4tq9I@tj8vUn-+gL~edH6mPv#!58~kaAl(w7nSa&v_ z?=eD6tal5$xqy}R*l}F!`V@u0p&+A$R2DvF%>HGrV-rnsqpH2^B&X010OskBmW>1q z4-2)D9`2H}0SdYWtruDTx&T#;2BFP2q7?|DK|K*L4)oV$)cXuf5XXz!(XampdO(H0 zBH8AHJcAi=gsyC-I|5E112gFPU_AbKH4&?Wx)!JbUHFk$4M%g&QRK>t!#8h_yRfTy zEz2|A=tnQK0HamDS%@P%+%RDA5M(}L^moKD4hGfj}HxoFNVVd0Ad+P zq)?VdNQifIvb~d_ZG0A;3J}s&&E$0!ovK{`SQh{!x)g%bRRhP+S@CW77TZH zj^AJdmxJ-SKM*-7A?QyhP*+BHlr(a%dw4Lf5gz?AjSypDwRCzlJpFjK2_My)(_hb4 zZ%=<+`*>FWb<=1zn}cA~Fl(Sk(KoyDznZh#N$|h8yN^KxT!wnBi*MBBN*f~g_NibL zujJm~If7`02XB60m6!h%B4ReTNm@_rNux$Nmdf6&?c`IN3W@KL4mLM27 zXH){%oi>a`r6($I^Qnl8Mr7ATT2p=2JvJ~ zOV0FH`J``Sr?*}EkK3*VKPLPbYD^Ztdk)XG;HLvWZTRuv$AzC3{5YyCwQ~dSZs6Sw zyu0Z-@MFV|1wSVI#O=1RtW1rD&*=I7*zb$mQ(AtWGlfn?!EaX~Ua|#i^31?PLjK^| zzr`ERFr@_O=~X@%bPWuXPIyR0C$@>ZW1+3*FdQU={HJJ(sgHMrO)*`KFJ{1Qn-w|!!FW7@Uw$9N4p202 zWgZO5I)q18$)x`8MNe2L3BZ`P1YN{j|G0( zC_-HX*LcaB9LONJ06{JsO=kgs6{G|Y@7w|4p=kpei{LS3iNe%5GQ$oQBe?^OLCs3( z)Z0&!<)P`}1$1Tynx6r}VV{_~f&`K(sG_~w9*zh)52w?s0DYvRaCkMWvG_-AHH4+g zjoJAC%|tWVOkI{q8iPUz({)Tk60D!!&R9%DGNbojN9jgZ?r3#E==Fu14MIV$)1>l; z0AiqA5zut8)vn`8^kIz}GzGp<&cDG~2!9AtG{9Q5U&H(Mu7f~X)qfBJpYGqAU5^E( zQn?&QAtka6{E^BIYT58u_rJLK7vtwje`7Fwc;B4>XbOh@0% zFnJR-g!^!KKH%iM+#I)jcyuJLae6h%<`m8}piUD>a}tGs&@^5gH;yFE8U~xQ-@>2b zy^FtS^Tq_lf%%(e0RS9qMWY1oUhi-1H;=i%Z$_Q_a!(DayZiG=T(@t!@-4LS#4N0f zt$T%aJ^8j(T9=x4Pt64#Tg8<<>e*b-vo)`0YeCQUyq>KEJ=^noCemNpG`)TP@}!(B zw>7ft#MF=|B?u{so<4(jOd+SU5D!O4YKRmXgt*98bh&5y@N#A@KZY|PeHJa@~z{{-8x@{ z{$GT_%OYWdMb;cFvc4RPta(^uEy5x*i$#jiSvsXZJ*&g!Is5##p_7$Gr&f$kDCbJ4 zOpb6aN-f4Gv_tWM-t+Mc^TwkA1)2Wux2^iE^BK8nzs1bv_glMuYklSrd~Ah-8QvWq z?MW#*mY=ZKdLCGfVqg)Npp~ZUB)f%4=Nz>4G_*4%+Q}i2h^FHdVj+q^z+}lzGzZ1Z zrwRB+&%lUZkZ!?)D6(m(G%kE|?jwn!Wn~mH<9Lny&&Kp#vHRZ5SC$H*?X!oX`QcSzIXaUmOSf!fm z@B{UV{{Xp`+tqXCNOioh)09eHSRz)-^V+wORiC@Da&6{bDb+f%GMX|^MAPVt)%mo_ z&3)_TVCr!@B?`2YvjvDMhC=0*txB1ll$9W3B3N9T60jb)QW13wB zQE(YzA{Np(pYMwjliS>-cz1lFNdUhYL{Tj%p>%ICF|@cAog8~TRib|!NUN+g$q zfMtR#K>9XmvGj}Z<&E}Me_05wO<~N1mjcuN?z{rb!X*?$;6uwvj>$Nz0nqY%Z9( zan+}H-6}|B_7tMPq@NgzjDHKLL^2k{gJYNpY=$8k1MfZ?j3k=0pDtmx`OQp8@tV=J zsIWEP&>0&`ip3YJR9>@}*&f;HrJ&^814>IM+{>?-Lf-{C`0stI4B$nD?KHqkb?ahV zlU2FX=%4CD0Tl$?PC25$8r#lJLKUz((m9AEz^i@vj^8X{)ws*LD>9I*y?NgqLW)dw zdD3!tW;s&Qe%THvwnA7jo}b)lzGmgl(0Q6;g?;1HIMcXc8Cf?<*{dme=-OH-1GQqR z-)JOs|JeevpPR?sU{opR6;BnNR$z#Do@_?i-zgI^C%w-~r7BTSnvKF2iE6dTmq}h# z<`k(v} zX6Yx_gffUDf28Y5#AH03hUWv=EJa>Xbm*3QMe%L1R}|kY@`^5Ui{^AU5Fjv)MZL`U06KhPA&48YPx0~62B%|SUobG^n8Gs$ZoKJ z0R_xVfm<$6q&Go(P94OSBFzcfB4UP=m>;DW650OJ)IdozPWJil#LK}9j zdFObW2;Px07)+IS`h48KRSs8V1jwe3feAf-u2XVmQbwH&0?-GdFlDcOy|rz+UCh5o zPwF>aqkh|^w67W1JEgFX*OdA_Q8m0&zh2z0nd{e7{nEuUdCar2nAg~Ja?@6wh87)oPU8Ou0;H0xO8L)L2WN>nMNZKhFJkLXNsojmOxV0iz zaf+c-7VxpWx)~F-Qbw5YzgLC)&r-l=`|aut$>+tS(@c@hhQ=hnj8$li;#It5bw;5L z($NO_1zaNL5nn+1AA<0!%`tcJ(jB-d3|<1ZbC_X%MbiMe8}(8E$sk+8eYABnD3Xs> z^R{3$+o_J1SP8oTffizUYOZ&qj*7Z0Ubuoyu>|3q4JQhm+pph<)Y56omRq`$d$Dlt z&CV~Lm0df8p+#%g%B)?%E?R=ba?eir_SfgBwtw;3Nu;Kwo40n{W$WJCZt2x4fTv=6 z=~Sd?krJaK4eSFbh=s!lJXER8#PbVYcDz~ytZslU<(8=*hx}hgL zOXX7A6lSijA+4#;cmJuKzAnP#IN;_=8NJon2Xu0wbzUA@BeNS~;t=hBw;5D!mV2hy z56E;G+uIa*mlqNY@@}O`VLM?hWmf#m9MCLLV$pFE?Jn0pl0Nv^Ki;QMnx%Sqn(LvH z=qowiKqS$vD=I5u@|vNFb%C0`D71@ssTrizjkx{J;`U8!zrYC4UNnAhx%Mq=->S`V zUzAu_GSl&v1DB26*?E0Fz2JrR{-Sj)M~^`;S1ZLS7ID_Q>S${ z&rz8OoXb$~r*{h@(Oa-e=ThpaPFJ7%x+wgJWU{-2A0=KA_KYkFMsg)zNk8=ppSBC1 zcI4A+xKQGYDx6gnhuyu!+mGoT{sD8UEkH|yew*~$qThBgrn<^kx>=60?Lw4w3)}Mw z%X)=ni`#7%mhBXl?XU#3x0Ps-Btf~2sPlO~7QS2{1S}w|MX~FeZ+Rh-oBkq6=Xch^ zO!G4$XR@ZB6|Uy7)HDiF4~0o36_v8-g;J5Fg*42UiOQv!B|4z(omK_e`lOhUkuY&1 z!-kBzNj;iWV(LAZNe^bG2Q%)$ypLRRa=$4pFKB6!kEsiCi>748qSidwr(juPQEt&3 zG+{0edT-frTCt2)0MDhzQYPtj7Qxe77DcEBr?!k(BhkLH?B-kM(9EJ9%>_HS%-H@g zJ8`albN`)Kdi>^Lwq9PC?>x|^TeMhDa|&%*c%Oe_<-u1{liKNj%dM^+&G@gO(ikN=jd53<#>nr>RQO%_5X_PxET;<@DP5>w zU}nCKsnuB^xRpzO=3L3I@N~xg%v(!{m-m#`(jvt?3F@9wo*Y?`n0GJJ*8N4WJ9L*4 zz+&UZ0`cfxmacUB1p?l^ENN+hXSaMswRdSQy-;6L>snbFFBb_i^FTchOn0zlEr(xP zPep>oecDeDY98~RXR%AaOPkWZ90G|s@1Dl5yIQOYO=9JA^l5oiG?MapVbRK|SNNhJ zESethwdKueK;FFn)f|myLG$Io+s1U}_deEFR_fmXhF_kCv*}~f(LX)^r@Z?0p{{>e zbpM0X@|?{550+;;kNH3U?eBkx5$UeiKS0ID+aDfpe|Wt8;qmr|$J-wk-~N!!r7!Q2 z)o*`@AL*ArsCxnyT>w#`tp6CnL-ZVWdJm~O=W|Fd8-U#%h}G$=w!xPi#5M5T%7O}+ z8rp3L`Qn8a4`d4WCO2aBqU554OetUm=@EqY8^WE&P%?;n+=&27OIISquX8Ka`%s0U z*M)YEK(&g~tySq!y>xM*TCJ#MxuSPyIE@1(?Q(0~3%bVOg6=U`qG{D)s%EbF@LuhQ z^E;Sxd&0lV^$A7tKm7D2SIyo({u24$v<=V8%Kt6TeU$(IF8SXmmj73a68Uouf0q0o z8b`iLnMKKrr&l4xZ65+d7V=6r zyy=>x2Y|qfy_X=qC(=9Y_KWZmWp^n}s0wLWL>KraU&ks*Gn1?C^lCC0N3-;c@wDVQ z%0+l6W14=BViRi;N=(IZY`=L+qR%_0`(l6VC0%iBe*e8pgR%WezN{73!rU0LUcMH- zEU5?ka&L<(=IhbRl8TsEqqIYOSxak5-Pgz4UBGL+CGQ2$&X>V#_of$2kTPz=f>&!q zig$nB-ldJu-P_;aeYv&Y-8%qOe!Gp&nt0ciY*GBQcVJuH{oSpDF6()W`-@J~SM*T?U+De=f?oa%)xJr@#f$dCtcs|(;1l#qK&+2d#8c6Q!vbYGq?c@l(Jl*ary8WFL#r4%U`#a(^GVL=MF<&K* zpsE@-FIqc0FF>}eZP0UClRq|#cMKN!Of3h5kkveDZf?%S%bFU`9-XxjfvVl4aeW48 z&IjjT0V`m*J3DQ3@zeiVi0!(zZNKQ)b0C(`ioXVA^I`Tyz@Q}fzZrGY9UEOrMNOr|O{w>aZ%$Nj?FG=Yt zg`^I{LU8gg_CP9Ig__~$V!Tmds&^za04>11#;zPkKCq}U(bQf8Pc<(LjW1*6nkpsA!W5EyXuY_?hzH*J?_ zz25_6;c5VSLBH8-V)m&EKdLo_M6})qKZ2QGoWcOkHu&D6>kr`|s9szKvuPDx)p2lj zHPxCve4N0)EOnNUJr3w9C4?6FvXQe>t}ld{0t2njFc|iR6Q1(Qi@*nL4yLe%?V8xc z+?TTC@3Cc&fVVo?h#ySQtv`$4f7uFkxl&6?KsOTwLGkUkqB=QkoniCe!GAEf`0M-8 zceR>kgX9(dV^fqdj)jE%KJY7=5(4i}oRUV)Vj9EcKgYCY5z_r-7&Q#~Ao%EXN>rb1 zQvNr$R*qaSSF&M-v!I7q_7t$p^vci-4f&sfXo@GM{FG2 z5xI*2pJu6Pfb%zILA}9v8Yp5`Q%omI{DJmQ10?jApX-7*Q<5TB@D)uxeJ<>8BQXJTjAo-I8s2)Ub+*(r8vSsJ)f&;P*B4a; z175{6!Mm}7X|0)Pj#H$c3d8zTw|%YYPUNpmaRa z#k~^8`m%mw8g_?nnPx51@8Y(Iux(T_4SjyR0s6oF{m*pA_$V-qFZTm2@c($O>t_5v zj%gT={-1yQ_^&J?6@`K2gTJuCWAxXfm+8^V^yp=J^fE2>GCc_|M(FrC{&DY(?kT#P z`zY}u6~%`oPrGsC(&g1G;{!sM5=OwCLK8`g*VxJs*t6AFn22 zbx<5Tl?|bq_WS|bPs(Dg%F45>3p=0J8v}yo)#m}~xwF{mGPe?`R-ir){0ZNBHT@7? z%;cXy-}-@m85W87_%+;6e;w4tfdxMfJ$bivw6nXtU(L*=E-q@t?|YLQcxmz5vUoO3 z9( z!9dGEiGd(X5KQZ-I6P_eAdzS^g{6sz5mDkencNL;n;BDX{tK82XyE67*&nA*#i?Hx z=XKGmi~gC^OQD^g7(rmsuP!d|W;tM$(%>6U7%dyYa3UsS%H=kVlXr!52^~7HdV|2H zOL=fOI0O)`BDQl}2j5{L@iB7W*h-XL=VE-nnV6JYZLKO16hInV-C5l#6fi=4ZC{~NHHDy+l&Vd1@ z$eGa{*CVtg`BTy8H+o0FUx)r>!OQbC|0rHFw6)((*4FT>*xUUR)9u<;_n&5~x(Xw% z<6@m2SZ6h{mVa&5S79MELuz?TCZ0W;m^DFCVsS^-X#;!Gnu8i^n^x+9)krWDEBS$p;O~5 zPa;YeGZo=|+uO*z$@DTaK+iHaDy7m&go47bE^dL@--cSj875hnorY)nGn1YjIBTiL zz$rF)J++77u;Ae>o<}|I!kSj0kUC}yU%!v0tqJ7h!sG8aVjQEgk(F1|@$|I|8QL9l^f%+_j4>tn%lR)2DT93%h<&+H zFV8jU-j}P{@)azuu*O2?Y85$l?Vi~GCxGlO8%ho>w-Yp^y_htfg>|_DYJj`RmfrNIUj8<2|KndAXWprAp+RE3PoLZ~Qo1@(0HA-fm8Xrr1d1}XkUoowV znS7|Yd;y0~JzA|*k-g~}U2UEafX3^7(2$xrM`oXo@dmF^f2yv}I)|5lrGTSj%>E>? zTE$}E<@Alo!0!dkg|g@E#E=YlIW0Nn@Tu~sXIuAY+WX`21Se62H8nwrGV#j?fCKFR?i$)7jhH7gGgvGD-m8gZ<~m&R$R*oeygf;1i? zK;t2zGae)~qahB0km}&Okw2u{ruXP#qF^SD$GtF^-PXn4?#T;WPx?HGu28BUjj2`z zYw;RPf*!6i&V>6IM}P}M{}yFUx)vK`R*=!*ae%GC=!WB2P+?HbKz;}?oVU*sJppGr zzL;J6GAMQn_MreEy+yt~tVa|laSsc5&0QN&?58U+!iL`~U2Q`e!@ z3#8XuHWD643!!Er)bB65x!q82P4}kVor#<76#v4Mqx47o-nMQWd=Jm@PmmQq^{*zs zbw~KUsY zr%Ui^9fVAXhgKXNEWGl(eonl8js!p73#!}=WU^C*G>(1@3K!BzO-5k`Ha7A5 z{lRa9LaI4gS>XwmfhV()kcD>wq7gpOYn#xl zQPYuB;wLL~I%3}H8F6o5;~~5O76}MHr}G(XzuMjYvAcErI(G&lyW@LR*xbZwy#2le#bkGE#_fwhS2U{CPdDkndNnfz&$ z(IPA~pBg1at)&SUwu)csvRW}2lch|p)cuLt07W`~niA^J)?2sk+PYQP`ch+GOl!Yn>`Sz6JrFGyccSKUQW<)l#gu$CtFYSL@g`vg zY9x1qu2$b#j-9Cenqw$xP%$G=yE$Ld%9b=2vLDrL0RxI(WqY36o>ktSm21zu8&gyB zk!(#3>W+fu}72!a>BR zp_*!}MOsal>UMiw*&0-+*0iQMnM101!3VUo9%x8KDigX+(IAIj3U$eLoL+|xL*uQ& z++1+u_h#~<>ZbUDf6$yvU9>=>E1LWLl)OaPN+C80C@75JAEx@lQh(SgPe`HIVoR|_ zV^rLlzD;SDiZx-d*h_!KXwH3V#Z6V*jEkFk@eC2LRBMStotEv5sK6$$ANwgn0`fWLVQl&U6Qg8U1$ zmAmOGCA&vyDs>hL;*A7pYQJ2$IfZdPt?R(5Vy!Q8Ce+^p=} ztb(~&xw%={xmktO2Ul)wQ$ke|9hx#fw33IoSgNF*lr-a#@k1pDb(wHs&A7Z2iPS5r zy98NVT54NXW~0exCAO5n_Boe=I+i^CBq`@_v9uDsOKhnZ8I#0?W|B}vt)!@RR|7+; zJMImwbo7TNdCPIcMgts1-nLp)C~qjd(6l=)q#o9DL#Qn=20&Y9sc~cr-ft{RYUu@l zoeRBut=pnn4+hR+yDQ<4QbDn;SOwJ^PAQv{IqbdA5>(z^Bh z7)G$HJRVzN8)$?T-*1X{yGOrtk6&-?@BcTo$)*VvaFk_8RcvZqp03H3m9g~!shk=! zTawC1-U6Z*Pdu|vi!86j1&b_bMVmSqZhi_`3tC})tDwGBPG^^(wDTsPFFXeTdD8s% z0pSY>ytpfg*Jn8gd5UUU#WnxMu&K-*yNJ=mL&>w6_?2!uUD%#g-kz0f&n#qLDN1B! zSeQNry^fWqUh{3V*}fK7W3%1-&$PSFe;~dw z>f##^O}_!j^c!0*@Kmg9ejBY+sUuKW;%^_qT2ka2cy?Z^ufWIgt9=kW{krK=qIf-p zu^iv$cui8ns$w3mny41RgI?7tcUZR8mo8iD4$Id13zn_*=PjEkTetPqpHP^XVbbsM zh>{8P$C#8Iwz=fnsJoIo7FZ&6M!Mc~5(Is|a73;>H%|koV^m2o610ktptTSQZWk{< zF=^YP$Dk3@eMaJ(1%L}WPcCee@PS`3vSe|ksUr)ipb}T&$!HI&pxg0uwsv;Vep@e^ zYi+6dxJ%9FPJ?!f2JJ2ww3`|LvHTT9>1%=49}2s*%@fm7V`=8K#xh{|x6*|NBe+ zJ^5<=Y8tJBI73wCp!@@9e@`Al`FoP+emJZz*8QG*q3TyW zh`XzPPaZ_`d-5=fA5Q8a6u&1AqW3*{AhqwwLu!3b9!}|d@*q0jlZR0Go;;Ms_vB#| zz9$c%?>+f4b+0nK6;*X;Mg_% zI=vlEB9JO>;L*y;Mx~-k%e!*|5GllW!A;N;M5YJhoeg78ZWQ=4*^tzyrtAM%J>6>jAHVTm-Lv=CtF=?{ zes;FDv;Ca@Sbe{;{`10+yIFsL@_WQ5je+|FZFEr-&g@T&I_`@EXaQiIMG!1@X(3Dl~VEEEB=wgEH#VSTCS>E))bZvnufL4dK`;gD|N zn*}hxuPSm3KdjfEuB)}!fUg_LwU(kP)_-WOezz_XiZ)%Z!lT-EFyi$~om9bqet)sG zf4uwt^SYs4;lq=oxA@G|pH<&q^MA1NpS7kC%a{S~GH9x&{|TS(M`wT)O?6iO{mR!S zpj}esPKK%op?gF&3&(H8Vh)hWZVA!iq zcXnSqT^CLAqNm^NgDmt^FEP@KP#2nJxj8n_4o;5?& zDn8v@-`rf!vOr)rcvQ*K`5)rx`uq23T*1Oz*36YvCHcX?KMw}+Gpv)zJH{QazuwwD zI!q6o9*NcWqxI&{??vNy^uX54+|Xg3AUp2lXD^>3w1#>UMk>7JiCAeypfUO@=^Jr@ z)PLtszl(36w3?>fwCb4D9BpA!tTyI)M6Q^IKS_-XWVfyKxCEiIKL{_iOD_34vUzJo zzi<>A*#a^0V6*zZ5Bnn3PO9S9nvC)})57-Q&Tc`~M3yV8i)h_kt6^pQgo*4N9_;^8 z1qwpst~rCvwZ4%pk0N<-`Ki1&l7XGC`Th_1uZi#QFMPuF=9NC5PSb_qL8>f>h4^@4 zF`yV;S_#l$Ms#^49d1kA){dNp*^APDeWe_est;W5DvW}u))snByrwvM2MPk+Cy!DI z9mc`3AT0yW0>LmsNPI#OgfH>@71iwim}En(HFfbZE&*B(d?_X*E6Zz;TUwN6CVoUG zi$GS0dLQbdc`>=Fi(uAk)=~5WDJ1NT2RP4opoI0+OMjYa3|a6;KCcv46WXakG7I4S zjF={=&UZIchD6E5GtFJ&b+B|hDKr-k6Q!nFQylyK!7U5P!@x(g$W_FQe+1$w?8Izi zv_M0=G?d0Mj>1b=qk*!e&_!=myeO3pMxp5ki#4&yOjGf?)a9+M;WV~Nu-JMI?VnG_ zgJ2e@YqVjOm;H0fHkxT}ih>^{hm6KBKbnJ-9%m8EjIOHIhgoZ;T8MF%K#SIWui?KR z;S*R&x}BK6jn98ox1v%p2QWhF5LH%TYT5n$S&0z5izr%=Hs04nXYlEIb03rA9G?J( z--svm#~(@IukAnnNHv3-G2OuP<72J5(3^q6Ut5_53Wk8>B-aErKto8kP(2078RTc9 z(dmL1@&1SG18npM@%6V^&ixI1C@MvWiCrczB6`!5<63{;{Mzh-bh}X~_0@~nP|e7E_{gv5ZuhRg!O7i} zn&0!M*)8}){1m7J#6y2{IZ*jtNwkp}Vux{W;Vc#)h#=+2Xj~DS#J1oI5Q!?hT}{{Nwo5A8-G7`_Dh#zN&2<{|xPX zZGLTS?d%-Ceg1Q5FXzi2Z>jQ77^?idp4u%SA-*ZyE&9%wCWW(;kegyMp6GzDWu}S1 znxX}W$^%1g&>t%>?_{^&=Kd;$*0F|m4&y&b_fCpE5Xkr`;Tb+jm>F@g06^UHrAE0m z9g52iKVAR+`_vOC^6Z)R zWb0t(>H4?YgMEIYJ=%VAe6-%1OryA`V|+5zpO66m^?LK1MNlXG0u3jpz@KgaPDvpR zSkP3rcQd`9KR_IeU+kY89=%*|4rb%%QriRt1|(RYb(Ftn&~ANx(c|5d{X3N1TDI)_ z)l^AknECz9_Gdiyd(#j6{smeG0Yjew8%{lpZ4Ym@-+vbG*Ve^*D3COB477BB7MdGA zc!9RN@km;4Ku`k8FaXjaNaSj1ruy2T?U@$ttHRD{ zYrJp1Z;(|;+HVu#Y?-BhqP2URnN(^<4?La1e#_^hmsVq3Zz6)g7&7ls93=cqgwztl z@ebKzv6WO4WEDw0Evf$#)dy83nxz`}2^&a1E;C(I3%DiLGuG(!^wVOp@eK;T!(p1h zWJQ;6pXx$DpRCZyBb4s>*?D&ybuY9Rr_ayN;+OjK7Z>sKi_G)WlUc#LZ-LqMVNU=a z;nE`VXo3csf~@YTVZw}ZRw}Dor8g*Q15$nZ+Whw0gvV(1Tr8#kP%)9V!r|_w=lIJ= z8{{ysC4OgS-BxC%BFs`A%n=DU^oZfCwb+TAHY ziKc6EU{Z8W^cNTudE(X3p(t=rB7&NhL&MBk2joMjOpc>k{(PLCPU6w-cHe=^co5Y>KW0ubN>+WXWijdlJem@!jW{0^wH&rju zfsOXA>1rK*=USZ8N=}>5gGN!;Ao8EamG%s&y^>87ib#$fa-$G`NzH) zv}Q#gRU{+cu|>A!*sMkI8~#XO$j{Xb{U#vhlC`5*VaK5KDQRYm?6h@X5G?R$JPVpH z58gJ|TJ?VA{Yw4)H}AihMB_`0cjhU5emq|Lc>Xtu|L)Q$?x8>V;>&*)p8qu+&&$Ps zdv@zF{`;>#|I0V`7)9rQE25yJE#CN1G@d=41%5mW{CF1l@htG;S>Wth;CtSKliYZd zJW}@`rk~>V-s)x?!6(%ERXQz7-5#B6@8Bsjk$t;$^t$_c>lZGCu{m8>v7;IZmbrqs z3E#ff%ju~gtE-%iX?u771l|I=LxsbgF7CTi*~a#(*IUOwu9;`GJ12<*(HbS(+(jRC zzEhJ9Q}f-KWkq&(j^E5L@fw3ai;G|!2o|CEB`EQEL*}Sc)82Wzwf}(Aey|+95^lMK z?0LAA6-nS$RzibYQ39e2+@1)9=Q=uSX?|*G)JHw1Iv-b;K+{@H{PBl)PcWO)8j$e4 ztp&|-ndRC;kS%DAiqy(?(3`!J?N{BOw-1kwmd7PVj)LbYw4g1O{7P*tzV-8_H;y7+ zUj1JhUsAKJW^32#8RSU=yQq8`lTu5aFV4f!w<918Bi0j9mhzwR>Om=BiU|Cxu3Q0u zTu?kiEEkl{5>CB1XCEUvpo$;h7ex$`MJvhpmEvhSnV=A@VqS-@V3$7VN~f2a*Z0TW zql4Z3f@S7x+1144Rz&#cy}i}mYA7JBX;;Hj=S(ZXS?#rdgJ4uq=)vpo5ijB#NT9_*S1z0}`szdb%Vgk}zRc8_Zn z1fE(}>f*(VlP-wxhugHAWt%v;i5gU=K&(#V{m2W3uYAzFdK5FN!6yyy#f1}qFD|PA zJYRUIZNnJgq|hOhK!rSyPz9Y{O(x@LRw(Ag@Og2xyZgo9xrl-wJBd>8loc)lPg&VQ z@W{d`=oEk_CRhoj((#B$RUxcO89)|9y^G6wW!Xz2GEMX*H)0jAd-(=3RmWEa3zXl~ za~7zqaM1#ll`UK#eO<(&1u9sBy+3UczI+uHE<<>ybqMdW5aFFxBK*Ro*aq3?_0Bes zj>98Rs28Y6sL^%@a?qyJyRJ)_)z2 z`s3?+Hiyh?{3(bA{)AO$I>!A4jiHqfgIMuzq^L1=_Ru$gt8_7ruKlQ=#-t2#E-b9! z=EAZ%YUT>3F!YX?`Fv~p$G-?Q9}qYHMC5#E?0i`CToOOe{ocpr5wx^)5r&o)E=19| z^l~`*M3Xd9@+_;e=}TXV#bVZ<(j{XpDM_bXVZ-KFYy0i0^p4Q&#`Rd(f{|? z`2X@wz4}u5f64Q+H5hO@wW)}LX%Kx1`tQ-GIeDK%Uzjynv-HKw7pXoq!8HfY8_+AE2HN_{Y6tX z1kSx6qi1ZEj9_MY?4QvZ}zHv4MOkES2QH>c;(SzVmM=L9~V7-uDghfvhVBEMrS zpZR%yo1xyORotdbfO|TdL7{I>hgc`VRJb^#k{Sa)SHq}thlMqw>A4z?{CHx_9SlJO znvRmDO9q2sjqy&3Qu~N0FLidd7q40J`z!3`%xFAM*w!yUl0nkuT%9i-}HZTj?`? zaGo2cc5e7TjpvpJEyQoKvi-l{EoMdbKMLd^KRr;8=*v$4EU^EzEF&BL@7RXo@TL$-ke7v zuszJ$N(S&fG%Jp#VNZ-Fvv3&xm(Qjv%pipIEAl?`#}fvRCk!4>7(AXZcsyb7#U~8D zS7A@h56`q3&E|T1^q@5Sl6~kUVSNQ5uA(r~9q)(N;u~dTBWW#zU?i_z$8W!G$iL)G z&whNv^VGJgP>+w~0xR1e`+aeHYBZZo`%L;^;W61tRW?y<{Fy=7s5#%zc_3f}7!<&{ zhOPs_*Vn3SlG{YSYfaf848(NhmD6%0-KptTZ+RHE@_y%vx^ehd&JO>pSQBl${TBMC zZ+IhnMLTk=#(zWO_tf~~9@}`W_DwQ(ymvT0jGPSW#)xl29$#~*!eWjpMi)P4$|bOL zU@WFtIGEep)L?E4dbxG7gSjm%*3JzkT~4jMA@AHC@Kw)Kz6$CVG@=_LxfnWC#Vn`- zWpDAGZb!QvIyD}u6x_^sD6+U&H1bxeB;NVm&XiOGu?hx)7crYW_`*7NK^+U~w0Q7l z;oz;J!COUxcZ&vZ6%E8G7>Et!EgpPfomN2|?8D{3TZMzSiw18O4c;pnyj?U9w_qRu z!CRXLUs%U0r~?DP^?2}hGI*i_w{6u1QYYV2-)?B1t8cf-x6cWIKx**4BnxY6DVmVo z)<|pmR};1QX`>Esqf(apo767N@0rwgDTKb0?c_Gs$!*dJ)4%dt^3tBg5&p@uEcas!knd@2e);9p zKHJDW-TnEb==sk-pIYgs7Cr4+xuVB!U%#e@`LTz1NqzCVTYPuRIHX_sPTW=E77Q70 zn2|i<0v7l-WaPj;@dcpSZ`~2SQk6&}9RWN7V3)xlK=px?m>WQ~-V9TA!z!6p>fNmj zs^Ah$@oIb>dHmEY@O%G_I=F~}CTr>1e%#1G(|Q~(ozgQ&sfWXi==0j>1{ zEyXQ%^b97BbHp0-9XjUXwDDxRGFdXoP6jK&k_UeU;G4z3FDz>nl$CD*mom$EleBb` zZVAeoi_6OI3JZWZ{l;V#E8x>Q<4!%19q+ee! z#awDpv<|;?QOwMuC`wArtEQ0xG}7{fMm(Kz;@MuFcD8lWiG{z2emZxcpDvM4@2=GI znWNLrXPb^jIq_sMlTGKYWb;m>@R7Xz>ykHZCz;uu1Tu7iPFKF=9P1ylj^qo3i?Kf&%jiT{j0F#%uF)3@8)KGD@aZ~UW z&^zcT+X?|t~|%a496m;cT2viaXE*L(E;KIVUW z^v*tdXCJ+@kKWmTU+-*kl7o{2;bBcY#UcHwLVHRnPm~`PxNmQA#a`H@6QO95b)g`3 z*UW1htPm7s_PR?tv&x)YH-=STI-waKjMZUUko#wTQZP#5Awho#2zdm%tDDJNC#q&~ zxlE$BY`F}`s{jvxYNPHfxu#I|i46Wi|CwllG9 z?>z5Yd+)F6>so)hYyDoe`ns?4IBB}Imck|%R4Q+52lr|xWZN7Fg0;daD?^G7T|U^^ zP8wk=K!b?26yxX5W-wi$H=v;uJgcO4Rm>JXZ8;wms0fac2j&;!-0~Bi^L5-PXe&by z(}N0}Bqq}GFM{N0Lk2>kudjj|7=x|Kqk}zCYc>wAOcOfe9%ZGMTmP(P)3S(jJUAdw zi3|slCc2#@B3n&|sLbZceW4MiNGpefcZW^6y!{)KBcR-{jAc{Dr*=8oN-{@Bk+g*j zsgf6=w4ASkiNFX(!RBXV6MCUC%gxeT!xOpfPs=1J8zVZl*k!t~wk!q67xyLuA66aZTJ zV&7~1m_4UIPI#Q}>giX$P~wiZqdpX-NaH5(UH%+h(|ekC`0d0y;mGm@_;K{{KmGiM z05RFhGdI{bm305h2Af{s>56{ueDgr=PJG`66v6h7gQL0w zA?yu{a3XRbe-pu_GSO~jc3!HaAkK`#1oza zf7+q#me6+~ChQN69dGi=pMAsZP#lC^mdzLDG$M1P~+)2C1{6-z=s4k|Z$aDEj$M z9L2>xyc@xBXH%!O=9R6bfEpj(%I}T{b9|vItMulM7m1wG=!-<{fNof_~B}pR6UosLn!-exGDcq0$ zzk9Gy71g7P0pN<+;e9z_^<~j^jHO(82l*HEWr`@j+;kx0mm>eh?&`VG{M~k`bz|Hg zS1@dH+j)Fr1LMnmvk*#v;H&du*%wzduEfJ}a|OP=)!Ug>10ulwq49IG{H7hwgq&9b zf<)lViN~1^J)cKDN&D<_=O>ufZgI6F-Re0DVy< zzBH8T0^*Nl01x>FU%EhpNENzEiK_=^O`D{s4QE*HXe{^o>;J?I=3ThMT4Ps~lP*FB zMXmv{#9>vNb7z61XE0n?pn-a&l7|St`UT^N^XrW&bw@%3#pQ!a1OB0zu|!??eU`6?X`-h1_ejqlF!|FIyj32!YDdSODm)+6Yt zjB*>5Fbw$o8Ar_`t0sdi4K1eqT2S8%9dL?92^Bp)YBN=_tab3Lds6NV%K%@rB>s{u zM7+ruj@lniDD(4K&H6ZbWG#|SOz12#$7pp(cQbe?5uVnU>eE_K~*^d#IO~QHVx%MUou`WtvOl+)~3_swzo@_*F)n z>bEeezyDC;sTq8zrG#)fmW0RHI55=%<$$;y)pYj$g64Qs1}K$K0+$6OJFO zv47Pl#fUjJW`*5TNN8ke){q>v@+k-|x`bTZ3|Hlr=~7%IY&T~PRj4jvmX5kSZA>0F z?5aL9+tsC>W2&O5CxRAKu8e$ms!^PFJh{^4HsvBh&kvGa6o>9D+u@X|msr{Oiv}2K z_R*tb0x}nxmjwPg1;y&|GAKNWqU{9!i^23|3xV_X)#i`=S(JfR(3j=E9vKD`pZC6d z6P0N$O{!&Fs`+sV21jSy8waNo#5xpj(&a2z>Ns6rYCLEq*`n#m!Q552xwv2Wa;>^> zgGTkk_3Kv`FG0d4C9myre2Wj98&q)aCuR}vmkS~YUI%~_%*Pd?7&8zr(;!hc{_#is z@t8e*#yP5a#Y+;q{myIj;&x&Ss;UN>;%rDVSd@4+R z#F^jPu_1RJF;?l5{4Mw6yh?3BI6%&s-`F0DU(q zGHz_pDYZN*8;I;uQct$>&uO%<70TFkL}XlTX-uKc~lz`<6bqKMS_yj*l)XerGrH!r6#gOB_s|_%mP-04TdCqiLcm)J3%NWK;DPT z9ZKr^m;>#S?^KnUXPTRprY(madgdfbD>MQHO2TjO1XVI7#KMJXD1YCy%8j zZ69lFWgLH#d>7rN=@ii&GROBbgo~zQ?4W%9Q(jFHGnz#PeS=Lw!umuwws1&`=mT;7 z1C(x-em`>UcPGv=i#U2yJ2^GFRWnw|f)(`T%RgE%d-6bgL%O#QmOCg~GnmZ{rh`Yq zJPl%~9pjW9Cys0ocWSXU;8$ai(BCfG({dOUVT?suNbA*vA+fAK$gqrE zvj(C?$3S$rS}S(3Z-Fo7@g!8QNDQ*-F}t2)$8ub~e|7L!J-`^+qwNQzS(*OW19;$A+0Ll2KOlh; zBW16oxut{=O*L}14nBQL=G=VpmMXRGFF9`Mq+i-$Lf{l>VZ}LtefPYiY3p07k=itl zwI#1(M(n9-3Pzb~tnKNJnN;Izvl<6!4$v|3U6F28(-ciY z-0Oq@f5}1GJs8Swky)Q+jw5=#4iJuzUg=&}c!tSZ3v5C+5m-Jj)pAEi??k&3s2L@XLiUi1N^1$_gZnK%D~QUd zSjsGPFoL6P~no#~D2h@@5tnQ%yj;ZnxeVc;c z{E!2V3Pw&2C}6ZdqEeWbGNS0j)ak?tBTTveLBQWbE;i&RvJSA!&$1U2+R;3+K8PGz^-{ z$eWy6_#BZ-WLtTSGAt#DQm*$-4bY1Onl+GXkpW@tQ)>20Qe<1jKCG5~l#LW=pq0=& z`<&pB%u-&be@5YzVYfrdp)FKNwfzvNcaErAO;|-c9EAyYYb!p)G@arAuN$9uI};MOYumCM>VR?{9XrOlQOQk0Io}uyEV(?#%mae^I4$7-=($H;rQ1iV57qgzUN&@KK zY%%uBE4`z$4k0(_e`~bX@zvHfZMhn*$r-M}!^nGSM8MG{%}_<{@z;k$qMvu*DUZD297bicx!%C5td5hgBt4dgZdJ z(2vs232le;l@Ja2M+f`hV4<6A%5KjcASqw>$#^od@TEH-9QlwYCcVpAdLT(BdC2Gn zYqOHEpf?;z@_|ht!#G48YR}#Oq>Dli?CHg zXBzg%0PO*?PT4HfqU0%3Mm^@+vaVGN*i~{T618#r&{F^R7n?Iy(eDhVtBOg?SKW+A z4H|+#P3GXkWI~d^plGm@lPgTk+)*JdMg=q3G!JOG#%+1B)=)o{Yk^u?+36H~Tgtsj zBs7R*SEe%^fCrbbE2Rc?n*|L*tgVTz6gz-mOJ~|EE#3J=Dnr>5{Zs)4wbX6HHW=OU z7~?%5AA*!yodI2#-VZXs{2wxKV~M|?YhL<;4B*WEhYTQH=aScUu9ri@89J3)NTM<& z-Uc!ny|{OwT-kSj$DrTu0XxZNiZwo)?|hqOiCukh%rxQO3w-H51DYeR{ZKrwhW~H3 z^7#I*^*`UX-VJ4z@ZSv6MU4Mg1tFXn69?XWrm2D;lvHj{``o9Tz<31okO()IX z+($O|@toq^Ci%9Rp4~^XeMdIS5Ktd~j$t@-(}#Yd_gm^Os08y!w3h`Py6`QxqV5r` z6JsB<4uy`Y2VSH-x`=z31i6-IBMbiOu1x_Teb8D@>yc%P$=Zq^BWEcJj&b)Z4(o^3Gm5HFdueJfWk3GsK zj{ltDwXIj>Pv4F$kJ;6rPnx1nR<}07lsUaf^Bxu32>=m=K)y4-W4##Ae;pd=;t7#76NiV9Ea9iMgDke6=^E9(ms znKXZrLei zo*iRuIEi8L(*xbFltlRfYLD;}Zl?e#eHZf8FHv=}t8`X`qTSc2D9P8^2q$8w5S_ZE zL<#?kkwxGgdrYX`*Ce3+Vw8y4eG7DeysG<~C%}YRkFHmM9`r8~G#K2{9ZK{ZwpIDC z6chA`>RP7Tn1YeMXy8a zJryP!+Z@LURIFRnA5CG~THs7NaIA?qYFYD3n+^*I*yJ`w&@@F_fh}eqQatDiLO9?; z|0kH=nN%5#n(03b%dHswMAd+?ZGXIDc`k7E>2>*e1K2+jfS_aPevk2c-Ln76y6{y- zs(9`Eo=dpf8T}SXdn=ecDr-=hpm=GsgPKYy-Bx8|gj;uKT|()3>_w$Wu$CSFyUZt0eyQnKSRfcDL5wmxkHIvE51n{Ggz3t@oKy zwHrk6e6U+U=;7goK+QS-xSwCr2gh}w8(~KK9{Uc)_kV?E?w8{K(`Ys%s;oYNfhw_s z{!Qt~ADJCTd|Wj8O6fSwAsDczVG^)6qQz;~zk&xnqN}fqR^nx>?Evl}isKP>4`$jk z&dd1|PzOR2vYH#*pHwiXrtim6#IZQQ{T`$gVYmA~*=8OImlJ_}MFGFT4B7cNP==3};_Xux~20s+bQRvMMmgV%JtFJXJ#H(kuBcVQdzB z57?0x?S*t=&Ia<{C|Z}_p&wVt6=G(C1D0? z-Ip4omKW7y;N9t4Ewtt?GIzI<%A?49@~7Q&gsWdCq2WIkq5I>yZ+)9AkUXlV4gc;f z9n5SOR{xDDhF(yb&}8&`Y-w5a?2xWL&Ox8j^_|-kaGTqN&}_PYuT9bJQnP#2>PueI zVgvfPBPT#bEb3<)rRz)l2Ov4wJ)h5K0D6Dr>#gba@ujH4@b~8WBR%Xy;m^XPo7&A_ zbSd4h!Io-FMMby+)hk{9h$}tQ=;U!h&92Wxxhki2@R$X{4kV@&|K{K#)15FE>pbX+ ztw;UGbQcUrI&+Q)obab+;vMb~+7-)6JNbZhC?= zXQ%`anD|um_i9e**`nO5X^~IsOp4ZJ3<^Bnq-Ce;vS%J%rczu%$pXSBO1D!(ez36T zsgV0FOi1>h{p~?S{-U&kTJED>g%rZX1j@+0xUjIsuEL3Ii=iXa3|6#Wxk0cr0?gJx zNYP&7#i`Jk&M#Br`3lq+r@8cagKnQ3eU{HxM``w2G5a;c19aL)qp?ToiX?)q29a_4 z)GzP$X6iCU#zBw$0#!clwe51U(z((;!jq{E_nruNzFjD~zn!C!Hh{v6uA*og)graK z+#=Qrvo$X@(+agUFZkfH^)iGZrx)eq+^P@xw*!NDFaIX}iMQ|W)RdU-ri+o68G!5; z2X~Ak8DR=2?f#wLA~1flzc}4LMHu%*;0CSU97l)KYgCThG&LHJUmK4D?#!|R#Z^@Y z*QG(5x=UuN0vOZa=3lLm_U9G>VB8-nvtUa}p&sN5GDzUBB_QXKPnck|J~OO6h%N9pnDoD?SM!iW>8( zUOg|4-I59hPDh)M4}i)WvTqHLG6OP+|HS=cTyJHUSHecsY3lu zBIQGTr0rQpO^)Q`7s;D~WE~^@+I9LIQ5SJwGvvkx9wNK(<^Y5L6M#(BFBRnFSS$dN zA~Dld#QmMZ^Nq%hunWR1kM|KOWu0}fTSs>{wMIUD`LNQ+EkgyW_IR!-Yn?Q4FG)&W zM?TrukwXp4$4*ZSSh)<#%TIrp5m%^~rumx|dK%T5#7`bNx{JY7cRNWi3bsrU8&sS; z#G6XV7kaT+xtpo!^)xvt{O=i+k=5YmZ)IaFpgKkc$vZYp1u5LImiCp}COziDx<=T~ z&XL6$t4-Y9vRrjSegCK}Q&nebvC^l8)UUF-FE2)B%SKwUTCYiX=JSvLqG0sxdf>UB z4mgV;PT{wX&KvCu+I2hW7&6{|v!S$m1Zac#K?x#YeJk`N#SOU6R!%NhH3;~5-s(?(|M z8ffKGxw&nb4v+!05Ol3ez7ZZc_17;39RC?}oD3IEi&X{71<3??TamkJdk1zTmuDuF zw5>dOR|MC8aX9%Bd$cZsO0`Dl>Y6MQl^SHKRd>{`l4zZ6k-kCMpf^)mtAvE|#(x&p zE2vvpW#MEGr)I#acjh0MMW^Nq)mq9_wHBw*o9{&hMk=GFag9Z9-_V7tG0kLlemVG( z*+`>22C}{e2lX!e!SWTI%{^5flPPvbC&P-f00bMVOu-0kz48DEqR&F2y_>ySt7|#9 zVMED&3n}&Quhb=VGQcCqZ{tc@l`TNC|EyVTg6np9>gv=ENk4dbmSbmW1%m;Btw5DH zR6yb9E!YynF>(0%v_Ju{V*<_E-^hI^wTjq+W->e{wOtM%T5p>nk&%p!n&Nx=Wvu?% z+ut{FNPAZ@PS{_rAC)8!_lC0#fu_T3E)Vss<3X_k=Nv`&nLs%^;6bH>2QsUJ)SFi4 z_m|Y8Eb*aZSTlyR+el&jAWmL(7Pnfvof zD|`7`<@|->7HFP{v}CV_+Iq<-S{X~;esL$DiFkFeK+~Jx#+M76Lp{_FhFP=z*p^vq zRv-}+(zxg=-d`hr4be-7V2x$b$;XUqXT%u0{hgzM>?Yw^hN6Z^6&O*QURlh;F~NP@ zuR}VbtDK`Pd2DUgb03njhm`e-r2TXKC23g*G+V1DrUL9nz$hYHq(gzK53`4a9D z1{>RdYtmO7Vo5I`15|A0K7^Lzkk;i(zWy*nmh6RAlY_}x_NEM@nMz2?FoAp{CXIB$6~$#`Em$j*8v70v_=WUn{4(#Al*EM4;x)Ba4d6Xz~pE zcbg6&!yw8$2i$X}C(D>-6Jq~qT!t$0wo)C&{=0gR0vyv&+*V`S#vz}7mvqT z5TGsYVt_sJo0GdIUFc}hqasH(KLH~jJR1dJd_;KYuT&IW1D=&$bHsNt**x*IYmkwH ziv)A21gsxpYm9*w%UVDmN>qWGJmA6_b{Us$3Z+I7_5cr&^}1nkG&WL)#*96`vmzC( zSBEn*4z^Q6Djvjbx1{Iz#(Ldt# z`ws$KztdpoILa+EH2uh2wfp6c4n%%}pC1&0Z(HANyo2+r45qCCHzq@%TQRQRP1rAq zwuQdx^y%TB1vdJ^TZIpMz_Vf(zP?UyV@8?Lep(uv!>6H+N?0YXp2#7}w<}PQ5XY>w zAF7-{`2HW~*8-)}IPksWZjRax`xZGpmpM9hzO8jJ3Mb>AJR8^<>|PUnqBukt#mCD< zl~}VpFmG;#OtW0~NuS0B!&9ps{(|va58(L&vr?_4rIV+VVH;mXenEt@QeEzrkNsQe zXyEjx8`el1UEc%)TzP5qC+vD9??q7?-m|jXSGo1cq3di%&{dVoj*V$K*Xx#LulM1t zCg6k8cVc(&O6wh)`fGA~AA#}Q1+8`-C+CoB+8nh&3@;*h&4mZX< z{a!3Nd3|$@C$Ro9SaCLssE~AI#3KCettUi87JD*A%}bTl;PfO{Ku^_T?vDVduR!>0 z2WTXk82l8T^QM*EY{jGEppT*H-U0kSc}G<$IZ<2yS>r9<6Q_TJ?Ij=L_H_BHh?JP=_Jolfgg z98O5+eT+-^(;aQiwfg{3V}G;>ZIw}FZgp~5#{O=Z5CL;l6}M-tv_Zxj?zwc=*`vtKG#`G{j4d4+g=%8tNAj8y z@Z>8t$EO5(AmhE(BmS8C~BRXdhV%Ey3VGO7ylm=(hR92hv}6 zKV0DC;ab5l`!of57ATevx+Y6S(-S$gP>3iTLzYe86+HFe;3Vw|sX>;G=E`{)VWgY} z{1)k=^`a3H)9(!{qB30uLp6*@j7ViojkP-@Hf$+n?WN+Gh%X)OGnrv$*%|ymsT#9N z_>=X-2Q#Yn*Dy)_eAMtld2t7$KisZ-sk#X0aNLwxlGLMGqCqg`*Xd!@%)Hde`MJ6T z*nvAHo6*6-tw;eUc=vUlinuXX=ne2(o#z|ddcpagrS8AH<_mgh7slG%jh9vX&4!F7 zoAJ~XJ$-JB~@6Z9_)t*G~yi+onms*l}eUnqv-R;Fl~*j zl+DcKs|c@j}qG54?mJtIX-w-QDye*3qJ7G0!A=Om=$qZ zo(LAmIAMqakp=Om37R~R-?;^U((^pX*NNMX7~OCqiRt2#7%`fq$(k{B3~q4QfV&2y z{RI<<2;>z$boiADsT$k|e%NI17=sPZNM+kzolxKjtSO8o36w&=EuXuW?rILg9axTL zb-1WndN!9ttyiVcAiQ8_7uGrX7x;+2FQo-m7T#N{f(dtM1#m!EGlL{bz+uK->$$@N zQg;QamS0p*>E+i|~j^ooPYiji0Ahdw{{}!0<1k&Tg z0r+vgeE6T9yl;>059ilBZ$ps>Qb&>)wVQ+13=8&qFe0bf>W+oF=Eu6TpdIe&6k#up z8ZmdecWAkkNCcLulwRs&?-VK_J#Gk3pT!a-=-=1ihYsHnlhX(r-6Nk^p8o!gYj?^|)GWbXL=U!a# zM-w|+RJED4b#BjqYcE0v#`5dNI->nLuw@4(kmB#QAqez<%%6?JhG1ug3<+u4_k#Ms zU>y;GXW&rF7MjfmB;DArhU(SI>RtBPYCzmi(D3bH()ki}Z%w-BNS0^25%7HNmr-d= z@w?o#-@SP9W9+`$ypY4VOc*I~=tF7^SuqD-ljenWZo$-n4SKD&MM3fO?BK`G1HJoV z)Ul{-5%;Xt2tzA=VB!6vAy>GVMb$Mtfw5pF{a!n~Df)^9O@ic&4vjt}_<>VIk$^nt z{i7_LTT7{*NI8uQTSP~uh%HI%r8W=|be>eLV4u#un`0~pS|Pl9ZcUfPPXm$NLSmtW zfmSG{oRC!;RG7L*Uk-<_PjYTMvlxs%LAwcApKTO@OzdP$DAo+-1hG1bkKytJc~i? zcug}TwSPaENqnB{hwq!aBZ70WrXz8Nc1BD_QgN>FDpgZ8Sg{#+V?}|`QA++F)#fA% zs~wz^i6VhK+kV(v9B*D}`=9aWX;x4EcLb1RI8oDlrIK(&uDxN&YZ^9`u*N^j1x0{R z%xydqvWfEORwKE7et?W(g~@`YJrz6sK=^^8Hk2;x3##>?m|XdJsK=Adg4LKi{ZvZ+ zQhZvFlRq)N-zFAYeY>TZe34C&XPNF_d=79Ncfr0d>+<~Omrs@mSuI2@Xm5M{u2sIX zTwHwDQ;nbE2(;mr7V^HrRoPUGu|Bi@ll0R00(iETKumcy3Klfp8unb~-LT zpHQsWHwZ=%7CdGx)}N8`rsE=P5Sw-NI09?&3r%Su0lv7m_CQX+FnB7nhmDJO3VhsG zcE1E>UWivGbg{ViyDjt1^->!Q(z2X?aPrxLM^k}MNK408{GZX;I4ZmVlQVG}^6x+*WF#1cdJ8^I?A&veAD$ep{3~=+L7$ zDF9ELRnbGt=3AEy%AMOc(z4J(>E&U-G;M=8PGUD0*`I~4u(G>+Y^!v(Th=~pT!0$I zG;yMkwmTT?npJbjx`c!(kmEOmN{7S413?3=9Jyte;qvmXCDT>;vQry|JclluZ&fn_ znVKmNTq7t>(jJbqeU5311XKjvapEd$fs}ahv!>%%OIeFjhwd7ms?={{OG9&MJA2nd z1dA!s&q+BNw{3WY0lBfx*s}Mxn=QL$vDk5-8!K9;siOJ>d=|?d_?{@>IRfM6Ka1(G zAGu-@XlSLJ8%-69;w)WXCsv>cmCa_tmxjFF*^*_wsPWid{A(}fI}U=q6n=>3~r zgvxB?%S4y1!`2Aoi{p5G;*Yea7O`{@u*VcLNV+218dx5hd32je#+W5kq$yU`vFPIc zQ%i9)8KnMKxRyM*FOSohFsCyvj!#ny^`@T29B;WJ-si%BWo}n7k6Ny(V8%ohgA;M9fh*Kfy~nn$^&-j*Eu`m0L{u|_y+cA>;*WI8;q$={<&9^nj=DJz|i1m0c_ zst68mMK#VnM!3?-~p7gRH05U;tJ`y{b+X*wtlvJR>wFirKi>fmXHj z%w@p$kN9*$z=>I%9+g_1HF^pa`fLIj1+Ih5oEt>d-~|Y@xTcuL&Y?mxy(A)pFEyPx z)!i~=Wm0C;MlR<`)3y3gVgv(YfzZ5BiFgfw?Gq_#sj0^roLD#7iRk@1koBe%h!!}H zURyQ*PaYso2;;cVN@7GM{@W4QslHyb(S@#sJC96e+RGL+N1iAA8-xq2m%sl2jMqhKSPfEYk^7Uo$2fT|GxOm zO`Ed<{8Ev*rBUtAyH~cNe*mjQbdptJ%DtCLP%qNyfR= zLd;9FMHsfCUSj@kH?c5KE*Vnhk%=sb2X^lx?rOVC#}^xDEtxA8IsC}vhxq`;=kZ|m zlFG3aFjHDel64JT6aCNci*7GJZ1D!hF28f-rq7Q(Mo3aK=Xx8c90=*rBi${vQCG*0 zpKJ_x1m>>^e=@Q;H^0h?Yd$_5Ql7D^df$kEj2;#B|2`{VMJ)Ul=Et}QmtITMjC@{s z^fnX4?z2c~NDyrQm|x+o?(gx^X=nOUVSJ%-Qv^bA$P9%d=yt&(d4-hCj=oafax8tV zIp|M<(%wzxitI3+N@$p2{2RyXR#ZcwP$8g0p^uZ;&iyCK)5Pq88$ar(VNbdjC59`iGvPGrAT(K}CM_oA*I^^WoRo zxtWF^kghpn^m`YaTp&hrsE%f=FqNUBUA!su5w*vJk@80>MkafYh zF9iGcydCU+LiHiL`{x2Mg57G|)!T#-NMMaZM^8<@Ik0Xh|7^ppH_UtCl!=ak)RY;P z0jRXpR44^A3Km#zv>TDatciwx2W#pr)xmh2FpPohHj~A?dJK#pB*M1+#%mexDG7wV z_UBLsBac!2o66g1S;NljoK_fazq+E21?V2rr^w5cAowH@Wj4qM=pspi8zbu_G*d6- zmmRAg+XDi+VnAPNhF2_0_9-Z5r1RxwHcojbcC{BS`j2u{Hr35#D%N5*>k^1U9hsG5 z%w%I?%&(ItapS%N5tib~ZDLhJ_c{Z-%!NhET=Azz*w1Vyz`9Ls>R~@)e>}!e9fHGzKG8Z;U6V7gMO*D zHelE|GVqoB%W@Q#8j{L1HBdfB5}5Q%08DMBConLmxt{RPa?PIUl~a|S4h~GsRhW#n zQvJZjm7+4Qdh{h<^8k!^%vG|Dk@9jU<1KLz{R_eX=1k{XDU&~#doQugzgy|!1XQk- zqpY81pX4n^O<8#+*wik?V}b!brDy$ZaOrO%ix29}6NJ!r#ca#SgIC*^q@=v-K7KNK z50mBObStCMFJJpwty%&0n`rdI$*|D$a5cVmm_=)7Oj^W=hY__owEw z-`w*%;QHBb=lc8S2Oq$<*WTyPTlv#1cswdzsd+O(%00E-ugrj>N8|lBgvQL`0l=#K zY+wd(j|N8I6q4Ro!R@~^vmgx+(_=O%!Q(>E)>h!P=V|1wBqu#Gf?hY#d zW@F^Z${yw&^~2a$Qw=TR?7`C0c5#1&!0>p#esqh3_p4US7VKM4Y0KYK7EOu+_g*U0CX)fd!1C|4h`}xyDl0rv9r+ zT8VH%-h~y9x*Z7~avNw9rAWbq#~{?zAEL|!@f?N2XxZ9Dgnu{?gV^KO%9kj|X(f(t zSFgiF`vef4j_^V=6Y}D_%;v%SDtMbf_xZ8(R<(`QO|)|Wf{$Z|w{H2uOZN#-tf0AI zq#hN-g&+}iT(go5(4BO)$nJ$GKD9U1>Z^!F>gaqe*!UF%eE$4yFng z6*-~p@EbVw50F~-dzkWG4QWhcQe>cdpFJ_G;%#8XxfwR`RNlN|v#=5$$=F1qU|T9` zmP0DXO<&kBfby)P_c!i_^D%VmQc!6}o6 zS<#Rus$QiEsiu-_-OWQv6AiSO1DtL{l~_0)2c|gXJb~>9^bVDES(R~E#8!u5ySXZl z9VppwCrR(cf22Kt6RGzoc#C~F&0L1m_yT+hOfXYf*S9LK+SWj(;eg#~rrT`TM{st@j-hF~JGi(9OTZ4i@G$3B`jQB|oMt3rEC zvie{KK9t`fJS*D$nx6ajh6dA!Mr~001H*@(oUTl&8q6pUcWbu5fNpsMqaV+LOu2`V zTu{E!u)Pra?3Ia1{|k{s7}<_BY^yifroGM5Xf%=GIF9hN*m6pkJWas8G^gz_rY-f! zWP+zhRmIYu*{W8$klwSh@&W!f&D~l46yeVTZY+2&n^!t%0Ju;+-e3*c<{G^9h-$0? ztuX0kiddfT(-kcE1&3WnBiu_b-!n(1xCYw>dD)h&)0pp?8G=p2Ct)-gDzU10@^fL; z^a0lv9xY*p6uy`nbFfd>JB_-V(p88e@CGB91lEmPS>d~|lpwb}ER_)O#mJ4xSlje( zKtCzCAftM4XuxrbTENdcmvtH)&fiE{*wqSO#9sO$UlULb1$H2g#(R+GJf^kiS!SgxoOdeGCIoX1JRCd>IG%ON8}du0@U(gJ-wRo60p zga#qHRl`j1q|ceaFqe%c{ugQ76z^#Q3M=aHXGE%ni|wp4lc;(Z}ucuda7Si5`7KKLFvE zuh7S5;LAJMt-2%Pl6rS8j^QWhGQG|56U*W_xB6JhLgpus+)(uluYBldpfsS`j5*hZ zFQ=y;-*u!%`_dyZ6Vn)1?t|gLqZi8tihF-ol^J-n5G>N8F$g<$Sc zU8kFaSIWeNB*^%Uq)?Co1V_j0ZaJG%C=31U7Ss(VQbcOCeM(a~&>wi6JB80;$8G-z zMK<~KrRR5wn73Qa{SQ1wK9gh{x=o#kWo}^(#MG~hD0a00B|&Jtxn`%BnuVx8Q-ksX zXshydO1@tnUSrD}q#Ph7PnW~Ct$aPMJ9}J_*95na*W>5@W9~OdQOmc;OFfazcJ-$c z1z(h?IPv9ZIK$Kl&R%)SWG6(dog61|;z4>j&!X}PgM3qM&pYs#B}f6E&~l5ioZN7B zp$-CL6$l$nGz$p zihls<#q1q;&KALrGf5lqzOAVmMl76xF9%j10D&>;yW^G3ICP!%wvjVkjRiBKP5pUk zDLg7I=#b~PEfA^P)w-<+Ze6$_`+^w|@NHDyy#Eu4YnTwHmVl@#3dW3IKul0C zu|?G=XHTM8A{PR`4H;EazE2eVov^=4lEI&QqPUNQ`ypTvIvD;1cMO@<8H@~;w-+u0 z=g{XA8cX}ZjK4GNkO!HdCO~lA#AY#7-w(p=ykB=TSgd+Ywsa4Y{fhybr&7m8fmz;R zHcZ!n`q^USXi^k|*E0?&Ew8cfgWC6aSqXX_ZNpa7$;xCUR}oyC+};UK3~-bZn4Ew>`qs)W5NZV8jU$uWML}8 zVv}i-QvSgcU!?NDOhkQl-jaQtj8Z`oS_)oxu`OJ)bzU@B-LSk*iHZyS&1=9bC>rGab6!>>+l`{! zlZlKS9D0vGOKGUKLN%&E&EcQ1Of^~7sYbl0_byLY9WEP{nQ6J{rfx*s#>}Mcbma^+ z4=LfsO#M?BoHtN}xMlsdxj56s%7PT;+>oP6h^=tcF7r0zsxMAEpJuyEw}!k9-S)|6 z75l$-0*&)(Vma)%abgY|%Jx#?{eK`O+Z~ctjU&6*1e+YgYOQTdT!W4$2ZR!{t&|NE z$FzSfrFFl+Pmi4H>Ah0RB(^P!H;)Lp%v39km-$08UUN23UvzV6=L5?O7o)X4?-Sv! z8~)wgK*JrD^5h7s@88I52zpBW7r;a7;ooBZS}d4Vza4(4wIsa&ZO8h9Px3Vn^A(ZY zIS~%&UDB!WRN(=pQUVRU)c8!>3dm z&7EgxG^FV*U4i`E8G#0$BloXlqtE7hO_*CcG@c1NnjgAkuI8?1;H<<|J#YT5!R|-kntIH9p6tR9;t6t* z0n3e2W4}R(0B*&1j1G7;?(X~NRPTYukwSOI40G8aDC(_@Np^(f4p|Az1X2x1)t#%oCB45Hw?&;3kZu@ zId=PWWW>Q8#-r|_JtbKTFQ7IY5iU~o!*&>)ajeLZ%y_wDhRx$mi4dkL*&v_0vf~41 zw+O(X)T)M4bSCn+0vpCh{2lD<=p39_?RQM@NgWp>c)8{#inh8}j&pYRh^X-m2Gh)h z;HbJ^dw-<)nasNiwd}khOte(mwg+b>dX<1v?H!gH5Fd{-7~nVWxPFN*{@>j8H&g9r zBeeeh6iq(%s{*I%bKrEzcq=IlGjQ+hMB7%j#}-kwTydsFff)^(U*>fGH9@0n@+w-= zhU?ai3g(tX!*Kh~v4*~JAk1K7RpGOj{u6vMrPJas-!%RaZ57gu9#x=5-05^%T@Wl2 zhM}|PZnTooXywdlH1aiSUDxQB^@4llT3bDNjW<)c48On;3-%7D#dM<*o8l$82V0Gv z5TqwOTx}Lorw*SC=Y11Z=dJN*rLZhTvUT$kZttL7R!=V>Fi~mvLh-!`}v=19Y zgNDs9L2sJEAAm1QS;S<;*TY6@G9Gj~xwIo-*LH;A$m2NGW)~_5qp- zH-#KrKYD-o=1p#aRtpAv0Uo;X3{w()S>q5Lixi&X*A82YUT%_LO`9_z@&{#YX>(bS*LGd~p%r+s0$QgshWBQOtWNu=7R{if%xFQ{)gt0Kq|v0AMP+HjxdJ zjh~6eMcbRA?TQJUn%a*adBLb)Ka+$hu?F3`xQ%cI7<3%iJ%pJ(a5#hQC7;nISHbAJ zs4|}JG*SU~~gajj(Fs*G2BN>?D==27oc^WLxnwQNAds3%KE*Z|% zm>RMQ)^A}UGWQ5?7Z`}v*U553-7JUxjucOQ@J@)yXxpvEDEiByKe(cq4PWhAg((ETL`NBAhWxw4j5V68%PQo^G8WzxTOsU$F~oGO`L7cv9I z5N?%A+pQg?wQ4!}M~pbbxVQUL2pHqPE3kVbyyzXWxOazZQLg&adG&Z7zQ7)@0xNZw zTNl8?!gVtw={?lBD+&v|DBm(;1shMHl=*9!oz~x-LHl>Gri~W`jt#Q|+>$L2peXTS854K0{a7-Cp6+;@>Jt5H zCJVSLaZxgY$t{`Ga~J9t;e|~RSm&-(yeZj_vBq6k)T5FEL$u_fCsRa(AB4BO)e4Q6 z7Y{RvM-Fvz$nnk&0Q0;H#k+9Z$rPZ_4evD&3f=fL^6eUO{-)2}S6~KR%)XFX>^8nM zdgs6{qJ+{^+|PlFEP-37U^~rrJZ;JP7AHKo3hkd!VaW{gKKK%kdd=bb)~paF>7IEo zI{)%E*0e$drM6{wIRGYPr8W$Cg4ZdDb(3YCVrcqJ(8Dl(o4YBi`q_N^#F(Stz^ zXwtduK1X~N*sXegi)!WfhrozIR!1#%j^p4{7p4KZx%E?X^()$FkY68F_Na1BHIut7 zTt$JCp;-(Dkb4#47PO(;LO`u8;a%nM09rQB)=0nJ+Q-R;q1#h=2inu1gV7 z8_kzfPl^sYt=Eb_IM0@iN)LJtVFEQ#E-;6GJf5OI1yN4gK)i$b_huDc)7&b>Hy+0| zZ0R6$NN5_ba8gxdafT-_hsW@T=`6zBcv5S*YiAhZE6ok-|DTGHe3Xfke01R}&lh1v z4J&iugTcA*+|nMT@TqX=Woa&A?Sz`excNK~xuJm`qULu+i1G z9ic6t86$7x++4<$JZU5Fn7!&}K zu7n|{ng@|2?Kd+ZT4xl;(3@Hvgt!!p2zWA1<-6tNZ`s|T?-~D^j*sWt9PKztd~pEn zKhxy`{k1F%GS;~n3ZI~~;ZM1&j9miLT41x37Y*npL1^I5@}`X@wr(U2&Ftb$?HrX3 zsOz?RvPYHQO7|;!Fl+fbvMzx=ZrvV#bLr{5cNBf79AW@WDj&g1*dy)&>2jVfSKq4~ zR%^$+3_ouz7`F0$@qm(?AM!@|fi{1qbZWnFecBz_?wUn{#+}xN{Q|qnFFUf+?O*i9 zasTNT+#b{zKjnT|76!Zdz2%nNrbrBmc15lyON*A>wrqYmyM4KJ8kQ8Ts9Y{asU)H; z>$Kh~huf{4J*C%ka?j3$YYxyZ(mFBkoX-j(`otMG9EPV(yIF3rxlhmeSDEtkRR7sC zotoja(({`IOVvUR#`sh2(3AyCwY9@pcVKUb!tM}@dMpQhrh~Ep*%f6oH5sd(gLI3# zsTQNgM&qcC!b`gJPO3D>TTnVB4a`$@UDZs%pA)Fr*-5ul^uil>@>4r)&e;;sXdb%X zDCsTVXfr)avWs0~kIpO%gUZVa&&mf0ml7lI)6n-+4Q<0$g+&{_r&ifD7+q#V>-?qj zbi?~}Gmn(+8>#rEXn7*mx)Qm!I0BGaUTG>> zQJ>~=(MCZ$4pwU*W#u+X1>GiJ19x}jyZiF}eYqslaJ=u22E87JlUwJ$>)h3z)xx;H=EpqSC&(RP#6G|Kb%oWteTtg~tpU3oi`c*z zD42~fAY2X&OYo->t0%*58xG&MF%NlG)!|jz-)LcW^pz&5*gM)E- zJuS(LtR{es(zfsUz5n^W=Q+%zc?p2qFwiF6VW>UjUOzJ~WuSMhpHP!{SGWrbQJ@Rm zdkfuLh31oA2(ecV_F*m45f&HKmpLwsX+m4h!Q~oq&9h=@LHaH~a8{o;=Gz%l;Dg_qGOu z$eR`d(QwH&Z@{av_@=n~(@zMfK)@QA{^tyK2<-c=C<^ic@E37C>0WNMnFWydn0%l6vp->b{rlBhL97(X4*I`wz0{0g~8?i|ZYjz^%Z`>}X$= zPRG{co_Tj*JU8OLFu4y(CoTM$v&JaP&?Gu#zdwm@5kG1i@-fLL*)+%U7~{>7in) zdo@xy?ZEKDl}=%;6clyeh=>CI0|VlqnS-iRkUHGPQ5DSweHHJ?0{URvr1_9p}gTRWQgY^k?Mo+VAQ>G!cEauV>!ga zPU3WpN8S=XpW<@khOV%?0>a7L{qpWO^xFL&#~44ZO@RV+zZQB6>~kCs ziCa*lIaN$zD{t};5C765wb`rEZy+%det`=#xT7pF+)Q6f+P9+8jkq)Yayb&uCD&DV zaynHjFp|-|ql3V2$J!EC!oigc8c;s>h>uSfpEhI+Ccq*4eLNU9d%v^ai{g*SzG(dY z?%b4ID=3Khlqcezs&GbjEUe<{*MQ_e19{dMHwHV{xFJ);7}rx zn)ui#sSjOLMvB_BKDP9SQFJ}^64*tkKXlPG5zWm0*wP=ms0hQgwq<^7l=KJJW2;=N z10J^?FLb$-Jk-*&q-a|Bt4{b3A|UeDUe*K%-=jQ`9hEpHzDfaUG|2?3sYjnm7lu)G zw;XPFcaD|e!fy@-5_P&4Xx+HWH^E%DE)v+F3K=S4)m8@OgK0oDmR#=?gvF%{8DtggCVbatx?UKGJ^uU?iPf> zuLP|(mZCNa}T%s;^&~NX+#H`P^MtD)2Zmi4^wUoUO2rvCOCi2c}B^=bnuxeW5kH1o3GklPJjjf5s^uxTfAm{*uiM(`dSstK|hfK(|n!WBN*5u+HOz`K+Rbbh;o8!ha z9(Car4^J!Zu9HBH%``FN9waYb@O8Oc=7I0hP!|aWC3Dj;c=`hc6+ENoB5UTqCS5q= zlZYuYhtlym8Dh2y5Hn$NqLNnS7Wf6E3S|?PC>#l9b|Y3|CUrB-{>45=-4QUkbQ){N z7Rb2yGY@IjZl{kH8YXcB0ih%9&PV-oR)*iu7>;*Ag1`jWs z;A~^C6~cx&Q-;DGL@zZpydRjB+5K+oR|MVH}Sg}~|zbwrK^TtW)Ki1yvS46`l!lPKh$d6s)s zS~ddPsF)|&Q5aIEH6C2U5u#D0kT&js__b5xrg_KT z3ZtTj? z^_#wqo|-#`V|}<8fV{WLaulRTBPg)q%ILiYo7 zzGb!MOPzR7|0VnnZEr-oCWlPXfN)E*>?iC{Sf=N<4CHmkC{p|w)0K!URwBrS@MD}o z6Cwkot3ZkwPasBs!%V=!8BuCedUsUWLl)j7BP2NL<9^oZ4Q@rBYW%WG?m@}BlD?Jj zj_!~_D9ss#G`s-?a6)lVw^xK?iXU8oOy{naaW5-oSTBo$o?9=xYU^GU82=2k*Q4m} zcrd!*G3G=Ym-jqUyuQ!I?Xwqm#zhXUjBS9W)IonZ5Ygeqj>p@AV-Z4XJds|X{HG0# zC`G<`L@q;WuOksUe5fmZ@rY-dvy%e= z+AvdG!jfSex2{*6*wx-Y(olO-8OToilbcJt9M>BfMAR{BfN0%ZQ!Bd+jO+%JRfa#aT7Nl(4w8<2FnP4d7xey1`=B7|ZEU_!jGIKzM1V5!r+Ipxz=q9mBZJ~s64RlJq z;iGZ3gX^eK**mX&sGa|;^GyYOrV`$dp#w9_*bE5Buhhd+909{JmgkW)mrR^qP7v)Z znaJQ#fMVEVOz95?qsEAq5GjhrGi%P9Lo08=>>Af9)s7#96eB;*SeTR!h%ZjflW>{J z6q0o91y3=?fT2>%`ME%Vq2-LJ^Ou6t-|?G9{j^%$dnYUg8*i!yCuh|Lz~eDhozfJ_ zVN)7|?G_WfPRxC7<3R%jiiPW0xxg1gnM@9zIs^!>F(tr%sGRLr_YUnu>;;U7NFxqZ zrOPG{*;}A*#w85?)O-_v!FVzAh1I^BZN9)p!@xRxpl%60S5(+_Q!$1Q@#;(@L2_QV zE;H(lbdL=wsfr+z>NoeZs-IW({;s6vj|0ka)J)>!HQ_$bgh_ky8YFl)wnSXak!m8Y zcN@h?LW0S!aU!biI`!5_O{k9?=BQy()GFb6&i{h)uURfy&Z!s0Fvv?QH^aAx!X^Ly zJ6punh`IRTKG6oLYg2g1rxmI(^l{z^hrF6w)1FF(*?wL@uRXofUDu9k$2rx0!2!ik zj5yRFtA^3b%>oOTb57Gm7tg_}hKD1PXdowvzM!We@AOr$*-D@(C^s5H=LO~xdZ202 zfJ->((Hfv3iPa^d)_QX&TIrs?)Q$j9f2YHrJez%vhB2ZhgepRtlOleOV z13gs1Apquq}9BqZs2@yn$czPy`8BI zgP!bI>sAR($YHL5=5_iaQZZBRA`x2_4&bN-EpS1;nS3TNo1%)eiXppiM~J6zxO~UK zdy;OsY{IZ)WMA|WfUTBQAPbIZyP7uoO_VRm*A!%eVe)5$-lIK7u)hb-6VgdcR)*26~ovmdE`%YEJjgHYz54hyu^*1FC{u{QzbEEE%sJ( zO#ETma0O^KywKoRhgAWb1uZgO$`RP;-VA#Lc*)?21;&}A!)B?_Gh;h4HYq&}IR@_l zW=gZWv){Vs`<;2kX!{jg)`!MMUhv*FdcvB! zT>+&Jx3gZRr8D*3atgWxxeMi&RE6f3X17QFXzHyh%hETCN}Q|e%UzW^&Tz|7rXDst z`cjk|)akzRxu{fPMdtbu3CjtP@PGkLMs%Cq?VDC-;%XVzgfKX3b^w?*>yB4gZTw?` z$pyyad+ydGRt4&3Z{r{Fa-Hk0N8`8yN5v^{ujQR*t1>jWJtO4mZx=+f9j~$)wei%v zfE<6YCYx^ODy0MgVsaJv!ni@u9_LG5eWJ z(%;S)MBhkP7Plz1nImUVxW_MQI?fZm*5F-;$%!iJ~dR=Fm9eRwA*L@cb~z(n?BIfD47}FZe3q(%JN^GBT5Wt=}0iBeP6rps}kS!)D!XfUpQ?`CKlBStVpJg;X(1 z{cl-1c!?OLez6Lrd44g;PMiI`$5EFj9|5Rb21nN%*D+N7`)*wD>9Oz@QNjq{Te z8PneY@{h{y$PA60m8fXWAXh3xqA$^um|yd%A~PYCkIPUcGana`m~rB^@^uAs=8St= zJ#U~wA@@QpRn$L2@j)SF@uEksM2kal_Cvp^gE%&h*>TU#w^ zoxI3g_#RuV)McZoDlwEBI?SAxC&|24GUb(gmr={)Q{Jj7DvVmwlfFv7FgKe_WXr}H6GmVL$!z4BBzk7zYY76rYHoHyzzpEMP(1n) zTg{WkSLtxkcvrM-OT-?liOk%KMk+#X=V5883<Ah?|rWfh{GG`xKkLknmv#~mQL}PYVSCiNJd4rkyQmzgose_bpY{m7nvc51f z&trx?l@*Z6yZ2zsDcT=+qEieum6lbV)&;LJ4~XzI>vWt>%9|BX6g5*Od`|38!9uN& zQ{K3nf-#$y9cljAx*Qow8Daa(<3*7fZW!U27#&YoG8u6tYa65va@^=*o?4JXR!phI z(gK8(rX$K{04S~*W7d!P;oIy8`0#UR?YYYK#^YIac)B+@eWOCt>{^aR9t>Dc^laY# zZ%J=R0pDt5hLs2-555hmw`Wjxm^V|`nT_SQq$7`!ADWNvHb!pz1@o>o(cl+1Sd7O( z2To-I-f4nV*S|7H={aXte#)W9Dxe9>82afm>&}`q!7vB2!`AW|^8A+U4T>7BPdgiQ zOmSK?D(q%@)Zo~wOqC&2|WVa{mR-PHO6lgu@^-3X4jWM&XgW zcX5|5`&6QP2d=z<6d`(jR`w+BO^H}0=h`sSr8wveJt74_569h2!^trdHfx(T0f06_ z7&tXjARMggue@o?-V&R&HCU+k!IhzA(D9T5jA%GugDP2Op1;{bS@wiG!kdL01B;kf z*-X-tLbCY-%L2K>w7mu%YSwzl79Aak)0DkY@RKOt$6`@FqTag&R@K^yxq+Z zm`vnf-j?SUtL(1S;=ry_4$4{toZj0sfz%RKv#%pEQ| zFIYF~m$wCFuj{tG-$?Bz42(+z}ys zIwDJ=EI0=gF{fnllchR!-waga8lc=su@<-ZX^P~ z)aQwLnmT%4ukCr8DtQ_*k5aqodl9p`Q#`*Gz1-d1GNl8w4xxM(1rWPg&{&VTBED7#d@(ia-|1 zu|7Q+sR$Lh5!BBGFG_deLEuQDeo)tnUL)22W8#nC8pp+U45wfs6ojw1Abi>RhWHJy zIFGAHXSV9fen&W_M_k>dUo5knrm(#JmJ{Xq6IH(GZzc$KckN7}dX>84V}tr;04 zb1O*IT29yU&tcABzPqV*0+bI?Jk(o?lOJj-9orP_1cepb4MwjXwz2!zWA>&Rl$5ga zq)o#C^H112FrFw{81P^V=nN*jZ&8Cnfy>(DxQ9n!5w`;`HK<67-%SG(2B_K!(s<=+ z1s=AV6K*m}@dx#tpbR{S;cdwAo3KlGoPNz<4+aRJ!S;Hkct4Bf$1hwjZQPiSYVoeNag zi0xUTNM$x2mfaZG(;DER&h*Bm2mf^7pzZLfz*&hmGZAgZ4KQ!RHPTHK^872{mPA zi8D5AuQN4m(&-69TpD{b?lE{(9{-p~YihpTQ{bcm*$mR$r%`0>dO9MqI4VpRA3!$C zh0#_~ktL8{>V9%M$CCph`zPE>IN!kmJx%^VJ7_uTZXe_fGzykCID+cY;2fG*nS~bY z2J;fBQ`atYwAxb!YKjdiM6aVx8pUMZ&TS3sK}IFtRA;aG+NnYhf!@@y-ZHZZ?%;gdx&T`#uGTckMN3#q{Hh0pnwm} zx@x*rf>m(0R}r2>d%0pRCXB#BWu>K67rmwiE$(~Yyc~Q19-KHUj!XU5 zGR}1uC7sb^I2QXhqOCt*aJcRBI9Ds~!t`hwLW?$yH&J>E;tqarR4_0n3eCHGp83T9 z`zk0Mi=ZMw&Xx| zL$Y$glaVB?LGbn(<#hn_Vzzm}h25-`x#cPC8VL%W>uuskv*a?RgP5Q#qE6{y02O$r z&pO;^AO&_V5R3cvy4#Ccu2@t<+s#f~vTZK3kFcE&P&&gS z?oHh8PHxBzwb{Q%Ik~`ic1=tM15)K3s&l#+f=^3%u)f-p5v)XuCD5Tvi9wcGqa7Jv z>4j#Qp0GtMiCvpG=Ai_G5G<6O!cI>|Ys|@Fh;n$q`1oe^;El*$qk~O1@8c1>2Kl!$ z>GkeSn7Po*Z9zZ2;bPB)} zQc)f0d?V;!l5ocno*zq`FF}f*^pj>M#z+jSGEPG>zivTUsO<2RE}mN&6I`+!upSmN zC(D%$6-8sj06vymINsrCD2M_OcZU{qztxRJWEV__OXoVRaE{sWJ+P=m90cBxeq>y))%64r_*S@PJO&?Mz^kWhTZYjeEs?o zS&`V0&nmHJ>5RVDionbu&~NMjel1$EUYeUoTC9OGul2;{X&6Y zDV+izdXrsuF_wwO5Nazi5*$FpayOJvuHxGeSdiqA^zuHHgt=o)y;$*2(_&swHc-TS z{urR9IZfF>t(7u>dQ7+3=Dv2P>+4^!)4ANL=4~u}3eR-NA}d<|+d@Wvj>F50E!E$) z;a#f?e{3O(auo6x-AS^H$_rwEgZ>GBENPW zqWtq#)wR5;>=9WojETp;&)x${CRP6tUSAJa$_yr=5udHn~jA6k>Ht2K;n8oI%iD@>0EjML6PP4hVIqG$dES%HjiNJ56 zP%?B#`b8$vl^<7TyjRz^D|P8<`k_trLGwnXbOUtwLIZ02D_glXlm7{exp{A5xj<=e z(ZRMvxf$6|O42q0is>Mqt`l{hWt$YSB9p;YuuXCW5Wjh(MIOuj1&OZQdCloRv_iY( zMBu^#dL`-r2g^pZ?7Z!eWu&0v*d^g)@8tAn-PQ{o*^9ULi3TABZ2qihc4+rsq3Sue8fhp@?0>o6D$$7~JaLed-adX<=jG5!G@HinxaLpHjia%vi z;00f@(8NtVGrrY<8RyDxfYNRO*Zc*J)*P0#ZvcZns0-Q27q`xc4Qt`b%+)x#(L3qn zMx`gz+3Ds2eXc@Akj0F!Vdk#QZLxSlDS2H4`!*%!J#HQ+bgY3xOt&@Z4JL_D%nOws zsUM96!|l1Lnhc$dR!FX%?^zCUu*1UmRfmo-92rT!*~d45SJLF{@~~Pt%RL1Rfh&Y^ zQsBPc#_!Pi9XY?(E-d-y!B*&~^-U6*uxvA2RYXu$XoB09Z_jbbCa{y6S?CecqWae7U&- z5tcI|5i-jv!$kwnoG>1BFEOS&UAJAv$jd0nb7n#@EpT~~YhZ)S+j8>L<5>p8H@TIpkjLvh zba`qxCKV|!v$(wKb?MH(K`c{J9gT`rn;m%UFEiWma$#eiaqnX9;f&a>W0tKON_K}< zHIBZD%Prd(P4xE!;ek|}6-Xkh3Ryq%6awDZB|0yES&im zzQOHh_HMBINB8dVdaoElqD?aao-)oBg7M@!3t&ad4$E5rTzhMNc&vQBPnJC7WMSMH zC^ku9HV3!pUMiHTl;Xj#2bwO0-E{kNf$ziid@VUtleO4xns@U6GUpAaN1PL>UpgH$ z==u^jjM!i*iOZ7L8&LVey8O!9So&c;T3t&u?Wwy%xSA@N%!#v44+zd>Ib>2E}aztqJ_e#>5#Mvrj9N+(pa z0!00mk^}|tAr8w;RW%$4>w6qSRMI2w^qN=8v=isZOhXGXfh)!M2UaYnAkAYi<0n7SYOXqKw_Z6FC6LB?D9Q0`l8jP#MN=sh5QeDatGUWUdL%wjsoR*sHqe{P5w; zS(d!H=pc=(iTsLPq~dA~Mx!_x4!Eb-c%X7BlH!3AlgezZ-eR%^!%zhe7=;*cF2tdC++Tls}pa!cUXf=D7cfo$e+iLal%jkT|A1N9H--f z+xXy1Jh~lq(M-^}yjB5zum@tQJXSef9Zk@Lv5Rq2I%qa7^qWhmfCbp}IHu7XY1Ten z5Ccay6l}dOn~(VkwAmTQBXMlK8A2;f$B#-`)MLyR@^DsGeHaEsE^Rq|*jJn9E5=kh z&ce0{$2pwkeK+|21YSj9+l7(fZSq4+Y@^d`$2k|r%Xa4lHmiVV`GUkEqa3N+P{m!G z*Isj|{OH%EWTP(>jncQ>etU3R@N#kU>dpnP;9xJ9b}z-TE$)%5JZLii;QvXT;SGP? z^hDSi9gliWcgLM~>0&7Ykc7(3veoEb1Xij**MA>6Hofv+SPW5LoN*-DfXZa)FOYdD zoE7w?Q;_0U!buBxRt%g)dSggtfNMe~^us*cE7MPR$Upa*{d(H+3mNg0DKn-^+}bW@ z-rBnJXUtv3ZEkwbvgd2&r7;L=zA5B}g$qxjxwCS!q8B{BD@D!pO&p%*v9t8qy~FLV zP?!Ol0BU${i1-Yi3`Vb|NfyNbcjgk~lmQRxiL%aAXXT-vClkGUxl+9YNvSoKaj%5l zNvj*kKAlVmgcg?DHJWK8GgTYfvfRaxEN(ifrjKaCnJq{w-BYIbv;Bi?&DDI}b0@w> z^zU&6dQ|_LkL*9~4?V|CUP^^FCwOzHcwBB|zvYbXEN-^%)eT)ALvmv>Zr_+XEEkX6<+}sTzvT{F-lO;aH5K_Gs{_q{Ue7EmdBs#vUOpNW>w;)% zAFm$WhrCsq)_fGsZ2rNHSvMucF1pE8kM{|Loan>6Yn`Y5-n+{2arLn7i*y!PIj`n% z+Iv$wKdYQqa~w1LN8_mSQxHrsRdclGj;R{Af}p-Yer=bdxyGj;`tar~R|-yM!F9Kaj<9!oEY|v&D^UTcY87!YYw5ZLg zR)WA2BWkLe$}jOqOBBzhzR)~7oVVyz+4-*j=bSoj7kyR%Dbk+BIRptKEQghaCc}VY zUSbNr(s0P=`VvY@UF7(&4QEWo6m*$;5I3_llq8O&rFo7|IU`J8&u)wuJAhp(qTOyP z!;1EGu;5$V-@(+8_zb%}qYb=qW2Wk74BtZQv>F6iV>>$eQ1vJ`(gVyees#h3L8VLE zE+CpbG@560yh!t|1(CA8F1c?q(dM(jc9*(_-GfHiWmXTx^mx4FF-84jZIQ6IXq{WY zb13lWc;boFz+T3NvQel#TZ7@f5x+`mK~*q~+a@JuzUL8dD5)c=SL4>$&?ciAQ~9Ii z^a7K1nLE-h^Y`Cb>Y1?{=wT=?Bl#tr9l-3Nz|EB2S=LXj}%|-AK^OL46JRfPmhGbkFAR|TAG$OcqTNg z$fDBvmX%XAM*}Mw;Tcv97>gl>>TuGY=Ge1r`&K&*k||qYWY8hzzO`~UXd{vww<1v{ zB!N$>!*8~%w8J#Q9hM8(4q$XWNJj^C(P0)2e78N^gz_pZuq!9~<5ehqIsAY)r6XmY z$9K%!RKR9yu&Mj25a^ZW^S|V(ea-6c4#UkHfb1Gg6AV{Tc9n>#q}AWhS011zqin32 zZr6S7Q(zmcFU3U!hP_CKh=CWk8soUvBL~r7IefVs zmGYS~JH^e)r|lfvW07$0CWgV^BD__do*WAL>71k#D z4-SR5tM0GB!YIfx#mGE~U^pza#Ze{g>GF4Ks$SAQ0&`nQ_#7(EVzdP28m=vVCy%=| zqEOt|8W`rt^bsmWt(2Lko9J$#jYUY;13(T3Nz(OR^*bo>n!OZrIh(Aume-bF2D`g! z!L-nxzA&MW>CM*@Is|f;AmOi1E=EP=)noM0ObmP`>5Ik5kmMRNj{rd@+IY#$hg@8F z^o7d(+ayi5oCA4QGth5=hk1%TZ9JCl48oqk0!XbSfpzFI+Sp7**-f2tr#Rn}Ur}a2 zff-R5JV+_I+0Umq942FsLP;fAMvdJZF@MrY9LToaLwFh|0*@dY$Gm`k)xV?*@{xjG z2gqsUK2vhG$q-bI;6^Rf zxfTZYhCPjbHLef>baKSKWncsX>I_!+)!aEHTy?in^~$bdSv?q61-2EJ`_ zPL@b{G?LEcA`}kV_%z~{(V&vtWW*%Y2;ov$wuwH?(6||bBO+jzJ1pz&?5UT_^CIXi zAn2fmO`KJZ-&S)k6rD6i{i{V#4G{C$J+ImnxFAtz?iox?4Ux$_-O}@F-BNQf>Eq%B z0SJWc5lhtVWj83Z_I!vi5rFN1agsn40Zi_42twm<11n96% z6ZVh-zZM>SCF^{JYiLvhnI6?SuzHp7|UrZ*lb>C>UKrmNgYxzQ|GbtGY`XhFHV>SW4SF0NPbXt@+cV~u;u}fo z=w4lq*|67a#Xj5UuS^y0xV2`Sc9#*_C(gCcr0!2r;+_3qIa9Qoa$hn{pg^1!cg;8o zX>>hXNTQgl9FIW!#- zWO~c-fZJqS#=@=fg#2RAw%A>D*(aJs&myS}?fB%p`Wmmqc~EeS0^8>I3$SY?J>&!c zR8B&Bhjzylb)WVP3R#Bf#V8ngvrQfjP1c$8xnh@$w#9Cpn719q_~v4@%l1W-aqDy( z6_3{gTml{u;4u>Jw63t9=zojY3mi{JB%*U%PsU^<;upI`+7=VhQ!H+)?>tP>SG00l z^4izI_*MXX_D^OF$B?2$xJ^5fuaQ&Dn?KXioVgX`V7Be+DI*VFrth>W%ma(^K&@8j zRauH-SVxOQx7_oete8Tx6%05-7SH^Px5oZ|GRrBypaMFU~h?#ciA?w(Om|d^e zriZLjS%4$&{LMlk-?!f%98}L5=O-tP`cdWZFdZwICOW)ube`i>;94K4I5B1nL028f zU%bfHysqXyiXh*Ir+Z8XQtys`OxQ3U;dQ?0bA&OT29!z~v5o<}hLo2HEry60qi2WE zkT(rKD47BkU5FWtL(Sf0eBJ!g1!+bL83%u_lU_2%p$yx1eO?t~{gZ5ca+Zgxx-8 z*JKbU@v~&zJzM*8gQqdg`JlH$sDQMUo}$4kagx6@;(6V-TeUcwkf zu5cjI8FPYESH@}F+KWJLqkihnqH8DgQbN^| z>Ky*+OS93#e3;Fl&<}9x7qX@*LpO^#w89mgNkxhPj6ie0Yz^0w(M>+c<&YBcK{Dn# zF;PxC-7jfJG}LqRR^8m|%2kRi5{y9cXVrhahZXR8cJPfa&E5ow2}S{DQyPO|$C|dr zL923J=UGO8dQ^dAm#DnoubrgnWNIB;%xAT|bC8-3Pd@Hf4=X>Xtbcz0-Iqhx45lWFuy|%zBhQRl6$>th#R=lCvJ@;7 zVA6B`mA31&@*B;FUv35qFPMXqv%RYFWBq39Cda92CqyPrUw189@@x)P;_oM+l(vk) zs1=(R3y&kGN2BYn#9(b)EKD-M)eOJwZ_R0UvK{XgEv0i@`ePJ7iGr-;^=SgKF1PKX z3xxB1O5jXaxjqAk?5Ms^3RUX$CVq6lSf44$%tiWG0{ttkQET=V7lZzQ<@t5i=Qn5k zZjSkB>oy}F{U5w=XF~CxyK?{CSMB3hET$#;X2KVjy-Hg43cv0GBddtVid2h@{I4|I zV&n_Y_1?+R>0$LJOhEMqPI>7o&bj6WXv5Wu?|2R_4{M#ra8TnTC$u*U6Vank`d6YQ zA4V4@tlBX$(8fV^@86V{SaGy#{Wri)VK9$oEsw&-Uy~|Kd@M{Cr0Md{+CwpVSO;f=+&=1V)p&=iQiCR6${=(Z?m zW_R%D?doxu_$$$XfrUr$2OZ(<-;`C@G3g#p36I6aUy2wkTr5lv_1ar`uWJ8wwV;&0Naip^_+WuN1heE)@13x@D`FrJEwX*+jI(F$+ z=u=EOHV%)no{+sQn>ifJR2YksS_Kc?jepboRX5Siyf=W_@oTO@PiBmI@+S;iyJjrR zl@IH08vE7LZ-4Q(v!!?FX#FcP*ta4Os z?7u(z)^=$2y%2R=GEK!jK+Kgn4%o6Jh zx4Aj9&8>yogp&}*R(1&*%GZ>WU1QZp%R5gc%D|$kcO`mf5ZwT|lS>n*+)~9JF zrq9%=pd8Z>F(VNCqY2_kC|HOZvWQ{IpfeO~snIV!@$V}2YNK}ip?X$dVCa9vbM#!g z+Kk~oUT6Ds{Qb$CWS*!6UlnaeSd$FwP^QGZOx$I!ev#U1Z_po)2EF=tG--`_1PVJM z5jj(k@qN0!u)4R*?BxrUQgSYH>@lX*MW=A(yD*BOHV^48pXs=NHXp;V;R+0@LHMa2 z@15*d&orLS&aEL>8Tz1&0>uLvbW9hAfE5{ki(lkG11B8V;{wn~EY|wnvFOgsvL=H8 z6xa)z7AM`E$6?>e!k8+a9Y9zFl}^=gf|c_C%&Af`z(bgNW5%W6L1t1#rexrfMoOtV zYM*|0+DLB3*AWb3L*}bHtiP)roC{3$y8Wm(xXPh}T8+pLsvOmh8+-51PYwHtz}VVQCT8XAN!vo(F`~ob<-8-9YjpX|2v#JLzN4n10%iHjsX-n8fzE;nkW7 z6|Y<+-yhdd;eS*;KCe1yNe%EGq{l3f2;e(Nhe;7=dp)h7?VI_qv_uTY8buqx9S!bX zk6`KlOJzHw7(J%QulR5Ofqyv2Vz{!l60Rnr*6K}fxYGLCeW3H+=K4B*hA%ft<|lqF zh3hZ>7Ot(m+}L=z2_Jteg<<$|{cr5w3Xyy;CH47l@<&0MhW9+=Y_1iss8rf2Mlc2J zq&03P-4?6$TPx`e5{g7v?j`&G;%2{i1SdWA0TV>y_OY6$_zH2mi!rk=~=a2XD4S2w~-pO2wj|2j?Zh=dV$rB_YU9h*N)#77_@?cRk4}F+EEQQ z8+LwDpw81Z*~tMrs-B@s=6U5!?XY(KGj(}TJ3q$mK!TxoD(tj!c3#_ie^@zVr|-{B zPwG{MBLs15@32xks_w5a00KH@)eo@4vHH8p;URT;aPt0mpY9bHZ_FGlds77{QKG}H zXr%kKv+CYC4oQF80~7*)hXn>A)?N+1U_;fPsxY9++0O+;3tIf3cmw0A9J2k&QROX+ zFPFxQi56@IrfBc|8Ewpnj{5sI_4C^K`|~P$dvdZ*D6dz~KGgQA^=*b`saWcLy;^`y z&MO5mDrg0e1|^{QoA>n^p^qY_oxMNB(FZW&9|1W4X$5NU6P^JnIA*}p$=T1)E}u0q z69xA1T@_xPA!Z3{6+{O&Rxpb}mw?Q3W3brHarNzC?QQjVuZjguu%VB&dNqKFs{wp( zu~qE+V+DGCPh-dV0@(Q18j+$T<^oMDs~xb){)ZaEFUkWg)N6ut2z`6+1ol^!fE&t~ zZtp4|s%VvUPy_(Wqcn*nXyB4i4f{EC z1G2pH29Sp>vKNWx{h0)ktNcx0k~+f(`mwi2j{>9grx6o(r@;2ce*pt zS1Fa-qkZ3LsyT2PEY>VY@W8C%<5wvG;E55Y`J^ihLI}%2X zwIVXz*`dIG*><8{VPh)9m7FPh{|mhTWe2<1{zZqt!UMu&jA5{r%S?dv>6g6jABNw( z$lrbX0bVP5&FyL74;_BFp1;zp7@xVkwm)&L}iO`r? zITTTffM}>0MaT|+%rih85IS2?VzkZPhQL9l^6ubw8I;W&h@UU9e_ zch@=Fw3mb1WQs_xMiW6IZ_nNf0)c0WJV@>IWa<#C{bu+HUEhzZ@6SMzxG-M*n)PCo z_2N4H0%;In_fepH?4`f8Jf}c9s}Ne)WY|Wh;Vbw@>Z`Kw|0~Bk^^ifBzZUrGc`4FU zbrfSjYLK6;>c_e|P1JOP{?$u$7G>vu<+S3UgYFvV!p6wO#xe0JcUYLdIgOG}#~1Tq zMO9CsMK-Y*W=3;hX5_^TUtqJaa_wRz${Tpes)g%?!-XRtMnsUh*tqs16Z)7Fo!8mu zRE-!21-Pc8Qw$erDX(B(X1TCP1xc7ia z{?!zL)AfH5hJ8T&-$t~F-#7kN3fD>-(RcmdpQQf_L)7aU~!h{%=wiO5I;FZg&Tk@(&;Nx|jB|l!|Z%S6crHpDq0# zt`X!~oYNZ1!A`#(ZoG;%Hx2^l_1;PSAlJAH$U<&?T9Pjb!;hlYYfWunNnU8`3VkM9|;v7}qDVGAn-~bFxmjf`69oFrHmdMH)CyNDrZ1AZ(Q6Rj+JoCh z@+&kz50Y^_d% z+}g6SQ1cpSg=_wVqqI8wW-FC$G0kU^HS|UCrqRieV7s?|xDH(Cltn)PuKOU17mC6Wu0l)N{5e zn1>`LlYf}p1Ha#W*55DXrQaMph5Gr7{d~4y|7`J{yHBmIK@rP$pD)UCIzC_EI`~9P z2I(4Jx}3qs7qH{YZkh0QiSW@1gRdrVM5e<}(M9>U(u2t=3Ds2N6VwPVOk~f`PLvM%H13L(R|qDm6yw{Ph+~HO5xhES-vTjllh8{yUS(H z2`pc)ad+2Pf5Et0EZa-eXZ<*e^JRlwS=hPBd<8s}NP`yrG7z}CX+X0uc4(n{vmBDL z#;iVs5ne2pXSI?xv6P=E%>s)zu#G=CwQ`bMzO;6-i}LVO=>k}YL0v`l7K-KfP&<~(J>135#jjYtojdpwqAmhz-k^N z&n0ZoM?tA|&2D3P!$r!0VG>W;gW~bg8OyzCjy@Mb=lFfN2QD=BhVM z>iZK10mq0aDHWo^dSSD$1p;9qj0)j;A>1rP@OZrtZ57twZK<%nRoK`pY;F~{N`+UO zPz;K0V5!m)EPOSP^J@LP@v(N?KtE=dTi+@Lo_FWfQ3&r-fICJ9M?5zF%JAK*R%s6?zPnuWpYxYCJJ{6M-_-90rMHg(R12TWOlHBg{ zuMvKQqp1+!X`*3e+XfcqSygVmdQFD{HaNkzZiYGDM0innUQC_`m}OHOf>ecwH%RoCqC|9|&sg~GSs8nO@q&M+ zVA1Nwrtt&#gZ@Df>%G{X2+5tEQ_yHsPhusm`@D=PDt3WKr7rML(wJ?EJ_aL3Eo-eo z=4?owXCQ>Cu1aE*`Icyq3RE%}A`o5+WQS|pmc>1lAm~(y4PS{(v&2hJ2^y0s@oGC| zIB!kvs=G&WLg8dXOdVKHxic8XePgOemmEOsOXJyey-Z>|x@y>&{!&W@$j}z38^ar@}Q8Kb0dXr~m_$OG= z{4l3DdvDOc3Pgtm=dq{znbW1g-?6sq48UvsWYXz$TiqCy8+;Tr#|ZY$58XL{w!4|l z;Q5AGmS7gG`pcFa5v*E2=|p?!KR}CS^PIEiwbDYKpYJaD+4-j#^@&$_>i@*6|2(}q z=Qy6~KlAFV`8`wCi$_J|Ua)xL)_BzHF|Hp$^)9|2jJj8p^qa?WbG^YWn$cc&udajFEG)71n^hF6S<(YGDYJQt z^KgiVVIdn_x(9W6qRl+e-d)m}L&)EF6^zKjz4Ej{mJDb|Q%i}XFmw_^X{zvmw2vvoiODYOs!(mS^2b$dIFax8Jweu+mI z37*?WBynqkd2X3-bOxSt)BMa87|l^P8T4T(qLBqmM=wrbVa6acPz{=u>2tEsjLbJ5 z!XSTqGu(C`-rEnc3@gL@-Tjg|1NXel&(q3?O)AXTq*8E2+v(@`spnLZz?(*1R+W2E zWjfVZRi?L&*8L79XVD~9xp%7wOs5Ag(CdyqlQ?S~b~_l+ng^scar=u$T#A)vVoZzN z{}EkvKBEy8&}*|rQaXuHy=F4zjjxqT?A@BQgf^CZgp& zpa)PUjM(RQzZOu5$2$TRGz1atetZoe6yP-8YNGv??2YO}A9yUer@{#bV4VQqTbR%r zl!X$&P}h`A6(7x=h;bk)(5c!}fv+`PA+tnrjmnHh`nq|F#3htz)efJnYDX&IXYpQH z@lsB6^-}BZXRv`6FW|SS!g?H|p7-(rFf^UUSLa`o-5WTM7BPm=C=QBNw2syMk;6zG z{@EO%=^+skhAdenWiXcw2Ee0%bghd9O~w?;1f}Tq;6@(fJKf$m9wjSQd;%1@e%UR* zd_@>8Z-oI~E#OA7?UpK+w@Ti()yw6wi9h#7pnAzx%PeP1XHm_wfjC7L9poU@%ej4Xw}0&?%+JyAB^A}*8P>+;qfpPH!-YPSeHMJVs_i@5l7(5KOTeuTyMj{Z4N$H<>4t@ zDXoS)3GF}1VX2hQg?QskSr zRtfNUFv61y&`T#x)=k(C9n=P3-!qT-$Yy4Pa$2d^tJ$#d*?EpZDb(ED#N$!7^_u;# z5_Z@RKag`^HoO4>{ErNf>+kpWs`WYt`C-Y8|Ii!`Vdmk44;|jET>k;~-=&wEn`?gy z*VfmgXk&eCgY3W8qmA$O-+z|<_e=J6Ft~!PN=AM#th+1y_9(u^(^~vJ(!+NH?(YWN z-wn9G8*tkO+^c!uiFx*a@k*Gv8!ElI9ChOk1zUqfPsc4-^j*~c>UAk9GG38Um^Tqi zg5nq)RZdS~OpT)oVCN@{Cn1ayQZMF>9RW-J7m!eJd1C|!5wxPwXbpRl1pi-(?@;Ps z&-b3Q-&Cv$Yz_-1JOb|#hx>@YHo`)Xe?2N!`jeYWU^U3PWY|~kq={_4GXi;C;7V!! zgoA%pZSt8M^T-jNsu=o}ssaaWzgc1Rmn&OE<9FjVy#*S?TfUUAWsM)$OBDyl}tc^l&+v zJ<`>K4*#XttSihR@qcsw|8`8VQ2!wR|Cj6QFE`Wv|KIgLf13WMR zIyu5Df(`o(jrn8k@UZcw+Nd9%d<*~|!%_3x zXN$)PYxRI=aYf>~;}QMO(Y?vpioVf&arU@ebW|G9C zan8(thPik`nW4vgDDp+Q^$zGI*-yz@{1N#K*^kK4$axf{9+4@Qw=ca2R$$qP&1dJCbB$c36GF~Wwv*S*Us>6nWDMS0Fr2qwG!u|v z^By*ib{#!AZ;~u1(xt-ribeAkTc5AkCeDfwop^RQ5Y#c>mv4~Ba8aVjm`QrQQ?}a) z%=q1Ija0ruV?oHN>xn(k#1@edggC<3@TTtwc)V@X|_MMZW zO&uE;w>UsJV))JdIEE89j@f*o*z!njx*f{ZMJ?^n@YR@iVaQ8vICPZ*h_=(W0FYpT z4eTSwUbrxbWQJ(q8IQf~rD~KJpzx}nb6@C*cZy4K!$y+5ctw}8WtCb}fFA_QZgJw6gYEcr(#;NGncBgZ-orPRX7M_5NOOd+C|ex zZWStou8|PhrqS99KYbuB(xfH=-@{4uxN_Kl^XkbNhkiloQz_`Q@M_dZQ_JJ-vpo?9Z#`NYSz%ENswIKFHa19e9kUv4Pqy4kYmu(XF;uh?c z@F-_-PXRhHLW|{DtGxvTG>&sqSRntECv}Ihf5}bB;ilVv2#ZsJ)u1B*m=2}K6*Far z`&k@D#=YYf-jssa-WIsKE%&yai#zhfk0^VP!~9}E0#%&skxlbdI5{DwH#B77J`#4i zRehTB1hy&j{Q{kva64)E#Fm|GjEZ>3D6|l6W(QXptj*jY#DR2mIK0sD3cqBvV`Le35{#Io zR07`={d34YXb`F?V(4k%GZQJ+BH)DEi~9wOxQDHqf@565f6G4O)?+2uE|*^$FuHPy zA5QppDgm+xZq%}Z0V7rND4zh-2E9{HKcISN?=Yt?@e8U{VAazeanqV0oD_T&GFzij zEz%lR2(}%qSKcn9qN<90lB?NZi=MQ*gXz6Fg#)c4q~8`oEwx`-b7;U*GBVFJM`MaS zmV&Q!ZVUG8mnuz|lr{TmR2Pd4NOWK)Kq zw?ic?4s}+opJOIxF-Xtx?)||*^{jDza?+?DRm^=E1Y@!pFqi}Rq!BBK?^q|DDv4KOy7^t%NLYsDC~VKBlgvL*(- z6ITq-KTDeTiO#V-dwBYHps_0VC6t;{qMll%f;JpJsP__lsTQ!Q`4{i(^{f~!m-k-a zxguw68To*=48Wc@MV1NIRG91w1qZN_O7M+HkV)%H9ytf+r-N?F*Uc|6&dk+djDE_D ziv;W*)gwT16pj$4sXagkIziUI#-l-Eah5b=xO5-F=I@67n7lH zvUseH`5;0Qz_LkzdhdmA=V;QGG>kVzST7NmxI}u<$_D2vATFtIy3dfuM*}vJi&w5z zScv7}!CHykB!Q6&9&xSbZx{KC2jhT2JIbgyquB=rA%vjZL1A@RiFUXGr+?K8@oWIQ z6u9w3>AbC9iN3~3)}J(;?KX1V4*iIl(J{q_B&R1DVCiEA9!SN8+X=#W>7NfI#@H;B)l{LP`%I+d*(`>colE8ykS4tnbFsVBe^Rj3iod=(oJYV zF3mCeWsp_{XdbAHY@cukp7gkZ68twF3`Gzr(K2ZVPxp>61-z9X?Z33$B-DXPGm1LH52?e=uaSVr`ZBI!h zIi^d>9pV`Yf(V|iku}X|Ps4DyV+cuAiQ#rj+Q!srL(-nKrJYUH=CZ{n3 zA``^byyHpFp6j&_#4un92CjR}erU5V3H~c48NQOsJTrD4QwYOS!M37~*|M;q>~oWZ zn$n)V(JKzPPeP=kT$EP?%>r5X(F_Zxs5t1O@fHq%LuQ?9vl$gFR?Uh6_Fpgom7j8S zMlvvKQ6PKmau-dB*k{4+yy(VdjfbNFN&G5gRceFr(;vzay+MM`Qq8M^P%N|? zM&=RM8wMew+%JBnZsv04n6Q^7ROM7|tzILwbGjrUz!FX^?p7{m@{;M75SqQ6i$EwO z?ZLK)5jUkZu!v3t8z2QyA>l7XDNggX8Mo`45ReWqEIP{@`}L}}=`eaX+dqHTIIf(XoqWXKZp}29K64PZGT8Kv zkE;8%_eW3Ym@XzB(=+^AeM-NZ8U22p#vIcMkVI?|U(4XWZebz3yT2TvN1kSXPXI{t zCXZQ)%|JT!U{b(-DY1Z277dNAp=Da7z4@H&{5o-^?h9o80`K0SF3^SaQC)4a*@)5rR(H8SlO zI_*N&zaEy{t!KHM8h4)g&#EplrK{>QCQoRUsFo7YsXq~QBmBI`^(@RB3nqHa2 z+)D@ucow%BcmyMmwf;beVC_ndCGy|3a!{>ciiX=u7+GQ2E04)Oa4|}b$a1i4g2h59pz1h zcXp>HBZa}IROr&C9YdnV7@Ti>J1EEyY5hUJculO;B2x-H-=5HkilQ)!c?ozPJK=<6 zE=P~%-VlK}Hraolp&WN;&1#}}IY~3|m$hCm> zx`PSD=t4F|@!K%U-HL@dp?%J8!BVrvWDuXtU~p(IC(6D$@l#>R6M9le?bmRo`m8o9 z8QT%W%u(}}0rlBBQuJs@#sdnUItAYk*5Pi7{O@v>@TE3ib5@I2IiLoXb=)pH2OG}K zya#Q4((yIq9JHsLw4Xicq|FZ*-{7RJKvr^P>I4R-AADJkLUj%h=`id%Mm6Fcnew=? zm_^$-$7=>PrZZq<%Gj@`l#=qWzr&Y{bXb3XiXLOr+IzJ~dj~LGnN3AuR#R}MZBBaQ z*GpcJ+EOuF_2lvnhl-Y2MY0=ghDbTkXMhVGTe)x)~at~v;`*5Cxy z9Qs<&RNomKtlL>7DLR~{3f{Io8~_Hefk$vHaB#sM z!6z-wE*=H6Cd7aZxP`gnTWfJ)Y?EscpS_ZtH``vYf!=V9xMkEvk!+caJzO?E?HG|l z6*3&bl2pg@4uF=*TNuDW4JG5V%JJK3?uB(TugOp#9NQ)drvpbnIz({%J_Tud4^p(5 zeKV3`o78stqW2)ORc?kJo8sao6RyNY_w44V&2KJ8F-j2$zY9SdpV%X|K69>7GqwNO zYWu~fNjagNSA)RT$zzWMumV*Y^4KP^J|fiThyUWo@Yl?=OPY0@Me?P)MQ0M^iPlg6 z`V_XdMHDPVjMerj!n5CRn8Fr_8vcDSh4^P_o#JmxPday|Z;>A~dNCq5m)TiymunXE zo}bVKS}*3-2Q&po`+Misg>93eWn>XOVK47FzImKsF1qlmvxw0k zJLbXG*J5-td7T(5oH7KtaO)w?w_F;rFD@@B`TGZn|yZAm{dlQ-*ZCi?VM@YMbO zPutb;gkhL(18psvbecD=+>2zjmIBo-Ps`e~b zDLb%zr2b^3I&cWpDEB0E&A^zy#%wft_0_-xj|X_pA51X2R`(_r_BKrlN6=@cI^hx| z2Fd}#x@1;&+q}1cA$1z*8~HtD3@1}mzhdl#F-D3Q#v_pHFmDbXc5j;ZC@u5rOxtb< z^-N^iBNJjZd);QjlZ^lnU8$eLi}TBv?)opAC@|ZKIkeRL5ksHEV+^W4Y4MOnml&L1 znEoBl zUt!Ws$%Oluh3loQ zFfOilP=6b6V9fr4?MKNZ9%mMS^3F_cq#awbt3P#lJwqJ;Pe+K(*?ykU4n0c8c z?4iPSr_92@xK`J3B$SwL2wbTWs3t|L@_*V^=6-KHB^7z3W?P@($|3rsD$iTHaiCA)UI*am@mP44S65!R8*wXr-Uvn`X<#@K+u^H!Y1yyvaLW@k zdNkYv>;a7j+P^_`WI`++DP^pBf+VDV_$)4f@vm>eqCxXtvIPkv!*;~5tHF*wt#4fj z=aGzn1lj^o;cutJ!>7pKyJ0ZHc1j#>52|~sr-yr{s)SuP6A{h{^IY;vJrR$W?k2=A zw6Jaff?xmvl*=3-pb(K>7?+Rk;|CE_1zlc)XXVl?Xa#3TH|uJHkl)ih>+Daq*|h1` zs`{MEf_hoCowxS_Lzq=X9K-4it7@;Av}!}xMmyKWET;?X_%vLmrdk&*mwjckIh22} zQ#h2WVEB<1cYRTYgrrA>9TPwMxnYcrJ|m@>p%07&DW}wRP$XZ(ZKJU1{ovM6@6y#Q zjiXynaGnOpV1k&4S6b47pI>+y15PI2N-(&q6-}#EeApZ%aRZYbhz^MtyA1UOFgiin zbLjbmK2Ne-ivw#`M9`#WNKECD^zZ?KmfSbZ!%}Nm(n|v)aBeSo*Dv=%=?{>Rk&Fpk zi-ciZf~NZhEWg%dMBY%XW=};S^EqgxXBc>nMOrCcln7HZ)2>@qCWDH)*?&A(tELznqRK zr{CJMYq2R^XxHRc(|z@=mF~CuHI2PVchWcoWK_@fm>(MpmYXS2bfSz6-{X`uRiZWM z-f4CU-5cSYc3CMaI#J4-I^(w4zE{ps#Gwo05-3x-NK9YnQxTWn--thHf3pRb9j({D z&WiiKko`iv?Kr}(nKsxOxFHnINBlKAWQ}>QTSWTkPf;mGx+Ot_EYeJjNDW4TtI=9UF&= zXgh0r1csSQ_82BJ1~K_2qcG#&PaB3|mt=vSj^s-ohgsPPY(0o4`fbrFFjt$bsHxa* z>on8SN-2$I1%sU{;BBU|N?$0=rkQ%>=oC&3cp?4QqWgnnHt?sl^SwWRxn>)xX6U`$ z_`DfbYc#qXhbTkturOx2+yf}5$n_4JSF_Rhwo*I(YfZkJ-y{?K`ZVxO_@{!em5&HM z72PS)fdJ()`n}6dHI_VTa^I-5y4x8JfdK8zo|VH&{agrNq5!xY+-CQz&Mzq$e+Y#Kg_FP^XQ^TD#L3*<*1s?}U41{Hvql?ITg) zc$j(O>rDEe`-9tlTDT3QsE5&Zo*ROnx(_l$+V{tpgpU%+E8-y#FBbIa^S-0ld-RJ|jhs6NDO_C4KRQ^=14#L57`Zsna42oA(RZF-Dek zwBg;|jR2ZivpCCqp-PNBaZ0z^hw~8ukIiyL%1&{FXFg24xfht|*(^h(+t+_^s+}yC2z+wECeSHE2mqh88-Atz{8NvbDGd zi#9O)W0GHc^xT*?OWqVlsadhubX!|zK7#H|-H)FTjHw`nkFbz>So+(){hyQn`=&Qs zx&9WZv9t4km)2fxgiikNFx*`Gp8xyL%K!Z`mCpNn2Ji0~y#JSG@Xko#eQ@&rc%P2` zBG2{r?A`y{vUihpN8{-5wDGQ?QZ&lnZu;f%{g5YiRwX}HalzCZ^}Pzv30-xE(N>@f z994d599Q3;0R^zNXlV(Xz%E5PWt3fvToxeJY_a@hw@ET)>P5FdoQxZ{F|rscA#RuH zx%r?UPexE#J^?xE2F}VL?6Cc~pTvjF`*^hdwSh^MAWP^G@UDeGeqe9U-b)DMJB<7& zn%1zh9{yX}w%^No{B5{By*8XnxCQ}piBHBch^kN^mnxj6(#kLgcE907-GPdSG@8I| z@M<*4IgsVynQDrx8nasB*N!O13u?sudp`M(rhpu2#1%)}CmDOC^{wQ;5G2279pu0D zD1xuy2FiaM>o3>8%YT2C{1>vHy2I<0lhGAB7@%t*N&?6=KaNmF>tmRZ?-Js73Gusx zND`u7K-2?1`FLEV*0?zLT}u34B_*Pe^se%u+JHeE)ZRAU8ImC^*iQEfr9x>b@j7~+*VNzWd+QyEGUo)Xh`vNf0tdl2FH-d)e^scr z_L_yoHU^s;;bw2wjzq8YZOv@}oyK1?n6>t(IlLb90U@4d)>Jd={+2NE(rdO+6!`VE zvF>T3z&3O<(8eaTu@Yv~Uh~v0uuahb)PDJzZTf3(sM?!G?R9G4B{l%Hw_dZCPVI+n zm4nj=QIWq%NV_~7#qrJX8a*!P%JHaP?YozbbpGOZEOa|W*(~(^0jF${p`iM*@R^PCTI)J~9tE|;C*NSDDdD&+B%@Qe||6n9&W zBcd?kS2mG5+<4x6w9BICrE^IrvN_r?0KIgRe~rd#k=Z0iw+R-Ko?S8T8;uWW?((O8 z6`kR#5&5b(GmyoCaT)ldwBa=93K zW1N(>)9uiS`_TT0_pby|7k8ajAJqc4e??uy%;ehi9n?b-+kW0n~b znZG0F{hEAlm=@{w*M9$9|JX2pY|hhjqmxiR9=vZm!VbZMIK@kck!J1coQNLO(B?zjonJELYxc;y?1J);0tYK)tg zz4%l3(mdwDp9+IlTG`+#;ZA|=ziHIp)ebNhukk*56|HZDYnkuE&C;vQ_3Zkkt@T%% z(T4Tj3rJ~w?d4jyp50Isg|A+Q+3&+J+**5;{l2uZ8Ln;40Z1v@3L|U8L?24b=!ww0 z6w7n>(jsA)J=`c&6abh6jNbSD4M+>spU$ht7zMc*6x8?2z#H0|w{tnYolB#gX5a)M zeU_t2J9=naE9RJjfVgY7|0N!w=6XB;@eo~}j+@6u+7!XWi7NfUp?eg)xc=@8pujG5 zA4MT#Bdt=ALx6&yDvBRHi~(sB2VTBeR3I9Gp?N2`TLhinU@*!>d2GmPpFe`OX@XKg z0uZIk=CXid7%f^yi2O&mfu4D-0wP*~s>?2i7X`OEKM-*!AF=EOWW-8_gWDXO+nd2M z6JLQeRwL6@m^M#&jBhmi&E9>|l}2ZtXw~u#jyvFyccAI9h`Ox9!Bw?jpXA~j`+=bi zFvARzy%|a9KtMe-Ay04RBf1Er#_)zf$`p-mztNfWTg-XLD`B3tCDZIvEj;ade0ZcI z4GyFltE89cWXR3q)B`7!34av-OFuCXBLOn}3=MoB)~cVP@M1f~xRcL_PS}#vYb%HW z)yFXg-gg+_;4a9lhT!tIb=24ze%5lZ6mFBg!Xd8FX|~3&PH+m;D$(9vn8nFLlEQ{` zWq!5kCV&v~*x?b@N0K#KTty2^85E2}>BA$~SPzeOjIidg0%76~kF<-givGz9B-ew{ z_^90)W7^N19cZGQ4zi=|@3o^d(vB{BK>rYQlIvE0h*+2CJP;auKf00B--D05;c%(ldQQN&6MKEa!s z$Oi9lY3ZrA0$3H)A}N@0_C@sqGkDx`i@Qi?gu}^<@0(0+%xF}UNS(Us!YJU(KN_@i zoW=P`wG?>ry@||joo)})#ZVTE!B}k3c#S&hw!5uK4|A^I#R1-k(#3NNt2t@%@TQw8 zb|xdbMQsmm`|12{&vFR+4h!ROs}rD>gpVTWH~aW1JJ*}xZtEYUok!I~`lr@KMxwU| zJFT(N2Qgwe^M!VpX6hE!1%2))%H_Xj1!*4N3^i{Th(l@tmehdOZ=0jGk;MTx8oVH~ z18$iY$w)c>NM&ai`kAwy-h6$!%bC^Q$hJ)oY1{V;AQMr=IYH=yGwz z<66q3nkxD(rv<2wDU3*&074;kb8oMNX{=g!=2ZDejw(N)C@vmw&{TK|gOCAf(IM`d z#$a#&_`e`!DUdBkVctrY38SeDhrN52z?x}N1{{>1=qO5t4@Efdy;-HSY*zz(JsA>z zD29>q!ddiUoS|==5}Z#6&axaVY)I~lf?Kp0Ug+&Bw2vK5O!e^9c6S%?Tr7T-u9wZO zBY)SpkWg%FU6jk=^z;k9$yZx-No>_Z+_#^nAiHo=8<=3MJpqg;1B_^KFro#)`0cA8 zMo-wvhIhiAHsE=hH?|wVM`;d$O}Lvr|DnU4PeC%be}sKg2h^U{D(=0@T7!C#I;eY^4&zVQT&&@Gu&PArVi=fLZch`al)Y1QBw_!y8%&IeZENDBV^55UZQFJ-v2EM7 zZQC|`V(+~F@BKE`-Y5H{p6XtG*sJQPy6@k0ftFpj$xb!4yzF2UgLa68sqzBuLNAYB z@HV6x=zQOG>EKqq^YnIu{E-I^tr!|>IK2Q5rQ%uGOurT|VIrOkv6K<6sHu$jEwKymF~S-Gl({NgBb_Q39Lp?-lI_be`*@bt^P3%ea(pQ*BYlxGTzw= z>-ob*h>E{v-IRjSgqc#fWYLY|t1`2fqj%V+efc2b4nNkgxiZtSM?A9BSOd~8|Age< zL<5EL?K!25q!Y&9?oc1LiLg6GmwJ@K7^dVgYj!4YPZy{A)Q?IvzK7_QA-?SDsfy*z zBwa*d%w1#x%0BaI^VZTCSv>M+q3(Sxub1t>3>;^A|Q*8tv2(X?W=77qyr>pEK- zO?~|ztBJth5>otd>0+zeKHhtFTyY$heN#$$B9m;Kj?sFUu?a_h-Z>p9XvWSYC=hg~%iCO7(iO4jv*cn8>e&8i)qcs;pd?$s z@fuc+xg7Ts4kB}YoX6#5f_-jHXXXWKL$toWwX$H~Rj(|CexTV^OWCs_rEkl@h7k&O03b+sKzZG+g zS;%Za+N|m(>{!muA;k5U8oNms2ke)E70rOdMp-=K1zu0shCO(ohJj%085k@GKeM*B z0J}RFB!+;1s~|)G%qHIYk0C2lOJoHpo#-I6xylI_HQD??bVX?B+|fk+d{M@nWnxi5 zQPuAHG~Pc4iUN+vU967Q#ccSkp9+?&jM9p~>iTJ)>DZSRG!{!xOqK4GhP|1KtlSfc zVtq5oV!tr*{WuNiAvioej-fSgE%8o1>(7bf(G8GvM5SB;VA2N@59>cx79UghK@f)3 zM!lT4vMYuHfB5f%t|uM>b1x%#bK6K;UN)_aP1!A#u%w5(|IV^N^*VmyDOrRlj_75= zvi!tY>vwJD$>QS~Ph^=<5{98zuQacUXXt_vR(397GpLDH+{)Q zY&dBv4Un_3Pl189j-GMJ*&tU(vA2u^nSKB#)$FxhyCfDctkkz+L$R4Ru|{pdrxB+~ zIUx%F?1)+p_*zMfNXQF!q6~*FTXGN!!rXn7jEEfTfcsulkK9FUcPW6Z$k;`RnJR`f4-3Vthc5TubU-`b{eQU#8 znN<~|@tFyu?1dHSE8uXr1^5{Hvld^d?l?;Zj8A`j!pyZG*$TGove@p9aNs_BdMk35 z+zWx+O-`?j2E`R%aE*o_yPQOo)>v?N;f&!OTJ4gN1!iE)X6W5w(N>`>NabkD`lU0; z@Q{awa3ZP}ptOgE3z*!BDM?=cVYM}LkGz{aiA2aKsFQu=!9$?;WWu{iZ*3Cde>(gK zPCB|gXQS(K9{iJg0H%q`@e@!i#|eLLI9ZK$1QQjI=*e`RMY8C}hFv5{>T!@&71|e9 z0*1r-grct)1^SS#TTAuZ=U}QVLW-4V@mEbL*)n8H|8KgJ@>3*7otmnAe;7gSzH*N) z9P2k6icAnmXj^0j**CIv{@6AU(H zmox@L2G44xDWohQU0j;M7VNg8Z@&377^f86f%`Ukl;)yAwDPw26pAQPjO(kD75Cj4 z7ye8KW#&Pq%XmjoqbL){dI8k;D3v%JzmJD>mzOZKC9fuN2O*&P(S_vshH%MYG=w## z)1JpPsdl!u>Kokc&9aSk>_1Gim`_CiZ5o+w83AL>) zwmO@7_EF?tjlJN8JNoVc%>gE08Wg)qea1{Bz}d3~dU|r-SH=(jkrI${s=czOg~q-g zUMQ8!;wqpw)oM8b!nSCubCu%1PR>E=L$j*ZkVZCKH9Q$Ie zV3g&)n>jaq@W>I;6OjV}S)p+S?QlLTDugC}wrY&c#Xk_vZLw|t0Vf`uIEZMB!30Qc zEZ&GV-=p>%<=!hFamcug1|ISm#~p=iPAU_5=)Wv+@N)(A6TS6psv#EWrBerr=X4H^ z@dmD*#AwtOHf?jw_s1&~gfSu@xT=m%vRKmvXB=yT>$1|{jM(SnUXiCDAYqKGyd!fx zY&qR4sb{?*5I*r83pIoCGUa_r>cW~_#K=Dbo)W2B*?n3{@__z zj+q9NGg|~s#pZq)O@9R`aAptj{6cZ!H7LlNF#K*~G(U7-g=NO&Ig9i8Po~4Z=V}Qq z7r+5DegrQtqW{76XB#i~qf`qDu`a%^BHDU1NK#W2V_`fHnH-wzES7>SG!s8;(uu$9 zqcPN^#m+pF+dYY32Y%CnuOa@7gE><>Gb|5@bO#r-Zpv07;k|~`zD&KS1?`+Fvv_1G z6|CV$cALs(9dNLI5NJt=I}6H@@TLt_YfkZ@BJVD(ZBg{ljR6Q@a3LZ|wMeqJV-DDZ zne~A9m5jkw(T!R{n8ZosCxKn)q=^~i=_D{A^OVy;Mr}O5XZHaM6d}LOCv5Zujk@_c zO0(IfG135s_|rB$3}vnV-n&6r{X+i!WYE!{}a%~xDu zfqA=mxxyy7#N1wDN;I`}-{U2HQKV#1=inKYzm)(*kgQ2=z-RX8H_6}``A4wu0?-?^ zga=4NI#x&@GVnr4!O}^u{vl(n|0^RE+I zOY)8bq6?p^9VWc{-af$^0XPCo@-#_?2|``6Yc3FxL_8$tomA)zM-yaXU|&%q!ADAG zD~)^bQJ09M)|NK#Cb+LL^(Yg?BOZ?1rQhJP7u6~V?$`Ib4WBtNB_^Z?#sjpPzS+B+ z9V$@vpC}tst7heDCK*MY4Yp`|YN$rHf+e&CW!gSvaq=_4dKme}TsvB#8v3*%{u)^r zj0`<&bSlaFoFMDZ%OJ-6|CBXW!jixNkJBWy%ZQQwdzp}}J$-o>aQyES!mHHjyvtqY zI`-(kw8`a8Xrw@t+@nptRGP;%VIB_7jS2?|v@i2mI}Zo1=LTF=!)g~s+^KJHZFU6n zz6l2_5UXlT6? zHdkG;awn2}kl*slJQgXPThRPqmk4zZHdkz&FPaUIMzv4yz)(Dp$SoMmmirXo%FGwL4 zr*Rj6qtMqSS?iXhN<3y9XC+E;LwMg6=K7rxQn)vb|vA!iHgZH1-+e5v+9GB9Cq~L783CFl%vPF(}^{ z5o-QV5WFZfLg(*)WS4oIstHjYx4$rJw5odj(a>|L`Y@nAw!QU+v{D)@B%G@#V4RP6 z`l%+#6)x`b5=nlgGPVFqptkgj!N%4U4Pd>GbVcuFSuwvBU$KtmKOb`4&99tbci|^ z;bo*7W}+pn;au%Sb;e?^7=<5) zbVFkpMX*+j*{UMWcq}AH~ZR*?9IQ#L!iHpY4eJC}>Gz4N$z9&qR5NSPg z>%&aP0a>F^U#9xc0Yz1sdT3;ssUtLA4vBT0SwzWwnv?p_Gu&L3jY9s?0a6rV z;l+|9!Os(n+1)$xB!9MS9ujqJMs#o9_lGhcWZc}Vl88@K65Z;~S9}tkgslY!E{8iP zH5;R#HJYPt?CCcFTC$M@rooHWF6Z*zRMd!^Rx2TaOE8t_$tx z#>54m)sS|}9ahcAum_POeWXV}T$#pM(~*4G*C0ykh?3BV@KIx6&mH|noecAyui()v z19?UaTxt66{Bf-eQ9O~(gp={2&U+CHd1iPej>+pBc{813nBT$=kW<|5&NmcOVj7Yf zeeh!s0hd8XfqC+@(l!gji0V!b|63u{Ks7{vw>Pzx*pjrcFtDz3)al~DQrqUbO-deQ?5XZg9F;g6eW7i0W3qLE40g0wM7J;GB1K4iHCRorI}vE- z1d6Sk>}5TaMRxKrR15?VO-vr1JaD@Ccw=l-&NOu`p6G`?ytG8WE>;aRGpDJWL4sE^ z4EkL}FzZDujb_@n1kRcId=EQfggtqzU3j59s~Tc{jlK7;@|tYLsBzMr=%b|OHA7xB zYjEb{mwI$UHM$2sfxr=f4kEX1Y(HA>xqCm)`rK_jYKgHbdzAdG^Kv@cij0WUd)+=F zmPyd)?l&JIu?)lDr~Xn7WpbYVSCd=TA@e}F8+EcD?EUqjp8ino&oD{NOxif(Uha)& zbq5(83hk<08lpHUy0#Px$;izhu}gxCi^Z`zRE{)e*Wq5jvmc~z&&#U+4tQg;{qt&F=< zhZ9@74%|ub5cDwbc|_ioC;IL3U-pNueSCB+8! zYPnEQ{ePHibN?#YPFp(E!lW1e16`}c`ww)DYCpjbhVy5K-~)~wJ$!Fa6*~izuED=( zGBkO;_P*8)Aw>Zm8kE2yB<*@Rn?MWDAH2;TQ`a&)8e@K79xSuOc}RTyJ77q|BVwLg z-_W(Nw}ax$3guKt=1gP2ls&wG2E*L5%A?gW$aC%V&eD0MkAvN3or8+;?Z^G)p|EvN z`^@$`JVOP%VtMw`b~m@_jV$8cv$AQ@fw!B7mye3)-RJvZW%Shh%$L&npSKahGwY*g zQ%Ip-R`<>>4#ReLRe}+-L+VG*ohntBYFBPIw;z1aZV-@FwFjt@EWT>o<$V}a({iwj z?(G!ZoO)tQEJ_035Y^eHS?p(&gQ4jT8ClTot&)f#R_<_ zR^5sld=(3^r4MvJ&{yN7pF|k7{~@mBvFs+qj3`?m4C^7Lc9nq@mge+cn>GHIw=!9M=d038&Bq53@b z?h>UUn;2|(Dsh8_(Oc#R3kI2oUEHSB%E4Pm1y!ds=-l|BtI9cBm?gmfm*}|{Xx>=9$*phm~rdzOVS%hBhc(~-W`CN?h zn2%++xKM;_>E@a@Dm1d74#S(2I329{@z z(NEQi0dcyq`{Zm(VAzrs0k3{X-4U!1Jcl%~rsLNtOGGV9qanwfU;i zh}8j`Fsc=M`aSAIH}{Abi7*|;@9%%iRm+K44}QdBUYpB4>r8rUkx*w|*7+NNobDEYZYpXudLnLGinx89=UY0~n$j(%C)e&ox zuT8$JyjFfv)DFPsr&Nzv(awrgk8QHg4o#ojGd~S6<7Ru+qS> zw=GENCb1!n6;if~Ed@ZjJ5C19l6J}CTT)emItdbtyW>3a)XTd2MlbWt#L**94s41X zapidtj-Ycz5F*YxnTjrUS-2w2=C+>@OLMP1K?5#Yg?1P&7#cvJ z#qfNBK|$s7T^Gw(I&tyF+|;K~3ATN20TwYl0?G8b1s1Ec3xa+emxpYsi?sDAlq&Vf z8va>UcWA~ z2b#aCd1)GBiWC9NR&W(8PfP0%033{dp$je>ZoB zqAt7L7qSuXnn#JrX&lTg{QvmKdVBft`KqgHJ&{8=T~bw6f^4#UNfOSeAs~URYq(A6 zvSsCctol~qwrbhDFJknbU#KkfyOHJwWHGDJ9$~0^kW|4BHw{txyW6)tN>fLeK|aW! z+|MXF!E8}K;Xt%t{NkwFVPwy?gg3DwEc)xfSX4Jr41HkAlfcx;NVSge%@f%~hvlmG z9p7Zx1-A6a1Y6)WB)LIxczw)3@k}#nuqwDnTLo5Dt{o!HSF4CW_FM&SQSZ95#l>c} zwpWKrPiHa-sj>Ij><@&co{WO;Hh)J$U2;&NlTc)vo$_au5;S2Xt5f38VDw#ewv_nz z5mk^OTP=}i)bk&1v2^7q@daywgy*BsXi?Rw06WE#r%i>UXxqGcrDH>Xo3GrB2sk?a z)JPz%uj?P~%6c9;_^e|gzCedz;gx?Y?nSX6!t6RQRHz>nm{0s+T6i{v;3i^jvM0~E z@XGzl)2PV)JI3$9U3Y%qKezMo+c{YLShE-hqjHg7ar`sM?1d>Pki)Wa> ztR3C$7!8CiBd(Clw>A^QU~FN4u5oAFoZE>aNF92%TLWq~r0{4Jdi3WM(FQhp+$H`J zsLwWTRw=Rr|5q6%qF6up%rH~-D2`5x@IaTlE#yQAs8lpc^h1q76Tu{NZS*8_yFPL&I77Cb zPt*jB<7ccuRU*Yj;<54|b@3#HVPx@|04-GDJmVt~U%lBLdvpj1WB?Fr*W#xQ&bh@m z%x0wJUj-wUS*}{TO%z2tkuQk3I}W6*0`tlDyxzamf&l4Za3p*D{R>?MSU55Z8iVHX z0h)fzn}J|8Mo35?bxiqO?yMhJh>EQjGo4kG!QqSm-SI%8B5VoQzv8l$&yI4ILPa|U ze=c)NeL##;$aQfd=KF`bGRMu{6uAwwRfsjCk7GF=fUbjTlRDMKqSl5wB{h8ZSF)^n zB_53MIoExNh?cu-t714(%ux8)*gIDv0+!U@x1y$R1lfAq?G;2C2=CAFqj>NhiTieh zwex@VejD)i*XHe4*6V5lis>o>{45haZhb$-b$!qiJMcNIO`_m`HAL3I+_I6XoE;*l zyzdpdl!K&)17h-4^0V}vL|CgTuK|ev#qrOq0Ms9Oer5~WCiAO>!%}|CeDqo8sAE_L zusTPmIC(n;*M>eY^ZqU#P)}#2>jV8o1CQBx>^3`5L(); zNeL8hVjBTD(Fbwi$zNklCRrlii=wxRiC>w2(h_e?2QMbmQels@IclziA7@;>Z?=%g z_)h2gP^{CC=_OZ$66ln-lk8qH$k7ovMgWQU(|!?tmI=bWNFfD+w6ctHi&F?F8Zm^Q zZBT)6)dd@4Onn|4CA$c^(A?7}vo_eTCjO{F-p%sJH8)20v!V2B43lB?E)7<Ir0qC0pefq`jQF-%oqJ}!ueMJCs!~I)U(@RqtpJNAW=@kVJC9Xdlx#Z+z5vTKoC8b|+ z1l~&YIAw}QWkYP}>Wgc{`=oc4W!U%Di#*tJqL9CuA`bEr{gq1&Oez>%a8X$b4}^X? z{paK-pZC=m_8HHo-dK6Jftu^6-Ie{ryqpQjLUrZES(LHc^Ajz#&f|4;c&0=y1aYP@ zjpHHHv**Zx9O6BJBDG}~#83y@OX_xuJCrhtY$+8y|LwB^DX<;U{gvzw?RMC1S?6bH zSZe;lwnN#Dg=_MYWi_7lAAV?s8bvr`~CryK&1&IeOAs85SdYVU*;SlKe}=s zp?$zic@Q6AZYGCPY6 zZ^#;SkZe68mJ%O+N`NpvNwB`HH*aY;NE>Vo>;;|Wa=O?gFx+w6l%MCJLPbCM%*Nw% z{-?eyvH$E?9SA8|1XiJ1;cKfD^Awd@r8RyTd7$$%;tW9TjjSIY5-hGq;N}F4HE=(i@6U;Q2!d%NDuR=EVOuV!z#7 ze#oDB@J^*4#IQmoEh!W161^2c=0ZQxfvCUTfaurG?w3kAzv_ylS*yf;1#V!1wBSo& z5z7LV=^JgOleFuY5;LO2XidsIV6HzA>Cc1Kh?9qnpOJ|6V^j4Mh)JUl zYD-5#283pc>MhH9@D4EGmnPtyC0&l9){9^+q;nx>t}`;5t--kQG;L1Bk(oWf`TKNm zY}!mx?ZdcH|FWyBYNdr{Gz3(WqNRpV;D_5&#pb&sf8!Djd@)R0+jg!mx>2QWUG${i z5j9mgNo?#7KdHhgrZ;`#ssTRTYKpZK-bIln{HjW z)$XUhc^^GH#_&QuuLv&OV=Z4tNTcysfVb83wc$sZx7F0O;X#=$ zt`uy!ME z#gOuQ>h4>HoLR*dPAz*&0<`$NORt3rkjW4N&5c&Dv zMEYh|7G573W>-4l2J zg*Z;Fw3CKYVS5dlhFqAiM|?B}COfT#&~<)!;9#8jzf0C9ByM#IGKSOJA>Bo7+U1Ob zHKr=oKMFTp8FtAI48!kO)NBiiMgZma72Clpod}wntC|e$YGw#7B9V3%jo%7pku81s zwqI|{ehzRYYIBe;t3$0Lj5t5bV5z0XwOYOv8P}y?u<2LT(;R>#5s}^i*4KDu!kZGR z9qnQ0dCi^+D9rAEZCXO0)jtvcgJd3ks~hECDC+o-+cFL!hj{$WnZ{0js7EzYUJ=Nn zZzgWSgfzLd^6PCK2LAra?H=B|5T~F`oI8)YsD95D;Vs&=fsF~K#II3(c_6WCR!!LJ zWjCl08*b2Kq3qj`yao!b>b2I~sxA=YWIqs!3ICqBdkLDnigCDgKFiLp$+1)qkmj8- zb__EoYEb!|-r0#tMfsD@Iiq~MUg}~!6XfrK>5+Os;F%Gul=_mieE5zuaYnQ|Lc@!8 zvNpf9xW**p5Kn0a{-s$(Sc&uPE}z;I_?FW?u5U1!z4PH;xv5t|rR-e-ty0z>vT39N!lI~rgz+ctyB0-o8`i$ud>-`^Z0{hDq zjvF)0QTrX{8_*mtr3#ETD_Hqh(*l3Xtu&~N1v2)Rj>qWm&k+F#jVVI(e~~YPr(7~l zYAs1!@nhWs#a->)8E!PKM$9aAT>DRtM2F=g^795;5U3FCaFUXT)ak3F=}o4oAEjE- z*(nK&ja;SdFt?xtRcur+U#RP}44|p0ZDu@ixspJBy*2;@Kx^DP(V4oLANO8l+swR{ z&xX5P&TB1;QR^5>%H5WoPh1x9M>v&5@XuzWgM~!DHy5(H=EUb%>_Kec#1C8+9o-{}+$>NiYHshL4~?M17B6{~Jts6@Fvn#7*e7V^>}*8#hOI6ApdfLp4t1IaPcq1-^K* zdet{SeafvUXQ}6arYqyodj^41LTrvKq-pj1{;$;xVeR=0--+6CRthd}Pje>f=Ook( z@mh7;1v0P!LzXKtHMD*>c?)<2TNVEG94|qQ*26TJxsQf2r6$CgH$p90dYs(~KN;(- z!(K`7koV+t$*NgsVp_pfydO69Cwc6#k;M4)Rne6*M7x|IFv8p!eo2v&NugqjrVCFe z(J?F`#@gm`18j)yBL^x^hjSp}MGr@TkkoUMJa{q?v?+DG8<{UE)s=(kpr=wTn`Tfg z9j1JDsYT|%g_?Dq`tO|&R|OFuMJy?;1;pV%sU&TU+u)mEdk8=PU4~iO_t|!wy7b;s zkmEpBkU7=Q5ZSPZ^b{n=O8Qe~DCXDp?Jy%Nrn~w_JxN;uDJ|^S1*`DnT@u0=^ z`drIaL4Qfk^LOkgFNbQ%wa@DLRvkmwGkca(n=wgP?}B8RA|rYZob?^xL}A?vQCsR* zUsM!&_+~>YCiXh4kdnvJZeP;--fE4D;Rs(&30nvI$)f`=6zkj=#3AA1Uz10g4THlQ zYmaSpNsRUkGXu)}W(~j4gS+|A0MnV!UvCN*Si)m%*oh0O{mZ+54##ajGIS}>xf<<2 zmmGLmK;QHwhPdgSB>>M<6u(Yy?70|l9K-fKRucu;fH!B<0)-bmiMci z47M0&(1Sk;>D*D>ooA9xNII7hBWVIMoB~r>p5l~sC}Z`>>wM}i5i+**RbCuYbgVS`8Lx40odSR9V5S_4^O3)->UckD(@Vg$?0U`NmQX}}XN08LvxT>}{Zd5R zkH)|%H`XI+_=7l=O}<(!4TYTdJ_c-|a0a!gu_=;X2+!3s2lr$v!%YdQe+EdKVgCeq z^a9Ls*kuPxT-mv~QoeY&BCq4_){)c}411?3oj`~rdX{}fKV)S7`9y^gK0p8aJkDXb zkR{gL?7C6!Bnp90gC?(2aEj!$R|=s5=YGO{jftV)w*u00ZzR6&Tg>NxI?ewXps@>b zw9B=RjX$Vf7X0wdxVU)6?%t$I%eg;4nwaVdvb?awEt+bw`#9Q>)JLnT`ub0RrT{PM z{h9IJC)*Cd+Ky>gT`^1suOp%fBK}{g87TG%2n!st=Rgt=S@y$_gIjC6;fulMF+yxg zKEm4!?5-c*l`Y12dY|27>P$y=bQeDc6SZ^proo62yUD=A0Y>OK^k0=>I^I0dPq$=x zwG^pM&#n!5o4L{HVBjgFr>&vDDT8(+Qr^9;8|6Coy+@#?5AC|GD>dsq%21?VpgfO{ z44CX3Xw-Bh7{z?A0@V+-dl^4;O=}&*?p<1ce5(R}kVhQMU1xwkS_#6AdoUognEY!IUzknh;6MPy#y(gF2pMCQM;qA=>@VPNUTB{|LxO+-2; z2w&x$YZF&R4qm2jWu`K=7e6oe%b$&!>jnV-zy!?(H|NL8|J_ye&3)nH;r)-R$lce+ zL1o0`^Te0Nx%A^8=DykCo#m3h#I*LIHi1Qjn~S&d|COEjTs>R+3({UbAL3NlLmy(?{^PBfP7nOjN7T4YLCURe^j>d4BA+5&U~&a+g+oD=XV}K zfn_JlUQD5R`q(`~7H4Q$=pRaqX&KK!Wi;&t_fD^3EXO(R?b?T)+Eo{S z1p)D@-~YF>Nbh3Dz#+MmcFPOHOpRiAC4! zsO9ac=BdfMU18vlYISN@rGuciZvnESX@$=HrRJZ#v#@I44Z{A}Bw9!n)+T^DVF6WH z|CJYf`>l0_dq^k37uwn8_WwvC-wie!^GCsQQs#Vb)2RS#mn}LElTt0)K2Y@fWEb>( zjXyXZzyLC^oO^mT8h1ADgP#SO+}=f>(dvHPt#RUPEUULBUB6Df1wwid)ukY>WmG1u z$^=}O&2hcGU#l9O_RgsrPp)0s`HfU*>IqNr0Z_@pG|uQzU9ely2hT=&v&47$+n{UX zjE1D^O9fT~(H*uq%HKsO6v=thKh8PnKoE6889-v6yrn^q3`Hpp-48%xW`*BRPj3^Q z_bJ4!OJPKw1;%pa9*3!yNp*;}mw%s%xiuavdsVr;(?4_mh$~ zEma_V{QgX!#H@>}e&)*hKTdl2{A&6^@hn|Ezy-)Z-qEU3T5SUOtpM*aq)(iJw?%8< z(Cr@?&&P@uq6}#FwK2nhDA|^kjp@$dOF0{Q{d~Q*R5BwGGPy$o%+5?FF3GrYe<5@= zaJjoEAjsj+_48*!J{zhV4P^vXu9CF_D|@&qKQ&GFEnpQ_YfAC7`P|nLp~G~z0vE|N zQgtHlSCJy0&Hh!8xvg->d|wY*jGZHvO|$l{Vt$Kn6oFBu2e#vdZlqMi2pFO{)h# zJBnVOJOrI9-Gpl@n*#xrly3O;(}n4gjXw=By(jNxqZ2|98Eg<>38qZ5Q)py39Gk+i zp)K)AFtGl>m{bc)@)6MbR~XSO3@gx>Gev&_{h5YbQO2uRv(l*hc;y6G46E01!yrg( z(9p@m@~yeT8iDjEq3mqLuDj?_vcUbNt=K$r-{02duu=LK!v#lmD%Iw&H^pOx5QO0~ zp}yCgsA+RP3~g482Yb)$xy!ny^R{Dz^a1b+=kQ3J{US`xpCdW6Rkn7l(|liImUCR$ zUn~EuZ1~;zwl>!RKisd%RQIh~y?b$AmLDuJ`(^6xBLz2&?Ic?FD}k-?5qjec*h* z8%5eO3G#9D+|d&t9n=ZX!FvO5b1^BYV0^+n;a6Lc@?QgekQboX#i+*eDGqR+H5hdE zETYvcIRD%qk$63YS4QufT;NO12K7K36`3 z638e<3h(hQC*%5(z{z2A6j5NxwO%~5CTS!v$f+DcUm!cG8Qpu&c7JRzUcb;k5n6og zM*A?MqZ+g5f^`P2fA%@$$V5l!h_Jq}9z_T(34Q)rQmLVE9GIAr_mf6)c^j{f7;?D- z)PGix^=7xV>nf3O_?t5@L4LxSsmo7m?H7cZE(pa&U4b8!tF2M`{uX@!aniRO7%-$}QiPNn zcG|EcHimNBRd%vO3F5&nJt}jDAIf3FpWTsC-p;O@5>B%mcyrXP2i7 zr@+MG$<&D(MZ~9iWIpq{kbbpZoOn3t zmBgd?8~M&AR=ODycW*BT@18mILzsM=Ah-O$l;Rr9?&%s8RP+L^G7iwye_27 zRXH-0l4VVJ=kmd7_eITaJ*Z^Yp-;8)oD#nq&YIGT5x1(a4aMRLg3BR6B7hMe={hmj zh^}tl0_xU{%)I(9*n{@)o~qwB8md@2AgZPnF621fWukFkHZz3bpu#4{0H?Ps_O(}= zy=iplL3k4v(89~mDuffKK$HHK0jtk8e1=q{;*G0dA*Wz$GV&Ao3S)u~PJP$)`pN4FkIr!FT(#fCrncMBB&=R7&>gkWZww(c$8uBnK{oFA(Y315$p zbgbRc5w{>#DB3DwV)=`{g;gvJi)f|A1Jd+N%+p@?3lX56y%Ao%H}IAz*(R$@%@Q?B0ULp|&?)yyxTw2n*4?q~ zj9YMYWCyt^gI%)VZnP^8#i{UCYf->la!a?4T@}!r%fq4eQRBgZ?oFu-{89;SsF%IXj-!6 z<)UUENV+~(oG7GPPz?J3`O&@XkNZe5MZt_uj9*AiD1yD5XK>WQ(AXrC=ka^(x!PI} zkYR#Bo z3n@w$@E4k(s)JD~V>g~h2nb}6LT<}LU|rr0`=rtdy7x@<63U3>3u~YIB8Eo$Nm$~4 zkK3INCr`ozH)~DAfCLWtQ5CBe2;Q~&Ds)1@e9>#q(Esw&zr^^>S>X+J@_Vi`B{Z6% z%N`TLEVob@{3j<$gA|o&2(ku01Q;8$DX0<#&}B(_RcNSF7=$P~DJ|+$JD9V8Hru{` zZ*|rY@vmMDzhSb*O6xG9w9%a^w{bS5w0%J5*-v_JOLiTbWQ+h^2JbyjQqs%&bXB*; zLBmaohFB4z>J(-)?cy67&)qN~&TedvK*cM!f6X&Z;_?--qNS#8`>h^<7xZ6g%)vBDG^Z8D{@2#Wy+z_l1*>t zSpfNh`5p;x&m2CIJCcVGB$up9`&P~Mn+Tn5&B;9jM(q>{XT@og22T6N9P|WaA`|&D zR^+AS2coZ82r!y+{A88VSu?~LVoah$KWKH92ctm0V zw5oRM$eot{>3!Y5HgCasT%JS8@{9R9#x9*boW*0qCyha`xriK($g(acnU{$(jPrJJ zvXc9!d+|Xe;X9Fn_VsMRB-5!PH1D0p49E$9j9d*$Nr*CFB8IQ$8fUqY?L z@Au$Wr%6`C%YZ8r{AJAV2gl4Y)9hjVsc3hKr>x7pbla)QFfL?&hcbnCht=hW|{S()L=^CTeuXz^(ve zi)CqOhrdr)bX;jeTgGRB7QU<}>j^mt8dQ`$}=kFrLumH)e{3W$x!fdrPXO z!Az#uVefN7WLxfT`5s?PS&ck}M&y*Kwm+`14ew>ZlF6jNlm87bGVmH1Lz1g6O-?{g zk8L7`%7`>?API!s549U^XF$5a`8jO%hFTDv6o`s-c$PxUl>;Q%W z$YzYZq*rf>M#&{THYhUlx4VNDR2!l)vtdv%#><0R*U1_8Mq>(&donBV+AZV8E;u}_ zgRFlNhLy$)Q(JkCwQlbm2}37e2B+L>>;H@fvbU%7uydm5u`AU)+mor3O! zBGk}`;PBKm$Y|0usAguW8;nt`dHm5%b$aUN-xT(^M6RN}z+m>@e<@|Gv9bu#hm%S{(79>!MC46$Zy!+yI2jN!u2&)fL@5RZhFdk)kAHfM-m71y~9^056M0DeG$ zzoc$N+?zuMnsbwY^cavQTGRgGg$beg8h@MQLmkaS0Ui=C;#u1iz;VtmWQ6eqw__jl zcy0W$V@v`)kvc`GKf?OU4qI#n02nvRqxm>uq7QNiuTImFN7*Bw_KpK%` zx8T$=7|25wmrN}d)aWd}TFiBjwPdnakyvZl3&^`zmcIIGfu4wE5jY%3ZcOoSvWBJ- zo;e}hH@y!_rqL!Dpu2k$g;kk%f1)toi?28#V0_=C{=iMjh==j`ooebz zO>JR0^Q7<<_A|4&Irp}J?e4NIlPCPC8?C`=9=+e1qH!)qgJGNNG|-pxZ@4+ZpYoDV zJ#FiKBqMnA)@!nn1^3@?wf!2WtN-*pIJFMv--FG%rsU{tCwTJaY)p!?Lod#nzU2-r z)^WJGw#AonxMA|rPSV=S(9U7Z4=pqKq3KE z;Dag^SW*6t*20%1{ak(8@4ang)^YkMnr&p%DM~n|_u+5D{X}l~@{w&&-6g>GJad)U za}|aK`hTw3N}SmWqtKkL(yM32d<)yp7`K z=GH6UH2K@seNfv1O?LZgdSb{6Bwt$J+A{iOo6$P8E#acy796Th23*X6OTa0XoWzHK zL*dMZi@9(aa46UWtf@L_xWbo+Teh*WxvARN*of3KWG$N<)-Wn<@Hz;W{w>>De-&x= z0c)P>zTBX>TU%ROH-0O+pgI}LMZ)%S>t)Eg)}fG-l4FpN}#BTr&S$>OPB4=VRuc?d;>4 zwu{sEaC_}%$QSeN;a^X*{A%LqUjUA;a)L*lNjrYLzD3rZqH)Rk%!1#eEh%PbX^Kvp z&Tl`SoVK#s{_AR7tof2Um$lNy+-etl(rm>Gi(Yb${isi;jnqN9L_3@KEJmdg?ON*j zIvjE3u0-FV%+}h=El(ZK?(k|&eF`|lv!Z;LF#|$co#%W)DjLQzc`u(@SYYawfUcI^2bBnbdo)LhRe@23u=k z^hfL{*v}%07n>6;s(Nwu4oCT7P0fOzU$KoW@_P01i~HeRL=9O6*0 z6&ZDk>bGoDwxJJw8!weEo4-^2rdZf|$l0IuS;P?Uilx$b^;wj^-MU5lbFMa2zb?zS z#w-u$4$kzUjd17UfmvggiX_pl#EXUZS@?2T`^IMYQh!35>m?uSC|b|u;Yrk)TGl+U z^XI(Y3>w>jJ&z7|^a%p><|eVDjgoOt68I4BiZ4qqH*_7wI*O4d;=Wl(Aj{II5pa2Tp*rVkJA|VMAZbML(eH{-51e+3U z5a3{u#AN(@_P5rvbT>AN@{&-$!~`0BwmNm{)LyARrENCOt;8`rzr^zB-ymu-D^!Wf zDR}U2aOH(z=yMU`=Wh>Ygn>ovtF@(;k++DFZ`QJFSu>?dzpO{O&?3z zT0E&*I!2#Kkw&(kuu}2xK%W=ujV7OGem|h^Nu@f!YgxaF;IBN_wwa2gM#M@4?=J$c z#Q2){E6@2oRU~nnAGFzg8uzcXfb(ZXg0GAJ4(k~IU5TQw49qsX7gj5^`}#lk^?&a}!S6%C z??b`wL&5)DYy7x3aXQF*(}3{Vyg&H4M@1{WAD+(U7yT&=|9q2p^I1jbrbilX3BZwj$vVk-F^NR?94PH zk$HF2zkypL_w{UEe9oUK{#QfWDZ^Fktlc~8_GHdE=p=J2?3|se*R(bp=7zv8W1jqA z`0;s=`SYLHU_Ux#*>~2nh%DTIos#c@PGd|-Q#onLe|eu zOL;dS-5XVN38&T)aq>GenWZmEmb|QBbZ>9-PG+x18DI%^q_I0auZ;tTVg^`E2WHNB zKOtAv-ciK343a{{%rxn4YHQ6=;3e0V-FIK}XSy=6wkWJ0Y=I>dRwFelgnB1n7iLoiyv^nUzxXYRb z;+cW=lk{7PL(dfa8Sfu(W4h*L3t~<}&Y{Jgl;SM=Xe(bhbHY`R8W@lH`ZS6`)YY0{}MSQadsc0q}xoxV3qGet!lO1uM8 z`13P8AKo%)UYFAt0cDOPfjzYfT-uDYbvor~QVWwrm`b;|DyKrpGL!t^vT`d~RWAHt zw5ml$T2IqfYCuTcJ+G*Rll#=6;`r+9sY3^6$*ioLs$Hu~JbADpS^N6Dvzp$1eUj1H zpPxCbURVgerqrjnj~iqi)f~6dAo$wP2%Ac)pOux}%cAXoAfxmK&Xj+YC3wT(Y4C=G zwNX(y?eNdf-2S&q zvzqj-M*}&?-=d_wcaXC&-&l|Dl97rjclQkNf)Dl*fz}XE3kIqt;T`wWcK7V~w5{E( zu3w}1+Nof?16@B}nP2?f z@ZITpL5wA)9FDvYJpJrlC22)^2TH}AMmw3jb1~d*u&m_li7``G&=S5Qc|E%qNY+$S zq!{~EX!&XJGnZjk;&Aj%wtDRDxtA+p+kSaF-n@L-KJA?yANRV4t%C!vWWq0r%R5`1 zN#5g*;6lZ{pQI^n<~3p1c3a3$xmZ^YN=P@k89;TVY=|Y=GQ_puFBy`NTh+wFNr(N| z62hdqK58BG+NY<-r^%8O$xQJj2aWwxsy82eD+CVq5m|AGigU{#Z?oheB{`LXy@&Fj zcdNVj{_JxR{(+O*T}ju}A80)SWY-PCtGhr2!ksDLSFf6)mfgL+2_BB(%lSjDmZt?& z<^InBmT@8AA*KQyO~&tLS#_3K#>6a#05j}P83Jpd;|XewI|%UIjohIo=@zslVR|2p@%a1jIz`$lGG; zodKEX!1`YX3TNDcyKk^eJ3GiIEs~+8#Y()-+?>4* zfVPK@4;q#`OX~n*7o8@*LU^5YLy{EL=95ijpYx4vOXMU?^T;C21p^v&-|UB z+-4K8DEGj)SvUY%rH}ejiYPC;w^c`NqFZ{9QDtelA`Mj?R+>=A(fzaHtSy%~N^Ys8 zuem>K6CLid%ZcNY*!;@NKsrZuP)x~R1t zfxhI)l&j+Rbuw>(Wh=c^2J;atw1*y{S-8gfn*UkE7Ni^elMaLa^%9?xLPC3;R#>xY z#8|Drn3K^hw6R*bT;Sr}%v?>?sFh!|j`rVn_Rn7TPSM-4d-j*?_Z;=}nm1pyI!9|> zIcRmyL>t=Me*=AXj@LCgdEM%^QIpy}?c&=)%lA{wT$yi~4$vttN(XBvfFZCpDrroA zLU&~V+>|SgUJj=-^%n4?RQF`=z)@V_Rsv%6r|)w8YuEC*VyOH#P{6(oK;) zpdoF~M*Csw%cjBjvV%In)7H_e_DaZE3$44>#hS$~GFIz0Oca(@521zY@|FEQXZY`a{3Ga{Ek zXkFaf$$t@Y>K!5l-|B<&dqw%oTVnb7U5ljM^$bq;w%kezje$iu!(gb7lj+Yh+7-21 zPRVzC2`{pe70KUI%R9az6KvQQq?H%(Wgi5jzoZyN8sg0n#)MJaQ+xkOx(Cm{>w5?QdjyPM$;YsD}9I-B>g=G(OatckE#<$mePhB%rTwl7=@{0K5; zPQSX#*J>3@JHLRQrjwhc(K<=*%U|wmdjB5lf6x1)`a3BBuE5(1)wRwp~Wcb@(%qPWn@i?CL(YShk6Tlb72f9Snvg6i6bdlzVs3ckY zO1lh+%R&Gj%gtuJ$sg;@Mwy?6VY3p|`D3+FtH2A;ENs@x^(sA$%GFA<#vkiZv&2u! zrDnCn&B~Q(6jrENx!!D6c!)|^27Kd>m0F}9>-D-!2bwqQb!t{E*GpA-3Nz3bnqf8M z&T3(;S(1;Huq4fDwMwbXbEq|{4SAsscrMNAQMJ+J7wQ#QB{!?r!fKPJ1G8x~8vLDI%s`zQM zTx;@Z%~DvY>Bok78dfV2kJgOBn#`dY)hqQfe=J9hS|lIqjhZ~IMAZ_H)`VV5JTu&% zW>r2`Dotrttv5pkNwXG~nlc(dGLkvKDk}OyGpb1sbptcR48f9Sy;`rx9P0IILz>l_ zQB$5aaB=c6Do4BlfO|DTu4V%!7Rtw3sVm=);t_|SV(9!Bu-2i}}f&}1K(MdJ{{q$p0(PoWuLnqm&nmGVwl=WjhGEW8u&nq*+sm0)DLP3(Zh>9)K2>&BuCKo0TJ-L$lmapaT9i%ty1#W;Ha;s#P;uwV}%d z_?gjaX2s2#9j#`zrCE2R}p(@dvfSJAMOY*ftD;dE-VM$OEuQMVuM zd>c*E8DOF|Q^JHFL$iuzWZ$(gYnCgfS=m0VRP0AH$!0aOAI-istF~FqzF?=`tl1vw zCDW{Kr(@Sf^jAOHW)0h{VTWkg9vXJO4ZGq--8OSNv-541GC!JqYc}m@?ngUtv*LYx zkbYXt{8;loK1e^UZ}9O!`e|c>j}KP9&|LQM!MYdjwpnO7g)KgQeltvmbkF~%^FLir zCqKmljKjE-^iON}|FB*T!vz0d1#a)2|NpJ>Kh=X*lgT@f2Rh@yZX)kfYkV<{KL)K4 z`jX!#eY#Kjbf5I;KIzka(x*F0`UL0i{p5PKD)rJP8J|Q6k8Y#cS)%lQ&-ig^$|*ll z`pOhj51{>GFejVGi5X0k!lVy&EHEb9x)y>M{v*cf=jS(b4pxRMsy$|XGAf_qS@3QW zP(%bk8#7vN?ey+2IKNl_cUGHcdB3ly0R7}amfL$^ypZ`Va*)dE#Pw-@z-Ad|g%}MX zkzr){*gI&qPIG2B*NH9Iae$RKohALBH>!Qj`ymys5sHN**vSfQp&K|;a<z6?jf~b}hRbq`_En%^v@UgUk?~5+Yo5E);P2NQF_{w`lK#)w{mzI3}+ zRTk&NKY7*(s3H^|E^Lf3@NEs{(v0wmyD zkRC5@0%TW5L+Dd(5*%4FdL-v;6Y`}I69>s!1hh$Yv*W~p27(}V(gx2myMx;%8_?>+ zlM(#BBtOP40*JlI_(MFMn|>7%G-=#{3H~RZj{76h0QBbqA1Cj~iZ!}HAhb3PtRko0 zU>H1I)fQf0MK1^1*+> zr$(t%$_GXH#Bai~IQyZyH8U4(tr=ot5^MsSwN!l#1+>shg2&RK^*6_Du_7@mA~ehR z2)I?<3~9;f7Bt;I;YlX$>WS>e^8lWH7y_cn41(Dti2H;0f{eH=BtJlj@PoQ(*ui}-~ZKl|dU$lereR`G3XBL_48Z5w*| zU=8D+jLO_Bs&FM`OoSWSSi`k?j8$QWh9WPyokWF#-op3$@x}Ke+;l%wpS(7NJGEC% z1oxfp*xdwq|5p35HavH$eOV=Us(bhn;Agvu`<~(1akfj{#kcSlUjZX)8`Mo>&7xDjy$6wt4qg<(l^`!qtIjr3Kf86_j-1~pr`+wZ~f86_j z-1~q0_WmEs%7|q+hGhGHh!aQ3*tOdGv9o4#YxXMR5Cgm>-a$(-)m&dF--PV`P4Enup~&*F~)Tb}SXuyvCJejb3` z5+x|9O{OSFU5}vu$rvQn>Ey~}BF(U3@A&Uqg>s@F6*2pRanCKZMV3fpLSh(vIB^Hf=q;~ZmrWfW2?ryQE1g?pac`cIZ5xVSO4M#T{ z>ZA!fJzL7o?UdWg(Hx-TPYwN-%DydN?U{0{vi=wu84Z@zRd6z+nEVYp)<$j-{ZSC+ zgU3N+TP?}{u#-{FPCGH}lRL~R`eg|YmODeOa)Z(<`3tx~1-Eh*k_jdJpfXk!kJq_) z{chLhI6|#=gYrDV%#xB?KhXt!Q3xca@Z}+JcMfCytMlP(G9C_Q3aKT&V_Uh4C8(HB ztUOmB$7v?Jtn8D_dtIOUYoAU&qBY%nHkjB8KM5;-KlxN!tmO8yO^r!krm^e8~ml;y9G=t z+reahTbRsm50m-lz+}D(Ch5bJCLn8k!8Rjzjzeswdtk~hcI$a;PDou}*^Or7(oC5} zkhb@w?kcw)Rz_|yGYhx-TY2mnHcal|4A?!&2I-^3eXzu*H{(XmaPM^(m_l|@+$|it zKVRs%YuU%?ua922Y+hl`AsHg#Li$Pi_rzYPhnd5#T^UFlN8^M`S~df+$_e>_CmSK{ zLvJDy_LBmRM2!etT;+_Za^1EZg9rPyyudOBAX7?TDTi9uSl^%cygvh|p&92xe>lPf zOjt*!IG9{rQ*j)6Z4jG!ivA(fYC%b_1uI)FVNh&#!z{1XgeTc*mc^p+Y7S*pKkxd( z@do|$d~X#YN~>R&B;k@}a2=EKIdGY62$$I!xXd<$%WONi%x(#n%ICsmz9C%ZYv3~9 z5H9oW;4)tamsN_NjU?1(OPL3SsoS{tJcF4jJ~teMb&icqC2 z<;&;Orj(!SI^kv|UGX^7)qSm{QD$bFQYo*&UDBy_Fq&-)quE**%{GS7Y+D%3ZVjW# z=fh~eF^uMGVKmW6zmnzHnq+l^Rz^UsxGN+2afy_-Y?oPujHo zB||oLwv^;{mW4YNJkf4#sFM-bHV~L?)YArWPf2OX6JkxYVR{(};q;dAO^zVHd3=*P zxUP(ETBX`wCM*7$0Z!Il@|y=ZZFI!41DuwrYf`aJ54@`{DVnFn^5o(8RU??P6jQvs zReGqTkBC>dY^j3Bt0sH<(3-3MC*lS43SAX}!An^df#HzLf(7q7$Daa6XLwN;X8Qi* z3IRr>UrauZuZT07Q_ZwYrN+AQh8u>O$%3=OWiocq33Pd|k&f<5vI`DK* z);2ummfDe3AzxhT(5-Zc>$TN*PEL>iqrFE32DzxzVduNf(W~BJ>+H1iU9a2ue_m~= ze?GWXVZUVQB^9&N)s|QY)m~K^H?YepwT|wD*>4CtAiX?V)=$FRwKSUu&dt<|*%*Y$ za!9{22-6}RsuOO%oYYDrx6Dt4;O9axdSaesrK&N%0O(UcB?xQ$iIb(^K1)p`mpRg0 zD$GATNdnchHWf;}s@`MoSJiIjI**UBBE}HKs1XOt0CXu7hQkrRnPGs^3^U3ALCza} zW=4*il_)9p&tNl@e4=CcU|Twf=Z_l%9wdD{OTb)k%>&+=N?B|ec1PF@KmGm7))(PL zlvKOrpCpSidU8A`GreX~<`b^BHPMCIQb0l|~>R5sn!w z8rc$^>$3Z>KE$uG{u96c6ThA~V!==D`$6z?7HJ?=(N2JAfPS)-x4hl`A=;s8>^Tp0 z^8R-I@bix=nm-CNI>@DZ2%bL=8cyM`(W6KDD=c|GFVSgF6b1T~Yt38rCa`_}@yYRKAb@{jK7E!{EE&_50o9 z>AT?NWHG)Vx|E0m{*SmnE*|!$gW%i#Xm}qAd>;yY9}0XQ3Va_5d}pD+tAlaz*G;2= zmj&)Voy{+RIoW;x+uxQ+*_}ofJkDNzY;t>1KnLeIJ)oQ}>%bYYb($7jyhELrdRYFp$qB6$V zt-j|N8lOM&Cj9l+LB>lMnrCN`oQPXrHYCpPfriwL;!BgbdKF0BRD-?Y1%JJs#vfc* zGjx!_#$TS6^1=TNO2J>~y+@&i$!7uN*)ubXohZHHVQR(2&}i;(#dNFvftUO!yv3ra zj`AOM%`4917NEG#zVy4x|8zCFCPmAg$bFm1f7N=alC1v~h4Aye{P(NKf2s1nR~QTm z>;jekl{&!aA0PCCzroiT3TN@?b2FWct|e25Q%+blaSgms<7uh)F~+N5_Cupo;-bPR zL6u8|px7(~5&Q|^KUMr&2pWZ;Njz|3@PwXJf?9;0g8}>2UC4xkhi|8zD@jSS#ra@Gbm{Bl8;S zW}piGCklBG>>+{&FLzdL^u|C60TFXn=;96M-b8PI3HdNj~AsxwB%q&TE6G z1QuRhDF1=BG<$fzQjxhu4DkjJ1*=j(<8pDGI28i8E`&iKpos`nxSpsg3!n!4P7_Bd zH+8onT^Vf#Otr$(uF4)2D`lE`wN4WvknnuMinOA63%Ci=w8BV+lUXqO)OA?w28W1h zGIRKaex>#$>a3!>Q=xY%q5h0L=*zg-P5Q`)R+sj)QP3K|BFG%-`fxi1_sfJB0wV@ZRWKtMhQ>hJ$-N5`q%jR9qMo=>!lq@!r*C-)PGl zyt+zVMwNGH6*#3D!MD!mwrWU9jlrUU8RIVDhZ7u-8t&D%G9=K_XQ_am-iSW zao7fJGkmS`#xQuQg0vMSu;xGVTF4{-!Cfyg-4$XH3E?5+Cpu8$K58`IDsO{=n>N2G z@Q!4eby}rh0Ua|$PKG!l3Xw0RUKMVL)5TXKv%E6B$fNMe<-ig7!=EeWrr>!9RhBKN zD@CXo(#0DT8Gux|k0wu<=R>cTOG22MdaOf3%;eD0BxxoU+0?phS>2FHzCv+TO+Ir> z>}veULyx-7jOYa-eu;oVQxYVPl(N%7XmBezA0gkfbkuOdkk?&8LPL(4O!A7j?vjjJGPhPy4?1r=0f(;tP?r#fmS-vImMLtAgCa$xAb9qvyBbq1g4W=Rm-5@&j zh&~m$+!_UCxez=!2yP1B1r2lP^(t%d=@6oVi!>0bD{x9O3c;IsgNDPEAWYzgnr>UQ ztnY_4b14&ON<#5znYB;|t`Z1yQ85>Qa77|f(v^hHn1oe?+cYd81Ctv818p6VZYJ0v z6L`FE!>T!Q*cYJ)e5PsBr0A4Jc8eonPs)0xl(d>x=v)ZbY0h`m5WkSG#S*rmo#)v_ z4f$xl^V>vVGEkhJ#`M+j7!1NtI;FIetA*V2 zVSn~RIWht+;UNo}%)wQK;)FGGJ%>Vt5EgXjN6J}5p{0jLxKS}UQqGX1ppv~ZNVr8P z@iuuvVN_bXh|oytQMptxD~W`n<3(TBOTDiB8c|$iLzUWyMJV$rlMO^B1aXY{1G$f? zBpM0_QI>7sQ^7Z7LokC@T@lJyRw0vkRJ@vuBt*9v4aag7ZbVr)@Vd4t>jC9UPe4}n zxFeagey!FFGa?%j8Aes^m}1S563d2n6`D^1JV}K$9;&WLS*shGUoXiv)~$G_B4tJR zGvy)?A~iVR zi9=K>ip+Jxe27#eJII%4%?Ki8d0ALIe_j@ z!!ksCo%2;}6faB@SVP3`;ZIGKNrjs$3wPP97`Cv?^Qoy~sZw)9(X#TpCBClsDJ@y` zHOeVljhIob@adw-Rz%FG$%_@EVJS1)&zc$G^Odj&mJuL~G{=}MDyt@gnzps7XR=~W zUc)GCMW4ej~V7v|C5sR! z0-mZ+MAS9Mz)-4?1yGs*foZmP&UU})r*vhd3F25UGOW%vNqEkzY682K>5mZoZ! z%R)@#0t(AUv8-Z1sMk$7Ayq1a+%VY3%~U)yzfrQ&E((2R&O&fjNN`h`w7O7N z5dlOIX~-s1Nzq7z<_e&9r1*2V1Wmu@UAE}C~R`{;+871b7=`wdM z8^St3)$@f$Mq_5ck(Wcm$*|@?Zd@^z7}`NURwBb`8jV%WfhJ2ld>ho2@Z%9+6@sgP zC4$CiFLztrP&mu(l=WzrmDogTmTI^P20BH2x6n<{?81*$mv7^#hmFL%A(Xz3MulQ2|Oeyvu;fYT(cfTdM*`6($N zH3)Mto(L(2TKW;TtYmrfh9xhoB2!Xd7JZ9Vf{IxpRJ9qibLLX6u;@_tomL$bf5DYh+D?_p-4A3J2Y6I^0`Tv{X!RLZNsJCdZJ(XOi^`&4#Gxn9;1-E4QpH zN@N&rtIbrkwWzWymWHySBeI5uNXe!^y&}iju}7616@ASx+!f0-i*~x)6c*7KRHzLhN2h`D?;^}j2DKkusvT?MJyae zR?Qo+BxM+RYX@`e?}AAcd%#4s5E-e0jtJl9%t;t)p;gE8|YR!wrW>Qi+ za8<75NGZ2kq>cTBR8wU(ne*%kG7XDWq61cnt_Q2e{sTl@jK)KyA>4IZZ8fq2NJZFk z+IYFbOU6jb`a?D4i}F&bW#}sD#fVX`&Ki+gD)|)@OR6H=*Yq-ul*d*ZABjEYn1sSE z8C8_rQ}}~wV#{(_H}xo#4gEFzb0pYrbjD>%%8Q~rs4D7`$R^RkCXueDrdHMVh{n`d8JSAgMCPw3uNjd}oDfRLQbidUdnRjD#}ZJH!z`yo zFf$SbfStMEa8VV@Rbyf@5RcR^Borx;C1|}Vg|J4(<$+|iCa+OdpdvLgf7Q^9VfrXO zQ*x%%zDk(MTW@TNkvTNXKvu-l+>7L z)aT|9mPLxFs#2iba3pBMy}Rx(O!~cxTXm44#2bbxj%)$NGy zrMg~W!jv{eViJZ$S4G@x$(~SNzwvc4$kDJHR93~WQk7cd`KMJKH>Xf_FQL+!s)%mN zEX%!AF?tBTnnSC!kV9G&M=4?+l>re!N5~y-cFiiY!pL$ERaNRbN&~Tx;F+ttK5TNS z;Yuq){N=7x&m^M;s;J9Y)Kn!-S#@e`qpKT%g*5?n<|~cIiI_{v3>!90*X4#HD_}wq zZnvo{0uLdx<6Tm%xM!86;tvoxPC_%1?R;3;(=2sl+l~HO(qEum*K+@zGwU^*? zC?+@|W|8sPiLAc0#-|zAUe;q9db~A>hpPD?s8(dG$Z<6a)t1F>wKer8DjAW`QPc?& z%Q{;=<5eTEiF<{h3azZd{J&z0DAg)TbQCQrRco86RRmj&*IZetaIIk!OOf^RGxVPr zDkbdlp0yL<^6)}1mM`W$DypYb3NK7yT{x$z6(7{%iH)uDP0fyV!!T8pl9!wMp=u4r z)&M0wB%$~LE1FiUFIkP%>}6JE88ff!TqJr%nxm)|%huVoZjhkZ6i2(F0Z(KtImRjx zsis|>b$G;P)f&DVGSPC?m~d3?kx4Zi-y7b(y4p@d(Y0EAZcUNc7}gBmAG#VpW9Ysa$S66t_&{Evx2J!xL3h8KA_6{3$Aq zr9fP+LcJT9HmC|TN;q?qyRWNMki|MoLsi((nhJkaz6#5Z-B@;xnN_hBuwZ6kT2_xu zX3ipUAC_(+Rjup7Dnf~BmZMh>&Z3c8Bjd7HrOVvvDb*q!sXdDbpzOLj;v1eaY{;Et zu9T{0kYyEIvDvV`@i_mwP{yiCQmRi3t-GUBd*9ydVNy z$~B{5CNZO~CKxiBTjQ>Jy>O#26q8UjG8QzezE`J8Cb?#JBgeF^n!Ac~8Y>N}*{cW^ zXk_I>^{bNx>nvoI20$%~^l$C$9nNX6Zv zaG}+@DwfQZNa`|$S4q!TMg4n1)geVyF+4e2r!y@xH0(Xm46P$&nGFnq^6SbP)~)0w zQ53vwdL){zF(I@zZ`SHGGy(#5v*u_iL_gjTEfwF@HLHlLs_C~<_b>69L|!mMD{OKY z86Wqu?*>qoYs;F-jaI#CZOJtuRgrZLY3M@hCVauQSbNbdN|S2#^ts;jY+7-`Y9diT zniHt@x*Cb?>Y-F}P0_{`jh&QgP7qT`#Ukb6*@9cLVI^qzvfgDHaKM;bwU)iADsroO z@G2q>k=QNPGa?1X?V@UekwkoPouXM96Gj9dG?Xkvio)hS8-E=;3{E6W8^DI0Htq8kFiZV)1YMI8CTe`~DXGchM6 zznK zsQi@bOw|Xk>^e||VlNcqA5TcGFXj@Bavn^7n3P_buOpNLo#KCAy!+wfa1}~0-e@Z4Mp=1@tNCTRxZxMTx@l2^YZUqgI z)~d>2)~weK&#NLKwAHF8c#RJ?2abm3dW7(S(hg6!I*^`j0aUC^2=4kHtn*6U>IdWXn3*6@Pj2|G!qqE zk`Ku}nqNs;#Ma}VVGRl;?iBv1eEn8O) zRqIlz{t{)Qpe@%6#=fPjPqm`zdbQ|iK!qC7%t;C5a;PeUQ8j2$E+G2$06onMG4QsTuBd3sKg=^rw$XF5=O=`mMn+jr>ucZkrUHZQ|A(<)5e{r z(QxkPf@6m%3#m8iLF1h$)TbsFxnWOSzt6g=+$i3|`nXk%XNTGnD|&I))lyVdJD~c3 zH6?zF{W_zPRrj-ssBUx*k+GbqBPHdwY!+4h&n$|BJvUSnT({DJaT~2j zh^HE2D&p6n8&()g>ZMNuYJxs>sD& zZdfZtS?-sH<5M3>*jCXf&V>ICD~`Rp*i?@hsN5lprXtLlQ zI-1$4ak3PkRmB;m>F9!0%T24P>WW>;m)cKO{to&d&B1yYsOk&(tMcEk}6;J#_oknq@{SyhAIdRy}$6((8ZbU042 zVjQQ`^lbcRg<6&V4d9|)AvvKz{ z-Z)K1;^c@a#omU7YFp>vin`Aua0(Fgb2SgsQqZ71-C^q!kj$R$ZQq1Dx^BY1m{# z;)^Ys2=+RtI1x^?0S(tFDy-Wx9Puz^jVh=ZOE(8unFJulftS#+BpxVY_EwFZIFr;Q z-hcyK%7zauIgaeQ0ZolIFB@BlvEbPRFOjwEgogSF6JKr^y`A#CHd-cBkk&+XBRntp zT9xb@w6hw>9cYx6TmyB>e3XrpDdw1(3VBY9mc(`%*J!q>MrA(<6A2>5y*M(uaT`Rd zEM`^0it2(v0?p9eU?JgEQ%-(W)FovN?5w*sVez9RDx+Rkk(KvUnPZrK@n~nzB-Lj7oNAl zO1*N!=p7A9Yi{SV7G#Y^q=- zx({-6m8>(4Q@A+y*`N|lwO1ACh}D7(@&Q*ik@A`}JvSP0-mO}PlS;!dno5F0HH+8m zyo)A+pr(Ny6-yeOq(J3{)m5nPR8%w04@OLi>W*VH=RUIm9L7##!<}jpGF7#)1QjL1 zO^;%P!ZwLKMV!2PUe%0VtQH#WjWPp~jTS2zql1!3Rhy~PLZ$4408(lK8w|l-<}9O@ z`TjEYa6x^Wu*&!e7sZ_>6o2W8MN{!B7SC@!vaZWhRJ8|`F;TNkXAb2Ltz^+@x{HLP<=sJc3v7r}@E zY_w`PHb1)JI0268s>Ootq(dpIA4o;{g<8R7sRR`(;viKtVHhS`M_4vGaJ|86hUKfd z`7p)LQAk#`#<5FPc7AU-nUv&qmx&fcOT+S!jgB=3u_>OoB$b334ZtV7rWOcQrx+nv zPj*qGqE%tmu+GnA>z>K_S7Nb*OiApX5pkSoDig9FiG8_d;%SXRp`wmwA$t@=8l0u_ zllo*7jCGd7U`Q8gHP6xDVAF{~Ylqs@jYkRX_P&+34MzglVC< zWy_8URCRZnYXd1sy=uL4%Fd594d60y@S5#T1+geHR^@8Lx>;Ezv(g5ha!vOov>7O> zD*mWUXuX#s$4RlKB+R&#Gz1!zvJ5ztnoY`LG7vhMa7xx0L9K;!j~VJ*ExT42 z*0e_ggpyTPq1d>A>7TM()oqq578yjsCLL5&9HBU!gW)!n?krLwCzncH3>9Qk zpdXqVCQu>Tr);JAFRRBwRQ5u!g=?rP!@w5b(0GYxa8D@gK-po+jHTH3#FCuK1&JIK zBrU5ESP!e@bPBBj&;&dfjZ#JJNNXV-8TX0+V?dn0igm6K160E#un|{Y<=z@qs{(WL zv(>^xqP==DJ0At}8kT_-BK8_W#RP%IW=Cn5)N!09Pi+9^q*QE9wz?$o3vDha{@66Z zQgtU4FsVv8Y$TG@X!Q-?MVM(3lVQ#cxy61wp2Y|FvZQR&SDgfI1?RhLfU#Fm_=VHo ztJ615Z=u&)nCLC^ddqU7F??E7Suy9x8zoAN68Uo$k231+zC^;mQ~ihjxIem?4QIbz z{RcRvl`7VMsFbUvS~;xLvHn98*6!;++}HoRum5*n|L=ES|8GeFz?a8wj`mwv{Z6Xn z-PiuRul={OI1ao%9LF%X*1`APPPe!Bz%SM}oM5d!w}?(32`r~=;94JHbRb>?XKDnyT`r3nuI)ezTF+%IGchWI{z%K!C zCY7+-jB3@gQ$~p2hEs?~sQ2>VxOLWRK~vKfaOSAnp~CeiZ2%~2Qdmkz0yKx_}%OK;GYTTv{52bljiJB38 z3~TVO!XHZ!aAowdRIb#j72AK&J}TN5i?(^uc3QMU73~Cyc3MR{S$F=GTD>OIYnGd} zCeNu^t3*7#QmxUfSE;%4QC}$9W<}eXGk<;LzvwjAP6O|wGXZB>$^LzyJK%MpW`@9d7VlkTqDt#*cTCg5z4PS%}&1WmZ7uw0Fr0w4QPU+_Qb3xW4hU-&iq zx660e>|mlrKNpsEuN+t^03G~sx6j!#=Oo!qU0kpeaHge`b?JjeN(a3itaUKa`RE)Q zrVnEbLYJR_w527^sZg-G{W}|FUv!(>U2%u9 z6L4vjOg61E;+sP6ydE&r7n6@aM3s_zU%&|PuTti9p^O{q$8w{pA8Y1gSTZk!)rx+M zO3j9Ttd}h`@c}GAaJf{8>iSwWtP3qH)xxU2P>&)ZHl;?nu9IrkN_GAimf%ixdk>>> zB$yDE8==fHteUxp^-@_IH|lliJt|e3vX!tI=3}K&kKEqz{+52CMy)Obl}pW%%)MNW zLPd#cwJGnGVN2y{1wP5Um2wo--QFv}AP6`rjk+$e3eb=i)k>wQPwQ2s2sN0yz`a(k zS7k-DTC?HxUN1%3xL&R`WIpwJSeAZZk~NudqY{~q^`^qB8JZQC)_gl5v(3#W#OnOwR72HJIJ79!P4Zv5Id!_+fEG-(fZtkyyvK0@ql z$j4e(a^W7?g+~ZK`3V06IROcDH==SmY?kF?qb_6wu&^v+CU_%!PzB1xztvzMX;G`2 ze(FFBWT1MZAqNWpT(9WOU#iuWH>uUi?yi;r;RPehrADnPA4515av4OWMp)Bpt69-2 z0!~C-J~kDKGlmG&G))sYhD$Dg+Q??R_UR0Of8_k+>2tX4m6{q(K zoZc!g91yF~;NF1=FGun;3hRxsd~8HQQ!C|4UGTk90b&x$$9lc&(ivDwB)C@rVk7{B z`y>*&2fZ}PGG+rPj=a#QHA8vYEbIJeQ{7#Kqg}1YZy`XwAs?GHA@^0-?3z3UXp|!P z2r!ZtDpf_FYBh>#E@a?T)aACU)}SYbLA4G9xF#PP02}_;fHlcXnsA0?Ot>p$ezj7$ zS#==;=wBAdz#QwcX*HObY+5Y>JmFc^VBaJ8SiwUi9~+U}DF}v=O9^TKY;6G)t|Yw! zl2>KSdK0Jue{8^EmZ!~72~n*H`^z8U+?Q)^@AXnsFVuQijpVS@@d#JsW34Gfy$&=< zNHlD<5;QnfaD(&5BgP+6eL4Lstu z_a=~MURMLImPRNafl_nt4Iq+o3pIf3%0P_>4s%65Hfz#*18}qE(nuh`6``LEI2W>& zjY^{--~bX?6(ZHB!o4fQ*P>cO-UXUelcxY&?_LE`*VOp{*_G8cU?ib44ZH9L3egSu zSgXlQn!q(g`Z0ksO(4$F4;;Rd;CmD1Aa{8ah^2mv;9jrD$C~a&6K+nK6e39I!o69p zMU{s920-FnZ6bM)e&CpE<4U67(HgXFA3tJJQ zjv#32(`HHEg;krk|7M=!c^hy|Wjsqy6rq&}Eo8|AFRk zh)SkvU|{mjicb~#r!*uwg)5A4UK?^WBhx3_S5^Ci10El>4tm|cbxwLTbkH>OBMb0{ z{-_)Uv*GCH-ZY-|udYY&v&e05=_fr3Mx`ouU$2&pi@o^AzVVF4h5D(^) zY4Af31wRHG|J!-Ie(1?!UPuppjDL?8^XtVNmh}!~6&M=?m&r6YipP(m{JLq#(2kWn zHG!SsxRAAK{M#9OBg2@RuUm#jlv(y~I6irY}S z(;?~|*;+Frq(O_-a2)(+SR!i>2%Q2N_?8QPrjFpxQ<@}vdh{sBI|@s(=8ZqZQ#g7P z>P4FK^2)p}M9CfK<;N!v+?K7;sCeC<&4L+VF4}`&%pm>%PQUBLGoGDG!BnaE*S%>yu<#sp$)+}hvA zLAZN>wmX81XmLhI;iQ9R=%EGVB{{a zn6*MZ^pBpIZgz5(DCG5_hk&h%ivp5f!ou_Z;Ag}VAV^_NsKW#(gGC$%N#My3c$i^U zuUiK%VOlhR%=#C#L%r;L*WT})9Cwb+loAo48}!G)c^oXRvG)pIva?C>F%D+$hnI7- z^f!Vl8T+dLGf<~_a5I^J}(@)Qz2f1jc+j-UNzV5s{gY(jWxrpfon@r>RVmc0T zmZs*V?UM(;WL?sDD_;#i^#Bm&uFmPh%f)!0ZxrP6`Y;(@1Uo(W?)0*A<9+S^PzEA` zB!9Lzznu23V*WO{yqv{z{yYffZ^VE1_|MCk+!)`sPWRh;2hK_g!Tjo)LGN-IgZ?O{ zhuHk5f9H?-OI;iR2#V%iK`z(&z=>d zye^wwfBY=iqvaSF4Wj48F!d6H5@~+!r)Q-nKRwkYJo)L-BYhjz_QOv@XBXzD6q!vh8~~1>GseWBe!Au1VSu9`SK@2CC#>%VMoh5OSaw+zWvGg zn>k`&1B;!|>npXTCrGNiLk#rpb z`MZ?2$M>||Jv%-%#K;nE_(O!6sO)?K@Ep!>dd4_191rKYGkM&Srz{ff(Ax#$f(x`y zX(=(r!}$caG2N@T0svP$&(ZVzs+ID4tCnik#xodC#>MQV4c^1gJ8<<)@zm$=>rVb_ zSqzD?owM(I#xn%=rhSGxb9#nLzY55=?1TJ5`d z4qJ6OS+k}3v;(iAn0Ptqk(i1X9`G4*Vd6J9jOHpFET+>Qh^RmJ-^cw6CZl9(Gs9o? zKV?1ce|Tp)F%Jim#dvNW51%+AmYhzmr;~Hjf%C{VcOG7$#LJ(&nSAJ9^zgA6sSe0)Cy)Xilzd;YB9U0|7A7oP=< zCmAomavnXhv%E{e}m3q-}pI2cXv)Z+|bj}Rh(c#eY5H9@INF9o*j z2Gc(IK+fOy*%kD1IGq`u7bl0>jpvrwJg%04ufL|v{d0QbJh0f6N>}jUS=QS4-Df2q zDuh2vhTs;(;uGg(iw%r<&OpWRiC`oKG$=w@2EiU;B}Dk-2Y3+}=P++Z`Ln)Qd=9t! z@FH(H7`QH;7&MdPte7pwm}F~huRr*W=wKrA_C$8{z}dku1}?y*Jsp}Yrfd0n2r|^D zKYbU^oRbKb^8$VZv4;*6Ui5vOCP_zw$<=i{ zo*_|G*5e``^>4)8mfyRG=cE?YL5Wuw!X^)&mY)oTNw_7dSS`~=sDev|gY&a@9PJ(* zw!Q;V(tTJ6l4!82Kj%}O;LbjJw!B5E0d2CgT!RyK@16x6m{l(0r;MqY-^|?n4VGi_ zizUkDnotZQF&uYqcttxri-|Grk8gtaeZVrH78gJz>;w(HK*}2f&JsRm>~-R1$k=$9 zp0kxtgHme0)2I1%dwC~tfoJM^)P63=rec`-^D)H{lhaT!>|2|t>_5KMb?3e%g=g-CP zm*7KhxRbl?4S~-+Q(%0Ai#=8_!cTDNlYj?n_<$&i+uA=L61wJKpYwL$q1w={Z99uJ z+Q_~xZ=dPA?pyQsAU(XFjQAEYtCS{P(IIBW{3!rnsp9g~>7ajo4WhN~Fl^Dqa0>SpJiCYoK=crbVvo&{Nqzh+=12OLf^xdsZ`A2|!Wo)8B=1BvM)V~?`5fRIRZ@g#cVK$Y}p-P`$sTF4hAX0fcYRF zJYMp0prgD6P@$@o@QWyp!mU4;0waRz2_%3++J4}<7BK}g{T$?2jY|#tpN3b9E9tU- zMLZO|WGR#YB#$j{NwA`o+ax%o$DDC|ma&7peY=WSNLogH;KBeIuDJyx%Q%iNm~-My zH9HEwee9EDr#<#bC$lR(z9bUEouCSb4)BL~+J9%%Jn3^e`4BT%A^^d# zixF)QZZ5nw(?f)9C)dzK!o_C1ww@JFU93!RpgmPeYVDoD3z3b5(+yN(azPXt8xnyw z+xRwSEgb;x6Hp$Q6QQ8teQ~Ak%z%sJi4F0r#My+7ZUWvb+-w=qnuK+cth#+-9}$mQ zl1D0x2R_63fmjoz>^%n=Y)2|v0ACW;a=U1O)ZX&;EtXTV-q~>nyrKau5L}Tt^q2wB zFicP(dhx{J5PXLJY6ZuCmBI2~ZOQk2NR9Ym#fTp=M*Ohlh_dAEcFISD!_E%=~5Gwq5Lp=JNA^M;EAsFQzdHAI5y%$A>%6M%()+IP_ z`z!L!()r_r+A9U)j2Dw|O95>~8wG?rj%`Dv3{G^qUpp6)Lc?7Z2@LPg3jAdfzy+F3 zK~6(WfSNJ;$jKl_gbdA$nAD}L{L>&TWu0Eu4XR!cC(Vn}<=Drx4o{1imO3556DcLM ze~j%!;<)Zx1(YvKb^t!AEF*AJzPf7ONR__L!ILeQikGV;OuJOs8-heiD6~kI_gcEx zlC4+BX!(nU(TgEU-|za!UOLwsMld@Zu>-AZ7uf*C3jCxPz@ggl$-Of{T3X0&!;?o# z-d1FOgyzTH%ObwzBT#-PC*v)rIcr+O8^y#aT6)5J8CaP8UIH!UNL>SWJ-^I7{6Ck0 z^S{539~LrH;)Njdz$=&vnIq?);NJX_8Duk?U-T~H{(LcwIWtSsbs4Pg)*6*2`Q?^( zEA?tb9^T<@y`s*~id#wYE zLOz7Mt4oOXIG3|lxP18ZX)dfjvZnKVKGC*))IQCDtdPrjeeHPP099jbNmlnI?c=-~ z#+!tcAOuT)y^G7n6EoHl@MAHz(<1~ohHUBuV( z_l_k>x-~3~>#;%hQe`uZ+ri<%Ne?)I&XI(gTW1XGP2e@fuxtF-KcB(uX|8sjJ32+V z&g^`0ZYMASKJhuU%;n8WT$`*kMf;r({Y)q(=2389W#N?3bhCzLe`PbXt*2}3iM-K! z?Sr#J%+0aGfP{~}kIyG#Vcghz$4s;kWcd)e&Y;6Wz}%FKsiE~fcGlea89wvx>K0+% z7+llT@~eIZswltXU`N3-_P;uco<$Ym3797CuvG>v@{|IhW!dNc_?+!hdw%8BN}`m;ChN<=);84eya$ z6|*0rs{fpj)VDV9FL0)MS-(Es5gYTz-fVFNtd)A+I{ledxmY3G;IM)Rm%ik4n7Uxc z|BnZV*$71XXQlLvXPk?rKTXVf8lyV)L)=a`!5bA5n7P07N7wKB1^(04zfrpFXtKDl z>#>`}#)+%`>}QLhKo9UieBt@?+uuz)e_a6Ywv`(B8NxB{k#o9jZ~Qa(QQD)x?ZJ2q z1}W!&hyruHDGV>#3A~wI$AcbwV3VBb&zbNP5HZSFs$eO|wEcImhUw&L?Mw5?@>ekZ z8uCX!0C(CuYQH%>KJtb%9e+i1wZWLU+cq|5gIoonB{3$M*qvMpoBK%WmmUsJb zfa~}nx!!#iw(NgPrfTt`?2}IMBkDS%O2Vg%95Ng~PHkhKIgWeY*a`nV8uVFE-Wl28 z2G^0Zyu%;$H#QIjc+(kn25wH?}re3^x$wF+Rw|s`1X~8;nq_^{dj^W!bZlPr!(Sf)>&F4Puc;{sJ zV?NPrxJk34=ux8OQE^xdHyo7T&1$~c;E#?Xw+F^sVo48=zilTF!2R|peY7JkC?L|3 zlYJb#qw3XyPFOFFAbW9zZD4gDmA z0AOzp?>Q9bNMsI6FkTX2!&b#<{LPHKhK~A2sHHTjpMqe~iQpF6P~7KCzJq74g$^O*tEZMCE#ixP_~U z+jrr#5PTQmf5IVt8b0w~An_6e@t%J0Bu@Xe$h;TX7o)_Rz?{HIfd9ff{SWVuSutXadequaE4Qh(*hd0P4I6qXu0=@!V7-aH;cgqzv2xYtsgt0txS&{>EIFc z?Qf&mE;~NHWE2wm9&R7L5}7&5TBu`he@-3{ID zhNO9hu~dL4}IyAfO$$iEcbdpYkQ&N8lD@<9-nO$jjI8jY`FKKMiyhOxLX0+AbC z1bqI1U5Bd;bEbO|5R$}P`)L?AFZ03w{%_!L=+dtG68{mKg_btkRp(KLIWZ1yOq?^d(7KBIZjfbO~ZR7`Z~`|YGA zUIZ|f!b=xnG%SAUefucU<`;K~c1DSzR^8+d9Ft(ny6zo5$hM^_h>5k^DOv@%PVnh6 zK&|97mQT-FgTwrpwvU|Y8IYtwXt@zQHZoc?q$pyUv!;m%{9ZuxJrv)SAwp9OCqRfLj? zD%k<6m4cFc?9QJ*%gAe%%?tQ40B#i*c!I7|%kmJNMFg*bcds~vBR$B{o}KB_q>HN- zlJ2^g>bhv{sTp1U=;fPPCKvGzrGF}rgVdwlQWXQX_7$A8g5P&DUfK>#~wxRSc> zT=%e$YT+YE{z*bUUV<;dGT_Tu^vu;I^SbcGPrP^Llk^*K=lE`LPh9>ubot{);ZhD6 zN9ZxEp82kGJ2}Jd7WETa1s+!{3*jz7X)tV{{~Q`UvcnWyj>4f}&QhJj>OO^jip%;b z`k=^?7%ZkoPXO^jfG8Gk4H9653{Y+Xl1B-UBwB3)l}8Dvcr83Q5To0l&0?VK4r-vy z99Jnv{>f4)D-(;zW)7pDPbRbZ4?j{YO#gzCSD~c-aS{OkeKq5V8j{y><1qGQGIrKLfLxahc*kVl>m9ff7w@!yF5Ddo{APhfBgm7?~nCA$lZc>1n@m7cdF?T7?Q05sm#2_ykR;vLE0kEs!Wc zIe0?2EIuW`pyhx7=Q%ItZWZ{eS_MQ!dNZFs$$*j;T?r$X^j~`N;K6#9>z}S^?5CvZ zVmQXaTCD4G6st}?A=~9oOSm}7VfiGb7Ql|5dBP<1`ZGNH*->r$?DU%G*y=v7uAd}i zhpTH>I(kR^;Lo0%0?&TJXNi`y-ba+XXeZI{FA2fur$0X%CIlS|Fy_YPdx5&mV7!w) zUpTU~aW_8on$Hy{e|~H><*{WIxIf>M&WiJHkiFI1I$A=PjeKM zUn&@{2VgH0Z{1eF0H>Vn5}ss=4+$?a;|aH=?kj=K?W-p)veR*vA6EX?B!ilt#V!8W%0^t(xr#z?nV^1fL3yb1%XTsq09dGvS zE7PQ1NcQF#&-OI_m@^On+C1byqK9mHA38y~UXevDFKL$+=GneQF~iMLaPfknBfBA&QB6oeYkf2kWRC~K1n_!G4C$jrNFS3Cn?qM@X}%f zv6<-j9ON(s3~gxMQ}Y_nXjZ7gQOPBxH6HCb4HpFem(**)U*J#mGQX4Ma?P`OGs9TL z*^p8%bApbTE2Rcu868?*^rt_|rgPACa>sWQWYfEl_a>hV!K?|n(CXjWbd zztUYml*pw!1YM5?g|(7TaWY?7MrxwcuSRJw^=oM(Li3A3;p84XPhRbLU&u1g4H_oi zf1DYi;3^T9brd@J^7$|$*_jnICoJW^QN9p!SmS}FTpP11ysWLHF2rT%Wbz|m8=4qX z7mN9B(4FXR5LxrLq+ltURx!mq*e(f3LLct2jG!57hA{6JpG6iliLRap)RBGg^jTo~ z@`tefg;|3Xv*Q?^K8w;XJII=Hm554?B`z%G{1<$$(>73u!O!G_?wNG-c@fLnT^52> zeW0adkG69Mqon1?JFfYO89q%8UM!dL57OqIJx#>G9i}Dt#!?3$ju6Z6Yzb?gOADpY zCVjdsGdlzd@#y@=our+KqT9$3Xr|8jzx=v0LThW%-1KOfy^VsZlG9!0B=p$9*(V8~ zob+!g3=Qr6xxPHRswGJpuKh02k`iY7JEbh%h+m0^`5hJM}{z@a?IFBp#pF9fl|Hmr2+$P!}mGa_I=tPI?9ltp`>%rRdSyNiJ6z7on4pJt< zlyDuZi$+**b|)w2^^x_j|6%wjs-RAjs?>!|=QweIhW~C@lXq*)TC;q)S$#8m z^ z2}m*55+$JfFcY0urgOBLl*~Y%L+@=6JjpU{sx9}m(vM~;$rL-3T*rU6kQkzn>YjW9 zmLw)|&qY-A4u&)K!-7jB1jzb3%*k>p&iXvnnSM^Q4l7=B)_)QFp9@-iqHldb5m-)g zVQ*_(|MblK48AX=h?EI0N-cOWU5wY}CehzFPETS2J27#}gN&MXPEqk>{+d)in{+x8 zua3r&{@0{CNmg!f%6ME(oLo5^iD*kI46b?<$NYfehEhvFmz|8qUxy}ZybBsknt$}> z;J{0=hDEUmifDlc+WqnI$7%n%*q>4c_f$2P#pNYPnMPBRH78*lb8b$vYJP{(_ZPBS zSl2pPZ}2R8vF0fzWRc$;h`9mwYu}W7kuu_QSBscYtR&~)q{TrG?|9X+O6fK`>^+Su zuG60^;Sm;Afxg_7ZUUWR;-_B{n~_>`Harc~m$xfE3*7gO?3pfGV&UVVwwuO?%bqZ$ zqlo-YxAo$n-Fta(+&b&EPCAHIfBM(_ha{vJ?v{7M$D-AGeCK0eh1hzvihsj;wdDTQ ze}4+G$az!(_Ne}+5|+FV{}fdJNPyIZ=-)r?{^O(F_je4MTBVY`|6#dS0o=g-FIP*Y zC@RDLM^RMzQ}Czz{r}?s$ozeM!&aT#ARk1fuvCQqgu!>i>-W3I(|5s3ym9*+#@YS( z24seV;ni>+lM4MUNFH;b{pUBqf5iQ9@vuJ~1m6M?=G-=ao4{}1PAGfH;~lCi7Nf(> zba=iXGc&#<{&KU)VmjdZZs$V~X(*k~6;N(6cTT2ipL@Vjv%|~bKxT!O`0IFjg;Tk} zjFcaSy25e=6$gxu)T7i;Cnzux%m(i zBvAD02%VFl57%Wt4EJ_IFydg;A6~`N-6gYt(HwB-EUr1!_e)GfY$aTsaj>{TOQ`PE zW2|gTN!qV4*lE}w%`Ci4igR}XysWd=oo>)QetGt`b=nT#^U3M)x1Ig=e(>UZ_^};e z28YwmtJi12>*Is{_Gve09qq%@qqEb_i#Ncrcd?uQ{_j>7T7UBm{n|SEK4^b;0vvre zI6ehF=j5ORJ;D&Dt)sI}y9>O}(cZzEeUOR@0rV0a9h0^509c|kc=PPIK!c}S2FEXh z!}jUkYxvrF(ZTX-G~~<9*%1!+^7xc$Tm~nt)3eUrn}gPAaPsE#>ac^ zhwc4cm;;O(w7+d1odw<3t%HNaf{))GwW&8)gS+71MH^;{tOyQAtKILM0_%#)vY++< zj4;UqIGiW#y$*c9zS`flVNtEq?+emxxBZ`Q;63;~*l!)SUcnl3Y3R71!ERui_THSf z4{`1QlJ1)q-LuZwo3nQC>iBq{z}{`2e%sk=cb^0Y$6W&4n{K-RgPgT+Z0Q962XDaZ zFWz)J1j5eIS^M<#%?T#e&cm+11qi`RThMx+V10ZnO{_;NHL$@R7L*UzcEzsY602C2OBGAO0;IEg+ z^Yg_^-_NH*km`@&0UUJ@Y$!<*If2;I2#o0iB&#NrkussYHmN`5EBq|x%7-K`&Vhi# zFb|W@xfT7QT7_P3a6MYg@c$3uPgu4*c)0fv%r!a=*OMs_u30dL5yz9!|md6En{L+X)bI214hg z5Fn+U03m0jz?R+>dB9H>Obf%M!WCpj@dMFqkt%K+;hO!oRJA(zqQeFbPMWZ>~BC1`& zixw|gK$X!j=&AvqcY?-kaQSI;{n6K6$TZ}QTJZDvWAb;eh9&xJ`deJXuFg66AG*nr z3I+>^n3d%AUYzC$G_1UZ<=WrAh2ONV7Hx-9FAj%x-~hv4E=Hpwdl00@cTm~DJo(Pm zWIU0o-UzkKR~93TYz!dFPgDV14tpp$Ry;qaT1#B*+ z-k6*N2SI8xs*{Hn@;Uzma2v$^5t5i7cXF_2M?uxOEzE=MoMhGs!XzhS-(wx5x;@s+ z;V%CQbd42QRCENx43a;n(??0o7VV$h9cRppkyi})%8Y~9nKgB^%TtvK@E4d<3LE{! zE(jaYC){NlJq)LTT*`N7Y66X52L|A$@Iedo%Ah@V&&j=fwTxacNLrD^vE@1c$8t}~6azdGQfH$8Q&tmG5Tpvx9ft=)W8xNVCQqJj06gGxGl zo^ukRTl~4Ax#dJdN6&GPWG7T_8om^QrO34msi+p*k}2gSs{)_hY5YHn;S``m%TQo@ z__P}wO(lWF7WEZ>vE>TB;hZMlKmT+>N^(TSj!K)g%`tYwzy{6FndoKCeC9H zbK~0N!?{I~v*aX*OpHGEZ-|(~$zNb{KDdbmO(@+g`m_Trd5`e@$hrJ5qs;<+ZHHXp zYlo{k;V*C%#Jlfyv4_F+O^)2Cd30vMjO#ijr=um2zn*C5WqN>)vzQ!dk>pV|s`p9c zo{w^Q#VlY``U8Mz%Q)Vf=KT@6IAbZg%Rbi3l3=wd+!j|?=mmelsqqM)@XL+Bk-DbE zpT{!O3oc|gj*)PJgw0;ZR~W#CozcA|qaqQ&UDLv3vQ%Ph(nlt>FhWq`$gy(wiw=k@ zXYCyDAjpE`1wq%e!YT^~?e9RA$e|^46n{c*qRrZNJFkvf2RUR-`y-M8@+(h;T~mMh zE|7T!L(xXS^>U3U$H|m)z>DSW%XV&jY0+jda}pxtFbOoDyin`Mp;tS@Tw5Zd0-Gnl zQzf?9+>YU_1K){`Z3wm^0ca)KOr1pzI;_w6wVss&Ufxla#4BHgohZXBnX696b* z-1e7u=vX=&&@WsGn5R!HH|txj`$*9Nmo;GwUsh|p3LACC~}`auSM73 z>0ddNS@< zs)5Xc9G(}soD#hW2QEFG-=G)sbPA*f&Wclg5s(WcDdbLg1;F94>ecVf0?d>s@qmsKg>1btyCH_RBZk zEQn-o&}KvlrRP**)$Yc{B%TqdHHzgtRz(S^y>t6#-{mbSI3A03IKd!XB9k$i08N=n zm^-qIMhXBjJDuDJ4On-x$=i6AmmSZJ#|FUlITKfXp)zS+F7MT{&E$Uz%%afUJ)x>! zaP$a6g-z>Y5FOt+*T9vHk>wqsrYDY-_YjVV>xlMIVKFA0psp=jOu8yGjld(WT^tkb z%3Ch*6PAjmf2 zEHQRza*a0(?+iwiWI(f!+5w(E-mRzvgdJWC<{nq?e15{qd=*Rj1R{z&_ow*6bLZWs zkLii@2+XlejIO>PhT|U%_Z~c*&z}Qre)<^x{v|jv$5&slMHnATks=*)Xkx#qJ$RDuD`Kp+}^T zEmDDM(zejsLyTP%368Y3Bea_W{=wa`7*I7CnV%&h*ls}DAeJDBJx7};+@c>bO59QD zAU}ygrPL$7=;$~p_6W4SmfP#0r~k+XrxSON9N=RwfHk)8=D8lsJA)=o_2ac$qO`jfVa_j*oBQYaGJ#< zpt{IF&eaU&AUau=xO}@LDZ4^BkvlK!akLz>$SX#v-X^f*kBe(O;9A6T?~L zBn*i|n)NS9B_-N0#CJ9?sjZ4O7JJ5(jpDh-rs@&$H0-+%Hf0Pv6=)U*Ys*Xc?z>*$ zO7q0klbeS-w2Kdfy9hci8)52lpr+5TvT61AndO5?tuAr}++1^WFgZ!tY;M^*W}VpR zx zTa@R%Pzqa$`m-|?N*$h+sQ`cmPnxsmdg9t?d&93vVDFm3W{}t~Kx1!5WV7k(64JUM zRTVh_#B{-htKQM^5&F{S zLZu8m!pw-1*35J#XpH{*E*^(9ZP)SemX!KHNj@MA$9fb-KH5d?;5)brhO?~dxI6f5 za+$LOCj+C4CMv5#>h!jR8sf9+R)tWV=GR>$|*t|EqkfTPUw8e5xK>kE1P}W6P z8EdjJZQfUi>g*r~(>FL{0F)UqCv^e}iM5=yedbXVrr#A3y>MYUUswV}sK(3FHg%#U9I1wMGnvET8(jOy zaz=v#6&*9!j)_uC#2?Z#kDdfOcp6g-i+@bBxsvp=DC1dWCHKNK^wRfAQ>EG+^EEVz z&(ff0qnZn^`tw!1jRY_B;ap5H;h*sVee}2(?k2CeuG}}$hF?C9Z_vul4d{-Yv8NzP zU{W#A?*&rA0I{y&goAD1 zZrVFLFh2icHB7m7&}3hsS0S0g)$JH?0&S&@)HGk806k5SoFF7I_qKBDTad+YV z8B)~PRevy@c%*ehj@WCXGhvGh8h%G3r^349y=a}5r}6cuKal+yXVL&UU#a<$pJ}$Q zWj524>9LtK7dYKy8xr)FH5y!WuT7pRdP|^G2zGaOm#Aa`FaG+=k{}b|)EPDQSx|C%xCyZ`uVotOZ zGT~4JmWzu^ad62DHVHBDw(hqIG4b)|*9CfI*_Kn<-j5qai zpLH*Flshc#yn3hur&y3lUa-G9gSxbmB$@NO)cadREtMA&{@>n%mPY#~|4^pN`zzsc9`VDP& zgM*3j|1=zlVMJ-6sZeKNPsO`i-O9~ORC&7q2(yRGlqU6$csfxTQAsuBDflZpdmU6=P_aXx=ag>U@exYsljth}X~% zVqk~QUZ1vG``y;dcJHLyezSi}*%)ObF%QMXZk8jxe;aP?NH5Lr%#q$_j|wRkVW}hi zzQgFt=Zzfc<=vHz^ud?$r2n;C=~G-%hAaIl5Be+|+1TqUW|6>3N@(19{g3?S8qLn`fCIPzrxxJ z>Pmt~VZ@iS-Qe})V+_|+!K2Z5Qe$N-M{4gPF^BF+zOrDH25tiG0K2Y76?O-uq95c1 zj$zAK7ii)+SwsI4;KuYxRzb`Q-U~B}IkZvgl%0;*!w9bNH@q-YISaeEB*npaaKjcd z6Og4^7bBjN^S?N$Q#Yi(3=W1r#~+8Y*ar-;7}u2S1SQHL2QZ=UJBQ0s9uiTfxE4%t zkVONiK(L?-W{`X{)0u5?!aWf!OS;_7`)zyo*UZa9Z;36uUDI;hm-2Sq@T$>?{90bF zvWrR{_CJH*8ZC?^x$x;mwsFzSAD&Ng%^UFko%FIS;3QLglJ3j|5EGnPx& zV99t zbzSY{fXw5E{%}MWzzkqSjM?A&xEMKI9Z?uj>1Qol>Bfv}=&=gzIXF^RvnN5dUMmrO zt2EF&E_o)6g~M9Q#V+XFL*_1{>sBPST`cp(7Yyq^PY(8i9HPdvXOtNnkH*V3J`*`U z9y|*r4wxlv2QC=oG!s3iW-&-c=}V$H3K*HG>{eiD6|Yk3A!21g8%8BUDTRr^wj0H& z(lAsj#GfdZadPDdh2(%iy* z2P`_L3Z}gYxzhBapDqH?cdUVbViKEUZ69&qn>F!G#VH;)0$@TKKyer~dM1m*pyAfg zG|{Ff&d7}SWFL@|3T!Qpp~d@%o7m*Qwo?VIDNQSK(=3TM2R_26`L9>iO*lP`o6Qvh z%#6syjdwYBQHQ1BzQ-2aIclG{pSz&4w6Bw$W%94ZAFk8?d|y#H&Lthvojj0x)8~li zFTZ=Ytc`5%sA;Yn=^e~~Ob%yCmB44hJ{mfIs(^mvw zJ8+|ofot?^u!zA*nd(tzYdA%6xRAU3Qp<#&+-H$c9wzyKA)vblS230p64G<7E83C# z8Znx4rKm#o#mK1VGl#D!)=Am*`+hh|5HR1U-{;Z#(}rBV-SnC__Y$|3r=b4r-h^rQ zMdD7oxxv1vk-hxX^BP)tfADq{m^S~$3k~0JPN7G`hQgXIFR|y1aylNFQS9TQ7Eqlv z8Lu$S^Jvf-2S0-h6cv5WHj=ZqqP^L+oS$*;||6*H>ENl|^i z&Edi7Jhy(E%k1*A(n}=$ywFWx@)Y_RcuRqw8HF_veN^Mdz#da}(~^O_`GLQp4HW(; zig}QPV(8qV)=r4kp0lqP6XZsOq&ai+(AaA?(YhQW#82mYKe^0C=j~q&g2#SU@IG%_ z{toHNy3id&*7~|#DOBuQ`{r~%-Dx%CXKlo^J&gpaz{aoB$owy9TPrNr$mCBK?|;L` zJXvR1cow@%!TXIfNfI8ko&dcR1j&b?vn;z-z3vIKWb0B~i`BwfRutzXTh`%rPV&x2aF9ttwA`CYKbdib zAE5%FrfNy$+BjCvZdP+m%7pbJL z6&n>&R<%CR6IvMEA`*R+jS@>`;9g;I>cI|xKTgLRz$z|}>J(&32~hRBxzrlOI@c%D zW;%dK2ZM-XvHdN2`Uahp8HT})NT>?V$#AS<22xwh96i&IY#-gn-Ok<$Jsc0%eB6On z#d`dc!8tZ`(RLpHo?wJMc+j$>*AH>6`!&t3!liwI+RQ~6vUf9|Ra(`zQe)2_-nk`Z;W%2te+ z;&;>A67+lmaKXQK-GA9MeL!LEL>Lz1AaKaGNSMe=d`8)6k1 zsq%SyQ5+t*jr_C6S8*26 z#_n9g?==?5h5rd!i88YZ65bUWB^Q(Ip4iYY2 z;<*`xr|PH?;3S|f!s)HL)LU>PTEd+kx4G0!|G*F79nV;Ul=3F+tRu(EQx}rW4q_i~ zif};T%*`2BPDx1j7Uz`%6?M-efCeD4rhU(=o>~gLyIi{R?UZT;A^cNAr!@M!#4PU*&GNDNA3Q`WNpv3TkcP=dyy7wJ%ela&2A{yh$|szDp;M?Jg^#$G~boV1PK?1qN9u1;7BGa zfMPL~7?~(Qo58XbX~YA-u`-6gZH~*^)j{>D?{Oi=G>E`Imh{ZyepJ?zU#VbOTJw2+tW)Ex$0_{gst=J ze3}H6?O?Lau&Y}6^!ChRq-P`B)Yd6ZRTU*;88j#?GWrUZg88olv&%p+EjNmk1n>Q= z*dcqQYnrLy1P>J9@murPj8YRu(}A|;d(=?_eR1n|tbRS#v65;P63lF+Q#FmpyW zXfC_4U+D2l*)Z92Zu*y00nnK?z>5;%Zo!!|U>symD9MU#UZQqGZ!-?mhodIa5lM7h zrQ$X>a7jmHfDWj0qs|8&*vp5t6+a%H;8qjTp~bxqCj(1-ERJgTJcC)1hD9wv=P_V*27=gQ=qHYwpouD2$$ z>dQ$!Sl)E^r#b-w>l{xWLTy{0rIT|}tt~ZJ^I$;(rgi>oh*3FQa-HR08;RA{DjTZx{qM zzLZ;{|3sSAHjfg{bA!!7qnbYsZK;E<22U4ev2JQeFaAOT5JCZ`5xLgY8s&Im%3ady zAXud4^D^_ubp0W=!t0pllK;56Tw%6851cN};dSFu5{)I4nEKVIi_qKSWrgMIR}M!? zafs0|C)pts2PKS$T31sv43stWowF_g@r7_$0?(*LRdWM*4762>h@_??;Do5ru4?t= zOf@|7M(c56=1p&bxeybRe?lM8WJXAU)Y^jmRdOqrapNIHjh zWhoi<_w8_>ALt~-P4ZVt3? zTniY>in%Kq680YVF@ZLq$pT&a+AQWGr|YAz`?DX3X4QNeC9G5+lstaQ#zV_hx!#gk zbs^0G6mzb6CF^?BDwGcO;kFd5j^KE4%vOBkLt0C)J?!{U^KfoRC%1+TMA=1K)m@%K zJ*+$3guZ)x3rLA(}k8=5C~8lD5&2AupxCwwn?j2x7uLAlpDjL`h+ek( z8vvV>j7J3_-$W4h+rwunOIV?Ou#%PGw-O^$zs)>ERcq@)4AY*X*fyqI@^fOgOFr%_wl_aB zR*X%3I~|&d$scgTCANT*+Bpe$FM4{jtH%e{YR>$c|;XI-;Xa2KQ#Mj zVv?o2w@j^ zG0T4VV}ueHg^GwQ^~mMz2iBZLI{n<`@$Wa)jG9tp|Tb_<5tAxAEwTkb^ zpi+LNYW2Rc`R+iCOsRjAM=;)$0-!6&bs}+TmELzs!-XCP7pE0$&$DYTWRj%=%Br%s zw9E3WD_J#e-lGw;?7)C|Nr+0d&T(iew!EOGLeDzG@#_Ie^Xcy<^u+DJjAhMX@3vAZ zLXft4d$@EqV!nk)l3wI=^!_400hs zkGVxH?`Ebc9)&MR-LZ2noShRZtOHt;`awmuORUu!rH{uWTOEP^i_JDO7o1h(>(_H1 zo@7U8<~OX!67gskKaBl$BK6K+rQ2_oDj9cA2NTKid2FmO?Qc7U8vMI#i62XzNjmeY z7TEb;}rXeQ$j3jO!QbfIIE&e#uQ_fT^BB9c@Z69cmr0 z&8T^78$BtDwWoWA9=hvN0EPKT5l|II%)k72gJTp#MPJb!n_C3IcEH9X)V{SoxVV*i z2H>lG&K(Z7NJjpCxvQsJ9(?V+w4YuQopfT_gzk*fgUY9(cdFjLXYA_S8H-7tc9bYR zv(?m|mvac3O-fyt|Na_jUaEFsp8&ea|}eCG+k6 zjifnf+uVV}i{Aci;7=$*GU>d%J&H;8qEfDSW20J~ywUx_NUc=n12cYTt{7onB>yN= zRHI3y@{RhD2Q(T%mDcSO>*KrK+UZ&2;(7OJcD(qr7g@6X9{i^m?tdM;eC-lba_ygz zF!TynNO^x09~f;@&bL4@Hvt zUbv#p{yqfurXnvM((dP`uva2|gLjl^P{M7O3IZ+OONv~uW)Bs9=89L8a+X9>XQc-!m!-hiV^{Ls1oADGf) zxJ2vXsQbHpF=%PqQ>eQsx(jh<&i6eJ2R8>It3M$C;fEKJ-ZytF1d!M()mSiQ#W zqz0Rjuyynd-o$l8;4-;6TD9|okZFdC)`1AQobOz|X?)CgnBjQO4)$E-;Og7e#?R3g zt=uVea$j2YaG2qQm)^?E#&uZ-uCnc(-{dlNLRf!qXMn^6nEI^qa>BM%%aNSXzr0+^ zWw-~hw!k82H|P~tVnABqMk}{(b68zx?bcnC@BooW-sK`W%B*?dz4&@Hc3br4tCwtJ z6s}vp^KJKd+<4S%b6R%#vmVXO*a-w|{^*E1IjjiwHh@Vt0rYJqS@i&u%bmsBTVB7; zb>7dW`sFKLXoTo?F!q*4ScVZb*x_VtAln;=j;}qbW+B20+^j|!ne9y786SM-Pg;H` z5R`-4SMep)Va4~ zqrq^8qt0cGJrTv{426f52iwptaBMWQ_T3b4pYjY$(1s^K0J6Ph;rDd~TAX%OiJke( zIEP@syVc2zD6WkOKfRl#%rjj3?H-1uyK(gJ;K>QL6~s=H@dw19!oVZ?)C-q@J&Uo9 zb6_mf%V!QE_^4Oq;`a_8i%e3Cy*%nPv)a}$7n^yqrf04GUv2_!yB8g3iM}+_wrZsX z1ZLp1z;E%+IR*&i@k_F!R$FqDmcD^NK7(vnllAbG1x4C_p^k)JSek;~w!ZL9-_X0qW46L2~Kg=*m8~@llubp zANAT;fB!=J0P~3G1{->RHoI1e*`K%7S@Eaq@1>VOKj^G?R2t3RSs??;I1|;8Tj^8$ zTzo|EOYIKYb$9CySbZOL?CS7w_>=XFu11gTCBMYUoxV>CFvz!AFY!4qK5`rXx;C$5 zkqJlClXqMBbiTfg7Jhv)Vq`2)U;N0iazW1d*5f`sdr~$EPa(=Vcf9E?O z>fT-UUuU)wxDbf;mUr@S5dEIs4MsHq=TVh`kH6pij!~hYFm8IdeCAl(Fl$t!PD{&n zEXduImUK$cOV-M5);5OmXx}F2I%$Z0DULgJwyBy5`LshPFXZfEO-%6pfYS}Ye5|`K zb6GmQRQkRBs+s<-@yMmUr$r1~J9&<-tE1lSzlM=|Q0WH;__s6gyTYQTg$`_FQeo=y z%aW-$^w9-&q5j)@DzD^*4cjIT>Rb46>-k&x{2MZ2)zjVy0O7m%_HAFJTt)Wy-FTz@ z{cUmj{j8XSdjRoDNS$={@7o5$=~3xTbkxAT;v94T0{_+6Y~9EhAJ1-kS#o<`tub~4NCf` zu7$>aIT%ckm`D`OmLl8BjWp+AEyy#+U|M7z+VM=$gzA~mpXwrW2J!G&GFQF2oGD7T zRZ9deUQtWNq^#V__Cc}y*Bi(VtU~AQiBSxa+7efT{Pr2lD&nzQi?NT(FFab(bRn8r z@(#@%^2_dd)JjzX2S!BR0o%&ibcWA}gyuy<Jps zVQ6JWG-Rj5{_K{&@n9vM*i$w)Ruz_f_#2_2fN={YS{NBn&yoX?<9_6hs#BHGd6*rz z@~fC*?W>k9!-D0TVnYl~1_`G5J=l>~$_5B@W*|*UtG(h$^kZgRNMIJ%Zp?2>`y;6u zZ8GT;3AtV49;N7HMklC`9N`?1OP>=&QPM7XR=Ov1Zi1;=??r3dLJe^zKA`svQmsU? zw1g@*TR?{1P3SRmW`-^2lfnQTcly!Hfo|sP5sD26VS&*eswD^^yK});)X%@FK`k4s zJv?_&g+rh~jdgtj9r`7NmM0`SXEvkYv3_sUY!rDP*^NE&>U_#nyBl_@JW1UUTedhp zf7qX7N67h+{ZOOpA#ML<#Bl`<2iB?o2 zXl^uVa5MP;`%}=Zt&JjF+lX#K{E6p|M7LB9i(l2Uc?8Gm$_ZoPNOjr2@rF96`(@$* z3&Lphkk)p{#55uM@&2>@w0O+NEC{@^|T~qSf&E=XvZ*@W4QRH1uPSul+Vo~Zt=F& z4}Xc#)-$x??j=F@U#3^eBbhrql>P)o#e@`Q#p#IbEom87GX8ii<2P?KYY4xLR`iJ( z8g8_P-3oY~U_kmonC*M+kr!1IWClJv%58W0{1FK0_9XcWefi7R5Rj+{xpzEOG(d^v zu-woH9~Ku-fWg3{_L14bL|DIjY$Nllx5Ux`c%TYN?z0c@=#}|6V1L8~&rDuY3_Wj4 zzJMYmuz&TnK9CoiNAKU!26YkGE|e<@IQKeGp4YbOtMrF%J$IW|L8+ffG6^GPwmi~# zR9Q^gY3#0M|BmuwTQTDIf})`v^&+$Yx%PH;|KJg$XTvFWWMHl+b|ktWG_y|qo!F45 zX@IH3+dfX+x?W-G4gHL(oZA})uz1;h{s z0SO5{Le0{%uUJmNz6x;YA<#`^Iy^l*9(}uW1Beirii5-Q;wnn4R(59*#nO&eUgaK4 z#dC2UFB(tNF?0weESY9_4JD*)Er$;b8_+WLc@j~?2Um~F$yU2ZuJ=^2{Sk6ksrOuA zJ;R@IPdPAt)-zFPX!o^aZfHjuAfSpNargODtJG6ge&nuwT7xv{e453FS}5u4?a_)g&Qoyj&c$J; zK~`nvu!W_g1XmoXloiZ8k1}`@6sCYrrkA-!6W@=Km|ArGwl7jhH14e@q#x~j!k5#5rBQDxt7KRe=VS`I zs8TDlHw!b23N60XY^ot^D!xuz(mX-FvkN0ZVnhJS) z9Sxd)?Pgp)Gyn&w#FS;ZkX|5p?HXddCo*_>*%P`XReI@4e+jaHm159@X~4zNAUpxS zv1w@9fRuBId-HgqpbY<^oxdGc>kI?1|Fvk_151o$ZT`D7Y~c*xG(d(Hfm>?&>@e{A zVmKEnW!s=pHJvV(7)2E*5NNPjVW1ji;_^e9Xq0jy+yR(Q?m$CvDE|;R6@tbU{3U=v zX3*kCuX&mFr7hdX@gO#yJ9CQh$x1*strOA#Gn{V=8IIgE7fbsPw8}|^9C|WFVL)3U zMa(H4*7f0>h$-s_e9hNT<9?#=b^MF2!9_8WBiYQB(YTS(58?t1iu7J@DY+L5X?6o0tY}}|)MkA27cp9&rTQb zDqt;nA|k2klPNQ^Be~}&6LWPsOW=>c3C^(=i?mws++HL?ahu3J{YDuMnG$j9YmptL zv|m_Ez1WR&zx3N6&A8y;n`S0>3?Je+lL|6v_asDE1!b1anD3b~ZX%X$6s7F!E~63} zi2@U-`IM!TO8G;#5Zff`X+U~CcFc8ryV9W-op;fE(6!Q{MfNu%2oV`Bn2ER$QJI$Kn$*OQ?TBj&44+t5JyZZuVc zl;w#b(?ukQ!4|yaj(&>0#lz^>WioF{TLO9eF_g4bna89;YS32kS`l2L$h{=b0V9`7 z%?IXzDKFuqmoA#N;XK?`ICtN%E4xGL6P}kDWVaNZ154lEm|)91WeEmiP*d(!_B7Js z3x9A@Ce$@+Ocgpwm-Te7CWG0!M|ugmn2HadBX<2ezNaVk(jvDSE9gA5;oWWI<9YQQ zdjA*aR3D>@ZiS9*eySSQI~$t8^0|ZM^J~FK2vZl>Rn_#1Rt9W+-DcOa8F|Cl7%K7?4vS&$~Ms#-vu|xfK)++oN3=Gf1UGX4P0>I`A_d%F1-S?LhM1Jv|ptQmn0 z?gE64O-*(0nUJP8pu|>F6UBDHs4~7*P%R~*+Ujkid~vZ--3OBx?tZz!44?lZm91Z7 z;cF_^fSyM-fjMoF@UB3HFCCEpi5ckpl|52>_b&|oiqZG1zN%-4hh1PaXverNSK3bw zr0Lp7)VMj_lAm7 ze$a9I&shlE*o2iu7Qh_2jz4v7$6H<79n3w7?^Vu`ABBRM3mWJ?_)(P?!Q`6bDFI+O zKbNar8h>l3sb~TVQa}Y>r)SfGRE0+^f<#+qUEm()YPGgbDmH**44j542M`%FHuadB z*(n>Up%2&E&R>&CUaw3Pz74M^bXIl*Gn_x*5jjSSel~)Xyt?4gbaU=h5Sg1CwY^f< zCGQ4rrF%)i>mh%p(owZ5*g8NFCA*Kcu~pP;oG~Fl%NqEUyN&sa9*ZJ6SVQaLrC4XF z-hC@~TNR2XN|qqBdhpM6A|DqmBu{Oun_=1~)$meE9^;&BuUjx0o51ACZNGs|elXn1 zzsD&@BFLj(!h>}QHj@Ix2{auO2$4w=bt|S!so>u>{8prBe-4?TJ4L84Q`%O`K6>)d z-}zoY6lOoE1Y(o9M&s$4DItb?iAwCM%h^@ga6K(LkpmhKOn08BtmII;rVfa zPPtNEPwzK-`W_h>g6ABG;3(LOg~W8iH>?=C2nj0n}-T`CSf*Y*Q_R zcnt_&Yk5IJJVP8kjSAK^RNZC z=|?oSA%%uE!a@PCZ8|pI+x6#Z%=BJ8;B3Yo^$g~QMkW~yCa8K;d_t# zn)^6%XD7@^meY6`tsVr-JeJIN@t*^kCQs10qL0jZznqF{WwBq}Ook=|V$o(GMHr_P zcb5n>ki=fSLP-_6b>!1)#o`x!Nq!X4A6MNf%BHO!1;-S0nE9lEJNjaj;Zhd)J>j z!*e-BpUg-nJ)l(qp2mVWBK9o#5*UX`UiKjd34uF0{I>KbPTP(SJf$5Isd$~BIwpyS zKqH5x8RCDYRGUc+nCsbV&U)S$_Nfs_?-GJ@@Ibil%b7!1fMUwGF0I-Q82PN)M1@EJ z4UaMwUYSohUMkv&P8pPJ6^KFxhzhU~zc#05V($}>3woaoIU(k{IvHQS#2nRVA4{o?K!IIFJEEc@OPR230%A_L!+S3qm#V-P*>~F8ywK&&5 zV89U~1DY#sUV}QonJ()+{KB|Gq^$Nagk%aIsA_l(S>}FkkOHxAha`AY8Q}I6KYt=F zMa&q4le*8`S&a1;4e(|)YcA&;9fXbiisr!3-qnbMp$kz+^`{#y1Xn0ItH2qkrqs~= z5?om(Q@PNA8~8T&L~gXCeD~tE%dtCR^ET`P;cz(*ESRr45;a>P2Y94`?_ z#Xy$8C7ciV_bu*@`dS3(Iv!=%07Kq4+OBXgrP@1I&LXPDGL+1Q^_BJUR*YhgQrvw) zo-t;e9z)v0R#ZJ9jTB;;#=x>Ur32bPOx_xqW6K^oa*mHJ|uyAPY!J3 z4`f9}z6NDc4ST68P@ zLyHD6f-dvqfwL8V2t&L&S<;D_qr&=zxURC}A~H}eL<>-#`ub!D9m+KDuHiqTAiu#F z>Y1|zudNA63^-1G9U^>t$DI9U0F8i~qE%t1(6_(PHXPn>0k5o_$H(7(HH_XfDa&q@ zQY}(+?xYT3--AarfX>1^t|8V2d4aXrg4Wh=C1?$WZXGG!h-b^N$eoCH0oWvHj{V~k zZYQHPuG-n`XkXy{N%kb`{Sg5KRdjB4{66%6_eqvuaLaH>nuI^XOa19-LC#(DSDitB4rsDWhVId`5J8=XF?IBPaxr^*z1-Evl^szxTfnJk6_@aNP z`5_A)bw}#lPbQit!jXnpNFyBbX2uLBJF?`%d$W?{pJ#B5gnw*PjvcG zf;mE4s>WXj`LrSHT1*uGNN+@Rlkg3Fek@{L0Lo+xym12O9tdQRo+o5j03(2TOCU+D zx>8vFPY@nRI1Kq7daoFnHGk;=y zP0;ZxRwW;jr(CtWo9x-%8U~|O5xJ-P$B1kh)8)3aZQc_G$6e3Jk^?k$roU`o0qP^ zobKh;zaQrmb%4f2SO~b#oYLVA&e7(LuH99|hlhEOC`|-yS$iAF7 zH(2H0lgK~KVaC(B<6Bb}Prv~uc>7H6V3~lr%@fz~7bX2W0mG-854(@g56CLcGy2v% zipn_@mxft=uF=ox8^y`)-M-Ch>UAB{P;!L0bOk)^XC}wuB}!=8j|RrzfPtn!C>dU2 z*xWkTLJ-K1WRk08PyVE;cd@q98M{Jg=JWlRq&~s3+O`Vk7n1aAdpPn|4arJaTzFmv z<3tx>d%cKPo@H4MkSqLkTXyqO4pV#_pDe@eb619TKdI{2Sbgo<`n+*t%XuPBMW^GO zwPh+}fo@`+PUT3N9e`61p}Nr~^!XvGH|R_}JZkH;q)0b;6Yo z_3oSwwquqye_g!r*K^tiS+XRVa!#W$p!aTGywDp->nG5WVI)6R&5T{vos$>Bhx?oG zZfLXOPKF*cIxYnbMVlmDEvvXiZ&pmPGhiviZw)U96BL1*>hY}6qaPwiY)w`wN`A+ z3A`p+V}d2Ua%!aN}E%a+jg=((1+{s9R*9phWunKB`o z#Foj?oJ?jF+R1#C5_E0WeaLN6M|r*Rx64SJyawIdm^o)7EJ(>w)#_Tk zIq)z6iSljoYN_Y3#%O~pH#s=$^i%7a(gE+?N;#nx^P{2l)rnUCe>I;@Q}%}$M{Q3$1^c3H{F8D>?sf6f7IDac zo!s5}n0Fr@M5|LHElv!ZNR5_1g=Lb_Mjvb6&oK5D$ozwxMawxx(_DYI{ie>X;h3z| zI847#@6~f29?!eplNvy(yzsu7Utg5uC&`#=m3*26zm~syY&+pHLbH88`s{hfljAu} z@t=?&SjIU)uX;wo7=vWoI7NkFLMPqGnPimT6v%Y~1&agJ`Nuud+Nx@U5us2{5o|J~VPx$vty?GNvn6dYT6)EeL2 zdP(*aocug{*QNi$M!;`5TX)-QYW=9uhJ?w(XUy^=_GGcG$S=#RR*ryMNe_pQ^>*V8 z(F(8G(8dcUQw`w?D-_aXWZFzT(&P%!d*OhAOa-oQgLas{zp6v8kGNn~{;&zny>|8) zmc@#1pRG_|L{)g(MYmr^ug@KBT^+|dYuEH~r^n2A-(OM&`X6@=TWCe7Xo&gaj2G1*nfc%-id z+Y1C7K)0* zZRT;5nICh@k|Y%}NACQK&4>*9{fp%*uj)Pj@s9hDr%KP%TN<<;H#-(`+`lAU#8+gv z#T1S=`RD!s(^c=wt%mT##R#l)#F>kaD3HLlTB=^+Y!0}S2Xpe?fUf z3n_CLALB^EQkNk=Ei?y3J}n;A{?5cuos(Id(=F{2^`{<)^Kq=eQl1{yo488fXFT%4 zYd6(qC2B=OPWN??hC4qwNWSu}3R0`_0nT`n5S{H96C-y*r-kfysBB9GB=01GVlPXWg*&WE=gmiieiIhmq$7i98X<8EyC= zN8T4Q^b?PKgJ=3JR*sXI7JDxdQ8CyIrHX(3V3{W_b`O6cUre%PTGehI#P>zV5(wb- z;plcX7}m#QS*73Hyl8q%;JLYy!t$Ej@L7cOa81mzvF2PdN9Z)u`FBO0?n*H2eqF#! zKYz^d@HtK+Zr%(1w~%L3^ZeG`MN@8$^$C{Yk4CFoF^ur%nRRxvUgH;ob++{DI+w$} z<68#~K&F}07JI(g?ta3#Li)v|%B4aYGw$@M1GPwP4^QLwo$cF|>25sqwGU@$)Q6@K~iqHjbIeqp;>Q%{q zicYI;Re!762!)tv{KC%BdXkz8Vav*>IAC=cYFD_2z5Qgho$T4gi@h#ay zL{DnNf0?|}+m8F~a)er|jEVL2v+3yCUVSZ{FjQqVje`LB@DePGFP2ah#eIDi!BMGV z|4Q*T)O_50b;83+Cqq5(kzcaZ1jdFrw2H?8U02QrZ7U-?b?9-}PM( zaC%(6(-bAc+s;qx@4XS%yTi`^8@$>1U&u*A^waL??5f%EU`GA^Je~9X_V?zQ;JHm# zo{om-Hl%G9kj^T6v`oO%?x+BydmxdthNwxFb2E}-^b^9?g-f(H8psJ5J11|yH3DZy z*8jJ`i{m8IOGc>cA`@@dmOe(Nwm{i-j+5v7qLafk3xdK%S|+;v5=fDL(Mmm&h#{$ufKdY-aXdz#1hMJ9Ix z3b`-rT=qj;QF(7?qbYNG^Ac#g)E72T)i@{ozqEMa+P;Hh9#jMwNYDeZyMk)_+!n7B zAvs4+t(BD6NHch7{6ENvpqk(Rzr@QHf&G~k^9~LRps+O*1X#D|{s$0RCu*fGaRMd7t!x$ z$Q-}Vv!5*kV(eraZZup86$U*IUk-v_HBl*Wi>f2IpcNvFh1u?%>WbN_#8efn2M=u~pDg z%gH>E-q}B-Q-)I4h6307-DGZ`zf>rMa%!kNtl)+Ta&HF>n)O>q7%OoE$Kx}624#;z z!>}kKT&{%;%wJ7gL8mZI@*2H;0rWaeG9D(w!<|<|^1k{5d8h`;S^DM(!9$|$mEvZ$HoZQc%ne^Q`eaWO91%8+WElJLR=_r_O(5=1B-2cZUn zBXE+L*t8MeHTP0kvF~Gf4by@sTd{e#rWgAp?iKK`F93VwDgBKYG^{r`36yn1r~GXV57 z02}Pe{14}O9w}R&dwFZbEM+mr-1x02I=$H+J`|}J7;T5*+4D|L_xj~?w*=dxV0h-^ znH**eQRUn+ezV)#{fv;?){mu~d-O>-IOiyi6^%S^X+a5acW2G`|GA23?}O zM~RxM-g7Z!KO*G4whS_{$&u|!Q7sh7gT&2;8j|u~oX1wf=|?G(<=4uID@zj{Oj)_S zY<0!s6QC+x)j3L}?8?>bR&QXNi?4{XVjT+M{zs%6Kgux0kmd62sjwkbKk5aS+~(k@E!%fr!8Ek*u_3r;J@*cIg}>W^xk$wT=f= zS;Cl<78|QZeKS7|-{2Z^b?BNu_b;F{u`iNGXP($#noE?udTabi+c@HX-AF6C${X3> zGRtwl%oQHWt~QISJ^m3CRj%|h7)&oW{4?1{Gsgfr_G^E{QTZ!Jg;TBEFtQSpGF;+u ziGQXay#~3d7!moY`txkQwk(yAR1-RUb;FC{bo52Xh=Be5?ndoqjrX(_{Jae$&m>(X z$xzIW8K`*0*rQp&k1L}&T+@XKU+EC?El&5O#e7`j9qnVw>&IUczUWvtp5Phna7nqs z5Zo%w{}gBa=MTAdy}m(>eFN7)+R7l*T>1r`g>AaM>H_N$nQeWfBHTqHl$UYGKLI6Q zjUZA?BN$?2mkKL>^GkYM1XR= zFzg8;2uYNM&Ka8N6KSdI3N7+3vCEY<>pX9c_U<19RuD%P7i{c?32eztsR-M8U>FX4 z71o4{(~$}qJE;UED3W-gZR|}}m=QyNG~qJyJb2{Wkjo>h5IJ-a9SG?_QL?6YQ%t7) zGan;HQtn>;pMkbU=`Sn)Q+-*X_;f2I2)Cx-a&vE~C>Rvsp=CQg6Y@b_T6z|)Uab;C z2K5ka!z@Un;q;fvFdJ8k1s}BW7A3Ks&QaR{(r}{wBOOu@dd!-Iu#8BCzN{8p` z&WDO2Al{j>$k_V?eg;A>&Ie1-mE|anPXZ&O3#u5C71~8EQ@jf&jVb-&!~e#wgjkY# zJ2sJf3cYDkYa&lgQ5*}Ql|Lm#&D)}A_L9K+A8C>0*URV4=KCHQTu;5--`AVS(TyT) zwSz^IL-a^=Jh`pmv`S`@MJrODi{$ze5YE$8fG`mP6UHx-e3F7uQB|p0K3Bd-zSwF? zBply&`0z7=S*9`FOk`Xay@=p|7D|0L8neFv0zMa^&g~j9>;=?_k}cT0Vww;W61_(k zjrFnBaCKODIx~mdOUI1FVMk7ZXkI<1CG=QV&o@%d_05IbrcT`|5v#UHh42v6&A5%y zGBMkGF3sBv3$MzQHgxU;`5@k)5`oU1P|LR&{gKf|eU0nRaNkxG?M2b!8+Q9mcrM$S zxoEVrT#lM~(fub)c-@{3wy_-h)K0ibOU@V1l9`Il_up$>v%??d)Ku_ow@?n!tyrn7 zNII1gg*8Iz88Uidcob(!9wD2Nc3=_=ExuaXZWXKHU3KpHUBv6l#ymkq6;-(Pt$4YCFbSO36-2jao`<=VeV5<>{AYO=>DpMp}zjDp7O6y7WdQLjB{_0LDdd-mwGS z@mJuPR&bPko%&6*_psfgKUNQ(>^}ns6&h{St2gP&$}yNH@@doNOneymz7}8P>VF@9 zKzsQi_A(<*900@Q>|U1$22<0Tq;`8|zw_e&Kiwajm=jD(sN*t6JKY+pn1b!0yxYFc zWJ}XMvo5lp_lZMWa zV%cBJAD{pM+@VzueLL`tPoAWqU}R>BV8}XK_2KNj8Nsn%H|KsaHAIZoG{~$9sHXDV z7R3Gj5}c=6c~$*TA2)eDlTCb3HWi0ev(L{tTMYS4j}^n#yHzS?20Wt$0~AgqAxN0C zUOp`=YXY-H3^H;=q{@4+By_37wxDeV#Tw5IY_Aqt$`nU4EOm^VDc>i#hwsZt;#4k= zPhvU1s9T>JsPH6yQGn#wiYa#&6GQkZrtHj?2%P4BSZex~l!O>p=#_+ea$%-xTB6NQ zx2lv+Nx!-K-4NgV}>yl{Ls- zWXG?>}#z?fxtu}I?q_{s}t_b7kXn3eVh7p5*f=_rNxqE=4u1PT&14x1Yp4)mut8s zFY@d|ImTiO%<_$8VxxX+2{%jF{4TFT@49M6(eB3P-7VMq3C<^^MfgePS`Kkj^N;&=JwQ7NAE8ASjvcb=Yzs;4-AAWTlY|2;rBoR2f_okX(l zzQf~K2T=Jv!V-(o39kW0%f#D|LsE+e=SqDs6KD91OH3r}G4*U|(Y-ibJau6kP*|_~eW3gbU5B%1XCvxut zCLV3R&ozM!&e5K(WHEkCT3I$?`GD)uI)XPHlc85ed=D6$SxLsymG9uSmZnfKw~$+H zCHkdTq;xRxceq0&e>&e<^YzX$@?DeWT=&Ot;t0obgIhoXNTht$G?5Rh`nqVD5-1|Y z86=0HiB|z>`6qQ`fd0rGJRi^BMkWijs{1J-*9soT=i=mfKrLvde}&Wjw)^MmVC)ILHv94>~nw zPwtR-QZ17sK4ATY$zbqrpE6JF_exekfy!Swq5@+fE#f3A_|V~`51k6a9OK^F8Y(5d z)G@?gjYYuahTw#)pU?vUvF(lPz?#$K?{s#N1vki;ooUPJ&@>Nb8q%g+A|ly&CVaW_ zKiwE=?S*Nc{KsHr+w=cu;tbucTVF*OFmaI)HcCdBb+A<(~^T#Bu?SRTKJ6)a_tfc>>u}6{MIm z$9dr0f7r)69`WIUIBHsJ)QAY$UgimI_&ek;-za2QwbB8LV82uCbeNa!p(t-c@Yf2R;>g|GB#nBGIJ{ho|cZf+{?KB7D3Kws&LNY)1(+i`7RO zlSVLb7sgl0k(}IzZMl6N3nCINM0>SrL3@qZ9J8^z+l;1haPcg{h&?9{AvLcrBHpT{ z3?K}n*CdkmQ11ycJN9X55DOD1HrN0X0u7qXqv#wD)`u7SY44P;5EmznVrXRp^J1bY zF#l1v{CKv-v9S~I<)K2$4VHp$`2v%J-gN%Y8l{X_keKjC|B<@crC z^DaQ5(IGPUi58)iWJj-b}G5id&-9lAF0eRIc`n zdaYu;T)>F(Y@!=>H%b!auQn(GIM9u7YG(dyijFjz&q6KPMNFPK%PlY^%~r}z)f`0| ziLV=slX+9)d*ylRC-}$>U0SMS=g>QBaQC%TeN8}y1%>g-*P(-Vpd1b`#EnU2VK1Rq z8xSP83A>eL_bcS3No)GD;Wz!Ly!id_4VOto3WF39IHfTF=L-G$Wsa0QJum{|{a6ycT*I%xd#NpRs%gDtOD@{f=d9?P4$?)91BeD(jkxAPBUtd4c4 z`zc5eQB*5)Z2C4{c}N)|Ao7`ygm9?Hv*@-cJzwStt09eYodk*V+sIxz-q*}lLNt@y zAKi3j*0bzbGP?^_sG#(9C*p=MzNJ^@T_8i==dwpix7K?8P--fO-V>GyySFnNV!hvi z4bz5|PBW!=9n@ug^_yn(1}Y6T*_g)S9oNJ;pgam&D3GU){GY2W{g(MBtZuAHf+8WS zU?T0SBCie57kjPAoyVS!p)Vtn_YPyzx~Bf}$U4qfGtqGb=-*=O1FekSBR1}PzcQ~#2Y!jH zts5`l^RXRrcmH!mdQh*(`>9QvoxD4BXG4IFT+p^ce`xSwqsNy^lq8aX)C-Yk{2gy8!D6o1PV?}*bnlTZP z!Tn~>#Mf0=EdEWqj5Ntc?_zO)RRc@vJ(eQJ{87WvvvDIG*sq07mRB)CpnLwa5C3oW zwJdXCLQAB3Wc_gfXDZ0Et@DgIVHP}GB1_T0EvBa--=;YHjaTi~;hC=co3ds@K+Ees z(wQadKI<&H5jw^tt88IjJWgdIl2wP#qygWL>5wEP`X2C1KB|9==wJBAb?-qeF=PV1 za%;Ef6>a)*>j9!=T^Bk-`jZ*+)2EYbv-lqQ+A5lWOi|$7nsE6#f?Ex{|C1%hwvBT| z<~Ec{c_gH^%LTk_kI{xBqRf>uCwt~L0PCZ~vA#__H|iBH*t&DzraGR?`0VtIXpES* zvJ}7y<;dGWK!XQ?3nAB$6UC*-+~JWB0ZDiLIwpm%jTy;rmZ6q9cSoquRA% zcI=+~v}`Iz@1LJ>v^uK*;F_vEV>Nos|uI4>!X$^@cB| z1y5rc-v9LA&@{kiQ&o-z*2dsDhYG=FZA1Bv*o`BS$zRnEhEGmvxt<;!6lJhJy{rAE zcHvkrPDrP&9C2okA3R+wYbINT6Z+ft;X@Y%_tG#=Ief|LZ^g+F@Xo7uS zc!XUxPUTBIB_P4E4%7Gjj=wPzL=KD3I~cj+$H1oh5FQ%mXW*k=j%jH?yeL3}iAaQT z!(@)zxk7){7ImNGT0?-I+^IW5Q{PdlVqLI?xgRC*k8kh*z-L<}*=RLX?;RY_*5pZ2&__k&XR8VUY6{ruQF#6QDUB1=(b8jI+yWMNI-=f_MYp@xINsrwN{w4 zOLChzMLU}!d&X$yN*eOEU3yyLHiwSnVZZb+r%qQLUj@Mz~y1iU!e;*-4Hda|%tYz?uXS-CgwQlQy z2cUbCiadGXJ74FD)F3+_1y+#^_+w&OxKt4wI3}3~N?rlow*DT4Skz_54s12Po6MNb z4W~gHl7b!85wlqZ8KBtW4EdMPSmzOZNw(argArQ#Z67Ptsw5lr@WYQdr2YdujYTz( zF-XX%D@{+a)}if2%Rbxn&8QhCXVJXK7eI@Odo$m9xfMm@U0esitQN|t{fxre!0^7a zb^v^anY?=408?7NFs^gDZ-2c{o|8Nx^Wy{9xuBD2-Gh_S7eQcazXF%{^ zewR$H)B+dUu9Ca|`YmG19&4y#@>_&@ri7BoUQKGG98+6J_1~7M(wl)n+^n zDvm8WiLVFpi1rQ6;+8jt%;-=5daE7XX>wIQt9NpnuOZJo&id9L$_`90jk}Z8ex+Z( zFU&2_0;$y^Ff#YQBTl?opF(pE^`39$Z}U=B6EikjNvL~xVJwvBG>y|~`6A~|-f zgNE#X`--fZtVa2pD!4#X`oX*or*i=al_nWvb>xi}ofG{g=v|El6!kBmn>;ia{IH@- zBe%Ln;<#V=Ov6rNZFwQ--A80S?#S1P>kOAdV+K%fAR*}zO|h<$?qS+i5uGM8^5TEN zmUv$M`y-6IA=rMRu(L^zviD*d&pbtu40e>t4t+&EgwvgMpAGhmL(#f*%dvk=ZS@#@ z!}aSMkSU&au}6$?%fPC;(t7j2I5F$?(BWSK%B6^zeoJr-uqn8DD`-X1Y3sUGN%*d$ z7mwG@{ysYWUFi(ZDqeWCk!6%gPuD1b@>V(yQ$Aal@f$5h3~#yzH}}*Ktcr+!wmvE> z$g6-B1aD!|uRpqW-=LaMqwR^i(#{NTJ~6efuSRc3gwOmlTaq39u^3y#tIp0e!njLw z(-02&NVZFvT4DyeZ{Ydldf4h#b#lgWg>+J>bDPYLoAT3~vegZp5iE=&RJ{+Og_{)D zbHDErcS5Oau{RP%c)rS2&p(L5(595I#(^C$#pEXv%yyvzku!=~X zT{h@Nh>^iE%m#t=FR=%hvcb%PSh+%CH92vg2^QsOw4S2b-7c3@eY~FWJ&--v>LdcI zcc6@YZMjY%fU-rI zml}Ui-W*Iui<*M0c{Kk|j?h6a6)38e114qSvE($^$uJBbMgZUy^a*4K;F>;jjTCj!`yx%VF7 zVPTAqfsI?>bDBn1^hjRjKR|DG;smcr)4t22lClM!Yi(CS*X&9qG6j(w53v& zYWYVQmKy!SwPGJBLR@EB!hcfsuL97&hbgRI#-hMDREp)y?FExtlu=i6`5RE*8eK6> z@oG-h%@F5Dm=^J~!VuC;@EjhL3*k{@LVv)%`xH)u;`VO-H{DiC5hA152fFtIh-*A% z1>ncIjF>YE7el=YxQZi<7Cv?b4AKKA;UE58k3cWW(BS+x7m>s7PdLSuQlNa>{skJ+ zYg%yl$3D$<>J5IJZ-o%xX7YQjK-wUGx&ooNlatE?%{Yc8@KBH#X1|Yr_~=8>hK@W8 zA|V-aG)X2{7z5G}WU-0aj*Sk&I`nltNYAxh^y&FvWo_~I|BLwC0KMgZBQ~U&aXw#t z0-f_8c(!J0stT?kTk90oHh^|s1WqW5D10-NNcO9Id}oav!Fi62uGe1%fctVZ5thDL zwnG5Q|0O`Dqqz~V>N+NJ0(F;=>$`wr>{?St(g*++(Em3H)@%0Vrf7xZ@+Pd_Biu0Z z>Q-|sDB$vJu}{>fZ^Slsb)K-YPuK4H4>E@YHRk`BpZ|nw|35WYxbC9=AMu(x`+wN0A4;xCIai`Up>LAoit$wA@I1TMvC z#j1ZVm9FNL^u>qlUn3O6s_ms2$)#gQNP;mQmr7C{tU~YL-yRLEbEAs}<61SZu7NzT z?KRYYnWn|X?Qqh(czei|(VXxnmY8Zn<=+CYzemybbJ;2?Pk;=?04{*H`TZkKYB?p- ztRZkOG=c8nN{(hqc#zI?H;M;+K^*F>2vc4Qtnhs~-T~kwV}MqWn7e{fg4=*I{5b6? z6oD-=eWLv3H!>()vu}nM#_E_AMsubiB`BbwkNqs7kWAGRvce?G^^75nopeL46a>8v zt&jBh8C)ruzR-Wwk+>bAE!}J1>ZNm9+7zloa<3IaL+5sA&ulMoA(y$!Jx^LQL!C_( z?Tq(sVUDIPM4Ndl&e%&d2ZTMYD1{}P!n+w88-`bjX7u6urSrIhYvm>vkBU1;2vmYm z6>e4sccYx*q-RBclXjZu(_J$Ub12viT1Fwkna4H)qUu~mX&MlK^-~Du6RZeTcq)@n zF4+1?DP1pSnA+^&(;E-#CH+5qGS5oTyvAAe)y^RyflsrmNBFa4$)2v-K_m;t| zzF&0c{!D$`{(ZjpV8Xo*Cr_v-0;My*isuawV*!YWm+1hlok73mdiY2|G+c+9Xhn(1+?&ZP`hjX;3_29cN*zM!bHsrhRH|r==69z`r`rw1@PiUC< z(CYni(WU8%(0ab41%}&H(IS#;U2hmgfjs$C^DBfy4O;SDL0Zkrxi!&3949;0^bj%4 zJjj0S*Z16XTGAcz2_FD8^4)WOtarj+6`MiTetlpBiyi0s$WlD`a|yT*?xJE*N&uUB zS6lhpgr;O-!y$E6^SI`^jO|gUIn?2s4k6Rzh7@pL62KruDAT~wHB;kNblU<@%lSvH zC=LH<7eGt~<2`VTD61{zgfPo;-gWQI5tSD^dSfKOeOLTLR1cNSgAKVgWZ}8r9z5&i zh+XE~;KUQ}TT>KxNbqz?BB4P59qP-s%V{I~9?8T7K=*Xcn#fXU!&A2ehZ|s`J4m_P zx2#`i^rq`W%BMgplVmd@QMw?g%(K*w>8)%h_eXmK{XE#uf&f8l2ZY$aTmXq*N6Z#y zcd$z=!FA~cE&ue*t2=uRE7%QR*OGiq35zwQW4go_a6e}y1sS)ET90K2?HQ&%W5z-U z22aFHB}4ot{xtq$KElL{ktCcx7H|=$2(md!Vkm>B&P&fo3-o$3i;Hx6;c_ z(4zoFS(OQU$5NhJO<6Ikhdh zs7b0>+M=&1iQ6HO7um#>Xx3_Qp4yyBVXaVveo-S_m~{_tIgBeR0?DOns#cQ9C`GH*K=Bwr$xx8g}FoCX3j_KFj8u7TcL2Qz%j-wsooT?~sBJSRL+ z0L3~U7xQ0aAzbRI+c%=#hpHtSx7^*!;}}7={IHPcz%`IE^6Z)I8n}uv1kFtbe*~VG zp0E{pJzMirQA;(9xPhiV6ZHkVc_y7Gx7l_AV^*X}f_b!HEzjvhh`PrOVdjs)i4QC9 z*CL;YR%!>gb;0gvQ6k&`Gi1#(8lgh0#%Rgk4Q<)?0N%jU>P$O)`A8y1 z%@a0S$FPRs>ma7yZY8#Dg>#1viV@$m=#L~|RlUYYZ8!%@kjE{@b)Um2L@w#UTh@gJo~N^}0JuCE2j zoj|v!l+2|~Bxtk+T^cupLl3P=$qHmJXu9^jpuLO*cM0HlDILT@kE2DKeQ{e}QNWPM zKyEl7M^_eoQrnVW&)o|Fg2fR_{AEmlq4o@Hn9O98W`YcP=k|O8yxkGkgPwHm1ed&~ zxwagq{_FTAwUbfgG=12~(e=r1nyIf~?9iSlC+H}cp*>A7&BFtX9>bfIF9+&-*4ypNqThcS8=QBWeuvzw;io_)eR)ClwC75RGS z*C1!5Wl@ebml|{#PL{_)QJQvwE-?i7BYeQw9WW6FMePNj$k4i@_n#6u>9q;%o;-!g z-{E44^zA6~P)t+jL}J56iXgZu%nE+lK}#k@_T=mW-o4a)qLf#@%@4PPFmmZOzlw=B7v^nEEOD=?WFxO;;nw}l+lvI(1DNiv_^qktTvLGA5p$6^?bVj|-cBJ&uvxLn*>0(*7_V))-Q8?7cK(?an5mlJh^! zO#BsY)x#O>6t3T5FKk27)54QJJ@m}DUAyfeT?LA0GEY`~e0|J(!x%=NB0GA5KLl;b zt>9-%cXGZXYgdHPK7GWw#a8>1LN`6WkM1R_P!e~9_xJ7Pf@S1OZEnJg|uFbcRZnV3kow%yaj@&*0 zQwt_tf`y|?3cDD%dUs^8JZw( z!p+BGobRlVo#gDOMkLlNW_g7W1dLspsaz4wiR?nVC4ahYG6D7WO#lAN?GVqZ@jH(; zb3dKC8+w14=29r|gR9!8-~-&K*yTJ*ZfS?gyd!Ni+4|a>ncBgj7I#06M!+-V$f@Ct zo^>PD#u~TbOisWJ=dg%1tRZ)gw>#}OU_;S+lDR|aNe@84$-u%KqBBmwvtucZ5)7^V z{$=7?RZVjGD!%{uPw{fzr{+)_ji1n>{d%Z zzr1@lWWry{y{y4Dzc%F6W6BqZfRWATG_pT3xV`HpJamy+jyq;1X9Hd<%=D1~Nn1CvIJ zm)D3|S7x>EndMz=cn=f+xj7Kl$>OKJVFY)3l<4S=|=hQ~!d{0%&3lmCRV(N2?Z4Oq%POsR6^&}uS(bdAfT#X%l~PX+ zq`uL0(Ll^i!MU>&lCtntqANt` zp@E>txy6$w!3(A{!>if{(vgxESoPlahpi!i6Qsu+GKmLtMA1?Y)Mt;c*~86*csg|b z-As5o^x^`r%ks=qPBLEY@>_Tar{DajpiPgZ?~@4g-?_&zQL7qafw!7<)FPw15vh*1 zqbuL7_nup-Pv5%^epFH_;C86*r)QeSw?S2@A0Jsci}lcKbx%0^u0IeHmX3YkP_(3K zHh)6*b%{JNY%pH!K_t@*Cy>J6{uG$I2nAfcBin{?9Pd7Jx`mC?v@XC1?;#y|5ep*O z>92o*q@J{3VMjcffPJnkB_$=p?M^u?yLt^W56U5w8bFeNo-co|?5=)1 zoj=#Qx^<#fcrKG9Mu2Po?We2k?p>H*NZyFM#r7ip{z*-7J87*_zK3i3RpM>!RWGR$ zKmG^(%QB>?D=?%XD!udE3l?Kw%>L+Dp5ME5L`7<6qzW>7-~l4>*@rg;izX48Z&CLT zrhz~X<7OACUQXwjmhCItncSlu2~i8kLsgcQEvf7z{pW9^!}$AF3ZqfY#u;gA?IXCy z*X=yl+ZOe%uTes3wmRGm53C(8AD+|4r}@ITH>&~yz6+JS4s7$Mjzq+#0 z6OIo2BC8jPb0Z_*wDuDh2GW@u7yPduPoBm->G9SR>PX}^t~@I?5Y3zkk_EGq7Mzd) z_a`L`B-9x3LZoZ8Nn>=Hw*^khvd6MDi#|`L1|x;7SXZ*{rz#RKTuO zKoJ;Pd~LEN)n&fg|FpYc;-PRZA}_PTOYqPar?(uJ4HN@j=`xEJ!i6&4blt|TArd# zUv-lQyZ`AB2|H@;UIt!X5&g5P1-)D*R)YZ5%D}N6E5iDuI>2muksM zY?zQ|F}gH+`;usxL|*_Bg;YoEqho&*?DUTz03we1BtH#jA`K)zAlt)ju7oDy$8Xcj zChn~oe)&2#8XWlo(7rhInfLtZL2!X%Y7$Fd?=LHnqA94GwS7P9W2HAayB&_}{xi}E z;+tm6;v}Br?p~!g-U{f!n!7IN>RcziA!~sU7`WPu34eTF>Ft3rRm*K{44ol;^LN&3 zcWGZ~Y~j`WA|Y}=1JF)X^8PhmF1MtC`=PAnJ#JOIRbkOU{=;K_#V>&H@A)l(t#pNu zE>HLeAq2Ds?MW}=ce>5v4JFbTiv_h1&7_EPPA}XGUQAhs*>d~NLn8K6vn2ZLa3HsQ zx?Z8p2q$rg53LFqq~L=sC1V|P>#SlPG>xT->DWS3n%csFRxolRQ-R7*V^m&3OEjUW zQ8sP)FZY&cYh?^|4drkraec;cn%_T7!>I?4X%>ny?kA6pl$hFAzTeS}$ugFKVb2!2 zvJ<-x1OM*ARNZ&*JTO-jz+%`F^*xWq4U>E_ug!J;>voh1tI?69sAzEUcs#9LnAzk! zd!2HLAZ&x?;j?PV9MP?EbXWv(HodF8p2e`%U69ROoE1e_b+vI3qNY|2VV1LOq&Y!# zTmPc-Jx$=6ML`wBrudetqX{u2RwjY*?JVnimJpP0KdSMwKWJ%a;c8hS04HD``?Uca z89FRMK^BS~y1l6zK;1xZ#5J_xpzLCGeuK!2Bm@UMhOUw4S?6S!a+j)F^{i zd=K7JOC@dfc#5w;46WXDK0ob}=Zic3;yE;`G6W+a z)eDGac5+sjFUeA_mKI{3Lj3cixcKJ2<1RH^RK5?6i{CJT$FFf`_^GW%j4ce&m5o7szf+@Hkd)3ixsx?GwW4 zI!&E=&G?hql#2)&plikjw^r*~GnYC05l@QrhaJC2OTc$GR>cyYw_Pw};ktMGFn2gP zTJ%bsGBcyF$Ow4-D@v9a^@`web!|NZxx`#<_F>A-DmL8|^Jj(bs{IpS*L(ZQ1*_uI z1^@T!N;ygw{e`t?o~o7~0@Y^$tD6TOsd`PMjX1F>%#0Lr3+R&!&7g|Kx{{a?G7N1M zcKJ9Z*;OA(MF3i~1zMK8;bISz2*j#CW6x?)6pN&yoSKt?UM~b(5+ASQtPw6YB29fO zCv!){85N;rw$>j!gRp0mPX65qaE4u;=6FIR92dSOiCId3~A9| z*xEhk-E%SiKg#2d2AyFUE;PB-Zo*>wm1!!}gmm4%_w=T~cI&zMZqf9EeqST3x$9j=<9Sh&MZ1c zVYJj#ubd1H@s1g$hNB+C?cD5^H+!+54#{gY^;fDUrQ%@sU5IZX1Y9xqv3q65Lk>{} z0NlzY#LRv+NgkO4=;2*(-vJJU6!;0L};B zoYY*`E_9(g(KKL(8^B3Hk;MH_hVIXOvzU+d;Y_!`LY6Y1e|-N+cB2F}wWh0OS_AmC zt#-(Ex{F3~D-4Rj2s!zH zeel~NGQ_nooOT&79lldE(oX<#cjZ=vjNT^^P|JUr8-zBvECH!#&4oU-ln={2`1T`` zXf-Uwofk=lG)I1lu#-3XQY&dYgt<(~E7^*813Lf8P&;T1*W1XW7IiDp7A42hY8jum zByxqM^Zk)h*bJFU2bz6;hI*R|I(U*>?Aoh9GbSC3#BqZImZIqZVXoK8XDuBK5>7!9 z&gHx2XCUhrUU~DA#tPJwZ>)8Du~TB}{K;QK@BTn4oBvaJ!V-|nvh#jr)ct1n`KtZq zq!s!}HGoo4=UXz$_>GGFwIVxu$z3Ghf$@pI7W@g3j~txTp45&9`iVb-VZ&Cx+|(mL zir{i?ZXo0}_{bt@l@dtqn`>;1GZj6x+ie*Qv+h0NV;7{PPO$f4arotSCFYC;?fM8` zzD>Ndvzd2UAumyZ7$vSAw}11x`vh@Z>R8B2%lN0hdqg)3psfCs6=_Gu>a9Z_Ds za-)Gt`yy>faqN9xl_`cB@|HsK3?JJRl;uuaHy&uG?6Zv{YnuVK>XyM$cQUDm+Jlyo zztPWB?*|%V)G*yO+RZ@?#;1f(@4uAS9%XvuPEkmi|B;*U#74 zzUi6wD$`(w{8Xp6Jn;YYjm-V9@T-IM6fj_yVRINF@tiD6&Kd=C!B5p-hysI!j@t_{$L)!QIp0qF&>Ab~QLCTMan#Kw+Oe%9 zev~LwYXD1Po38zo^|4Gh&q{K%%x=DSVw0jfX+F;izGpAs9`|eeR#h)o?;0&PiG0oI z4t*$w+a1c-o3liZz}qq81~*h9|F&q_1~Q(v`ZX?@QU2#-EwE~{Hdn}ejlX-df<=_B zdj)?ge?$1gfNV%gt7KBH93l$-O-DQ;Oap|T-ZXO+rw-BR|Hx+`9e87m3TbD5(={41TmaH(o{E8Y@1Qeo2 z2Ac#z-f`NA<9do#=<>khiebYY`NUi7-=mh02l6|A<}`z#6MuI$!dTd~`D;3*EHWGW ze5mY0YvuJre<8y)^t94n*|Zll?Weg!OSd4(H1==$Kaq`5>b1P|gDQ!*uyiZNOv zHCx!Kl@TLt7V}p*SwwtWgg<5Y^T$C?8@d6(j-&o$=|p0gbR}9{;=djbxZX6h~}kUA4It(2`S_po%|T?GSe0y(vd=Y~Zs=SIJJi>usPu>5Js-p!;N zNH6*XrX5aH-W?g8L^;&4EexV1vO)rP*x)Ulg7ys33Tbe-z;aK5+#pZS+94;5Z9x>6 zW8@m&6YisU9cRx;xDLF7x9!yF=Xx&*ix4hbqRnt)Rg)uN$_aRYy^)u`$c>p%% znDvO6xn25d6r2a1)2>qF<*=D9;T;j~ohmSSBDT(ZQVar`C7xpH8Yq?n=Xi(v57MnX zS4*Zx$GJ+#PYR0Js%(UtNiV@QK+$15aoV+ud=?}wejeNCA!3d1$bSQDvU3q9XcSSS zdYZpP>_|Y z0@3Dp5ZJ;6yNk5{bHbYklJ}ab=g1bkJvGNvGa~@T*6cPNwKpqE4PtI6-xn=Z;=4a# z?0XUSask0`fbYK~U3uhp6L(x#lZ=7A)DK`U@ zd0r89Z*yKjjy9_W%SWlq!Tgi~}VsAgZQWy1n?) zqs7k6_O^N5W-cg4@uPKjVfgSuh&{Sy2#H_&$1h2p0&!v()9cy zA{bvw`I?9Dp+qGe(9LPfB<7G`8|M?gl9B6}uCAY%RhDU93Sp`vR<67!4C8UgfCMa! zb&Xe67@xn}-QVsNI8%P}ky;dgM{;jLhuk$*W#JW-GbDWvs%VX%D#?VxAOdhcv-Nz? zM~0!NXVxIQ{Hm4?f>~>bd-@cTE-BpHFww!@&T_+mM>wk};sz4n_<*_R0Dq zpEA(FeHb8#Jd>A5aHWM@NIc7E9YfI5q_qZi7?)#AfkqT7h@ef7WOt?qD-lHZEVo{U zED^LVM}~v&vm10h1(O~p!ZJMmXz04vUq-c385II#^90ph~tm~B?d^d7SjW@$6 zR?c8clQchzI~?gcvx@wM1#1SHo4am*G}{41AZf_M-{p;^L3#7-KHoj>V&Ym0sl}k2Z zf|yv&Gk1EeFM0H{yIjm1eGRXa4NLpzL=-bElHh2|iLj^IBygEy_T%gP?mPpHgY*7g zT12ZJkmW-O#E6X!h3wRxj<&%i-7AV(IC@dEQjK9t!@~03U(;=)bO88#HKfxv`?+0G z!j^FcEA8-#Gwko_QX^@8tn{rOaH=M|f=0MWzM96Bw8;qOFh1Kdd~gPKxy|NI?8Lr( z?+3IAmj>&|><2II`5N@T&p(+Ogz<6)k|M7S**~o1X$4;#MT4h{V+_ZA zb}52Opp)#j0n$KWz#nacjRUuxq4iOf<#Z>b(YG={As5Iv)NLt?A$WzmA1s*?3f551 zliZ0=MFV`|hS@~F!9wZULe&Hxvd@=&#ykyue6`v2O-?1uIDaBD?rAv|6nr+%5kS^~ zWrbB(tWTU#2>vpR-Yw#6)tbhyOs?_Pzo**5XzT_~fNYx2;oGqDic6~Mh?mi_a8kLX zzs|^V(9EA5>)_OaW9$q_b^bB#OH+LY^Yxiic=(rS9geblF79@Znr@J^DdO(*GyQgj z;V*{I=$Ak|!$N(#E(j&*wifu&`ULP)Wrn^Q*(rRYWfO4o)7tn2EmNkWL(-QrXv^KVE9_J%<{iM|+dW&~k zbP8O$dnI@6_~WV9AxIy9E>!U<<0iTS06EJ>JtkD%qi%i9jZ4UDl?Z-( zQw8dwS99R@+X7fyGrf{w=V*EwXuo{-0!zg5gjop)emV9y(jzN7q313dw1xJJ`i4Qd z&ac}p1YRGrK_JCYbXv$`x~&sggXe}krs)OwCE|+0(Y$DFmkOiaulDr)Bc#>>j0Do^ z4=4>%FB!`Q<%O-bkK%@^x~eoT<>$Ut)~a=hqhx9bnNd3pBJ#y74B?=ciK~3pZ517| z6UXk08_o^?T~3t0X0&#XLL=VB^n57hia zr1w^Eom0%b5bvFW+BREZqNgmdXPk4egl@U`URnNP)v^*Ibu)<|iBV6y5#3R1*AGAF zzuobZUQ<3ktlv-@gi&>r`dhHar#i8*!6@*@@>=QN3QD>2Rk@~IeSUG-Rc&TQs&nh_ zI}7$h)Cs0q`p_x~F&NWiyS3-}wipF_yuyyrpb^>)wSx4Rx{_Sik`^a%`zQ?WX*5~> zy;LkbZfV!ES?JsZa-gkL?K@hy8b9xEo_*xe5gH0I2?4z@;yQ~S=&#*=)wrOw z$)-L-D_LqGw7a%0XH;1JD4CJeF8)L?pdYEEzlWL^%`=Qm6$2}PPH~&pQ6>sVWKsXS4-!BUYp26TQt16oNDf=D0I^0rre!QlHX`5~1h> zPuZh!1D&MwPU5uxet?<0HO<%{X1n}^^S?2a{u!b)yS#4XMq#y0hxs&z7;wG4lxD+1 z;o`n57PA`0r|@WilPZQ)G?+HuPa>pDB(|OO>y^_LQY+7-z(*zZ+r5hPoZ$@GN=aj7Ps8(Gy7NQLdwK z$khpa2H!y0%)dg~Lj)#LbYq3-op5Warj-R;p`o(sCC46nG);hC+{r%a7+42D^##8e zAfGzU_1MFKS;|&tn*0bZp93}#oNLK)%#i2Nex9ctLG%aOIUH%QB=Hj%A7M(`Zrd^H z#`}rEH@T`gC~lDLil%{>x>xsyto?g|nyS~at@+{%3&)c^HmUZamt>TPMC9dBUr@Lldlcu5r z$0y0Pzj1-8dwSg1OYAfOa(^ok*(#^L0dd#rJsWYhyzuOr2QX$@Hx`oQHmN3HWM+H* zLQr$}hsTTx5Vg1CbrK-!>#qByc2Z z(C(@bl3Ghb6@jd6ks~CdTK)l01zc^vk;(K}Id2u-*rbu^**<5N%zSc%4q27JlFeo1 z-ufNnp7gKvcIF*}yP1ZE9tG?2O|{5+gLxxbL0W~i9_3k3yb*fW#y<$TCP+SeW;_0w zXIk-XF|z4dh*1fClDO~E-uf1NcZE>koQZ;@;ejn^W*=&FLcaEZ6XkX@u&Us%m04TR8o7U%Zp}Wv%m@;u=bFMC}(@MLXp(s7-ymw5XeFrQ7F( z1;=6RTwroM($MQqXI&)VXVg5%F-{q(oS_0y)EyE6bToGdvsT$M9K-$Q`Fd@Vb*ZM#IeE! znC!#LBF*UZ+FnDKXkK0V+qgj3-i=|RQTe-*IBqpW;7&}g+ zFI@&Um_;S|VeA;2d$O&Dg@L1=apO>L(~v^v;O5v*$yPbVV>epJGX*+uDW&6|`31;D zI_vicnWCY#Ih%f+H$MaZ2LM|@q`z$)cUp~(%mqkgLer5vWsk!p^wc)39K zBTq5;!m7vs<>4+Lyrn%eBrYWjUht&|e59VwvO3Tcw0PuY3HSu2;AS|`|EpaV)HFWG ziV8mVA+9ZBM25@_5ZHgUfj%;%S{{D$!M_p{o#+uN>}7+u)ML-iMCnJtRpvLYJJtQO z2uvVUr%8pI_s=5%c~+Y{_LT?kMv_RyI@^X39Py4u;Mfw+o+~?bzEp_HSQ7p%<$ z+;~}r>=4)oc|FB3rXVDah5$bb=?94HiwhyY4Qs_2X2fpioQAu*Ss*MBvT`%&HfG1n z5J%QRTr_{KmjB@Qn7snzLUECfbY)4=Z`Jn8e*R3s;U%OTzfp4Gm*J3)&$lSu5_rQk zvDC;kZK$YKHbk26tw4GP1fdOwnq|xsZDOUvkYs|cVrPOJ^Dx_Ty9KGe`+WJs);F3 zT}Xmz6b%~dr9n=DW*7|yNYI!deUL5^NrQe8G$wPKroySvM}#KyW}S4XCM865X-ZTB zq^K@Ki|V?F5j{J?$WcBcTSSoL+OmKo{beMgwEk>FX?|Ct1WYC+ODeh~VY(CVlBRSf znuItd+PM>Xk~@^2Hs!O`Siny*Il=dUfICGk2p{z;YsTrE<&As!IrhP^Gi=g;Xk0Q5=aba`knr7k(Yoqi-%F z@+4Pdf`Vy;6$uKG>(HH*73^jzwa8ySAfrVo?&o16@(9ukR571Flxrnf&MJhR^d5)A zOhFO_$J?(+%fnI<$m(>VE+PzdEtH`yPa5j#w4o*;4s}h`p{|`g)OFE^Bn+%hA>1`N zmPXJMZyi(uaF(Z&h(RW!6nAj3wBmC$yaTo15Z6sF-ro5rCON@Kd-00Y!adZZNd;Xe z?@TAy&E<$BVqgg<#2rwK$K91U}y4s$;v4S%c%*=6&97l zLfzYm5mHV={9_&j?PiR*CSh(h7IIr_gXU}FdB~fZzQNKq3c}nKH)n9iP>eCWI1;tgiunVVhz|_+- z(CQCPv{&!#(0p|N>9sL)NE?%LU?`@cF}oi3gZ%XTZp2RG``Zz_GqVn%WZ6@DMD9n$ z{iwPh3yUeoM->fc_7amrBa#?;QKVqE+HAK^+URvAg=F;r;q{#um;L1NL(xf0-c0#_ z(wS2#WN)Ten|{H-jkzh`6LSz0wquIT0Ry#WQ;}{}SSmDrFd( zL;395e{C{}&r2*^`zirj;B1$PxqTVZrAX6B>5UDHLF$xV$Nk>COQvxu|;Y`8y>tb_NT(lU~uzcjee0 z-Pkgw{3`XLIMi}cI|#Mj@0FIjk~3!$j;0c z+L@1nLeaL7X55(Lb+@yjQJwLIs)11t76&$#ik=4;B@NT!iKuY!@Liu!Ixb7U@?xTVGcuyQ))3r-qhRs&0`pdgOE4QD8e%V%zyihW8?q1?r0J5$nB!% zl-hQqTenQgB9s8NftNT^U)o99ER2YxVLzDQ6XR61WXhG&*w48HQ;sZVuAM| zXprKS68qdg`Stzl<}s%C7=O9FGDcYRmM2#bKKr4yx>RH4FU=XS3>h7BBI72AGLk?d zKaR_3LT6ApSVUJ-eV8CPyT7~--}IW#kY&PQRsoRt=ZJjhZJ(%VwY3kP3?mQqk!@*NAvhc%7pkxKEVwUnk04VoF?+EpBVq zW*->-Mj&e#CW3hUd!zBywMd54`w*Kzj3>ATy^>OcU5>||bYEe&Xjs%+>1K@QN=x5! zMu}J$kF+n~CN!}5by8{7>TKuMjlS&Pqel}r;`fNGy2pmG%?A>0$%gsMFhp=CK z-V{*m@;*oy2dOD?!_IWr8i1TLQ;G-;GLU*kf2}?B}}I0 zB+bB!FJg=BO?B%UbKkvjlI7v9d(wG^A|zdUe`ck4OeU_@^ROBt2^z^Ll!_0-WKbf4 z3uNsW9S8V2c5d6h?0iF7%xD4?971=ajbRbyN>wg%2{|iwGfCR@wX4zGVHJ+OapN(c z=!iFB@;ph}0(-VbJ=2`d6AQ>jy>tjSl1un%NZV10#u~Az84Ip!KWXtivLegZ;^iG) z-QM2fZAWMbT7H?Q7F~mj#A+gD5J38uP&z?f?^epI^s83i-^b{v-PXZ-!Nur0R{-Ph zHc~0jW=8I%(090;bMN?8nR^F3V+JeSyc)q5keFZ@<1TAVLDtQ^v#xcZH~c_Z90~Pf z%nWO7BxUB0rREcH@yEYQHNO6U44gleuePQGgR0Nyt;e*Tv32=3 zP!VAGJe6D14|K~(?0#H7YBGPC_vf&tDdjodZQz}oPkC&_lYegWgChTt=X3jzP2}hl znK_@cZQl=&us5mZSE(YWgJ305kuU$t`KYJyl6GB6+)eo+BkQ^;CBO2nzQ*(<`oKFt zXBfU@SoSEH1X0f0V|U~LLn&T{E2lQ*3KA_+e!wf}fixniwm*}g4Z?Ra z!A|5zdH{-r2A8vIH;K6cQljbysVUC=}oHZ$Ux2{a~nlOMb9MjlFn$cmzctj_ZhNm`c1MN+F-0CDa@rE2L3e{Ng zT&}?i`Lwn5i?HxZf+l)z`;o4xa!4!Rk%T$xLL5uc>*ZoXaaYMcG!>J@ykj z>o!upUR}>vx{+bZ?ru2;MJw!JY8b3zpEMkd=c7KctSsy?y=|y?0=3K$b>Q>V zoI!W+!1Q3MkFvcnXvC-Jv(#rVCiM3gb2{Fh!&uM)GuZCwFSFDbg`Mo81}%Dy0Vpo9 zZTpmCkK$(b^bwmHp!>q+1xhuAssMhogDGyueI7{@9zieBG)^oAHSzH!eL>9FlE&%$ zVgM4=q1iJ=7A0k#;1f{#`!E0slW9bbevcU@yq_|GR;E&%&ooFHbiT@CNMX!SeRRt( z&686!bfoTpkabei*W-!7EeJ3k9;TC02VTwx7{n7T3K&oeZ?x8r-?Mj^q5Zh~e$Pn< zY}^nzv!& znA|R&B1Gl@lxUv9cqU;G`qjEb<7$>!(7zYgv)SbN&d%r0pSM9J-5yV`b_N`Vwe!*q za7wXPp&8>#&*0HeF)vqaA1D+m%rJnEXps7HDN=h+^y!T9t~>KflL&$>-~v;(LS3&I z&lf1q(5KIc{7B@-Qdy$R_nQZD76l&>1!|e+V!fP&OB;Eq zlpVO~@lPyg{FmjOSWQOndd!rUPgSNp-VcF%6~!Q7zM^&TpT1B~o#(*}JK0sQ!vVG$OgGaZa1Q)~+AUziqkgt1$_ z*Aqd-2F4f166t=%v8Y2Gi1n@Lt~I~pM+6embYV)?`6(<9TLwj*0jJ5qY~Ww`1EWhl zyL!fB3to+2q4fE5*xC)%9>L-TYEoPIS8r-l1?Y)5SIeSRI2sZX|d&8yX$3M%| zb_3)^{|x#y<-aZQ$F%>Boev|K5N#rO>=71N8aZKIbRrYk_ND}ibBo9M=fI^f^c4{9 zW96CH5I6kgl5!P?uh^~fqkx}KS0zkdnYh~tmWFF$2pTgGhzZ!Fsu&z%4m;7t<6k!R z;9Cub0QF(tz?bu0&oKH%KZ_B&aL)SU5zGwditvxvA{w{_AHgkTV2$}#5#Z}H@n&3U z6h(3h`>i#4hE7+&uQNmv?3si8XZRYxOi-Qe?_n3Np@rer%il>&IPPoU_(QPP0J<- zpc9G#4m&Q1Fd!KL+OJV6g;IjwkeEXI6NanAPU9Y=0*f$#*?UI=3fwGtL9h9~v z$H5&p%b__khx4H;KRMf#n3!_G*|3JzRc*tGJ}&s#M#_y%XxCBHic{$)b}H}(Q)2VO zZ5x`yA4goYvu>@KF+`Y_5vWXaEm)h;Lvb!kk{YK9z}jn|Q#PM$+dC!nhxSTLl%Sop z4{MU_g3m~JNg>CQ-{SXe3wqNtV3}MQ+aqJPlL988+0wEfmMsU_@1aHBZB58%ES*XH zp0ZPID|U`;!GHg-IgxXiKy0H6b4|-zCO{$o*n*VJKHx>~lYV79-|&EV@z~$(9lNcU z-jXdKYFu*;aoEtgoP^(oMZ!JhST)gcQaH%KR-dd{1od)Z$zgFPP{^J@=Y>dLVMG1H z-l+a?x3ATZNt@tO$ix~uNw9e*{3XW_51jO~{zdo;|Vt z4P1JIrUa(qF>r%zy8UBI?*^=$iB;Qp<~-Qed(Tji0zC52!a`^#q0w7x!&z&=kvNM_ z%-yD!P$W%?4!bFr1cq$9pi|+W|@ot3l5BbTey|Yh{w)Np1yNA8-caAgI)iEa~Z+lq0OXqkmynVAd zR!HB5WGNy&-suauQVc=IMLpLEt}XB9-p(OUduF%cay?k+7pSSCpVR_cq>5g2lDxn9 z2MYTuqEu(kwr`(N@3%LC0|(9Lvko%MY;4=O9p?OsbdAKEnYy~;-!EWi-~0pj_d9fd zuypt7r0ftR64bToBYklD8_ZzTP;7C;-*;PsTDj|PrYK)Hz6}x;0W|dKYT0>tBf6D* zYV3j7vm?f5>y>wyni=4j&rUY5TG3QECaInzVRO`{==A_mzr4glIH5J_Xt;930_f&k zAB3TV)@T?~y3h%{lad%8GhV^JzoW!rP3BW`JhvR=kljQyP7=n2!Obb-kp*l3Cf9(j zdjZWYZoa@nR@f+sO|o>o^=p>xpJiFA-TD<2D3C}#Uz?yN(Y|?W577(CKVA}R0A2$5 z1xf{$<1)ODGd$b;3I*&5<5n3T_rnBtr0-tNr!?u;AbJf%6*Ot`6Gq~a?Ph)dsA?k0>?clYi*757- zZ0A`plBfNHrPb_XEblyn@-LsNsP}>*2i!%U+4MTa)hAmISlal4OOL1S0=fn*Qk=zz zz5^8W@g+4di|VuIE#C}E;aib5Ov$Wpt z=g_x?J;P%cBZss>4`6e|(|dFb98T~E!u^K7(QjhIdnUBuEyOJ^Q0mF^+uW19I>cZ7 zZTR)ZSCT&dHXa#J_^jK=`(6VthZo|I3Ews0!NV!<(&xV?@Ug)K?XX$MO3$D!q0$D!r%aaj4&dbjZ=Se_n3`P47ApIhs=)%_)f05sSExw{Mp z)jDn*p6xfa{Z^Z8Nagv{)^Vp>KRm>@ziea{)bA_?kP@0y`tk3LqxwIaTH~zUZXS2F z!&aw@g}%~4>{3bui?75?${qM&>s7nne$TMb^XIsHGya#YX2dekRRTHvOm znUy}_1snheCuhg|Ovya3&%Yo4$B$Z1+5pzc8e{mss+JU+{};<;1^B;ODOMi%|F`(D zxe-l1dfC#6tiyI(%MJ>DY1@A02nfu6!hSh9K75}^fxO7`uhR8lE1lb?t8cdZGv_rL zS5;=W>DPxRuj+?*?0MR3ci*$KP7`?0A^J!&OmH4sxB(kc{dm9L-eHQo)@cH_ZED9Snh@kWnG~h!PD_lLG@?VE!>0Mg#EWu*gNnp9nn6#~L-hIu z$$MjiUkyY*_YC$z`o`D*%BJh5r%hn2#ADmdf1S13&3%bm59MxLruoLudEevWhu#!>jSTtxPdiMA{w9af-P76n9yv0#EeV>kw^<^hJG&=qOyM1}Un z2fPBNIgY{U_Stc_b=0JKjryr@DAM+uUD)_rNGymtPd}l3d0=$m3tQkoH48>4E>g6$ z&e`ed36e+);mR%2^etP6?O21-sg!8YoaHOGSxl0V2d`&t(nIb0|Q2OLb2 zdFP@1oh*&c{Ck?U`(;ytL|)?W!&ZIY`#;`p(fHAZwLSc_-mNii|5wTt*#8S9wXBx& z`4aB`#r%W+?>G5rG!MIUD~Z+EzfnU+ioc|9z@Y_Kpod}$<)S2A ziwi#H+1W#0@cSAP@Xu4JVWVe9q;{T+X6QcRdC)g{p6|v;`pz%V(A63LL-L9=<+5~D z2QLG<&$LgbWl;vhtNBdon*G>)GSDXjy(e{TsL!s)6RFOy-;>G@FQ=m`7>x7;Z>_jr z$Cd}r^lW0z3WoW9DtBQ;wBytq4$|n{-zl9qGUw8Df_B8Qyv1&^Ue>EW(VK+ z8sf#h50MzWPlx8j;&X?eri$;4hiJo#IGqc9OD%@J;r$MMb@SiAb0jfd!$V*A7)l48 z!9SX#^0s1N)9H@W|V=TSFipPxoy1PboKC|s)P zC91|;tlBmp2#@2>{yx~pqiG520$)9BAf;He0RL4m2IW4MW;~| zI`D0?{pzIC1Yrcjair>J-4oI;xbu1ko?G*azB$c}FFt}2W~J(l!;?n+P^%yD+x0b; zYq4Q5l>%K|JM6kDb`8_g(k1VKo=WYbv9)vdifpzuye7$`+?<}eU>>Ju`6!OqAB0=U6rDIajUS=jh*h z(E7ExubrN>j=QN&>+qijbvdajAW%k)B?6VsEPr^Fr*higB( z%J|l7Mh0@Y@9Y<&aSm_Hp>o@2_63L>`6~Uw59hk}S>G?uohR+)+ZLUjx{vCwo4uJkgyYyb3!6cLb^!_HW8UFO*iq>vXDj= zQpRF>h@%2$DM=d~s1-ZT^X;Bo=y0F!Ev|ADzRjcpi_ix@@E+R5>4sa+k#Fi0P9ku}r6Ipox1$0?Em%{|QKw&$oNE?ZH?mCUyx~ zzH~~ExMP=)B~GVAu%FJtj~l-$XDx#Q7qq*k>@GS2nfPoEKeMEay0Fm*k(K0qsd6~a zmf1!kCJ)RcA!HXN>p;U&jYgn^R3kqOzUxbPh>;Co@NqB#j5V|{2oQ@}gCbE)VQsga zRk67M^fLGp!p@>0iDFU1vY{kHp^%&wwP_zQ_Tr%=Yg33}i`ukLF?;b)?r93W;Fp<3 zI_+9CHaw8+#nivAQMs^}8ImpSE*h3yE^25FoO>Fc5B@SkBtd=A__)EL7YD(=1SAXQ zS*Lq)q#d2?H#=cwkS(tr#PLu_U~_<~QWcVYQ~n43vH9OSvaM7lR3eebB}T`)hsPYO zX2-VO4ywN)k!~YOZ4Zn7$IgKvo(f041n6J;sX|5+N62{6#o9PUj=-hT>dX+tzhpIFhe|iWbeuAhHONF+WiMf>*=HD(C_BX#3@8?&(l$)f%$Qm$RbJRNPRYyl54Et>Iw#dkSVL$m z%QP1lR^nPKj>_A|#jRL_QEVY0^rK^SL>I1%ksS!VAfFQdZ`4tR-LHX1T^`v%PB?d%%O zNNM*hK9fSYgl7Q!%Q?%9*amF+&ZsjR>;wDb54LPiVaC=4RvJogVCW+UZZ1h}s)BW$ zJqSxwi938{1wRYWN!|LZLGaFC;-h!}XY@w|6Uw|aThs;esuqBmmm zNguBRi<|bGn0fpsJ95gUD5Kf;czf6S=!&Q4!a$Gn=@cVg`C__Lcreq6;^S1N_*3?s za(=OYa7)QZ0Tu?;;v*2TN6`mEq`Ik%#u#@7e*3y3f+E^c!E&Ns1AT@eNyX^#rZ@$m z;Wz6kTBJU`K;p2 z&T4_^hMll5FzGGM43A!D$2Ov1r+AH8@69*{riL9H)15t$>5cqeL@Z3aTaKf&BV1BH z>qYbd5>5ry zFirx}ZsTbG^-2A(BS_W6Afys zKpy}vkC=BTzIFKcG1h15OSaQDZgxg6p*;Sa-3tJ54nT5-4~~CIKDgEXA4OVt=Ho53 z4H0;8;~9Gy56nTqrRjX!UeG>l4m=d2Q{x=x#@C4q`!JPwiiAV1VJ=S9GE@+ zC6%ICe@-E(aiJj*Q3ODwqcA>0es2zq3Rb_Ja%ciJln6Y9^x8!k)(=Af>^9q{Z%&Ti zKWA}*3W*a;77%bmj&ogqY*1{-{#a&1Gg#}yhG?N!Vw1`8_0^)-*BIp^72(41WZSAe z5uO>(11VAXi)3|!j&wdXDaC^r15RcPuZm%3VaZci5Q;D|)MqIH&kqioO8viuEwEnz zt_lFP(>m(yzpxkV@e7=uU!d)Su^TKnCq-c)osp%D?W^r9b8^9C+^*cc@zlv_S35gy zbu~QJb&ds+Snue#V4R7FPZ9ycZ%tYB0LeFgQrE}); zI4z0+!HNt{t{WewD#q8gcV^I!PsLW$$YxY;JL-al)R>mYcai=?wg&I)_WXDa^>R#D zSoY`ijz@GRW<*#bVoY8)K+m`E5qgS5^*wwDcc>cTgeoB+&}|Pc$Oq1`rn=<>Mws9G zmt*L@?*G|lw{^vRN#_5rsAUoVrKsjh#Y&m{|H}{l|KH?iXOl_uzHO(-!r)VsvDB-^ z-bzt8q3q^PDg^*ui;Kc7^mW8CuuTsQ*pvEL;wSQoByZu?@xh7q>OGwngjMXtS8Gru zIRTVhP`2e`IZq;7y4*mn_LvpPtrhgzrm9JDxQ0NH6T%W8H(R+>I*{C)iaOb)f+d}# z-@J2pe~~)W&+)Wj-ki-+ea@Qpo3GAz)rOrq$@0`sQ#^FNca2_}jt;7`OAOb@(;KjZ z)3ZzfGQT;1kPkxApUK4qdQaOYzw+`t&6Qk)r}Y*?M2Arn^%Oh2AqB$2S$x40x@}*- zWFk60oia#}_~vnl_d>Kc1P^(rV+k}Jf!V-FiVV}kZqsoEsJN8JmGKO#{0jV|0A$-q zd|^-fgUjA%QAhU=4;sg!pRv$jri6EGJV2O|?)y{Nm=?qQ4`tMQ<|yw0Sch$Uf)|6i zTmUeFvklbd$nNM9K&>DJ{PM1puaJ5lB#}V0x0Q4Nq#(7~0mf zBVsn%o0F4&`oL1^ocTqLhgcosIRxd31|p(_1hA7~P;}`4R^meVsz6&=~q-f}T(rnonZb#ID{r-lpwvBIFVjt^VMO%E^xQfjUOrMcfZ z^?)g_0_CW=->S=Cc&w5YAYnau{(vHMo)Xhdd1^82HEkf%c`p(oMrR@7aK;!5lMjAq z^i4fEXm{W)?4B<}t7Ri2AxsAajQ}9*V`Zn#qq(qSj4C6g|6Bx=>u}!AUSO)WTQ@bp z60q&qG4*=8@upl%+=PGf9HVwj8zEB|=y~}3C4n9`i+=F_IZOgKgqS11I(SY9)x|UA zW})K+E@Y2+4L<4z)wk7(gKNCk2ES zs#rkk5|Gq*P{nO!31DbxTCgAhUyCUV;W{f>pe-6EqHZ~uHU?v1s>=ga7ehsaE)Ca* zS0O*>{XV+-3&}yw-^KIoxuLY}@bDM#3D%4(K-fnRpb55{7&I)TA-eoeSy1R?Qx4G` z1cXV%V`1O|mNGCcg2yG&5Qt;=Xx$DkP+Gc19475yx89EE-|_X<7*6n5_mcew1MGv!h(}9gUqJ)WcuMCod;oHvsjv?e2-YGSxkg!R zobS&NJ|03nLt@vtzf8lCY0wsnLH}XPnPqt%LF@qev_QpY4iMfi%Srdgv$W!gFeSnx zv(-=LC3R5KdXvH2!hd$3Ih@o_!Wtczd0gc;`oQr3;D~*ONiRXD2Go2qZa##?I6aO`vqVj#TJc4_SHyYciBOfAn5MhwFou?}p# zjjgTcXx?z<&Spzm+iq-3Xx20vo~C8(46kGcazfTylktddr4e9P@C2-ZJ~JUJ5`xx+bLz6O7}8M%_~X{eihiS=Hz<&WO~I8P?RJK42nzHhcqSp1f*BYswW6*&Fl)taEbEeOGTc8GHtj_-$*y zxzAp`hnG#(I5~aaZoPifWp6}`|N8Mh`fr1b{OYWG0*Wnw`Okmq9jN{68NIC^zh})~ z(Mr<6cXg_7NqEHxgi$xaT~ zQM28617Afrd1~^Y)jh`M4o=z#s1BNZyW47<9oF0I^sIe~0Sa-1`>jsnu--aq?r%dM zpk3B{+dS^F&KuCYeFHvucibdsFa~+R>{SzbipTue9F2Cr)owPrI4t*51JDSaJj}Ar zX|vIS4+yLIYZC@lZ@hg5aP}{%`C%PIoP&<0*HeWQ2fri{2aD8%2V+LfMU{ad{K67F=vh3ZPCcJ7RdI@WFM2Aqzq+-w{ zAhRnC7U3K>Umvz!H;)@l$^?Lb-nBZ-3`}0Dg9(gUyzzH+X!(rBj*|v`;~!f@jy6GO zX?9ubfYtZkwy^)AJkUd@CCG=+*LWkaznwx48PF7+!$La`20RoY$~J8Gn+?b0;Jl;r z>+$yWOYb9o1T8%qn7|dSKskQ&Ej>d=QGY3MTr539`#FDd$u6dP`%nMJ<6b` zwRn`)Fj3R%cLi0`G7?1RXcmTuK@r_Iz*c&O#k(%F;VWY{F#$UNYa_+Q7mrA`Aw3C3 zv)D*E;Ew9QYN+HifjX2@KA-WtIcV3>_F6wWW$99-oTp1nGrHC(E)JQ{14 z^WT2sIiwknQO#{!{5C0+0UTXgH|M1fwcm?XkOQ)65q~RX`mN$`eEgO2J|awGI?Y<2 z%t>}KFhe-J?Cm->I6vQ#F+r; z(1)G_=l7K70=T?N)IImz&L-V~!b=#)2n@!LXXkhTB(jgNdO!u zI8?*bEuw~6DkZArDbq(Q=lE8@kc)|_+kiO%8kOIOd6$v@HATM!H^4?~;ayQUAkN+* z@G2lU>t7U(T>lAHjgFo^HRAp|f%Sv+fuREg`29k~-vWl0^klw0pL*#I18tukHqb{= zM`E(B?L{sVleC3+m!3U`EKmP)mXc+#IqmSiXBqU$M_3ZHM>V%-B$Z(m&*Ga6oOWqh zzixK5!+NJH7_hc~)~=(Jn0^Z5&19U#AJ+nujO$DQX@oF3`LY9)2aj9oLQHZ8i8|gNc)hUuc%9E?C_rkH`E2Qa=9K%I@I=jj=hpMzwRv=>Mj-{N z{#{nx{~FUV1G)BUcD>}9;&Ryf8C0Nm0Qxe(IN{-WUY5V^(Cz$!-oDKH`-qB{t!1TM z7pe?uU;O*)*)ZG@0sG zL!G^DG+5u%uSR1Fbs8Aib<{f$pvO}Xp*M2xM&l9kBu8^y4N-XsM?b*O$CJQt7EPG1 zAg7*3oP6R4ur<2T2cYZTX@$rv-K$qDBD`Au4h+q19zEwl>Hn^MkWql2mu*s>lg3p4 z?Uo%h8w}=VZmc*d@pJNXPI<1b+{3m3f;cz92Bp4*J3zbH0ltr}`pre`UI^Nux)s6% z3Hk%06s!6GLb22l;!_-<<2mY#Xk5?pcv-x^t~y*UlI|-D(&6GSiq{{r#+QlF zn;CuA$l<8_$h6HDFI3-CZ0amuj_|kD5uTM<1a_A77}Y^4`Z#)x$;F zN2#rF#V1gCsZ~;lUL|>XoFO~BH10?S@=XLHNhXpy7*~98hYnh3LuuEKUpJv2K8sf- z*!rvn93x-|^H=m%Lqn`kcs->a1uSZjWBD3JU6J&@ST`niL7`=kjqnf~vzA>h@2d0N=IlX(ReFd8JDtQw5{dH;et7l%&d4DG6W<0_( z+!3Nyzia z_3N5RS*utykqI=gAABB@^JX=a*ipL5FQdyWAxR)TsJV;VnSs8Zm*y8*`&>3=1u~!l z?PaMPzx|yq7c*XQ1G?iJ(nzEcVj=%zP9{j1Lv#$bbK9X&2rJ9d6;e04_Cpb)?=erJ z9ak6(GkcLNFo_A&wtq4v43ub89#1AtgOZezmz&}OR8^cF!0SJ1o+E@uULBTK@$R)) zH*g|R%>+RP!Eq@lO87zSxSjE0%_mMx4a#`VhsL)PF?Bne??j|A$}gznbxIU}h3hq^ z1G*U@;=ElLJso{bDEQ+T_OGc;tgv3hH6jE3Q6_ArQy3(j%26D@ZHM`I4)^HLLmXLs zsQs>#vnn3!W!37}y|D7~DOzu8*HX&rZeFRDvZ_*16}3>RmgiBQ7sDMO+ycNYsMS)r zTB#Iv=UJs#RZ11LTvoH?-D07XFIGz7pm0b7J|qN^&la=pVDKfrt4SuSCq-vwU0GWo z1%H2d@uDCd__*hSF2T+`@RYnqP8O;_sZ=OC+JKk2ClVlB;njTkvKo8=Qos3BlKb5^ z1&=HO6pA`C>xfi0CJKztY zvL|X^u=DIJE7O+CRRUyL2x@?XJ5uG}n4tL1c)&+>7-H$dwk|Bd{ItjCEVpn=+jowb6k%ge6~h@aVo@4~vMVdxwE zeW8dCq3dBCobKDNp4F&^B*{cnvxyEU;e<2ul8!vzGd`Vww%^qfOsS)#%hrIIWf*;4 zNGaxvMa84b&j2=mSE_ici`rAJouJF|*HFFasS;F+lo*xhV^Ea=!kpQZDZOofuC;%w ziT-=ua3WHGh^YVYPNt(c0aKdYS{&5~xGRzkVa@yyLpAX<11d+(G6qC?J_2&cLe?Rf;#`?GG2=+X^lwCH8Ug_2GD zb|cm%w`B7dY;0$n2)r>yHyUm)?v)#OFt_l5;4{?3OEv1q2(RdDoLTyn@ti%e*!c^D z_VNQVXzC8CNxqW|MdI6bbAqSZ-Kl}}1)tL!on~`?!*M|8eNi$dmCHHs3t4X_%ooOF!8z{+hx0 zaXOLZqx5*;vL}oW!r5;GhBE#}ncM`!^Cz-!P&lB`jX52U@B%GM<5bq3SQ*;9nKT33 z6{=&*sP8YNc%XYAhd6TH8(} zzH4JJxttH2L$F}wp?=HU12P)|wuUP-E6zYsrGux9!#duQJZXq?v5;$VHWB-Wv;m46 z(a&DY-fM$&IRq9LOu)B=KZNS|*6|-Omtt>Sp%EhEKd6dQRw};u4~4R-Jj8!^i2v{q z|KTD2!$bUshxiYF>i7?Kq-5@7Mv*>GTXwEY1I>YUrdocRm@mWQOvzISRa-8Xw81Ma0FKkUn#QU|s+(!Vrspz-4FN!Zk?MF6Q{K(;`GA!Ew^G>I4COh4o8x z6-L>ei!KW1Vg{ZXc=S<6?+>Qj;9o9 z*fMbpQv7+bOXT+7)(>B|fsY{-kU&2lA;G{#f>^%-C999ASMVk_L#+>Ec+P}^=Y&(f zf-d)XC+7(9U$VCur#59W#%wA4C2-{Zboxsso4(Ct!)njux!U!?=XC z9u8QV5GQPEI+#8~4$eXk59+N$8H<)CV%BAP}w3M6QU+Gv`y$kH4sN9`!UdB7zeX6%;p98}z`^PM*Qd*mGWunXP7+%K@_6DM~Z+Jh$)x#fRc zXn0_Zhs7_7dp-Xtb}cG&h~&hPhUzutk3ZnIntA#(ZN8|f`C|2tKg^d3867i!`~hVi z)s&}C;Ww5sAJy`i6@$Y#op{pE)SmR&w)f|Wb0pWxnpyK@{^yO2=NtIOy$*m=x3wi1 zenr>@+6#fCoCx0h1d-9YaPLA!VT+%75WD%->2{rlsmWKQK=&F;K)BXo+~#v^8KUoheB?D_V2dnSF41^gwu_%s}fZ?@wmc)9L{%}7|s z*mj}`mT4z)4_93guobL?V|-mPDk~!U{`h zXA@zZwz`cs>{_=N$nKZM6c2ZeFGi0aXH4|jHJ(0C44wjI%#RA}1SMoU!SVO`wRLfL zngBV}Z1m(T+##jC@ouxkJF;MYUgqh~i=2|ME5hwgbVvAV31<+;N3dK#w^jGXlzT-g zZ}-LL(&vdMVUZsn$jK-fJwk!`PlG2H2g<^cDu3#c#;#w!_O|1HmKI7vJe&0Be~|R2ps4F5G3BlQ-9~o68l{N_qDiG=%L` zzr}!*Qq)Azlk(0O>})@bY;!fZj2op9e2!*ZQHhO+fK)J(n$w9wr!)+v29y7=RM!K z-x+s|`)Ai&v+Ai?wf3mB_o|xnnXYEs%NmJE1)11pMU6-9pi(Rk3!9n70)VQ9m8xBH zx?jhN8ZEp8UwMA)(-}8AQ36rUX3*_c^QejC93_%}{AVf}}={xg+JH0Rd_-YL?!M&D?;l+D+e{(;ad^kh0 zCY^{qTA$x3x!iHy+tcx>;zZK#qHU9hRD?Z^bknhKmfzTZtYrDn@$u6dwYf0M?Teb; zW{*#2(mqKowEO+6&czBAkCO&Z&j+pOSrGSL8h;tpJucZhw$rLa zid!2JGZOTMcMU1gH!a|pAzOTuF9=({1zo zh;>}JHk=7K%P)GWVm;_AWG;Jli$!_Dqb~RS30|DkF#<^f|1rgWmxE{*&aE^d=K6O3g=dwEGk;~ZpnYvYV`2A_BE^Pr zjJL~5wVLBMI5UBHs*fYi2*<}g)!*g}b&2K~>-omRHH4H8f#7L$s*+7E2p(>Rx58{J zX<7$e>x;2E(^}zgT{$#adgD~yFVQ=>1UosdfeZ{=`=TwzYLl0^cr2m4I?p^tbC&O> zAIJ02SgiPd#!?{FXgXYz>sxI1@b01W`jq}}j@L@z`V2SM8xD@&Y;D-{O5bVUz9Y3# zq+Ue`bKO1-)c&*xBs4^w$}VueCKwh%7!(#LpoTv+7;?i2`--}bbhrz&S^y&Wo| zb+x6`T9dMLu^r;Z@kfkrV7h-o=bkQ?L%jzWO4{}1R?QOZ56I6v<$LiT=JC6_Ro5WU z+8}99vymrt9VO^)T-0!@kB&^-Q>swX#|WFV@r*t$``xuWA7QM+QvE2`1tbwHlleGj z8jy_+f0y1C%p|nby74Dx$$4Y0AE{)n0U;4bkFUQBS}U$8QMl9JA0E=P;zT?^q+>u6 z^O#!Fz;ruAq+Ba%Y$A9IKrdPW_to$R8dR&Gb|-g}{L%+taqhpy&mo0Jynz$gKt-_> z@DT-lCwUY=B`V>+8V8~OIFSm%Ti_A-=?q__;6x^a88P~{P>cN=a477M-u;!jV6Uer z9jU;QHRLxOs_g1?RMX+Ak~4&|@(bU}2EZlvPS0#jG4$s)h!=Q^Zq!UPsE|8CQq`%W zg?(BFR_0NixlDLx_~t0Rw-|NPN75bT1FO zv%j#SKjpwdH3_)3a|agc95M;gb*}Z|S~V7v?@@olo2h z*Y3K7RqZja3C+4Y3>~zdrqly;tejQZ+5%nD0*(_N>yK6h7KUV6Fr6RCGvd$mkEw|| zuTtc=Z?N=h45T%LtY<-cn9J$%*HN!qsgvU991bJjm5sc>Eq&H-cE7E~%ZuS{J~h2D z<-8QwPeDW9$lA^NL%)fxm+FUr?lS}jx^6V2f!&I4$ow3-DsPs&yuLAaidH-lVE|Ay zj!~VC&HmnV^nKN)jK=))*pX0IY9DP^@@7X-?imz2xx8Rt_RwMcit8vz%4k2ezD+H= zBlg#!lHBnt#K6cIiF*~5yfMO>%DT%A&E~PIdPAfM+m`2zP2IkbErV6BKawT8>QYJ$ zhPd+8OKuOo>atue+4@ws`uyplhPGW>d`+O2o3=k54s!FEPnzhZ879m&{POSDxmb;Q z6SwS;*)D+|x54KDDDxE}+WF57ZSt&)j^+qdWs|~9Fx9)p>wPj9cX}7~y+ASBzYv6h z%+G);F}w@W&HQAfsAhb1U_zdm#l=45?j`~(B6|`VCr2cfhZwXJA_z+$j>et|BATxi zjxu)!_#gZ!??sz@`Rafbv&FWV=rZ)M4|b?D?0v#{lBJjgHJpeQ<)jj&?l1$i(#KF?$xnx1uD6UeyTpUnP_6N5c>4j4 z@L<^?RLI?*I~WK=4##7iB=^_Ge_!ZE@u|uPssLIvD>gjy(8P^~55+eAU9cF+x)n}6 zJDKS5nYS?O)4oL!G)@dBP;*qSn7_5e)dGdZ=7)SYcyMurk5azbiBzE9sBDT9g=T>W z*`eORI;Hc{nbd0BYHkL}kSpJ4md%DTi0V8Q!hikSm_kHSQ9wMPOW8q{kSq_TS?fes zh{lthWyS>*T@os^^n>tY_^T-QRTf=kj*!J^T7Hk_kU30H5NPV_5zW-(9KzPC*oo%& zcxgflSz8ubD_bgTU8=X=l4J%O8#%kx_`#ngteNhM3*GX^rC4^3g4dmnFVXg6HyT&L z#8Mg3^w!t{>d(=$F3VsKAL_K@5+sI;$#!uW_MG@QML#~9-+K}#DPK&mqzPLeZ9(nMF1!pkh4xK9;^mqe70!E)G<0P8}nC*FHYGveWcxiN@vcgahbOP0`g|m!LaMe+W%(fmHD6 zQXR|IIRg^C{th!P*cd_)3}wQSY=U1gP(;N%Zt-cUv&UfWa|-LsI{O1rf9)0KU(Q9j z5KN@mwv?c{+7-ZlS8zOgqD*RZ(~H5|q^Ei^ z3W((!1CFfUhmaq}(m2H298a@9ph(Sx-pC_Ji={Z@4tRT%SO0)_E3eg1DpV^sD&~>JS zhyBsDMEo=%#NWf*gWxPpV^vmM3^sGvIrEJw`1(}n@LQ1!cIE5*^Fb%obqXtXcFS%D1cBmLT$5eYjX9ysYxCw!_w)TWQ2Rwdi|? zg+2T=oal^QQn%?i<$TiI{M`DWGun5~#~|?-K!%S)MaVS)yZKQ5c0}imCF6s%dN?|g z@5`}fK_^zV@i@{AjS%uPr-Pj@K|IX5_@+FbpYq&B(7bDUyJt2X&zyW{gh{aHwPMqW z5cA6e_ki-WUE$BVBTBL`b9YHSP&YY&G00Q)b)u1 zAvu|cnrgvgGNk=HUx2yZkGtBh^j&Yve4!(e?f`BX@S=uEW7Skd`P2ZjIUd!f{eJR| zjq5sw4vBH;I<8U+msq>ocZtcFP!c*q&_nJzf@&K8wk6wqq%p(yrrezWjKsRW65K6- zrSHqS7c8WhiU{W_%|%E1aA4rT zxxOOvD@iEq)YM&dup{Y6lfA7`<8Y_g*~I~Ed7efx0@c7X*_Fm3UiBUK?dCEWNNu$*LR8op|cwIsM?e zko#|iB|2k3G7$yYNH-W1-ElSefo6{rKwH$VRYQlw3N@C+GdWAy z{`nx7IEgsxyAyZHIr+j%`71_fJH@4{9erJM-zR~E&2$N+Dp9S%E9eW;# zH|%A|%Tb0uT`vN)gg-onPR-a6?!9J;&r+Ve3m)x{(lR@7Jm?@CnBZ%q_YxtZ(nB9tF7gejP%T;@nPv7YMph9ZEN=t;+4=>)c zjB;&(g%qm0pzV-xBE)f}%!(a(bnafZJDc@yhiB)J6lP2>>XjChgD=hXfg_!oGI$SwE{?fpDo(kZS&PR=X4_knRVfR-CI)a=b$oBeYxE8WcdI~S>8q792CX~XOY z_7)v*b|NW<9M2nR*|N*s4L2W$n<%&+k~dNx#_s*@u4bXsU7KQfWi{!qTZZ{D9PSmxX9NXEGptbwW}WiA@F?%NoNCI-v1?yA zVtZ`tPjY{q?0|L>4OYORGgsmKU7iHzOlha!37P~x0%h!g>8Sg;5m>LMNplfK%GXH}LF;!tP|S@y{p zlxbAb*D(aQG#kV3R)}^wd)j0Nkx7vPFkx7891uy^!>yuq3#*^(_q)3XhKGDh`uxJbG!M@wK4<)@>!n9cb{`zloJ7^FxiL<@f>UVVh0K_De^O zo$Gv_;hX9fceD87F9=y7o0Ilydy3B8u5K>fKZnEw^!aY?rVhA+?}t5DgTAGE!l%Lc z{`s_dFkeKE(7c>HcrkF078|4a)jg@6g{L3a{lx`t8DO3tZJ{1#X7Y7jU(SwAew3V*SRBTp&&b zjaOl}&dz^6SX6s__cfBW5*5q6)7Vl_92mLPB*Tlg!*9aH{JN3o(UrzU#^?FVE%LNd zl_MI-1QbOg%|lTfI#2>icuow$=T}AZvvOJI-h(FjbU1l|X>7I!wmT{}&oC1&r*)=` z?eGCb>AtV!zIh`eS4M&_&elzqA*R~BE{=?U!?Z~K1alfIkfH<+Xs`+=R4DH$DZ&G#!BcnCr6?F z9r7K6C7$#Y3B4kAK0qB*6QZu&HwhsFAVJTRqu9w9lTugd**J|pY*qXdELO*$N=ll@b>t{ zvtF%&GZ2?+1%FwW*r3haZip3k~@iS@aIqXw{md7GzzeCyOZGAa_ix96CS| zOFrO!YrqgGb8E^7JdC!gucVgOP9Br)k(9wm;k=l29JW8DZ-?$#`$BHjmb;^JXhL1@YIZGiT z^p&Z%+A))V@uiT@kZ{MC2W7Q{P9DJD;?%*5Q3m9v6QEy|K|@aT3q00i#p%m!sc3yB zKQRVrKBb;0^Eu{80jKBBa6J}xG7@jR*3f=a$_ko@uQl9DT9D`Icb)Ip;bEf2wZ*H< zCocu^+nS?ZMMDpD4osk&=Cb$*@5&^`;fEfB4OUNe-tliYVxA@1d4&a?guuJiPbu8i zufjqp5H&Yj`#Owb0N_kyjn57QM0yeS5S$sX73B7mrHl!NW0G0Xqm6Asa|U|L!E4K9 zw}y%06#BQXaSV`$Z?_>MoOh-BqL+e292lKhGN#X3j&oyTjRcYm?iO1ZmlrLPW0XCB zVJL)tYPnbsePE1P3=4Uahfe4+HYrz$Z0u>mvO`!B7ico)C0MNJgVNgR4qNkTmB>ll zw<>2sc5aIHZ=eaA?kwYS+v-FTOC=O81P3A2`I89q5Jcw&I#dJvxZ8D8e&&a0GoEVp z@JqyV*<;@V%@t;thR(1j^@s|aRNh)BUnm|BqdF(d-x$Ei_K~d_qo3#1aLwg>t4x9f z$3(D^&%Vzc>>Vq6W3o-k9GJ7?Esyf&Ripl(XM))1@j@VZ~FMbi@s1_!$7DTf_T0=>l|EOS``*BfC^+{{G$Rl4X+vfa$ zka<77#f9>%)699QM=u8-k7ZTsaZltFZ^5_^h0Geupj(BB__EI}cu==fnBCa>#nrQ7 ze=)Xp=11A~VS?h2kxbhZ87Gf?C(Lp|7nJF!MKLK01dY14&R_)Gg^q;CFUiy<3;`9A zPIJipnuZ3amXtM(hO9R}RXo?H$&sVHRC+trW)*_r>1N|wx^MGTUIZOJnxi5EPugo} znhwf+FA%!aj+VqiPnu2mchc?F+|gyH=Td(f{lHq}>xTdX#UzfELV8kW+b%?7le1qu zC#!o=lC!F^F;%X8T9EgEcl8ihO7ire9sJ+<*R~}Bqt%XxsUS^br0CE7@vCbY&l5xjOV6 zSBO>0?=~n8LOtfuCr=32Cp!SC3Q;mXxIgPQa0$q1&7`zojX~=~oFl~*5aaM%fwDxX zYr1qG;~;vHoBEZ3WR0(?vq=(Z`i7zv`K{rNJB#z+w65n`p7~h%%8w;p-rthYHFuO7 z%_*is`Vj%*)8x}Us6W$8qLz2+NEBJ#L2DpYu)wB}3X>(<$mo`vm4vzjMcyac-*v`@ zx!Qs~TZ5&0@2aQY+Pn^gbd;x~taG)ouB@EL7p3*I=%&mUs$sm%fqSv0vbXw)(6!hH zs8!l8XR!r-?=jYsTP>rZm4GSH@6spAxgdB6nC;vxSFq;R5Lg?^)sNc9mredPl`l`c zSfOxrcLp8V?F?SX^5AyW?v4a<{AB}NNa0>cS!o`gAkFhhVQvcc_(lf7i{X{(2*2%U zME`z~WcgZY$jrCUl)CW}_#3rB+LJ4TXEMH|M_Za0%%#p^%rBe!as|m#HH{v8cZv5~ zx3H;ae+xpQ93mM-=lli_?<=Aya;Gf=FC)clAAZw0Q34gz`d9oN6pURwKU#j2#iKx5 zEVUQz!UxG?j{yG1eR}ZTT>82Y4K{}qAu;@X-2s%RpiR9yl)R@qr(4c5Y|K&HhzDd& zM|PZ7#K<{%aT-{0{N^YppY_)IvfHixu~AdDV3F&OT?_;(z8u_N8Q>F4W)V0}&d-)i z3)Nva+(zcE+c0-> z4vdZ|G_l)4DN95iZ86Blj7UqW6X2;kGA?jH#-@3|l))ff`wE*71Z{|ve3v?s=KDi| z*7KKBVun!T=R2bJsd~wW;;^N)#b_nIYxYA}>N*K$BY0+ACoRZ+*Ex2QpB>KCFjbx9 zl^=55l82REvt|ESItJ`8#KAxP0)R(@gVXrQ2Kz)=zC?C22GQrU9sD ziL)cK@5djpj402HJjbzDo?(Xo$4QY5OkNIG6rACa*P$JYw~E{8zsHu&o9kE?xSRf* z5d|CjXY|PX=QIFtpm0o|07-=9*aM4LGZXtFS_a#*U0^nLcj24!FQlq`H~#P7=-Tpp zQ6b$cP-X=5~;E`_ukI9mrMRF@kzjkwC7dqfy^snU!vMRL1l!MSDku zG5&50_gaK*GMC4rIqYmSin0)L*+BXoZlx_z3SA3qed47Hkc1?F zH1^pOi9DU(mcvVy5eWHh>tVu1{urPFyDba3o}A&_{x)o4l+$00r1=^1bi+r-O18Z# z#lu+ZjK*~4V2_YUWfhHW#pEO#LSuC$A4%67@w9hvBkMs!BQm1F5nxc={nF6nf$W|r ztTqB@Aa{@?jmKy_Tnc1BqIcV(F_V9wj%0^f$Ry6z*v|^Nu$&tH7 z%w)03tRnLrgI9?(w2so!PIw(JfvEa;9;m0L)3ZKc&+bH^nP8Pl;rH8Rr4;^V&Si8o zNbGE1qGrIb_fl{c**)bavvfC8ZaqcmrAb-q?HhFWT1g9V4#MrPcurIsDehhcsC?}p zI07X!_U~~Vf@RU&B!FUC+s*;_$*w$Y=5!Y$^KW5i6Ot-M9hQf`mK)xcD3NYlp*fu4 zmbK*>BhiI{0F5qGZGtGon1pIAz9dhS)TSIWSbUCb25nYq$U6b|mSUqFgi$_}OOLsi zEobh1hb!5wIS+~8#9AV>nvOY_H}8{$!zoqSOT^KK&PQJu20kG5#g~4;g;XkKMQTq_-L0s8PBRq($b`3)A#W z^|3RFJU=7*yW>9%b!YzYzRAH9ybo%G=`NL?=4i0Zws(&FEDQ%D!;+@IkHo&4{XCq{ z6_lr+KnX(u?KFU?k?1Fow_V6QQ!zGpCg04gLyt2Fim?p?JezQJF}_0Kin6BWZjplGHRM6A{=I3z!tDWDY1G+F)= zuwE`&VTtR4ZS}lfIi@cuP}3h8J1F;W!2{p+%U=2r{0Nt2H*|~7!GMj)ayz@M$AZ`$ z>fe(H#9Sl=dMH^iruI1llqtvCd&5)L+m_h@FbbF>UEusg&t7A`e>Dm<+eZ~5UEb`H z<6OS|n{o8WEcp@bB)v6$&CACs=7WARwAWDs#53{>u06yP^VDNjj#M5z7RnnkIOv}O%{-2ffhTyP^Zr; z`T$e;OXg(F-y50V{CLCLPCZY3g}~5MPkx3AZy{f?rSyR)dJF{XT@HZ^)aHr_hW?1c zOG7GF;QhEod~FCWUp>U_5>Dyjo1b1V;{5ET8{@WVMe^Exh9H%nyd`;a5PR++W8}=L zt~l3pKDzh$^9b|>n0^zQjQ=kugt&4n;Y+ z1ui7@M^uB6&>Gd$0kYZe<WT|m zh+Ba)e^Te1DnuwhXwiWnwP=x0HCrp+AiwQCKme9T$UC<^1tH98+Pp5mV%2?ED^cgTT+)%uSBX+_{^kg0OurLJJ-Ep~KhBK2%8!1sgLL7%!k z*gK!$GS9*2DeQd=!!25XUaCuEt-4fA`l(U_j39>wi{?&l66;#K3un?6wNhMXL(qq3bMX;%=Vw0~xiv=Tr;ptMWb=^OfBBi?5Pi?Ew zx?_jqU5I&2Oq+`8r%Ww+CaI`;wN3x27Vz-)R1WgPLzNoUFeM6-HsW{%MJ=P8Dzqcq zcsGN(gBCNWMP2x}4Ar}>$95c)b*&8;Z8JJk9I1Z@jFokYvr{{Us^fIUdcDmIZNG{( zXDWw8Gv#m(kzy~@aizwTwE4lBLBIv(8Cku)&-*P6a7fFJAC{!G!lV_%}44ztWKU9eBIOD zcR_UY`;gIodHzg>`{$CtSs!Gz3wRrZzA^pR%-F&YkVluOG2K11;?h*qXo^9OW767o z$I|dxXf;%K<2w?y`T~NXEpz8gV~krHzU!Cnx7V!hD6OfPkZ#v9 z(e?!Ac$jwDC7gm;Tm{M5{OH_U#N zLKV!ugENCrYod%DS!uu=WEGVTgv6PI?bii*+$m=BF;g;)FsF{$QJH?2lPRTol|+w& zZE^uv)dWB#U~t?)ajU#qAQYfd3bF-A7XFS%-$k9=zn~TBr0N++LRcyUsWYoust^ij zS1`n)&X<0qSLxZE)un8P+jlEiqfZ7`g<$Za^0W*E8xMqrd{PhbCwo#4^T&8n5A|07 zHB$`KR58HBNEd}PL%~LP3wHY98AYPosQ5p+e^&=4_3)R1)R*?q7RHzL(1Lvn@K-=I zL-F|b)gJQr1MG^?0|euL5h5QYJ+#z6q5%_yVE=$3e)rJs_(DLE%Tr0hEB#|J!IUap z5bS@Hn>p#L%Y zAJBi{|E~zBFYTi(|KVw+rv=*LTlyoKdZO@ubkQTts_CK_W{RPjA^7kgf}H|$qFb=l-_ksWFO_w(uPt~ z*iv58*cM5wF=?p7C?sgD`*I(NtocSVk?IbbQ&`n8%N4{-VPMksA2G{6NEpNZ5~-}4 z?tYGk({O<$=i&2)&}d1wkQg}czcB@+H1uy)8w`rZT{38J)~?(o@U=9`NN2@So?de8 z0i_Dss?wc9F^s1I>EpNs4G|a*Pt0E{lL$q|)%>#OE5Z@Br=5Q^k(XMp5?wg;snTI4 z?@8U-advA)IQLSiE3$$#hUb|V{D9w7@G@^jjq35>5J|9%8YHpwq7?3L_91fsQK8I# zNTx|u2n9U{G-m3Qg-~N1skor4RvB>TClsh90nacM93cdk2w}+7CzV-eQmIuCiavEf zO?*@cq9GM zQ?v~>+rn3&#PAKbZw=BKKm_$xJx;Dt=?mJ|ow0HvS_Ha8sfmh|4WiQ>%f$ zgLMKhq#EPJ-%4`R(}w z`&-P72>!6b3+2v1u<_9tXEwDx;Ik<_UM)2$X~;0~P*y7edU(bK#2!#X-^L0!eIBS+63_!> zmGe-|-{P=>ymw0{5@rIn zs(3oJ6(GI91zj!SXI+spEvhq;uJZQ4dzcDvN!ak7FF40G)lBW-auo^%NooT4Ss~Rs)!zj;&*IKg5ZanJBh+%n1VXjVnfcLGw>JT5jwjg#<}XL8}DE{Hl}$lu;ex z!04DU5F~!w_&C@CF$z_+=#T0IPSe7(#;!41vM7cn_DYvP5FwtMaj}hygYXCCcDP_tCR$-8v0Hhn^O12719H=cSv=WVliAvPSkz-^U_nZRsFPm@`}-=I;++JVhgEa448(`0abw z0`*!-;Km`5VoCZ{BknU&WfEC+Ldpu1X%RJ2WCS8H+;+*4)<0NuUJg)Fx${0y&nMeO z&=v}XYB(a(uCNnz1RVed^3$ueCvOd7gTYQ29sCCM%ljdrE!CwBx9B$<)LSpAH=)aP zbM(Q&$zt#B!BYEe`tFG?y;jA_=#$mWerlN|iJmfUn#{J6x42g{jea$f2X@J(+H*#;Y1UT1Ts2B-gKnBQw-nY0 z3$$^xplT^Te*{^K&$mq%aHIMJ7X~t3B%Y}s{37`fy_M)M!*pn-#ge$9O?|S9G+&Rv zKXaQa%IRZ7LZ7|5&*?Q`rVjvyLkPRFW> zU{gkb$~vKh2V9MAj42!x;V*hQY&J4HodOBzG6niWOKYSZV9^Yp3MHyKJrKP9#D@O*VU(ht(el>&a!@jyO-1wgS>iCs%rBMBWkg98BsR0pSQWdF@S-Y(=atOn;y0cql#(7!W7aJH&Iy8t&LDH<4}s&ufQuah*X#&=ret28ROBP^E6m z8j07YzDKiFdHha&>^j;NbvMb>Pz>oLAZq&rZXlLrc_r?hf*}0W~EMm}podneKGm?azzhMJ4z?t8$M}RBU8Mx9$ zz&j|Ed?qc|l|f0QXU!Zvqa9D5U|GRHNqrGiRatUtdmG7vxDh2JDrEk&DXxDCL?mi% z<2E^1XYYWP{ul(sUB)Y`NcdC`Cp$78abW-JO_$?ydbO0Rcvxkss9@v3ro-abWX$B0!1-p;2n{kFFinimIcqq5_1NZsY(2^5n>q3gG0zQ;Ay< zdmoJSUV6D0IRS%S$0* zJIB!xR0<;{w_3v#73dd;D`6#)VM1=ev^K4y^EP(g*0qsRsCC8R37v#qs?&ea zZ0AtltEWaO(>#_ELXwvM2Nf$vYUDwXWgII={Xt5nZ0jUSO3Ac9B8b|?fz;nARii91 z2!--}qg*gSD0ploO=n(#3pDcL~p?Ud0eapw^7VS7CQ;dcNNNQ7;B zLxR(2YsJ;O<7~&%eM7ut(0c*_eKuD22R5hVho|6rWDJj6Ua%Wy0e?y-TDvG$_xV8L4lHzYwJKSQLyuc3-tfE?=)r*tR)E>`z- zt4Q~#ym+*BX3P>Otbp;dpxEE9n|QGL-9|;kvg)h#*I*FwNx%baAl%P31Q_-m+TCaL zuni&N>b;E_g4{sX=wVVC4iu=1&!gQEg;Ml2msKTdrkx{U-qR(oD*oxrD5lklUT^Nb^6*bamH9C3VL(>lnF#xg*F{3Gu)pN`~02O%4u6b)Zo> z@+yi24ou;Re1>F7N1xsLxzbq(an2bE#xP>f3%(*Cpeiv0R*+|aA<12OQ3#9LE>0gf zsL&Y0c z=;cElDS(@kSm^JkVqo*3_%ud5sHV`4)i}@LAV@F(JO$D$tbv91pavM=O)N_nj?rqW zbA}2XM8SBnpfH_9_CS+q!(!CM-l|rA+hWl`%?OOMnGnG8wXhD zA)RtJ52~DCQ@-uptPL784c15_X72nM1q@EV8Ox3?1;(ZBSDNH%rxPSP9{x`^Ij;lqZkoKbsV(~)X_wx-Y?90w2m94Ao&r0w`*_tn_hkJ3CVx)@HSrW(Md_RF4$?z8 z0#)dg-vpyRd2G1KLxP>wZlDBfx*af;R-Ma3FJx;}C_`otv6tIIE9Rl#>PAvJ8uhv9 z_xQ}k%!qT=|JXhQ>Yd*rJ}d-0L;^|@v7mjL(45 z)_MG~z6(FUn}4Fv8x{9>(mhIRC;2wI@IR<#lirl>ZM;UGZ}>gaI3=P^NGlA*q!&Tl z?r00oid{jt+57k1k4Q=xJU-m^{Zk?y0en;du;oO$=thm;)k0g3vT-ay6gA%AFA8Be zy=Y6F?@i~TQ;3dk_WTSnl9Jss7x*nm^*zvBQy1rloC#tMsAq29FR+O+qql2#+~Gq| z*6bgrfDq5#$0Nnv#rOuzN{W9WfiX9Kf)Nft|AJRQYdj)Y7p%X6>igTTvSDcuTh~*t|TG`h$J_7N~mvYp+Zm1db(RXH%s4W$F!hS5x9k(QWHk0qr=RJ>HtLtW%1mT}#k z?ASH7owm0{tnY3(q^xhP_n?M~U+L(gv+b1vqh0Ex)v?~+Nq~$5`sZBibEx{d@N1Ql zZld&eYC2m!+{+lPGun+^}5*YLa#SN&RhuY~Sr+lRBT!rdWJ z2Ygz(N3Vp37lbhT?LCkDax9;#qcX5QpO=Gd=sOpL9LBn1uYIQu+i9Sww_R6UI!}+W zq#Ia@7ax8;bcep%t}R!WjpLsB9{BWNesR)Y0@B0#hfK83=ckIbM9VAxk=p2|%D~k`>ev+USEAN(83nrT^}D;(NRMdVq6{{|C!|1oMJjLFaMcb z4FcWOdz|y*<7*%N&3l~VW4APJk}mr__wT1C%(BhPL|(~f$2tlsev7)8%jC?uw=_A~ z*4OhSV+dyD4dQ+%hta}B9^XW;6C0aYglW~nVtXV=)X{eJ$kZ<0295*sn^ocQ1L%l$ zUi77sb)bm!CV|#{m%`F{K@TrEr^RVvbNHLPB?;0nYIgYZIZE`7*HBLQ^FHn|_3T`8 zxZj8e@DaaV$TLD0#oe3Iz+dkqHR|y}0VLHs#o~BX_`~yVLrL@EAznW%s-rk@>mi>1 z;!#RWjFCaGP2OdY#zoJEC4nVG?dY8N6B|wM8qmqR*G#M;eO;pCNdAst^KC)b6tX*w ztp6F}X#nii4^R4Tm`B58GtM}YPXq4!)sc2q9vFT0RWdpZdj{!5!%i9UlIEMYYF~)xgyo1 z2Hq28y=~RpsO~d3@vA(Gy;HyKzp3Jwex)M)Gb0qEkTp*cqUmVE4!*_%fCZ^7Da5^6F@w% zDwe>kkjgN^f!c-Z-I9WgMSJT$7yT#d@OK#A&w zIVdczWdBDXtZM8_k5aWFt=r>oecGYvS_K-vMb!}w z9#uJgQ=TM$j-icUx?AG(bGJo`e0;Cz@*rnZ-S!L*HVUVSFkB%%G|IU=3-N9! zR1kW!bU)sM#Rfb;ghT^~qYzb+0Zsko?IWu#H2FwsI4F=4l4MW`{kP(4p5q<3t>T!o z&0y)c8{WbEDN4&9yZnTSdV?Q=aX4)kjK-{I8%?#!V)EI;3Hc5UuqbHCUlT4vwseZusnp_ci%?89aB-1%ow zMXJR(;};IImxg40Rms6o68TCSPS(3j)T>dBz&BaMR9hiM#MpAVk_#-nEVdtFZ=?TW zgZz%|bg7j$*Y3=kH|@V=-{0Are7o-S0iOTi-eI2ITteDW<5i^w^jvk8dB7DGH*u{fsAj#NJ#?9LzXl>D{Gps;iLlPfLC4t+Y&c=FF;A+V;zcuH7XzU zv2@9Uq|7HzdncC^(xqdmzP~9^u!0)v zASs7i0SE^yh^ixq%18>l?jkQ91mgf4#u@d5Y`Gi(-K?yn$3wH^#5lA7&zCxUjC-GWm%f{1a2MnYII3%8G&2N9I&bY&hjjQ4 z5)PBT{e6^nxz4!Gp9x)>uK$O!cW4i!VZ&`>JL%Zz*tTukwr$(Ct&VNmwrxAvdB4HA z&K~Y@{eh~w*RxjlTkqTLfeK=lKmmzd;^>{oVQQXhvqv)Y+$9kQ&SiEB`Hz=!cF-{d zUwo@ZH;#90yUO$E7lBh=0a^fM1!2aole66zp~CWxcgG=FzGhPfF~dLp6M z%x@Sgv|1$FMrv{9S(8-#8D$V@&7XU&8feH<(-6}3&7nV{Ih0GTWFdu`(S77REG^<> z9cEm%ASZ4<>s*UUYCbZ~lHu2TA8j%}N86d3@LCb%30UX|78Vpc)r%AL=bDQu2LLo( zupfgDH~ibm0E*ABJr)B(M@fSVswp8W28y7N?@us%KX&YDu?^g@;=nRTLd>;|MuOUvL7Xj-~PH#7!K=k>vDX*v?_xx`+HXJL=>F?D$@VADkQvlLG^~~1m4q1kCzVX)wNCz} zCB>JXqFGpm@sn<_D&)qCo}Bw*x4dVhM@MB_H*uGwJy}D=(y?rMsnJ8f8Vs1-&eQ`? znk5yD^_vLXQQYht-!EZhz|S;nrI z5%rb^S8GWzH{T?q(FtA8Ez~V%QTjQK=TG`N0RQa6m?7T?wl)qWF*4=AGiMdCWy#Ul zSbox22biBwl_37CRFZIiqxA_2uKpGzN0G3=kZsJv&H+&U?)$zoecuZl-g8OzDm3$czXs^Oz-3O1Nic!@+DZq#2`o`42#A+_kf=)U917J`t&|A*iph%Iz3SZ`aA>;pR-=5PA)Qs zhErWi4-lWN}~t9?t2}^cYWHc^9RUJ9k`3~v)k+=0sXxzGF)KEAIH?4<{{FDuyEY) z*M<+bi%?=ABolLJ6pkQp`M(s}zsB-T>nqlmwaS;<`Y}w>(wmLy72Ed9sj)quhAn-3 zvfhOQn~tYnjrROCe%jAx>9+s+OwQcK`<>_V=Tqa>rPHc-W)q)|IiQePfi~}Ta|RCI zn*9NS(a^z)I+)z*oj6(_c5{q|HrW~|1`-zhvJolxCB)+m>uu9_g)@W#0<-(PzD zlhX!?2|bWY@3{h!TR0JyMYM3swkb2325#bO5r9d66uzO#aowtM7r5Wzdp(GMY2&5= z$g1?MhLH^XX3giT>>G194bDJR1UA6m+#;(fQ*_mpPyFOkxpd<^$2s%zX>5!qziYv& z$C^1Kn>$1Wn#y_E+$2BV24@3R4!~XxD53|*Ip_alq)<*7=`L;n1ZNjG7Pm>YaOveKfdJYPy6Yu3Yb`ZaLo<^V65+a2i5kmA;o!6NNqGHc*9YcfZoNl@AN z`EE3_O~6QMK)*br4^btW6^l=hSh#;+kH{ie%L*xM&LHCzp3Oe}`{aV`Xwy za5tP=BZYU+V|v<+M*b#wTHf*hH1gtdX98|~4z?gsgc>jbt3(re%8q=kxfAoB?$ zfWbh-akM(eXOI@nL*UhIqM;W?CDrox7qFZ2g0}_F2Eu$;RKVM-9%O?LdhorH#u+Y{ zLza?NrF#RrxNLr!og|FE)04dm9_d3vKL)DaI|ry%yZf*xT>tu?T47iWBuW&>lj@Stx7AowM&$6}|YeRNAxwsKtV&qqlD-!Hh@oWqbgu=O0cb=wG1 zLW2!rVMaZrgY}zT-OadKIiPQqV9u3Uv{0zkKLD*We^0R7^C@1&@^;=Rof)4N@m(ac z*B7YYU>bFn+e2cTEi$4?N0qJM2@)4^0PWV`^2j&#zaPXScBow?_qrDLtQbhQ%PlFR zRy1z?&`B<}KUh3PQ|x&(U3VK1o1fX%n_U@eg0lx@;*8C*@gHD^5h9&g6~*O~H~nb& zpHF^su7Dq3E{|yc=)IrFUas9Nd$lTiYJIMAZU5lJCG*%cXuzsig5krh!TD?!=Fh!g zPTbHlgzvA^%zO({m&;R^TUtki{G^2p|CGU*fxM_0)2y@_>{d+n`K9-)`&qpv z0Y3Th{G=gOcw|7||D8Fam(25FTPH`wwd&h5G&5}ywv_s1A@i?AwnX(3z}2(O;rMUzC`=58Vzw&n6)$i}S>m2Hdh zMcqa{^O`l{EQeKw6*r4?GfgImW~Fpu^<2r=vf+Y}Wu19_(;CxS#_wZl7HJpJOcFbx zjodJ!UmGO>e#l&%`%bGIGZ&bwXLbNfllt$_836Ol?x5`ov8-ZR5s&^7e-G=_3H6l9H+EDeB;?*zST)B8q;)tBFv| zuQBtMes=M5x<>>LkgmCID{}SIP_jNvhjVN4)nihNg*y?XUg;5cN~B9PEUI@qZ(-NK z?5UOEQNBb1JJx2~TGfTNH$;~|2R)8Tpla`ms6`z6^1y~ppuRj`xloA+jNl;r($J3# zKUz|-lCKP}+fvU0xYMV5RV<7CN6+&qZ<+MnkJGj$iXV;SSx%wDvkWF@>MXh1N=^!% z5#H>fr0b+SL^S&*Yo$S~#Fe-6sfq()GoyO|aW0Sl`quewYPmaEh85#PVjs(kbz!Bp zhG4@z9r*p=o19J`7;^6@vQ62wBT99I&vh@?aKz5nR0koGnZ!A>NM+33j6k z!UrsYOfUThD1H*IDJh2l8GCGZ?tNCDo*@ z?2NZ^J{#l>0L$&~#4%s|QT#VTND5Y@Hra559)a#VVHICdF&G{zA~(pFJX2rmiR{WP ztH{u_WrQwki9GB`Ty;5sX;kt;DI@?pCgB?YqSC=A(A`P%dl}j#Oa-t8dCm$oPj7l# z=jQB@i}}pp|JJ-kZ3V=QR%yx|glzoau62dDHXF{!X4R%ip<~cyo2~O-)Rvp8=c)W9 zmKMydG{dXtT6A6cX>C|^xygCziBM3I$ou&NeI$^t_B)gOpd9i4eAv9>d3>SZCiQ|7 z-||Cx$pPUd^>R}93rKh?`fd!uXn|L+tYf*28sj$uLO;)Uu6J+O9?86HK_kdb{x1Yk z=bK$w`ezUea^DN2vp|;atZc*^*a~z;=QJ6ifX^Z`FKOy$UCjROD3(GX?VzwLDHMhbw6zO}qTHCmJ9x<4R8 zaNzGY`wx$q*=uaRSVFzRW8J_UVVLjly7ELGfigW0pvfV5<&nYOJoV}@RtdJ3#!PLa z&vk_n#&Zy4vBJ#dYVPy{9s?eOz-cGaIFsHy1HWdmrBEi?!vxhzV`~9uMB}VqacFx& zmt1{&Mwi@+SB-~6bE(OPL^Gb7u?g=yk#@N@8MAh^c3BhG%c-gbchj<}h4;sp=$)%+ zLl&OKsdOwRPtW(62Gi{_*&15j%E@ubdp-$|6*(RVfKD2kmp@uvt=o7PJ~3tT{&vdd z2^O(uVZ;cl#Fa>O@xobb<}JLF3iE^Sr{FjI_fxrs4^%Eiy3}!bfeNGMD>Tzuf*)PA zIAf!0q194}7Ier=+d9h9?rlPalEPC8h?0P@_L@W~ZPHYIJt*}3k)&LyvzI=aLjDE2 z_K-kDDMB|wupa6>sN9t2_;PUlk}5;Nq7EMEBu!C-!1;1;`;zLG09!6i2?A8i_t8Yf z7lMTV^^KtEzD-i96UMpe`xlpYVdpL@sPD0F&JG!dEl$<}){?5^(@H(9P$BoEm%_ha zX=tpb=3`Wp#OVHgj;8N>bpDfxA_run?rea6%eqxneo5~0D&eO~;r5gJU7)u-Lig+w z_rsB7Q>!Vj!ma%J-+_^Z&(uKRlW2>c@^>8+hzPf5=Jk3p;Iz{&+2Kh`xpgCC{Y*L$ zb=tkye?qSE!p51Y_&%ZNtq6drCG@8Qx3BF(rKe`z|5C<3*QbFB-~l==a{wt%F?zQtMPUN=;! zfeefR)K>0+5r_?F#+=`C8iw(nxK|&ScPI|RCTiw*CHrTDyO@(+Hh#C1murY~p5Im~ zyW!$Nt7!w>BIzX)_fota+DS_0=|k39kkhXkP_6bKkAG2*0MYz|YsG|aZRF5PJ7gO@ z;^cdl$tgQNASZtzG}hzyK7vlR2>bQ+R33YU12JMm=S5RJ(CSgye&E?YN9Q#9*lXb* zOz#m{+a}Z&CasmQ2Xrw9-8pW1Tub!-o><@anOIMD@6ZGSnHUZ96W%Hl6=9}4z{vG_ z_JMMn_YZl1)p zUVS8mxLi-)lt|;@)#L8(DyAnlVv@!IRRQ^Z6ULrnd%2PSi6;_$l|FIMWeE7^ZTRK%a�g4uH3$6-0%b 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�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

      Lm$RT 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� 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 literal 0 HcmV?d00001 diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh index b2c69bbdb..786c8aef8 100755 --- a/trunk/auto/depends.sh +++ b/trunk/auto/depends.sh @@ -84,6 +84,13 @@ function Ubuntu_prepare() echo "The unzip is installed." fi + nasm -v >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then + echo "Installing nasm." + require_sudoer "sudo apt-get install -y --force-yes nasm" + sudo apt-get install -y --force-yes nasm; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi + echo "The nasm is installed." + fi + if [[ $SRS_VALGRIND == YES ]]; then valgrind --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then echo "Installing valgrind." @@ -157,6 +164,13 @@ function Centos_prepare() echo "The unzip is installed." fi + nasm -v >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then + echo "Installing nasm." + require_sudoer "sudo yum install -y nasm" + sudo yum install -y nasm; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi + echo "The nasm is installed." + fi + if [[ $SRS_VALGRIND == YES ]]; then valgrind --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then echo "Installing valgrind." @@ -373,7 +387,7 @@ if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL != YES ]]; then rm -rf ${SRS_OBJS}/openssl-1.1.0e && cd ${SRS_OBJS} && unzip -q ../3rdparty/openssl-1.1.0e.zip && cd openssl-1.1.0e && ${OPENSSL_CONFIG} --prefix=`pwd`/_release $OPENSSL_OPTIONS && - make CC=${SRS_TOOL_CC} AR="${SRS_TOOL_AR} -rs" LD=${SRS_TOOL_LD} RANDLIB=${SRS_TOOL_RANDLIB} && make install_sw && + make CC=${SRS_TOOL_CC} AR="${SRS_TOOL_AR} -rs" LD=${SRS_TOOL_LD} RANDLIB=${SRS_TOOL_RANDLIB} ${SRS_JOBS} && make install_sw && cd .. && rm -rf openssl && ln -sf openssl-1.1.0e/_release openssl ) fi @@ -382,6 +396,27 @@ if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL != YES ]]; then if [ ! -f ${SRS_OBJS}/openssl/lib/libssl.a ]; then echo "Build openssl-1.1.0e failed."; exit -1; fi fi +##################################################################################### +# libopus, for WebRTC to transcode AAC with Opus. +##################################################################################### +if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then + # cross build not specified, if exists flag, need to rebuild for no-arm platform. + if [[ -f ${SRS_OBJS}/opus/lib/libopus.a ]]; then + echo "The opus-1.3.1 is ok."; + else + echo "Building opus-1.3.1."; + ( + rm -rf ${SRS_OBJS}/opus-1.3.1 && cd ${SRS_OBJS} && + tar xf ../3rdparty/opus-1.3.1.tar.gz && cd opus-1.3.1 && + ./configure --prefix=`pwd`/_release --enable-static --disable-shared && make ${SRS_JOBS} && make install + cd .. && rm -rf opus && ln -sf opus-1.3.1/_release opus + ) + fi + # check status + ret=$?; if [[ $ret -ne 0 ]]; then echo "Build opus-1.3.1 failed, ret=$ret"; exit $ret; fi + if [ ! -f ${SRS_OBJS}/opus/lib/libopus.a ]; then echo "Build opus-1.3.1 failed."; exit -1; fi +fi + ##################################################################################### # live transcoding, ffmpeg-4.1, x264-core157, lame-3.99.5, libaacplus-2.0.2. ##################################################################################### @@ -393,17 +428,9 @@ if [ $SRS_FFMPEG_TOOL = YES ]; then if [[ -f ${SRS_OBJS}/ffmpeg/bin/ffmpeg ]]; then echo "ffmpeg-4.1 is ok."; else - echo "build ffmpeg-4.1"; - ( - cd ${SRS_OBJS} && pwd_dir=`pwd` && - rm -rf ffmepg.src && mkdir -p ffmpeg.src && cd ffmpeg.src && - rm -f build_ffmpeg.sh && ln -sf ../../auto/build_ffmpeg.sh && . build_ffmpeg.sh && - cd ${pwd_dir} && rm -rf ffmpeg && ln -sf ffmpeg.src/_release ffmpeg - ) + echo "no ffmpeg-4.1 found, please run in docker ossrs/srs:dev"; + exit -1; fi - # check status - ret=$?; if [[ $ret -ne 0 ]]; then echo "build ffmpeg-4.1 failed, ret=$ret"; exit $ret; fi - if [ ! -f ${SRS_OBJS}/ffmpeg/bin/ffmpeg ]; then echo "build ffmpeg-4.1 failed."; exit -1; fi fi ##################################################################################### @@ -417,7 +444,7 @@ if [[ $SRS_SRT == YES ]]; then if [[ -f ${SRS_OBJS}/srt/lib/libsrt.a ]]; then echo "libsrt-1.4.1 is ok."; else - echo "no libsrt, please use srs-docker or build from source https://github.com/ossrs/srs/issues/1147#issuecomment-577469119"; + echo "no libsrt, please run in docker ossrs/srs:srt or build from source https://github.com/ossrs/srs/issues/1147#issuecomment-577469119"; exit -1; fi fi From 4308f238c069ba856678b5843294368615215823 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 22 Mar 2020 16:34:54 +0800 Subject: [PATCH 2/4] For #1659, #307, add ffmpeg-4.2-fit for rtc --- trunk/3rdparty/ffmpeg-4.2-fit/.gitignore | 17 + trunk/3rdparty/ffmpeg-4.2-fit/.version | 0 trunk/3rdparty/ffmpeg-4.2-fit/Makefile | 169 + .../compat/atomics/gcc/stdatomic.h | 173 + .../3rdparty/ffmpeg-4.2-fit/compat/va_copy.h | 34 + trunk/3rdparty/ffmpeg-4.2-fit/configure | 7531 +++++++++++++++++ .../3rdparty/ffmpeg-4.2-fit/ffbuild/arch.mak | 17 + .../ffmpeg-4.2-fit/ffbuild/common.mak | 175 + .../ffmpeg-4.2-fit/ffbuild/library.mak | 107 + .../ffmpeg-4.2-fit/ffbuild/libversion.sh | 13 + .../ffbuild/pkgconfig_generate.sh | 62 + .../ffmpeg-4.2-fit/ffbuild/version.sh | 63 + .../ffmpeg-4.2-fit/libavcodec/Makefile | 1225 +++ .../3rdparty/ffmpeg-4.2-fit/libavcodec/aac.h | 377 + .../libavcodec/aac_ac3_parser.c | 105 + .../libavcodec/aac_ac3_parser.h | 66 + .../libavcodec/aac_adtstoasc_bsf.c | 158 + .../ffmpeg-4.2-fit/libavcodec/aac_defines.h | 116 + .../ffmpeg-4.2-fit/libavcodec/aac_parser.c | 71 + .../ffmpeg-4.2-fit/libavcodec/aaccoder.c | 964 +++ .../libavcodec/aaccoder_trellis.h | 192 + .../libavcodec/aaccoder_twoloop.h | 763 ++ .../ffmpeg-4.2-fit/libavcodec/aacdec.c | 591 ++ .../ffmpeg-4.2-fit/libavcodec/aacdec_fixed.c | 468 + .../libavcodec/aacdec_template.c | 3450 ++++++++ .../ffmpeg-4.2-fit/libavcodec/aacdectab.h | 74 + .../ffmpeg-4.2-fit/libavcodec/aacenc.c | 1165 +++ .../ffmpeg-4.2-fit/libavcodec/aacenc.h | 428 + .../ffmpeg-4.2-fit/libavcodec/aacenc_is.c | 158 + .../ffmpeg-4.2-fit/libavcodec/aacenc_is.h | 51 + .../ffmpeg-4.2-fit/libavcodec/aacenc_ltp.c | 236 + .../ffmpeg-4.2-fit/libavcodec/aacenc_ltp.h | 41 + .../ffmpeg-4.2-fit/libavcodec/aacenc_pred.c | 347 + .../ffmpeg-4.2-fit/libavcodec/aacenc_pred.h | 47 + .../libavcodec/aacenc_quantization.h | 283 + .../libavcodec/aacenc_quantization_misc.h | 53 + .../ffmpeg-4.2-fit/libavcodec/aacenc_tns.c | 215 + .../ffmpeg-4.2-fit/libavcodec/aacenc_tns.h | 37 + .../ffmpeg-4.2-fit/libavcodec/aacenc_utils.h | 279 + .../ffmpeg-4.2-fit/libavcodec/aacencdsp.asm | 86 + .../libavcodec/aacencdsp_init.c | 43 + .../ffmpeg-4.2-fit/libavcodec/aacenctab.c | 108 + .../ffmpeg-4.2-fit/libavcodec/aacenctab.h | 139 + .../ffmpeg-4.2-fit/libavcodec/aacps.c | 1046 +++ .../ffmpeg-4.2-fit/libavcodec/aacps.h | 86 + .../ffmpeg-4.2-fit/libavcodec/aacps_fixed.c | 24 + .../libavcodec/aacps_fixed_tablegen.c | 24 + .../libavcodec/aacps_fixed_tablegen.h | 403 + .../ffmpeg-4.2-fit/libavcodec/aacps_float.c | 24 + .../libavcodec/aacps_tablegen.c | 24 + .../libavcodec/aacps_tablegen.h | 217 + .../libavcodec/aacps_tablegen_template.c | 107 + .../ffmpeg-4.2-fit/libavcodec/aacpsdata.c | 163 + .../ffmpeg-4.2-fit/libavcodec/aacpsdsp.asm | 487 ++ .../ffmpeg-4.2-fit/libavcodec/aacpsdsp.h | 60 + .../libavcodec/aacpsdsp_fixed.c | 23 + .../libavcodec/aacpsdsp_float.c | 23 + .../ffmpeg-4.2-fit/libavcodec/aacpsdsp_init.c | 72 + .../libavcodec/aacpsdsp_template.c | 233 + .../ffmpeg-4.2-fit/libavcodec/aacpsy.c | 1025 +++ .../ffmpeg-4.2-fit/libavcodec/aacsbr.c | 370 + .../ffmpeg-4.2-fit/libavcodec/aacsbr.h | 96 + .../ffmpeg-4.2-fit/libavcodec/aacsbr_fixed.c | 613 ++ .../libavcodec/aacsbr_fixed_tablegen.h | 28 + .../libavcodec/aacsbr_tablegen.h | 28 + .../libavcodec/aacsbr_tablegen_common.h | 114 + .../libavcodec/aacsbr_template.c | 1583 ++++ .../ffmpeg-4.2-fit/libavcodec/aacsbrdata.h | 535 ++ .../ffmpeg-4.2-fit/libavcodec/aactab.c | 3282 +++++++ .../ffmpeg-4.2-fit/libavcodec/aactab.h | 186 + .../aarch64/aacpsdsp_init_aarch64.c | 48 + .../libavcodec/aarch64/asm-offsets.h | 25 + .../ffmpeg-4.2-fit/libavcodec/aarch64/cabac.h | 104 + .../libavcodec/aarch64/fft_init_aarch64.c | 50 + .../libavcodec/aarch64/fmtconvert_init.c | 43 + .../aarch64/h264chroma_init_aarch64.c | 59 + .../libavcodec/aarch64/h264dsp_init_aarch64.c | 129 + .../libavcodec/aarch64/h264pred_init.c | 93 + .../aarch64/h264qpel_init_aarch64.c | 172 + .../libavcodec/aarch64/hpeldsp_init_aarch64.c | 123 + .../ffmpeg-4.2-fit/libavcodec/aarch64/idct.h | 28 + .../libavcodec/aarch64/idctdsp_init_aarch64.c | 41 + .../libavcodec/aarch64/mpegaudiodsp_init.c | 40 + .../libavcodec/aarch64/opusdsp_init.c | 35 + .../libavcodec/aarch64/rv40dsp_init_aarch64.c | 48 + .../libavcodec/aarch64/sbrdsp_init_aarch64.c | 70 + .../libavcodec/aarch64/synth_filter_init.c | 47 + .../libavcodec/aarch64/vc1dsp_init_aarch64.c | 47 + .../libavcodec/aarch64/videodsp_init.c | 32 + .../libavcodec/aarch64/vorbisdsp_init.c | 34 + .../libavcodec/aarch64/vp8dsp.h | 75 + .../libavcodec/aarch64/vp8dsp_init_aarch64.c | 124 + .../libavcodec/aarch64/vp9dsp_init.h | 29 + .../aarch64/vp9dsp_init_10bpp_aarch64.c | 23 + .../aarch64/vp9dsp_init_12bpp_aarch64.c | 23 + .../vp9dsp_init_16bpp_aarch64_template.c | 273 + .../libavcodec/aarch64/vp9dsp_init_aarch64.c | 258 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.c | 211 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.h | 263 + .../ffmpeg-4.2-fit/libavcodec/ac3_parser.c | 258 + .../ffmpeg-4.2-fit/libavcodec/ac3_parser.h | 36 + .../libavcodec/ac3_parser_internal.h | 42 + .../ffmpeg-4.2-fit/libavcodec/ac3dec.c | 1843 ++++ .../ffmpeg-4.2-fit/libavcodec/ac3dec.h | 277 + .../ffmpeg-4.2-fit/libavcodec/ac3dec_data.c | 60 + .../ffmpeg-4.2-fit/libavcodec/ac3dec_data.h | 32 + .../ffmpeg-4.2-fit/libavcodec/ac3dec_fixed.c | 197 + .../ffmpeg-4.2-fit/libavcodec/ac3dec_float.c | 93 + .../ffmpeg-4.2-fit/libavcodec/ac3dsp.c | 447 + .../ffmpeg-4.2-fit/libavcodec/ac3dsp.h | 167 + .../ffmpeg-4.2-fit/libavcodec/ac3enc.c | 2495 ++++++ .../ffmpeg-4.2-fit/libavcodec/ac3enc.h | 315 + .../ffmpeg-4.2-fit/libavcodec/ac3enc_fixed.c | 160 + .../ffmpeg-4.2-fit/libavcodec/ac3enc_float.c | 155 + .../libavcodec/ac3enc_opts_template.c | 82 + .../libavcodec/ac3enc_template.c | 436 + .../ffmpeg-4.2-fit/libavcodec/ac3tab.c | 334 + .../ffmpeg-4.2-fit/libavcodec/ac3tab.h | 71 + .../ffmpeg-4.2-fit/libavcodec/adts_header.c | 71 + .../ffmpeg-4.2-fit/libavcodec/adts_header.h | 50 + .../ffmpeg-4.2-fit/libavcodec/adts_parser.c | 44 + .../ffmpeg-4.2-fit/libavcodec/adts_parser.h | 37 + .../ffmpeg-4.2-fit/libavcodec/allcodecs.c | 921 ++ .../libavcodec/audio_frame_queue.c | 113 + .../libavcodec/audio_frame_queue.h | 83 + .../ffmpeg-4.2-fit/libavcodec/avcodec.h | 6228 ++++++++++++++ .../ffmpeg-4.2-fit/libavcodec/avdct.c | 129 + .../ffmpeg-4.2-fit/libavcodec/avdct.h | 84 + .../ffmpeg-4.2-fit/libavcodec/avfft.c | 145 + .../ffmpeg-4.2-fit/libavcodec/avfft.h | 118 + .../ffmpeg-4.2-fit/libavcodec/avpacket.c | 743 ++ .../ffmpeg-4.2-fit/libavcodec/avpicture.c | 82 + .../ffmpeg-4.2-fit/libavcodec/bitstream.c | 362 + .../libavcodec/bitstream_filter.c | 185 + .../libavcodec/bitstream_filters.c | 114 + .../ffmpeg-4.2-fit/libavcodec/blockdsp.c | 78 + .../ffmpeg-4.2-fit/libavcodec/blockdsp.h | 50 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.c | 567 ++ .../3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.h | 44 + .../ffmpeg-4.2-fit/libavcodec/bsf_list.c | 3 + .../ffmpeg-4.2-fit/libavcodec/bytestream.h | 376 + .../ffmpeg-4.2-fit/libavcodec/cbrt_data.c | 30 + .../ffmpeg-4.2-fit/libavcodec/cbrt_data.h | 40 + .../libavcodec/cbrt_data_fixed.c | 29 + .../ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.c | 24 + .../ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.h | 73 + .../ffmpeg-4.2-fit/libavcodec/codec_desc.c | 3286 +++++++ .../ffmpeg-4.2-fit/libavcodec/codec_list.c | 9 + .../ffmpeg-4.2-fit/libavcodec/d3d11va.c | 48 + .../ffmpeg-4.2-fit/libavcodec/d3d11va.h | 112 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/dct.h | 69 + .../ffmpeg-4.2-fit/libavcodec/decode.c | 2062 +++++ .../ffmpeg-4.2-fit/libavcodec/decode.h | 81 + .../ffmpeg-4.2-fit/libavcodec/dirac.c | 408 + .../ffmpeg-4.2-fit/libavcodec/dirac.h | 131 + .../ffmpeg-4.2-fit/libavcodec/dirac_arith.h | 202 + .../ffmpeg-4.2-fit/libavcodec/dirac_dwt.h | 132 + .../ffmpeg-4.2-fit/libavcodec/dirac_vlc.h | 51 + .../ffmpeg-4.2-fit/libavcodec/diracdsp.h | 72 + .../ffmpeg-4.2-fit/libavcodec/diractab.h | 43 + .../ffmpeg-4.2-fit/libavcodec/dv_profile.c | 341 + .../ffmpeg-4.2-fit/libavcodec/dv_profile.h | 83 + .../libavcodec/dv_profile_internal.h | 35 + .../ffmpeg-4.2-fit/libavcodec/dxva2.h | 93 + .../ffmpeg-4.2-fit/libavcodec/encode.c | 447 + .../libavcodec/error_resilience.c | 1366 +++ .../libavcodec/error_resilience.h | 97 + .../ffmpeg-4.2-fit/libavcodec/fdctdsp.h | 37 + .../ffmpeg-4.2-fit/libavcodec/fft-internal.h | 94 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/fft.h | 175 + .../ffmpeg-4.2-fit/libavcodec/fft_fixed.c | 21 + .../ffmpeg-4.2-fit/libavcodec/fft_fixed_32.c | 52 + .../ffmpeg-4.2-fit/libavcodec/fft_float.c | 21 + .../ffmpeg-4.2-fit/libavcodec/fft_init.c | 61 + .../libavcodec/fft_init_table.c | 328 + .../ffmpeg-4.2-fit/libavcodec/fft_table.h | 66 + .../ffmpeg-4.2-fit/libavcodec/fft_template.c | 639 ++ .../libavcodec/frame_thread_encoder.c | 327 + .../libavcodec/frame_thread_encoder.h | 30 + .../ffmpeg-4.2-fit/libavcodec/get_bits.h | 868 ++ .../ffmpeg-4.2-fit/libavcodec/golomb.c | 173 + .../ffmpeg-4.2-fit/libavcodec/golomb.h | 747 ++ .../ffmpeg-4.2-fit/libavcodec/h263dsp.c | 126 + .../ffmpeg-4.2-fit/libavcodec/h263dsp.h | 35 + .../ffmpeg-4.2-fit/libavcodec/h264chroma.c | 59 + .../ffmpeg-4.2-fit/libavcodec/h264chroma.h | 40 + .../ffmpeg-4.2-fit/libavcodec/hpeldsp.c | 370 + .../ffmpeg-4.2-fit/libavcodec/hpeldsp.h | 106 + .../ffmpeg-4.2-fit/libavcodec/hwaccel.h | 84 + .../ffmpeg-4.2-fit/libavcodec/hwaccels.h | 78 + .../ffmpeg-4.2-fit/libavcodec/idctdsp.h | 122 + .../ffmpeg-4.2-fit/libavcodec/iirfilter.c | 327 + .../ffmpeg-4.2-fit/libavcodec/iirfilter.h | 147 + .../ffmpeg-4.2-fit/libavcodec/imgconvert.c | 232 + .../ffmpeg-4.2-fit/libavcodec/internal.h | 433 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/jni.c | 79 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/jni.h | 46 + .../ffmpeg-4.2-fit/libavcodec/kbdwin.c | 57 + .../ffmpeg-4.2-fit/libavcodec/kbdwin.h | 38 + .../ffmpeg-4.2-fit/libavcodec/latm_parser.c | 112 + .../ffmpeg-4.2-fit/libavcodec/libopus.c | 48 + .../ffmpeg-4.2-fit/libavcodec/libopus.h | 27 + .../ffmpeg-4.2-fit/libavcodec/libopusdec.c | 245 + .../ffmpeg-4.2-fit/libavcodec/libopusenc.c | 594 ++ .../3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.c | 325 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.h | 212 + .../ffmpeg-4.2-fit/libavcodec/mathops.h | 251 + .../ffmpeg-4.2-fit/libavcodec/mathtables.c | 114 + .../ffmpeg-4.2-fit/libavcodec/mdct15.asm | 221 + .../ffmpeg-4.2-fit/libavcodec/mdct15.c | 329 + .../ffmpeg-4.2-fit/libavcodec/mdct15.h | 62 + .../ffmpeg-4.2-fit/libavcodec/mdct15_init.c | 99 + .../ffmpeg-4.2-fit/libavcodec/mdct_fixed.c | 65 + .../ffmpeg-4.2-fit/libavcodec/mdct_fixed_32.c | 52 + .../ffmpeg-4.2-fit/libavcodec/mdct_float.c | 21 + .../ffmpeg-4.2-fit/libavcodec/mdct_template.c | 213 + .../ffmpeg-4.2-fit/libavcodec/me_cmp.c | 1098 +++ .../ffmpeg-4.2-fit/libavcodec/me_cmp.h | 95 + .../ffmpeg-4.2-fit/libavcodec/mediacodec.c | 149 + .../ffmpeg-4.2-fit/libavcodec/mediacodec.h | 101 + .../libavcodec/mediacodec_surface.h | 31 + .../libavcodec/mediacodec_sw_buffer.h | 62 + .../libavcodec/mediacodec_wrapper.h | 131 + .../libavcodec/mediacodecdec_common.h | 109 + .../ffmpeg-4.2-fit/libavcodec/mjpegenc.h | 111 + .../libavcodec/mjpegenc_common.h | 46 + .../libavcodec/mjpegenc_huffman.c | 192 + .../libavcodec/mjpegenc_huffman.h | 76 + .../ffmpeg-4.2-fit/libavcodec/motion_est.c | 1741 ++++ .../ffmpeg-4.2-fit/libavcodec/motion_est.h | 135 + .../ffmpeg-4.2-fit/libavcodec/mpeg12.c | 332 + .../ffmpeg-4.2-fit/libavcodec/mpeg12.h | 80 + .../ffmpeg-4.2-fit/libavcodec/mpeg12data.c | 412 + .../ffmpeg-4.2-fit/libavcodec/mpeg12data.h | 57 + .../libavcodec/mpeg12framerate.c | 103 + .../ffmpeg-4.2-fit/libavcodec/mpeg12vlc.h | 52 + .../ffmpeg-4.2-fit/libavcodec/mpeg4audio.c | 169 + .../ffmpeg-4.2-fit/libavcodec/mpeg4audio.h | 162 + .../ffmpeg-4.2-fit/libavcodec/mpegpicture.c | 483 ++ .../ffmpeg-4.2-fit/libavcodec/mpegpicture.h | 114 + .../ffmpeg-4.2-fit/libavcodec/mpegutils.c | 393 + .../ffmpeg-4.2-fit/libavcodec/mpegutils.h | 148 + .../ffmpeg-4.2-fit/libavcodec/mpegvideo.c | 2356 ++++++ .../ffmpeg-4.2-fit/libavcodec/mpegvideo.h | 770 ++ .../ffmpeg-4.2-fit/libavcodec/mpegvideodata.c | 109 + .../ffmpeg-4.2-fit/libavcodec/mpegvideodata.h | 35 + .../ffmpeg-4.2-fit/libavcodec/mpegvideodsp.c | 119 + .../ffmpeg-4.2-fit/libavcodec/mpegvideodsp.h | 47 + .../libavcodec/mpegvideoencdsp.c | 256 + .../libavcodec/mpegvideoencdsp.h | 58 + .../ffmpeg-4.2-fit/libavcodec/null_bsf.c | 35 + .../ffmpeg-4.2-fit/libavcodec/options.c | 349 + .../ffmpeg-4.2-fit/libavcodec/options_table.h | 495 ++ .../3rdparty/ffmpeg-4.2-fit/libavcodec/opus.c | 900 ++ .../3rdparty/ffmpeg-4.2-fit/libavcodec/opus.h | 200 + .../ffmpeg-4.2-fit/libavcodec/opus_celt.c | 576 ++ .../ffmpeg-4.2-fit/libavcodec/opus_celt.h | 171 + .../ffmpeg-4.2-fit/libavcodec/opus_pvq.c | 917 ++ .../ffmpeg-4.2-fit/libavcodec/opus_pvq.h | 48 + .../ffmpeg-4.2-fit/libavcodec/opus_rc.c | 411 + .../ffmpeg-4.2-fit/libavcodec/opus_rc.h | 126 + .../ffmpeg-4.2-fit/libavcodec/opusdsp.c | 67 + .../ffmpeg-4.2-fit/libavcodec/opusdsp.h | 36 + .../ffmpeg-4.2-fit/libavcodec/opusenc.c | 738 ++ .../ffmpeg-4.2-fit/libavcodec/opusenc.h | 54 + .../ffmpeg-4.2-fit/libavcodec/opusenc_psy.c | 612 ++ .../ffmpeg-4.2-fit/libavcodec/opusenc_psy.h | 104 + .../ffmpeg-4.2-fit/libavcodec/opusenc_utils.h | 87 + .../ffmpeg-4.2-fit/libavcodec/opustab.c | 1158 +++ .../ffmpeg-4.2-fit/libavcodec/opustab.h | 161 + .../ffmpeg-4.2-fit/libavcodec/parser.c | 334 + .../ffmpeg-4.2-fit/libavcodec/parser.h | 60 + .../ffmpeg-4.2-fit/libavcodec/parser_list.c | 3 + .../ffmpeg-4.2-fit/libavcodec/parsers.c | 110 + .../ffmpeg-4.2-fit/libavcodec/pixblockdsp.h | 55 + .../ffmpeg-4.2-fit/libavcodec/profiles.c | 179 + .../ffmpeg-4.2-fit/libavcodec/profiles.h | 40 + .../ffmpeg-4.2-fit/libavcodec/psymodel.c | 161 + .../ffmpeg-4.2-fit/libavcodec/psymodel.h | 204 + .../ffmpeg-4.2-fit/libavcodec/pthread.c | 88 + .../ffmpeg-4.2-fit/libavcodec/pthread_frame.c | 1013 +++ .../libavcodec/pthread_internal.h | 34 + .../ffmpeg-4.2-fit/libavcodec/pthread_slice.c | 242 + .../ffmpeg-4.2-fit/libavcodec/put_bits.h | 365 + .../ffmpeg-4.2-fit/libavcodec/qpeldsp.c | 816 ++ .../ffmpeg-4.2-fit/libavcodec/qpeldsp.h | 83 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/qsv.h | 107 + .../ffmpeg-4.2-fit/libavcodec/qsv_api.c | 42 + .../ffmpeg-4.2-fit/libavcodec/ratecontrol.c | 1028 +++ .../ffmpeg-4.2-fit/libavcodec/ratecontrol.h | 99 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/raw.c | 338 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/raw.h | 48 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/rdft.h | 52 + trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.c | 147 + trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.h | 87 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/rle.h | 51 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/sbr.h | 217 + .../ffmpeg-4.2-fit/libavcodec/sbrdsp.asm | 548 ++ .../ffmpeg-4.2-fit/libavcodec/sbrdsp.c | 225 + .../ffmpeg-4.2-fit/libavcodec/sbrdsp.h | 55 + .../ffmpeg-4.2-fit/libavcodec/sbrdsp_fixed.c | 315 + .../ffmpeg-4.2-fit/libavcodec/sbrdsp_init.c | 87 + .../libavcodec/sbrdsp_template.c | 104 + .../ffmpeg-4.2-fit/libavcodec/sinewin.c | 21 + .../ffmpeg-4.2-fit/libavcodec/sinewin.h | 70 + .../ffmpeg-4.2-fit/libavcodec/sinewin_fixed.c | 21 + .../libavcodec/sinewin_tablegen.c | 24 + .../libavcodec/sinewin_tablegen.h | 83 + .../ffmpeg-4.2-fit/libavcodec/thread.h | 144 + .../ffmpeg-4.2-fit/libavcodec/utils.c | 2234 +++++ .../ffmpeg-4.2-fit/libavcodec/vaapi.h | 86 + .../ffmpeg-4.2-fit/libavcodec/vdpau.h | 176 + .../ffmpeg-4.2-fit/libavcodec/version.h | 140 + .../ffmpeg-4.2-fit/libavcodec/videodsp.c | 57 + .../ffmpeg-4.2-fit/libavcodec/videodsp.h | 88 + .../ffmpeg-4.2-fit/libavcodec/videotoolbox.h | 127 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/vlc.h | 81 + .../ffmpeg-4.2-fit/libavcodec/vorbis.c | 218 + .../ffmpeg-4.2-fit/libavcodec/vorbis.h | 50 + .../ffmpeg-4.2-fit/libavcodec/vorbis_data.c | 2193 +++++ .../libavcodec/vorbis_enc_data.h | 504 ++ .../ffmpeg-4.2-fit/libavcodec/vorbis_parser.c | 341 + .../ffmpeg-4.2-fit/libavcodec/vorbis_parser.h | 74 + .../libavcodec/vorbis_parser_internal.h | 46 + .../ffmpeg-4.2-fit/libavcodec/vorbisdsp.h | 38 + .../libavcodec/x86/aacencdsp_init.c | 43 + .../libavcodec/x86/aacpsdsp_init.c | 72 + .../libavcodec/x86/ac3dsp_init.c | 164 + .../libavcodec/x86/alacdsp_init.c | 44 + .../libavcodec/x86/audiodsp_init.c | 66 + .../libavcodec/x86/blockdsp_init.c | 60 + .../libavcodec/x86/bswapdsp_init.c | 40 + .../ffmpeg-4.2-fit/libavcodec/x86/cabac.h | 301 + .../ffmpeg-4.2-fit/libavcodec/x86/cavsdsp.c | 463 + .../libavcodec/x86/celt_pvq_init.c | 43 + .../ffmpeg-4.2-fit/libavcodec/x86/constants.c | 94 + .../ffmpeg-4.2-fit/libavcodec/x86/constants.h | 72 + .../libavcodec/x86/dcadsp_init.c | 52 + .../ffmpeg-4.2-fit/libavcodec/x86/dct_init.c | 41 + .../libavcodec/x86/dirac_dwt_init.c | 229 + .../libavcodec/x86/diracdsp_init.c | 195 + .../libavcodec/x86/dnxhdenc_init.c | 37 + .../libavcodec/x86/exrdsp_init.c | 52 + .../ffmpeg-4.2-fit/libavcodec/x86/fdct.c | 594 ++ .../ffmpeg-4.2-fit/libavcodec/x86/fdct.h | 28 + .../libavcodec/x86/fdctdsp_init.c | 44 + .../ffmpeg-4.2-fit/libavcodec/x86/fft.h | 38 + .../ffmpeg-4.2-fit/libavcodec/x86/fft_init.c | 61 + .../libavcodec/x86/flacdsp_init.c | 115 + .../libavcodec/x86/fmtconvert_init.c | 55 + .../ffmpeg-4.2-fit/libavcodec/x86/fpel.h | 49 + .../libavcodec/x86/g722dsp_init.c | 35 + .../libavcodec/x86/h263dsp_init.c | 39 + .../libavcodec/x86/h264_cabac.c | 208 + .../libavcodec/x86/h264_intrapred_init.c | 410 + .../ffmpeg-4.2-fit/libavcodec/x86/h264_qpel.c | 634 ++ .../libavcodec/x86/h264chroma_init.c | 117 + .../libavcodec/x86/h264dsp_init.c | 448 + .../ffmpeg-4.2-fit/libavcodec/x86/hevcdsp.h | 259 + .../libavcodec/x86/hevcdsp_init.c | 1151 +++ .../ffmpeg-4.2-fit/libavcodec/x86/hpeldsp.h | 57 + .../libavcodec/x86/hpeldsp_init.c | 313 + .../libavcodec/x86/hpeldsp_rnd_template.c | 202 + .../libavcodec/x86/hpeldsp_vp3_init.c | 56 + .../libavcodec/x86/huffyuvdsp_init.c | 61 + .../libavcodec/x86/huffyuvencdsp_init.c | 60 + .../ffmpeg-4.2-fit/libavcodec/x86/idctdsp.h | 39 + .../libavcodec/x86/idctdsp_init.c | 162 + .../libavcodec/x86/inline_asm.h | 100 + .../libavcodec/x86/jpeg2000dsp_init.c | 60 + .../libavcodec/x86/lossless_audiodsp_init.c | 56 + .../libavcodec/x86/lossless_videodsp_init.c | 128 + .../x86/lossless_videoencdsp_init.c | 111 + .../ffmpeg-4.2-fit/libavcodec/x86/lpc.c | 162 + .../ffmpeg-4.2-fit/libavcodec/x86/mathops.h | 133 + .../libavcodec/x86/mdct15_init.c | 99 + .../libavcodec/x86/me_cmp_init.c | 651 ++ .../libavcodec/x86/mlpdsp_init.c | 204 + .../libavcodec/x86/mpegaudiodsp.c | 289 + .../ffmpeg-4.2-fit/libavcodec/x86/mpegvideo.c | 469 + .../libavcodec/x86/mpegvideodsp.c | 161 + .../libavcodec/x86/mpegvideoenc.c | 244 + .../x86/mpegvideoenc_qns_template.c | 109 + .../libavcodec/x86/mpegvideoenc_template.c | 423 + .../libavcodec/x86/mpegvideoencdsp_init.c | 272 + .../libavcodec/x86/opusdsp_init.c | 35 + .../libavcodec/x86/pixblockdsp_init.c | 52 + .../libavcodec/x86/pngdsp_init.c | 50 + .../libavcodec/x86/proresdsp_init.c | 50 + .../libavcodec/x86/qpeldsp_init.c | 544 ++ .../libavcodec/x86/rnd_template.c | 175 + .../libavcodec/x86/rv34dsp_init.c | 48 + .../libavcodec/x86/rv40dsp_init.c | 278 + .../libavcodec/x86/sbcdsp_init.c | 51 + .../libavcodec/x86/sbrdsp_init.c | 87 + .../libavcodec/x86/simple_idct.h | 53 + .../ffmpeg-4.2-fit/libavcodec/x86/snowdsp.c | 908 ++ .../libavcodec/x86/svq1enc_init.c | 42 + .../libavcodec/x86/synth_filter_init.c | 74 + .../libavcodec/x86/takdsp_init.c | 45 + .../libavcodec/x86/ttadsp_init.c | 42 + .../libavcodec/x86/ttaencdsp_init.c | 42 + .../libavcodec/x86/utvideodsp_init.c | 54 + .../ffmpeg-4.2-fit/libavcodec/x86/v210-init.c | 56 + .../libavcodec/x86/v210enc_init.c | 54 + .../ffmpeg-4.2-fit/libavcodec/x86/vc1dsp.h | 29 + .../libavcodec/x86/vc1dsp_init.c | 168 + .../libavcodec/x86/vc1dsp_mmx.c | 486 ++ .../libavcodec/x86/videodsp_init.c | 309 + .../libavcodec/x86/vorbisdsp_init.c | 42 + .../libavcodec/x86/vp3dsp_init.c | 71 + .../libavcodec/x86/vp56_arith.h | 51 + .../libavcodec/x86/vp6dsp_init.c | 45 + .../libavcodec/x86/vp8dsp_init.c | 467 + .../libavcodec/x86/vp9dsp_init.c | 416 + .../libavcodec/x86/vp9dsp_init.h | 189 + .../libavcodec/x86/vp9dsp_init_10bpp.c | 25 + .../libavcodec/x86/vp9dsp_init_12bpp.c | 25 + .../libavcodec/x86/vp9dsp_init_16bpp.c | 149 + .../x86/vp9dsp_init_16bpp_template.c | 240 + .../ffmpeg-4.2-fit/libavcodec/x86/xvididct.h | 44 + .../libavcodec/x86/xvididct_init.c | 89 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.c | 63 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.h | 43 + .../3rdparty/ffmpeg-4.2-fit/libavcodec/xvmc.h | 170 + .../ffmpeg-4.2-fit/libavdevice/alldevices.c | 68 + .../ffmpeg-4.2-fit/libavdevice/indev_list.c | 2 + .../ffmpeg-4.2-fit/libavdevice/outdev_list.c | 2 + .../ffmpeg-4.2-fit/libavfilter/allfilters.c | 536 ++ .../ffmpeg-4.2-fit/libavfilter/avfilter.h | 1168 +++ .../ffmpeg-4.2-fit/libavfilter/bufferqueue.h | 121 + .../ffmpeg-4.2-fit/libavfilter/filter_list.c | 6 + .../ffmpeg-4.2-fit/libavfilter/version.h | 66 + .../ffmpeg-4.2-fit/libavfilter/window_func.h | 199 + .../ffmpeg-4.2-fit/libavformat/allformats.c | 641 ++ .../ffmpeg-4.2-fit/libavformat/demuxer_list.c | 2 + .../ffmpeg-4.2-fit/libavformat/muxer_list.c | 2 + .../libavformat/protocol_list.c | 2 + .../ffmpeg-4.2-fit/libavformat/protocols.c | 131 + .../ffmpeg-4.2-fit/libavutil/Makefile | 250 + .../ffmpeg-4.2-fit/libavutil/aarch64/bswap.h | 50 + .../ffmpeg-4.2-fit/libavutil/aarch64/cpu.c | 38 + .../ffmpeg-4.2-fit/libavutil/aarch64/cpu.h | 29 + .../libavutil/aarch64/float_dsp_init.c | 69 + .../libavutil/aarch64/neontest.h | 70 + .../ffmpeg-4.2-fit/libavutil/aarch64/timer.h | 44 + .../ffmpeg-4.2-fit/libavutil/adler32.c | 97 + .../ffmpeg-4.2-fit/libavutil/adler32.h | 60 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.c | 268 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.h | 65 + .../ffmpeg-4.2-fit/libavutil/aes_ctr.c | 135 + .../ffmpeg-4.2-fit/libavutil/aes_ctr.h | 88 + .../ffmpeg-4.2-fit/libavutil/aes_internal.h | 43 + .../ffmpeg-4.2-fit/libavutil/arm/bswap.h | 67 + .../ffmpeg-4.2-fit/libavutil/arm/cpu.c | 170 + .../ffmpeg-4.2-fit/libavutil/arm/cpu.h | 38 + .../libavutil/arm/float_dsp_arm.h | 29 + .../libavutil/arm/float_dsp_init_arm.c | 32 + .../libavutil/arm/float_dsp_init_neon.c | 59 + .../libavutil/arm/float_dsp_init_vfp.c | 46 + .../ffmpeg-4.2-fit/libavutil/arm/intmath.h | 134 + .../libavutil/arm/intreadwrite.h | 91 + .../ffmpeg-4.2-fit/libavutil/arm/neontest.h | 67 + .../ffmpeg-4.2-fit/libavutil/arm/timer.h | 40 + .../ffmpeg-4.2-fit/libavutil/attributes.h | 167 + .../ffmpeg-4.2-fit/libavutil/audio_fifo.c | 236 + .../ffmpeg-4.2-fit/libavutil/audio_fifo.h | 187 + .../ffmpeg-4.2-fit/libavutil/avassert.h | 75 + .../ffmpeg-4.2-fit/libavutil/avconfig.h | 6 + .../ffmpeg-4.2-fit/libavutil/avsscanf.c | 970 +++ .../ffmpeg-4.2-fit/libavutil/avstring.c | 461 + .../ffmpeg-4.2-fit/libavutil/avstring.h | 413 + .../ffmpeg-4.2-fit/libavutil/avutil.h | 365 + .../ffmpeg-4.2-fit/libavutil/avutilres.rc | 55 + .../ffmpeg-4.2-fit/libavutil/base64.c | 174 + .../ffmpeg-4.2-fit/libavutil/base64.h | 72 + .../ffmpeg-4.2-fit/libavutil/blowfish.c | 424 + .../ffmpeg-4.2-fit/libavutil/blowfish.h | 82 + .../ffmpeg-4.2-fit/libavutil/bprint.c | 305 + .../ffmpeg-4.2-fit/libavutil/bprint.h | 219 + .../3rdparty/ffmpeg-4.2-fit/libavutil/bswap.h | 109 + .../ffmpeg-4.2-fit/libavutil/buffer.c | 357 + .../ffmpeg-4.2-fit/libavutil/buffer.h | 291 + .../libavutil/buffer_internal.h | 98 + .../ffmpeg-4.2-fit/libavutil/camellia.c | 412 + .../ffmpeg-4.2-fit/libavutil/camellia.h | 70 + .../3rdparty/ffmpeg-4.2-fit/libavutil/cast5.c | 507 ++ .../3rdparty/ffmpeg-4.2-fit/libavutil/cast5.h | 80 + .../ffmpeg-4.2-fit/libavutil/channel_layout.c | 287 + .../ffmpeg-4.2-fit/libavutil/channel_layout.h | 232 + .../ffmpeg-4.2-fit/libavutil/color_utils.c | 235 + .../ffmpeg-4.2-fit/libavutil/color_utils.h | 56 + .../ffmpeg-4.2-fit/libavutil/colorspace.h | 150 + .../ffmpeg-4.2-fit/libavutil/common.h | 560 ++ trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.c | 321 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.h | 130 + .../ffmpeg-4.2-fit/libavutil/cpu_internal.h | 54 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.c | 415 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.h | 100 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.c | 331 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.h | 77 + .../3rdparty/ffmpeg-4.2-fit/libavutil/dict.c | 272 + .../3rdparty/ffmpeg-4.2-fit/libavutil/dict.h | 200 + .../ffmpeg-4.2-fit/libavutil/display.c | 73 + .../ffmpeg-4.2-fit/libavutil/display.h | 114 + .../ffmpeg-4.2-fit/libavutil/downmix_info.c | 38 + .../ffmpeg-4.2-fit/libavutil/downmix_info.h | 115 + .../ffmpeg-4.2-fit/libavutil/dynarray.h | 70 + .../libavutil/encryption_info.c | 339 + .../libavutil/encryption_info.h | 205 + .../3rdparty/ffmpeg-4.2-fit/libavutil/error.c | 129 + .../3rdparty/ffmpeg-4.2-fit/libavutil/error.h | 126 + .../3rdparty/ffmpeg-4.2-fit/libavutil/eval.c | 760 ++ .../3rdparty/ffmpeg-4.2-fit/libavutil/eval.h | 113 + .../ffmpeg-4.2-fit/libavutil/ffmath.h | 67 + .../ffmpeg-4.2-fit/libavutil/ffversion.h | 5 + .../3rdparty/ffmpeg-4.2-fit/libavutil/fifo.c | 240 + .../3rdparty/ffmpeg-4.2-fit/libavutil/fifo.h | 179 + .../3rdparty/ffmpeg-4.2-fit/libavutil/file.c | 154 + .../3rdparty/ffmpeg-4.2-fit/libavutil/file.h | 71 + .../ffmpeg-4.2-fit/libavutil/file_open.c | 190 + .../ffmpeg-4.2-fit/libavutil/fixed_dsp.c | 167 + .../ffmpeg-4.2-fit/libavutil/fixed_dsp.h | 205 + .../ffmpeg-4.2-fit/libavutil/float_dsp.c | 164 + .../ffmpeg-4.2-fit/libavutil/float_dsp.h | 218 + .../3rdparty/ffmpeg-4.2-fit/libavutil/frame.c | 947 +++ .../3rdparty/ffmpeg-4.2-fit/libavutil/frame.h | 971 +++ .../3rdparty/ffmpeg-4.2-fit/libavutil/hash.c | 243 + .../3rdparty/ffmpeg-4.2-fit/libavutil/hash.h | 269 + .../libavutil/hdr_dynamic_metadata.c | 47 + .../libavutil/hdr_dynamic_metadata.h | 343 + .../3rdparty/ffmpeg-4.2-fit/libavutil/hmac.c | 196 + .../3rdparty/ffmpeg-4.2-fit/libavutil/hmac.h | 100 + .../ffmpeg-4.2-fit/libavutil/hwcontext.c | 879 ++ .../ffmpeg-4.2-fit/libavutil/hwcontext.h | 584 ++ .../ffmpeg-4.2-fit/libavutil/hwcontext_cuda.c | 381 + .../ffmpeg-4.2-fit/libavutil/hwcontext_cuda.h | 52 + .../libavutil/hwcontext_cuda_internal.h | 37 + .../libavutil/hwcontext_d3d11va.c | 615 ++ .../libavutil/hwcontext_d3d11va.h | 169 + .../ffmpeg-4.2-fit/libavutil/hwcontext_drm.c | 289 + .../ffmpeg-4.2-fit/libavutil/hwcontext_drm.h | 169 + .../libavutil/hwcontext_dxva2.c | 594 ++ .../libavutil/hwcontext_dxva2.h | 75 + .../libavutil/hwcontext_internal.h | 176 + .../libavutil/hwcontext_mediacodec.c | 50 + .../libavutil/hwcontext_mediacodec.h | 36 + .../libavutil/hwcontext_opencl.c | 2942 +++++++ .../libavutil/hwcontext_opencl.h | 100 + .../ffmpeg-4.2-fit/libavutil/hwcontext_qsv.c | 1278 +++ .../ffmpeg-4.2-fit/libavutil/hwcontext_qsv.h | 53 + .../libavutil/hwcontext_vaapi.c | 1689 ++++ .../libavutil/hwcontext_vaapi.h | 117 + .../libavutil/hwcontext_vdpau.c | 511 ++ .../libavutil/hwcontext_vdpau.h | 44 + .../libavutil/hwcontext_videotoolbox.c | 246 + .../libavutil/hwcontext_videotoolbox.h | 54 + .../ffmpeg-4.2-fit/libavutil/imgutils.c | 645 ++ .../ffmpeg-4.2-fit/libavutil/imgutils.h | 277 + .../libavutil/imgutils_internal.h | 30 + .../ffmpeg-4.2-fit/libavutil/integer.c | 166 + .../ffmpeg-4.2-fit/libavutil/integer.h | 86 + .../ffmpeg-4.2-fit/libavutil/internal.h | 372 + .../ffmpeg-4.2-fit/libavutil/intfloat.h | 77 + .../ffmpeg-4.2-fit/libavutil/intmath.c | 34 + .../ffmpeg-4.2-fit/libavutil/intmath.h | 165 + .../ffmpeg-4.2-fit/libavutil/intreadwrite.h | 644 ++ trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.c | 87 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.h | 71 + .../3rdparty/ffmpeg-4.2-fit/libavutil/libm.h | 471 ++ trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.c | 123 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.h | 64 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.c | 435 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.h | 362 + .../ffmpeg-4.2-fit/libavutil/log2_tab.c | 32 + .../ffmpeg-4.2-fit/libavutil/macros.h | 50 + .../libavutil/mastering_display_metadata.c | 66 + .../libavutil/mastering_display_metadata.h | 128 + .../ffmpeg-4.2-fit/libavutil/mathematics.c | 211 + .../ffmpeg-4.2-fit/libavutil/mathematics.h | 242 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.c | 218 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.h | 98 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.c | 508 ++ trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.h | 700 ++ .../ffmpeg-4.2-fit/libavutil/mem_internal.h | 45 + .../ffmpeg-4.2-fit/libavutil/motion_vector.h | 57 + .../ffmpeg-4.2-fit/libavutil/murmur3.c | 159 + .../ffmpeg-4.2-fit/libavutil/murmur3.h | 120 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.c | 2039 +++++ trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.h | 865 ++ .../ffmpeg-4.2-fit/libavutil/parseutils.c | 786 ++ .../ffmpeg-4.2-fit/libavutil/parseutils.h | 193 + .../ffmpeg-4.2-fit/libavutil/pixdesc.c | 2961 +++++++ .../ffmpeg-4.2-fit/libavutil/pixdesc.h | 440 + .../ffmpeg-4.2-fit/libavutil/pixelutils.c | 89 + .../ffmpeg-4.2-fit/libavutil/pixelutils.h | 52 + .../ffmpeg-4.2-fit/libavutil/pixfmt.h | 552 ++ .../3rdparty/ffmpeg-4.2-fit/libavutil/qsort.h | 122 + .../ffmpeg-4.2-fit/libavutil/random_seed.c | 145 + .../ffmpeg-4.2-fit/libavutil/random_seed.h | 43 + .../ffmpeg-4.2-fit/libavutil/rational.c | 184 + .../ffmpeg-4.2-fit/libavutil/rational.h | 214 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.c | 65 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.h | 66 + .../ffmpeg-4.2-fit/libavutil/replaygain.h | 50 + .../ffmpeg-4.2-fit/libavutil/reverse.c | 40 + .../ffmpeg-4.2-fit/libavutil/reverse.h | 28 + .../ffmpeg-4.2-fit/libavutil/ripemd.c | 555 ++ .../ffmpeg-4.2-fit/libavutil/ripemd.h | 87 + .../ffmpeg-4.2-fit/libavutil/samplefmt.c | 254 + .../ffmpeg-4.2-fit/libavutil/samplefmt.h | 272 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.c | 356 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.h | 95 + .../ffmpeg-4.2-fit/libavutil/sha512.c | 287 + .../ffmpeg-4.2-fit/libavutil/sha512.h | 97 + .../ffmpeg-4.2-fit/libavutil/slicethread.c | 255 + .../ffmpeg-4.2-fit/libavutil/slicethread.h | 52 + .../ffmpeg-4.2-fit/libavutil/softfloat.h | 289 + .../libavutil/softfloat_ieee754.h | 115 + .../libavutil/softfloat_tables.h | 262 + .../ffmpeg-4.2-fit/libavutil/spherical.c | 79 + .../ffmpeg-4.2-fit/libavutil/spherical.h | 232 + .../ffmpeg-4.2-fit/libavutil/stereo3d.c | 76 + .../ffmpeg-4.2-fit/libavutil/stereo3d.h | 233 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.c | 121 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.h | 71 + .../ffmpeg-4.2-fit/libavutil/thread.h | 173 + .../ffmpeg-4.2-fit/libavutil/threadmessage.c | 235 + .../ffmpeg-4.2-fit/libavutil/threadmessage.h | 115 + .../3rdparty/ffmpeg-4.2-fit/libavutil/time.c | 98 + .../3rdparty/ffmpeg-4.2-fit/libavutil/time.h | 56 + .../ffmpeg-4.2-fit/libavutil/time_internal.h | 49 + .../ffmpeg-4.2-fit/libavutil/timecode.c | 220 + .../ffmpeg-4.2-fit/libavutil/timecode.h | 140 + .../3rdparty/ffmpeg-4.2-fit/libavutil/timer.h | 141 + .../ffmpeg-4.2-fit/libavutil/timestamp.h | 78 + .../3rdparty/ffmpeg-4.2-fit/libavutil/tree.c | 168 + .../3rdparty/ffmpeg-4.2-fit/libavutil/tree.h | 138 + .../ffmpeg-4.2-fit/libavutil/twofish.c | 331 + .../ffmpeg-4.2-fit/libavutil/twofish.h | 70 + trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.c | 803 ++ trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.h | 81 + .../3rdparty/ffmpeg-4.2-fit/libavutil/utils.c | 160 + .../ffmpeg-4.2-fit/libavutil/version.h | 139 + .../ffmpeg-4.2-fit/libavutil/x86/asm.h | 154 + .../ffmpeg-4.2-fit/libavutil/x86/bswap.h | 87 + .../ffmpeg-4.2-fit/libavutil/x86/cpu.c | 272 + .../ffmpeg-4.2-fit/libavutil/x86/cpu.h | 113 + .../ffmpeg-4.2-fit/libavutil/x86/emms.h | 55 + .../libavutil/x86/fixed_dsp_init.c | 35 + .../libavutil/x86/float_dsp_init.c | 121 + .../libavutil/x86/imgutils_init.c | 49 + .../ffmpeg-4.2-fit/libavutil/x86/intmath.h | 139 + .../libavutil/x86/intreadwrite.h | 97 + .../ffmpeg-4.2-fit/libavutil/x86/lls_init.c | 45 + .../ffmpeg-4.2-fit/libavutil/x86/pixelutils.h | 26 + .../libavutil/x86/pixelutils_init.c | 94 + .../ffmpeg-4.2-fit/libavutil/x86/timer.h | 50 + .../ffmpeg-4.2-fit/libavutil/x86/w64xmmtest.h | 78 + .../ffmpeg-4.2-fit/libavutil/xga_font_data.c | 417 + .../ffmpeg-4.2-fit/libavutil/xga_font_data.h | 35 + .../3rdparty/ffmpeg-4.2-fit/libavutil/xtea.c | 253 + .../3rdparty/ffmpeg-4.2-fit/libavutil/xtea.h | 94 + .../ffmpeg-4.2-fit/libswresample/Makefile | 23 + .../aarch64/audio_convert_init.c | 67 + .../libswresample/aarch64/resample_init.c | 120 + .../libswresample/arm/audio_convert_init.c | 67 + .../libswresample/arm/resample_init.c | 120 + .../libswresample/audioconvert.c | 247 + .../libswresample/audioconvert.h | 78 + .../ffmpeg-4.2-fit/libswresample/dither.c | 148 + .../libswresample/dither_template.c | 84 + .../libswresample/noise_shaping_data.c | 224 + .../ffmpeg-4.2-fit/libswresample/options.c | 156 + .../ffmpeg-4.2-fit/libswresample/rematrix.c | 576 ++ .../libswresample/rematrix_template.c | 111 + .../ffmpeg-4.2-fit/libswresample/resample.c | 622 ++ .../ffmpeg-4.2-fit/libswresample/resample.h | 68 + .../libswresample/resample_dsp.c | 74 + .../libswresample/resample_template.c | 212 + .../ffmpeg-4.2-fit/libswresample/swresample.c | 949 +++ .../ffmpeg-4.2-fit/libswresample/swresample.h | 579 ++ .../libswresample/swresample_frame.c | 159 + .../libswresample/swresample_internal.h | 222 + .../libswresample/swresampleres.rc | 55 + .../ffmpeg-4.2-fit/libswresample/version.h | 45 + .../libswresample/x86/audio_convert_init.c | 181 + .../libswresample/x86/rematrix_init.c | 90 + .../libswresample/x86/resample_init.c | 100 + trunk/auto/depends.sh | 65 +- 690 files changed, 182077 insertions(+), 1 deletion(-) create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/.gitignore create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/.version create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/compat/atomics/gcc/stdatomic.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/compat/va_copy.h create mode 100755 trunk/3rdparty/ffmpeg-4.2-fit/configure create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/arch.mak create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/common.mak create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/library.mak create mode 100755 trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/libversion.sh create mode 100755 trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/pkgconfig_generate.sh create mode 100755 trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/version.sh create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_ac3_parser.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_ac3_parser.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_adtstoasc_bsf.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_defines.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_parser.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder_trellis.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder_twoloop.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdectab.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_is.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_is.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_ltp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_ltp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_pred.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_pred.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_quantization.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_quantization_misc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_tns.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_tns.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_utils.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacencdsp.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacencdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenctab.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenctab.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed_tablegen.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed_tablegen.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_float.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdata.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_float.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsy.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_fixed_tablegen.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_tablegen.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_tablegen_common.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbrdata.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aactab.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aactab.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/aacpsdsp_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/asm-offsets.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/cabac.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/fft_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/fmtconvert_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264chroma_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264dsp_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264pred_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264qpel_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/hpeldsp_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/idct.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/idctdsp_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/mpegaudiodsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/opusdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/rv40dsp_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/sbrdsp_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/synth_filter_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vc1dsp_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/videodsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vorbisdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp8dsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp8dsp_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_10bpp_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_12bpp_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_aarch64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_data.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_data.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_float.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_float.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_opts_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3tab.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3tab.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_header.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_header.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_parser.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_parser.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/allcodecs.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/audio_frame_queue.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/audio_frame_queue.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avcodec.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avdct.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avdct.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avfft.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avfft.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avpacket.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avpicture.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream_filter.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream_filters.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/blockdsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/blockdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf_list.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bytestream.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/codec_desc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/codec_list.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/d3d11va.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/d3d11va.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dct.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/decode.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/decode.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_arith.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_dwt.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_vlc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/diracdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/diractab.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dxva2.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/encode.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/error_resilience.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/error_resilience.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fdctdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft-internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_fixed_32.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_float.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_init_table.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_table.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/frame_thread_encoder.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/frame_thread_encoder.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/get_bits.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/golomb.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/golomb.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h263dsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h263dsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h264chroma.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h264chroma.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hpeldsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hpeldsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hwaccel.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hwaccels.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/idctdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/iirfilter.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/iirfilter.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/imgconvert.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/jni.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/jni.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/kbdwin.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/kbdwin.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/latm_parser.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopus.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopus.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopusdec.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopusenc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mathops.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mathtables.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct_fixed_32.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct_float.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/me_cmp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/me_cmp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_surface.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_sw_buffer.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_wrapper.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodecdec_common.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_common.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_huffman.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_huffman.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/motion_est.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/motion_est.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12data.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12data.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12framerate.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12vlc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg4audio.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg4audio.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegpicture.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegpicture.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegutils.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegutils.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideo.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideo.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodata.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodata.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideoencdsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideoencdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/null_bsf.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/options.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/options_table.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_celt.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_celt.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_pvq.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_pvq.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_rc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_rc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusdsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_psy.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_psy.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_utils.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opustab.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opustab.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser_list.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parsers.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pixblockdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/profiles.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/profiles.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/psymodel.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/psymodel.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_frame.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_slice.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/put_bits.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qpeldsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qpeldsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qsv.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qsv_api.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ratecontrol.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ratecontrol.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/raw.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/raw.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rdft.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rle.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbr.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_fixed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_tablegen.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_tablegen.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/thread.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/utils.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vaapi.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vdpau.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/version.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videodsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videodsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videotoolbox.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vlc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_data.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_enc_data.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbisdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacencdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacpsdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ac3dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/alacdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/audiodsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/blockdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/bswapdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/cabac.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/cavsdsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/celt_pvq_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/constants.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/constants.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dcadsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dct_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dirac_dwt_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/diracdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dnxhdenc_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/exrdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdct.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdct.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdctdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/flacdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fmtconvert_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fpel.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/g722dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h263dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_cabac.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_intrapred_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_qpel.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264chroma_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hevcdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hevcdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_rnd_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_vp3_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/huffyuvdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/huffyuvencdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/idctdsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/idctdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/inline_asm.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/jpeg2000dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_audiodsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_videodsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_videoencdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lpc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mathops.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mdct15_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/me_cmp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mlpdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegaudiodsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideo.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideodsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc_qns_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoencdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/opusdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/pixblockdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/pngdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/proresdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/qpeldsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rnd_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rv34dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rv40dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbcdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbrdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/simple_idct.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/snowdsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/svq1enc_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/synth_filter_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/takdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ttadsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ttaencdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/utvideodsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/v210-init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/v210enc_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp_mmx.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/videodsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vorbisdsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp3dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp56_arith.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp6dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp8dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_10bpp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_12bpp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_16bpp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_16bpp_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/xvididct.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/xvididct_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xvmc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/alldevices.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/indev_list.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/outdev_list.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/allfilters.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/avfilter.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/bufferqueue.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/filter_list.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/version.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/window_func.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavformat/allformats.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavformat/demuxer_list.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavformat/muxer_list.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavformat/protocol_list.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavformat/protocols.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/bswap.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/cpu.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/cpu.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/float_dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/neontest.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/timer.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/adler32.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/adler32.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_ctr.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_ctr.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/bswap.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/cpu.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/cpu.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_arm.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_arm.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_neon.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_vfp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/intmath.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/intreadwrite.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/neontest.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/timer.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/attributes.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/audio_fifo.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/audio_fifo.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avassert.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avconfig.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avsscanf.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avstring.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avstring.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avutil.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avutilres.rc create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/base64.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/base64.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/blowfish.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/blowfish.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bprint.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bprint.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bswap.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/camellia.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/camellia.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cast5.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cast5.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/channel_layout.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/channel_layout.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/color_utils.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/color_utils.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/colorspace.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/common.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dict.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dict.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/display.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/display.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/downmix_info.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/downmix_info.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dynarray.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/encryption_info.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/encryption_info.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/error.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/error.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/eval.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/eval.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffmath.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffversion.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fifo.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fifo.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file_open.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fixed_dsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fixed_dsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/float_dsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/float_dsp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/frame.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/frame.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hash.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hash.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hdr_dynamic_metadata.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hdr_dynamic_metadata.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hmac.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hmac.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_d3d11va.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_d3d11va.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_drm.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_drm.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_dxva2.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_dxva2.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_mediacodec.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_mediacodec.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_opencl.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_opencl.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_qsv.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_qsv.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vaapi.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vaapi.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vdpau.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vdpau.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_videotoolbox.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_videotoolbox.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/integer.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/integer.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intfloat.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intmath.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intmath.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intreadwrite.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/libm.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log2_tab.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/macros.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mastering_display_metadata.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mastering_display_metadata.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mathematics.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mathematics.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/motion_vector.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/murmur3.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/murmur3.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/parseutils.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/parseutils.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixdesc.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixdesc.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixelutils.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixelutils.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixfmt.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/qsort.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/random_seed.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/random_seed.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rational.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rational.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/replaygain.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/reverse.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/reverse.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ripemd.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ripemd.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/samplefmt.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/samplefmt.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha512.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha512.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/slicethread.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/slicethread.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat_ieee754.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat_tables.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/spherical.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/spherical.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/stereo3d.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/stereo3d.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/thread.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/threadmessage.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/threadmessage.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timecode.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timecode.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timer.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timestamp.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tree.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tree.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/twofish.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/twofish.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/utils.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/version.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/asm.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/bswap.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpu.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpu.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/emms.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/fixed_dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/float_dsp_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/imgutils_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/intmath.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/intreadwrite.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/lls_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/pixelutils.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/pixelutils_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/timer.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/w64xmmtest.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xga_font_data.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xga_font_data.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xtea.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xtea.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/audio_convert_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/resample_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/audio_convert_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/resample_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/audioconvert.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/audioconvert.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/dither.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/dither_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/noise_shaping_data.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/options.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/rematrix.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/rematrix_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample_dsp.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample_template.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample_frame.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample_internal.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresampleres.rc create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/version.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/audio_convert_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/rematrix_init.c create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/resample_init.c diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/.gitignore b/trunk/3rdparty/ffmpeg-4.2-fit/.gitignore new file mode 100644 index 000000000..c348b5e28 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/.gitignore @@ -0,0 +1,17 @@ +# Ignore files. +*.d +*.pc +*.o +config.asm +config.h +_release +doc +ffbuild/config.fate +ffbuild/config.log +ffbuild/config.mak +ffbuild/config.sh +ffbuild/.config +libavutil/lib.version +libavcodec/libavcodec.version +libavutil/libavutil.version +libswresample/libswresample.version \ No newline at end of file diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/.version b/trunk/3rdparty/ffmpeg-4.2-fit/.version new file mode 100644 index 000000000..e69de29bb diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/Makefile new file mode 100644 index 000000000..8bf04c169 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/Makefile @@ -0,0 +1,169 @@ +MAIN_MAKEFILE=1 +include ffbuild/config.mak + +vpath %.c $(SRC_PATH) +vpath %.cpp $(SRC_PATH) +vpath %.h $(SRC_PATH) +vpath %.inc $(SRC_PATH) +vpath %.m $(SRC_PATH) +vpath %.S $(SRC_PATH) +vpath %.asm $(SRC_PATH) +vpath %.rc $(SRC_PATH) +vpath %.v $(SRC_PATH) +vpath %.texi $(SRC_PATH) +vpath %.cu $(SRC_PATH) +vpath %.ptx $(SRC_PATH) +vpath %/fate_config.sh.template $(SRC_PATH) + +TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch +HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options + +# $(FFLIBS-yes) needs to be in linking order +FFLIBS-$(CONFIG_AVDEVICE) += avdevice +FFLIBS-$(CONFIG_AVFILTER) += avfilter +FFLIBS-$(CONFIG_AVFORMAT) += avformat +FFLIBS-$(CONFIG_AVCODEC) += avcodec +FFLIBS-$(CONFIG_AVRESAMPLE) += avresample +FFLIBS-$(CONFIG_POSTPROC) += postproc +FFLIBS-$(CONFIG_SWRESAMPLE) += swresample +FFLIBS-$(CONFIG_SWSCALE) += swscale + +FFLIBS := avutil + +DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd + +SKIPHEADERS = compat/w32pthreads.h + +# first so "all" becomes default target +all: all-yes + +include $(SRC_PATH)/ffbuild/common.mak + +FF_EXTRALIBS := $(FFEXTRALIBS) +FF_DEP_LIBS := $(DEP_LIBS) +FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS) + +$(TOOLS): %$(EXESUF): %.o + $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(EXTRALIBS-$(*F)) $(EXTRALIBS) $(ELIBS) + +target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS) + $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH) + +tools/target_dem_fuzzer$(EXESUF): tools/target_dem_fuzzer.o $(FF_DEP_LIBS) + $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH) + +tools/sofa2wavs$(EXESUF): ELIBS = $(FF_EXTRALIBS) +tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS) +tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS) +tools/target_dec_%_fuzzer$(EXESUF): $(FF_DEP_LIBS) + +CONFIGURABLE_COMPONENTS = \ + $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \ + $(SRC_PATH)/libavcodec/bitstream_filters.c \ + $(SRC_PATH)/libavcodec/parsers.c \ + $(SRC_PATH)/libavformat/protocols.c \ + +config.h: ffbuild/.config +ffbuild/.config: $(CONFIGURABLE_COMPONENTS) + @-tput bold 2>/dev/null + @-printf '\nWARNING: $(?) newer than config.h, rerun configure\n\n' + @-tput sgr0 2>/dev/null + +SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \ + HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \ + ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \ + ALTIVEC-OBJS VSX-OBJS MMX-OBJS X86ASM-OBJS \ + MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \ + MMI-OBJS OBJS SLIBOBJS HOSTOBJS TESTOBJS + +define RESET +$(1) := +$(1)-yes := +endef + +define DOSUBDIR +$(foreach V,$(SUBDIR_VARS),$(eval $(call RESET,$(V)))) +SUBDIR := $(1)/ +include $(SRC_PATH)/$(1)/Makefile +-include $(SRC_PATH)/$(1)/$(ARCH)/Makefile +-include $(SRC_PATH)/$(1)/$(INTRINSICS)/Makefile +include $(SRC_PATH)/ffbuild/library.mak +endef + +$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D)))) + +libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h + +$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF) +ifeq ($(STRIPTYPE),direct) + $(STRIP) -o $@ $< +else + $(CP) $< $@ + $(STRIP) $@ +endif + +%$(PROGSSUF)_g$(EXESUF): $(FF_DEP_LIBS) + $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS) + +VERSION_SH = $(SRC_PATH)/ffbuild/version.sh +GIT_LOG = $(SRC_PATH)/.git/logs/HEAD + +.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) ffbuild/config.mak +.version: M=@ + +libavutil/ffversion.h .version: + $(M)$(VERSION_SH) $(SRC_PATH) libavutil/ffversion.h $(EXTRA_VERSION) + $(Q)touch .version + +# force version.sh to run whenever version might have changed +-include .version + +install: install-libs install-headers + +install-libs: install-libs-yes + +install-data: $(DATA_FILES) + $(Q)mkdir -p "$(DATADIR)" + $(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)" + +uninstall: uninstall-data uninstall-headers uninstall-libs uninstall-pkgconfig + +uninstall-data: + $(RM) -r "$(DATADIR)" + +clean:: + $(RM) $(CLEANSUFFIXES) + $(RM) $(addprefix compat/,$(CLEANSUFFIXES)) $(addprefix compat/*/,$(CLEANSUFFIXES)) $(addprefix compat/*/*/,$(CLEANSUFFIXES)) + $(RM) -r coverage-html + $(RM) -rf coverage.info coverage.info.in lcov + +distclean:: clean + $(RM) .version avversion.h config.asm config.h mapfile \ + ffbuild/.config ffbuild/config.* libavutil/avconfig.h \ + version.h libavutil/ffversion.h libavcodec/codec_names.h \ + libavcodec/bsf_list.c libavformat/protocol_list.c \ + libavcodec/codec_list.c libavcodec/parser_list.c \ + libavformat/muxer_list.c libavformat/demuxer_list.c +ifeq ($(SRC_LINK),src) + $(RM) src +endif + +config: + $(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION) + +build: all alltools testprogs +check: all alltools testprogs fate + +$(sort $(OUTDIRS)): + $(Q)mkdir -p $@ + +# Dummy rule to stop make trying to rebuild removed or renamed headers +%.h: + @: + +# Disable suffix rules. Most of the builtin rules are suffix rules, +# so this saves some time on slow systems. +.SUFFIXES: + +.PHONY: all all-yes alltools build check config testprogs +.PHONY: *clean install* uninstall* diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/compat/atomics/gcc/stdatomic.h b/trunk/3rdparty/ffmpeg-4.2-fit/compat/atomics/gcc/stdatomic.h new file mode 100644 index 000000000..e13ed0e06 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/compat/atomics/gcc/stdatomic.h @@ -0,0 +1,173 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * based on vlc_atomic.h from VLC + * Copyright (C) 2010 Rémi Denis-Courmont + */ + +#ifndef COMPAT_ATOMICS_GCC_STDATOMIC_H +#define COMPAT_ATOMICS_GCC_STDATOMIC_H + +#include +#include + +#define ATOMIC_FLAG_INIT 0 + +#define ATOMIC_VAR_INIT(value) (value) + +#define atomic_init(obj, value) \ +do { \ + *(obj) = (value); \ +} while(0) + +#define kill_dependency(y) ((void)0) + +#define atomic_thread_fence(order) \ + __sync_synchronize() + +#define atomic_signal_fence(order) \ + ((void)0) + +#define atomic_is_lock_free(obj) 0 + +typedef _Bool atomic_flag; +typedef _Bool atomic_bool; +typedef char atomic_char; +typedef signed char atomic_schar; +typedef unsigned char atomic_uchar; +typedef short atomic_short; +typedef unsigned short atomic_ushort; +typedef int atomic_int; +typedef unsigned int atomic_uint; +typedef long atomic_long; +typedef unsigned long atomic_ulong; +typedef long long atomic_llong; +typedef unsigned long long atomic_ullong; +typedef wchar_t atomic_wchar_t; +typedef int_least8_t atomic_int_least8_t; +typedef uint_least8_t atomic_uint_least8_t; +typedef int_least16_t atomic_int_least16_t; +typedef uint_least16_t atomic_uint_least16_t; +typedef int_least32_t atomic_int_least32_t; +typedef uint_least32_t atomic_uint_least32_t; +typedef int_least64_t atomic_int_least64_t; +typedef uint_least64_t atomic_uint_least64_t; +typedef int_fast8_t atomic_int_fast8_t; +typedef uint_fast8_t atomic_uint_fast8_t; +typedef int_fast16_t atomic_int_fast16_t; +typedef uint_fast16_t atomic_uint_fast16_t; +typedef int_fast32_t atomic_int_fast32_t; +typedef uint_fast32_t atomic_uint_fast32_t; +typedef int_fast64_t atomic_int_fast64_t; +typedef uint_fast64_t atomic_uint_fast64_t; +typedef intptr_t atomic_intptr_t; +typedef uintptr_t atomic_uintptr_t; +typedef size_t atomic_size_t; +typedef ptrdiff_t atomic_ptrdiff_t; +typedef intmax_t atomic_intmax_t; +typedef uintmax_t atomic_uintmax_t; + +#define atomic_store(object, desired) \ +do { \ + *(object) = (desired); \ + __sync_synchronize(); \ +} while (0) + +#define atomic_store_explicit(object, desired, order) \ + atomic_store(object, desired) + +#define atomic_load(object) \ + (__sync_synchronize(), *(object)) + +#define atomic_load_explicit(object, order) \ + atomic_load(object) + +#define atomic_exchange(object, desired) \ +({ \ + __typeof__(object) _obj = (object); \ + __typeof__(*object) _old; \ + do \ + _old = atomic_load(_obj); \ + while (!__sync_bool_compare_and_swap(_obj, _old, (desired))); \ + _old; \ +}) + +#define atomic_exchange_explicit(object, desired, order) \ + atomic_exchange(object, desired) + +#define atomic_compare_exchange_strong(object, expected, desired) \ +({ \ + __typeof__(object) _exp = (expected); \ + __typeof__(*object) _old = *_exp; \ + *_exp = __sync_val_compare_and_swap((object), _old, (desired)); \ + *_exp == _old; \ +}) + +#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_weak(object, expected, desired) + +#define atomic_fetch_add(object, operand) \ + __sync_fetch_and_add(object, operand) + +#define atomic_fetch_add_explicit(object, operand, order) \ + atomic_fetch_add(object, operand) + +#define atomic_fetch_sub(object, operand) \ + __sync_fetch_and_sub(object, operand) + +#define atomic_fetch_sub_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_or(object, operand) \ + __sync_fetch_and_or(object, operand) + +#define atomic_fetch_or_explicit(object, operand, order) \ + atomic_fetch_or(object, operand) + +#define atomic_fetch_xor(object, operand) \ + __sync_fetch_and_xor(object, operand) + +#define atomic_fetch_xor_explicit(object, operand, order) \ + atomic_fetch_xor(object, operand) + +#define atomic_fetch_and(object, operand) \ + __sync_fetch_and_and(object, operand) + +#define atomic_fetch_and_explicit(object, operand, order) \ + atomic_fetch_and(object, operand) + +#define atomic_flag_test_and_set(object) \ + atomic_exchange(object, 1) + +#define atomic_flag_test_and_set_explicit(object, order) \ + atomic_flag_test_and_set(object) + +#define atomic_flag_clear(object) \ + atomic_store(object, 0) + +#define atomic_flag_clear_explicit(object, order) \ + atomic_flag_clear(object) + +#endif /* COMPAT_ATOMICS_GCC_STDATOMIC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/compat/va_copy.h b/trunk/3rdparty/ffmpeg-4.2-fit/compat/va_copy.h new file mode 100644 index 000000000..a40bbe663 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/compat/va_copy.h @@ -0,0 +1,34 @@ +/* + * MSVC Compatible va_copy macro + * Copyright (c) 2012 Derek Buitenhuis + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef COMPAT_VA_COPY_H +#define COMPAT_VA_COPY_H + +#include + +#if !defined(va_copy) && defined(_MSC_VER) +#define va_copy(dst, src) ((dst) = (src)) +#endif +#if !defined(va_copy) && defined(__GNUC__) && __GNUC__ < 3 +#define va_copy(dst, src) __va_copy(dst, src) +#endif + +#endif /* COMPAT_VA_COPY_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/configure b/trunk/3rdparty/ffmpeg-4.2-fit/configure new file mode 100755 index 000000000..b950783be --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/configure @@ -0,0 +1,7531 @@ +#!/bin/sh +# +# FFmpeg configure script +# +# Copyright (c) 2000-2002 Fabrice Bellard +# Copyright (c) 2005-2008 Diego Biurrun +# Copyright (c) 2005-2008 Mans Rullgard +# + +# Prevent locale nonsense from breaking basic text processing. +LC_ALL=C +export LC_ALL + +# make sure we are running under a compatible shell +# try to make this part work with most shells + +try_exec(){ + echo "Trying shell $1" + type "$1" > /dev/null 2>&1 && exec "$@" +} + +unset foo +(: ${foo%%bar}) 2> /dev/null +E1="$?" + +(: ${foo?}) 2> /dev/null +E2="$?" + +if test "$E1" != 0 || test "$E2" = 0; then + echo "Broken shell detected. Trying alternatives." + export FF_CONF_EXEC + if test "0$FF_CONF_EXEC" -lt 1; then + FF_CONF_EXEC=1 + try_exec bash "$0" "$@" + fi + if test "0$FF_CONF_EXEC" -lt 2; then + FF_CONF_EXEC=2 + try_exec ksh "$0" "$@" + fi + if test "0$FF_CONF_EXEC" -lt 3; then + FF_CONF_EXEC=3 + try_exec /usr/xpg4/bin/sh "$0" "$@" + fi + echo "No compatible shell script interpreter found." + echo "This configure script requires a POSIX-compatible shell" + echo "such as bash or ksh." + echo "THIS IS NOT A BUG IN FFMPEG, DO NOT REPORT IT AS SUCH." + echo "Instead, install a working POSIX-compatible shell." + echo "Disabling this configure test will create a broken FFmpeg." + if test "$BASH_VERSION" = '2.04.0(1)-release'; then + echo "This bash version ($BASH_VERSION) is broken on your platform." + echo "Upgrade to a later version if available." + fi + exit 1 +fi + +test -d /usr/xpg4/bin && PATH=/usr/xpg4/bin:$PATH + +show_help(){ + cat </dev/null 2>&1; then + ncolors=$(tput colors) + if test -n "$ncolors" && test $ncolors -ge 8; then + bold_color=$(tput bold) + warn_color=$(tput setaf 3) + error_color=$(tput setaf 1) + reset_color=$(tput sgr0) + fi + # 72 used instead of 80 since that's the default of pr + ncols=$(tput cols) +fi +: ${ncols:=72} + +log(){ + echo "$@" >> $logfile +} + +log_file(){ + log BEGIN "$1" + log_file_i=1 + while IFS= read -r log_file_line; do + printf '%5d\t%s\n' "$log_file_i" "$log_file_line" + log_file_i=$(($log_file_i+1)) + done < "$1" >> "$logfile" + log END "$1" +} + +warn(){ + log "WARNING: $*" + WARNINGS="${WARNINGS}WARNING: $*\n" +} + +die(){ + log "$@" + echo "$error_color$bold_color$@$reset_color" + cat <>file; + } else if (file ~ /\\.asm\$/) { + printf(\"%%define %s %d\\n\", c, v) >>file; + } else if (file ~ /\\.mak\$/) { + n = -v ? \"\" : \"!\"; + printf(\"%s%s=yes\\n\", n, c) >>file; + } else if (file ~ /\\.texi\$/) { + pre = -v ? \"\" : \"@c \"; + yesno = \$2; + c2 = tolower(c); + gsub(/_/, \"-\", c2); + printf(\"%s@set %s %s\\n\", pre, c2, yesno) >>file; + } + } + }" +} + +print_enabled(){ + suf=$1 + shift + for v; do + enabled $v && printf "%s\n" ${v%$suf} + done +} + +append(){ + var=$1 + shift + eval "$var=\"\$$var $*\"" +} + +prepend(){ + var=$1 + shift + eval "$var=\"$* \$$var\"" +} + +reverse () { + eval ' + reverse_out= + for v in $'$1'; do + reverse_out="$v $reverse_out" + done + '$1'=$reverse_out + ' +} + +# keeps the last occurence of each non-unique item +unique(){ + unique_out= + eval unique_in=\$$1 + reverse unique_in + for v in $unique_in; do + # " $unique_out" +space such that every item is surrounded with spaces + case " $unique_out" in *" $v "*) continue; esac # already in list + unique_out="$unique_out$v " + done + reverse unique_out + eval $1=\$unique_out +} + +resolve(){ + resolve_out= + eval resolve_in=\$$1 + for v in $resolve_in; do + eval 'resolve_out="$resolve_out$'$v' "' + done + eval $1=\$resolve_out +} + +add_cppflags(){ + append CPPFLAGS "$@" +} + +add_cflags(){ + append CFLAGS $($cflags_filter "$@") +} + +add_cflags_headers(){ + append CFLAGS_HEADERS $($cflags_filter "$@") +} + +add_cxxflags(){ + append CXXFLAGS $($cflags_filter "$@") +} + +add_objcflags(){ + append OBJCFLAGS $($objcflags_filter "$@") +} + +add_asflags(){ + append ASFLAGS $($asflags_filter "$@") +} + +add_ldflags(){ + append LDFLAGS $($ldflags_filter "$@") +} + +add_ldexeflags(){ + append LDEXEFLAGS $($ldflags_filter "$@") +} + +add_ldsoflags(){ + append LDSOFLAGS $($ldflags_filter "$@") +} + +add_extralibs(){ + prepend extralibs $($ldflags_filter "$@") +} + +add_stripflags(){ + append ASMSTRIPFLAGS "$@" +} + +add_host_cppflags(){ + append host_cppflags "$@" +} + +add_host_cflags(){ + append host_cflags $($host_cflags_filter "$@") +} + +add_host_ldflags(){ + append host_ldflags $($host_ldflags_filter "$@") +} + +add_compat(){ + append compat_objs $1 + shift + map 'add_cppflags -D$v' "$@" +} + +test_cmd(){ + log "$@" + "$@" >> $logfile 2>&1 +} + +test_stat(){ + log test_stat "$@" + stat "$1" >> $logfile 2>&1 +} + +cc_e(){ + eval printf '%s\\n' $CC_E +} + +cc_o(){ + eval printf '%s\\n' $CC_O +} + +as_o(){ + eval printf '%s\\n' $AS_O +} + +x86asm_o(){ + eval printf '%s\\n' $X86ASM_O +} + +ld_o(){ + eval printf '%s\\n' $LD_O +} + +hostcc_e(){ + eval printf '%s\\n' $HOSTCC_E +} + +hostcc_o(){ + eval printf '%s\\n' $HOSTCC_O +} + +nvcc_o(){ + eval printf '%s\\n' $NVCC_O +} + +test_cc(){ + log test_cc "$@" + cat > $TMPC + log_file $TMPC + test_cmd $cc $CPPFLAGS $CFLAGS "$@" $CC_C $(cc_o $TMPO) $TMPC +} + +test_cxx(){ + log test_cxx "$@" + cat > $TMPCPP + log_file $TMPCPP + test_cmd $cxx $CPPFLAGS $CFLAGS $CXXFLAGS "$@" $CXX_C -o $TMPO $TMPCPP +} + +test_objcc(){ + log test_objcc "$@" + cat > $TMPM + log_file $TMPM + test_cmd $objcc -Werror=missing-prototypes $CPPFLAGS $CFLAGS $OBJCFLAGS "$@" $OBJCC_C $(cc_o $TMPO) $TMPM +} + +test_nvcc(){ + log test_nvcc "$@" + cat > $TMPCU + log_file $TMPCU + tmpcu_=$TMPCU + tmpo_=$TMPO + [ -x "$(command -v cygpath)" ] && tmpcu_=$(cygpath -m $tmpcu_) && tmpo_=$(cygpath -m $tmpo_) + test_cmd $nvcc $nvccflags "$@" $NVCC_C $(nvcc_o $tmpo_) $tmpcu_ +} + +check_nvcc() { + log check_nvcc "$@" + name=$1 + shift 1 + disabled $name && return + disable $name + test_nvcc "$@" < $TMPC + log_file $TMPC + test_cmd $cc $CPPFLAGS $CFLAGS "$@" $(cc_e $TMPO) $TMPC +} + +test_as(){ + log test_as "$@" + cat > $TMPS + log_file $TMPS + test_cmd $as $CPPFLAGS $ASFLAGS "$@" $AS_C $(as_o $TMPO) $TMPS +} + +test_x86asm(){ + log test_x86asm "$@" + echo "$1" > $TMPASM + log_file $TMPASM + shift + test_cmd $x86asmexe $X86ASMFLAGS -Werror "$@" $(x86asm_o $TMPO) $TMPASM +} + +check_cmd(){ + log check_cmd "$@" + cmd=$1 + disabled $cmd && return + disable $cmd + test_cmd $@ && enable $cmd +} + +check_as(){ + log check_as "$@" + name=$1 + code=$2 + shift 2 + disable $name + test_as $@ < $TMPC <" +} + +test_code(){ + log test_code "$@" + check=$1 + headers=$2 + code=$3 + shift 3 + { + for hdr in $headers; do + print_include $hdr + done + echo "int main(void) { $code; return 0; }" + } | test_$check "$@" +} + +check_cppflags(){ + log check_cppflags "$@" + test_cpp "$@" < +EOF +} + +test_cflags(){ + log test_cflags "$@" + set -- $($cflags_filter "$@") + test_cc "$@" <" + echo "int main(void) { return 0; }" + } | test_objcc && test_stat "$TMPO" && enable_sanitized $header +} + +check_apple_framework(){ + log check_apple_framework "$@" + framework="$1" + name="$(tolower $framework)" + header="${framework}/${framework}.h" + disable $name + check_header_objcc $header && + enable $name && eval ${name}_extralibs='"-framework $framework"' +} + +check_func(){ + log check_func "$@" + func=$1 + shift + disable $func + test_ld "cc" "$@" < +#include +float foo(complex float f, complex float g) { return $func($args); } +int main(void){ return (int) foo; } +EOF +} + +check_mathfunc(){ + log check_mathfunc "$@" + func=$1 + narg=$2 + shift 2 + test $narg = 2 && args="f, g" || args="f" + disable $func + test_ld "cc" "$@" < +float foo(float f, float g) { return $func($args); } +int main(void){ return (int) foo; } +EOF +} + +check_func_headers(){ + log check_func_headers "$@" + headers=$1 + funcs=$2 + shift 2 + { + for hdr in $headers; do + print_include $hdr + done + echo "#include " + for func in $funcs; do + echo "long check_$func(void) { return (long) $func; }" + done + echo "int main(void) { int ret = 0;" + # LTO could optimize out the test functions without this + for func in $funcs; do + echo " ret |= ((intptr_t)check_$func) & 0xFFFF;" + done + echo "return ret; }" + } | test_ld "cc" "$@" && enable $funcs && enable_sanitized $headers +} + +check_class_headers_cpp(){ + log check_class_headers_cpp "$@" + headers=$1 + classes=$2 + shift 2 + { + for hdr in $headers; do + echo "#include <$hdr>" + done + echo "int main(void) { " + i=1 + for class in $classes; do + echo "$class obj$i;" + i=$(expr $i + 1) + done + echo "return 0; }" + } | test_ld "cxx" "$@" && enable $funcs && enable_sanitized $headers +} + +test_cpp_condition(){ + log test_cpp_condition "$@" + header=$1 + condition=$2 + shift 2 + test_cpp "$@" < +#if !($condition) +#error "unsatisfied condition: $condition" +#endif +EOF +} + +check_cpp_condition(){ + log check_cpp_condition "$@" + name=$1 + shift 1 + disable $name + test_cpp_condition "$@" && enable $name +} + +test_cflags_cc(){ + log test_cflags_cc "$@" + flags=$1 + header=$2 + condition=$3 + shift 3 + set -- $($cflags_filter "$flags") + test_cc "$@" < +#if !($condition) +#error "unsatisfied condition: $condition" +#endif +EOF +} + +check_lib(){ + log check_lib "$@" + name="$1" + headers="$2" + funcs="$3" + shift 3 + disable $name + check_func_headers "$headers" "$funcs" "$@" && + enable $name && eval ${name}_extralibs="\$@" +} + +check_lib_cpp(){ + log check_lib_cpp "$@" + name="$1" + headers="$2" + classes="$3" + shift 3 + disable $name + check_class_headers_cpp "$headers" "$classes" "$@" && + enable $name && eval ${name}_extralibs="\$@" +} + +test_pkg_config(){ + log test_pkg_config "$@" + name="$1" + pkg_version="$2" + pkg="${2%% *}" + headers="$3" + funcs="$4" + shift 4 + disable $name + test_cmd $pkg_config --exists --print-errors $pkg_version || return + pkg_cflags=$($pkg_config --cflags $pkg_config_flags $pkg) + pkg_libs=$($pkg_config --libs $pkg_config_flags $pkg) + check_func_headers "$headers" "$funcs" $pkg_cflags $pkg_libs "$@" && + enable $name && + set_sanitized "${name}_cflags" $pkg_cflags && + set_sanitized "${name}_extralibs" $pkg_libs +} + +check_pkg_config(){ + log check_pkg_config "$@" + name="$1" + test_pkg_config "$@" && + eval add_cflags \$${name}_cflags +} + +test_exec(){ + test_ld "cc" "$@" && { enabled cross_compile || $TMPE >> $logfile 2>&1; } +} + +check_exec_crash(){ + log check_exec_crash "$@" + code=$(cat) + + # exit() is not async signal safe. _Exit (C99) and _exit (POSIX) + # are safe but may not be available everywhere. Thus we use + # raise(SIGTERM) instead. The check is run in a subshell so we + # can redirect the "Terminated" message from the shell. SIGBUS + # is not defined by standard C so it is used conditionally. + + (test_exec "$@") >> $logfile 2>&1 < +static void sighandler(int sig){ + raise(SIGTERM); +} +int foo(void){ + $code +} +int (*func_ptr)(void) = foo; +int main(void){ + signal(SIGILL, sighandler); + signal(SIGFPE, sighandler); + signal(SIGSEGV, sighandler); +#ifdef SIGBUS + signal(SIGBUS, sighandler); +#endif + return func_ptr(); +} +EOF +} + +check_type(){ + log check_type "$@" + headers=$1 + type=$2 + shift 2 + disable_sanitized "$type" + test_code cc "$headers" "$type v" "$@" && enable_sanitized "$type" +} + +check_struct(){ + log check_struct "$@" + headers=$1 + struct=$2 + member=$3 + shift 3 + disable_sanitized "${struct}_${member}" + test_code cc "$headers" "const void *p = &(($struct *)0)->$member" "$@" && + enable_sanitized "${struct}_${member}" +} + +check_builtin(){ + log check_builtin "$@" + name=$1 + headers=$2 + builtin=$3 + shift 3 + disable "$name" + test_code ld "$headers" "$builtin" "cc" "$@" && enable "$name" +} + +check_compile_assert(){ + log check_compile_assert "$@" + name=$1 + headers=$2 + condition=$3 + shift 3 + disable "$name" + test_code cc "$headers" "char c[2 * !!($condition) - 1]" "$@" && enable "$name" +} + +check_cc(){ + log check_cc "$@" + name=$1 + shift + disable "$name" + test_code cc "$@" && enable "$name" +} + +require(){ + log require "$@" + name_version="$1" + name="${1%% *}" + shift + check_lib $name "$@" || die "ERROR: $name_version not found" +} + +require_cc(){ + log require_cc "$@" + name="$1" + check_cc "$@" || die "ERROR: $name failed" +} + +require_cpp(){ + name="$1" + headers="$2" + classes="$3" + shift 3 + check_lib_cpp "$headers" "$classes" "$@" || die "ERROR: $name not found" +} + +require_headers(){ + log require_headers "$@" + headers="$1" + check_headers "$@" || die "ERROR: $headers not found" +} + +require_cpp_condition(){ + log require_cpp_condition "$@" + condition="$3" + check_cpp_condition "$@" || die "ERROR: $condition not satisfied" +} + +require_pkg_config(){ + log require_pkg_config "$@" + pkg_version="$2" + check_pkg_config "$@" || die "ERROR: $pkg_version not found using pkg-config$pkg_config_fail_message" +} + +test_host_cc(){ + log test_host_cc "$@" + cat > $TMPC + log_file $TMPC + test_cmd $host_cc $host_cflags "$@" $HOSTCC_C $(hostcc_o $TMPO) $TMPC +} + +test_host_cpp(){ + log test_host_cpp "$@" + cat > $TMPC + log_file $TMPC + test_cmd $host_cc $host_cppflags $host_cflags "$@" $(hostcc_e $TMPO) $TMPC +} + +check_host_cppflags(){ + log check_host_cppflags "$@" + test_host_cpp "$@" < +EOF +} + +check_host_cflags(){ + log check_host_cflags "$@" + set -- $($host_cflags_filter "$@") + test_host_cc "$@" < +#if !($condition) +#error "unsatisfied condition: $condition" +#endif +EOF +} + +check_host_cpp_condition(){ + log check_host_cpp_condition "$@" + name=$1 + shift 1 + disable $name + test_host_cpp_condition "$@" && enable $name +} + +cp_if_changed(){ + cmp -s "$1" "$2" && { test "$quiet" != "yes" && echo "$2 is unchanged"; } && return + mkdir -p "$(dirname $2)" + cp -f "$1" "$2" +} + +# CONFIG_LIST contains configurable options, while HAVE_LIST is for +# system-dependent things. + +AVCODEC_COMPONENTS=" + bsfs + decoders + encoders + hwaccels + parsers +" + +AVDEVICE_COMPONENTS=" + indevs + outdevs +" + +AVFILTER_COMPONENTS=" + filters +" + +AVFORMAT_COMPONENTS=" + demuxers + muxers + protocols +" + +COMPONENT_LIST=" + $AVCODEC_COMPONENTS + $AVDEVICE_COMPONENTS + $AVFILTER_COMPONENTS + $AVFORMAT_COMPONENTS +" + +EXAMPLE_LIST=" + avio_dir_cmd_example + avio_reading_example + decode_audio_example + decode_video_example + demuxing_decoding_example + encode_audio_example + encode_video_example + extract_mvs_example + filter_audio_example + filtering_audio_example + filtering_video_example + http_multiclient_example + hw_decode_example + metadata_example + muxing_example + qsvdec_example + remuxing_example + resampling_audio_example + scaling_video_example + transcode_aac_example + transcoding_example + vaapi_encode_example + vaapi_transcode_example +" + +EXTERNAL_AUTODETECT_LIBRARY_LIST=" + alsa + appkit + avfoundation + bzlib + coreimage + iconv + libxcb + libxcb_shm + libxcb_shape + libxcb_xfixes + lzma + schannel + sdl2 + securetransport + sndio + xlib + zlib +" + +EXTERNAL_LIBRARY_GPL_LIST=" + avisynth + frei0r + libcdio + libdavs2 + librubberband + libvidstab + libx264 + libx265 + libxavs + libxavs2 + libxvid +" + +EXTERNAL_LIBRARY_NONFREE_LIST=" + decklink + libfdk_aac + openssl + libtls +" + +EXTERNAL_LIBRARY_VERSION3_LIST=" + gmp + libaribb24 + liblensfun + libopencore_amrnb + libopencore_amrwb + libvmaf + libvo_amrwbenc + mbedtls + rkmpp +" + +EXTERNAL_LIBRARY_GPLV3_LIST=" + libsmbclient +" + +EXTERNAL_LIBRARY_LIST=" + $EXTERNAL_LIBRARY_GPL_LIST + $EXTERNAL_LIBRARY_NONFREE_LIST + $EXTERNAL_LIBRARY_VERSION3_LIST + $EXTERNAL_LIBRARY_GPLV3_LIST + chromaprint + gcrypt + gnutls + jni + ladspa + libaom + libass + libbluray + libbs2b + libcaca + libcelt + libcodec2 + libdav1d + libdc1394 + libdrm + libflite + libfontconfig + libfreetype + libfribidi + libgme + libgsm + libiec61883 + libilbc + libjack + libklvanc + libkvazaar + libmodplug + libmp3lame + libmysofa + libopencv + libopenh264 + libopenjpeg + libopenmpt + libopus + libpulse + librsvg + librtmp + libshine + libsmbclient + libsnappy + libsoxr + libspeex + libsrt + libssh + libtensorflow + libtesseract + libtheora + libtwolame + libv4l2 + libvorbis + libvpx + libwavpack + libwebp + libxml2 + libzimg + libzmq + libzvbi + lv2 + mediacodec + openal + opengl + pocketsphinx + vapoursynth +" + +HWACCEL_AUTODETECT_LIBRARY_LIST=" + amf + audiotoolbox + crystalhd + cuda + cuda_llvm + cuvid + d3d11va + dxva2 + ffnvcodec + nvdec + nvenc + vaapi + vdpau + videotoolbox + v4l2_m2m + xvmc +" + +# catchall list of things that require external libs to link +EXTRALIBS_LIST=" + cpu_init + cws2fws +" + +HWACCEL_LIBRARY_NONFREE_LIST=" + cuda_nvcc + cuda_sdk + libnpp +" + +HWACCEL_LIBRARY_LIST=" + $HWACCEL_LIBRARY_NONFREE_LIST + libmfx + mmal + omx + opencl +" + +DOCUMENT_LIST=" + doc + htmlpages + manpages + podpages + txtpages +" + +FEATURE_LIST=" + ftrapv + gray + hardcoded_tables + omx_rpi + runtime_cpudetect + safe_bitstream_reader + shared + small + static + swscale_alpha +" + +# this list should be kept in linking order +LIBRARY_LIST=" + avdevice + avfilter + swscale + postproc + avformat + avcodec + swresample + avresample + avutil +" + +LICENSE_LIST=" + gpl + nonfree + version3 +" + +PROGRAM_LIST=" + ffplay + ffprobe + ffmpeg +" + +SUBSYSTEM_LIST=" + dct + dwt + error_resilience + faan + fast_unaligned + fft + lsp + lzo + mdct + pixelutils + network + rdft +" + +# COMPONENT_LIST needs to come last to ensure correct dependency checking +CONFIG_LIST=" + $DOCUMENT_LIST + $EXAMPLE_LIST + $EXTERNAL_LIBRARY_LIST + $EXTERNAL_AUTODETECT_LIBRARY_LIST + $HWACCEL_LIBRARY_LIST + $HWACCEL_AUTODETECT_LIBRARY_LIST + $FEATURE_LIST + $LICENSE_LIST + $LIBRARY_LIST + $PROGRAM_LIST + $SUBSYSTEM_LIST + autodetect + fontconfig + linux_perf + memory_poisoning + neon_clobber_test + ossfuzz + pic + thumb + valgrind_backtrace + xmm_clobber_test + $COMPONENT_LIST +" + +THREADS_LIST=" + pthreads + os2threads + w32threads +" + +ATOMICS_LIST=" + atomics_gcc + atomics_suncc + atomics_win32 +" + +AUTODETECT_LIBS=" + $EXTERNAL_AUTODETECT_LIBRARY_LIST + $HWACCEL_AUTODETECT_LIBRARY_LIST + $THREADS_LIST +" + +ARCH_LIST=" + aarch64 + alpha + arm + avr32 + avr32_ap + avr32_uc + bfin + ia64 + m68k + mips + mips64 + parisc + ppc + ppc64 + s390 + sh4 + sparc + sparc64 + tilegx + tilepro + tomi + x86 + x86_32 + x86_64 +" + +ARCH_EXT_LIST_ARM=" + armv5te + armv6 + armv6t2 + armv8 + neon + vfp + vfpv3 + setend +" + +ARCH_EXT_LIST_MIPS=" + mipsfpu + mips32r2 + mips32r5 + mips64r2 + mips32r6 + mips64r6 + mipsdsp + mipsdspr2 + msa + msa2 +" + +ARCH_EXT_LIST_LOONGSON=" + loongson2 + loongson3 + mmi +" + +ARCH_EXT_LIST_X86_SIMD=" + aesni + amd3dnow + amd3dnowext + avx + avx2 + avx512 + fma3 + fma4 + mmx + mmxext + sse + sse2 + sse3 + sse4 + sse42 + ssse3 + xop +" + +ARCH_EXT_LIST_PPC=" + altivec + dcbzl + ldbrx + power8 + ppc4xx + vsx +" + +ARCH_EXT_LIST_X86=" + $ARCH_EXT_LIST_X86_SIMD + cpunop + i686 +" + +ARCH_EXT_LIST=" + $ARCH_EXT_LIST_ARM + $ARCH_EXT_LIST_PPC + $ARCH_EXT_LIST_X86 + $ARCH_EXT_LIST_MIPS + $ARCH_EXT_LIST_LOONGSON +" + +ARCH_FEATURES=" + aligned_stack + fast_64bit + fast_clz + fast_cmov + local_aligned + simd_align_16 + simd_align_32 + simd_align_64 +" + +BUILTIN_LIST=" + atomic_cas_ptr + machine_rw_barrier + MemoryBarrier + mm_empty + rdtsc + sem_timedwait + sync_val_compare_and_swap +" +HAVE_LIST_CMDLINE=" + inline_asm + symver + x86asm +" + +HAVE_LIST_PUB=" + bigendian + fast_unaligned +" + +HEADERS_LIST=" + arpa_inet_h + asm_types_h + cdio_paranoia_h + cdio_paranoia_paranoia_h + cuda_h + dispatch_dispatch_h + dev_bktr_ioctl_bt848_h + dev_bktr_ioctl_meteor_h + dev_ic_bt8xx_h + dev_video_bktr_ioctl_bt848_h + dev_video_meteor_ioctl_meteor_h + direct_h + dirent_h + dxgidebug_h + dxva_h + ES2_gl_h + gsm_h + io_h + linux_perf_event_h + machine_ioctl_bt848_h + machine_ioctl_meteor_h + malloc_h + opencv2_core_core_c_h + OpenGL_gl3_h + poll_h + sys_param_h + sys_resource_h + sys_select_h + sys_soundcard_h + sys_time_h + sys_un_h + sys_videoio_h + termios_h + udplite_h + unistd_h + valgrind_valgrind_h + windows_h + winsock2_h +" + +INTRINSICS_LIST=" + intrinsics_neon +" + +COMPLEX_FUNCS=" + cabs + cexp +" + +MATH_FUNCS=" + atanf + atan2f + cbrt + cbrtf + copysign + cosf + erf + exp2 + exp2f + expf + hypot + isfinite + isinf + isnan + ldexpf + llrint + llrintf + log2 + log2f + log10f + lrint + lrintf + powf + rint + round + roundf + sinf + trunc + truncf +" + +SYSTEM_FEATURES=" + dos_paths + libc_msvcrt + MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS + section_data_rel_ro + threads + uwp + winrt +" + +SYSTEM_FUNCS=" + access + aligned_malloc + arc4random + clock_gettime + closesocket + CommandLineToArgvW + fcntl + getaddrinfo + gethrtime + getopt + GetProcessAffinityMask + GetProcessMemoryInfo + GetProcessTimes + getrusage + GetSystemTimeAsFileTime + gettimeofday + glob + glXGetProcAddress + gmtime_r + inet_aton + isatty + kbhit + localtime_r + lstat + lzo1x_999_compress + mach_absolute_time + MapViewOfFile + memalign + mkstemp + mmap + mprotect + nanosleep + PeekNamedPipe + posix_memalign + pthread_cancel + sched_getaffinity + SecItemImport + SetConsoleTextAttribute + SetConsoleCtrlHandler + setmode + setrlimit + Sleep + strerror_r + sysconf + sysctl + usleep + UTGetOSTypeFromString + VirtualAlloc + wglGetProcAddress +" + +SYSTEM_LIBRARIES=" + bcrypt + vaapi_drm + vaapi_x11 + vdpau_x11 +" + +TOOLCHAIN_FEATURES=" + as_arch_directive + as_dn_directive + as_fpu_directive + as_func + as_object_arch + asm_mod_q + blocks_extension + ebp_available + ebx_available + gnu_as + gnu_windres + ibm_asm + inline_asm_direct_symbol_refs + inline_asm_labels + inline_asm_nonlocal_labels + pragma_deprecated + rsync_contimeout + symver_asm_label + symver_gnu_asm + vfp_args + xform_asm + xmm_clobbers +" + +TYPES_LIST=" + kCMVideoCodecType_HEVC + kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange + socklen_t + struct_addrinfo + struct_group_source_req + struct_ip_mreq_source + struct_ipv6_mreq + struct_msghdr_msg_flags + struct_pollfd + struct_rusage_ru_maxrss + struct_sctp_event_subscribe + struct_sockaddr_in6 + struct_sockaddr_sa_len + struct_sockaddr_storage + struct_stat_st_mtim_tv_nsec + struct_v4l2_frmivalenum_discrete +" + +HAVE_LIST=" + $ARCH_EXT_LIST + $(add_suffix _external $ARCH_EXT_LIST) + $(add_suffix _inline $ARCH_EXT_LIST) + $ARCH_FEATURES + $BUILTIN_LIST + $COMPLEX_FUNCS + $HAVE_LIST_CMDLINE + $HAVE_LIST_PUB + $HEADERS_LIST + $INTRINSICS_LIST + $MATH_FUNCS + $SYSTEM_FEATURES + $SYSTEM_FUNCS + $SYSTEM_LIBRARIES + $THREADS_LIST + $TOOLCHAIN_FEATURES + $TYPES_LIST + makeinfo + makeinfo_html + opencl_d3d11 + opencl_drm_arm + opencl_drm_beignet + opencl_dxva2 + opencl_vaapi_beignet + opencl_vaapi_intel_media + perl + pod2man + texi2html +" + +# options emitted with CONFIG_ prefix but not available on the command line +CONFIG_EXTRA=" + aandcttables + ac3dsp + adts_header + audio_frame_queue + audiodsp + blockdsp + bswapdsp + cabac + cbs + cbs_av1 + cbs_h264 + cbs_h265 + cbs_jpeg + cbs_mpeg2 + cbs_vp9 + dirac_parse + dnn + dvprofile + exif + faandct + faanidct + fdctdsp + flacdsp + fmtconvert + frame_thread_encoder + g722dsp + golomb + gplv3 + h263dsp + h264chroma + h264dsp + h264parse + h264pred + h264qpel + hevcparse + hpeldsp + huffman + huffyuvdsp + huffyuvencdsp + idctdsp + iirfilter + mdct15 + intrax8 + iso_media + ividsp + jpegtables + lgplv3 + libx262 + llauddsp + llviddsp + llvidencdsp + lpc + lzf + me_cmp + mpeg_er + mpegaudio + mpegaudiodsp + mpegaudioheader + mpegvideo + mpegvideoenc + mss34dsp + pixblockdsp + qpeldsp + qsv + qsvdec + qsvenc + qsvvpp + rangecoder + riffdec + riffenc + rtpdec + rtpenc_chain + rv34dsp + scene_sad + sinewin + snappy + srtp + startcode + texturedsp + texturedspenc + tpeldsp + vaapi_1 + vaapi_encode + vc1dsp + videodsp + vp3dsp + vp56dsp + vp8dsp + wma_freqs + wmv2dsp +" + +CMDLINE_SELECT=" + $ARCH_EXT_LIST + $CONFIG_LIST + $HAVE_LIST_CMDLINE + $THREADS_LIST + asm + cross_compile + debug + extra_warnings + logging + lto + optimizations + rpath + stripping +" + +PATHS_LIST=" + bindir + datadir + docdir + incdir + libdir + mandir + pkgconfigdir + prefix + shlibdir + install_name_dir +" + +CMDLINE_SET=" + $PATHS_LIST + ar + arch + as + assert_level + build_suffix + cc + objcc + cpu + cross_prefix + custom_allocator + cxx + dep_cc + doxygen + env + extra_version + gas + host_cc + host_cflags + host_extralibs + host_ld + host_ldflags + host_os + ignore_tests + install + ld + ln_s + logfile + malloc_prefix + nm + optflags + nvcc + nvccflags + pkg_config + pkg_config_flags + progs_suffix + random_seed + ranlib + samples + strip + sws_max_filter_size + sysinclude + sysroot + target_exec + target_os + target_path + target_samples + tempprefix + toolchain + valgrind + windres + x86asmexe +" + +CMDLINE_APPEND=" + extra_cflags + extra_cxxflags + extra_objcflags + host_cppflags +" + +# code dependency declarations + +# architecture extensions + +armv5te_deps="arm" +armv6_deps="arm" +armv6t2_deps="arm" +armv8_deps="aarch64" +neon_deps_any="aarch64 arm" +intrinsics_neon_deps="neon" +vfp_deps_any="aarch64 arm" +vfpv3_deps="vfp" +setend_deps="arm" + +map 'eval ${v}_inline_deps=inline_asm' $ARCH_EXT_LIST_ARM + +altivec_deps="ppc" +dcbzl_deps="ppc" +ldbrx_deps="ppc" +ppc4xx_deps="ppc" +vsx_deps="altivec" +power8_deps="vsx" + +loongson2_deps="mips" +loongson3_deps="mips" +mips32r2_deps="mips" +mips32r5_deps="mips" +mips32r6_deps="mips" +mips64r2_deps="mips" +mips64r6_deps="mips" +mipsfpu_deps="mips" +mipsdsp_deps="mips" +mipsdspr2_deps="mips" +mmi_deps="mips" +msa_deps="mipsfpu" +msa2_deps="msa" + +cpunop_deps="i686" +x86_64_select="i686" +x86_64_suggest="fast_cmov" + +amd3dnow_deps="mmx" +amd3dnowext_deps="amd3dnow" +i686_deps="x86" +mmx_deps="x86" +mmxext_deps="mmx" +sse_deps="mmxext" +sse2_deps="sse" +sse3_deps="sse2" +ssse3_deps="sse3" +sse4_deps="ssse3" +sse42_deps="sse4" +aesni_deps="sse42" +avx_deps="sse42" +xop_deps="avx" +fma3_deps="avx" +fma4_deps="avx" +avx2_deps="avx" +avx512_deps="avx2" + +mmx_external_deps="x86asm" +mmx_inline_deps="inline_asm x86" +mmx_suggest="mmx_external mmx_inline" + +for ext in $(filter_out mmx $ARCH_EXT_LIST_X86_SIMD); do + eval dep=\$${ext}_deps + eval ${ext}_external_deps='"${dep}_external"' + eval ${ext}_inline_deps='"${dep}_inline"' + eval ${ext}_suggest='"${ext}_external ${ext}_inline"' +done + +aligned_stack_if_any="aarch64 ppc x86" +fast_64bit_if_any="aarch64 alpha ia64 mips64 parisc64 ppc64 sparc64 x86_64" +fast_clz_if_any="aarch64 alpha avr32 mips ppc x86" +fast_unaligned_if_any="aarch64 ppc x86" +simd_align_16_if_any="altivec neon sse" +simd_align_32_if_any="avx" +simd_align_64_if_any="avx512" + +# system capabilities +linux_perf_deps="linux_perf_event_h" +symver_if_any="symver_asm_label symver_gnu_asm" +valgrind_backtrace_conflict="optimizations" +valgrind_backtrace_deps="valgrind_valgrind_h" + +# threading support +atomics_gcc_if="sync_val_compare_and_swap" +atomics_suncc_if="atomic_cas_ptr machine_rw_barrier" +atomics_win32_if="MemoryBarrier" +atomics_native_if_any="$ATOMICS_LIST" +w32threads_deps="atomics_native" +threads_if_any="$THREADS_LIST" + +# subsystems +cbs_av1_select="cbs" +cbs_h264_select="cbs" +cbs_h265_select="cbs" +cbs_jpeg_select="cbs" +cbs_mpeg2_select="cbs" +cbs_vp9_select="cbs" +dct_select="rdft" +dirac_parse_select="golomb" +dnn_suggest="libtensorflow" +error_resilience_select="me_cmp" +faandct_deps="faan" +faandct_select="fdctdsp" +faanidct_deps="faan" +faanidct_select="idctdsp" +h264dsp_select="startcode" +hevcparse_select="golomb" +frame_thread_encoder_deps="encoders threads" +intrax8_select="blockdsp idctdsp" +mdct_select="fft" +mdct15_select="fft" +me_cmp_select="fdctdsp idctdsp pixblockdsp" +mpeg_er_select="error_resilience" +mpegaudio_select="mpegaudiodsp mpegaudioheader" +mpegaudiodsp_select="dct" +mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp me_cmp mpeg_er videodsp" +mpegvideoenc_select="aandcttables me_cmp mpegvideo pixblockdsp qpeldsp" +vc1dsp_select="h264chroma qpeldsp startcode" +rdft_select="fft" + +# decoders / encoders +aac_decoder_select="adts_header mdct15 mdct sinewin" +aac_fixed_decoder_select="adts_header mdct sinewin" +aac_encoder_select="audio_frame_queue iirfilter lpc mdct sinewin" +aac_latm_decoder_select="aac_decoder aac_latm_parser" +ac3_decoder_select="ac3_parser ac3dsp bswapdsp fmtconvert mdct" +ac3_fixed_decoder_select="ac3_parser ac3dsp bswapdsp mdct" +ac3_encoder_select="ac3dsp audiodsp mdct me_cmp" +ac3_fixed_encoder_select="ac3dsp audiodsp mdct me_cmp" +adpcm_g722_decoder_select="g722dsp" +adpcm_g722_encoder_select="g722dsp" +aic_decoder_select="golomb idctdsp" +alac_encoder_select="lpc" +als_decoder_select="bswapdsp" +amrnb_decoder_select="lsp" +amrwb_decoder_select="lsp" +amv_decoder_select="sp5x_decoder exif" +amv_encoder_select="jpegtables mpegvideoenc" +ape_decoder_select="bswapdsp llauddsp" +apng_decoder_deps="zlib" +apng_encoder_deps="zlib" +apng_encoder_select="llvidencdsp" +aptx_decoder_select="audio_frame_queue" +aptx_encoder_select="audio_frame_queue" +aptx_hd_decoder_select="audio_frame_queue" +aptx_hd_encoder_select="audio_frame_queue" +asv1_decoder_select="blockdsp bswapdsp idctdsp" +asv1_encoder_select="aandcttables bswapdsp fdctdsp pixblockdsp" +asv2_decoder_select="blockdsp bswapdsp idctdsp" +asv2_encoder_select="aandcttables bswapdsp fdctdsp pixblockdsp" +atrac1_decoder_select="mdct sinewin" +atrac3_decoder_select="mdct" +atrac3p_decoder_select="mdct sinewin" +atrac9_decoder_select="mdct" +avrn_decoder_select="exif jpegtables" +bink_decoder_select="blockdsp hpeldsp" +binkaudio_dct_decoder_select="mdct rdft dct sinewin wma_freqs" +binkaudio_rdft_decoder_select="mdct rdft sinewin wma_freqs" +cavs_decoder_select="blockdsp golomb h264chroma idctdsp qpeldsp videodsp" +clearvideo_decoder_select="idctdsp" +cllc_decoder_select="bswapdsp" +comfortnoise_encoder_select="lpc" +cook_decoder_select="audiodsp mdct sinewin" +cscd_decoder_select="lzo" +cscd_decoder_suggest="zlib" +dca_decoder_select="mdct" +dds_decoder_select="texturedsp" +dirac_decoder_select="dirac_parse dwt golomb videodsp mpegvideoenc" +dnxhd_decoder_select="blockdsp idctdsp" +dnxhd_encoder_select="blockdsp fdctdsp idctdsp mpegvideoenc pixblockdsp" +dolby_e_decoder_select="mdct" +dvvideo_decoder_select="dvprofile idctdsp" +dvvideo_encoder_select="dvprofile fdctdsp me_cmp pixblockdsp" +dxa_decoder_deps="zlib" +dxv_decoder_select="lzf texturedsp" +eac3_decoder_select="ac3_decoder" +eac3_encoder_select="ac3_encoder" +eamad_decoder_select="aandcttables blockdsp bswapdsp idctdsp mpegvideo" +eatgq_decoder_select="aandcttables" +eatqi_decoder_select="aandcttables blockdsp bswapdsp idctdsp" +exr_decoder_deps="zlib" +ffv1_decoder_select="rangecoder" +ffv1_encoder_select="rangecoder" +ffvhuff_decoder_select="huffyuv_decoder" +ffvhuff_encoder_select="huffyuv_encoder" +fic_decoder_select="golomb" +flac_decoder_select="flacdsp" +flac_encoder_select="bswapdsp flacdsp lpc" +flashsv2_decoder_deps="zlib" +flashsv2_encoder_deps="zlib" +flashsv_decoder_deps="zlib" +flashsv_encoder_deps="zlib" +flv_decoder_select="h263_decoder" +flv_encoder_select="h263_encoder" +fourxm_decoder_select="blockdsp bswapdsp" +fraps_decoder_select="bswapdsp huffman" +g2m_decoder_deps="zlib" +g2m_decoder_select="blockdsp idctdsp jpegtables" +g729_decoder_select="audiodsp" +h261_decoder_select="mpegvideo" +h261_encoder_select="mpegvideoenc" +h263_decoder_select="h263_parser h263dsp mpegvideo qpeldsp" +h263_encoder_select="h263dsp mpegvideoenc" +h263i_decoder_select="h263_decoder" +h263p_decoder_select="h263_decoder" +h263p_encoder_select="h263_encoder" +h264_decoder_select="cabac golomb h264chroma h264dsp h264parse h264pred h264qpel videodsp" +h264_decoder_suggest="error_resilience" +hap_decoder_select="snappy texturedsp" +hap_encoder_deps="libsnappy" +hap_encoder_select="texturedspenc" +hevc_decoder_select="bswapdsp cabac golomb hevcparse videodsp" +huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp" +huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp" +hymt_decoder_select="huffyuv_decoder" +iac_decoder_select="imc_decoder" +imc_decoder_select="bswapdsp fft mdct sinewin" +indeo3_decoder_select="hpeldsp" +indeo4_decoder_select="ividsp" +indeo5_decoder_select="ividsp" +interplay_video_decoder_select="hpeldsp" +jpegls_decoder_select="mjpeg_decoder" +jv_decoder_select="blockdsp" +lagarith_decoder_select="llviddsp" +ljpeg_encoder_select="idctdsp jpegtables mpegvideoenc" +lscr_decoder_deps="zlib" +magicyuv_decoder_select="llviddsp" +magicyuv_encoder_select="llvidencdsp" +mdec_decoder_select="blockdsp idctdsp mpegvideo" +metasound_decoder_select="lsp mdct sinewin" +mimic_decoder_select="blockdsp bswapdsp hpeldsp idctdsp" +mjpeg_decoder_select="blockdsp hpeldsp exif idctdsp jpegtables" +mjpeg_encoder_select="jpegtables mpegvideoenc" +mjpegb_decoder_select="mjpeg_decoder" +mlp_decoder_select="mlp_parser" +mlp_encoder_select="lpc audio_frame_queue" +motionpixels_decoder_select="bswapdsp" +mp1_decoder_select="mpegaudio" +mp1float_decoder_select="mpegaudio" +mp2_decoder_select="mpegaudio" +mp2float_decoder_select="mpegaudio" +mp3_decoder_select="mpegaudio" +mp3adu_decoder_select="mpegaudio" +mp3adufloat_decoder_select="mpegaudio" +mp3float_decoder_select="mpegaudio" +mp3on4_decoder_select="mpegaudio" +mp3on4float_decoder_select="mpegaudio" +mpc7_decoder_select="bswapdsp mpegaudiodsp" +mpc8_decoder_select="mpegaudiodsp" +mpegvideo_decoder_select="mpegvideo" +mpeg1video_decoder_select="mpegvideo" +mpeg1video_encoder_select="mpegvideoenc h263dsp" +mpeg2video_decoder_select="mpegvideo" +mpeg2video_encoder_select="mpegvideoenc h263dsp" +mpeg4_decoder_select="h263_decoder mpeg4video_parser" +mpeg4_encoder_select="h263_encoder" +msa1_decoder_select="mss34dsp" +mscc_decoder_deps="zlib" +msmpeg4v1_decoder_select="h263_decoder" +msmpeg4v2_decoder_select="h263_decoder" +msmpeg4v2_encoder_select="h263_encoder" +msmpeg4v3_decoder_select="h263_decoder" +msmpeg4v3_encoder_select="h263_encoder" +mss2_decoder_select="mpegvideo qpeldsp vc1_decoder" +mts2_decoder_select="mss34dsp" +mwsc_decoder_deps="zlib" +mxpeg_decoder_select="mjpeg_decoder" +nellymoser_decoder_select="mdct sinewin" +nellymoser_encoder_select="audio_frame_queue mdct sinewin" +nuv_decoder_select="idctdsp lzo" +on2avc_decoder_select="mdct" +opus_decoder_deps="swresample" +opus_decoder_select="mdct15" +opus_encoder_select="audio_frame_queue mdct15" +png_decoder_deps="zlib" +png_encoder_deps="zlib" +png_encoder_select="llvidencdsp" +prores_decoder_select="blockdsp idctdsp" +prores_encoder_select="fdctdsp" +qcelp_decoder_select="lsp" +qdm2_decoder_select="mdct rdft mpegaudiodsp" +ra_144_decoder_select="audiodsp" +ra_144_encoder_select="audio_frame_queue lpc audiodsp" +ralf_decoder_select="golomb" +rasc_decoder_deps="zlib" +rawvideo_decoder_select="bswapdsp" +rscc_decoder_deps="zlib" +rtjpeg_decoder_select="me_cmp" +rv10_decoder_select="h263_decoder" +rv10_encoder_select="h263_encoder" +rv20_decoder_select="h263_decoder" +rv20_encoder_select="h263_encoder" +rv30_decoder_select="golomb h264pred h264qpel mpegvideo rv34dsp" +rv40_decoder_select="golomb h264pred h264qpel mpegvideo rv34dsp" +screenpresso_decoder_deps="zlib" +shorten_decoder_select="bswapdsp" +sipr_decoder_select="lsp" +snow_decoder_select="dwt h264qpel hpeldsp me_cmp rangecoder videodsp" +snow_encoder_select="dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder" +sonic_decoder_select="golomb rangecoder" +sonic_encoder_select="golomb rangecoder" +sonic_ls_encoder_select="golomb rangecoder" +sp5x_decoder_select="mjpeg_decoder" +speedhq_decoder_select="mpegvideo" +srgc_decoder_deps="zlib" +svq1_decoder_select="hpeldsp" +svq1_encoder_select="hpeldsp me_cmp mpegvideoenc" +svq3_decoder_select="golomb h264dsp h264parse h264pred hpeldsp tpeldsp videodsp" +svq3_decoder_suggest="zlib" +tak_decoder_select="audiodsp" +tdsc_decoder_deps="zlib" +tdsc_decoder_select="mjpeg_decoder" +theora_decoder_select="vp3_decoder" +thp_decoder_select="mjpeg_decoder" +tiff_decoder_suggest="zlib lzma" +tiff_encoder_suggest="zlib" +truehd_decoder_select="mlp_parser" +truehd_encoder_select="lpc audio_frame_queue" +truemotion2_decoder_select="bswapdsp" +truespeech_decoder_select="bswapdsp" +tscc_decoder_deps="zlib" +twinvq_decoder_select="mdct lsp sinewin" +txd_decoder_select="texturedsp" +utvideo_decoder_select="bswapdsp llviddsp" +utvideo_encoder_select="bswapdsp huffman llvidencdsp" +vble_decoder_select="llviddsp" +vc1_decoder_select="blockdsp h263_decoder h264qpel intrax8 mpegvideo vc1dsp" +vc1image_decoder_select="vc1_decoder" +vorbis_decoder_select="mdct" +vorbis_encoder_select="audio_frame_queue mdct" +vp3_decoder_select="hpeldsp vp3dsp videodsp" +vp4_decoder_select="vp3_decoder" +vp5_decoder_select="h264chroma hpeldsp videodsp vp3dsp vp56dsp" +vp6_decoder_select="h264chroma hpeldsp huffman videodsp vp3dsp vp56dsp" +vp6a_decoder_select="vp6_decoder" +vp6f_decoder_select="vp6_decoder" +vp7_decoder_select="h264pred videodsp vp8dsp" +vp8_decoder_select="h264pred videodsp vp8dsp" +vp9_decoder_select="videodsp vp9_parser vp9_superframe_split_bsf" +wcmv_decoder_deps="zlib" +webp_decoder_select="vp8_decoder exif" +wmalossless_decoder_select="llauddsp" +wmapro_decoder_select="mdct sinewin wma_freqs" +wmav1_decoder_select="mdct sinewin wma_freqs" +wmav1_encoder_select="mdct sinewin wma_freqs" +wmav2_decoder_select="mdct sinewin wma_freqs" +wmav2_encoder_select="mdct sinewin wma_freqs" +wmavoice_decoder_select="lsp rdft dct mdct sinewin" +wmv1_decoder_select="h263_decoder" +wmv1_encoder_select="h263_encoder" +wmv2_decoder_select="blockdsp error_resilience h263_decoder idctdsp intrax8 videodsp wmv2dsp" +wmv2_encoder_select="h263_encoder wmv2dsp" +wmv3_decoder_select="vc1_decoder" +wmv3image_decoder_select="wmv3_decoder" +xma1_decoder_select="wmapro_decoder" +xma2_decoder_select="wmapro_decoder" +zerocodec_decoder_deps="zlib" +zlib_decoder_deps="zlib" +zlib_encoder_deps="zlib" +zmbv_decoder_deps="zlib" +zmbv_encoder_deps="zlib" + +# hardware accelerators +crystalhd_deps="libcrystalhd_libcrystalhd_if_h" +cuda_deps="ffnvcodec" +cuvid_deps="ffnvcodec" +d3d11va_deps="dxva_h ID3D11VideoDecoder ID3D11VideoContext" +dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32 user32" +ffnvcodec_deps_any="libdl LoadLibrary" +nvdec_deps="ffnvcodec" +vaapi_x11_deps="xlib" +videotoolbox_hwaccel_deps="videotoolbox pthreads" +videotoolbox_hwaccel_extralibs="-framework QuartzCore" +xvmc_deps="X11_extensions_XvMClib_h" + +h263_vaapi_hwaccel_deps="vaapi" +h263_vaapi_hwaccel_select="h263_decoder" +h263_videotoolbox_hwaccel_deps="videotoolbox" +h263_videotoolbox_hwaccel_select="h263_decoder" +h264_d3d11va_hwaccel_deps="d3d11va" +h264_d3d11va_hwaccel_select="h264_decoder" +h264_d3d11va2_hwaccel_deps="d3d11va" +h264_d3d11va2_hwaccel_select="h264_decoder" +h264_dxva2_hwaccel_deps="dxva2" +h264_dxva2_hwaccel_select="h264_decoder" +h264_nvdec_hwaccel_deps="nvdec" +h264_nvdec_hwaccel_select="h264_decoder" +h264_vaapi_hwaccel_deps="vaapi" +h264_vaapi_hwaccel_select="h264_decoder" +h264_vdpau_hwaccel_deps="vdpau" +h264_vdpau_hwaccel_select="h264_decoder" +h264_videotoolbox_hwaccel_deps="videotoolbox" +h264_videotoolbox_hwaccel_select="h264_decoder" +hevc_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_HEVC" +hevc_d3d11va_hwaccel_select="hevc_decoder" +hevc_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_HEVC" +hevc_d3d11va2_hwaccel_select="hevc_decoder" +hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" +hevc_dxva2_hwaccel_select="hevc_decoder" +hevc_nvdec_hwaccel_deps="nvdec" +hevc_nvdec_hwaccel_select="hevc_decoder" +hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC" +hevc_vaapi_hwaccel_select="hevc_decoder" +hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" +hevc_vdpau_hwaccel_select="hevc_decoder" +hevc_videotoolbox_hwaccel_deps="videotoolbox" +hevc_videotoolbox_hwaccel_select="hevc_decoder" +mjpeg_nvdec_hwaccel_deps="nvdec" +mjpeg_nvdec_hwaccel_select="mjpeg_decoder" +mjpeg_vaapi_hwaccel_deps="vaapi" +mjpeg_vaapi_hwaccel_select="mjpeg_decoder" +mpeg_xvmc_hwaccel_deps="xvmc" +mpeg_xvmc_hwaccel_select="mpeg2video_decoder" +mpeg1_nvdec_hwaccel_deps="nvdec" +mpeg1_nvdec_hwaccel_select="mpeg1video_decoder" +mpeg1_vdpau_hwaccel_deps="vdpau" +mpeg1_vdpau_hwaccel_select="mpeg1video_decoder" +mpeg1_videotoolbox_hwaccel_deps="videotoolbox" +mpeg1_videotoolbox_hwaccel_select="mpeg1video_decoder" +mpeg1_xvmc_hwaccel_deps="xvmc" +mpeg1_xvmc_hwaccel_select="mpeg1video_decoder" +mpeg2_d3d11va_hwaccel_deps="d3d11va" +mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder" +mpeg2_d3d11va2_hwaccel_deps="d3d11va" +mpeg2_d3d11va2_hwaccel_select="mpeg2video_decoder" +mpeg2_dxva2_hwaccel_deps="dxva2" +mpeg2_dxva2_hwaccel_select="mpeg2video_decoder" +mpeg2_nvdec_hwaccel_deps="nvdec" +mpeg2_nvdec_hwaccel_select="mpeg2video_decoder" +mpeg2_vaapi_hwaccel_deps="vaapi" +mpeg2_vaapi_hwaccel_select="mpeg2video_decoder" +mpeg2_vdpau_hwaccel_deps="vdpau" +mpeg2_vdpau_hwaccel_select="mpeg2video_decoder" +mpeg2_videotoolbox_hwaccel_deps="videotoolbox" +mpeg2_videotoolbox_hwaccel_select="mpeg2video_decoder" +mpeg2_xvmc_hwaccel_deps="xvmc" +mpeg2_xvmc_hwaccel_select="mpeg2video_decoder" +mpeg4_nvdec_hwaccel_deps="nvdec" +mpeg4_nvdec_hwaccel_select="mpeg4_decoder" +mpeg4_vaapi_hwaccel_deps="vaapi" +mpeg4_vaapi_hwaccel_select="mpeg4_decoder" +mpeg4_vdpau_hwaccel_deps="vdpau" +mpeg4_vdpau_hwaccel_select="mpeg4_decoder" +mpeg4_videotoolbox_hwaccel_deps="videotoolbox" +mpeg4_videotoolbox_hwaccel_select="mpeg4_decoder" +vc1_d3d11va_hwaccel_deps="d3d11va" +vc1_d3d11va_hwaccel_select="vc1_decoder" +vc1_d3d11va2_hwaccel_deps="d3d11va" +vc1_d3d11va2_hwaccel_select="vc1_decoder" +vc1_dxva2_hwaccel_deps="dxva2" +vc1_dxva2_hwaccel_select="vc1_decoder" +vc1_nvdec_hwaccel_deps="nvdec" +vc1_nvdec_hwaccel_select="vc1_decoder" +vc1_vaapi_hwaccel_deps="vaapi" +vc1_vaapi_hwaccel_select="vc1_decoder" +vc1_vdpau_hwaccel_deps="vdpau" +vc1_vdpau_hwaccel_select="vc1_decoder" +vp8_nvdec_hwaccel_deps="nvdec" +vp8_nvdec_hwaccel_select="vp8_decoder" +vp8_vaapi_hwaccel_deps="vaapi" +vp8_vaapi_hwaccel_select="vp8_decoder" +vp9_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_VP9" +vp9_d3d11va_hwaccel_select="vp9_decoder" +vp9_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_VP9" +vp9_d3d11va2_hwaccel_select="vp9_decoder" +vp9_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_VP9" +vp9_dxva2_hwaccel_select="vp9_decoder" +vp9_nvdec_hwaccel_deps="nvdec" +vp9_nvdec_hwaccel_select="vp9_decoder" +vp9_vaapi_hwaccel_deps="vaapi VADecPictureParameterBufferVP9_bit_depth" +vp9_vaapi_hwaccel_select="vp9_decoder" +wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel" +wmv3_d3d11va2_hwaccel_select="vc1_d3d11va2_hwaccel" +wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel" +wmv3_nvdec_hwaccel_select="vc1_nvdec_hwaccel" +wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" +wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel" + +# hardware-accelerated codecs +omx_deps="libdl pthreads" +omx_rpi_select="omx" +qsv_deps="libmfx" +qsvdec_select="qsv" +qsvenc_select="qsv" +qsvvpp_select="qsv" +vaapi_encode_deps="vaapi" +v4l2_m2m_deps="linux_videodev2_h sem_timedwait" + +hwupload_cuda_filter_deps="ffnvcodec" +scale_npp_filter_deps="ffnvcodec libnpp" +scale_cuda_filter_deps="ffnvcodec" +scale_cuda_filter_deps_any="cuda_nvcc cuda_llvm" +thumbnail_cuda_filter_deps="ffnvcodec" +thumbnail_cuda_filter_deps_any="cuda_nvcc cuda_llvm" +transpose_npp_filter_deps="ffnvcodec libnpp" + +amf_deps_any="libdl LoadLibrary" +nvenc_deps="ffnvcodec" +nvenc_deps_any="libdl LoadLibrary" +nvenc_encoder_deps="nvenc" + +h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m" +h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m" +h264_amf_encoder_deps="amf" +h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser" +h264_cuvid_decoder_deps="cuvid" +h264_cuvid_decoder_select="h264_mp4toannexb_bsf" +h264_mediacodec_decoder_deps="mediacodec" +h264_mediacodec_decoder_select="h264_mp4toannexb_bsf h264_parser" +h264_mmal_decoder_deps="mmal" +h264_nvenc_encoder_deps="nvenc" +h264_omx_encoder_deps="omx" +h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec" +h264_qsv_encoder_select="qsvenc" +h264_rkmpp_decoder_deps="rkmpp" +h264_rkmpp_decoder_select="h264_mp4toannexb_bsf" +h264_vaapi_encoder_select="cbs_h264 vaapi_encode" +h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m" +h264_v4l2m2m_decoder_select="h264_mp4toannexb_bsf" +h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m" +hevc_amf_encoder_deps="amf" +hevc_cuvid_decoder_deps="cuvid" +hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf" +hevc_mediacodec_decoder_deps="mediacodec" +hevc_mediacodec_decoder_select="hevc_mp4toannexb_bsf hevc_parser" +hevc_nvenc_encoder_deps="nvenc" +hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser qsvdec" +hevc_qsv_encoder_select="hevcparse qsvenc" +hevc_rkmpp_decoder_deps="rkmpp" +hevc_rkmpp_decoder_select="hevc_mp4toannexb_bsf" +hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC" +hevc_vaapi_encoder_select="cbs_h265 vaapi_encode" +hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m" +hevc_v4l2m2m_decoder_select="hevc_mp4toannexb_bsf" +hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m" +mjpeg_cuvid_decoder_deps="cuvid" +mjpeg_qsv_encoder_deps="libmfx" +mjpeg_qsv_encoder_select="qsvenc" +mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG" +mjpeg_vaapi_encoder_select="cbs_jpeg jpegtables vaapi_encode" +mpeg1_cuvid_decoder_deps="cuvid" +mpeg1_v4l2m2m_decoder_deps="v4l2_m2m mpeg1_v4l2_m2m" +mpeg2_crystalhd_decoder_select="crystalhd" +mpeg2_cuvid_decoder_deps="cuvid" +mpeg2_mmal_decoder_deps="mmal" +mpeg2_mediacodec_decoder_deps="mediacodec" +mpeg2_qsv_decoder_select="qsvdec mpegvideo_parser" +mpeg2_qsv_encoder_select="qsvenc" +mpeg2_vaapi_encoder_select="cbs_mpeg2 vaapi_encode" +mpeg2_v4l2m2m_decoder_deps="v4l2_m2m mpeg2_v4l2_m2m" +mpeg4_crystalhd_decoder_select="crystalhd" +mpeg4_cuvid_decoder_deps="cuvid" +mpeg4_mediacodec_decoder_deps="mediacodec" +mpeg4_mmal_decoder_deps="mmal" +mpeg4_omx_encoder_deps="omx" +mpeg4_v4l2m2m_decoder_deps="v4l2_m2m mpeg4_v4l2_m2m" +mpeg4_v4l2m2m_encoder_deps="v4l2_m2m mpeg4_v4l2_m2m" +msmpeg4_crystalhd_decoder_select="crystalhd" +nvenc_h264_encoder_select="h264_nvenc_encoder" +nvenc_hevc_encoder_select="hevc_nvenc_encoder" +vc1_crystalhd_decoder_select="crystalhd" +vc1_cuvid_decoder_deps="cuvid" +vc1_mmal_decoder_deps="mmal" +vc1_qsv_decoder_select="qsvdec vc1_parser" +vc1_v4l2m2m_decoder_deps="v4l2_m2m vc1_v4l2_m2m" +vp8_cuvid_decoder_deps="cuvid" +vp8_mediacodec_decoder_deps="mediacodec" +vp8_qsv_decoder_select="qsvdec vp8_parser" +vp8_rkmpp_decoder_deps="rkmpp" +vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8" +vp8_vaapi_encoder_select="vaapi_encode" +vp8_v4l2m2m_decoder_deps="v4l2_m2m vp8_v4l2_m2m" +vp8_v4l2m2m_encoder_deps="v4l2_m2m vp8_v4l2_m2m" +vp9_cuvid_decoder_deps="cuvid" +vp9_mediacodec_decoder_deps="mediacodec" +vp9_rkmpp_decoder_deps="rkmpp" +vp9_vaapi_encoder_deps="VAEncPictureParameterBufferVP9" +vp9_vaapi_encoder_select="vaapi_encode" +vp9_v4l2m2m_decoder_deps="v4l2_m2m vp9_v4l2_m2m" +wmv3_crystalhd_decoder_select="crystalhd" + +# parsers +aac_parser_select="adts_header" +av1_parser_select="cbs_av1" +h264_parser_select="golomb h264dsp h264parse" +hevc_parser_select="hevcparse" +mpegaudio_parser_select="mpegaudioheader" +mpegvideo_parser_select="mpegvideo" +mpeg4video_parser_select="h263dsp mpegvideo qpeldsp" +vc1_parser_select="vc1dsp" + +# bitstream_filters +aac_adtstoasc_bsf_select="adts_header" +av1_frame_split_bsf_select="cbs_av1" +av1_metadata_bsf_select="cbs_av1" +eac3_core_bsf_select="ac3_parser" +filter_units_bsf_select="cbs" +h264_metadata_bsf_deps="const_nan" +h264_metadata_bsf_select="cbs_h264" +h264_redundant_pps_bsf_select="cbs_h264" +hevc_metadata_bsf_select="cbs_h265" +mjpeg2jpeg_bsf_select="jpegtables" +mpeg2_metadata_bsf_select="cbs_mpeg2" +trace_headers_bsf_select="cbs" +vp9_metadata_bsf_select="cbs_vp9" + +# external libraries +aac_at_decoder_deps="audiotoolbox" +aac_at_decoder_select="aac_adtstoasc_bsf" +ac3_at_decoder_deps="audiotoolbox" +ac3_at_decoder_select="ac3_parser" +adpcm_ima_qt_at_decoder_deps="audiotoolbox" +alac_at_decoder_deps="audiotoolbox" +amr_nb_at_decoder_deps="audiotoolbox" +avisynth_deps_any="libdl LoadLibrary" +avisynth_demuxer_deps="avisynth" +avisynth_demuxer_select="riffdec" +eac3_at_decoder_deps="audiotoolbox" +eac3_at_decoder_select="ac3_parser" +gsm_ms_at_decoder_deps="audiotoolbox" +ilbc_at_decoder_deps="audiotoolbox" +mp1_at_decoder_deps="audiotoolbox" +mp2_at_decoder_deps="audiotoolbox" +mp3_at_decoder_deps="audiotoolbox" +mp1_at_decoder_select="mpegaudioheader" +mp2_at_decoder_select="mpegaudioheader" +mp3_at_decoder_select="mpegaudioheader" +pcm_alaw_at_decoder_deps="audiotoolbox" +pcm_mulaw_at_decoder_deps="audiotoolbox" +qdmc_at_decoder_deps="audiotoolbox" +qdm2_at_decoder_deps="audiotoolbox" +aac_at_encoder_deps="audiotoolbox" +aac_at_encoder_select="audio_frame_queue" +alac_at_encoder_deps="audiotoolbox" +alac_at_encoder_select="audio_frame_queue" +ilbc_at_encoder_deps="audiotoolbox" +ilbc_at_encoder_select="audio_frame_queue" +pcm_alaw_at_encoder_deps="audiotoolbox" +pcm_alaw_at_encoder_select="audio_frame_queue" +pcm_mulaw_at_encoder_deps="audiotoolbox" +pcm_mulaw_at_encoder_select="audio_frame_queue" +chromaprint_muxer_deps="chromaprint" +h264_videotoolbox_encoder_deps="pthreads" +h264_videotoolbox_encoder_select="videotoolbox_encoder" +hevc_videotoolbox_encoder_deps="pthreads" +hevc_videotoolbox_encoder_select="videotoolbox_encoder" +libaom_av1_decoder_deps="libaom" +libaom_av1_encoder_deps="libaom" +libaom_av1_encoder_select="extract_extradata_bsf" +libaribb24_decoder_deps="libaribb24" +libcelt_decoder_deps="libcelt" +libcodec2_decoder_deps="libcodec2" +libcodec2_encoder_deps="libcodec2" +libdav1d_decoder_deps="libdav1d" +libdavs2_decoder_deps="libdavs2" +libfdk_aac_decoder_deps="libfdk_aac" +libfdk_aac_encoder_deps="libfdk_aac" +libfdk_aac_encoder_select="audio_frame_queue" +libgme_demuxer_deps="libgme" +libgsm_decoder_deps="libgsm" +libgsm_encoder_deps="libgsm" +libgsm_ms_decoder_deps="libgsm" +libgsm_ms_encoder_deps="libgsm" +libilbc_decoder_deps="libilbc" +libilbc_encoder_deps="libilbc" +libkvazaar_encoder_deps="libkvazaar" +libmodplug_demuxer_deps="libmodplug" +libmp3lame_encoder_deps="libmp3lame" +libmp3lame_encoder_select="audio_frame_queue mpegaudioheader" +libopencore_amrnb_decoder_deps="libopencore_amrnb" +libopencore_amrnb_encoder_deps="libopencore_amrnb" +libopencore_amrnb_encoder_select="audio_frame_queue" +libopencore_amrwb_decoder_deps="libopencore_amrwb" +libopenh264_decoder_deps="libopenh264" +libopenh264_decoder_select="h264_mp4toannexb_bsf" +libopenh264_encoder_deps="libopenh264" +libopenjpeg_decoder_deps="libopenjpeg" +libopenjpeg_encoder_deps="libopenjpeg" +libopenmpt_demuxer_deps="libopenmpt" +libopus_decoder_deps="libopus" +libopus_encoder_deps="libopus" +libopus_encoder_select="audio_frame_queue" +librsvg_decoder_deps="librsvg" +libshine_encoder_deps="libshine" +libshine_encoder_select="audio_frame_queue" +libspeex_decoder_deps="libspeex" +libspeex_encoder_deps="libspeex" +libspeex_encoder_select="audio_frame_queue" +libtheora_encoder_deps="libtheora" +libtwolame_encoder_deps="libtwolame" +libvo_amrwbenc_encoder_deps="libvo_amrwbenc" +libvorbis_decoder_deps="libvorbis" +libvorbis_encoder_deps="libvorbis libvorbisenc" +libvorbis_encoder_select="audio_frame_queue" +libvpx_vp8_decoder_deps="libvpx" +libvpx_vp8_encoder_deps="libvpx" +libvpx_vp9_decoder_deps="libvpx" +libvpx_vp9_encoder_deps="libvpx" +libwavpack_encoder_deps="libwavpack" +libwavpack_encoder_select="audio_frame_queue" +libwebp_encoder_deps="libwebp" +libwebp_anim_encoder_deps="libwebp" +libx262_encoder_deps="libx262" +libx264_encoder_deps="libx264" +libx264rgb_encoder_deps="libx264 x264_csp_bgr" +libx264rgb_encoder_select="libx264_encoder" +libx265_encoder_deps="libx265" +libxavs_encoder_deps="libxavs" +libxavs2_encoder_deps="libxavs2" +libxvid_encoder_deps="libxvid" +libzvbi_teletext_decoder_deps="libzvbi" +vapoursynth_demuxer_deps="vapoursynth" +videotoolbox_suggest="coreservices" +videotoolbox_deps="corefoundation coremedia corevideo" +videotoolbox_encoder_deps="videotoolbox VTCompressionSessionPrepareToEncodeFrames" + +# demuxers / muxers +ac3_demuxer_select="ac3_parser" +aiff_muxer_select="iso_media" +asf_demuxer_select="riffdec" +asf_o_demuxer_select="riffdec" +asf_muxer_select="riffenc" +asf_stream_muxer_select="asf_muxer" +avi_demuxer_select="iso_media riffdec exif" +avi_muxer_select="riffenc" +caf_demuxer_select="iso_media riffdec" +caf_muxer_select="iso_media" +dash_muxer_select="mp4_muxer" +dash_demuxer_deps="libxml2" +dirac_demuxer_select="dirac_parser" +dts_demuxer_select="dca_parser" +dtshd_demuxer_select="dca_parser" +dv_demuxer_select="dvprofile" +dv_muxer_select="dvprofile" +dxa_demuxer_select="riffdec" +eac3_demuxer_select="ac3_parser" +f4v_muxer_select="mov_muxer" +fifo_muxer_deps="threads" +flac_demuxer_select="flac_parser" +hds_muxer_select="flv_muxer" +hls_muxer_select="mpegts_muxer" +hls_muxer_suggest="gcrypt openssl" +image2_alias_pix_demuxer_select="image2_demuxer" +image2_brender_pix_demuxer_select="image2_demuxer" +ipod_muxer_select="mov_muxer" +ismv_muxer_select="mov_muxer" +ivf_muxer_select="av1_metadata_bsf vp9_superframe_bsf" +matroska_audio_muxer_select="matroska_muxer" +matroska_demuxer_select="iso_media riffdec" +matroska_demuxer_suggest="bzlib lzo zlib" +matroska_muxer_select="iso_media riffenc" +mmf_muxer_select="riffenc" +mov_demuxer_select="iso_media riffdec" +mov_demuxer_suggest="zlib" +mov_muxer_select="iso_media riffenc rtpenc_chain" +mp3_demuxer_select="mpegaudio_parser" +mp3_muxer_select="mpegaudioheader" +mp4_muxer_select="mov_muxer" +mpegts_demuxer_select="iso_media" +mpegts_muxer_select="adts_muxer latm_muxer" +mpegtsraw_demuxer_select="mpegts_demuxer" +mxf_d10_muxer_select="mxf_muxer" +mxf_opatom_muxer_select="mxf_muxer" +nut_muxer_select="riffenc" +nuv_demuxer_select="riffdec" +oga_muxer_select="ogg_muxer" +ogg_demuxer_select="dirac_parse" +ogv_muxer_select="ogg_muxer" +opus_muxer_select="ogg_muxer" +psp_muxer_select="mov_muxer" +rtp_demuxer_select="sdp_demuxer" +rtp_muxer_select="golomb" +rtpdec_select="asf_demuxer jpegtables mov_demuxer mpegts_demuxer rm_demuxer rtp_protocol srtp" +rtsp_demuxer_select="http_protocol rtpdec" +rtsp_muxer_select="rtp_muxer http_protocol rtp_protocol rtpenc_chain" +sap_demuxer_select="sdp_demuxer" +sap_muxer_select="rtp_muxer rtp_protocol rtpenc_chain" +sdp_demuxer_select="rtpdec" +smoothstreaming_muxer_select="ismv_muxer" +spdif_demuxer_select="adts_header" +spdif_muxer_select="adts_header" +spx_muxer_select="ogg_muxer" +swf_demuxer_suggest="zlib" +tak_demuxer_select="tak_parser" +tg2_muxer_select="mov_muxer" +tgp_muxer_select="mov_muxer" +vobsub_demuxer_select="mpegps_demuxer" +w64_demuxer_select="wav_demuxer" +w64_muxer_select="wav_muxer" +wav_demuxer_select="riffdec" +wav_muxer_select="riffenc" +webm_muxer_select="iso_media riffenc" +webm_dash_manifest_demuxer_select="matroska_demuxer" +wtv_demuxer_select="mpegts_demuxer riffdec" +wtv_muxer_select="mpegts_muxer riffenc" +xmv_demuxer_select="riffdec" +xwma_demuxer_select="riffdec" + +# indevs / outdevs +android_camera_indev_deps="android camera2ndk mediandk pthreads" +android_camera_indev_extralibs="-landroid -lcamera2ndk -lmediandk" +alsa_indev_deps="alsa" +alsa_outdev_deps="alsa" +avfoundation_indev_deps="avfoundation corevideo coremedia pthreads" +avfoundation_indev_suggest="coregraphics applicationservices" +avfoundation_indev_extralibs="-framework Foundation" +bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h" +caca_outdev_deps="libcaca" +decklink_deps_any="libdl LoadLibrary" +decklink_indev_deps="decklink threads" +decklink_indev_extralibs="-lstdc++" +decklink_outdev_deps="decklink threads" +decklink_outdev_suggest="libklvanc" +decklink_outdev_extralibs="-lstdc++" +dshow_indev_deps="IBaseFilter" +dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid -loleaut32 -lshlwapi" +fbdev_indev_deps="linux_fb_h" +fbdev_outdev_deps="linux_fb_h" +gdigrab_indev_deps="CreateDIBSection" +gdigrab_indev_extralibs="-lgdi32" +gdigrab_indev_select="bmp_decoder" +iec61883_indev_deps="libiec61883" +jack_indev_deps="libjack" +jack_indev_deps_any="sem_timedwait dispatch_dispatch_h" +kmsgrab_indev_deps="libdrm" +lavfi_indev_deps="avfilter" +libcdio_indev_deps="libcdio" +libdc1394_indev_deps="libdc1394" +openal_indev_deps="openal" +opengl_outdev_deps="opengl" +opengl_outdev_suggest="sdl2" +oss_indev_deps_any="sys_soundcard_h" +oss_outdev_deps_any="sys_soundcard_h" +pulse_indev_deps="libpulse" +pulse_outdev_deps="libpulse" +sdl2_outdev_deps="sdl2" +sndio_indev_deps="sndio" +sndio_outdev_deps="sndio" +v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" +v4l2_indev_suggest="libv4l2" +v4l2_outdev_deps_any="linux_videodev2_h sys_videoio_h" +v4l2_outdev_suggest="libv4l2" +vfwcap_indev_deps="vfw32 vfwcap_defines" +xcbgrab_indev_deps="libxcb" +xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes" +xv_outdev_deps="xlib" + +# protocols +async_protocol_deps="threads" +bluray_protocol_deps="libbluray" +ffrtmpcrypt_protocol_conflict="librtmp_protocol" +ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl mbedtls" +ffrtmpcrypt_protocol_select="tcp_protocol" +ffrtmphttp_protocol_conflict="librtmp_protocol" +ffrtmphttp_protocol_select="http_protocol" +ftp_protocol_select="tcp_protocol" +gopher_protocol_select="network" +http_protocol_select="tcp_protocol" +http_protocol_suggest="zlib" +httpproxy_protocol_select="tcp_protocol" +httpproxy_protocol_suggest="zlib" +https_protocol_select="tls_protocol" +https_protocol_suggest="zlib" +icecast_protocol_select="http_protocol" +mmsh_protocol_select="http_protocol" +mmst_protocol_select="network" +rtmp_protocol_conflict="librtmp_protocol" +rtmp_protocol_select="tcp_protocol" +rtmp_protocol_suggest="zlib" +rtmpe_protocol_select="ffrtmpcrypt_protocol" +rtmpe_protocol_suggest="zlib" +rtmps_protocol_conflict="librtmp_protocol" +rtmps_protocol_select="tls_protocol" +rtmps_protocol_suggest="zlib" +rtmpt_protocol_select="ffrtmphttp_protocol" +rtmpt_protocol_suggest="zlib" +rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol" +rtmpte_protocol_suggest="zlib" +rtmpts_protocol_select="ffrtmphttp_protocol https_protocol" +rtmpts_protocol_suggest="zlib" +rtp_protocol_select="udp_protocol" +schannel_conflict="openssl gnutls libtls mbedtls" +sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags" +sctp_protocol_select="network" +securetransport_conflict="openssl gnutls libtls mbedtls" +srtp_protocol_select="rtp_protocol srtp" +tcp_protocol_select="network" +tls_protocol_deps_any="gnutls openssl schannel securetransport libtls mbedtls" +tls_protocol_select="tcp_protocol" +udp_protocol_select="network" +udplite_protocol_select="network" +unix_protocol_deps="sys_un_h" +unix_protocol_select="network" + +# external library protocols +librtmp_protocol_deps="librtmp" +librtmpe_protocol_deps="librtmp" +librtmps_protocol_deps="librtmp" +librtmpt_protocol_deps="librtmp" +librtmpte_protocol_deps="librtmp" +libsmbclient_protocol_deps="libsmbclient gplv3" +libsrt_protocol_deps="libsrt" +libsrt_protocol_select="network" +libssh_protocol_deps="libssh" +libtls_conflict="openssl gnutls mbedtls" + +# filters +afftdn_filter_deps="avcodec" +afftdn_filter_select="fft" +afftfilt_filter_deps="avcodec" +afftfilt_filter_select="fft" +afir_filter_deps="avcodec" +afir_filter_select="fft" +amovie_filter_deps="avcodec avformat" +aresample_filter_deps="swresample" +asr_filter_deps="pocketsphinx" +ass_filter_deps="libass" +atempo_filter_deps="avcodec" +atempo_filter_select="rdft" +avgblur_opencl_filter_deps="opencl" +azmq_filter_deps="libzmq" +blackframe_filter_deps="gpl" +bm3d_filter_deps="avcodec" +bm3d_filter_select="dct" +boxblur_filter_deps="gpl" +boxblur_opencl_filter_deps="opencl gpl" +bs2b_filter_deps="libbs2b" +colorkey_opencl_filter_deps="opencl" +colormatrix_filter_deps="gpl" +convolution_opencl_filter_deps="opencl" +convolve_filter_deps="avcodec" +convolve_filter_select="fft" +coreimage_filter_deps="coreimage appkit" +coreimage_filter_extralibs="-framework OpenGL" +coreimagesrc_filter_deps="coreimage appkit" +coreimagesrc_filter_extralibs="-framework OpenGL" +cover_rect_filter_deps="avcodec avformat gpl" +cropdetect_filter_deps="gpl" +deconvolve_filter_deps="avcodec" +deconvolve_filter_select="fft" +deinterlace_qsv_filter_deps="libmfx" +deinterlace_vaapi_filter_deps="vaapi" +delogo_filter_deps="gpl" +denoise_vaapi_filter_deps="vaapi" +derain_filter_select="dnn" +deshake_filter_select="pixelutils" +dilation_opencl_filter_deps="opencl" +drawtext_filter_deps="libfreetype" +drawtext_filter_suggest="libfontconfig libfribidi" +elbg_filter_deps="avcodec" +eq_filter_deps="gpl" +erosion_opencl_filter_deps="opencl" +fftfilt_filter_deps="avcodec" +fftfilt_filter_select="rdft" +fftdnoiz_filter_deps="avcodec" +fftdnoiz_filter_select="fft" +find_rect_filter_deps="avcodec avformat gpl" +firequalizer_filter_deps="avcodec" +firequalizer_filter_select="rdft" +flite_filter_deps="libflite" +framerate_filter_select="scene_sad" +freezedetect_filter_select="scene_sad" +frei0r_filter_deps="frei0r libdl" +frei0r_src_filter_deps="frei0r libdl" +fspp_filter_deps="gpl" +geq_filter_deps="gpl" +histeq_filter_deps="gpl" +hqdn3d_filter_deps="gpl" +interlace_filter_deps="gpl" +kerndeint_filter_deps="gpl" +ladspa_filter_deps="ladspa libdl" +lensfun_filter_deps="liblensfun version3" +lv2_filter_deps="lv2" +mcdeint_filter_deps="avcodec gpl" +movie_filter_deps="avcodec avformat" +mpdecimate_filter_deps="gpl" +mpdecimate_filter_select="pixelutils" +minterpolate_filter_select="scene_sad" +mptestsrc_filter_deps="gpl" +negate_filter_deps="lut_filter" +nlmeans_opencl_filter_deps="opencl" +nnedi_filter_deps="gpl" +ocr_filter_deps="libtesseract" +ocv_filter_deps="libopencv" +openclsrc_filter_deps="opencl" +overlay_opencl_filter_deps="opencl" +overlay_qsv_filter_deps="libmfx" +overlay_qsv_filter_select="qsvvpp" +owdenoise_filter_deps="gpl" +pan_filter_deps="swresample" +perspective_filter_deps="gpl" +phase_filter_deps="gpl" +pp7_filter_deps="gpl" +pp_filter_deps="gpl postproc" +prewitt_opencl_filter_deps="opencl" +procamp_vaapi_filter_deps="vaapi" +program_opencl_filter_deps="opencl" +pullup_filter_deps="gpl" +removelogo_filter_deps="avcodec avformat swscale" +repeatfields_filter_deps="gpl" +resample_filter_deps="avresample" +roberts_opencl_filter_deps="opencl" +rubberband_filter_deps="librubberband" +sab_filter_deps="gpl swscale" +scale2ref_filter_deps="swscale" +scale_filter_deps="swscale" +scale_qsv_filter_deps="libmfx" +select_filter_select="scene_sad" +sharpness_vaapi_filter_deps="vaapi" +showcqt_filter_deps="avcodec avformat swscale" +showcqt_filter_suggest="libfontconfig libfreetype" +showcqt_filter_select="fft" +showfreqs_filter_deps="avcodec" +showfreqs_filter_select="fft" +showspectrum_filter_deps="avcodec" +showspectrum_filter_select="fft" +showspectrumpic_filter_deps="avcodec" +showspectrumpic_filter_select="fft" +signature_filter_deps="gpl avcodec avformat" +smartblur_filter_deps="gpl swscale" +sobel_opencl_filter_deps="opencl" +sofalizer_filter_deps="libmysofa avcodec" +sofalizer_filter_select="fft" +spectrumsynth_filter_deps="avcodec" +spectrumsynth_filter_select="fft" +spp_filter_deps="gpl avcodec" +spp_filter_select="fft idctdsp fdctdsp me_cmp pixblockdsp" +sr_filter_deps="avformat swscale" +sr_filter_select="dnn" +stereo3d_filter_deps="gpl" +subtitles_filter_deps="avformat avcodec libass" +super2xsai_filter_deps="gpl" +pixfmts_super2xsai_test_deps="super2xsai_filter" +tinterlace_filter_deps="gpl" +tinterlace_merge_test_deps="tinterlace_filter" +tinterlace_pad_test_deps="tinterlace_filter" +tonemap_filter_deps="const_nan" +tonemap_opencl_filter_deps="opencl const_nan" +transpose_opencl_filter_deps="opencl" +transpose_vaapi_filter_deps="vaapi VAProcPipelineCaps_rotation_flags" +unsharp_opencl_filter_deps="opencl" +uspp_filter_deps="gpl avcodec" +vaguedenoiser_filter_deps="gpl" +vidstabdetect_filter_deps="libvidstab" +vidstabtransform_filter_deps="libvidstab" +libvmaf_filter_deps="libvmaf pthreads" +zmq_filter_deps="libzmq" +zoompan_filter_deps="swscale" +zscale_filter_deps="libzimg const_nan" +scale_vaapi_filter_deps="vaapi" +vpp_qsv_filter_deps="libmfx" +vpp_qsv_filter_select="qsvvpp" +yadif_cuda_filter_deps="ffnvcodec" +yadif_cuda_filter_deps_any="cuda_nvcc cuda_llvm" + +# examples +avio_dir_cmd_deps="avformat avutil" +avio_reading_deps="avformat avcodec avutil" +decode_audio_example_deps="avcodec avutil" +decode_video_example_deps="avcodec avutil" +demuxing_decoding_example_deps="avcodec avformat avutil" +encode_audio_example_deps="avcodec avutil" +encode_video_example_deps="avcodec avutil" +extract_mvs_example_deps="avcodec avformat avutil" +filter_audio_example_deps="avfilter avutil" +filtering_audio_example_deps="avfilter avcodec avformat avutil" +filtering_video_example_deps="avfilter avcodec avformat avutil" +http_multiclient_example_deps="avformat avutil fork" +hw_decode_example_deps="avcodec avformat avutil" +metadata_example_deps="avformat avutil" +muxing_example_deps="avcodec avformat avutil swscale" +qsvdec_example_deps="avcodec avutil libmfx h264_qsv_decoder" +remuxing_example_deps="avcodec avformat avutil" +resampling_audio_example_deps="avutil swresample" +scaling_video_example_deps="avutil swscale" +transcode_aac_example_deps="avcodec avformat swresample" +transcoding_example_deps="avfilter avcodec avformat avutil" +vaapi_encode_example_deps="avcodec avutil h264_vaapi_encoder" +vaapi_transcode_example_deps="avcodec avformat avutil h264_vaapi_encoder" + +# EXTRALIBS_LIST +cpu_init_extralibs="pthreads_extralibs" +cws2fws_extralibs="zlib_extralibs" + +# libraries, in any order +avcodec_deps="avutil" +avcodec_suggest="libm" +avcodec_select="null_bsf" +avdevice_deps="avformat avcodec avutil" +avdevice_suggest="libm" +avfilter_deps="avutil" +avfilter_suggest="libm" +avformat_deps="avcodec avutil" +avformat_suggest="libm network zlib" +avresample_deps="avutil" +avresample_suggest="libm" +avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 vaapi videotoolbox corefoundation corevideo coremedia bcrypt" +postproc_deps="avutil gpl" +postproc_suggest="libm" +swresample_deps="avutil" +swresample_suggest="libm libsoxr" +swscale_deps="avutil" +swscale_suggest="libm" + +avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs" +avfilter_extralibs="pthreads_extralibs" +avutil_extralibs="d3d11va_extralibs nanosleep_extralibs pthreads_extralibs vaapi_drm_extralibs vaapi_x11_extralibs vdpau_x11_extralibs" + +# programs +ffmpeg_deps="avcodec avfilter avformat" +ffmpeg_select="aformat_filter anull_filter atrim_filter format_filter + hflip_filter null_filter + transpose_filter trim_filter vflip_filter" +ffmpeg_suggest="ole32 psapi shell32" +ffplay_deps="avcodec avformat swscale swresample sdl2" +ffplay_select="rdft crop_filter transpose_filter hflip_filter vflip_filter rotate_filter" +ffplay_suggest="shell32" +ffprobe_deps="avcodec avformat" +ffprobe_suggest="shell32" + +# documentation +podpages_deps="perl" +manpages_deps="perl pod2man" +htmlpages_deps="perl" +htmlpages_deps_any="makeinfo_html texi2html" +txtpages_deps="perl makeinfo" +doc_deps_any="manpages htmlpages podpages txtpages" + +# default parameters + +logfile="ffbuild/config.log" + +# installation paths +prefix_default="/usr/local" +bindir_default='${prefix}/bin' +datadir_default='${prefix}/share/ffmpeg' +docdir_default='${prefix}/share/doc/ffmpeg' +incdir_default='${prefix}/include' +libdir_default='${prefix}/lib' +mandir_default='${prefix}/share/man' + +# toolchain +ar_default="ar" +cc_default="gcc" +cxx_default="g++" +host_cc_default="gcc" +doxygen_default="doxygen" +install="install" +ln_s_default="ln -s -f" +nm_default="nm -g" +pkg_config_default=pkg-config +ranlib_default="ranlib" +strip_default="strip" +version_script='--version-script' +objformat="elf32" +x86asmexe_default="nasm" +windres_default="windres" +striptype="direct" + +# OS +target_os_default=$(tolower $(uname -s)) +host_os=$target_os_default + +# machine +if test "$target_os_default" = aix; then + arch_default=$(uname -p) + strip_default="strip -X32_64" + nm_default="nm -g -X32_64" +else + arch_default=$(uname -m) +fi +cpu="generic" +intrinsics="none" + +# configurable options +enable $PROGRAM_LIST +enable $DOCUMENT_LIST +enable $EXAMPLE_LIST +enable $(filter_out avresample $LIBRARY_LIST) +enable stripping + +enable asm +enable debug +enable doc +enable faan faandct faanidct +enable optimizations +enable runtime_cpudetect +enable safe_bitstream_reader +enable static +enable swscale_alpha +enable valgrind_backtrace + +sws_max_filter_size_default=256 +set_default sws_max_filter_size + +# internal components are enabled by default +enable $EXTRALIBS_LIST + +# Avoid external, non-system, libraries getting enabled by dependency resolution +disable $EXTERNAL_LIBRARY_LIST $HWACCEL_LIBRARY_LIST + +# build settings +SHFLAGS='-shared -Wl,-soname,$$(@F)' +LIBPREF="lib" +LIBSUF=".a" +FULLNAME='$(NAME)$(BUILDSUF)' +LIBNAME='$(LIBPREF)$(FULLNAME)$(LIBSUF)' +SLIBPREF="lib" +SLIBSUF=".so" +SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)' +SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)' +SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)' +LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"' +SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)' +SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)' +VERSION_SCRIPT_POSTPROCESS_CMD="cat" + +asflags_filter=echo +cflags_filter=echo +ldflags_filter=echo + +AS_C='-c' +AS_O='-o $@' +CC_C='-c' +CC_E='-E -o $@' +CC_O='-o $@' +CXX_C='-c' +CXX_O='-o $@' +OBJCC_C='-c' +OBJCC_E='-E -o $@' +OBJCC_O='-o $@' +X86ASM_O='-o $@' +LD_O='-o $@' +LD_LIB='-l%' +LD_PATH='-L' +HOSTCC_C='-c' +HOSTCC_E='-E -o $@' +HOSTCC_O='-o $@' +HOSTLD_O='-o $@' +NVCC_C='-c' +NVCC_O='-o $@' + +host_extralibs='-lm' +host_cflags_filter=echo +host_ldflags_filter=echo + +target_path='$(CURDIR)' + +# since the object filename is not given with the -MM flag, the compiler +# is only able to print the basename, and we must add the path ourselves +DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>/dev/null | sed -e "/^\#.*/d" -e "s,^[[:space:]]*$(@F),$(@D)/$(@F)," > $(@:.o=.d)' +DEPFLAGS='-MM' + +mkdir -p ffbuild + +# find source path +if test -f configure; then + source_path=. +elif test -f src/configure; then + source_path=src +else + source_path=$(cd $(dirname "$0"); pwd) + case "$source_path" in + *[[:blank:]]*) die "Out of tree builds are impossible with whitespace in source path." ;; + esac + test -e "$source_path/config.h" && + die "Out of tree builds are impossible with config.h in source dir." +fi + +for v in "$@"; do + r=${v#*=} + l=${v%"$r"} + r=$(sh_quote "$r") + FFMPEG_CONFIGURATION="${FFMPEG_CONFIGURATION# } ${l}${r}" +done + +find_things_extern(){ + thing=$1 + pattern=$2 + file=$source_path/$3 + out=${4:-$thing} + sed -n "s/^[^#]*extern.*$pattern *ff_\([^ ]*\)_$thing;/\1_$out/p" "$file" +} + +find_filters_extern(){ + file=$source_path/$1 + sed -n 's/^extern AVFilter ff_[avfsinkrc]\{2,5\}_\([[:alnum:]_]\{1,\}\);/\1_filter/p' $file +} + +FILTER_LIST=$(find_filters_extern libavfilter/allfilters.c) +OUTDEV_LIST=$(find_things_extern muxer AVOutputFormat libavdevice/alldevices.c outdev) +INDEV_LIST=$(find_things_extern demuxer AVInputFormat libavdevice/alldevices.c indev) +MUXER_LIST=$(find_things_extern muxer AVOutputFormat libavformat/allformats.c) +DEMUXER_LIST=$(find_things_extern demuxer AVInputFormat libavformat/allformats.c) +ENCODER_LIST=$(find_things_extern encoder AVCodec libavcodec/allcodecs.c) +DECODER_LIST=$(find_things_extern decoder AVCodec libavcodec/allcodecs.c) +CODEC_LIST=" + $ENCODER_LIST + $DECODER_LIST +" +PARSER_LIST=$(find_things_extern parser AVCodecParser libavcodec/parsers.c) +BSF_LIST=$(find_things_extern bsf AVBitStreamFilter libavcodec/bitstream_filters.c) +HWACCEL_LIST=$(find_things_extern hwaccel AVHWAccel libavcodec/hwaccels.h) +PROTOCOL_LIST=$(find_things_extern protocol URLProtocol libavformat/protocols.c) + +AVCODEC_COMPONENTS_LIST=" + $BSF_LIST + $DECODER_LIST + $ENCODER_LIST + $HWACCEL_LIST + $PARSER_LIST +" + +AVDEVICE_COMPONENTS_LIST=" + $INDEV_LIST + $OUTDEV_LIST +" + +AVFILTER_COMPONENTS_LIST=" + $FILTER_LIST +" + +AVFORMAT_COMPONENTS_LIST=" + $DEMUXER_LIST + $MUXER_LIST + $PROTOCOL_LIST +" + +ALL_COMPONENTS=" + $AVCODEC_COMPONENTS_LIST + $AVDEVICE_COMPONENTS_LIST + $AVFILTER_COMPONENTS_LIST + $AVFORMAT_COMPONENTS_LIST +" + +for n in $COMPONENT_LIST; do + v=$(toupper ${n%s})_LIST + eval enable \$$v + eval ${n}_if_any="\$$v" +done + +enable $ARCH_EXT_LIST + +die_unknown(){ + echo "Unknown option \"$1\"." + echo "See $0 --help for available options." + exit 1 +} + +print_in_columns() { + tr ' ' '\n' | sort | tr '\r\n' ' ' | awk -v col_width=24 -v width="$ncols" ' + { + num_cols = width > col_width ? int(width / col_width) : 1; + num_rows = int((NF + num_cols-1) / num_cols); + y = x = 1; + for (y = 1; y <= num_rows; y++) { + i = y; + for (x = 1; x <= num_cols; x++) { + if (i <= NF) { + line = sprintf("%s%-" col_width "s", line, $i); + } + i = i + num_rows; + } + print line; line = ""; + } + }' | sed 's/ *$//' +} + +show_list() { + suffix=_$1 + shift + echo $* | sed s/$suffix//g | print_in_columns + exit 0 +} + +rand_list(){ + IFS=', ' + set -- $* + unset IFS + for thing; do + comp=${thing%:*} + prob=${thing#$comp} + prob=${prob#:} + is_in ${comp} $COMPONENT_LIST && eval comp=\$$(toupper ${comp%s})_LIST + echo "prob ${prob:-0.5}" + printf '%s\n' $comp + done +} + +do_random(){ + action=$1 + shift + random_seed=$(awk "BEGIN { srand($random_seed); print srand() }") + $action $(rand_list "$@" | awk "BEGIN { srand($random_seed) } \$1 == \"prob\" { prob = \$2; next } rand() < prob { print }") +} + +for opt do + optval="${opt#*=}" + case "$opt" in + --extra-ldflags=*) + add_ldflags $optval + ;; + --extra-ldexeflags=*) + add_ldexeflags $optval + ;; + --extra-ldsoflags=*) + add_ldsoflags $optval + ;; + --extra-ldlibflags=*) + warn "The --extra-ldlibflags option is only provided for compatibility and will be\n"\ + "removed in the future. Use --extra-ldsoflags instead." + add_ldsoflags $optval + ;; + --extra-libs=*) + add_extralibs $optval + ;; + --disable-devices) + disable $INDEV_LIST $OUTDEV_LIST + ;; + --enable-debug=*) + debuglevel="$optval" + ;; + --disable-programs) + disable $PROGRAM_LIST + ;; + --disable-everything) + map 'eval unset \${$(toupper ${v%s})_LIST}' $COMPONENT_LIST + ;; + --disable-all) + map 'eval unset \${$(toupper ${v%s})_LIST}' $COMPONENT_LIST + disable $LIBRARY_LIST $PROGRAM_LIST doc + enable avutil + ;; + --enable-random|--disable-random) + action=${opt%%-random} + do_random ${action#--} $COMPONENT_LIST + ;; + --enable-random=*|--disable-random=*) + action=${opt%%-random=*} + do_random ${action#--} $optval + ;; + --enable-sdl) + enable sdl2 + ;; + --enable-*=*|--disable-*=*) + eval $(echo "${opt%%=*}" | sed 's/--/action=/;s/-/ thing=/') + is_in "${thing}s" $COMPONENT_LIST || die_unknown "$opt" + eval list=\$$(toupper $thing)_LIST + name=$(echo "${optval}" | sed "s/,/_${thing}|/g")_${thing} + list=$(filter "$name" $list) + [ "$list" = "" ] && warn "Option $opt did not match anything" + test $action = enable && warn_if_gets_disabled $list + $action $list + ;; + --enable-yasm|--disable-yasm) + warn "The ${opt} option is only provided for compatibility and will be\n"\ + "removed in the future. Use --enable-x86asm / --disable-x86asm instead." + test $opt = --enable-yasm && x86asm=yes || x86asm=no + ;; + --yasmexe=*) + warn "The --yasmexe option is only provided for compatibility and will be\n"\ + "removed in the future. Use --x86asmexe instead." + x86asmexe="$optval" + ;; + --enable-?*|--disable-?*) + eval $(echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g') + if is_in $option $COMPONENT_LIST; then + test $action = disable && action=unset + eval $action \$$(toupper ${option%s})_LIST + elif is_in $option $CMDLINE_SELECT; then + $action $option + else + die_unknown $opt + fi + ;; + --list-*) + NAME="${opt#--list-}" + is_in $NAME $COMPONENT_LIST || die_unknown $opt + NAME=${NAME%s} + eval show_list $NAME \$$(toupper $NAME)_LIST + ;; + --help|-h) show_help + ;; + --quiet|-q) quiet=yes + ;; + --fatal-warnings) enable fatal_warnings + ;; + --libfuzzer=*) + libfuzzer_path="$optval" + ;; + *) + optname="${opt%%=*}" + optname="${optname#--}" + optname=$(echo "$optname" | sed 's/-/_/g') + if is_in $optname $CMDLINE_SET; then + eval $optname='$optval' + elif is_in $optname $CMDLINE_APPEND; then + append $optname "$optval" + else + die_unknown $opt + fi + ;; + esac +done + +for e in $env; do + eval "export $e" +done + +if disabled autodetect; then + + # Unless iconv is explicitely disabled by the user, we still want to probe + # for the iconv from the libc. + disabled iconv || enable libc_iconv + + disable_weak $EXTERNAL_AUTODETECT_LIBRARY_LIST + disable_weak $HWACCEL_AUTODETECT_LIBRARY_LIST +fi +# Mark specifically enabled, but normally autodetected libraries as requested. +for lib in $AUTODETECT_LIBS; do + enabled $lib && request $lib +done +#TODO: switch to $AUTODETECT_LIBS when $THREADS_LIST is supported the same way +enable_weak $EXTERNAL_AUTODETECT_LIBRARY_LIST +enable_weak $HWACCEL_AUTODETECT_LIBRARY_LIST + +disabled logging && logfile=/dev/null + +# command line configuration sanity checks + +# we need to build at least one lib type +if ! enabled_any static shared; then + cat < $logfile +set >> $logfile + +test -n "$valgrind" && toolchain="valgrind-memcheck" + +enabled ossfuzz && ! echo $CFLAGS | grep -q -- "-fsanitize=" && ! echo $CFLAGS | grep -q -- "-fcoverage-mapping" &&{ + add_cflags -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard,trace-cmp -fno-omit-frame-pointer + add_ldflags -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard,trace-cmp +} + +case "$toolchain" in + *-asan) + cc_default="${toolchain%-asan}" + add_cflags -fsanitize=address + add_ldflags -fsanitize=address + ;; + *-msan) + cc_default="${toolchain%-msan}" + add_cflags -fsanitize=memory -fsanitize-memory-track-origins + add_ldflags -fsanitize=memory + ;; + *-tsan) + cc_default="${toolchain%-tsan}" + add_cflags -fsanitize=thread + add_ldflags -fsanitize=thread + case "$toolchain" in + gcc-tsan) + add_cflags -fPIC + add_ldflags -fPIC + ;; + esac + ;; + *-usan) + cc_default="${toolchain%-usan}" + add_cflags -fsanitize=undefined + add_ldflags -fsanitize=undefined + ;; + valgrind-*) + target_exec_default="valgrind" + case "$toolchain" in + valgrind-massif) + target_exec_args="--tool=massif --alloc-fn=av_malloc --alloc-fn=av_mallocz --alloc-fn=av_calloc --alloc-fn=av_fast_padded_malloc --alloc-fn=av_fast_malloc --alloc-fn=av_realloc_f --alloc-fn=av_fast_realloc --alloc-fn=av_realloc" + ;; + valgrind-memcheck) + target_exec_args="--error-exitcode=1 --malloc-fill=0x2a --track-origins=yes --leak-check=full --gen-suppressions=all --suppressions=$source_path/tests/fate-valgrind.supp" + ;; + esac + ;; + msvc) + # Check whether the current MSVC version needs the C99 converter. + # From MSVC 2013 (compiler major version 18) onwards, it does actually + # support enough of C99 to build ffmpeg. Default to the new + # behaviour if the regexp was unable to match anything, since this + # successfully parses the version number of existing supported + # versions that require the converter (MSVC 2010 and 2012). + cl_major_ver=$(cl.exe 2>&1 | sed -n 's/.*Version \([[:digit:]]\{1,\}\)\..*/\1/p') + if [ -z "$cl_major_ver" ] || [ $cl_major_ver -ge 18 ]; then + cc_default="cl.exe" + cxx_default="cl.exe" + else + die "Unsupported MSVC version (2013 or newer required)" + fi + ld_default="$source_path/compat/windows/mslink" + nm_default="dumpbin.exe -symbols" + ar_default="lib.exe" + case "$arch" in + aarch64|arm64) + as_default="armasm64.exe" + ;; + arm*) + as_default="armasm.exe" + ;; + esac + target_os_default="win32" + # Use a relative path for TMPDIR. This makes sure all the + # ffconf temp files are written with a relative path, avoiding + # issues with msys/win32 path conversion for MSVC parameters + # such as -Fo or -out:. + TMPDIR=. + ;; + icl) + cc_default="icl" + ld_default="xilink" + nm_default="dumpbin -symbols" + ar_default="xilib" + target_os_default="win32" + TMPDIR=. + ;; + gcov) + add_cflags -fprofile-arcs -ftest-coverage + add_ldflags -fprofile-arcs -ftest-coverage + ;; + llvm-cov) + add_cflags -fprofile-arcs -ftest-coverage + add_ldflags --coverage + ;; + hardened) + add_cppflags -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 + add_cflags -fno-strict-overflow -fstack-protector-all + add_ldflags -Wl,-z,relro -Wl,-z,now + add_cflags -fPIE + add_ldexeflags -fPIE -pie + ;; + ?*) + die "Unknown toolchain $toolchain" + ;; +esac + +if test -n "$cross_prefix"; then + test -n "$arch" && test -n "$target_os" || + die "Must specify target arch (--arch) and OS (--target-os) when cross-compiling" + enable cross_compile +fi + +set_default target_os +if test "$target_os" = android; then + cc_default="clang" +fi + +ar_default="${cross_prefix}${ar_default}" +cc_default="${cross_prefix}${cc_default}" +cxx_default="${cross_prefix}${cxx_default}" +nm_default="${cross_prefix}${nm_default}" +pkg_config_default="${cross_prefix}${pkg_config_default}" +if ${cross_prefix}${ranlib_default} 2>&1 | grep -q "\-D "; then + ranlib_default="${cross_prefix}${ranlib_default} -D" +else + ranlib_default="${cross_prefix}${ranlib_default}" +fi +strip_default="${cross_prefix}${strip_default}" +windres_default="${cross_prefix}${windres_default}" + +sysinclude_default="${sysroot}/usr/include" + +if enabled cuda_sdk; then + warn "Option --enable-cuda-sdk is deprecated. Use --enable-cuda-nvcc instead." + enable cuda_nvcc +fi + +if enabled cuda_nvcc; then + nvcc_default="nvcc" + nvccflags_default="-gencode arch=compute_30,code=sm_30 -O2" +else + nvcc_default="clang" + nvccflags_default="--cuda-gpu-arch=sm_30 -O2" + NVCC_C="" +fi + +set_default arch cc cxx doxygen pkg_config ranlib strip sysinclude \ + target_exec x86asmexe nvcc +enabled cross_compile || host_cc_default=$cc +set_default host_cc + +pkg_config_fail_message="" +if ! $pkg_config --version >/dev/null 2>&1; then + warn "$pkg_config not found, library detection may fail." + pkg_config=false +elif is_in -static $cc $LDFLAGS && ! is_in --static $pkg_config $pkg_config_flags; then + pkg_config_fail_message=" +Note: When building a static binary, add --pkg-config-flags=\"--static\"." +fi + +if test $doxygen != $doxygen_default && \ + ! $doxygen --version >/dev/null 2>&1; then + warn "Specified doxygen \"$doxygen\" not found, API documentation will fail to build." +fi + +exesuf() { + case $1 in + mingw32*|mingw64*|win32|win64|cygwin*|*-dos|freedos|opendos|os/2*|symbian) echo .exe ;; + esac +} + +EXESUF=$(exesuf $target_os) +HOSTEXESUF=$(exesuf $host_os) + +# set temporary file name +: ${TMPDIR:=$TEMPDIR} +: ${TMPDIR:=$TMP} +: ${TMPDIR:=/tmp} + +if [ -n "$tempprefix" ] ; then + mktemp(){ + tmpname="$tempprefix.${HOSTNAME}.${UID}" + echo "$tmpname" + mkdir "$tmpname" + } +elif ! test_cmd mktemp -u XXXXXX; then + # simple replacement for missing mktemp + # NOT SAFE FOR GENERAL USE + mktemp(){ + tmpname="${2%%XXX*}.${HOSTNAME}.${UID}.$$" + echo "$tmpname" + mkdir "$tmpname" + } +fi + +FFTMPDIR=$(mktemp -d "${TMPDIR}/ffconf.XXXXXXXX" 2> /dev/null) || + die "Unable to create temporary directory in $TMPDIR." + +tmpfile(){ + tmp="${FFTMPDIR}/test"$2 + (set -C; exec > $tmp) 2> /dev/null || + die "Unable to create temporary file in $FFTMPDIR." + eval $1=$tmp +} + +trap 'rm -rf -- "$FFTMPDIR"' EXIT +trap 'exit 2' INT + +tmpfile TMPASM .asm +tmpfile TMPC .c +tmpfile TMPCPP .cpp +tmpfile TMPE $EXESUF +tmpfile TMPH .h +tmpfile TMPM .m +tmpfile TMPCU .cu +tmpfile TMPO .o +tmpfile TMPS .S +tmpfile TMPSH .sh +tmpfile TMPV .ver + +unset -f mktemp + +chmod +x $TMPE + +# make sure we can execute files in $TMPDIR +cat > $TMPSH 2>> $logfile <> $logfile 2>&1 +if ! $TMPSH >> $logfile 2>&1; then + cat <&1 | grep -q '^GNU assembler'; then + true # no-op to avoid reading stdin in following checks + elif $_cc -v 2>&1 | grep -q '^gcc.*LLVM'; then + _type=llvm_gcc + gcc_extra_ver=$(expr "$($_cc --version 2>/dev/null | head -n1)" : '.*\((.*)\)') + _ident="llvm-gcc $($_cc -dumpversion 2>/dev/null) $gcc_extra_ver" + _depflags='-MMD -MF $(@:.o=.d) -MT $@' + _cflags_speed='-O3' + _cflags_size='-Os' + elif $_cc -v 2>&1 | grep -qi ^gcc; then + _type=gcc + gcc_version=$($_cc --version | head -n1) + gcc_basever=$($_cc -dumpversion) + gcc_pkg_ver=$(expr "$gcc_version" : '[^ ]* \(([^)]*)\)') + gcc_ext_ver=$(expr "$gcc_version" : ".*$gcc_pkg_ver $gcc_basever \\(.*\\)") + _ident=$(cleanws "gcc $gcc_basever $gcc_pkg_ver $gcc_ext_ver") + case $gcc_basever in + 2) ;; + 2.*) ;; + *) _depflags='-MMD -MF $(@:.o=.d) -MT $@' ;; + esac + if [ "$first" = true ]; then + case $gcc_basever in + 4.2*) + warn "gcc 4.2 is outdated and may miscompile FFmpeg. Please use a newer compiler." ;; + esac + fi + _cflags_speed='-O3' + _cflags_size='-Os' + elif $_cc --version 2>/dev/null | grep -q ^icc; then + _type=icc + _ident=$($_cc --version | head -n1) + _depflags='-MMD' + _cflags_speed='-O3' + _cflags_size='-Os' + _cflags_noopt='-O1' + _flags_filter=icc_flags + elif $_cc -v 2>&1 | grep -q xlc; then + _type=xlc + _ident=$($_cc -qversion 2>/dev/null | head -n1) + _cflags_speed='-O5' + _cflags_size='-O5 -qcompact' + elif $_cc --vsn 2>/dev/null | grep -Eq "ARM (C/C\+\+ )?Compiler"; then + test -d "$sysroot" || die "No valid sysroot specified." + _type=armcc + _ident=$($_cc --vsn | grep -i build | head -n1 | sed 's/.*: //') + armcc_conf="$PWD/armcc.conf" + $_cc --arm_linux_configure \ + --arm_linux_config_file="$armcc_conf" \ + --configure_sysroot="$sysroot" \ + --configure_cpp_headers="$sysinclude" >>$logfile 2>&1 || + die "Error creating armcc configuration file." + $_cc --vsn | grep -q RVCT && armcc_opt=rvct || armcc_opt=armcc + _flags="--arm_linux_config_file=$armcc_conf --translate_gcc" + as_default="${cross_prefix}gcc" + _depflags='-MMD' + _cflags_speed='-O3' + _cflags_size='-Os' + elif $_cc -v 2>&1 | grep -q clang && ! $_cc -? > /dev/null 2>&1; then + _type=clang + _ident=$($_cc --version 2>/dev/null | head -n1) + _depflags='-MMD -MF $(@:.o=.d) -MT $@' + _cflags_speed='-O3' + _cflags_size='-Oz' + elif $_cc -V 2>&1 | grep -q Sun; then + _type=suncc + _ident=$($_cc -V 2>&1 | head -n1 | cut -d' ' -f 2-) + _DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< | sed -e "1s,^.*: ,$@: ," -e "\$$!s,\$$, \\\," -e "1!s,^.*: , ," > $(@:.o=.d)' + _DEPFLAGS='-xM1 -xc99' + _ldflags='-std=c99' + _cflags_speed='-O5' + _cflags_size='-O5 -xspace' + _flags_filter=suncc_flags + elif $_cc -v 2>&1 | grep -q 'PathScale\|Path64'; then + _type=pathscale + _ident=$($_cc -v 2>&1 | head -n1 | tr -d :) + _depflags='-MMD -MF $(@:.o=.d) -MT $@' + _cflags_speed='-O2' + _cflags_size='-Os' + _flags_filter='filter_out -Wdisabled-optimization' + elif $_cc -v 2>&1 | grep -q Open64; then + _type=open64 + _ident=$($_cc -v 2>&1 | head -n1 | tr -d :) + _depflags='-MMD -MF $(@:.o=.d) -MT $@' + _cflags_speed='-O2' + _cflags_size='-Os' + _flags_filter='filter_out -Wdisabled-optimization|-Wtype-limits|-fno-signed-zeros' + elif $_cc 2>&1 | grep -q 'Microsoft.*ARM.*Assembler'; then + _type=armasm + _ident=$($_cc | head -n1) + # 4509: "This form of conditional instruction is deprecated" + _flags="-nologo -ignore 4509" + _flags_filter=armasm_flags + elif $_cc 2>&1 | grep -q Intel; then + _type=icl + _ident=$($_cc 2>&1 | head -n1) + _depflags='-QMMD -QMF$(@:.o=.d) -QMT$@' + # Not only is O3 broken on 13.x+ but it is slower on all previous + # versions (tested) as well. + _cflags_speed="-O2" + _cflags_size="-O1 -Oi" # -O1 without -Oi miscompiles stuff + if $_cc 2>&1 | grep -q Linker; then + _ld_o='-out:$@' + else + _ld_o='-Fe$@' + fi + _cc_o='-Fo$@' + _cc_e='-P' + _flags_filter=icl_flags + _ld_lib='lib%.a' + _ld_path='-libpath:' + # -Qdiag-error to make icl error when seeing certain unknown arguments + _flags='-nologo -Qdiag-error:4044,10157' + # -Qvec- -Qsimd- to prevent miscompilation, -GS, fp:precise for consistency + # with MSVC which enables it by default. + _cflags='-Qms0 -Qvec- -Qsimd- -GS -fp:precise' + disable stripping + elif $_cc -? 2>/dev/null | grep -q 'LLVM.*Linker'; then + # lld can emulate multiple different linkers; in ms link.exe mode, + # the -? parameter gives the help output which contains an identifyable + # string, while it gives an error in other modes. + _type=lld-link + # The link.exe mode doesn't have a switch for getting the version, + # but we can force it back to gnu mode and get the version from there. + _ident=$($_cc -flavor gnu --version 2>/dev/null) + _ld_o='-out:$@' + _flags_filter=msvc_flags + _ld_lib='lib%.a' + _ld_path='-libpath:' + elif $_cc -nologo- 2>&1 | grep -q Microsoft || { $_cc -v 2>&1 | grep -q clang && $_cc -? > /dev/null 2>&1; }; then + _type=msvc + _ident=$($_cc 2>&1 | head -n1 | tr -d '\r') + _DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); gsub(/\\/, "/"); if (!match($$0, / /)) print "$@:", $$0 }'\'' > $(@:.o=.d)' + _DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs' + _cflags_speed="-O2" + _cflags_size="-O1" + _cflags_noopt="-O1" + if $_cc -nologo- 2>&1 | grep -q Linker; then + _ld_o='-out:$@' + else + _ld_o='-Fe$@' + fi + _cc_o='-Fo$@' + _cc_e='-P -Fi$@' + _flags_filter=msvc_flags + _ld_lib='lib%.a' + _ld_path='-libpath:' + _flags='-nologo' + disable stripping + elif $_cc --version 2>/dev/null | grep -q ^cparser; then + _type=cparser + _ident=$($_cc --version | head -n1) + _depflags='-MMD' + _cflags_speed='-O4' + _cflags_size='-O2' + _flags_filter=cparser_flags + fi + + eval ${pfx}_type=\$_type + eval ${pfx}_ident=\$_ident +} + +set_ccvars(){ + eval ${1}_C=\${_cc_c-\${${1}_C}} + eval ${1}_E=\${_cc_e-\${${1}_E}} + eval ${1}_O=\${_cc_o-\${${1}_O}} + + if [ -n "$_depflags" ]; then + eval ${1}_DEPFLAGS=\$_depflags + else + eval ${1}DEP=\${_DEPCMD:-\$DEPCMD} + eval ${1}DEP_FLAGS=\${_DEPFLAGS:-\$DEPFLAGS} + eval DEP${1}FLAGS=\$_flags + fi +} + +probe_cc cc "$cc" "true" +cflags_filter=$_flags_filter +cflags_speed=$_cflags_speed +cflags_size=$_cflags_size +cflags_noopt=$_cflags_noopt +add_cflags $_flags $_cflags +cc_ldflags=$_ldflags +set_ccvars CC +set_ccvars CXX + +probe_cc hostcc "$host_cc" +host_cflags_filter=$_flags_filter +host_cflags_speed=$_cflags_speed +add_host_cflags $_flags $_cflags +set_ccvars HOSTCC + +test -n "$cc_type" && enable $cc_type || + warn "Unknown C compiler $cc, unable to select optimal CFLAGS" + +: ${as_default:=$cc} +: ${objcc_default:=$cc} +: ${dep_cc_default:=$cc} +: ${ld_default:=$cc} +: ${host_ld_default:=$host_cc} +set_default ar as objcc dep_cc ld ln_s host_ld windres + +probe_cc as "$as" +asflags_filter=$_flags_filter +add_asflags $_flags $_cflags +set_ccvars AS + +probe_cc objcc "$objcc" +objcflags_filter=$_flags_filter +add_objcflags $_flags $_cflags +set_ccvars OBJC + +probe_cc ld "$ld" +ldflags_filter=$_flags_filter +add_ldflags $_flags $_ldflags +test "$cc_type" != "$ld_type" && add_ldflags $cc_ldflags +LD_O=${_ld_o-$LD_O} +LD_LIB=${_ld_lib-$LD_LIB} +LD_PATH=${_ld_path-$LD_PATH} + +probe_cc hostld "$host_ld" +host_ldflags_filter=$_flags_filter +add_host_ldflags $_flags $_ldflags +HOSTLD_O=${_ld_o-$HOSTLD_O} + +if [ -z "$CC_DEPFLAGS" ] && [ "$dep_cc" != "$cc" ]; then + probe_cc depcc "$dep_cc" + CCDEP=${_DEPCMD:-$DEPCMD} + CCDEP_FLAGS=${_DEPFLAGS:=$DEPFLAGS} + DEPCCFLAGS=$_flags +fi + +if $ar 2>&1 | grep -q Microsoft; then + arflags="-nologo" + ar_o='-out:$@' +elif $ar 2>&1 | grep -q "\[D\] "; then + arflags="rcD" + ar_o='$@' +else + arflags="rc" + ar_o='$@' +fi + +add_cflags $extra_cflags +add_cxxflags $extra_cxxflags +add_objcflags $extra_objcflags +add_asflags $extra_cflags + +if test -n "$sysroot"; then + case "$cc_type" in + gcc|llvm_gcc|clang) + add_cppflags --sysroot="$sysroot" + add_ldflags --sysroot="$sysroot" + ;; + esac +fi + +if test "$cpu" = host; then + enabled cross_compile && + die "--cpu=host makes no sense when cross-compiling." + + case "$cc_type" in + gcc|llvm_gcc) + check_native(){ + $cc $1=native -v -c -o $TMPO $TMPC >$TMPE 2>&1 || return + sed -n "/cc1.*$1=/{ + s/.*$1=\\([^ ]*\\).*/\\1/ + p + q + }" $TMPE + } + cpu=$(check_native -march || check_native -mcpu) + ;; + clang) + check_native(){ + $cc $1=native -v -c -o $TMPO $TMPC >$TMPE 2>&1 || return + sed -n "/cc1.*-target-cpu /{ + s/.*-target-cpu \\([^ ]*\\).*/\\1/ + p + q + }" $TMPE + } + cpu=$(check_native -march) + ;; + esac + + test "${cpu:-host}" = host && + die "--cpu=host not supported with compiler $cc" +fi + +# Deal with common $arch aliases +case "$arch" in + aarch64|arm64) + arch="aarch64" + ;; + arm*|iPad*|iPhone*) + arch="arm" + ;; + mips*|IP*) + case "$arch" in + *el) + add_cppflags -EL + add_ldflags -EL + ;; + *eb) + add_cppflags -EB + add_ldflags -EB + ;; + esac + arch="mips" + ;; + parisc*|hppa*) + arch="parisc" + ;; + "Power Macintosh"|ppc*|powerpc*) + arch="ppc" + ;; + s390|s390x) + arch="s390" + ;; + sh4|sh) + arch="sh4" + ;; + sun4*|sparc*) + arch="sparc" + ;; + tilegx|tile-gx) + arch="tilegx" + ;; + i[3-6]86*|i86pc|BePC|x86pc|x86_64|x86_32|amd64) + arch="x86" + ;; +esac + +is_in $arch $ARCH_LIST || warn "unknown architecture $arch" +enable $arch + +# Add processor-specific flags +if enabled aarch64; then + + case $cpu in + armv*) + cpuflags="-march=$cpu" + ;; + *) + cpuflags="-mcpu=$cpu" + ;; + esac + +elif enabled alpha; then + + cpuflags="-mcpu=$cpu" + +elif enabled arm; then + + check_arm_arch() { + test_cpp_condition stddef.h \ + "defined __ARM_ARCH_${1}__ || defined __TARGET_ARCH_${2:-$1}" \ + $cpuflags + } + + probe_arm_arch() { + if check_arm_arch 4; then echo armv4 + elif check_arm_arch 4T; then echo armv4t + elif check_arm_arch 5; then echo armv5 + elif check_arm_arch 5E; then echo armv5e + elif check_arm_arch 5T; then echo armv5t + elif check_arm_arch 5TE; then echo armv5te + elif check_arm_arch 5TEJ; then echo armv5te + elif check_arm_arch 6; then echo armv6 + elif check_arm_arch 6J; then echo armv6j + elif check_arm_arch 6K; then echo armv6k + elif check_arm_arch 6Z; then echo armv6z + elif check_arm_arch 6KZ; then echo armv6zk + elif check_arm_arch 6ZK; then echo armv6zk + elif check_arm_arch 6T2; then echo armv6t2 + elif check_arm_arch 7; then echo armv7 + elif check_arm_arch 7A 7_A; then echo armv7-a + elif check_arm_arch 7S; then echo armv7-a + elif check_arm_arch 7R 7_R; then echo armv7-r + elif check_arm_arch 7M 7_M; then echo armv7-m + elif check_arm_arch 7EM 7E_M; then echo armv7-m + elif check_arm_arch 8A 8_A; then echo armv8-a + fi + } + + [ "$cpu" = generic ] && cpu=$(probe_arm_arch) + + case $cpu in + armv*) + cpuflags="-march=$cpu" + subarch=$(echo $cpu | sed 's/[^a-z0-9]//g') + ;; + *) + cpuflags="-mcpu=$cpu" + case $cpu in + cortex-a*) subarch=armv7a ;; + cortex-r*) subarch=armv7r ;; + cortex-m*) enable thumb; subarch=armv7m ;; + arm11*) subarch=armv6 ;; + arm[79]*e*|arm9[24]6*|arm96*|arm102[26]) subarch=armv5te ;; + armv4*|arm7*|arm9[24]*) subarch=armv4 ;; + *) subarch=$(probe_arm_arch) ;; + esac + ;; + esac + + case "$subarch" in + armv5t*) enable fast_clz ;; + armv[6-8]*) + enable fast_clz + disabled fast_unaligned || enable fast_unaligned + ;; + esac + +elif enabled avr32; then + + case $cpu in + ap7[02]0[0-2]) + subarch="avr32_ap" + cpuflags="-mpart=$cpu" + ;; + ap) + subarch="avr32_ap" + cpuflags="-march=$cpu" + ;; + uc3[ab]*) + subarch="avr32_uc" + cpuflags="-mcpu=$cpu" + ;; + uc) + subarch="avr32_uc" + cpuflags="-march=$cpu" + ;; + esac + +elif enabled bfin; then + + cpuflags="-mcpu=$cpu" + +elif enabled mips; then + + cpuflags="-march=$cpu" + + if [ "$cpu" != "generic" ]; then + disable mips32r2 + disable mips32r5 + disable mips64r2 + disable mips32r6 + disable mips64r6 + disable loongson2 + disable loongson3 + + case $cpu in + 24kc|24kf*|24kec|34kc|1004kc|24kef*|34kf*|1004kf*|74kc|74kf) + enable mips32r2 + disable msa + ;; + p5600|i6400|p6600) + disable mipsdsp + disable mipsdspr2 + ;; + loongson*) + enable loongson2 + enable loongson3 + enable local_aligned + enable simd_align_16 + enable fast_64bit + enable fast_clz + enable fast_cmov + enable fast_unaligned + disable aligned_stack + disable mipsdsp + disable mipsdspr2 + # When gcc version less than 5.3.0, add -fno-expensive-optimizations flag. + if [ $cc == gcc ]; then + gcc_version=$(gcc -dumpversion) + if [ "$(echo "$gcc_version 5.3.0" | tr " " "\n" | sort -rV | head -n 1)" == "$gcc_version" ]; then + expensive_optimization_flag="" + else + expensive_optimization_flag="-fno-expensive-optimizations" + fi + fi + case $cpu in + loongson3*) + cpuflags="-march=loongson3a -mhard-float $expensive_optimization_flag" + ;; + loongson2e) + cpuflags="-march=loongson2e -mhard-float $expensive_optimization_flag" + ;; + loongson2f) + cpuflags="-march=loongson2f -mhard-float $expensive_optimization_flag" + ;; + esac + ;; + *) + # Unknown CPU. Disable everything. + warn "unknown CPU. Disabling all MIPS optimizations." + disable mipsfpu + disable mipsdsp + disable mipsdspr2 + disable msa + disable mmi + ;; + esac + + case $cpu in + 24kc) + disable mipsfpu + disable mipsdsp + disable mipsdspr2 + ;; + 24kf*) + disable mipsdsp + disable mipsdspr2 + ;; + 24kec|34kc|1004kc) + disable mipsfpu + disable mipsdspr2 + ;; + 24kef*|34kf*|1004kf*) + disable mipsdspr2 + ;; + 74kc) + disable mipsfpu + ;; + p5600) + enable mips32r5 + check_cflags "-mtune=p5600" && check_cflags "-msched-weight -mload-store-pairs -funroll-loops" + ;; + i6400) + enable mips64r6 + check_cflags "-mtune=i6400 -mabi=64" && check_cflags "-msched-weight -mload-store-pairs -funroll-loops" && check_ldflags "-mabi=64" + ;; + p6600) + enable mips64r6 + check_cflags "-mtune=p6600 -mabi=64" && check_cflags "-msched-weight -mload-store-pairs -funroll-loops" && check_ldflags "-mabi=64" + ;; + esac + else + # We do not disable anything. Is up to the user to disable the unwanted features. + warn 'generic cpu selected' + fi + +elif enabled ppc; then + + disable ldbrx + + case $(tolower $cpu) in + 601|ppc601|powerpc601) + cpuflags="-mcpu=601" + disable altivec + ;; + 603*|ppc603*|powerpc603*) + cpuflags="-mcpu=603" + disable altivec + ;; + 604*|ppc604*|powerpc604*) + cpuflags="-mcpu=604" + disable altivec + ;; + g3|75*|ppc75*|powerpc75*) + cpuflags="-mcpu=750" + disable altivec + ;; + g4|745*|ppc745*|powerpc745*) + cpuflags="-mcpu=7450" + disable vsx + ;; + 74*|ppc74*|powerpc74*) + cpuflags="-mcpu=7400" + disable vsx + ;; + g5|970|ppc970|powerpc970) + cpuflags="-mcpu=970" + disable vsx + ;; + power[3-6]*) + cpuflags="-mcpu=$cpu" + disable vsx + ;; + power[7-8]*) + cpuflags="-mcpu=$cpu" + ;; + cell) + cpuflags="-mcpu=cell" + enable ldbrx + disable vsx + ;; + e500mc) + cpuflags="-mcpu=e500mc" + disable altivec + ;; + e500v2) + cpuflags="-mcpu=8548 -mhard-float -mfloat-gprs=double" + disable altivec + disable dcbzl + ;; + e500) + cpuflags="-mcpu=8540 -mhard-float" + disable altivec + disable dcbzl + ;; + esac + +elif enabled sparc; then + + case $cpu in + cypress|f93[04]|tsc701|sparcl*|supersparc|hypersparc|niagara|v[789]) + cpuflags="-mcpu=$cpu" + ;; + ultrasparc*|niagara[234]) + cpuflags="-mcpu=$cpu" + ;; + esac + +elif enabled x86; then + + case $cpu in + i[345]86|pentium) + cpuflags="-march=$cpu" + disable i686 + disable mmx + ;; + # targets that do NOT support nopl and conditional mov (cmov) + pentium-mmx|k6|k6-[23]|winchip-c6|winchip2|c3) + cpuflags="-march=$cpu" + disable i686 + ;; + # targets that do support nopl and conditional mov (cmov) + i686|pentiumpro|pentium[23]|pentium-m|athlon|athlon-tbird|athlon-4|athlon-[mx]p|athlon64*|k8*|opteron*|athlon-fx\ + |core*|atom|bonnell|nehalem|westmere|silvermont|sandybridge|ivybridge|haswell|broadwell|skylake*|knl\ + |amdfam10|barcelona|b[dt]ver*|znver*) + cpuflags="-march=$cpu" + enable i686 + enable fast_cmov + ;; + # targets that do support conditional mov but on which it's slow + pentium4|pentium4m|prescott|nocona) + cpuflags="-march=$cpu" + enable i686 + disable fast_cmov + ;; + esac + +fi + +if [ "$cpu" != generic ]; then + add_cflags $cpuflags + add_asflags $cpuflags + test "$cc_type" = "$ld_type" && add_ldflags $cpuflags +fi + +# compiler sanity check +test_exec <= 201112L" && + add_cflags -std=c11 || + check_cflags -std=c99 + +check_cppflags -D_FILE_OFFSET_BITS=64 +check_cppflags -D_LARGEFILE_SOURCE + +add_host_cppflags -D_ISOC99_SOURCE +check_host_cflags -std=c99 +check_host_cflags -Wall +check_host_cflags $host_cflags_speed + +check_64bit(){ + arch32=$1 + arch64=$2 + expr=${3:-'sizeof(void *) > 4'} + test_code cc "" "int test[2*($expr) - 1]" && + subarch=$arch64 || subarch=$arch32 + enable $subarch +} + +case "$arch" in + aarch64|alpha|ia64) + enabled shared && enable_weak pic + ;; + mips) + check_64bit mips mips64 '_MIPS_SIM > 1' + enabled shared && enable_weak pic + ;; + parisc) + check_64bit parisc parisc64 + enabled shared && enable_weak pic + ;; + ppc) + check_64bit ppc ppc64 + enabled shared && enable_weak pic + ;; + s390) + check_64bit s390 s390x + enabled shared && enable_weak pic + ;; + sparc) + check_64bit sparc sparc64 + enabled shared && enable_weak pic + ;; + x86) + check_64bit x86_32 x86_64 + # Treat x32 as x64 for now. Note it also needs pic if shared + test "$subarch" = "x86_32" && test_cpp_condition stddef.h 'defined(__x86_64__)' && + subarch=x86_64 && enable x86_64 && disable x86_32 + if enabled x86_64; then + enabled shared && enable_weak pic + objformat=elf64 + fi + ;; +esac + +# OS specific +case $target_os in + aix) + SHFLAGS=-shared + add_cppflags '-I\$(SRC_PATH)/compat/aix' + enabled shared && add_ldflags -Wl,-brtl + arflags='-Xany -r -c' + striptype="" + ;; + android) + disable symver + enable section_data_rel_ro + add_cflags -fPIE + add_ldexeflags -fPIE -pie + SLIB_INSTALL_NAME='$(SLIBNAME)' + SLIB_INSTALL_LINKS= + SHFLAGS='-shared -Wl,-soname,$(SLIBNAME)' + ;; + haiku) + prefix_default="/boot/common" + network_extralibs="-lnetwork" + host_extralibs= + ;; + sunos) + SHFLAGS='-shared -Wl,-h,$$(@F)' + enabled x86 && append SHFLAGS -mimpure-text + network_extralibs="-lsocket -lnsl" + add_cppflags -D__EXTENSIONS__ + # When using suncc to build, the Solaris linker will mark + # an executable with each instruction set encountered by + # the Solaris assembler. As our libraries contain their own + # guards for processor-specific code, instead suppress + # generation of the HWCAPS ELF section on Solaris x86 only. + enabled_all suncc x86 && + echo "hwcap_1 = OVERRIDE;" > mapfile && + add_ldflags -Wl,-M,mapfile + nm_default='nm -P -g' + striptype="" + version_script='-M' + VERSION_SCRIPT_POSTPROCESS_CMD='perl $(SRC_PATH)/compat/solaris/make_sunver.pl - $(OBJS)' + ;; + netbsd) + disable symver + oss_indev_extralibs="-lossaudio" + oss_outdev_extralibs="-lossaudio" + enabled gcc || check_ldflags -Wl,-zmuldefs + ;; + openbsd|bitrig) + disable symver + striptype="" + SHFLAGS='-shared' + SLIB_INSTALL_NAME='$(SLIBNAME).$(LIBMAJOR).$(LIBMINOR)' + SLIB_INSTALL_LINKS= + oss_indev_extralibs="-lossaudio" + oss_outdev_extralibs="-lossaudio" + ;; + dragonfly) + disable symver + ;; + freebsd) + ;; + bsd/os) + add_extralibs -lpoll -lgnugetopt + strip="strip -d" + ;; + darwin) + enabled ppc && add_asflags -force_cpusubtype_ALL + install_name_dir_default='$(SHLIBDIR)' + SHFLAGS='-dynamiclib -Wl,-single_module -Wl,-install_name,$(INSTALL_NAME_DIR)/$(SLIBNAME_WITH_MAJOR),-current_version,$(LIBVERSION),-compatibility_version,$(LIBMAJOR)' + enabled x86_32 && append SHFLAGS -Wl,-read_only_relocs,suppress + strip="${strip} -x" + add_ldflags -Wl,-dynamic,-search_paths_first + check_cflags -Werror=partial-availability + SLIBSUF=".dylib" + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME).$(LIBVERSION)$(SLIBSUF)' + SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME).$(LIBMAJOR)$(SLIBSUF)' + enabled x86_64 && objformat="macho64" || objformat="macho32" + enabled_any pic shared x86_64 || + { check_cflags -mdynamic-no-pic && add_asflags -mdynamic-no-pic; } + check_headers dispatch/dispatch.h && + add_cppflags '-I\$(SRC_PATH)/compat/dispatch_semaphore' + if test -n "$sysroot"; then + is_in -isysroot $cc $CPPFLAGS $CFLAGS || check_cppflags -isysroot $sysroot + is_in -isysroot $ld $LDFLAGS || check_ldflags -isysroot $sysroot + fi + version_script='-exported_symbols_list' + VERSION_SCRIPT_POSTPROCESS_CMD='tr " " "\n" | sed -n /global:/,/local:/p | grep ";" | tr ";" "\n" | sed -E "s/(.+)/_\1/g" | sed -E "s/(.+[^*])$$$$/\1*/"' + ;; + msys*) + die "Native MSYS builds are discouraged, please use the MINGW environment." + ;; + mingw32*|mingw64*) + target_os=mingw32 + LIBTARGET=i386 + if enabled x86_64; then + LIBTARGET="i386:x86-64" + elif enabled arm; then + LIBTARGET="arm" + elif enabled aarch64; then + LIBTARGET="arm64" + fi + if enabled shared; then + # Cannot build both shared and static libs when using dllimport. + disable static + fi + enabled shared && ! enabled small && test_cmd $windres --version && enable gnu_windres + enabled x86_32 && check_ldflags -Wl,--large-address-aware + shlibdir_default="$bindir_default" + SLIBPREF="" + SLIBSUF=".dll" + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' + SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' + if test_cmd lib.exe -list; then + SLIB_EXTRA_CMD=-'lib.exe -nologo -machine:$(LIBTARGET) -def:$$(@:$(SLIBSUF)=.def) -out:$(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib)' + if enabled x86_64; then + LIBTARGET=x64 + fi + else + SLIB_EXTRA_CMD=-'$(DLLTOOL) -m $(LIBTARGET) -d $$(@:$(SLIBSUF)=.def) -l $(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib) -D $(SLIBNAME_WITH_MAJOR)' + fi + SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' + SLIB_INSTALL_LINKS= + SLIB_INSTALL_EXTRA_SHLIB='$(SLIBNAME:$(SLIBSUF)=.lib)' + SLIB_INSTALL_EXTRA_LIB='lib$(SLIBNAME:$(SLIBSUF)=.dll.a) $(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.def)' + SLIB_CREATE_DEF_CMD='EXTERN_PREFIX="$(EXTERN_PREFIX)" AR="$(AR_CMD)" NM="$(NM_CMD)" $(SRC_PATH)/compat/windows/makedef $(SUBDIR)lib$(NAME).ver $(OBJS) > $$(@:$(SLIBSUF)=.def)' + SHFLAGS='-shared -Wl,--out-implib,$(SUBDIR)lib$(SLIBNAME:$(SLIBSUF)=.dll.a) -Wl,--disable-auto-image-base $$(@:$(SLIBSUF)=.def)' + enabled x86_64 && objformat="win64" || objformat="win32" + dlltool="${cross_prefix}dlltool" + ranlib=: + enable dos_paths + check_ldflags -Wl,--nxcompat,--dynamicbase + # Lets work around some stupidity in binutils. + # ld will strip relocations from executables even though we need them + # for dynamicbase (ASLR). Using -pie does retain the reloc section + # however ld then forgets what the entry point should be (oops) so we + # have to manually (re)set it. + if enabled x86_32; then + disabled debug && add_ldexeflags -Wl,--pic-executable,-e,_mainCRTStartup + elif enabled x86_64; then + disabled debug && add_ldexeflags -Wl,--pic-executable,-e,mainCRTStartup + check_ldflags -Wl,--high-entropy-va # binutils 2.25 + # Set image base >4GB for extra entropy with HEASLR + add_ldexeflags -Wl,--image-base,0x140000000 + append SHFLAGS -Wl,--image-base,0x180000000 + fi + ;; + win32|win64) + disable symver + if enabled shared; then + # Link to the import library instead of the normal static library + # for shared libs. + LD_LIB='%.lib' + # Cannot build both shared and static libs with MSVC or icl. + disable static + fi + enabled x86_32 && check_ldflags -LARGEADDRESSAWARE + shlibdir_default="$bindir_default" + SLIBPREF="" + SLIBSUF=".dll" + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' + SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' + SLIB_CREATE_DEF_CMD='EXTERN_PREFIX="$(EXTERN_PREFIX)" $(SRC_PATH)/compat/windows/makedef $(SUBDIR)lib$(NAME).ver $(OBJS) > $$(@:$(SLIBSUF)=.def)' + SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' + SLIB_INSTALL_LINKS= + SLIB_INSTALL_EXTRA_SHLIB='$(SLIBNAME:$(SLIBSUF)=.lib)' + SLIB_INSTALL_EXTRA_LIB='$(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.def)' + SHFLAGS='-dll -def:$$(@:$(SLIBSUF)=.def) -implib:$(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib)' + enabled x86_64 && objformat="win64" || objformat="win32" + ranlib=: + enable dos_paths + ;; + cygwin*) + target_os=cygwin + shlibdir_default="$bindir_default" + SLIBPREF="cyg" + SLIBSUF=".dll" + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' + SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' + SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' + SLIB_INSTALL_LINKS= + SLIB_INSTALL_EXTRA_LIB='lib$(FULLNAME).dll.a' + SHFLAGS='-shared -Wl,--out-implib,$(SUBDIR)lib$(FULLNAME).dll.a' + enabled x86_64 && objformat="win64" || objformat="win32" + enable dos_paths + enabled shared && ! enabled small && test_cmd $windres --version && enable gnu_windres + add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 + ;; + *-dos|freedos|opendos) + network_extralibs="-lsocket" + objformat="coff" + enable dos_paths + ;; + linux) + enable section_data_rel_ro + enabled_any arm aarch64 && enable_weak linux_perf + ;; + irix*) + target_os=irix + ranlib="echo ignoring ranlib" + ;; + os/2*) + strip="lxlite -CS" + striptype="" + objformat="aout" + add_cppflags -D_GNU_SOURCE + add_ldflags -Zomf -Zbin-files -Zargs-wild -Zhigh-mem -Zmap + SHFLAGS='$(SUBDIR)$(NAME).def -Zdll -Zomf' + LIBSUF="_s.a" + SLIBPREF="" + SLIBSUF=".dll" + SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' + SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(shell echo $(FULLNAME) | cut -c1-6)$(LIBMAJOR)$(SLIBSUF)' + SLIB_CREATE_DEF_CMD='echo LIBRARY $(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=) INITINSTANCE TERMINSTANCE > $(SUBDIR)$(FULLNAME).def; \ + echo CODE PRELOAD MOVEABLE DISCARDABLE >> $(SUBDIR)$(FULLNAME).def; \ + echo DATA PRELOAD MOVEABLE MULTIPLE NONSHARED >> $(SUBDIR)$(FULLNAME).def; \ + echo EXPORTS >> $(SUBDIR)$(FULLNAME).def; \ + emxexp $(OBJS) >> $(SUBDIR)$(FULLNAME).def' + SLIB_EXTRA_CMD='emximp -o $(SUBDIR)$(LIBPREF)$(FULLNAME)_dll.a $(SUBDIR)$(FULLNAME).def; \ + emximp -o $(SUBDIR)$(LIBPREF)$(FULLNAME)_dll.lib $(SUBDIR)$(FULLNAME).def;' + SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' + SLIB_INSTALL_LINKS= + SLIB_INSTALL_EXTRA_LIB='$(LIBPREF)$(FULLNAME)_dll.a $(LIBPREF)$(FULLNAME)_dll.lib' + enable dos_paths + enable_weak os2threads + ;; + gnu/kfreebsd) + add_cppflags -D_BSD_SOURCE + ;; + gnu) + ;; + qnx) + add_cppflags -D_QNX_SOURCE + network_extralibs="-lsocket" + ;; + symbian) + SLIBSUF=".dll" + enable dos_paths + add_cflags --include=$sysinclude/gcce/gcce.h -fvisibility=default + add_cppflags -D__GCCE__ -D__SYMBIAN32__ -DSYMBIAN_OE_POSIX_SIGNALS + add_ldflags -Wl,--target1-abs,--no-undefined \ + -Wl,-Ttext,0x80000,-Tdata,0x1000000 -shared \ + -Wl,--entry=_E32Startup -Wl,-u,_E32Startup + add_extralibs -l:eexe.lib -l:usrt2_2.lib -l:dfpaeabi.dso \ + -l:drtaeabi.dso -l:scppnwdl.dso -lsupc++ -lgcc \ + -l:libc.dso -l:libm.dso -l:euser.dso -l:libcrt0.lib + ;; + minix) + ;; + none) + ;; + *) + die "Unknown OS '$target_os'." + ;; +esac + +# test if creating links works +link_dest=$(mktemp -u $TMPDIR/dest_XXXXXXXX) +link_name=$(mktemp -u $TMPDIR/name_XXXXXXXX) +mkdir "$link_dest" +$ln_s "$link_dest" "$link_name" +touch "$link_dest/test_file" +if [ "$source_path" != "." ] && [ "$source_path" != "src" ] && ([ ! -d src ] || [ -L src ]) && [ -e "$link_name/test_file" ]; then + # create link to source path + [ -e src ] && rm src + $ln_s "$source_path" src + source_link=src +else + # creating directory links doesn't work + # fall back to using the full source path + source_link="$source_path" +fi +# cleanup +rm -r "$link_dest" +rm -r "$link_name" + +# determine libc flavour + +probe_libc(){ + pfx=$1 + pfx_no_=${pfx%_} + # uclibc defines __GLIBC__, so it needs to be checked before glibc. + if test_${pfx}cpp_condition features.h "defined __UCLIBC__"; then + eval ${pfx}libc_type=uclibc + add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 + elif test_${pfx}cpp_condition features.h "defined __GLIBC__"; then + eval ${pfx}libc_type=glibc + add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 + # MinGW headers can be installed on Cygwin, so check for newlib first. + elif test_${pfx}cpp_condition newlib.h "defined _NEWLIB_VERSION"; then + eval ${pfx}libc_type=newlib + add_${pfx}cppflags -U__STRICT_ANSI__ -D_XOPEN_SOURCE=600 + # MinGW64 is backwards compatible with MinGW32, so check for it first. + elif test_${pfx}cpp_condition _mingw.h "defined __MINGW64_VERSION_MAJOR"; then + eval ${pfx}libc_type=mingw64 + if test_${pfx}cpp_condition _mingw.h "__MINGW64_VERSION_MAJOR < 3"; then + add_compat msvcrt/snprintf.o + add_cflags "-include $source_path/compat/msvcrt/snprintf.h" + fi + add_${pfx}cppflags -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 + eval test \$${pfx_no_}cc_type = "gcc" && + add_${pfx}cppflags -D__printf__=__gnu_printf__ + test_${pfx}cpp_condition windows.h "!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600" && + add_${pfx}cppflags -D_WIN32_WINNT=0x0600 + add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 + elif test_${pfx}cpp_condition _mingw.h "defined __MINGW_VERSION" || + test_${pfx}cpp_condition _mingw.h "defined __MINGW32_VERSION"; then + eval ${pfx}libc_type=mingw32 + test_${pfx}cpp_condition _mingw.h "__MINGW32_MAJOR_VERSION > 3 || \ + (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 15)" || + die "ERROR: MinGW32 runtime version must be >= 3.15." + add_${pfx}cppflags -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 + test_${pfx}cpp_condition _mingw.h "__MSVCRT_VERSION__ < 0x0700" && + add_${pfx}cppflags -D__MSVCRT_VERSION__=0x0700 + test_${pfx}cpp_condition windows.h "!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600" && + add_${pfx}cppflags -D_WIN32_WINNT=0x0600 + eval test \$${pfx_no_}cc_type = "gcc" && + add_${pfx}cppflags -D__printf__=__gnu_printf__ + add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 + elif test_${pfx}cpp_condition crtversion.h "defined _VC_CRT_MAJOR_VERSION"; then + eval ${pfx}libc_type=msvcrt + if test_${pfx}cpp_condition crtversion.h "_VC_CRT_MAJOR_VERSION < 14"; then + if [ "$pfx" = host_ ]; then + add_host_cppflags -Dsnprintf=_snprintf + else + add_compat strtod.o strtod=avpriv_strtod + add_compat msvcrt/snprintf.o snprintf=avpriv_snprintf \ + _snprintf=avpriv_snprintf \ + vsnprintf=avpriv_vsnprintf + fi + fi + add_${pfx}cppflags -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS + # The MSVC 2010 headers (Win 7.0 SDK) set _WIN32_WINNT to + # 0x601 by default unless something else is set by the user. + # This can easily lead to us detecting functions only present + # in such new versions and producing binaries requiring windows 7.0. + # Therefore explicitly set the default to Vista unless the user has + # set something else on the command line. + # Don't do this if WINAPI_FAMILY is set and is set to a non-desktop + # family. For these cases, configure is free to use any functions + # found in the SDK headers by default. (Alternatively, we could force + # _WIN32_WINNT to 0x0602 in that case.) + test_${pfx}cpp_condition stdlib.h "defined(_WIN32_WINNT)" || + { test_${pfx}cpp < +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#error not desktop +#endif +#endif +EOF + if [ "$pfx" = "" ]; then + check_func strtoll || add_cflags -Dstrtoll=_strtoi64 + check_func strtoull || add_cflags -Dstrtoull=_strtoui64 + fi + elif test_${pfx}cpp_condition stddef.h "defined __KLIBC__"; then + eval ${pfx}libc_type=klibc + elif test_${pfx}cpp_condition sys/cdefs.h "defined __BIONIC__"; then + eval ${pfx}libc_type=bionic + elif test_${pfx}cpp_condition sys/brand.h "defined LABELED_BRAND_NAME"; then + eval ${pfx}libc_type=solaris + add_${pfx}cppflags -D__EXTENSIONS__ -D_XOPEN_SOURCE=600 + elif test_${pfx}cpp_condition sys/version.h "defined __DJGPP__"; then + eval ${pfx}libc_type=djgpp + add_cppflags -U__STRICT_ANSI__ + add_cflags "-include $source_path/compat/djgpp/math.h" + add_compat djgpp/math.o + fi + test_${pfx}cc < +void *v = localtime_r; +EOF +test "$?" != 0 && test_${pfx}cc -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 < +void *v = localtime_r; +EOF + + eval test -n "\${${pfx}libc_type}" && enable ${pfx}libc_${libc_type} +} + +probe_libc +probe_libc host_ + +# hacks for compiler/libc/os combinations + +case $libc_type in + bionic) + add_compat strtod.o strtod=avpriv_strtod + ;; +esac + +check_compile_assert flt_lim "float.h limits.h" "DBL_MAX == (double)DBL_MAX" || + add_cppflags '-I\$(SRC_PATH)/compat/float' + +test_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable_weak pic + +set_default libdir +: ${shlibdir_default:="$libdir"} +: ${pkgconfigdir_default:="$libdir/pkgconfig"} + +set_default $PATHS_LIST +set_default nm + +disabled optimizations || enabled ossfuzz || check_cflags -fomit-frame-pointer + +enable_weak_pic() { + disabled pic && return + enable pic + add_cppflags -DPIC + case "$target_os" in + mingw*|cygwin*|win*) + ;; + *) + add_cflags -fPIC + add_asflags -fPIC + ;; + esac +} + +enabled pic && enable_weak_pic + +test_cc <= 30"; then + : + elif ! test_cpp_condition stddef.h "defined __ARM_PCS || defined __SOFTFP__" && [ $target_os != darwin ]; then + case "${cross_prefix:-$cc}" in + *hardfloat*) enable vfp_args; fpabi=vfp ;; + *) check_ld "cc" vfp_args <= 9.0.18.0" "$ffnv_hdr_list" "" || \ + check_pkg_config ffnvcodec "ffnvcodec >= 8.2.15.8 ffnvcodec < 8.3" "$ffnv_hdr_list" "" || \ + check_pkg_config ffnvcodec "ffnvcodec >= 8.1.24.9 ffnvcodec < 8.2" "$ffnv_hdr_list" "" || \ + check_pkg_config ffnvcodec "ffnvcodec >= 8.0.14.9 ffnvcodec < 8.1" "$ffnv_hdr_list" "" +fi + +check_cpp_condition winrt windows.h "!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)" + +if ! disabled w32threads && ! enabled pthreads; then + check_func_headers "windows.h process.h" _beginthreadex && + check_type "windows.h" CONDITION_VARIABLE && + check_type "windows.h" INIT_ONCE && + enable w32threads || disable w32threads + if ! enabled w32threads && enabled winrt; then + check_func_headers "windows.h" CreateThread && + enable w32threads || disable w32threads + fi +fi + +# check for some common methods of building with pthread support +# do this before the optional library checks as some of them require pthreads +if ! disabled pthreads && ! enabled w32threads && ! enabled os2threads; then + if check_lib pthreads pthread.h pthread_join -pthread && + check_lib pthreads pthread.h pthread_create -pthread; then + add_cflags -pthread + elif check_lib pthreads pthread.h pthread_join -pthreads && + check_lib pthreads pthread.h pthread_create -pthreads; then + add_cflags -pthreads + elif check_lib pthreads pthread.h pthread_join -ldl -pthread && + check_lib pthreads pthread.h pthread_create -ldl -pthread; then + add_cflags -ldl -pthread + elif check_lib pthreads pthread.h pthread_join -lpthreadGC2 && + check_lib pthreads pthread.h pthread_create -lpthreadGC2; then + : + elif check_lib pthreads pthread.h pthread_join -lpthread && + check_lib pthreads pthread.h pthread_create -lpthread; then + : + elif check_func pthread_join && check_func pthread_create; then + enable pthreads + fi + check_cc pthreads "pthread.h" "static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER" + + if enabled pthreads; then + check_builtin sem_timedwait semaphore.h "sem_t *s; sem_init(s,0,0); sem_timedwait(s,0); sem_destroy(s)" $pthreads_extralibs + check_func pthread_cancel $pthreads_extralibs + fi +fi + +enabled zlib && { check_pkg_config zlib zlib "zlib.h" zlibVersion || + check_lib zlib zlib.h zlibVersion -lz; } +enabled bzlib && check_lib bzlib bzlib.h BZ2_bzlibVersion -lbz2 +enabled lzma && check_lib lzma lzma.h lzma_version_number -llzma + +# On some systems dynamic loading requires no extra linker flags +check_lib libdl dlfcn.h "dlopen dlsym" || check_lib libdl dlfcn.h "dlopen dlsym" -ldl + +check_lib libm math.h sin -lm + +atan2f_args=2 +copysign_args=2 +hypot_args=2 +ldexpf_args=2 +powf_args=2 + +for func in $MATH_FUNCS; do + eval check_mathfunc $func \${${func}_args:-1} $libm_extralibs +done + +for func in $COMPLEX_FUNCS; do + eval check_complexfunc $func \${${func}_args:-1} +done + +# these are off by default, so fail if requested and not available +enabled cuda_nvcc && { check_nvcc cuda_nvcc || die "ERROR: failed checking for nvcc."; } +enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint +enabled decklink && { require_headers DeckLinkAPI.h && + { test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a090500" || die "ERROR: Decklink API version must be >= 10.9.5."; } } +enabled frei0r && require_headers "frei0r.h dlfcn.h" +enabled gmp && require gmp gmp.h mpz_export -lgmp +enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init +enabled jni && { [ $target_os = "android" ] && check_headers jni.h && enabled pthreads || die "ERROR: jni not found"; } +enabled ladspa && require_headers "ladspa.h dlfcn.h" +enabled libaom && require_pkg_config libaom "aom >= 1.0.0" aom/aom_codec.h aom_codec_version +enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new || + { enabled gpl && require_pkg_config libaribb24 aribb24 "aribb24/aribb24.h" arib_instance_new; } || + die "ERROR: libaribb24 requires version higher than 1.0.3 or --enable-gpl."; } +enabled lv2 && require_pkg_config lv2 lilv-0 "lilv/lilv.h" lilv_world_new +enabled libiec61883 && require libiec61883 libiec61883/iec61883.h iec61883_cmp_connect -lraw1394 -lavc1394 -lrom1394 -liec61883 +enabled libass && require_pkg_config libass libass ass/ass.h ass_library_init +enabled libbluray && require_pkg_config libbluray libbluray libbluray/bluray.h bd_open +enabled libbs2b && require_pkg_config libbs2b libbs2b bs2b.h bs2b_open +enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && + { check_lib libcelt celt/celt.h celt_decoder_create_custom -lcelt0 || + die "ERROR: libcelt must be installed and version must be >= 0.11.0."; } +enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas +enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2 +enabled libdav1d && require_pkg_config libdav1d "dav1d >= 0.2.1" "dav1d/dav1d.h" dav1d_version +enabled libdavs2 && require_pkg_config libdavs2 "davs2 >= 1.6.0" davs2.h davs2_decoder_open +enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new +enabled libdrm && require_pkg_config libdrm libdrm xf86drm.h drmGetVersion +enabled libfdk_aac && { check_pkg_config libfdk_aac fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen || + { require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac && + warn "using libfdk without pkg-config"; } } +flite_extralibs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite" +enabled libflite && require libflite "flite/flite.h" flite_init $flite_extralibs +enabled fontconfig && enable libfontconfig +enabled libfontconfig && require_pkg_config libfontconfig fontconfig "fontconfig/fontconfig.h" FcInit +enabled libfreetype && require_pkg_config libfreetype freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType +enabled libfribidi && require_pkg_config libfribidi fribidi fribidi.h fribidi_version_info +enabled libgme && { check_pkg_config libgme libgme gme/gme.h gme_new_emu || + require libgme gme/gme.h gme_new_emu -lgme -lstdc++; } +enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do + check_lib libgsm "${gsm_hdr}" gsm_create -lgsm && break; + done || die "ERROR: libgsm not found"; } +enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc $pthreads_extralibs +enabled libklvanc && require libklvanc libklvanc/vanc.h klvanc_context_create -lklvanc +enabled libkvazaar && require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get +enabled liblensfun && require_pkg_config liblensfun lensfun lensfun.h lf_db_new +# While it may appear that require is being used as a pkg-config +# fallback for libmfx, it is actually being used to detect a different +# installation route altogether. If libmfx is installed via the Intel +# Media SDK or Intel Media Server Studio, these don't come with +# pkg-config support. Instead, users should make sure that the build +# can find the libraries and headers through other means. +enabled libmfx && { check_pkg_config libmfx libmfx "mfx/mfxvideo.h" MFXInit || + { require libmfx "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } } +enabled libmodplug && require_pkg_config libmodplug libmodplug libmodplug/modplug.h ModPlug_Load +enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame $libm_extralibs +enabled libmysofa && { check_pkg_config libmysofa libmysofa mysofa.h mysofa_load || + require libmysofa mysofa.h mysofa_load -lmysofa $zlib_extralibs; } +enabled libnpp && { check_lib libnpp npp.h nppGetLibVersion -lnppig -lnppicc -lnppc -lnppidei || + check_lib libnpp npp.h nppGetLibVersion -lnppi -lnppc -lnppidei || + die "ERROR: libnpp not found"; } +enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb +enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb +enabled libopencv && { check_headers opencv2/core/core_c.h && + { check_pkg_config libopencv opencv opencv2/core/core_c.h cvCreateImageHeader || + require libopencv opencv2/core/core_c.h cvCreateImageHeader -lopencv_core -lopencv_imgproc; } || + require_pkg_config libopencv opencv opencv/cxcore.h cvCreateImageHeader; } +enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_api.h WelsGetCodecVersion +enabled libopenjpeg && { check_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version || + { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } } +enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++" +enabled libopus && { + enabled libopus_decoder && { + require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create + } + enabled libopus_encoder && { + require_pkg_config libopus opus opus_multistream.h opus_multistream_surround_encoder_create + } +} +enabled libpulse && require_pkg_config libpulse libpulse pulse/pulseaudio.h pa_context_new +enabled librsvg && require_pkg_config librsvg librsvg-2.0 librsvg-2.0/librsvg/rsvg.h rsvg_handle_render_cairo +enabled librtmp && require_pkg_config librtmp librtmp librtmp/rtmp.h RTMP_Socket +enabled librubberband && require_pkg_config librubberband "rubberband >= 1.8.1" rubberband/rubberband-c.h rubberband_new -lstdc++ && append librubberband_extralibs "-lstdc++" +enabled libshine && require_pkg_config libshine shine shine/layer3.h shine_encode_buffer +enabled libsmbclient && { check_pkg_config libsmbclient smbclient libsmbclient.h smbc_init || + require libsmbclient libsmbclient.h smbc_init -lsmbclient; } +enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnappy -lstdc++ +enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr +enabled libssh && require_pkg_config libssh libssh libssh/sftp.h sftp_init +enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init +enabled libsrt && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket +enabled libtensorflow && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow +enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate +enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg +enabled libtls && require_pkg_config libtls libtls tls.h tls_configure +enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame && + { check_lib libtwolame twolame.h twolame_encode_buffer_float32_interleaved -ltwolame || + die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; } +enabled libv4l2 && require_pkg_config libv4l2 libv4l2 libv4l2.h v4l2_ioctl +enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit +enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 1.3.9" libvmaf.h compute_vmaf +enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc +enabled libvorbis && require_pkg_config libvorbis vorbis vorbis/codec.h vorbis_info_init && + require_pkg_config libvorbisenc vorbisenc vorbis/vorbisenc.h vorbis_encode_init + +enabled libvpx && { + enabled libvpx_vp8_decoder && { + check_pkg_config libvpx_vp8_decoder "vpx >= 1.4.0" "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp8_dx || + check_lib libvpx_vp8_decoder "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp8_dx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs $pthreads_extralibs" + } + enabled libvpx_vp8_encoder && { + check_pkg_config libvpx_vp8_encoder "vpx >= 1.4.0" "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp8_cx || + check_lib libvpx_vp8_encoder "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp8_cx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs $pthreads_extralibs" + } + enabled libvpx_vp9_decoder && { + check_pkg_config libvpx_vp9_decoder "vpx >= 1.4.0" "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp9_dx || + check_lib libvpx_vp9_decoder "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs $pthreads_extralibs" + } + enabled libvpx_vp9_encoder && { + check_pkg_config libvpx_vp9_encoder "vpx >= 1.4.0" "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp9_cx || + check_lib libvpx_vp9_encoder "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs $pthreads_extralibs" + } + if disabled_all libvpx_vp8_decoder libvpx_vp9_decoder libvpx_vp8_encoder libvpx_vp9_encoder; then + die "libvpx enabled but no supported decoders found" + fi +} + +enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack +enabled libwebp && { + enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion + enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; } +enabled libx264 && { check_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode || + { require libx264 "stdint.h x264.h" x264_encoder_encode "-lx264 $pthreads_extralibs $libm_extralibs" && + warn "using libx264 without pkg-config"; } } && + require_cpp_condition libx264 x264.h "X264_BUILD >= 118" && + check_cpp_condition libx262 x264.h "X264_MPEG2" +enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get && + require_cpp_condition libx265 x265.h "X265_BUILD >= 68" +enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode "-lxavs $pthreads_extralibs $libm_extralibs" +enabled libxavs2 && require_pkg_config libxavs2 "xavs2 >= 1.3.0" "stdint.h xavs2.h" xavs2_api_get +enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore +enabled libzimg && require_pkg_config libzimg "zimg >= 2.7.0" zimg.h zimg_get_api_version +enabled libzmq && require_pkg_config libzmq libzmq zmq.h zmq_ctx_new +enabled libzvbi && require_pkg_config libzvbi zvbi-0.2 libzvbi.h vbi_decoder_new && + { test_cpp_condition libzvbi.h "VBI_VERSION_MAJOR > 0 || VBI_VERSION_MINOR > 2 || VBI_VERSION_MINOR == 2 && VBI_VERSION_MICRO >= 28" || + enabled gpl || die "ERROR: libzvbi requires version 0.2.28 or --enable-gpl."; } +enabled libxml2 && require_pkg_config libxml2 libxml-2.0 libxml2/libxml/xmlversion.h xmlCheckVersion +enabled mbedtls && { check_pkg_config mbedtls mbedtls mbedtls/x509_crt.h mbedtls_x509_crt_init || + check_pkg_config mbedtls mbedtls mbedtls/ssl.h mbedtls_ssl_init || + check_lib mbedtls mbedtls/ssl.h mbedtls_ssl_init -lmbedtls -lmbedx509 -lmbedcrypto || + die "ERROR: mbedTLS not found"; } +enabled mediacodec && { enabled jni || die "ERROR: mediacodec requires --enable-jni"; } +enabled mmal && { check_lib mmal interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host || + { ! enabled cross_compile && + add_cflags -isystem/opt/vc/include/ -isystem/opt/vc/include/interface/vmcs_host/linux -isystem/opt/vc/include/interface/vcos/pthreads -fgnu89-inline && + add_ldflags -L/opt/vc/lib/ && + check_lib mmal interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host; } || + die "ERROR: mmal not found" && + check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS"; } +enabled openal && { { for al_extralibs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do + check_lib openal 'AL/al.h' alGetError "${al_extralibs}" && break; done } || + die "ERROR: openal not found"; } && + { test_cpp_condition "AL/al.h" "defined(AL_VERSION_1_1)" || + die "ERROR: openal must be installed and version must be 1.1 or compatible"; } +enabled opencl && { check_pkg_config opencl OpenCL CL/cl.h clEnqueueNDRangeKernel || + check_lib opencl OpenCL/cl.h clEnqueueNDRangeKernel -Wl,-framework,OpenCL || + check_lib opencl CL/cl.h clEnqueueNDRangeKernel -lOpenCL || + die "ERROR: opencl not found"; } && + { test_cpp_condition "OpenCL/cl.h" "defined(CL_VERSION_1_2)" || + test_cpp_condition "CL/cl.h" "defined(CL_VERSION_1_2)" || + die "ERROR: opencl must be installed and version must be 1.2 or compatible"; } +enabled opengl && { check_lib opengl GL/glx.h glXGetProcAddress "-lGL" || + check_lib opengl windows.h wglGetProcAddress "-lopengl32 -lgdi32" || + check_lib opengl OpenGL/gl3.h glGetError "-Wl,-framework,OpenGL" || + check_lib opengl ES2/gl.h glGetError "-isysroot=${sysroot} -Wl,-framework,OpenGLES" || + die "ERROR: opengl not found." + } +enabled omx && require_headers OMX_Core.h +enabled omx_rpi && { check_headers OMX_Core.h || + { ! enabled cross_compile && add_cflags -isystem/opt/vc/include/IL && check_headers OMX_Core.h ; } || + die "ERROR: OpenMAX IL headers not found"; } && enable omx +enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OPENSSL_init_ssl || + check_pkg_config openssl openssl openssl/ssl.h SSL_library_init || + check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto || + check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || + check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || + die "ERROR: openssl not found"; } +enabled pocketsphinx && require_pkg_config pocketsphinx pocketsphinx pocketsphinx/pocketsphinx.h ps_init +enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/rk_mpi.h mpp_create && + require_pkg_config rockchip_mpp "rockchip_mpp >= 1.3.7" rockchip/rk_mpi.h mpp_create && + { enabled libdrm || + die "ERROR: rkmpp requires --enable-libdrm"; } + } +enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init + + +if enabled gcrypt; then + GCRYPT_CONFIG="${cross_prefix}libgcrypt-config" + if "${GCRYPT_CONFIG}" --version > /dev/null 2>&1; then + gcrypt_cflags=$("${GCRYPT_CONFIG}" --cflags) + gcrypt_extralibs=$("${GCRYPT_CONFIG}" --libs) + check_func_headers gcrypt.h gcry_mpi_new $gcrypt_cflags $gcrypt_extralibs || + die "ERROR: gcrypt not found" + add_cflags $gcrypt_cflags + else + require gcrypt gcrypt.h gcry_mpi_new -lgcrypt + fi +fi + +if enabled sdl2; then + SDL2_CONFIG="${cross_prefix}sdl2-config" + test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 2.1.0" SDL_events.h SDL_PollEvent + if disabled sdl2 && "${SDL2_CONFIG}" --version > /dev/null 2>&1; then + sdl2_cflags=$("${SDL2_CONFIG}" --cflags) + sdl2_extralibs=$("${SDL2_CONFIG}" --libs) + test_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags && + test_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x020100" $sdl2_cflags && + check_func_headers SDL_events.h SDL_PollEvent $sdl2_extralibs $sdl2_cflags && + enable sdl2 + fi + if test $target_os = "mingw32"; then + sdl2_extralibs=$(filter_out '-mwindows' $sdl2_extralibs) + fi +fi + +if enabled decklink; then + case $target_os in + mingw32*|mingw64*|win32|win64) + decklink_outdev_extralibs="$decklink_outdev_extralibs -lole32 -loleaut32" + decklink_indev_extralibs="$decklink_indev_extralibs -lole32 -loleaut32" + ;; + esac +fi + +enabled securetransport && + check_func SecIdentityCreate "-Wl,-framework,CoreFoundation -Wl,-framework,Security" && + check_lib securetransport "Security/SecureTransport.h Security/Security.h" "SSLCreateContext" "-Wl,-framework,CoreFoundation -Wl,-framework,Security" || + disable securetransport + +enabled securetransport && + check_func SecItemImport "-Wl,-framework,CoreFoundation -Wl,-framework,Security" + +enabled schannel && + check_func_headers "windows.h security.h" InitializeSecurityContext -DSECURITY_WIN32 -lsecur32 && + test_cpp_condition winerror.h "defined(SEC_I_CONTEXT_EXPIRED)" && + schannel_extralibs="-lsecur32" || + disable schannel + +makeinfo --version > /dev/null 2>&1 && enable makeinfo || disable makeinfo +enabled makeinfo \ + && [ 0$(makeinfo --version | grep "texinfo" | sed 's/.*texinfo[^0-9]*\([0-9]*\)\..*/\1/') -ge 5 ] \ + && enable makeinfo_html || disable makeinfo_html +disabled makeinfo_html && texi2html --help 2> /dev/null | grep -q 'init-file' && enable texi2html || disable texi2html +perl -v > /dev/null 2>&1 && enable perl || disable perl +pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man +rsync --help 2> /dev/null | grep -q 'contimeout' && enable rsync_contimeout || disable rsync_contimeout + +# check V4L2 codecs available in the API +check_headers linux/fb.h +check_headers linux/videodev2.h +test_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete +check_cc v4l2_m2m linux/videodev2.h "int i = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_BUF_FLAG_LAST;" +check_cc vc1_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VC1_ANNEX_G;" +check_cc mpeg1_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG1;" +check_cc mpeg2_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2;" +check_cc mpeg4_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG4;" +check_cc hevc_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_HEVC;" +check_cc h263_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_H263;" +check_cc h264_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_H264;" +check_cc vp8_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP8;" +check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;" + +check_headers sys/videoio.h +test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete + +check_lib user32 "windows.h winuser.h" GetShellWindow -luser32 +check_lib vfw32 "windows.h vfw.h" capCreateCaptureWindow -lvfw32 +# check that WM_CAP_DRIVER_CONNECT is defined to the proper value +# w32api 3.12 had it defined wrong +check_cpp_condition vfwcap_defines vfw.h "WM_CAP_DRIVER_CONNECT > WM_USER" + +check_type "dshow.h" IBaseFilter + +# check for ioctl_meteor.h, ioctl_bt848.h and alternatives +check_headers "dev/bktr/ioctl_meteor.h dev/bktr/ioctl_bt848.h" || + check_headers "machine/ioctl_meteor.h machine/ioctl_bt848.h" || + check_headers "dev/video/meteor/ioctl_meteor.h dev/video/bktr/ioctl_bt848.h" || + check_headers "dev/ic/bt8xx.h" + +if check_struct sys/soundcard.h audio_buf_info bytes; then + enable_sanitized sys/soundcard.h +else + test_cc -D__BSD_VISIBLE -D__XSI_VISIBLE < + audio_buf_info abc; +EOF +fi + +enabled alsa && check_pkg_config alsa alsa "alsa/asoundlib.h" snd_pcm_htimestamp || + check_lib alsa alsa/asoundlib.h snd_pcm_htimestamp -lasound + +enabled libjack && + require_pkg_config libjack jack jack/jack.h jack_port_get_latency_range + +enabled sndio && check_lib sndio sndio.h sio_open -lsndio + +if enabled libcdio; then + check_pkg_config libcdio libcdio_paranoia "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open || + check_pkg_config libcdio libcdio_paranoia "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open || + check_lib libcdio "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || + check_lib libcdio "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || + die "ERROR: No usable libcdio/cdparanoia found" +fi + +enabled libxcb && check_pkg_config libxcb "xcb >= 1.4" xcb/xcb.h xcb_connect || + disable libxcb_shm libxcb_shape libxcb_xfixes + +if enabled libxcb; then + enabled libxcb_shm && check_pkg_config libxcb_shm xcb-shm xcb/shm.h xcb_shm_attach + enabled libxcb_shape && check_pkg_config libxcb_shape xcb-shape xcb/shape.h xcb_shape_get_rectangles + enabled libxcb_xfixes && check_pkg_config libxcb_xfixes xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image +fi + +check_func_headers "windows.h" CreateDIBSection "$gdigrab_indev_extralibs" + +# d3d11va requires linking directly to dxgi and d3d11 if not building for +# the desktop api partition +test_cpp < +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#error desktop, not uwp +#else +// WINAPI_FAMILY_APP, WINAPI_FAMILY_PHONE_APP => UWP +#endif +#else +#error no family set +#endif +EOF + +enabled vaapi && + check_pkg_config vaapi "libva >= 0.35.0" "va/va.h" vaInitialize + +if enabled vaapi; then + check_pkg_config vaapi_drm "libva-drm" "va/va_drm.h" vaGetDisplayDRM + + if enabled xlib; then + check_pkg_config vaapi_x11 "libva-x11" "va/va_x11.h" vaGetDisplay + fi + + check_cpp_condition vaapi_1 "va/va.h" "VA_CHECK_VERSION(1, 0, 0)" + + check_type "va/va.h va/va_dec_hevc.h" "VAPictureParameterBufferHEVC" + check_struct "va/va.h" "VADecPictureParameterBufferVP9" bit_depth + check_struct "va/va.h va/va_vpp.h" "VAProcPipelineCaps" rotation_flags + check_type "va/va.h va/va_enc_hevc.h" "VAEncPictureParameterBufferHEVC" + check_type "va/va.h va/va_enc_jpeg.h" "VAEncPictureParameterBufferJPEG" + check_type "va/va.h va/va_enc_vp8.h" "VAEncPictureParameterBufferVP8" + check_type "va/va.h va/va_enc_vp9.h" "VAEncPictureParameterBufferVP9" +fi + +if enabled_all opencl libdrm ; then + check_type "CL/cl_intel.h" "clCreateImageFromFdINTEL_fn" && + enable opencl_drm_beignet + check_func_headers "CL/cl_ext.h" clImportMemoryARM && + enable opencl_drm_arm +fi + +if enabled_all opencl vaapi ; then + if enabled opencl_drm_beignet ; then + enable opencl_vaapi_beignet + else + check_type "CL/cl.h CL/cl_va_api_media_sharing_intel.h" "clCreateFromVA_APIMediaSurfaceINTEL_fn" && + enable opencl_vaapi_intel_media + fi +fi + +if enabled_all opencl dxva2 ; then + check_type "CL/cl_dx9_media_sharing.h" cl_dx9_surface_info_khr && + enable opencl_dxva2 +fi + +if enabled_all opencl d3d11va ; then + check_type "CL/cl_d3d11.h" clGetDeviceIDsFromD3D11KHR_fn && + enable opencl_d3d11 +fi + +enabled vdpau && + check_cpp_condition vdpau vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" + +enabled vdpau && + check_lib vdpau_x11 "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau -lX11 + +enabled crystalhd && check_lib crystalhd "stdint.h libcrystalhd/libcrystalhd_if.h" DtsCrystalHDVersion -lcrystalhd + +if enabled x86; then + case $target_os in + mingw32*|mingw64*|win32|win64|linux|cygwin*) + ;; + *) + disable ffnvcodec cuvid nvdec nvenc + ;; + esac +elif enabled ppc64 && ! enabled bigendian; then + case $target_os in + linux) + ;; + *) + disable ffnvcodec cuvid nvdec nvenc + ;; + esac +else + disable ffnvcodec cuvid nvdec nvenc +fi + +enabled ffnvcodec && enable cuda + +enabled nvenc && + test_cc -I$source_path < +NV_ENCODE_API_FUNCTION_LIST flist; +void f(void) { struct { const GUID guid; } s[] = { { NV_ENC_PRESET_HQ_GUID } }; } +int main(void) { return 0; } +EOF + +enabled amf && + check_cpp_condition amf "AMF/core/Version.h" \ + "(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400040001" + +# Funny iconv installations are not unusual, so check it after all flags have been set +if enabled libc_iconv; then + check_func_headers iconv.h iconv +elif enabled iconv; then + check_func_headers iconv.h iconv || check_lib iconv iconv.h iconv -liconv +fi + +enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" + +# add some useful compiler flags if supported +check_cflags -Wdeclaration-after-statement +check_cflags -Wall +check_cflags -Wdisabled-optimization +check_cflags -Wpointer-arith +check_cflags -Wredundant-decls +check_cflags -Wwrite-strings +check_cflags -Wtype-limits +check_cflags -Wundef +check_cflags -Wmissing-prototypes +check_cflags -Wno-pointer-to-int-cast +check_cflags -Wstrict-prototypes +check_cflags -Wempty-body + +if enabled extra_warnings; then + check_cflags -Wcast-qual + check_cflags -Wextra + check_cflags -Wpedantic +fi + +check_disable_warning(){ + warning_flag=-W${1#-Wno-} + test_cflags $unknown_warning_flags $warning_flag && add_cflags $1 +} + +test_cflags -Werror=unused-command-line-argument && + append unknown_warning_flags "-Werror=unused-command-line-argument" +test_cflags -Werror=unknown-warning-option && + append unknown_warning_flags "-Werror=unknown-warning-option" + +check_disable_warning -Wno-parentheses +check_disable_warning -Wno-switch +check_disable_warning -Wno-format-zero-length +check_disable_warning -Wno-pointer-sign +check_disable_warning -Wno-unused-const-variable +check_disable_warning -Wno-bool-operation +check_disable_warning -Wno-char-subscripts + +check_disable_warning_headers(){ + warning_flag=-W${1#-Wno-} + test_cflags $warning_flag && add_cflags_headers $1 +} + +check_disable_warning_headers -Wno-deprecated-declarations +check_disable_warning_headers -Wno-unused-variable + +test_cc < $TMPV + if test_ldflags -Wl,${version_script},$TMPV; then + append SHFLAGS '-Wl,${version_script},\$(SUBDIR)lib\$(NAME).ver' + quotes='""' + test_cc <= 1400" && + add_cflags -Qansi-alias + # Some inline asm is not compilable in debug + if enabled debug; then + disable ebp_available + disable ebx_available + fi + fi + # msvcrt10 x64 incorrectly enables log2, only msvcrt12 (MSVC 2013) onwards actually has log2. + check_cpp_condition log2 crtversion.h "_VC_CRT_MAJOR_VERSION >= 12" + # The CRT headers contain __declspec(restrict) in a few places, but if redefining + # restrict, this might break. MSVC 2010 and 2012 fail with __declspec(__restrict) + # (as it ends up if the restrict redefine is done before including stdlib.h), while + # MSVC 2013 and newer can handle it fine. + # If this declspec fails, force including stdlib.h before the restrict redefinition + # happens in config.h. + if [ $restrict_keyword != restrict ]; then + test_cc <= 190024218" || + check_cflags -d2SSAOptimizer- + # enable utf-8 source processing on VS2015 U2 and newer + test_cpp_condition windows.h "_MSC_FULL_VER >= 190023918" && + add_cflags -utf-8 +fi + +for pfx in "" host_; do + varname=${pfx%_}cc_type + eval "type=\$$varname" + if [ "$type" = "msvc" ]; then + test_${pfx}cc < Makefile + +esc(){ + echo "$*" | sed 's/%/%25/g;s/:/%3a/g' +} + +echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $FFMPEG_CONFIGURATION)" > ffbuild/config.fate + +enabled stripping || strip="echo skipping strip" +enabled stripping || striptype="" + +config_files="$TMPH ffbuild/config.mak" + +cat > ffbuild/config.mak <> ffbuild/config.mak' $LIBRARY_LIST + +for entry in $LIBRARY_LIST $PROGRAM_LIST $EXTRALIBS_LIST; do + eval echo "EXTRALIBS-${entry}=\$${entry}_extralibs" >> ffbuild/config.mak +done + +cat > $TMPH <>$TMPH + +test -n "$malloc_prefix" && + echo "#define MALLOC_PREFIX $malloc_prefix" >>$TMPH + +if enabled x86asm; then + append config_files $TMPASM + cat > $TMPASM <> $TMPH + +print_config ARCH_ "$config_files" $ARCH_LIST +print_config HAVE_ "$config_files" $HAVE_LIST +print_config CONFIG_ "$config_files" $CONFIG_LIST \ + $CONFIG_EXTRA \ + $ALL_COMPONENTS \ + +echo "#endif /* FFMPEG_CONFIG_H */" >> $TMPH +echo "endif # FFMPEG_CONFIG_MAK" >> ffbuild/config.mak + +# Do not overwrite an unchanged config.h to avoid superfluous rebuilds. +cp_if_changed $TMPH config.h +touch ffbuild/.config + +enabled x86asm && cp_if_changed $TMPASM config.asm + +cat > $TMPH <> $TMPH + +cp_if_changed $TMPH libavutil/avconfig.h + +# full_filter_name_foo=vf_foo +# full_filter_name_bar=asrc_bar +# ... +eval "$(sed -n "s/^extern AVFilter ff_\([avfsinkrc]\{2,5\}\)_\(.*\);/full_filter_name_\2=\1_\2/p" $source_path/libavfilter/allfilters.c)" + +# generate the lists of enabled components +print_enabled_components(){ + file=$1 + struct_name=$2 + name=$3 + shift 3 + echo "static const $struct_name * const $name[] = {" > $TMPH + for c in $*; do + if enabled $c; then + case $name in + filter_list) + eval c=\$full_filter_name_${c%_filter} + ;; + indev_list) + c=${c%_indev}_demuxer + ;; + outdev_list) + c=${c%_outdev}_muxer + ;; + esac + printf " &ff_%s,\n" $c >> $TMPH + fi + done + if [ "$name" = "filter_list" ]; then + for c in asrc_abuffer vsrc_buffer asink_abuffer vsink_buffer; do + printf " &ff_%s,\n" $c >> $TMPH + done + fi + echo " NULL };" >> $TMPH + cp_if_changed $TMPH $file +} + +print_enabled_components libavfilter/filter_list.c AVFilter filter_list $FILTER_LIST +print_enabled_components libavcodec/codec_list.c AVCodec codec_list $CODEC_LIST +print_enabled_components libavcodec/parser_list.c AVCodecParser parser_list $PARSER_LIST +print_enabled_components libavcodec/bsf_list.c AVBitStreamFilter bitstream_filters $BSF_LIST +print_enabled_components libavformat/demuxer_list.c AVInputFormat demuxer_list $DEMUXER_LIST +print_enabled_components libavformat/muxer_list.c AVOutputFormat muxer_list $MUXER_LIST +print_enabled_components libavdevice/indev_list.c AVInputFormat indev_list $INDEV_LIST +print_enabled_components libavdevice/outdev_list.c AVOutputFormat outdev_list $OUTDEV_LIST +print_enabled_components libavformat/protocol_list.c URLProtocol url_protocols $PROTOCOL_LIST + +# Settings for pkg-config files + +cat > $TMPH <> $TMPH +done + +cp_if_changed $TMPH ffbuild/config.sh diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/arch.mak b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/arch.mak new file mode 100644 index 000000000..e09006efc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/arch.mak @@ -0,0 +1,17 @@ +OBJS-$(HAVE_ARMV5TE) += $(ARMV5TE-OBJS) $(ARMV5TE-OBJS-yes) +OBJS-$(HAVE_ARMV6) += $(ARMV6-OBJS) $(ARMV6-OBJS-yes) +OBJS-$(HAVE_ARMV8) += $(ARMV8-OBJS) $(ARMV8-OBJS-yes) +OBJS-$(HAVE_VFP) += $(VFP-OBJS) $(VFP-OBJS-yes) +OBJS-$(HAVE_NEON) += $(NEON-OBJS) $(NEON-OBJS-yes) + +OBJS-$(HAVE_MIPSFPU) += $(MIPSFPU-OBJS) $(MIPSFPU-OBJS-yes) +OBJS-$(HAVE_MIPSDSP) += $(MIPSDSP-OBJS) $(MIPSDSP-OBJS-yes) +OBJS-$(HAVE_MIPSDSPR2) += $(MIPSDSPR2-OBJS) $(MIPSDSPR2-OBJS-yes) +OBJS-$(HAVE_MSA) += $(MSA-OBJS) $(MSA-OBJS-yes) +OBJS-$(HAVE_MMI) += $(MMI-OBJS) $(MMI-OBJS-yes) + +OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes) +OBJS-$(HAVE_VSX) += $(VSX-OBJS) $(VSX-OBJS-yes) + +OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes) +OBJS-$(HAVE_X86ASM) += $(X86ASM-OBJS) $(X86ASM-OBJS-yes) diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/common.mak b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/common.mak new file mode 100644 index 000000000..7355508ea --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/common.mak @@ -0,0 +1,175 @@ +# +# common bits used by all libraries +# + +DEFAULT_X86ASMD=.dbg + +ifeq ($(DBG),1) +X86ASMD=$(DEFAULT_X86ASMD) +else +X86ASMD= +endif + +ifndef SUBDIR + +ifndef V +Q = @ +ECHO = printf "$(1)\t%s\n" $(2) +BRIEF = CC CXX OBJCC HOSTCC HOSTLD AS X86ASM AR LD STRIP CP WINDRES NVCC +SILENT = DEPCC DEPHOSTCC DEPAS DEPX86ASM RANLIB RM + +MSG = $@ +M = @$(call ECHO,$(TAG),$@); +$(foreach VAR,$(BRIEF), \ + $(eval override $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR)))) +$(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR)))) +$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL)) +endif + +ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil postproc swscale swresample + +# NASM requires -I path terminated with / +IFLAGS := -I. -I$(SRC_LINK)/ +CPPFLAGS := $(IFLAGS) $(CPPFLAGS) +CFLAGS += $(ECFLAGS) +CCFLAGS = $(CPPFLAGS) $(CFLAGS) +OBJCFLAGS += $(EOBJCFLAGS) +OBJCCFLAGS = $(CPPFLAGS) $(CFLAGS) $(OBJCFLAGS) +ASFLAGS := $(CPPFLAGS) $(ASFLAGS) +CXXFLAGS := $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS) +X86ASMFLAGS += $(IFLAGS:%=%/) -I$( $(@:.asm=.d) + $(X86ASM) $(X86ASMFLAGS) -e $< | sed '/^%/d;/^$$/d;' > $@ + +%.o: %.asm + $(COMPILE_X86ASM) + -$(if $(ASMSTRIPFLAGS), $(STRIP) $(ASMSTRIPFLAGS) $@) + +%.o: %.rc + $(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $< + +%.i: %.c + $(CC) $(CCFLAGS) $(CC_E) $< + +%.h.c: + $(Q)echo '#include "$*.h"' >$@ + +%.ptx: %.cu $(SRC_PATH)/compat/cuda/cuda_runtime.h + $(COMPILE_NVCC) + +%.ptx.c: %.ptx + $(Q)sh $(SRC_PATH)/compat/cuda/ptx2c.sh $@ $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) + +%.c %.h %.pc %.ver %.version: TAG = GEN + +# Dummy rule to stop make trying to rebuild removed or renamed headers +%.h: + @: + +# Disable suffix rules. Most of the builtin rules are suffix rules, +# so this saves some time on slow systems. +.SUFFIXES: + +# Do not delete intermediate files from chains of implicit rules +$(OBJS): +endif + +include $(SRC_PATH)/ffbuild/arch.mak + +OBJS += $(OBJS-yes) +SLIBOBJS += $(SLIBOBJS-yes) +FFLIBS := $($(NAME)_FFLIBS) $(FFLIBS-yes) $(FFLIBS) +TESTPROGS += $(TESTPROGS-yes) + +LDLIBS = $(FFLIBS:%=%$(BUILDSUF)) +FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(foreach lib,EXTRALIBS-$(NAME) $(FFLIBS:%=EXTRALIBS-%),$($(lib))) $(EXTRALIBS) + +OBJS := $(sort $(OBJS:%=$(SUBDIR)%)) +SLIBOBJS := $(sort $(SLIBOBJS:%=$(SUBDIR)%)) +TESTOBJS := $(TESTOBJS:%=$(SUBDIR)tests/%) $(TESTPROGS:%=$(SUBDIR)tests/%.o) +TESTPROGS := $(TESTPROGS:%=$(SUBDIR)tests/%$(EXESUF)) +HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o) +HOSTPROGS := $(HOSTPROGS:%=$(SUBDIR)%$(HOSTEXESUF)) +TOOLS += $(TOOLS-yes) +TOOLOBJS := $(TOOLS:%=tools/%.o) +TOOLS := $(TOOLS:%=tools/%$(EXESUF)) +HEADERS += $(HEADERS-yes) + +PATH_LIBNAME = $(foreach NAME,$(1),lib$(NAME)/$($(2)LIBNAME)) +DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib),$(CONFIG_SHARED:yes=S))) +STATIC_DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib))) + +SRC_DIR := $(SRC_PATH)/lib$(NAME) +ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h)) +SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-) +SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%) +HOBJS = $(filter-out $(SKIPHEADERS:.h=.h.o),$(ALLHEADERS:.h=.h.o)) +PTXOBJS = $(filter %.ptx.o,$(OBJS)) +$(HOBJS): CCFLAGS += $(CFLAGS_HEADERS) +checkheaders: $(HOBJS) +.SECONDARY: $(HOBJS:.o=.c) $(PTXOBJS:.o=.c) $(PTXOBJS:.o=) + +alltools: $(TOOLS) + +$(HOSTOBJS): %.o: %.c + $(COMPILE_HOSTC) + +$(HOSTPROGS): %$(HOSTEXESUF): %.o + $(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTEXTRALIBS) + +$(OBJS): | $(sort $(dir $(OBJS))) +$(HOBJS): | $(sort $(dir $(HOBJS))) +$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS))) +$(SLIBOBJS): | $(sort $(dir $(SLIBOBJS))) +$(TESTOBJS): | $(sort $(dir $(TESTOBJS))) +$(TOOLOBJS): | tools + +OUTDIRS := $(OUTDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(TESTOBJS)) + +CLEANSUFFIXES = *.d *.gcda *.gcno *.h.c *.ho *.map *.o *.pc *.ptx *.ptx.c *.ver *.version *$(DEFAULT_X86ASMD).asm *~ +LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a + +define RULES +clean:: + $(RM) $(HOSTPROGS) $(TESTPROGS) $(TOOLS) +endef + +$(eval $(RULES)) + +-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SLIBOBJS:.o=.d)) $(OBJS:.o=$(DEFAULT_X86ASMD).d) diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/library.mak b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/library.mak new file mode 100644 index 000000000..612bacb98 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/library.mak @@ -0,0 +1,107 @@ +include $(SRC_PATH)/ffbuild/common.mak + +ifeq (,$(filter %clean config,$(MAKECMDGOALS))) +-include $(SUBDIR)lib$(NAME).version +endif + +LIBVERSION := $(lib$(NAME)_VERSION) +LIBMAJOR := $(lib$(NAME)_VERSION_MAJOR) +LIBMINOR := $(lib$(NAME)_VERSION_MINOR) +INCINSTDIR := $(INCDIR)/lib$(NAME) + +INSTHEADERS := $(INSTHEADERS) $(HEADERS:%=$(SUBDIR)%) + +all-$(CONFIG_STATIC): $(SUBDIR)$(LIBNAME) $(SUBDIR)lib$(FULLNAME).pc +all-$(CONFIG_SHARED): $(SUBDIR)$(SLIBNAME) $(SUBDIR)lib$(FULLNAME).pc + +LIBOBJS := $(OBJS) $(SUBDIR)%.h.o $(TESTOBJS) +$(LIBOBJS) $(LIBOBJS:.o=.s) $(LIBOBJS:.o=.i): CPPFLAGS += -DHAVE_AV_CONFIG_H + +$(SUBDIR)$(LIBNAME): $(OBJS) + $(RM) $@ + $(AR) $(ARFLAGS) $(AR_O) $^ + $(RANLIB) $@ + +install-headers: install-lib$(NAME)-headers install-lib$(NAME)-pkgconfig + +install-libs-$(CONFIG_STATIC): install-lib$(NAME)-static +install-libs-$(CONFIG_SHARED): install-lib$(NAME)-shared + +define RULES +$(TOOLS): THISLIB = $(FULLNAME:%=$(LD_LIB)) +$(TESTPROGS): THISLIB = $(SUBDIR)$(LIBNAME) + +$(LIBOBJS): CPPFLAGS += -DBUILDING_$(NAME) + +$(TESTPROGS) $(TOOLS): %$(EXESUF): %.o + $$(LD) $(LDFLAGS) $(LDEXEFLAGS) $$(LD_O) $$(filter %.o,$$^) $$(THISLIB) $(FFEXTRALIBS) $$(EXTRALIBS-$$(*F)) $$(ELIBS) + +$(SUBDIR)lib$(NAME).version: $(SUBDIR)version.h | $(SUBDIR) + $$(M) $$(SRC_PATH)/ffbuild/libversion.sh $(NAME) $$< > $$@ + +$(SUBDIR)lib$(FULLNAME).pc: $(SUBDIR)version.h ffbuild/config.sh | $(SUBDIR) + $$(M) $$(SRC_PATH)/ffbuild/pkgconfig_generate.sh $(NAME) "$(DESC)" + +$(SUBDIR)lib$(NAME).ver: $(SUBDIR)lib$(NAME).v $(OBJS) + $$(M)sed 's/MAJOR/$(lib$(NAME)_VERSION_MAJOR)/' $$< | $(VERSION_SCRIPT_POSTPROCESS_CMD) > $$@ + +$(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR) + $(Q)cd ./$(SUBDIR) && $(LN_S) $(SLIBNAME_WITH_MAJOR) $(SLIBNAME) + +$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SLIBOBJS) $(SUBDIR)lib$(NAME).ver + $(SLIB_CREATE_DEF_CMD) + $$(LD) $(SHFLAGS) $(LDFLAGS) $(LDSOFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS) + $(SLIB_EXTRA_CMD) + +ifdef SUBDIR +$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(DEP_LIBS) +endif + +clean:: + $(RM) $(addprefix $(SUBDIR),$(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \ + $(CLEANSUFFIXES:%=$(SUBDIR)$(ARCH)/%) $(CLEANSUFFIXES:%=$(SUBDIR)tests/%) + +install-lib$(NAME)-shared: $(SUBDIR)$(SLIBNAME) + $(Q)mkdir -p "$(SHLIBDIR)" + $$(INSTALL) -m 755 $$< "$(SHLIBDIR)/$(SLIB_INSTALL_NAME)" + $$(STRIP) "$(SHLIBDIR)/$(SLIB_INSTALL_NAME)" + $(Q)$(foreach F,$(SLIB_INSTALL_LINKS),(cd "$(SHLIBDIR)" && $(LN_S) $(SLIB_INSTALL_NAME) $(F));) + $(if $(SLIB_INSTALL_EXTRA_SHLIB),$$(INSTALL) -m 644 $(SLIB_INSTALL_EXTRA_SHLIB:%=$(SUBDIR)%) "$(SHLIBDIR)") + $(if $(SLIB_INSTALL_EXTRA_LIB),$(Q)mkdir -p "$(LIBDIR)") + $(if $(SLIB_INSTALL_EXTRA_LIB),$$(INSTALL) -m 644 $(SLIB_INSTALL_EXTRA_LIB:%=$(SUBDIR)%) "$(LIBDIR)") + +install-lib$(NAME)-static: $(SUBDIR)$(LIBNAME) + $(Q)mkdir -p "$(LIBDIR)" + $$(INSTALL) -m 644 $$< "$(LIBDIR)" + $(LIB_INSTALL_EXTRA_CMD) + +install-lib$(NAME)-headers: $(addprefix $(SUBDIR),$(HEADERS) $(BUILT_HEADERS)) + $(Q)mkdir -p "$(INCINSTDIR)" + $$(INSTALL) -m 644 $$^ "$(INCINSTDIR)" + +install-lib$(NAME)-pkgconfig: $(SUBDIR)lib$(FULLNAME).pc + $(Q)mkdir -p "$(PKGCONFIGDIR)" + $$(INSTALL) -m 644 $$^ "$(PKGCONFIGDIR)" + +uninstall-libs:: + -$(RM) "$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR)" \ + "$(SHLIBDIR)/$(SLIBNAME)" \ + "$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)" + -$(RM) $(SLIB_INSTALL_EXTRA_SHLIB:%="$(SHLIBDIR)/%") + -$(RM) $(SLIB_INSTALL_EXTRA_LIB:%="$(LIBDIR)/%") + -$(RM) "$(LIBDIR)/$(LIBNAME)" + +uninstall-headers:: + $(RM) $(addprefix "$(INCINSTDIR)/",$(HEADERS) $(BUILT_HEADERS)) + -rmdir "$(INCINSTDIR)" + +uninstall-pkgconfig:: + $(RM) "$(PKGCONFIGDIR)/lib$(FULLNAME).pc" +endef + +$(eval $(RULES)) + +$(TOOLS): $(DEP_LIBS) $(SUBDIR)$($(CONFIG_SHARED:yes=S)LIBNAME) +$(TESTPROGS): $(DEP_LIBS) $(SUBDIR)$(LIBNAME) + +testprogs: $(TESTPROGS) diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/libversion.sh b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/libversion.sh new file mode 100755 index 000000000..990ce9f64 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/libversion.sh @@ -0,0 +1,13 @@ +toupper(){ + echo "$@" | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ +} + +name=lib$1 +ucname=$(toupper ${name}) +file=$2 + +eval $(awk "/#define ${ucname}_VERSION_M/ { print \$2 \"=\" \$3 }" "$file") +eval ${ucname}_VERSION=\$${ucname}_VERSION_MAJOR.\$${ucname}_VERSION_MINOR.\$${ucname}_VERSION_MICRO +eval echo "${name}_VERSION=\$${ucname}_VERSION" +eval echo "${name}_VERSION_MAJOR=\$${ucname}_VERSION_MAJOR" +eval echo "${name}_VERSION_MINOR=\$${ucname}_VERSION_MINOR" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/pkgconfig_generate.sh b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/pkgconfig_generate.sh new file mode 100755 index 000000000..e5de6716d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/pkgconfig_generate.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +. ffbuild/config.sh + +if test "$shared" = "yes"; then + shared=true +else + shared=false +fi + +shortname=$1 +name=lib${shortname} +fullname=${name}${build_suffix} +comment=$2 +libs=$(eval echo \$extralibs_${shortname}) +deps=$(eval echo \$${shortname}_deps) + +for dep in $deps; do + depname=lib${dep} + fulldepname=${depname}${build_suffix} + . ${depname}/${depname}.version + depversion=$(eval echo \$${depname}_VERSION) + requires="$requires ${fulldepname} >= ${depversion}, " +done +requires=${requires%, } + +version=$(grep ${name}_VERSION= $name/${name}.version | cut -d= -f2) + +cat < $name/$fullname.pc +prefix=$prefix +exec_prefix=\${prefix} +libdir=$libdir +includedir=$incdir + +Name: $fullname +Description: $comment +Version: $version +Requires: $($shared || echo $requires) +Requires.private: $($shared && echo $requires) +Conflicts: +Libs: -L\${libdir} $rpath -l${fullname#lib} $($shared || echo $libs) +Libs.private: $($shared && echo $libs) +Cflags: -I\${includedir} +EOF + +mkdir -p doc/examples/pc-uninstalled +includedir=${source_path} +[ "$includedir" = . ] && includedir="\${pcfiledir}/../../.." + cat < doc/examples/pc-uninstalled/${name}-uninstalled.pc +prefix= +exec_prefix= +libdir=\${pcfiledir}/../../../$name +includedir=${source_path} + +Name: $fullname +Description: $comment +Version: $version +Requires: $requires +Conflicts: +Libs: -L\${libdir} -Wl,-rpath,\${libdir} -l${fullname#lib} $($shared || echo $libs) +Cflags: -I\${includedir} +EOF diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/version.sh b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/version.sh new file mode 100755 index 000000000..edc4dd33c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/ffbuild/version.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# Usage: version.sh + +# check for git short hash +if ! test "$revision"; then + if (cd "$1" && grep git RELEASE 2> /dev/null >/dev/null) ; then + revision=$(cd "$1" && git describe --tags --match N 2> /dev/null) + else + revision=$(cd "$1" && git describe --tags --always 2> /dev/null) + fi +fi + +# Shallow Git clones (--depth) do not have the N tag: +# use 'git-YYYY-MM-DD-hhhhhhh'. +test "$revision" || revision=$(cd "$1" && + git log -1 --pretty=format:"git-%cd-%h" --date=short 2> /dev/null) + +# Snapshots from gitweb are in a directory called ffmpeg-hhhhhhh or +# ffmpeg-HEAD-hhhhhhh. +if [ -z "$revision" ]; then + srcdir=$(cd "$1" && pwd) + case "$srcdir" in + */ffmpeg-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]) + git_hash="${srcdir##*-}";; + */ffmpeg-HEAD-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]) + git_hash="${srcdir##*-}";; + esac +fi + +# no revision number found +test "$revision" || revision=$(cd "$1" && cat RELEASE 2> /dev/null) + +# Append the Git hash if we have one +test "$revision" && test "$git_hash" && revision="$revision-$git_hash" + +# releases extract the version number from the VERSION file +version=$(cd "$1" && cat VERSION 2> /dev/null) +test "$version" || version=$revision + +test -n "$3" && version=$version-$3 + +if [ -z "$2" ]; then + echo "$version" + exit +fi + +NEW_REVISION="#define FFMPEG_VERSION \"$version\"" +OLD_REVISION=$(cat "$2" 2> /dev/null | head -4 | tail -1) + +# String used for preprocessor guard +GUARD=$(echo "$2" | sed 's/\//_/' | sed 's/\./_/' | tr '[:lower:]' '[:upper:]' | sed 's/LIB//') + +# Update version header only on revision changes to avoid spurious rebuilds +if test "$NEW_REVISION" != "$OLD_REVISION"; then + cat << EOF > "$2" +/* Automatically generated by version.sh, do not manually edit! */ +#ifndef $GUARD +#define $GUARD +$NEW_REVISION +#endif /* $GUARD */ +EOF +fi diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/Makefile new file mode 100644 index 000000000..3cd73fbcc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/Makefile @@ -0,0 +1,1225 @@ +NAME = avcodec +DESC = FFmpeg codec library + +HEADERS = ac3_parser.h \ + adts_parser.h \ + avcodec.h \ + avdct.h \ + avfft.h \ + d3d11va.h \ + dirac.h \ + dv_profile.h \ + dxva2.h \ + jni.h \ + mediacodec.h \ + qsv.h \ + vaapi.h \ + vdpau.h \ + version.h \ + videotoolbox.h \ + vorbis_parser.h \ + xvmc.h \ + +OBJS = ac3_parser.o \ + adts_parser.o \ + allcodecs.o \ + avdct.o \ + avpacket.o \ + avpicture.o \ + bitstream.o \ + bitstream_filter.o \ + bitstream_filters.o \ + bsf.o \ + codec_desc.o \ + d3d11va.o \ + decode.o \ + dirac.o \ + dv_profile.o \ + encode.o \ + imgconvert.o \ + jni.o \ + mathtables.o \ + mediacodec.o \ + mpeg12framerate.o \ + options.o \ + mjpegenc_huffman.o \ + parser.o \ + parsers.o \ + profiles.o \ + qsv_api.o \ + raw.o \ + utils.o \ + vorbis_parser.o \ + xiph.o \ + +# subsystems +OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o +OBJS-$(CONFIG_AC3DSP) += ac3dsp.o ac3.o ac3tab.o +OBJS-$(CONFIG_ADTS_HEADER) += adts_header.o mpeg4audio.o +OBJS-$(CONFIG_AMF) += amfenc.o +OBJS-$(CONFIG_AUDIO_FRAME_QUEUE) += audio_frame_queue.o +OBJS-$(CONFIG_AUDIODSP) += audiodsp.o +OBJS-$(CONFIG_BLOCKDSP) += blockdsp.o +OBJS-$(CONFIG_BSWAPDSP) += bswapdsp.o +OBJS-$(CONFIG_CABAC) += cabac.o +OBJS-$(CONFIG_CBS) += cbs.o +OBJS-$(CONFIG_CBS_AV1) += cbs_av1.o +OBJS-$(CONFIG_CBS_H264) += cbs_h2645.o h2645_parse.o +OBJS-$(CONFIG_CBS_H265) += cbs_h2645.o h2645_parse.o +OBJS-$(CONFIG_CBS_JPEG) += cbs_jpeg.o +OBJS-$(CONFIG_CBS_MPEG2) += cbs_mpeg2.o +OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o +OBJS-$(CONFIG_CRYSTALHD) += crystalhd.o +OBJS-$(CONFIG_DCT) += dct.o dct32_fixed.o dct32_float.o +OBJS-$(CONFIG_ERROR_RESILIENCE) += error_resilience.o +OBJS-$(CONFIG_EXIF) += exif.o tiff_common.o +OBJS-$(CONFIG_FAANDCT) += faandct.o +OBJS-$(CONFIG_FAANIDCT) += faanidct.o +OBJS-$(CONFIG_FDCTDSP) += fdctdsp.o jfdctfst.o jfdctint.o +FFT-OBJS-$(CONFIG_HARDCODED_TABLES) += cos_tables.o cos_fixed_tables.o +OBJS-$(CONFIG_FFT) += avfft.o fft_fixed.o fft_float.o \ + fft_fixed_32.o fft_init_table.o \ + $(FFT-OBJS-yes) +OBJS-$(CONFIG_FLACDSP) += flacdsp.o +OBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o +OBJS-$(CONFIG_GOLOMB) += golomb.o +OBJS-$(CONFIG_H263DSP) += h263dsp.o +OBJS-$(CONFIG_H264CHROMA) += h264chroma.o +OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o +OBJS-$(CONFIG_H264PARSE) += h264_parse.o h2645_parse.o h264_ps.o +OBJS-$(CONFIG_H264PRED) += h264pred.o +OBJS-$(CONFIG_H264QPEL) += h264qpel.o +OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o h2645_parse.o hevc_ps.o hevc_sei.o hevc_data.o +OBJS-$(CONFIG_HPELDSP) += hpeldsp.o +OBJS-$(CONFIG_HUFFMAN) += huffman.o +OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o +OBJS-$(CONFIG_HUFFYUVENCDSP) += huffyuvencdsp.o +OBJS-$(CONFIG_IDCTDSP) += idctdsp.o simple_idct.o jrevdct.o +OBJS-$(CONFIG_IIRFILTER) += iirfilter.o +OBJS-$(CONFIG_MDCT15) += mdct15.o +OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o msmpeg4data.o +OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o +OBJS-$(CONFIG_JNI) += ffjni.o jni.o +OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o +OBJS-$(CONFIG_LLAUDDSP) += lossless_audiodsp.o +OBJS-$(CONFIG_LLVIDDSP) += lossless_videodsp.o +OBJS-$(CONFIG_LLVIDENCDSP) += lossless_videoencdsp.o +OBJS-$(CONFIG_LPC) += lpc.o +OBJS-$(CONFIG_LSP) += lsp.o +OBJS-$(CONFIG_LZF) += lzf.o +OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o mdct_fixed_32.o +OBJS-$(CONFIG_ME_CMP) += me_cmp.o +OBJS-$(CONFIG_MEDIACODEC) += mediacodecdec_common.o mediacodec_surface.o mediacodec_wrapper.o mediacodec_sw_buffer.o +OBJS-$(CONFIG_MPEG_ER) += mpeg_er.o +OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o +OBJS-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.o \ + mpegaudiodsp_data.o \ + mpegaudiodsp_fixed.o \ + mpegaudiodsp_float.o +OBJS-$(CONFIG_MPEGAUDIOHEADER) += mpegaudiodecheader.o mpegaudiodata.o +OBJS-$(CONFIG_MPEGVIDEO) += mpegvideo.o mpegvideodsp.o rl.o \ + mpegvideo_motion.o mpegutils.o \ + mpegvideodata.o mpegpicture.o +OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \ + motion_est.o ratecontrol.o \ + mpegvideoencdsp.o +OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o +OBJS-$(CONFIG_NVENC) += nvenc.o +OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o +OBJS-$(CONFIG_QPELDSP) += qpeldsp.o +OBJS-$(CONFIG_QSV) += qsv.o +OBJS-$(CONFIG_QSVDEC) += qsvdec.o +OBJS-$(CONFIG_QSVENC) += qsvenc.o +OBJS-$(CONFIG_RANGECODER) += rangecoder.o +OBJS-$(CONFIG_RDFT) += rdft.o +OBJS-$(CONFIG_RV34DSP) += rv34dsp.o +OBJS-$(CONFIG_SHARED) += log2_tab.o reverse.o +OBJS-$(CONFIG_SINEWIN) += sinewin.o sinewin_fixed.o +OBJS-$(CONFIG_SNAPPY) += snappy.o +OBJS-$(CONFIG_STARTCODE) += startcode.o +OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o +OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o +OBJS-$(CONFIG_TPELDSP) += tpeldsp.o +OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o +OBJS-$(CONFIG_VC1DSP) += vc1dsp.o +OBJS-$(CONFIG_VIDEODSP) += videodsp.o +OBJS-$(CONFIG_VP3DSP) += vp3dsp.o +OBJS-$(CONFIG_VP56DSP) += vp56dsp.o +OBJS-$(CONFIG_VP8DSP) += vp8dsp.o +OBJS-$(CONFIG_V4L2_M2M) += v4l2_m2m.o v4l2_context.o v4l2_buffers.o v4l2_fmt.o +OBJS-$(CONFIG_WMA_FREQS) += wma_freqs.o +OBJS-$(CONFIG_WMV2DSP) += wmv2dsp.o + +# decoders/encoders +OBJS-$(CONFIG_ZERO12V_DECODER) += 012v.o +OBJS-$(CONFIG_A64MULTI_ENCODER) += a64multienc.o elbg.o +OBJS-$(CONFIG_A64MULTI5_ENCODER) += a64multienc.o elbg.o +OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aactab.o aacsbr.o aacps_float.o \ + mpeg4audio.o kbdwin.o \ + sbrdsp.o aacpsdsp_float.o cbrt_data.o +OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aactab.o aacsbr_fixed.o aacps_fixed.o \ + mpeg4audio.o kbdwin.o \ + sbrdsp_fixed.o aacpsdsp_fixed.o cbrt_data_fixed.o +OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \ + aacpsy.o aactab.o \ + aacenc_is.o \ + aacenc_tns.o \ + aacenc_ltp.o \ + aacenc_pred.o \ + psymodel.o mpeg4audio.o kbdwin.o cbrt_data.o +OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o +OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o kbdwin.o ac3tab.o +OBJS-$(CONFIG_AC3_FIXED_DECODER) += ac3dec_fixed.o ac3dec_data.o ac3.o kbdwin.o ac3tab.o +OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \ + ac3.o kbdwin.o +OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o +OBJS-$(CONFIG_AGM_DECODER) += agm.o +OBJS-$(CONFIG_AIC_DECODER) += aic.o +OBJS-$(CONFIG_ALAC_DECODER) += alac.o alac_data.o alacdsp.o +OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o alac_data.o +OBJS-$(CONFIG_ALIAS_PIX_DECODER) += aliaspixdec.o +OBJS-$(CONFIG_ALIAS_PIX_ENCODER) += aliaspixenc.o +OBJS-$(CONFIG_ALS_DECODER) += alsdec.o bgmc.o mlz.o mpeg4audio.o +OBJS-$(CONFIG_AMRNB_DECODER) += amrnbdec.o celp_filters.o \ + celp_math.o acelp_filters.o \ + acelp_vectors.o \ + acelp_pitch_delay.o +OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \ + celp_math.o acelp_filters.o \ + acelp_vectors.o \ + acelp_pitch_delay.o +OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o \ + mjpegenc_huffman.o +OBJS-$(CONFIG_ANM_DECODER) += anm.o +OBJS-$(CONFIG_ANSI_DECODER) += ansi.o cga_data.o +OBJS-$(CONFIG_APE_DECODER) += apedec.o +OBJS-$(CONFIG_APTX_DECODER) += aptx.o +OBJS-$(CONFIG_APTX_ENCODER) += aptx.o +OBJS-$(CONFIG_APTX_HD_DECODER) += aptx.o +OBJS-$(CONFIG_APTX_HD_ENCODER) += aptx.o +OBJS-$(CONFIG_APNG_DECODER) += png.o pngdec.o pngdsp.o +OBJS-$(CONFIG_APNG_ENCODER) += png.o pngenc.o +OBJS-$(CONFIG_ARBC_DECODER) += arbc.o +OBJS-$(CONFIG_SSA_DECODER) += assdec.o ass.o +OBJS-$(CONFIG_SSA_ENCODER) += assenc.o ass.o +OBJS-$(CONFIG_ASS_DECODER) += assdec.o ass.o +OBJS-$(CONFIG_ASS_ENCODER) += assenc.o ass.o +OBJS-$(CONFIG_ASV1_DECODER) += asvdec.o asv.o mpeg12data.o +OBJS-$(CONFIG_ASV1_ENCODER) += asvenc.o asv.o mpeg12data.o +OBJS-$(CONFIG_ASV2_DECODER) += asvdec.o asv.o mpeg12data.o +OBJS-$(CONFIG_ASV2_ENCODER) += asvenc.o asv.o mpeg12data.o +OBJS-$(CONFIG_ATRAC1_DECODER) += atrac1.o atrac.o +OBJS-$(CONFIG_ATRAC3_DECODER) += atrac3.o atrac.o +OBJS-$(CONFIG_ATRAC3AL_DECODER) += atrac3.o atrac.o +OBJS-$(CONFIG_ATRAC3P_DECODER) += atrac3plusdec.o atrac3plus.o \ + atrac3plusdsp.o atrac.o +OBJS-$(CONFIG_ATRAC3PAL_DECODER) += atrac3plusdec.o atrac3plus.o \ + atrac3plusdsp.o atrac.o +OBJS-$(CONFIG_ATRAC9_DECODER) += atrac9dec.o +OBJS-$(CONFIG_AURA_DECODER) += cyuv.o +OBJS-$(CONFIG_AURA2_DECODER) += aura.o +OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o mjpegdec.o +OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o +OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o +OBJS-$(CONFIG_AVS_DECODER) += avs.o +OBJS-$(CONFIG_AVUI_DECODER) += avuidec.o +OBJS-$(CONFIG_AVUI_ENCODER) += avuienc.o +OBJS-$(CONFIG_AYUV_DECODER) += v408dec.o +OBJS-$(CONFIG_AYUV_ENCODER) += v408enc.o +OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o +OBJS-$(CONFIG_BFI_DECODER) += bfi.o +OBJS-$(CONFIG_BINK_DECODER) += bink.o binkdsp.o +OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o +OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o +OBJS-$(CONFIG_BINTEXT_DECODER) += bintext.o cga_data.o +OBJS-$(CONFIG_BITPACKED_DECODER) += bitpacked.o +OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o +OBJS-$(CONFIG_BMP_ENCODER) += bmpenc.o +OBJS-$(CONFIG_BMV_AUDIO_DECODER) += bmvaudio.o +OBJS-$(CONFIG_BMV_VIDEO_DECODER) += bmvvideo.o +OBJS-$(CONFIG_BRENDER_PIX_DECODER) += brenderpix.o +OBJS-$(CONFIG_C93_DECODER) += c93.o +OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \ + cavsdata.o +OBJS-$(CONFIG_CCAPTION_DECODER) += ccaption_dec.o +OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o +OBJS-$(CONFIG_CDXL_DECODER) += cdxl.o +OBJS-$(CONFIG_CFHD_DECODER) += cfhd.o cfhddata.o +OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o +OBJS-$(CONFIG_CINEPAK_ENCODER) += cinepakenc.o elbg.o +OBJS-$(CONFIG_CLEARVIDEO_DECODER) += clearvideo.o +OBJS-$(CONFIG_CLJR_DECODER) += cljrdec.o +OBJS-$(CONFIG_CLJR_ENCODER) += cljrenc.o +OBJS-$(CONFIG_CLLC_DECODER) += cllc.o canopus.o +OBJS-$(CONFIG_COMFORTNOISE_DECODER) += cngdec.o celp_filters.o +OBJS-$(CONFIG_COMFORTNOISE_ENCODER) += cngenc.o +OBJS-$(CONFIG_COOK_DECODER) += cook.o +OBJS-$(CONFIG_CPIA_DECODER) += cpia.o +OBJS-$(CONFIG_CSCD_DECODER) += cscd.o +OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o +OBJS-$(CONFIG_DCA_DECODER) += dcadec.o dca.o dcadata.o dcahuff.o \ + dca_core.o dca_exss.o dca_xll.o dca_lbr.o \ + dcadsp.o dcadct.o synth_filter.o +OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dca.o dcadata.o dcahuff.o \ + dcaadpcm.o +OBJS-$(CONFIG_DDS_DECODER) += dds.o +OBJS-$(CONFIG_DIRAC_DECODER) += diracdec.o dirac.o diracdsp.o diractab.o \ + dirac_arith.o dirac_dwt.o dirac_vlc.o +OBJS-$(CONFIG_DFA_DECODER) += dfa.o +OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o +OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o +OBJS-$(CONFIG_DOLBY_E_DECODER) += dolby_e.o kbdwin.o +OBJS-$(CONFIG_DPX_DECODER) += dpx.o +OBJS-$(CONFIG_DPX_ENCODER) += dpxenc.o +OBJS-$(CONFIG_DSD_LSBF_DECODER) += dsddec.o dsd.o +OBJS-$(CONFIG_DSD_MSBF_DECODER) += dsddec.o dsd.o +OBJS-$(CONFIG_DSD_LSBF_PLANAR_DECODER) += dsddec.o dsd.o +OBJS-$(CONFIG_DSD_MSBF_PLANAR_DECODER) += dsddec.o dsd.o +OBJS-$(CONFIG_DSICINAUDIO_DECODER) += dsicinaudio.o +OBJS-$(CONFIG_DSICINVIDEO_DECODER) += dsicinvideo.o +OBJS-$(CONFIG_DSS_SP_DECODER) += dss_sp.o +OBJS-$(CONFIG_DST_DECODER) += dstdec.o dsd.o +OBJS-$(CONFIG_DVBSUB_DECODER) += dvbsubdec.o +OBJS-$(CONFIG_DVBSUB_ENCODER) += dvbsub.o +OBJS-$(CONFIG_DVDSUB_DECODER) += dvdsubdec.o +OBJS-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.o +OBJS-$(CONFIG_DVAUDIO_DECODER) += dvaudiodec.o +OBJS-$(CONFIG_DVVIDEO_DECODER) += dvdec.o dv.o dvdata.o +OBJS-$(CONFIG_DVVIDEO_ENCODER) += dvenc.o dv.o dvdata.o +OBJS-$(CONFIG_DXA_DECODER) += dxa.o +OBJS-$(CONFIG_DXTORY_DECODER) += dxtory.o +OBJS-$(CONFIG_DXV_DECODER) += dxv.o +OBJS-$(CONFIG_EAC3_DECODER) += eac3_data.o +OBJS-$(CONFIG_EAC3_ENCODER) += eac3enc.o eac3_data.o +OBJS-$(CONFIG_EACMV_DECODER) += eacmv.o +OBJS-$(CONFIG_EAMAD_DECODER) += eamad.o eaidct.o mpeg12.o \ + mpeg12data.o +OBJS-$(CONFIG_EATGQ_DECODER) += eatgq.o eaidct.o +OBJS-$(CONFIG_EATGV_DECODER) += eatgv.o +OBJS-$(CONFIG_EATQI_DECODER) += eatqi.o eaidct.o mpeg12.o mpeg12data.o mpegvideodata.o rl.o +OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o +OBJS-$(CONFIG_EIGHTSVX_EXP_DECODER) += 8svx.o +OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER) += 8svx.o +OBJS-$(CONFIG_ESCAPE124_DECODER) += escape124.o +OBJS-$(CONFIG_ESCAPE130_DECODER) += escape130.o +OBJS-$(CONFIG_EVRC_DECODER) += evrcdec.o acelp_vectors.o lsp.o +OBJS-$(CONFIG_EXR_DECODER) += exr.o exrdsp.o +OBJS-$(CONFIG_FFV1_DECODER) += ffv1dec.o ffv1.o +OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o +OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o +OBJS-$(CONFIG_FIC_DECODER) += fic.o +OBJS-$(CONFIG_FITS_DECODER) += fitsdec.o fits.o +OBJS-$(CONFIG_FITS_ENCODER) += fitsenc.o +OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o +OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o vorbis_data.o +OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o +OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o +OBJS-$(CONFIG_FLASHSV2_ENCODER) += flashsv2enc.o +OBJS-$(CONFIG_FLASHSV2_DECODER) += flashsv.o +OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o +OBJS-$(CONFIG_FMVC_DECODER) += fmvc.o +OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o +OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o +OBJS-$(CONFIG_FRWU_DECODER) += frwu.o +OBJS-$(CONFIG_G2M_DECODER) += g2meet.o elsdec.o +OBJS-$(CONFIG_G723_1_DECODER) += g723_1dec.o g723_1.o \ + acelp_vectors.o celp_filters.o celp_math.o +OBJS-$(CONFIG_G723_1_ENCODER) += g723_1enc.o g723_1.o \ + acelp_vectors.o celp_filters.o celp_math.o +OBJS-$(CONFIG_G729_DECODER) += g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o +OBJS-$(CONFIG_GDV_DECODER) += gdv.o +OBJS-$(CONFIG_GIF_DECODER) += gifdec.o lzw.o +OBJS-$(CONFIG_GIF_ENCODER) += gif.o lzwenc.o +OBJS-$(CONFIG_GREMLIN_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_GSM_DECODER) += gsmdec.o gsmdec_data.o msgsmdec.o +OBJS-$(CONFIG_GSM_MS_DECODER) += gsmdec.o gsmdec_data.o msgsmdec.o +OBJS-$(CONFIG_H261_DECODER) += h261dec.o h261data.o h261.o +OBJS-$(CONFIG_H261_ENCODER) += h261enc.o h261data.o h261.o +OBJS-$(CONFIG_H263_DECODER) += h263dec.o h263.o ituh263dec.o \ + mpeg4video.o mpeg4videodec.o flvdec.o\ + intelh263dec.o h263data.o +OBJS-$(CONFIG_H263_ENCODER) += mpeg4videoenc.o mpeg4video.o \ + h263.o ituh263enc.o flvenc.o h263data.o +OBJS-$(CONFIG_H263_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_H263_V4L2M2M_ENCODER) += v4l2_m2m_enc.o +OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \ + h264_direct.o h264_loopfilter.o \ + h264_mb.o h264_picture.o \ + h264_refs.o h264_sei.o \ + h264_slice.o h264data.o +OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o +OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o +OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o +OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o +OBJS-$(CONFIG_NVENC_ENCODER) += nvenc_h264.o +OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc_h264.o +OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o +OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o +OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o +OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o +OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o +OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o +OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o +OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o +OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o +OBJS-$(CONFIG_HCOM_DECODER) += hcom.o +OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \ + hevc_cabac.o hevc_refs.o hevcpred.o \ + hevcdsp.o hevc_filter.o hevc_data.o +OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o +OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o +OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o +OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc_hevc.o +OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o +OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \ + hevc_data.o +OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o +OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o +OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o +OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o +OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \ + canopus.o +OBJS-$(CONFIG_HQX_DECODER) += hqx.o hqxvlc.o hqxdsp.o canopus.o +OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o huffyuvdec.o +OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o +OBJS-$(CONFIG_HYMT_DECODER) += huffyuv.o huffyuvdec.o +OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o +OBJS-$(CONFIG_IDF_DECODER) += bintext.o cga_data.o +OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o +OBJS-$(CONFIG_ILBC_DECODER) += ilbcdec.o +OBJS-$(CONFIG_IMC_DECODER) += imc.o +OBJS-$(CONFIG_IMM4_DECODER) += imm4.o +OBJS-$(CONFIG_INDEO2_DECODER) += indeo2.o +OBJS-$(CONFIG_INDEO3_DECODER) += indeo3.o +OBJS-$(CONFIG_INDEO4_DECODER) += indeo4.o ivi.o +OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi.o +OBJS-$(CONFIG_INTERPLAY_ACM_DECODER) += interplayacm.o +OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o +OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o +OBJS-$(CONFIG_JPEG2000_ENCODER) += j2kenc.o mqcenc.o mqc.o jpeg2000.o \ + jpeg2000dwt.o +OBJS-$(CONFIG_JPEG2000_DECODER) += jpeg2000dec.o jpeg2000.o jpeg2000dsp.o \ + jpeg2000dwt.o mqcdec.o mqc.o +OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o +OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o +OBJS-$(CONFIG_JV_DECODER) += jvdec.o +OBJS-$(CONFIG_KGV1_DECODER) += kgv1dec.o +OBJS-$(CONFIG_KMVC_DECODER) += kmvc.o +OBJS-$(CONFIG_LAGARITH_DECODER) += lagarith.o lagarithrac.o +OBJS-$(CONFIG_LJPEG_ENCODER) += ljpegenc.o mjpegenc_common.o +OBJS-$(CONFIG_LOCO_DECODER) += loco.o +OBJS-$(CONFIG_LSCR_DECODER) += png.o pngdec.o pngdsp.o +OBJS-$(CONFIG_M101_DECODER) += m101.o +OBJS-$(CONFIG_MACE3_DECODER) += mace.o +OBJS-$(CONFIG_MACE6_DECODER) += mace.o +OBJS-$(CONFIG_MAGICYUV_DECODER) += magicyuv.o +OBJS-$(CONFIG_MAGICYUV_ENCODER) += magicyuvenc.o +OBJS-$(CONFIG_MDEC_DECODER) += mdec.o mpeg12.o mpeg12data.o +OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o metasound_data.o \ + twinvq.o +OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o +OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o +OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o +OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpegenc_common.o \ + mjpegenc_huffman.o +OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o +OBJS-$(CONFIG_MJPEG_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_MJPEG_QSV_ENCODER) += qsvenc_jpeg.o +OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o +OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o +OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o mlp.o +OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o +OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o +OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o +OBJS-$(CONFIG_MOVTEXT_ENCODER) += movtextenc.o ass_split.o +OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec_fixed.o +OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o +OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec_fixed.o +OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc_float.o mpegaudio.o \ + mpegaudiodata.o mpegaudiodsp_data.o +OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \ + mpegaudiodata.o mpegaudiodsp_data.o +OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o +OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o +OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o +OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o +OBJS-$(CONFIG_MP3FLOAT_DECODER) += mpegaudiodec_float.o +OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec_fixed.o mpeg4audio.o +OBJS-$(CONFIG_MP3ON4FLOAT_DECODER) += mpegaudiodec_float.o mpeg4audio.o +OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o +OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o +OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o +OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o +OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o +OBJS-$(CONFIG_MPEG1_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_MPEG1_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_MPEG2_MMAL_DECODER) += mmaldec.o +OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o +OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o +OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o +OBJS-$(CONFIG_MPEG2_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_MPEG2_MEDIACODEC_DECODER) += mediacodecdec.o +OBJS-$(CONFIG_MPEG2_VAAPI_ENCODER) += vaapi_encode_mpeg2.o +OBJS-$(CONFIG_MPEG2_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_MPEG4_DECODER) += xvididct.o +OBJS-$(CONFIG_MPEG4_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o +OBJS-$(CONFIG_MPEG4_OMX_ENCODER) += omx.o +OBJS-$(CONFIG_MPEG4_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_MPEG4_V4L2M2M_ENCODER) += v4l2_m2m_enc.o +OBJS-$(CONFIG_MPL2_DECODER) += mpl2dec.o ass.o +OBJS-$(CONFIG_MSA1_DECODER) += mss3.o +OBJS-$(CONFIG_MSCC_DECODER) += mscc.o +OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4enc.o msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o +OBJS-$(CONFIG_MSS1_DECODER) += mss1.o mss12.o +OBJS-$(CONFIG_MSS2_DECODER) += mss2.o mss12.o mss2dsp.o wmv2data.o +OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o +OBJS-$(CONFIG_MSVIDEO1_ENCODER) += msvideo1enc.o elbg.o +OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o +OBJS-$(CONFIG_MTS2_DECODER) += mss4.o +OBJS-$(CONFIG_MVC1_DECODER) += mvcdec.o +OBJS-$(CONFIG_MVC2_DECODER) += mvcdec.o +OBJS-$(CONFIG_MWSC_DECODER) += mwsc.o +OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o +OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o +OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o +OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o +OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o +OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o opus_rc.o \ + opus_pvq.o opus_silk.o opustab.o vorbis_data.o \ + opusdsp.o +OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus.o opus_rc.o opustab.o opus_pvq.o \ + opusenc_psy.o +OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o +OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o +OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o +OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o +OBJS-$(CONFIG_PBM_DECODER) += pnmdec.o pnm.o +OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o +OBJS-$(CONFIG_PCX_DECODER) += pcx.o +OBJS-$(CONFIG_PCX_ENCODER) += pcxenc.o +OBJS-$(CONFIG_PGM_DECODER) += pnmdec.o pnm.o +OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o +OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o +OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o +OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o +OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o +OBJS-$(CONFIG_PIXLET_DECODER) += pixlet.o +OBJS-$(CONFIG_PJS_DECODER) += textdec.o ass.o +OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o pngdsp.o +OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o +OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o +OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o +OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o proresdata.o +OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o proresdata.o +OBJS-$(CONFIG_PRORES_AW_ENCODER) += proresenc_anatoliy.o proresdata.o +OBJS-$(CONFIG_PRORES_KS_ENCODER) += proresenc_kostya.o proresdata.o +OBJS-$(CONFIG_PROSUMER_DECODER) += prosumer.o +OBJS-$(CONFIG_PSD_DECODER) += psd.o +OBJS-$(CONFIG_PTX_DECODER) += ptx.o +OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o \ + celp_filters.o acelp_vectors.o \ + acelp_filters.o +OBJS-$(CONFIG_QDM2_DECODER) += qdm2.o +OBJS-$(CONFIG_QDMC_DECODER) += qdmc.o +OBJS-$(CONFIG_QDRAW_DECODER) += qdrw.o +OBJS-$(CONFIG_QPEG_DECODER) += qpeg.o +OBJS-$(CONFIG_QTRLE_DECODER) += qtrle.o +OBJS-$(CONFIG_QTRLE_ENCODER) += qtrleenc.o +OBJS-$(CONFIG_R10K_DECODER) += r210dec.o +OBJS-$(CONFIG_R10K_ENCODER) += r210enc.o +OBJS-$(CONFIG_R210_DECODER) += r210dec.o +OBJS-$(CONFIG_R210_ENCODER) += r210enc.o +OBJS-$(CONFIG_RA_144_DECODER) += ra144dec.o ra144.o celp_filters.o +OBJS-$(CONFIG_RA_144_ENCODER) += ra144enc.o ra144.o celp_filters.o +OBJS-$(CONFIG_RA_288_DECODER) += ra288.o celp_filters.o +OBJS-$(CONFIG_RALF_DECODER) += ralf.o +OBJS-$(CONFIG_RASC_DECODER) += rasc.o +OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o +OBJS-$(CONFIG_RAWVIDEO_ENCODER) += rawenc.o +OBJS-$(CONFIG_REALTEXT_DECODER) += realtextdec.o ass.o +OBJS-$(CONFIG_RL2_DECODER) += rl2.o +OBJS-$(CONFIG_ROQ_DECODER) += roqvideodec.o roqvideo.o +OBJS-$(CONFIG_ROQ_ENCODER) += roqvideoenc.o roqvideo.o elbg.o +OBJS-$(CONFIG_ROQ_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_ROQ_DPCM_ENCODER) += roqaudioenc.o +OBJS-$(CONFIG_RPZA_DECODER) += rpza.o +OBJS-$(CONFIG_RSCC_DECODER) += rscc.o +OBJS-$(CONFIG_RV10_DECODER) += rv10.o +OBJS-$(CONFIG_RV10_ENCODER) += rv10enc.o +OBJS-$(CONFIG_RV20_DECODER) += rv10.o +OBJS-$(CONFIG_RV20_ENCODER) += rv20enc.o +OBJS-$(CONFIG_RV30_DECODER) += rv30.o rv34.o rv30dsp.o +OBJS-$(CONFIG_RV40_DECODER) += rv40.o rv34.o rv40dsp.o +OBJS-$(CONFIG_SAMI_DECODER) += samidec.o ass.o htmlsubtitles.o +OBJS-$(CONFIG_S302M_DECODER) += s302m.o +OBJS-$(CONFIG_S302M_ENCODER) += s302menc.o +OBJS-$(CONFIG_SANM_DECODER) += sanm.o +OBJS-$(CONFIG_SCPR_DECODER) += scpr.o +OBJS-$(CONFIG_SCREENPRESSO_DECODER) += screenpresso.o +OBJS-$(CONFIG_SDX2_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_SGI_DECODER) += sgidec.o +OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o +OBJS-$(CONFIG_SGIRLE_DECODER) += sgirledec.o +OBJS-$(CONFIG_SHEERVIDEO_DECODER) += sheervideo.o +OBJS-$(CONFIG_SHORTEN_DECODER) += shorten.o +OBJS-$(CONFIG_SIPR_DECODER) += sipr.o acelp_pitch_delay.o \ + celp_math.o acelp_vectors.o \ + acelp_filters.o celp_filters.o \ + sipr16k.o +OBJS-$(CONFIG_SMACKAUD_DECODER) += smacker.o +OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o +OBJS-$(CONFIG_SMC_DECODER) += smc.o +OBJS-$(CONFIG_SMVJPEG_DECODER) += smvjpegdec.o +OBJS-$(CONFIG_SNOW_DECODER) += snowdec.o snow.o snow_dwt.o +OBJS-$(CONFIG_SNOW_ENCODER) += snowenc.o snow.o snow_dwt.o \ + h263.o ituh263enc.o +OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_SONIC_DECODER) += sonic.o +OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o +OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o +OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhq.o mpeg12.o mpeg12data.o simple_idct.o +OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o +OBJS-$(CONFIG_SRGC_DECODER) += mscc.o +OBJS-$(CONFIG_SRT_DECODER) += srtdec.o ass.o htmlsubtitles.o +OBJS-$(CONFIG_SRT_ENCODER) += srtenc.o ass_split.o +OBJS-$(CONFIG_STL_DECODER) += textdec.o ass.o +OBJS-$(CONFIG_SUBRIP_DECODER) += srtdec.o ass.o htmlsubtitles.o +OBJS-$(CONFIG_SUBRIP_ENCODER) += srtenc.o ass_split.o +OBJS-$(CONFIG_SUBVIEWER1_DECODER) += textdec.o ass.o +OBJS-$(CONFIG_SUBVIEWER_DECODER) += subviewerdec.o ass.o +OBJS-$(CONFIG_SUNRAST_DECODER) += sunrast.o +OBJS-$(CONFIG_SUNRAST_ENCODER) += sunrastenc.o +OBJS-$(CONFIG_LIBRSVG_DECODER) += librsvgdec.o +OBJS-$(CONFIG_SBC_DECODER) += sbcdec.o sbcdec_data.o sbc.o +OBJS-$(CONFIG_SBC_ENCODER) += sbcenc.o sbc.o sbcdsp.o sbcdsp_data.o +OBJS-$(CONFIG_SVQ1_DECODER) += svq1dec.o svq1.o svq13.o h263data.o +OBJS-$(CONFIG_SVQ1_ENCODER) += svq1enc.o svq1.o h263data.o \ + h263.o ituh263enc.o +OBJS-$(CONFIG_SVQ3_DECODER) += svq3.o svq13.o mpegutils.o h264data.o +OBJS-$(CONFIG_TEXT_DECODER) += textdec.o ass.o +OBJS-$(CONFIG_TEXT_ENCODER) += srtenc.o ass_split.o +OBJS-$(CONFIG_TAK_DECODER) += takdec.o tak.o takdsp.o +OBJS-$(CONFIG_TARGA_DECODER) += targa.o +OBJS-$(CONFIG_TARGA_ENCODER) += targaenc.o rle.o +OBJS-$(CONFIG_TARGA_Y216_DECODER) += targa_y216dec.o +OBJS-$(CONFIG_TDSC_DECODER) += tdsc.o +OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o +OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o tiff_data.o tiff_common.o +OBJS-$(CONFIG_TIFF_ENCODER) += tiffenc.o rle.o lzwenc.o tiff_data.o +OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o +OBJS-$(CONFIG_TRUEHD_DECODER) += mlpdec.o mlpdsp.o +OBJS-$(CONFIG_TRUEHD_ENCODER) += mlpenc.o mlp.o +OBJS-$(CONFIG_TRUEMOTION1_DECODER) += truemotion1.o +OBJS-$(CONFIG_TRUEMOTION2_DECODER) += truemotion2.o +OBJS-$(CONFIG_TRUEMOTION2RT_DECODER) += truemotion2rt.o +OBJS-$(CONFIG_TRUESPEECH_DECODER) += truespeech.o +OBJS-$(CONFIG_TSCC_DECODER) += tscc.o msrledec.o +OBJS-$(CONFIG_TSCC2_DECODER) += tscc2.o +OBJS-$(CONFIG_TTA_DECODER) += tta.o ttadata.o ttadsp.o +OBJS-$(CONFIG_TTA_ENCODER) += ttaenc.o ttaencdsp.o ttadata.o +OBJS-$(CONFIG_TWINVQ_DECODER) += twinvqdec.o twinvq.o +OBJS-$(CONFIG_TXD_DECODER) += txd.o +OBJS-$(CONFIG_ULTI_DECODER) += ulti.o +OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideodec.o utvideo.o utvideodsp.o +OBJS-$(CONFIG_UTVIDEO_ENCODER) += utvideoenc.o utvideo.o +OBJS-$(CONFIG_V210_DECODER) += v210dec.o +OBJS-$(CONFIG_V210_ENCODER) += v210enc.o +OBJS-$(CONFIG_V210X_DECODER) += v210x.o +OBJS-$(CONFIG_V308_DECODER) += v308dec.o +OBJS-$(CONFIG_V308_ENCODER) += v308enc.o +OBJS-$(CONFIG_V408_DECODER) += v408dec.o +OBJS-$(CONFIG_V408_ENCODER) += v408enc.o +OBJS-$(CONFIG_V410_DECODER) += v410dec.o +OBJS-$(CONFIG_V410_ENCODER) += v410enc.o +OBJS-$(CONFIG_VB_DECODER) += vb.o +OBJS-$(CONFIG_VBLE_DECODER) += vble.o +OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1_loopfilter.o \ + vc1_mc.o vc1_pred.o vc1.o vc1data.o \ + msmpeg4dec.o msmpeg4.o msmpeg4data.o \ + wmv2dsp.o wmv2data.o +OBJS-$(CONFIG_VC1_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_VC1_MMAL_DECODER) += mmaldec.o +OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_VC1_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_VC2_ENCODER) += vc2enc.o vc2enc_dwt.o diractab.o +OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o +OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.o +OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdvideo.o +OBJS-$(CONFIG_VMNC_DECODER) += vmnc.o +OBJS-$(CONFIG_VORBIS_DECODER) += vorbisdec.o vorbisdsp.o vorbis.o \ + vorbis_data.o +OBJS-$(CONFIG_VORBIS_ENCODER) += vorbisenc.o vorbis.o \ + vorbis_data.o +OBJS-$(CONFIG_VP3_DECODER) += vp3.o +OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vp56rac.o +OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o \ + vp6dsp.o vp56rac.o +OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp56rac.o +OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o +OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o +OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec_other.o +OBJS-$(CONFIG_VP8_RKMPP_DECODER) += rkmppdec.o +OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o +OBJS-$(CONFIG_VP8_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_VP8_V4L2M2M_ENCODER) += v4l2_m2m_enc.o +OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o vp9recon.o \ + vp9block.o vp9prob.o vp9mvs.o vp56rac.o \ + vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o +OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuviddec.o +OBJS-$(CONFIG_VP9_MEDIACODEC_DECODER) += mediacodecdec.o +OBJS-$(CONFIG_VP9_RKMPP_DECODER) += rkmppdec.o +OBJS-$(CONFIG_VP9_VAAPI_ENCODER) += vaapi_encode_vp9.o +OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o +OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o +OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o +OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o +OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackenc.o +OBJS-$(CONFIG_WCMV_DECODER) += wcmv.o +OBJS-$(CONFIG_WEBP_DECODER) += webp.o +OBJS-$(CONFIG_WEBVTT_DECODER) += webvttdec.o ass.o +OBJS-$(CONFIG_WEBVTT_ENCODER) += webvttenc.o ass_split.o +OBJS-$(CONFIG_WMALOSSLESS_DECODER) += wmalosslessdec.o wma_common.o +OBJS-$(CONFIG_WMAPRO_DECODER) += wmaprodec.o wma.o wma_common.o +OBJS-$(CONFIG_WMAV1_DECODER) += wmadec.o wma.o wma_common.o aactab.o +OBJS-$(CONFIG_WMAV1_ENCODER) += wmaenc.o wma.o wma_common.o aactab.o +OBJS-$(CONFIG_WMAV2_DECODER) += wmadec.o wma.o wma_common.o aactab.o +OBJS-$(CONFIG_WMAV2_ENCODER) += wmaenc.o wma.o wma_common.o aactab.o +OBJS-$(CONFIG_WMAVOICE_DECODER) += wmavoice.o \ + celp_filters.o \ + acelp_vectors.o acelp_filters.o +OBJS-$(CONFIG_WMV1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_WMV1_ENCODER) += msmpeg4enc.o +OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o wmv2data.o \ + msmpeg4dec.o msmpeg4.o msmpeg4data.o +OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o wmv2data.o \ + msmpeg4.o msmpeg4enc.o msmpeg4data.o +OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o +OBJS-$(CONFIG_WRAPPED_AVFRAME_DECODER) += wrapped_avframe.o +OBJS-$(CONFIG_WRAPPED_AVFRAME_ENCODER) += wrapped_avframe.o +OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o +OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_XAN_WC3_DECODER) += xan.o +OBJS-$(CONFIG_XAN_WC4_DECODER) += xxan.o +OBJS-$(CONFIG_XBIN_DECODER) += bintext.o cga_data.o +OBJS-$(CONFIG_XBM_DECODER) += xbmdec.o +OBJS-$(CONFIG_XBM_ENCODER) += xbmenc.o +OBJS-$(CONFIG_XFACE_DECODER) += xfacedec.o xface.o +OBJS-$(CONFIG_XFACE_ENCODER) += xfaceenc.o xface.o +OBJS-$(CONFIG_XL_DECODER) += xl.o +OBJS-$(CONFIG_XMA1_DECODER) += wmaprodec.o wma.o wma_common.o +OBJS-$(CONFIG_XMA2_DECODER) += wmaprodec.o wma.o wma_common.o +OBJS-$(CONFIG_XPM_DECODER) += xpmdec.o +OBJS-$(CONFIG_XSUB_DECODER) += xsubdec.o +OBJS-$(CONFIG_XSUB_ENCODER) += xsubenc.o +OBJS-$(CONFIG_XWD_DECODER) += xwddec.o +OBJS-$(CONFIG_XWD_ENCODER) += xwdenc.o +OBJS-$(CONFIG_Y41P_DECODER) += y41pdec.o +OBJS-$(CONFIG_Y41P_ENCODER) += y41penc.o +OBJS-$(CONFIG_YLC_DECODER) += ylc.o +OBJS-$(CONFIG_YOP_DECODER) += yop.o +OBJS-$(CONFIG_YUV4_DECODER) += yuv4dec.o +OBJS-$(CONFIG_YUV4_ENCODER) += yuv4enc.o +OBJS-$(CONFIG_ZEROCODEC_DECODER) += zerocodec.o +OBJS-$(CONFIG_ZLIB_DECODER) += lcldec.o +OBJS-$(CONFIG_ZLIB_ENCODER) += lclenc.o +OBJS-$(CONFIG_ZMBV_DECODER) += zmbv.o +OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o + +# (AD)PCM decoders/encoders +OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_BLURAY_DECODER) += pcm-bluray.o +OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm-dvd.o +OBJS-$(CONFIG_PCM_DVD_ENCODER) += pcm-dvdenc.o +OBJS-$(CONFIG_PCM_F16LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_F24LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_F32BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_F32BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_F32LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_F32LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_F64BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_F64BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_F64LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_F64LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_LXF_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_MULAW_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_MULAW_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S8_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S8_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S8_PLANAR_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S8_PLANAR_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S16BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S16BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S16BE_PLANAR_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S16BE_PLANAR_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S16LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S16LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S16LE_PLANAR_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S16LE_PLANAR_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S24BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S24BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S24DAUD_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S24DAUD_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S24LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S24LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S24LE_PLANAR_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S24LE_PLANAR_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S32BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S32BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S32LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S32LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S32LE_PLANAR_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S32LE_PLANAR_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S64BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S64BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S64LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S64LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U8_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U8_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U16BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U16BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U16LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U16LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U24BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U24BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U24LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U24LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U32BE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U32BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U32LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U32LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_VIDC_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_VIDC_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_ZORK_DECODER) += pcm.o + +OBJS-$(CONFIG_ADPCM_4XM_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o adx.o +OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adxenc.o adx.o +OBJS-$(CONFIG_ADPCM_AFC_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_AGM_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_AICA_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_DTK_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_EA_MAXIS_XA_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_EA_R1_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_EA_R2_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_EA_R3_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_EA_XAS_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_G722_DECODER) += g722.o g722dsp.o g722dec.o +OBJS-$(CONFIG_ADPCM_G722_ENCODER) += g722.o g722dsp.o g722enc.o +OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o +OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o +OBJS-$(CONFIG_ADPCM_G726LE_DECODER) += g726.o +OBJS-$(CONFIG_ADPCM_G726LE_ENCODER) += g726.o +OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_DAT4_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_OKI_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER) += adpcmenc.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_RAD_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcmenc.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_MS_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcmenc.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_MTAF_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_PSX_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_SBPRO_3_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_SBPRO_4_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_SWF_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_SWF_ENCODER) += adpcmenc.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_THP_LE_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_VIMA_DECODER) += vima.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o + +# hardware accelerators +OBJS-$(CONFIG_D3D11VA) += dxva2.o +OBJS-$(CONFIG_DXVA2) += dxva2.o +OBJS-$(CONFIG_NVDEC) += nvdec.o +OBJS-$(CONFIG_VAAPI) += vaapi_decode.o +OBJS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.o +OBJS-$(CONFIG_VDPAU) += vdpau.o + +OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o +OBJS-$(CONFIG_H263_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o +OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o +OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o +OBJS-$(CONFIG_H264_NVDEC_HWACCEL) += nvdec_h264.o +OBJS-$(CONFIG_H264_QSV_HWACCEL) += qsvdec_h2645.o +OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o +OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o +OBJS-$(CONFIG_H264_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o +OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o +OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o +OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o +OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o +OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o +OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o +OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o +OBJS-$(CONFIG_MJPEG_VAAPI_HWACCEL) += vaapi_mjpeg.o +OBJS-$(CONFIG_MPEG1_NVDEC_HWACCEL) += nvdec_mpeg12.o +OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL) += vdpau_mpeg12.o +OBJS-$(CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o +OBJS-$(CONFIG_MPEG1_XVMC_HWACCEL) += mpegvideo_xvmc.o +OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o +OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o +OBJS-$(CONFIG_MPEG2_NVDEC_HWACCEL) += nvdec_mpeg12.o +OBJS-$(CONFIG_MPEG2_QSV_HWACCEL) += qsvdec_other.o +OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o +OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o +OBJS-$(CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o +OBJS-$(CONFIG_MPEG2_XVMC_HWACCEL) += mpegvideo_xvmc.o +OBJS-$(CONFIG_MPEG4_NVDEC_HWACCEL) += nvdec_mpeg4.o +OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o +OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL) += vdpau_mpeg4.o +OBJS-$(CONFIG_MPEG4_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o +OBJS-$(CONFIG_VC1_D3D11VA_HWACCEL) += dxva2_vc1.o +OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o +OBJS-$(CONFIG_VC1_NVDEC_HWACCEL) += nvdec_vc1.o +OBJS-$(CONFIG_VC1_QSV_HWACCEL) += qsvdec_other.o +OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o +OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o +OBJS-$(CONFIG_VP8_NVDEC_HWACCEL) += nvdec_vp8.o +OBJS-$(CONFIG_VP8_VAAPI_HWACCEL) += vaapi_vp8.o +OBJS-$(CONFIG_VP9_D3D11VA_HWACCEL) += dxva2_vp9.o +OBJS-$(CONFIG_VP9_DXVA2_HWACCEL) += dxva2_vp9.o +OBJS-$(CONFIG_VP9_NVDEC_HWACCEL) += nvdec_vp9.o +OBJS-$(CONFIG_VP9_VAAPI_HWACCEL) += vaapi_vp9.o +OBJS-$(CONFIG_VP8_QSV_HWACCEL) += qsvdec_other.o + +# libavformat dependencies +OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o + +OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o +OBJS-$(CONFIG_CAF_DEMUXER) += ac3tab.o +OBJS-$(CONFIG_CODEC2_DEMUXER) += codec2utils.o +OBJS-$(CONFIG_CODEC2_MUXER) += codec2utils.o +OBJS-$(CONFIG_CODEC2RAW_DEMUXER) += codec2utils.o +OBJS-$(CONFIG_DNXHD_DEMUXER) += dnxhddata.o +OBJS-$(CONFIG_FITS_DEMUXER) += fits.o +OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o +OBJS-$(CONFIG_LATM_MUXER) += mpeg4audio.o +OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += mpeg4audio.o +OBJS-$(CONFIG_MATROSKA_MUXER) += mpeg4audio.o +OBJS-$(CONFIG_MOV_DEMUXER) += ac3tab.o +OBJS-$(CONFIG_MXF_MUXER) += dnxhddata.o +OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o +OBJS-$(CONFIG_NUT_DEMUXER) += mpegaudiodata.o mpeg4audio.o +OBJS-$(CONFIG_RTP_MUXER) += mpeg4audio.o +OBJS-$(CONFIG_SPDIF_MUXER) += dca.o +OBJS-$(CONFIG_TAK_DEMUXER) += tak.o +OBJS-$(CONFIG_WEBM_MUXER) += mpeg4audio.o + +# libavfilter dependencies +OBJS-$(CONFIG_ELBG_FILTER) += elbg.o + +# external codec libraries +OBJS-$(CONFIG_AAC_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_AC3_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_ADPCM_IMA_QT_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_ALAC_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_AMR_NB_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_EAC3_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_GSM_MS_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_ILBC_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_MP1_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_MP2_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_MP3_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_PCM_MULAW_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_PCM_ALAW_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_QDMC_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_QDM2_AT_DECODER) += audiotoolboxdec.o +OBJS-$(CONFIG_AAC_AT_ENCODER) += audiotoolboxenc.o +OBJS-$(CONFIG_ALAC_AT_ENCODER) += audiotoolboxenc.o +OBJS-$(CONFIG_ILBC_AT_ENCODER) += audiotoolboxenc.o +OBJS-$(CONFIG_PCM_ALAW_AT_ENCODER) += audiotoolboxenc.o +OBJS-$(CONFIG_PCM_MULAW_AT_ENCODER) += audiotoolboxenc.o +OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o +OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o +OBJS-$(CONFIG_LIBARIBB24_DECODER) += libaribb24.o ass.o +OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o +OBJS-$(CONFIG_LIBCODEC2_DECODER) += libcodec2.o codec2utils.o +OBJS-$(CONFIG_LIBCODEC2_ENCODER) += libcodec2.o codec2utils.o +OBJS-$(CONFIG_LIBDAV1D_DECODER) += libdav1d.o +OBJS-$(CONFIG_LIBDAVS2_DECODER) += libdavs2.o +OBJS-$(CONFIG_LIBFDK_AAC_DECODER) += libfdk-aacdec.o +OBJS-$(CONFIG_LIBFDK_AAC_ENCODER) += libfdk-aacenc.o +OBJS-$(CONFIG_LIBGSM_DECODER) += libgsmdec.o +OBJS-$(CONFIG_LIBGSM_ENCODER) += libgsmenc.o +OBJS-$(CONFIG_LIBGSM_MS_DECODER) += libgsmdec.o +OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsmenc.o +OBJS-$(CONFIG_LIBILBC_DECODER) += libilbc.o +OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o +OBJS-$(CONFIG_LIBKVAZAAR_ENCODER) += libkvazaar.o +OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o +OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o +OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o +OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o +OBJS-$(CONFIG_LIBOPENH264_DECODER) += libopenh264dec.o libopenh264.o +OBJS-$(CONFIG_LIBOPENH264_ENCODER) += libopenh264enc.o libopenh264.o +OBJS-$(CONFIG_LIBOPENJPEG_DECODER) += libopenjpegdec.o +OBJS-$(CONFIG_LIBOPENJPEG_ENCODER) += libopenjpegenc.o +OBJS-$(CONFIG_LIBOPUS_DECODER) += libopusdec.o libopus.o \ + vorbis_data.o +OBJS-$(CONFIG_LIBOPUS_ENCODER) += libopusenc.o libopus.o \ + vorbis_data.o +OBJS-$(CONFIG_LIBSHINE_ENCODER) += libshine.o +OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o +OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o +OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o +OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o +OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o +OBJS-$(CONFIG_LIBVORBIS_DECODER) += libvorbisdec.o +OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o \ + vorbis_data.o +OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o +OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o +OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o libvpx.o +OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o libvpx.o +OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o +OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o +OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o +OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o +OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o +OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o +OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o +OBJS-$(CONFIG_LIBXAVS2_ENCODER) += libxavs2.o +OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o +OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o ass.o + +# parsers +OBJS-$(CONFIG_AAC_LATM_PARSER) += latm_parser.o +OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \ + mpeg4audio.o +OBJS-$(CONFIG_AC3_PARSER) += ac3tab.o aac_ac3_parser.o +OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o +OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o av1_parse.o +OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o +OBJS-$(CONFIG_BMP_PARSER) += bmp_parser.o +OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o +OBJS-$(CONFIG_COOK_PARSER) += cook_parser.o +OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o dca_exss.o dca.o +OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o +OBJS-$(CONFIG_DNXHD_PARSER) += dnxhd_parser.o dnxhddata.o +OBJS-$(CONFIG_DPX_PARSER) += dpx_parser.o +OBJS-$(CONFIG_DVAUDIO_PARSER) += dvaudio_parser.o +OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsub_parser.o +OBJS-$(CONFIG_DVD_NAV_PARSER) += dvd_nav_parser.o +OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsub_parser.o +OBJS-$(CONFIG_FLAC_PARSER) += flac_parser.o flacdata.o flac.o \ + vorbis_data.o +OBJS-$(CONFIG_G723_1_PARSER) += g723_1_parser.o +OBJS-$(CONFIG_G729_PARSER) += g729_parser.o +OBJS-$(CONFIG_GIF_PARSER) += gif_parser.o +OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o +OBJS-$(CONFIG_H261_PARSER) += h261_parser.o +OBJS-$(CONFIG_H263_PARSER) += h263_parser.o +OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264_sei.o h264data.o +OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o hevc_data.o +OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o +OBJS-$(CONFIG_MLP_PARSER) += mlp_parse.o mlp_parser.o mlp.o +OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \ + mpeg4videodec.o mpeg4video.o \ + ituh263dec.o h263dec.o h263data.o +OBJS-$(CONFIG_PNG_PARSER) += png_parser.o +OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o +OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \ + mpeg12.o mpeg12data.o +OBJS-$(CONFIG_OPUS_PARSER) += opus_parser.o opus.o opustab.o \ + opus_rc.o vorbis_data.o +OBJS-$(CONFIG_PNG_PARSER) += png_parser.o +OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o +OBJS-$(CONFIG_RV30_PARSER) += rv34_parser.o +OBJS-$(CONFIG_RV40_PARSER) += rv34_parser.o +OBJS-$(CONFIG_SBC_PARSER) += sbc_parser.o +OBJS-$(CONFIG_SIPR_PARSER) += sipr_parser.o +OBJS-$(CONFIG_TAK_PARSER) += tak_parser.o tak.o +OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \ + simple_idct.o wmv2data.o +OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o +OBJS-$(CONFIG_VP8_PARSER) += vp8_parser.o +OBJS-$(CONFIG_VP9_PARSER) += vp9_parser.o +OBJS-$(CONFIG_XMA_PARSER) += xma_parser.o + +# bitstream filters +OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o mpeg4audio.o +OBJS-$(CONFIG_AV1_METADATA_BSF) += av1_metadata_bsf.o +OBJS-$(CONFIG_AV1_FRAME_SPLIT_BSF) += av1_frame_split_bsf.o +OBJS-$(CONFIG_CHOMP_BSF) += chomp_bsf.o +OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o +OBJS-$(CONFIG_DCA_CORE_BSF) += dca_core_bsf.o +OBJS-$(CONFIG_EAC3_CORE_BSF) += eac3_core_bsf.o +OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF) += extract_extradata_bsf.o \ + av1_parse.o h2645_parse.o +OBJS-$(CONFIG_FILTER_UNITS_BSF) += filter_units_bsf.o +OBJS-$(CONFIG_H264_METADATA_BSF) += h264_metadata_bsf.o h264_levels.o +OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o +OBJS-$(CONFIG_H264_REDUNDANT_PPS_BSF) += h264_redundant_pps_bsf.o +OBJS-$(CONFIG_HAPQA_EXTRACT_BSF) += hapqa_extract_bsf.o hap.o +OBJS-$(CONFIG_HEVC_METADATA_BSF) += h265_metadata_bsf.o h265_profile_level.o +OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF) += hevc_mp4toannexb_bsf.o +OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o +OBJS-$(CONFIG_MJPEG2JPEG_BSF) += mjpeg2jpeg_bsf.o +OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o +OBJS-$(CONFIG_MPEG4_UNPACK_BFRAMES_BSF) += mpeg4_unpack_bframes_bsf.o +OBJS-$(CONFIG_MOV2TEXTSUB_BSF) += movsub_bsf.o +OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF) += mp3_header_decompress_bsf.o \ + mpegaudiodata.o +OBJS-$(CONFIG_MPEG2_METADATA_BSF) += mpeg2_metadata_bsf.o +OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o +OBJS-$(CONFIG_NULL_BSF) += null_bsf.o +OBJS-$(CONFIG_PRORES_METADATA_BSF) += prores_metadata_bsf.o +OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o +OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o +OBJS-$(CONFIG_TRACE_HEADERS_BSF) += trace_headers_bsf.o +OBJS-$(CONFIG_TRUEHD_CORE_BSF) += truehd_core_bsf.o mlp_parse.o mlp.o +OBJS-$(CONFIG_VP9_METADATA_BSF) += vp9_metadata_bsf.o +OBJS-$(CONFIG_VP9_RAW_REORDER_BSF) += vp9_raw_reorder_bsf.o +OBJS-$(CONFIG_VP9_SUPERFRAME_BSF) += vp9_superframe_bsf.o +OBJS-$(CONFIG_VP9_SUPERFRAME_SPLIT_BSF) += vp9_superframe_split_bsf.o + +# thread libraries +OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o +OBJS-$(HAVE_THREADS) += pthread.o pthread_slice.o pthread_frame.o + +OBJS-$(CONFIG_FRAME_THREAD_ENCODER) += frame_thread_encoder.o + +# Windows resource file +SLIBOBJS-$(HAVE_GNU_WINDRES) += avcodecres.o + +SKIPHEADERS += %_tablegen.h \ + %_tables.h \ + fft-internal.h \ + tableprint.h \ + tableprint_vlc.h \ + aaccoder_twoloop.h \ + aaccoder_trellis.h \ + aacenc_quantization.h \ + aacenc_quantization_misc.h \ + $(ARCH)/vp56_arith.h \ + +SKIPHEADERS-$(CONFIG_AMF) += amfenc.h +SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h +SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h +SKIPHEADERS-$(CONFIG_JNI) += ffjni.h +SKIPHEADERS-$(CONFIG_LIBVPX) += libvpx.h +SKIPHEADERS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.h +SKIPHEADERS-$(CONFIG_MEDIACODEC) += mediacodecdec_common.h mediacodec_surface.h mediacodec_wrapper.h mediacodec_sw_buffer.h +SKIPHEADERS-$(CONFIG_NVDEC) += nvdec.h +SKIPHEADERS-$(CONFIG_NVENC) += nvenc.h +SKIPHEADERS-$(CONFIG_QSV) += qsv.h qsv_internal.h +SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h +SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h +SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h +SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_encode.h +SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h +SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vt_internal.h +SKIPHEADERS-$(CONFIG_V4L2_M2M) += v4l2_buffers.h v4l2_context.h v4l2_m2m.h + +TESTPROGS = avpacket \ + celp_math \ + codec_desc \ + htmlsubtitles \ + imgconvert \ + jpeg2000dwt \ + mathops \ + options \ + mjpegenc_huffman \ + utils \ + +TESTPROGS-$(CONFIG_CABAC) += cabac +TESTPROGS-$(CONFIG_DCT) += avfft +TESTPROGS-$(CONFIG_FFT) += fft fft-fixed fft-fixed32 +TESTPROGS-$(CONFIG_GOLOMB) += golomb +TESTPROGS-$(CONFIG_IDCTDSP) += dct +TESTPROGS-$(CONFIG_IIRFILTER) += iirfilter +TESTPROGS-$(HAVE_MMX) += motion +TESTPROGS-$(CONFIG_MPEGVIDEO) += mpeg12framerate +TESTPROGS-$(CONFIG_H264_METADATA_BSF) += h264_levels +TESTPROGS-$(CONFIG_HEVC_METADATA_BSF) += h265_levels +TESTPROGS-$(CONFIG_RANGECODER) += rangecoder +TESTPROGS-$(CONFIG_SNOW_ENCODER) += snowenc + +TESTOBJS = dctref.o + +TOOLS = fourcc2pixfmt + +HOSTPROGS = aacps_tablegen \ + aacps_fixed_tablegen \ + cbrt_tablegen \ + cbrt_fixed_tablegen \ + cos_tablegen \ + dv_tablegen \ + motionpixels_tablegen \ + mpegaudio_tablegen \ + pcm_tablegen \ + qdm2_tablegen \ + sinewin_tablegen \ + sinewin_fixed_tablegen \ + +CLEANFILES = *_tables.c *_tables.h *_tablegen$(HOSTEXESUF) + +$(SUBDIR)tests/dct$(EXESUF): $(SUBDIR)dctref.o $(SUBDIR)aandcttab.o +$(SUBDIR)dv_tablegen$(HOSTEXESUF): $(SUBDIR)dvdata_host.o + +TRIG_TABLES = cos cos_fixed sin +TRIG_TABLES := $(TRIG_TABLES:%=$(SUBDIR)%_tables.c) + +$(TRIG_TABLES): $(SUBDIR)%_tables.c: $(SUBDIR)cos_tablegen$(HOSTEXESUF) + $(M)./$< $* > $@ + +ifdef CONFIG_SMALL +$(SUBDIR)%_tablegen$(HOSTEXESUF): HOSTCFLAGS += -DCONFIG_SMALL=1 +else +$(SUBDIR)%_tablegen$(HOSTEXESUF): HOSTCFLAGS += -DCONFIG_SMALL=0 +endif + +GEN_HEADERS = cbrt_tables.h cbrt_fixed_tables.h aacps_tables.h aacps_fixed_tables.h \ + dv_tables.h \ + sinewin_tables.h sinewin_fixed_tables.h mpegaudio_tables.h motionpixels_tables.h \ + pcm_tables.h qdm2_tables.h +GEN_HEADERS := $(addprefix $(SUBDIR), $(GEN_HEADERS)) + +$(GEN_HEADERS): $(SUBDIR)%_tables.h: $(SUBDIR)%_tablegen$(HOSTEXESUF) + $(M)./$< > $@ + +ifdef CONFIG_HARDCODED_TABLES +$(SUBDIR)cbrt_data.o: $(SUBDIR)cbrt_tables.h +$(SUBDIR)cbrt_data_fixed.o: $(SUBDIR)cbrt_fixed_tables.h +$(SUBDIR)aacps_float.o: $(SUBDIR)aacps_tables.h +$(SUBDIR)aacps_fixed.o: $(SUBDIR)aacps_fixed_tables.h +$(SUBDIR)aactab_fixed.o: $(SUBDIR)aac_fixed_tables.h +$(SUBDIR)dvenc.o: $(SUBDIR)dv_tables.h +$(SUBDIR)motionpixels.o: $(SUBDIR)motionpixels_tables.h +$(SUBDIR)mpegaudiodec_fixed.o: $(SUBDIR)mpegaudio_tables.h +$(SUBDIR)mpegaudiodec_float.o: $(SUBDIR)mpegaudio_tables.h +$(SUBDIR)pcm.o: $(SUBDIR)pcm_tables.h +$(SUBDIR)qdm2.o: $(SUBDIR)qdm2_tables.h +$(SUBDIR)sinewin.o: $(SUBDIR)sinewin_tables.h +$(SUBDIR)sinewin_fixed.o: $(SUBDIR)sinewin_fixed_tables.h +endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac.h new file mode 100644 index 000000000..c2b9c980c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac.h @@ -0,0 +1,377 @@ +/* + * AAC definitions and structures + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC definitions and structures + * @author Oded Shimon ( ods15 ods15 dyndns org ) + * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) + */ + +#ifndef AVCODEC_AAC_H +#define AVCODEC_AAC_H + + +#include "aac_defines.h" +#include "libavutil/float_dsp.h" +#include "libavutil/fixed_dsp.h" +#include "avcodec.h" +#if !USE_FIXED +#include "mdct15.h" +#endif +#include "fft.h" +#include "mpeg4audio.h" +#include "sbr.h" + +#include + +#define MAX_CHANNELS 64 +#define MAX_ELEM_ID 16 + +#define TNS_MAX_ORDER 20 +#define MAX_LTP_LONG_SFB 40 + +#define CLIP_AVOIDANCE_FACTOR 0.95f + +enum RawDataBlockType { + TYPE_SCE, + TYPE_CPE, + TYPE_CCE, + TYPE_LFE, + TYPE_DSE, + TYPE_PCE, + TYPE_FIL, + TYPE_END, +}; + +enum ExtensionPayloadID { + EXT_FILL, + EXT_FILL_DATA, + EXT_DATA_ELEMENT, + EXT_DYNAMIC_RANGE = 0xb, + EXT_SBR_DATA = 0xd, + EXT_SBR_DATA_CRC = 0xe, +}; + +enum WindowSequence { + ONLY_LONG_SEQUENCE, + LONG_START_SEQUENCE, + EIGHT_SHORT_SEQUENCE, + LONG_STOP_SEQUENCE, +}; + +enum BandType { + ZERO_BT = 0, ///< Scalefactors and spectral data are all zero. + FIRST_PAIR_BT = 5, ///< This and later band types encode two values (rather than four) with one code word. + ESC_BT = 11, ///< Spectral data are coded with an escape sequence. + RESERVED_BT = 12, ///< Band types following are encoded differently from others. + NOISE_BT = 13, ///< Spectral data are scaled white noise not coded in the bitstream. + INTENSITY_BT2 = 14, ///< Scalefactor data are intensity stereo positions (out of phase). + INTENSITY_BT = 15, ///< Scalefactor data are intensity stereo positions (in phase). +}; + +#define IS_CODEBOOK_UNSIGNED(x) (((x) - 1) & 10) + +enum ChannelPosition { + AAC_CHANNEL_OFF = 0, + AAC_CHANNEL_FRONT = 1, + AAC_CHANNEL_SIDE = 2, + AAC_CHANNEL_BACK = 3, + AAC_CHANNEL_LFE = 4, + AAC_CHANNEL_CC = 5, +}; + +/** + * The point during decoding at which channel coupling is applied. + */ +enum CouplingPoint { + BEFORE_TNS, + BETWEEN_TNS_AND_IMDCT, + AFTER_IMDCT = 3, +}; + +/** + * Output configuration status + */ +enum OCStatus { + OC_NONE, ///< Output unconfigured + OC_TRIAL_PCE, ///< Output configuration under trial specified by an inband PCE + OC_TRIAL_FRAME, ///< Output configuration under trial specified by a frame header + OC_GLOBAL_HDR, ///< Output configuration set in a global header but not yet locked + OC_LOCKED, ///< Output configuration locked in place +}; + +typedef struct OutputConfiguration { + MPEG4AudioConfig m4ac; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int layout_map_tags; + int channels; + uint64_t channel_layout; + enum OCStatus status; +} OutputConfiguration; + +/** + * Predictor State + */ +typedef struct PredictorState { + AAC_FLOAT cor0; + AAC_FLOAT cor1; + AAC_FLOAT var0; + AAC_FLOAT var1; + AAC_FLOAT r0; + AAC_FLOAT r1; + AAC_FLOAT k1; + AAC_FLOAT x_est; +} PredictorState; + +#define MAX_PREDICTORS 672 + +#define SCALE_DIV_512 36 ///< scalefactor difference that corresponds to scale difference in 512 times +#define SCALE_ONE_POS 140 ///< scalefactor index that corresponds to scale=1.0 +#define SCALE_MAX_POS 255 ///< scalefactor index maximum value +#define SCALE_MAX_DIFF 60 ///< maximum scalefactor difference allowed by standard +#define SCALE_DIFF_ZERO 60 ///< codebook index corresponding to zero scalefactor indices difference + +#define POW_SF2_ZERO 200 ///< ff_aac_pow2sf_tab index corresponding to pow(2, 0); + +#define NOISE_PRE 256 ///< preamble for NOISE_BT, put in bitstream with the first noise band +#define NOISE_PRE_BITS 9 ///< length of preamble +#define NOISE_OFFSET 90 ///< subtracted from global gain, used as offset for the preamble + +/** + * Long Term Prediction + */ +typedef struct LongTermPrediction { + int8_t present; + int16_t lag; + int coef_idx; + INTFLOAT coef; + int8_t used[MAX_LTP_LONG_SFB]; +} LongTermPrediction; + +/** + * Individual Channel Stream + */ +typedef struct IndividualChannelStream { + uint8_t max_sfb; ///< number of scalefactor bands per group + enum WindowSequence window_sequence[2]; + uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window. + int num_window_groups; + uint8_t group_len[8]; + LongTermPrediction ltp; + const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window + const uint8_t *swb_sizes; ///< table of scalefactor band sizes for a particular window + int num_swb; ///< number of scalefactor window bands + int num_windows; + int tns_max_bands; + int predictor_present; + int predictor_initialized; + int predictor_reset_group; + int predictor_reset_count[31]; ///< used by encoder to count prediction resets + uint8_t prediction_used[41]; + uint8_t window_clipping[8]; ///< set if a certain window is near clipping + float clip_avoidance_factor; ///< set if any window is near clipping to the necessary atennuation factor to avoid it +} IndividualChannelStream; + +/** + * Temporal Noise Shaping + */ +typedef struct TemporalNoiseShaping { + int present; + int n_filt[8]; + int length[8][4]; + int direction[8][4]; + int order[8][4]; + int coef_idx[8][4][TNS_MAX_ORDER]; + INTFLOAT coef[8][4][TNS_MAX_ORDER]; +} TemporalNoiseShaping; + +/** + * Dynamic Range Control - decoded from the bitstream but not processed further. + */ +typedef struct DynamicRangeControl { + int pce_instance_tag; ///< Indicates with which program the DRC info is associated. + int dyn_rng_sgn[17]; ///< DRC sign information; 0 - positive, 1 - negative + int dyn_rng_ctl[17]; ///< DRC magnitude information + int exclude_mask[MAX_CHANNELS]; ///< Channels to be excluded from DRC processing. + int band_incr; ///< Number of DRC bands greater than 1 having DRC info. + int interpolation_scheme; ///< Indicates the interpolation scheme used in the SBR QMF domain. + int band_top[17]; ///< Indicates the top of the i-th DRC band in units of 4 spectral lines. + int prog_ref_level; /**< A reference level for the long-term program audio level for all + * channels combined. + */ +} DynamicRangeControl; + +typedef struct Pulse { + int num_pulse; + int start; + int pos[4]; + int amp[4]; +} Pulse; + +/** + * coupling parameters + */ +typedef struct ChannelCoupling { + enum CouplingPoint coupling_point; ///< The point during decoding at which coupling is applied. + int num_coupled; ///< number of target elements + enum RawDataBlockType type[8]; ///< Type of channel element to be coupled - SCE or CPE. + int id_select[8]; ///< element id + int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for right channel; + * [2] list of gains for left channel; [3] lists of gains for both channels + */ + INTFLOAT gain[16][120]; +} ChannelCoupling; + +/** + * Single Channel Element - used for both SCE and LFE elements. + */ +typedef struct SingleChannelElement { + IndividualChannelStream ics; + TemporalNoiseShaping tns; + Pulse pulse; + enum BandType band_type[128]; ///< band types + enum BandType band_alt[128]; ///< alternative band type (used by encoder) + int band_type_run_end[120]; ///< band type run end points + INTFLOAT sf[120]; ///< scalefactors + int sf_idx[128]; ///< scalefactor indices (used by encoder) + uint8_t zeroes[128]; ///< band is not coded (used by encoder) + uint8_t can_pns[128]; ///< band is allowed to PNS (informative) + float is_ener[128]; ///< Intensity stereo pos (used by encoder) + float pns_ener[128]; ///< Noise energy values (used by encoder) + DECLARE_ALIGNED(32, INTFLOAT, pcoeffs)[1024]; ///< coefficients for IMDCT, pristine + DECLARE_ALIGNED(32, INTFLOAT, coeffs)[1024]; ///< coefficients for IMDCT, maybe processed + DECLARE_ALIGNED(32, INTFLOAT, saved)[1536]; ///< overlap + DECLARE_ALIGNED(32, INTFLOAT, ret_buf)[2048]; ///< PCM output buffer + DECLARE_ALIGNED(16, INTFLOAT, ltp_state)[3072]; ///< time signal for LTP + DECLARE_ALIGNED(32, AAC_FLOAT, lcoeffs)[1024]; ///< MDCT of LTP coefficients (used by encoder) + DECLARE_ALIGNED(32, AAC_FLOAT, prcoeffs)[1024]; ///< Main prediction coefs (used by encoder) + PredictorState predictor_state[MAX_PREDICTORS]; + INTFLOAT *ret; ///< PCM output +} SingleChannelElement; + +/** + * channel element - generic struct for SCE/CPE/CCE/LFE + */ +typedef struct ChannelElement { + int present; + // CPE specific + int common_window; ///< Set if channels share a common 'IndividualChannelStream' in bitstream. + int ms_mode; ///< Signals mid/side stereo flags coding mode (used by encoder) + uint8_t is_mode; ///< Set if any bands have been encoded using intensity stereo (used by encoder) + uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band + uint8_t is_mask[128]; ///< Set if intensity stereo is used (used by encoder) + // shared + SingleChannelElement ch[2]; + // CCE specific + ChannelCoupling coup; + SpectralBandReplication sbr; +} ChannelElement; + +/** + * main AAC context + */ +struct AACContext { + AVClass *class; + AVCodecContext *avctx; + AVFrame *frame; + + int is_saved; ///< Set if elements have stored overlap from previous frame. + DynamicRangeControl che_drc; + + /** + * @name Channel element related data + * @{ + */ + ChannelElement *che[4][MAX_ELEM_ID]; + ChannelElement *tag_che_map[4][MAX_ELEM_ID]; + int tags_mapped; + int warned_remapping_once; + /** @} */ + + /** + * @name temporary aligned temporary buffers + * (We do not want to have these on the stack.) + * @{ + */ + DECLARE_ALIGNED(32, INTFLOAT, buf_mdct)[1024]; + /** @} */ + + /** + * @name Computed / set up during initialization + * @{ + */ + FFTContext mdct; + FFTContext mdct_small; + FFTContext mdct_ld; + FFTContext mdct_ltp; +#if USE_FIXED + AVFixedDSPContext *fdsp; +#else + MDCT15Context *mdct120; + MDCT15Context *mdct480; + MDCT15Context *mdct960; + AVFloatDSPContext *fdsp; +#endif /* USE_FIXED */ + int random_state; + /** @} */ + + /** + * @name Members used for output + * @{ + */ + SingleChannelElement *output_element[MAX_CHANNELS]; ///< Points to each SingleChannelElement + /** @} */ + + + /** + * @name Japanese DTV specific extension + * @{ + */ + int force_dmono_mode;///< 0->not dmono, 1->use first channel, 2->use second channel + int dmono_mode; ///< 0->not dmono, 1->use first channel, 2->use second channel + /** @} */ + + DECLARE_ALIGNED(32, INTFLOAT, temp)[128]; + + OutputConfiguration oc[2]; + int warned_num_aac_frames; + int warned_960_sbr; + + int warned_gain_control; + + /* aacdec functions pointers */ + void (*imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce); + void (*apply_ltp)(AACContext *ac, SingleChannelElement *sce); + void (*apply_tns)(INTFLOAT coef[1024], TemporalNoiseShaping *tns, + IndividualChannelStream *ics, int decode); + void (*windowing_and_mdct_ltp)(AACContext *ac, INTFLOAT *out, + INTFLOAT *in, IndividualChannelStream *ics); + void (*update_ltp)(AACContext *ac, SingleChannelElement *sce); + void (*vector_pow43)(int *coefs, int len); + void (*subband_scale)(int *dst, int *src, int scale, int offset, int len, void *log_context); + +}; + +void ff_aacdec_init_mips(AACContext *c); + +#endif /* AVCODEC_AAC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_ac3_parser.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_ac3_parser.c new file mode 100644 index 000000000..54e459844 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_ac3_parser.c @@ -0,0 +1,105 @@ +/* + * Common AAC and AC-3 parser + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/channel_layout.h" +#include "libavutil/common.h" +#include "parser.h" +#include "aac_ac3_parser.h" + +int ff_aac_ac3_parse(AVCodecParserContext *s1, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + AACAC3ParseContext *s = s1->priv_data; + ParseContext *pc = &s->pc; + int len, i; + int new_frame_start; + int got_frame = 0; + +get_next: + i=END_NOT_FOUND; + if(s->remaining_size <= buf_size){ + if(s->remaining_size && !s->need_next_header){ + i= s->remaining_size; + s->remaining_size = 0; + }else{ //we need a header first + len=0; + for(i=s->remaining_size; istate = (s->state<<8) + buf[i]; + if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start))) + break; + } + if(len<=0){ + i=END_NOT_FOUND; + }else{ + got_frame = 1; + s->state=0; + i-= s->header_size -1; + s->remaining_size = len; + if(!new_frame_start || pc->index+i<=0){ + s->remaining_size += i; + goto get_next; + } + else if (i < 0) { + s->remaining_size += i; + } + } + } + } + + if(ff_combine_frame(pc, i, &buf, &buf_size)<0){ + s->remaining_size -= FFMIN(s->remaining_size, buf_size); + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + + /* update codec info */ + if(s->codec_id) + avctx->codec_id = s->codec_id; + + if (got_frame) { + /* Due to backwards compatible HE-AAC the sample rate, channel count, + and total number of samples found in an AAC ADTS header are not + reliable. Bit rate is still accurate because the total frame + duration in seconds is still correct (as is the number of bits in + the frame). */ + if (avctx->codec_id != AV_CODEC_ID_AAC) { + avctx->sample_rate = s->sample_rate; + if (avctx->codec_id != AV_CODEC_ID_EAC3) { + avctx->channels = s->channels; + avctx->channel_layout = s->channel_layout; + } + s1->duration = s->samples; + avctx->audio_service_type = s->service_type; + } + + if (avctx->codec_id != AV_CODEC_ID_EAC3) + avctx->bit_rate = s->bit_rate; + } + + return i; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_ac3_parser.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_ac3_parser.h new file mode 100644 index 000000000..c2506a5bf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_ac3_parser.h @@ -0,0 +1,66 @@ +/* + * Common AAC and AC-3 parser prototypes + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AAC_AC3_PARSER_H +#define AVCODEC_AAC_AC3_PARSER_H + +#include +#include "avcodec.h" +#include "parser.h" + +typedef enum { + AAC_AC3_PARSE_ERROR_SYNC = -0x1030c0a, + AAC_AC3_PARSE_ERROR_BSID = -0x2030c0a, + AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -0x3030c0a, + AAC_AC3_PARSE_ERROR_FRAME_SIZE = -0x4030c0a, + AAC_AC3_PARSE_ERROR_FRAME_TYPE = -0x5030c0a, + AAC_AC3_PARSE_ERROR_CRC = -0x6030c0a, + AAC_AC3_PARSE_ERROR_CHANNEL_CFG = -0x7030c0a, +} AACAC3ParseError; + +typedef struct AACAC3ParseContext { + ParseContext pc; + int frame_size; + int header_size; + int (*sync)(uint64_t state, struct AACAC3ParseContext *hdr_info, + int *need_next_header, int *new_frame_start); + + int channels; + int sample_rate; + int bit_rate; + int samples; + uint64_t channel_layout; + int service_type; + + int remaining_size; + uint64_t state; + + int need_next_header; + enum AVCodecID codec_id; +} AACAC3ParseContext; + +int ff_aac_ac3_parse(AVCodecParserContext *s1, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + +#endif /* AVCODEC_AAC_AC3_PARSER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_adtstoasc_bsf.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_adtstoasc_bsf.c new file mode 100644 index 000000000..6541b1189 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_adtstoasc_bsf.c @@ -0,0 +1,158 @@ +/* + * MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter + * Copyright (c) 2009 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "adts_header.h" +#include "adts_parser.h" +#include "avcodec.h" +#include "bsf.h" +#include "put_bits.h" +#include "get_bits.h" +#include "mpeg4audio.h" +#include "internal.h" + +typedef struct AACBSFContext { + int first_frame_done; +} AACBSFContext; + +/** + * This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4 + * ADTS header and removes the ADTS header. + */ +static int aac_adtstoasc_filter(AVBSFContext *bsfc, AVPacket *pkt) +{ + AACBSFContext *ctx = bsfc->priv_data; + + GetBitContext gb; + PutBitContext pb; + AACADTSHeaderInfo hdr; + int ret; + + ret = ff_bsf_get_packet_ref(bsfc, pkt); + if (ret < 0) + return ret; + + if (bsfc->par_in->extradata && pkt->size >= 2 && (AV_RB16(pkt->data) >> 4) != 0xfff) + return 0; + + if (pkt->size < AV_AAC_ADTS_HEADER_SIZE) + goto packet_too_small; + + init_get_bits(&gb, pkt->data, AV_AAC_ADTS_HEADER_SIZE * 8); + + if (ff_adts_header_parse(&gb, &hdr) < 0) { + av_log(bsfc, AV_LOG_ERROR, "Error parsing ADTS frame header!\n"); + ret = AVERROR_INVALIDDATA; + goto fail; + } + + if (!hdr.crc_absent && hdr.num_aac_frames > 1) { + avpriv_report_missing_feature(bsfc, + "Multiple RDBs per frame with CRC"); + ret = AVERROR_PATCHWELCOME; + goto fail; + } + + pkt->size -= AV_AAC_ADTS_HEADER_SIZE + 2 * !hdr.crc_absent; + if (pkt->size <= 0) + goto packet_too_small; + pkt->data += AV_AAC_ADTS_HEADER_SIZE + 2 * !hdr.crc_absent; + + if (!ctx->first_frame_done) { + int pce_size = 0; + uint8_t pce_data[MAX_PCE_SIZE]; + uint8_t *extradata; + + if (!hdr.chan_config) { + init_get_bits(&gb, pkt->data, pkt->size * 8); + if (get_bits(&gb, 3) != 5) { + avpriv_report_missing_feature(bsfc, + "PCE-based channel configuration " + "without PCE as first syntax " + "element"); + ret = AVERROR_PATCHWELCOME; + goto fail; + } + init_put_bits(&pb, pce_data, MAX_PCE_SIZE); + pce_size = ff_copy_pce_data(&pb, &gb) / 8; + flush_put_bits(&pb); + pkt->size -= get_bits_count(&gb)/8; + pkt->data += get_bits_count(&gb)/8; + } + + extradata = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, + 2 + pce_size); + if (!extradata) { + ret = AVERROR(ENOMEM); + goto fail; + } + + init_put_bits(&pb, extradata, 2 + pce_size); + put_bits(&pb, 5, hdr.object_type); + put_bits(&pb, 4, hdr.sampling_index); + put_bits(&pb, 4, hdr.chan_config); + put_bits(&pb, 1, 0); //frame length - 1024 samples + put_bits(&pb, 1, 0); //does not depend on core coder + put_bits(&pb, 1, 0); //is not extension + flush_put_bits(&pb); + if (pce_size) { + memcpy(extradata + 2, pce_data, pce_size); + } + + ctx->first_frame_done = 1; + } + + return 0; + +packet_too_small: + av_log(bsfc, AV_LOG_ERROR, "Input packet too small\n"); + ret = AVERROR_INVALIDDATA; +fail: + av_packet_unref(pkt); + return ret; +} + +static int aac_adtstoasc_init(AVBSFContext *ctx) +{ + /* Validate the extradata if the stream is already MPEG-4 AudioSpecificConfig */ + if (ctx->par_in->extradata) { + MPEG4AudioConfig mp4ac; + int ret = avpriv_mpeg4audio_get_config(&mp4ac, ctx->par_in->extradata, + ctx->par_in->extradata_size * 8, 1); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error parsing AudioSpecificConfig extradata!\n"); + return ret; + } + } + + return 0; +} + +static const enum AVCodecID codec_ids[] = { + AV_CODEC_ID_AAC, AV_CODEC_ID_NONE, +}; + +const AVBitStreamFilter ff_aac_adtstoasc_bsf = { + .name = "aac_adtstoasc", + .priv_data_size = sizeof(AACBSFContext), + .init = aac_adtstoasc_init, + .filter = aac_adtstoasc_filter, + .codec_ids = codec_ids, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_defines.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_defines.h new file mode 100644 index 000000000..438d78a7a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_defines.h @@ -0,0 +1,116 @@ +/* + * AAC defines + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AAC_DEFINES_H +#define AVCODEC_AAC_DEFINES_H + +#ifndef USE_FIXED +#define USE_FIXED 0 +#endif + +#if USE_FIXED + +#include "libavutil/softfloat.h" + +#define FFT_FLOAT 0 +#define FFT_FIXED_32 1 + +#define AAC_RENAME(x) x ## _fixed +#define AAC_RENAME_32(x) x ## _fixed_32 +typedef int INTFLOAT; +typedef unsigned UINTFLOAT; ///< Equivalent to INTFLOAT, Used as temporal cast to avoid undefined sign overflow operations. +typedef int64_t INT64FLOAT; +typedef int16_t SHORTFLOAT; +typedef SoftFloat AAC_FLOAT; +typedef int AAC_SIGNE; +#define FIXR(a) ((int)((a) * 1 + 0.5)) +#define FIXR10(a) ((int)((a) * 1024.0 + 0.5)) +#define Q23(a) (int)((a) * 8388608.0 + 0.5) +#define Q30(x) (int)((x)*1073741824.0 + 0.5) +#define Q31(x) (int)((x)*2147483648.0 + 0.5) +#define RANGE15(x) x +#define GET_GAIN(x, y) (-(y) * (1 << (x))) + 1024 +#define AAC_MUL16(x, y) (int)(((int64_t)(x) * (y) + 0x8000) >> 16) +#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26) +#define AAC_MUL30(x, y) (int)(((int64_t)(x) * (y) + 0x20000000) >> 30) +#define AAC_MUL31(x, y) (int)(((int64_t)(x) * (y) + 0x40000000) >> 31) +#define AAC_MADD28(x, y, a, b) (int)((((int64_t)(x) * (y)) + \ + ((int64_t)(a) * (b)) + \ + 0x8000000) >> 28) +#define AAC_MADD30(x, y, a, b) (int)((((int64_t)(x) * (y)) + \ + ((int64_t)(a) * (b)) + \ + 0x20000000) >> 30) +#define AAC_MADD30_V8(x, y, a, b, c, d, e, f) (int)((((int64_t)(x) * (y)) + \ + ((int64_t)(a) * (b)) + \ + ((int64_t)(c) * (d)) + \ + ((int64_t)(e) * (f)) + \ + 0x20000000) >> 30) +#define AAC_MSUB30(x, y, a, b) (int)((((int64_t)(x) * (y)) - \ + ((int64_t)(a) * (b)) + \ + 0x20000000) >> 30) +#define AAC_MSUB30_V8(x, y, a, b, c, d, e, f) (int)((((int64_t)(x) * (y)) + \ + ((int64_t)(a) * (b)) - \ + ((int64_t)(c) * (d)) - \ + ((int64_t)(e) * (f)) + \ + 0x20000000) >> 30) +#define AAC_MSUB31_V3(x, y, z) (int)((((int64_t)(x) * (z)) - \ + ((int64_t)(y) * (z)) + \ + 0x40000000) >> 31) +#define AAC_HALF_SUM(x, y) (((x) >> 1) + ((y) >> 1)) +#define AAC_SRA_R(x, y) (int)(((x) + (1 << ((y) - 1))) >> (y)) + +#else + +#define FFT_FLOAT 1 +#define FFT_FIXED_32 0 + +#define AAC_RENAME(x) x +#define AAC_RENAME_32(x) x +typedef float INTFLOAT; +typedef float UINTFLOAT; +typedef float INT64FLOAT; +typedef float SHORTFLOAT; +typedef float AAC_FLOAT; +typedef unsigned AAC_SIGNE; +#define FIXR(x) ((float)(x)) +#define FIXR10(x) ((float)(x)) +#define Q23(x) ((float)(x)) +#define Q30(x) ((float)(x)) +#define Q31(x) ((float)(x)) +#define RANGE15(x) (32768.0 * (x)) +#define GET_GAIN(x, y) powf((x), -(y)) +#define AAC_MUL16(x, y) ((x) * (y)) +#define AAC_MUL26(x, y) ((x) * (y)) +#define AAC_MUL30(x, y) ((x) * (y)) +#define AAC_MUL31(x, y) ((x) * (y)) +#define AAC_MADD28(x, y, a, b) ((x) * (y) + (a) * (b)) +#define AAC_MADD30(x, y, a, b) ((x) * (y) + (a) * (b)) +#define AAC_MADD30_V8(x, y, a, b, c, d, e, f) ((x) * (y) + (a) * (b) + \ + (c) * (d) + (e) * (f)) +#define AAC_MSUB30(x, y, a, b) ((x) * (y) - (a) * (b)) +#define AAC_MSUB30_V8(x, y, a, b, c, d, e, f) ((x) * (y) + (a) * (b) - \ + (c) * (d) - (e) * (f)) +#define AAC_MSUB31_V3(x, y, z) ((x) - (y)) * (z) +#define AAC_HALF_SUM(x, y) ((x) + (y)) * 0.5f +#define AAC_SRA_R(x, y) (x) + +#endif /* USE_FIXED */ + +#endif /* AVCODEC_AAC_DEFINES_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_parser.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_parser.c new file mode 100644 index 000000000..b8692625f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aac_parser.c @@ -0,0 +1,71 @@ +/* + * Audio and Video frame extraction + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "parser.h" +#include "aac_ac3_parser.h" +#include "adts_header.h" +#include "adts_parser.h" +#include "get_bits.h" +#include "mpeg4audio.h" + +static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info, + int *need_next_header, int *new_frame_start) +{ + GetBitContext bits; + AACADTSHeaderInfo hdr; + int size; + union { + uint64_t u64; + uint8_t u8[8 + AV_INPUT_BUFFER_PADDING_SIZE]; + } tmp; + + tmp.u64 = av_be2ne64(state); + init_get_bits(&bits, tmp.u8 + 8 - AV_AAC_ADTS_HEADER_SIZE, + AV_AAC_ADTS_HEADER_SIZE * 8); + + if ((size = ff_adts_header_parse(&bits, &hdr)) < 0) + return 0; + *need_next_header = 0; + *new_frame_start = 1; + hdr_info->sample_rate = hdr.sample_rate; + hdr_info->channels = ff_mpeg4audio_channels[hdr.chan_config]; + hdr_info->samples = hdr.samples; + hdr_info->bit_rate = hdr.bit_rate; + return size; +} + +static av_cold int aac_parse_init(AVCodecParserContext *s1) +{ + AACAC3ParseContext *s = s1->priv_data; + s->header_size = AV_AAC_ADTS_HEADER_SIZE; + s->sync = aac_sync; + return 0; +} + + +AVCodecParser ff_aac_parser = { + .codec_ids = { AV_CODEC_ID_AAC }, + .priv_data_size = sizeof(AACAC3ParseContext), + .parser_init = aac_parse_init, + .parser_parse = ff_aac_ac3_parse, + .parser_close = ff_parse_close, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder.c new file mode 100644 index 000000000..baa82489b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder.c @@ -0,0 +1,964 @@ +/* + * AAC coefficients encoder + * Copyright (C) 2008-2009 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC coefficients encoder + */ + +/*********************************** + * TODOs: + * speedup quantizer selection + * add sane pulse detection + ***********************************/ + +#include "libavutil/libm.h" // brought forward to work around cygwin header breakage + +#include + +#include "libavutil/mathematics.h" +#include "mathops.h" +#include "avcodec.h" +#include "put_bits.h" +#include "aac.h" +#include "aacenc.h" +#include "aactab.h" +#include "aacenctab.h" +#include "aacenc_utils.h" +#include "aacenc_quantization.h" + +#include "aacenc_is.h" +#include "aacenc_tns.h" +#include "aacenc_ltp.h" +#include "aacenc_pred.h" + +#include "libavcodec/aaccoder_twoloop.h" + +/* Parameter of f(x) = a*(lambda/100), defines the maximum fourier spread + * beyond which no PNS is used (since the SFBs contain tone rather than noise) */ +#define NOISE_SPREAD_THRESHOLD 0.9f + +/* Parameter of f(x) = a*(100/lambda), defines how much PNS is allowed to + * replace low energy non zero bands */ +#define NOISE_LAMBDA_REPLACE 1.948f + +#include "libavcodec/aaccoder_trellis.h" + +/** + * structure used in optimal codebook search + */ +typedef struct BandCodingPath { + int prev_idx; ///< pointer to the previous path point + float cost; ///< path cost + int run; +} BandCodingPath; + +/** + * Encode band info for single window group bands. + */ +static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce, + int win, int group_len, const float lambda) +{ + BandCodingPath path[120][CB_TOT_ALL]; + int w, swb, cb, start, size; + int i, j; + const int max_sfb = sce->ics.max_sfb; + const int run_bits = sce->ics.num_windows == 1 ? 5 : 3; + const int run_esc = (1 << run_bits) - 1; + int idx, ppos, count; + int stackrun[120], stackcb[120], stack_len; + float next_minrd = INFINITY; + int next_mincb = 0; + + s->abs_pow34(s->scoefs, sce->coeffs, 1024); + start = win*128; + for (cb = 0; cb < CB_TOT_ALL; cb++) { + path[0][cb].cost = 0.0f; + path[0][cb].prev_idx = -1; + path[0][cb].run = 0; + } + for (swb = 0; swb < max_sfb; swb++) { + size = sce->ics.swb_sizes[swb]; + if (sce->zeroes[win*16 + swb]) { + for (cb = 0; cb < CB_TOT_ALL; cb++) { + path[swb+1][cb].prev_idx = cb; + path[swb+1][cb].cost = path[swb][cb].cost; + path[swb+1][cb].run = path[swb][cb].run + 1; + } + } else { + float minrd = next_minrd; + int mincb = next_mincb; + next_minrd = INFINITY; + next_mincb = 0; + for (cb = 0; cb < CB_TOT_ALL; cb++) { + float cost_stay_here, cost_get_here; + float rd = 0.0f; + if (cb >= 12 && sce->band_type[win*16+swb] < aac_cb_out_map[cb] || + cb < aac_cb_in_map[sce->band_type[win*16+swb]] && sce->band_type[win*16+swb] > aac_cb_out_map[cb]) { + path[swb+1][cb].prev_idx = -1; + path[swb+1][cb].cost = INFINITY; + path[swb+1][cb].run = path[swb][cb].run + 1; + continue; + } + for (w = 0; w < group_len; w++) { + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(win+w)*16+swb]; + rd += quantize_band_cost(s, &sce->coeffs[start + w*128], + &s->scoefs[start + w*128], size, + sce->sf_idx[(win+w)*16+swb], aac_cb_out_map[cb], + lambda / band->threshold, INFINITY, NULL, NULL, 0); + } + cost_stay_here = path[swb][cb].cost + rd; + cost_get_here = minrd + rd + run_bits + 4; + if ( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run] + != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1]) + cost_stay_here += run_bits; + if (cost_get_here < cost_stay_here) { + path[swb+1][cb].prev_idx = mincb; + path[swb+1][cb].cost = cost_get_here; + path[swb+1][cb].run = 1; + } else { + path[swb+1][cb].prev_idx = cb; + path[swb+1][cb].cost = cost_stay_here; + path[swb+1][cb].run = path[swb][cb].run + 1; + } + if (path[swb+1][cb].cost < next_minrd) { + next_minrd = path[swb+1][cb].cost; + next_mincb = cb; + } + } + } + start += sce->ics.swb_sizes[swb]; + } + + //convert resulting path from backward-linked list + stack_len = 0; + idx = 0; + for (cb = 1; cb < CB_TOT_ALL; cb++) + if (path[max_sfb][cb].cost < path[max_sfb][idx].cost) + idx = cb; + ppos = max_sfb; + while (ppos > 0) { + av_assert1(idx >= 0); + cb = idx; + stackrun[stack_len] = path[ppos][cb].run; + stackcb [stack_len] = cb; + idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx; + ppos -= path[ppos][cb].run; + stack_len++; + } + //perform actual band info encoding + start = 0; + for (i = stack_len - 1; i >= 0; i--) { + cb = aac_cb_out_map[stackcb[i]]; + put_bits(&s->pb, 4, cb); + count = stackrun[i]; + memset(sce->zeroes + win*16 + start, !cb, count); + //XXX: memset when band_type is also uint8_t + for (j = 0; j < count; j++) { + sce->band_type[win*16 + start] = cb; + start++; + } + while (count >= run_esc) { + put_bits(&s->pb, run_bits, run_esc); + count -= run_esc; + } + put_bits(&s->pb, run_bits, count); + } +} + + +typedef struct TrellisPath { + float cost; + int prev; +} TrellisPath; + +#define TRELLIS_STAGES 121 +#define TRELLIS_STATES (SCALE_MAX_DIFF+1) + +static void set_special_band_scalefactors(AACEncContext *s, SingleChannelElement *sce) +{ + int w, g; + int prevscaler_n = -255, prevscaler_i = 0; + int bands = 0; + + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = 0; g < sce->ics.num_swb; g++) { + if (sce->zeroes[w*16+g]) + continue; + if (sce->band_type[w*16+g] == INTENSITY_BT || sce->band_type[w*16+g] == INTENSITY_BT2) { + sce->sf_idx[w*16+g] = av_clip(roundf(log2f(sce->is_ener[w*16+g])*2), -155, 100); + bands++; + } else if (sce->band_type[w*16+g] == NOISE_BT) { + sce->sf_idx[w*16+g] = av_clip(3+ceilf(log2f(sce->pns_ener[w*16+g])*2), -100, 155); + if (prevscaler_n == -255) + prevscaler_n = sce->sf_idx[w*16+g]; + bands++; + } + } + } + + if (!bands) + return; + + /* Clip the scalefactor indices */ + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = 0; g < sce->ics.num_swb; g++) { + if (sce->zeroes[w*16+g]) + continue; + if (sce->band_type[w*16+g] == INTENSITY_BT || sce->band_type[w*16+g] == INTENSITY_BT2) { + sce->sf_idx[w*16+g] = prevscaler_i = av_clip(sce->sf_idx[w*16+g], prevscaler_i - SCALE_MAX_DIFF, prevscaler_i + SCALE_MAX_DIFF); + } else if (sce->band_type[w*16+g] == NOISE_BT) { + sce->sf_idx[w*16+g] = prevscaler_n = av_clip(sce->sf_idx[w*16+g], prevscaler_n - SCALE_MAX_DIFF, prevscaler_n + SCALE_MAX_DIFF); + } + } + } +} + +static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s, + SingleChannelElement *sce, + const float lambda) +{ + int q, w, w2, g, start = 0; + int i, j; + int idx; + TrellisPath paths[TRELLIS_STAGES][TRELLIS_STATES]; + int bandaddr[TRELLIS_STAGES]; + int minq; + float mincost; + float q0f = FLT_MAX, q1f = 0.0f, qnrgf = 0.0f; + int q0, q1, qcnt = 0; + + for (i = 0; i < 1024; i++) { + float t = fabsf(sce->coeffs[i]); + if (t > 0.0f) { + q0f = FFMIN(q0f, t); + q1f = FFMAX(q1f, t); + qnrgf += t*t; + qcnt++; + } + } + + if (!qcnt) { + memset(sce->sf_idx, 0, sizeof(sce->sf_idx)); + memset(sce->zeroes, 1, sizeof(sce->zeroes)); + return; + } + + //minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped + q0 = av_clip(coef2minsf(q0f), 0, SCALE_MAX_POS-1); + //maximum scalefactor index is when maximum coefficient after quantizing is still not zero + q1 = av_clip(coef2maxsf(q1f), 1, SCALE_MAX_POS); + if (q1 - q0 > 60) { + int q0low = q0; + int q1high = q1; + //minimum scalefactor index is when maximum nonzero coefficient after quantizing is not clipped + int qnrg = av_clip_uint8(log2f(sqrtf(qnrgf/qcnt))*4 - 31 + SCALE_ONE_POS - SCALE_DIV_512); + q1 = qnrg + 30; + q0 = qnrg - 30; + if (q0 < q0low) { + q1 += q0low - q0; + q0 = q0low; + } else if (q1 > q1high) { + q0 -= q1 - q1high; + q1 = q1high; + } + } + // q0 == q1 isn't really a legal situation + if (q0 == q1) { + // the following is indirect but guarantees q1 != q0 && q1 near q0 + q1 = av_clip(q0+1, 1, SCALE_MAX_POS); + q0 = av_clip(q1-1, 0, SCALE_MAX_POS - 1); + } + + for (i = 0; i < TRELLIS_STATES; i++) { + paths[0][i].cost = 0.0f; + paths[0][i].prev = -1; + } + for (j = 1; j < TRELLIS_STAGES; j++) { + for (i = 0; i < TRELLIS_STATES; i++) { + paths[j][i].cost = INFINITY; + paths[j][i].prev = -2; + } + } + idx = 1; + s->abs_pow34(s->scoefs, sce->coeffs, 1024); + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = w*128; + for (g = 0; g < sce->ics.num_swb; g++) { + const float *coefs = &sce->coeffs[start]; + float qmin, qmax; + int nz = 0; + + bandaddr[idx] = w * 16 + g; + qmin = INT_MAX; + qmax = 0.0f; + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; + if (band->energy <= band->threshold || band->threshold == 0.0f) { + sce->zeroes[(w+w2)*16+g] = 1; + continue; + } + sce->zeroes[(w+w2)*16+g] = 0; + nz = 1; + for (i = 0; i < sce->ics.swb_sizes[g]; i++) { + float t = fabsf(coefs[w2*128+i]); + if (t > 0.0f) + qmin = FFMIN(qmin, t); + qmax = FFMAX(qmax, t); + } + } + if (nz) { + int minscale, maxscale; + float minrd = INFINITY; + float maxval; + //minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped + minscale = coef2minsf(qmin); + //maximum scalefactor index is when maximum coefficient after quantizing is still not zero + maxscale = coef2maxsf(qmax); + minscale = av_clip(minscale - q0, 0, TRELLIS_STATES - 1); + maxscale = av_clip(maxscale - q0, 0, TRELLIS_STATES); + if (minscale == maxscale) { + maxscale = av_clip(minscale+1, 1, TRELLIS_STATES); + minscale = av_clip(maxscale-1, 0, TRELLIS_STATES - 1); + } + maxval = find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], s->scoefs+start); + for (q = minscale; q < maxscale; q++) { + float dist = 0; + int cb = find_min_book(maxval, sce->sf_idx[w*16+g]); + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; + dist += quantize_band_cost(s, coefs + w2*128, s->scoefs + start + w2*128, sce->ics.swb_sizes[g], + q + q0, cb, lambda / band->threshold, INFINITY, NULL, NULL, 0); + } + minrd = FFMIN(minrd, dist); + + for (i = 0; i < q1 - q0; i++) { + float cost; + cost = paths[idx - 1][i].cost + dist + + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO]; + if (cost < paths[idx][q].cost) { + paths[idx][q].cost = cost; + paths[idx][q].prev = i; + } + } + } + } else { + for (q = 0; q < q1 - q0; q++) { + paths[idx][q].cost = paths[idx - 1][q].cost + 1; + paths[idx][q].prev = q; + } + } + sce->zeroes[w*16+g] = !nz; + start += sce->ics.swb_sizes[g]; + idx++; + } + } + idx--; + mincost = paths[idx][0].cost; + minq = 0; + for (i = 1; i < TRELLIS_STATES; i++) { + if (paths[idx][i].cost < mincost) { + mincost = paths[idx][i].cost; + minq = i; + } + } + while (idx) { + sce->sf_idx[bandaddr[idx]] = minq + q0; + minq = FFMAX(paths[idx][minq].prev, 0); + idx--; + } + //set the same quantizers inside window groups + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) + for (g = 0; g < sce->ics.num_swb; g++) + for (w2 = 1; w2 < sce->ics.group_len[w]; w2++) + sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g]; +} + +static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s, + SingleChannelElement *sce, + const float lambda) +{ + int start = 0, i, w, w2, g; + int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f); + float dists[128] = { 0 }, uplims[128] = { 0 }; + float maxvals[128]; + int fflag, minscaler; + int its = 0; + int allz = 0; + float minthr = INFINITY; + + // for values above this the decoder might end up in an endless loop + // due to always having more bits than what can be encoded. + destbits = FFMIN(destbits, 5800); + //some heuristic to determine initial quantizers will reduce search time + //determine zero bands and upper limits + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = 0; + for (g = 0; g < sce->ics.num_swb; g++) { + int nz = 0; + float uplim = 0.0f, energy = 0.0f; + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; + uplim += band->threshold; + energy += band->energy; + if (band->energy <= band->threshold || band->threshold == 0.0f) { + sce->zeroes[(w+w2)*16+g] = 1; + continue; + } + nz = 1; + } + uplims[w*16+g] = uplim *512; + sce->band_type[w*16+g] = 0; + sce->zeroes[w*16+g] = !nz; + if (nz) + minthr = FFMIN(minthr, uplim); + allz |= nz; + start += sce->ics.swb_sizes[g]; + } + } + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = 0; g < sce->ics.num_swb; g++) { + if (sce->zeroes[w*16+g]) { + sce->sf_idx[w*16+g] = SCALE_ONE_POS; + continue; + } + sce->sf_idx[w*16+g] = SCALE_ONE_POS + FFMIN(log2f(uplims[w*16+g]/minthr)*4,59); + } + } + + if (!allz) + return; + s->abs_pow34(s->scoefs, sce->coeffs, 1024); + ff_quantize_band_cost_cache_init(s); + + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = w*128; + for (g = 0; g < sce->ics.num_swb; g++) { + const float *scaled = s->scoefs + start; + maxvals[w*16+g] = find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], scaled); + start += sce->ics.swb_sizes[g]; + } + } + + //perform two-loop search + //outer loop - improve quality + do { + int tbits, qstep; + minscaler = sce->sf_idx[0]; + //inner loop - quantize spectrum to fit into given number of bits + qstep = its ? 1 : 32; + do { + int prev = -1; + tbits = 0; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = w*128; + for (g = 0; g < sce->ics.num_swb; g++) { + const float *coefs = sce->coeffs + start; + const float *scaled = s->scoefs + start; + int bits = 0; + int cb; + float dist = 0.0f; + + if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) { + start += sce->ics.swb_sizes[g]; + continue; + } + minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]); + cb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + int b; + dist += quantize_band_cost_cached(s, w + w2, g, + coefs + w2*128, + scaled + w2*128, + sce->ics.swb_sizes[g], + sce->sf_idx[w*16+g], + cb, 1.0f, INFINITY, + &b, NULL, 0); + bits += b; + } + dists[w*16+g] = dist - bits; + if (prev != -1) { + bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO]; + } + tbits += bits; + start += sce->ics.swb_sizes[g]; + prev = sce->sf_idx[w*16+g]; + } + } + if (tbits > destbits) { + for (i = 0; i < 128; i++) + if (sce->sf_idx[i] < 218 - qstep) + sce->sf_idx[i] += qstep; + } else { + for (i = 0; i < 128; i++) + if (sce->sf_idx[i] > 60 - qstep) + sce->sf_idx[i] -= qstep; + } + qstep >>= 1; + if (!qstep && tbits > destbits*1.02 && sce->sf_idx[0] < 217) + qstep = 1; + } while (qstep); + + fflag = 0; + minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF); + + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = 0; g < sce->ics.num_swb; g++) { + int prevsc = sce->sf_idx[w*16+g]; + if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60) { + if (find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1)) + sce->sf_idx[w*16+g]--; + else //Try to make sure there is some energy in every band + sce->sf_idx[w*16+g]-=2; + } + sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF); + sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219); + if (sce->sf_idx[w*16+g] != prevsc) + fflag = 1; + sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); + } + } + its++; + } while (fflag && its < 10); +} + +static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce) +{ + FFPsyBand *band; + int w, g, w2, i; + int wlen = 1024 / sce->ics.num_windows; + int bandwidth, cutoff; + float *PNS = &s->scoefs[0*128], *PNS34 = &s->scoefs[1*128]; + float *NOR34 = &s->scoefs[3*128]; + uint8_t nextband[128]; + const float lambda = s->lambda; + const float freq_mult = avctx->sample_rate*0.5f/wlen; + const float thr_mult = NOISE_LAMBDA_REPLACE*(100.0f/lambda); + const float spread_threshold = FFMIN(0.75f, NOISE_SPREAD_THRESHOLD*FFMAX(0.5f, lambda/100.f)); + const float dist_bias = av_clipf(4.f * 120 / lambda, 0.25f, 4.0f); + const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f); + + int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate + / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) + * (lambda / 120.f); + + /** Keep this in sync with twoloop's cutoff selection */ + float rate_bandwidth_multiplier = 1.5f; + int prev = -1000, prev_sf = -1; + int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE) + ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) + : (avctx->bit_rate / avctx->channels); + + frame_bit_rate *= 1.15f; + + if (avctx->cutoff > 0) { + bandwidth = avctx->cutoff; + } else { + bandwidth = FFMAX(3000, AAC_CUTOFF_FROM_BITRATE(frame_bit_rate, 1, avctx->sample_rate)); + } + + cutoff = bandwidth * 2 * wlen / avctx->sample_rate; + + memcpy(sce->band_alt, sce->band_type, sizeof(sce->band_type)); + ff_init_nextband_map(sce, nextband); + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + int wstart = w*128; + for (g = 0; g < sce->ics.num_swb; g++) { + int noise_sfi; + float dist1 = 0.0f, dist2 = 0.0f, noise_amp; + float pns_energy = 0.0f, pns_tgt_energy, energy_ratio, dist_thresh; + float sfb_energy = 0.0f, threshold = 0.0f, spread = 2.0f; + float min_energy = -1.0f, max_energy = 0.0f; + const int start = wstart+sce->ics.swb_offset[g]; + const float freq = (start-wstart)*freq_mult; + const float freq_boost = FFMAX(0.88f*freq/NOISE_LOW_LIMIT, 1.0f); + if (freq < NOISE_LOW_LIMIT || (start-wstart) >= cutoff) { + if (!sce->zeroes[w*16+g]) + prev_sf = sce->sf_idx[w*16+g]; + continue; + } + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; + sfb_energy += band->energy; + spread = FFMIN(spread, band->spread); + threshold += band->threshold; + if (!w2) { + min_energy = max_energy = band->energy; + } else { + min_energy = FFMIN(min_energy, band->energy); + max_energy = FFMAX(max_energy, band->energy); + } + } + + /* Ramps down at ~8000Hz and loosens the dist threshold */ + dist_thresh = av_clipf(2.5f*NOISE_LOW_LIMIT/freq, 0.5f, 2.5f) * dist_bias; + + /* PNS is acceptable when all of these are true: + * 1. high spread energy (noise-like band) + * 2. near-threshold energy (high PE means the random nature of PNS content will be noticed) + * 3. on short window groups, all windows have similar energy (variations in energy would be destroyed by PNS) + * + * At this stage, point 2 is relaxed for zeroed bands near the noise threshold (hole avoidance is more important) + */ + if ((!sce->zeroes[w*16+g] && !ff_sfdelta_can_remove_band(sce, nextband, prev_sf, w*16+g)) || + ((sce->zeroes[w*16+g] || !sce->band_alt[w*16+g]) && sfb_energy < threshold*sqrtf(1.0f/freq_boost)) || spread < spread_threshold || + (!sce->zeroes[w*16+g] && sce->band_alt[w*16+g] && sfb_energy > threshold*thr_mult*freq_boost) || + min_energy < pns_transient_energy_r * max_energy ) { + sce->pns_ener[w*16+g] = sfb_energy; + if (!sce->zeroes[w*16+g]) + prev_sf = sce->sf_idx[w*16+g]; + continue; + } + + pns_tgt_energy = sfb_energy*FFMIN(1.0f, spread*spread); + noise_sfi = av_clip(roundf(log2f(pns_tgt_energy)*2), -100, 155); /* Quantize */ + noise_amp = -ff_aac_pow2sf_tab[noise_sfi + POW_SF2_ZERO]; /* Dequantize */ + if (prev != -1000) { + int noise_sfdiff = noise_sfi - prev + SCALE_DIFF_ZERO; + if (noise_sfdiff < 0 || noise_sfdiff > 2*SCALE_MAX_DIFF) { + if (!sce->zeroes[w*16+g]) + prev_sf = sce->sf_idx[w*16+g]; + continue; + } + } + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + float band_energy, scale, pns_senergy; + const int start_c = (w+w2)*128+sce->ics.swb_offset[g]; + band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; + for (i = 0; i < sce->ics.swb_sizes[g]; i++) { + s->random_state = lcg_random(s->random_state); + PNS[i] = s->random_state; + } + band_energy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]); + scale = noise_amp/sqrtf(band_energy); + s->fdsp->vector_fmul_scalar(PNS, PNS, scale, sce->ics.swb_sizes[g]); + pns_senergy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]); + pns_energy += pns_senergy; + s->abs_pow34(NOR34, &sce->coeffs[start_c], sce->ics.swb_sizes[g]); + s->abs_pow34(PNS34, PNS, sce->ics.swb_sizes[g]); + dist1 += quantize_band_cost(s, &sce->coeffs[start_c], + NOR34, + sce->ics.swb_sizes[g], + sce->sf_idx[(w+w2)*16+g], + sce->band_alt[(w+w2)*16+g], + lambda/band->threshold, INFINITY, NULL, NULL, 0); + /* Estimate rd on average as 5 bits for SF, 4 for the CB, plus spread energy * lambda/thr */ + dist2 += band->energy/(band->spread*band->spread)*lambda*dist_thresh/band->threshold; + } + if (g && sce->band_type[w*16+g-1] == NOISE_BT) { + dist2 += 5; + } else { + dist2 += 9; + } + energy_ratio = pns_tgt_energy/pns_energy; /* Compensates for quantization error */ + sce->pns_ener[w*16+g] = energy_ratio*pns_tgt_energy; + if (sce->zeroes[w*16+g] || !sce->band_alt[w*16+g] || (energy_ratio > 0.85f && energy_ratio < 1.25f && dist2 < dist1)) { + sce->band_type[w*16+g] = NOISE_BT; + sce->zeroes[w*16+g] = 0; + prev = noise_sfi; + } else { + if (!sce->zeroes[w*16+g]) + prev_sf = sce->sf_idx[w*16+g]; + } + } + } +} + +static void mark_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce) +{ + FFPsyBand *band; + int w, g, w2; + int wlen = 1024 / sce->ics.num_windows; + int bandwidth, cutoff; + const float lambda = s->lambda; + const float freq_mult = avctx->sample_rate*0.5f/wlen; + const float spread_threshold = FFMIN(0.75f, NOISE_SPREAD_THRESHOLD*FFMAX(0.5f, lambda/100.f)); + const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f); + + int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate + / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) + * (lambda / 120.f); + + /** Keep this in sync with twoloop's cutoff selection */ + float rate_bandwidth_multiplier = 1.5f; + int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE) + ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) + : (avctx->bit_rate / avctx->channels); + + frame_bit_rate *= 1.15f; + + if (avctx->cutoff > 0) { + bandwidth = avctx->cutoff; + } else { + bandwidth = FFMAX(3000, AAC_CUTOFF_FROM_BITRATE(frame_bit_rate, 1, avctx->sample_rate)); + } + + cutoff = bandwidth * 2 * wlen / avctx->sample_rate; + + memcpy(sce->band_alt, sce->band_type, sizeof(sce->band_type)); + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = 0; g < sce->ics.num_swb; g++) { + float sfb_energy = 0.0f, threshold = 0.0f, spread = 2.0f; + float min_energy = -1.0f, max_energy = 0.0f; + const int start = sce->ics.swb_offset[g]; + const float freq = start*freq_mult; + const float freq_boost = FFMAX(0.88f*freq/NOISE_LOW_LIMIT, 1.0f); + if (freq < NOISE_LOW_LIMIT || start >= cutoff) { + sce->can_pns[w*16+g] = 0; + continue; + } + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; + sfb_energy += band->energy; + spread = FFMIN(spread, band->spread); + threshold += band->threshold; + if (!w2) { + min_energy = max_energy = band->energy; + } else { + min_energy = FFMIN(min_energy, band->energy); + max_energy = FFMAX(max_energy, band->energy); + } + } + + /* PNS is acceptable when all of these are true: + * 1. high spread energy (noise-like band) + * 2. near-threshold energy (high PE means the random nature of PNS content will be noticed) + * 3. on short window groups, all windows have similar energy (variations in energy would be destroyed by PNS) + */ + sce->pns_ener[w*16+g] = sfb_energy; + if (sfb_energy < threshold*sqrtf(1.5f/freq_boost) || spread < spread_threshold || min_energy < pns_transient_energy_r * max_energy) { + sce->can_pns[w*16+g] = 0; + } else { + sce->can_pns[w*16+g] = 1; + } + } + } +} + +static void search_for_ms(AACEncContext *s, ChannelElement *cpe) +{ + int start = 0, i, w, w2, g, sid_sf_boost, prev_mid, prev_side; + uint8_t nextband0[128], nextband1[128]; + float *M = s->scoefs + 128*0, *S = s->scoefs + 128*1; + float *L34 = s->scoefs + 128*2, *R34 = s->scoefs + 128*3; + float *M34 = s->scoefs + 128*4, *S34 = s->scoefs + 128*5; + const float lambda = s->lambda; + const float mslambda = FFMIN(1.0f, lambda / 120.f); + SingleChannelElement *sce0 = &cpe->ch[0]; + SingleChannelElement *sce1 = &cpe->ch[1]; + if (!cpe->common_window) + return; + + /** Scout out next nonzero bands */ + ff_init_nextband_map(sce0, nextband0); + ff_init_nextband_map(sce1, nextband1); + + prev_mid = sce0->sf_idx[0]; + prev_side = sce1->sf_idx[0]; + for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) { + start = 0; + for (g = 0; g < sce0->ics.num_swb; g++) { + float bmax = bval2bmax(g * 17.0f / sce0->ics.num_swb) / 0.0045f; + if (!cpe->is_mask[w*16+g]) + cpe->ms_mask[w*16+g] = 0; + if (!sce0->zeroes[w*16+g] && !sce1->zeroes[w*16+g] && !cpe->is_mask[w*16+g]) { + float Mmax = 0.0f, Smax = 0.0f; + + /* Must compute mid/side SF and book for the whole window group */ + for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { + for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { + M[i] = (sce0->coeffs[start+(w+w2)*128+i] + + sce1->coeffs[start+(w+w2)*128+i]) * 0.5; + S[i] = M[i] + - sce1->coeffs[start+(w+w2)*128+i]; + } + s->abs_pow34(M34, M, sce0->ics.swb_sizes[g]); + s->abs_pow34(S34, S, sce0->ics.swb_sizes[g]); + for (i = 0; i < sce0->ics.swb_sizes[g]; i++ ) { + Mmax = FFMAX(Mmax, M34[i]); + Smax = FFMAX(Smax, S34[i]); + } + } + + for (sid_sf_boost = 0; sid_sf_boost < 4; sid_sf_boost++) { + float dist1 = 0.0f, dist2 = 0.0f; + int B0 = 0, B1 = 0; + int minidx; + int mididx, sididx; + int midcb, sidcb; + + minidx = FFMIN(sce0->sf_idx[w*16+g], sce1->sf_idx[w*16+g]); + mididx = av_clip(minidx, 0, SCALE_MAX_POS - SCALE_DIV_512); + sididx = av_clip(minidx - sid_sf_boost * 3, 0, SCALE_MAX_POS - SCALE_DIV_512); + if (sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT + && ( !ff_sfdelta_can_replace(sce0, nextband0, prev_mid, mididx, w*16+g) + || !ff_sfdelta_can_replace(sce1, nextband1, prev_side, sididx, w*16+g))) { + /* scalefactor range violation, bad stuff, will decrease quality unacceptably */ + continue; + } + + midcb = find_min_book(Mmax, mididx); + sidcb = find_min_book(Smax, sididx); + + /* No CB can be zero */ + midcb = FFMAX(1,midcb); + sidcb = FFMAX(1,sidcb); + + for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { + FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g]; + FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g]; + float minthr = FFMIN(band0->threshold, band1->threshold); + int b1,b2,b3,b4; + for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { + M[i] = (sce0->coeffs[start+(w+w2)*128+i] + + sce1->coeffs[start+(w+w2)*128+i]) * 0.5; + S[i] = M[i] + - sce1->coeffs[start+(w+w2)*128+i]; + } + + s->abs_pow34(L34, sce0->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); + s->abs_pow34(R34, sce1->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); + s->abs_pow34(M34, M, sce0->ics.swb_sizes[g]); + s->abs_pow34(S34, S, sce0->ics.swb_sizes[g]); + dist1 += quantize_band_cost(s, &sce0->coeffs[start + (w+w2)*128], + L34, + sce0->ics.swb_sizes[g], + sce0->sf_idx[w*16+g], + sce0->band_type[w*16+g], + lambda / band0->threshold, INFINITY, &b1, NULL, 0); + dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128], + R34, + sce1->ics.swb_sizes[g], + sce1->sf_idx[w*16+g], + sce1->band_type[w*16+g], + lambda / band1->threshold, INFINITY, &b2, NULL, 0); + dist2 += quantize_band_cost(s, M, + M34, + sce0->ics.swb_sizes[g], + mididx, + midcb, + lambda / minthr, INFINITY, &b3, NULL, 0); + dist2 += quantize_band_cost(s, S, + S34, + sce1->ics.swb_sizes[g], + sididx, + sidcb, + mslambda / (minthr * bmax), INFINITY, &b4, NULL, 0); + B0 += b1+b2; + B1 += b3+b4; + dist1 -= b1+b2; + dist2 -= b3+b4; + } + cpe->ms_mask[w*16+g] = dist2 <= dist1 && B1 < B0; + if (cpe->ms_mask[w*16+g]) { + if (sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT) { + sce0->sf_idx[w*16+g] = mididx; + sce1->sf_idx[w*16+g] = sididx; + sce0->band_type[w*16+g] = midcb; + sce1->band_type[w*16+g] = sidcb; + } else if ((sce0->band_type[w*16+g] != NOISE_BT) ^ (sce1->band_type[w*16+g] != NOISE_BT)) { + /* ms_mask unneeded, and it confuses some decoders */ + cpe->ms_mask[w*16+g] = 0; + } + break; + } else if (B1 > B0) { + /* More boost won't fix this */ + break; + } + } + } + if (!sce0->zeroes[w*16+g] && sce0->band_type[w*16+g] < RESERVED_BT) + prev_mid = sce0->sf_idx[w*16+g]; + if (!sce1->zeroes[w*16+g] && !cpe->is_mask[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT) + prev_side = sce1->sf_idx[w*16+g]; + start += sce0->ics.swb_sizes[g]; + } + } +} + +const AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { + [AAC_CODER_ANMR] = { + search_for_quantizers_anmr, + encode_window_bands_info, + quantize_and_encode_band, + ff_aac_encode_tns_info, + ff_aac_encode_ltp_info, + ff_aac_encode_main_pred, + ff_aac_adjust_common_pred, + ff_aac_adjust_common_ltp, + ff_aac_apply_main_pred, + ff_aac_apply_tns, + ff_aac_update_ltp, + ff_aac_ltp_insert_new_frame, + set_special_band_scalefactors, + search_for_pns, + mark_pns, + ff_aac_search_for_tns, + ff_aac_search_for_ltp, + search_for_ms, + ff_aac_search_for_is, + ff_aac_search_for_pred, + }, + [AAC_CODER_TWOLOOP] = { + search_for_quantizers_twoloop, + codebook_trellis_rate, + quantize_and_encode_band, + ff_aac_encode_tns_info, + ff_aac_encode_ltp_info, + ff_aac_encode_main_pred, + ff_aac_adjust_common_pred, + ff_aac_adjust_common_ltp, + ff_aac_apply_main_pred, + ff_aac_apply_tns, + ff_aac_update_ltp, + ff_aac_ltp_insert_new_frame, + set_special_band_scalefactors, + search_for_pns, + mark_pns, + ff_aac_search_for_tns, + ff_aac_search_for_ltp, + search_for_ms, + ff_aac_search_for_is, + ff_aac_search_for_pred, + }, + [AAC_CODER_FAST] = { + search_for_quantizers_fast, + codebook_trellis_rate, + quantize_and_encode_band, + ff_aac_encode_tns_info, + ff_aac_encode_ltp_info, + ff_aac_encode_main_pred, + ff_aac_adjust_common_pred, + ff_aac_adjust_common_ltp, + ff_aac_apply_main_pred, + ff_aac_apply_tns, + ff_aac_update_ltp, + ff_aac_ltp_insert_new_frame, + set_special_band_scalefactors, + search_for_pns, + mark_pns, + ff_aac_search_for_tns, + ff_aac_search_for_ltp, + search_for_ms, + ff_aac_search_for_is, + ff_aac_search_for_pred, + }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder_trellis.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder_trellis.h new file mode 100644 index 000000000..940ebf029 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder_trellis.h @@ -0,0 +1,192 @@ +/* + * AAC encoder trellis codebook selector + * Copyright (C) 2008-2009 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder trellis codebook selector + * @author Konstantin Shishkov + */ + +/** + * This file contains a template for the codebook_trellis_rate selector function. + * It needs to be provided, externally, as an already included declaration, + * the following functions from aacenc_quantization/util.h. They're not included + * explicitly here to make it possible to provide alternative implementations: + * - quantize_band_cost_bits + * - abs_pow34_v + */ + +#ifndef AVCODEC_AACCODER_TRELLIS_H +#define AVCODEC_AACCODER_TRELLIS_H + +#include +#include "libavutil/mathematics.h" +#include "avcodec.h" +#include "put_bits.h" +#include "aac.h" +#include "aacenc.h" +#include "aactab.h" +#include "aacenctab.h" + +/** + * structure used in optimal codebook search + */ +typedef struct TrellisBandCodingPath { + int prev_idx; ///< pointer to the previous path point + float cost; ///< path cost + int run; +} TrellisBandCodingPath; + + +static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce, + int win, int group_len, const float lambda) +{ + TrellisBandCodingPath path[120][CB_TOT_ALL]; + int w, swb, cb, start, size; + int i, j; + const int max_sfb = sce->ics.max_sfb; + const int run_bits = sce->ics.num_windows == 1 ? 5 : 3; + const int run_esc = (1 << run_bits) - 1; + int idx, ppos, count; + int stackrun[120], stackcb[120], stack_len; + float next_minbits = INFINITY; + int next_mincb = 0; + + s->abs_pow34(s->scoefs, sce->coeffs, 1024); + start = win*128; + for (cb = 0; cb < CB_TOT_ALL; cb++) { + path[0][cb].cost = run_bits+4; + path[0][cb].prev_idx = -1; + path[0][cb].run = 0; + } + for (swb = 0; swb < max_sfb; swb++) { + size = sce->ics.swb_sizes[swb]; + if (sce->zeroes[win*16 + swb]) { + float cost_stay_here = path[swb][0].cost; + float cost_get_here = next_minbits + run_bits + 4; + if ( run_value_bits[sce->ics.num_windows == 8][path[swb][0].run] + != run_value_bits[sce->ics.num_windows == 8][path[swb][0].run+1]) + cost_stay_here += run_bits; + if (cost_get_here < cost_stay_here) { + path[swb+1][0].prev_idx = next_mincb; + path[swb+1][0].cost = cost_get_here; + path[swb+1][0].run = 1; + } else { + path[swb+1][0].prev_idx = 0; + path[swb+1][0].cost = cost_stay_here; + path[swb+1][0].run = path[swb][0].run + 1; + } + next_minbits = path[swb+1][0].cost; + next_mincb = 0; + for (cb = 1; cb < CB_TOT_ALL; cb++) { + path[swb+1][cb].cost = 61450; + path[swb+1][cb].prev_idx = -1; + path[swb+1][cb].run = 0; + } + } else { + float minbits = next_minbits; + int mincb = next_mincb; + int startcb = sce->band_type[win*16+swb]; + startcb = aac_cb_in_map[startcb]; + next_minbits = INFINITY; + next_mincb = 0; + for (cb = 0; cb < startcb; cb++) { + path[swb+1][cb].cost = 61450; + path[swb+1][cb].prev_idx = -1; + path[swb+1][cb].run = 0; + } + for (cb = startcb; cb < CB_TOT_ALL; cb++) { + float cost_stay_here, cost_get_here; + float bits = 0.0f; + if (cb >= 12 && sce->band_type[win*16+swb] != aac_cb_out_map[cb]) { + path[swb+1][cb].cost = 61450; + path[swb+1][cb].prev_idx = -1; + path[swb+1][cb].run = 0; + continue; + } + for (w = 0; w < group_len; w++) { + bits += quantize_band_cost_bits(s, &sce->coeffs[start + w*128], + &s->scoefs[start + w*128], size, + sce->sf_idx[win*16+swb], + aac_cb_out_map[cb], + 0, INFINITY, NULL, NULL, 0); + } + cost_stay_here = path[swb][cb].cost + bits; + cost_get_here = minbits + bits + run_bits + 4; + if ( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run] + != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1]) + cost_stay_here += run_bits; + if (cost_get_here < cost_stay_here) { + path[swb+1][cb].prev_idx = mincb; + path[swb+1][cb].cost = cost_get_here; + path[swb+1][cb].run = 1; + } else { + path[swb+1][cb].prev_idx = cb; + path[swb+1][cb].cost = cost_stay_here; + path[swb+1][cb].run = path[swb][cb].run + 1; + } + if (path[swb+1][cb].cost < next_minbits) { + next_minbits = path[swb+1][cb].cost; + next_mincb = cb; + } + } + } + start += sce->ics.swb_sizes[swb]; + } + + //convert resulting path from backward-linked list + stack_len = 0; + idx = 0; + for (cb = 1; cb < CB_TOT_ALL; cb++) + if (path[max_sfb][cb].cost < path[max_sfb][idx].cost) + idx = cb; + ppos = max_sfb; + while (ppos > 0) { + av_assert1(idx >= 0); + cb = idx; + stackrun[stack_len] = path[ppos][cb].run; + stackcb [stack_len] = cb; + idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx; + ppos -= path[ppos][cb].run; + stack_len++; + } + //perform actual band info encoding + start = 0; + for (i = stack_len - 1; i >= 0; i--) { + cb = aac_cb_out_map[stackcb[i]]; + put_bits(&s->pb, 4, cb); + count = stackrun[i]; + memset(sce->zeroes + win*16 + start, !cb, count); + //XXX: memset when band_type is also uint8_t + for (j = 0; j < count; j++) { + sce->band_type[win*16 + start] = cb; + start++; + } + while (count >= run_esc) { + put_bits(&s->pb, run_bits, run_esc); + count -= run_esc; + } + put_bits(&s->pb, run_bits, count); + } +} + + +#endif /* AVCODEC_AACCODER_TRELLIS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder_twoloop.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder_twoloop.h new file mode 100644 index 000000000..8e1bc88a8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aaccoder_twoloop.h @@ -0,0 +1,763 @@ +/* + * AAC encoder twoloop coder + * Copyright (C) 2008-2009 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder twoloop coder + * @author Konstantin Shishkov, Claudio Freire + */ + +/** + * This file contains a template for the twoloop coder function. + * It needs to be provided, externally, as an already included declaration, + * the following functions from aacenc_quantization/util.h. They're not included + * explicitly here to make it possible to provide alternative implementations: + * - quantize_band_cost + * - abs_pow34_v + * - find_max_val + * - find_min_book + * - find_form_factor + */ + +#ifndef AVCODEC_AACCODER_TWOLOOP_H +#define AVCODEC_AACCODER_TWOLOOP_H + +#include +#include "libavutil/mathematics.h" +#include "mathops.h" +#include "avcodec.h" +#include "put_bits.h" +#include "aac.h" +#include "aacenc.h" +#include "aactab.h" +#include "aacenctab.h" + +/** Frequency in Hz for lower limit of noise substitution **/ +#define NOISE_LOW_LIMIT 4000 + +#define sclip(x) av_clip(x,60,218) + +/* Reflects the cost to change codebooks */ +static inline int ff_pns_bits(SingleChannelElement *sce, int w, int g) +{ + return (!g || !sce->zeroes[w*16+g-1] || !sce->can_pns[w*16+g-1]) ? 9 : 5; +} + +/** + * two-loop quantizers search taken from ISO 13818-7 Appendix C + */ +static void search_for_quantizers_twoloop(AVCodecContext *avctx, + AACEncContext *s, + SingleChannelElement *sce, + const float lambda) +{ + int start = 0, i, w, w2, g, recomprd; + int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate + / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) + * (lambda / 120.f); + int refbits = destbits; + int toomanybits, toofewbits; + char nzs[128]; + uint8_t nextband[128]; + int maxsf[128], minsf[128]; + float dists[128] = { 0 }, qenergies[128] = { 0 }, uplims[128], euplims[128], energies[128]; + float maxvals[128], spread_thr_r[128]; + float min_spread_thr_r, max_spread_thr_r; + + /** + * rdlambda controls the maximum tolerated distortion. Twoloop + * will keep iterating until it fails to lower it or it reaches + * ulimit * rdlambda. Keeping it low increases quality on difficult + * signals, but lower it too much, and bits will be taken from weak + * signals, creating "holes". A balance is necessary. + * rdmax and rdmin specify the relative deviation from rdlambda + * allowed for tonality compensation + */ + float rdlambda = av_clipf(2.0f * 120.f / lambda, 0.0625f, 16.0f); + const float nzslope = 1.5f; + float rdmin = 0.03125f; + float rdmax = 1.0f; + + /** + * sfoffs controls an offset of optmium allocation that will be + * applied based on lambda. Keep it real and modest, the loop + * will take care of the rest, this just accelerates convergence + */ + float sfoffs = av_clipf(log2f(120.0f / lambda) * 4.0f, -5, 10); + + int fflag, minscaler, maxscaler, nminscaler; + int its = 0; + int maxits = 30; + int allz = 0; + int tbits; + int cutoff = 1024; + int pns_start_pos; + int prev; + + /** + * zeroscale controls a multiplier of the threshold, if band energy + * is below this, a zero is forced. Keep it lower than 1, unless + * low lambda is used, because energy < threshold doesn't mean there's + * no audible signal outright, it's just energy. Also make it rise + * slower than rdlambda, as rdscale has due compensation with + * noisy band depriorization below, whereas zeroing logic is rather dumb + */ + float zeroscale; + if (lambda > 120.f) { + zeroscale = av_clipf(powf(120.f / lambda, 0.25f), 0.0625f, 1.0f); + } else { + zeroscale = 1.f; + } + + if (s->psy.bitres.alloc >= 0) { + /** + * Psy granted us extra bits to use, from the reservoire + * adjust for lambda except what psy already did + */ + destbits = s->psy.bitres.alloc + * (lambda / (avctx->global_quality ? avctx->global_quality : 120)); + } + + if (avctx->flags & AV_CODEC_FLAG_QSCALE) { + /** + * Constant Q-scale doesn't compensate MS coding on its own + * No need to be overly precise, this only controls RD + * adjustment CB limits when going overboard + */ + if (s->options.mid_side && s->cur_type == TYPE_CPE) + destbits *= 2; + + /** + * When using a constant Q-scale, don't adjust bits, just use RD + * Don't let it go overboard, though... 8x psy target is enough + */ + toomanybits = 5800; + toofewbits = destbits / 16; + + /** Don't offset scalers, just RD */ + sfoffs = sce->ics.num_windows - 1; + rdlambda = sqrtf(rdlambda); + + /** search further */ + maxits *= 2; + } else { + /* When using ABR, be strict, but a reasonable leeway is + * critical to allow RC to smoothly track desired bitrate + * without sudden quality drops that cause audible artifacts. + * Symmetry is also desirable, to avoid systematic bias. + */ + toomanybits = destbits + destbits/8; + toofewbits = destbits - destbits/8; + + sfoffs = 0; + rdlambda = sqrtf(rdlambda); + } + + /** and zero out above cutoff frequency */ + { + int wlen = 1024 / sce->ics.num_windows; + int bandwidth; + + /** + * Scale, psy gives us constant quality, this LP only scales + * bitrate by lambda, so we save bits on subjectively unimportant HF + * rather than increase quantization noise. Adjust nominal bitrate + * to effective bitrate according to encoding parameters, + * AAC_CUTOFF_FROM_BITRATE is calibrated for effective bitrate. + */ + float rate_bandwidth_multiplier = 1.5f; + int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE) + ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) + : (avctx->bit_rate / avctx->channels); + + /** Compensate for extensions that increase efficiency */ + if (s->options.pns || s->options.intensity_stereo) + frame_bit_rate *= 1.15f; + + if (avctx->cutoff > 0) { + bandwidth = avctx->cutoff; + } else { + bandwidth = FFMAX(3000, AAC_CUTOFF_FROM_BITRATE(frame_bit_rate, 1, avctx->sample_rate)); + s->psy.cutoff = bandwidth; + } + + cutoff = bandwidth * 2 * wlen / avctx->sample_rate; + pns_start_pos = NOISE_LOW_LIMIT * 2 * wlen / avctx->sample_rate; + } + + /** + * for values above this the decoder might end up in an endless loop + * due to always having more bits than what can be encoded. + */ + destbits = FFMIN(destbits, 5800); + toomanybits = FFMIN(toomanybits, 5800); + toofewbits = FFMIN(toofewbits, 5800); + /** + * XXX: some heuristic to determine initial quantizers will reduce search time + * determine zero bands and upper distortion limits + */ + min_spread_thr_r = -1; + max_spread_thr_r = -1; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = start = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) { + int nz = 0; + float uplim = 0.0f, energy = 0.0f, spread = 0.0f; + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; + if (start >= cutoff || band->energy <= (band->threshold * zeroscale) || band->threshold == 0.0f) { + sce->zeroes[(w+w2)*16+g] = 1; + continue; + } + nz = 1; + } + if (!nz) { + uplim = 0.0f; + } else { + nz = 0; + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; + if (band->energy <= (band->threshold * zeroscale) || band->threshold == 0.0f) + continue; + uplim += band->threshold; + energy += band->energy; + spread += band->spread; + nz++; + } + } + uplims[w*16+g] = uplim; + energies[w*16+g] = energy; + nzs[w*16+g] = nz; + sce->zeroes[w*16+g] = !nz; + allz |= nz; + if (nz && sce->can_pns[w*16+g]) { + spread_thr_r[w*16+g] = energy * nz / (uplim * spread); + if (min_spread_thr_r < 0) { + min_spread_thr_r = max_spread_thr_r = spread_thr_r[w*16+g]; + } else { + min_spread_thr_r = FFMIN(min_spread_thr_r, spread_thr_r[w*16+g]); + max_spread_thr_r = FFMAX(max_spread_thr_r, spread_thr_r[w*16+g]); + } + } + } + } + + /** Compute initial scalers */ + minscaler = 65535; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = 0; g < sce->ics.num_swb; g++) { + if (sce->zeroes[w*16+g]) { + sce->sf_idx[w*16+g] = SCALE_ONE_POS; + continue; + } + /** + * log2f-to-distortion ratio is, technically, 2 (1.5db = 4, but it's power vs level so it's 2). + * But, as offsets are applied, low-frequency signals are too sensitive to the induced distortion, + * so we make scaling more conservative by choosing a lower log2f-to-distortion ratio, and thus + * more robust. + */ + sce->sf_idx[w*16+g] = av_clip( + SCALE_ONE_POS + + 1.75*log2f(FFMAX(0.00125f,uplims[w*16+g]) / sce->ics.swb_sizes[g]) + + sfoffs, + 60, SCALE_MAX_POS); + minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]); + } + } + + /** Clip */ + minscaler = av_clip(minscaler, SCALE_ONE_POS - SCALE_DIV_512, SCALE_MAX_POS - SCALE_DIV_512); + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) + for (g = 0; g < sce->ics.num_swb; g++) + if (!sce->zeroes[w*16+g]) + sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF - 1); + + if (!allz) + return; + s->abs_pow34(s->scoefs, sce->coeffs, 1024); + ff_quantize_band_cost_cache_init(s); + + for (i = 0; i < sizeof(minsf) / sizeof(minsf[0]); ++i) + minsf[i] = 0; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = w*128; + for (g = 0; g < sce->ics.num_swb; g++) { + const float *scaled = s->scoefs + start; + int minsfidx; + maxvals[w*16+g] = find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], scaled); + if (maxvals[w*16+g] > 0) { + minsfidx = coef2minsf(maxvals[w*16+g]); + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) + minsf[(w+w2)*16+g] = minsfidx; + } + start += sce->ics.swb_sizes[g]; + } + } + + /** + * Scale uplims to match rate distortion to quality + * bu applying noisy band depriorization and tonal band priorization. + * Maxval-energy ratio gives us an idea of how noisy/tonal the band is. + * If maxval^2 ~ energy, then that band is mostly noise, and we can relax + * rate distortion requirements. + */ + memcpy(euplims, uplims, sizeof(euplims)); + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + /** psy already priorizes transients to some extent */ + float de_psy_factor = (sce->ics.num_windows > 1) ? 8.0f / sce->ics.group_len[w] : 1.0f; + start = w*128; + for (g = 0; g < sce->ics.num_swb; g++) { + if (nzs[g] > 0) { + float cleanup_factor = ff_sqrf(av_clipf(start / (cutoff * 0.75f), 1.0f, 2.0f)); + float energy2uplim = find_form_factor( + sce->ics.group_len[w], sce->ics.swb_sizes[g], + uplims[w*16+g] / (nzs[g] * sce->ics.swb_sizes[w]), + sce->coeffs + start, + nzslope * cleanup_factor); + energy2uplim *= de_psy_factor; + if (!(avctx->flags & AV_CODEC_FLAG_QSCALE)) { + /** In ABR, we need to priorize less and let rate control do its thing */ + energy2uplim = sqrtf(energy2uplim); + } + energy2uplim = FFMAX(0.015625f, FFMIN(1.0f, energy2uplim)); + uplims[w*16+g] *= av_clipf(rdlambda * energy2uplim, rdmin, rdmax) + * sce->ics.group_len[w]; + + energy2uplim = find_form_factor( + sce->ics.group_len[w], sce->ics.swb_sizes[g], + uplims[w*16+g] / (nzs[g] * sce->ics.swb_sizes[w]), + sce->coeffs + start, + 2.0f); + energy2uplim *= de_psy_factor; + if (!(avctx->flags & AV_CODEC_FLAG_QSCALE)) { + /** In ABR, we need to priorize less and let rate control do its thing */ + energy2uplim = sqrtf(energy2uplim); + } + energy2uplim = FFMAX(0.015625f, FFMIN(1.0f, energy2uplim)); + euplims[w*16+g] *= av_clipf(rdlambda * energy2uplim * sce->ics.group_len[w], + 0.5f, 1.0f); + } + start += sce->ics.swb_sizes[g]; + } + } + + for (i = 0; i < sizeof(maxsf) / sizeof(maxsf[0]); ++i) + maxsf[i] = SCALE_MAX_POS; + + //perform two-loop search + //outer loop - improve quality + do { + //inner loop - quantize spectrum to fit into given number of bits + int overdist; + int qstep = its ? 1 : 32; + do { + int changed = 0; + prev = -1; + recomprd = 0; + tbits = 0; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = w*128; + for (g = 0; g < sce->ics.num_swb; g++) { + const float *coefs = &sce->coeffs[start]; + const float *scaled = &s->scoefs[start]; + int bits = 0; + int cb; + float dist = 0.0f; + float qenergy = 0.0f; + + if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) { + start += sce->ics.swb_sizes[g]; + if (sce->can_pns[w*16+g]) { + /** PNS isn't free */ + tbits += ff_pns_bits(sce, w, g); + } + continue; + } + cb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + int b; + float sqenergy; + dist += quantize_band_cost_cached(s, w + w2, g, coefs + w2*128, + scaled + w2*128, + sce->ics.swb_sizes[g], + sce->sf_idx[w*16+g], + cb, + 1.0f, + INFINITY, + &b, &sqenergy, + 0); + bits += b; + qenergy += sqenergy; + } + dists[w*16+g] = dist - bits; + qenergies[w*16+g] = qenergy; + if (prev != -1) { + int sfdiff = av_clip(sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO, 0, 2*SCALE_MAX_DIFF); + bits += ff_aac_scalefactor_bits[sfdiff]; + } + tbits += bits; + start += sce->ics.swb_sizes[g]; + prev = sce->sf_idx[w*16+g]; + } + } + if (tbits > toomanybits) { + recomprd = 1; + for (i = 0; i < 128; i++) { + if (sce->sf_idx[i] < (SCALE_MAX_POS - SCALE_DIV_512)) { + int maxsf_i = (tbits > 5800) ? SCALE_MAX_POS : maxsf[i]; + int new_sf = FFMIN(maxsf_i, sce->sf_idx[i] + qstep); + if (new_sf != sce->sf_idx[i]) { + sce->sf_idx[i] = new_sf; + changed = 1; + } + } + } + } else if (tbits < toofewbits) { + recomprd = 1; + for (i = 0; i < 128; i++) { + if (sce->sf_idx[i] > SCALE_ONE_POS) { + int new_sf = FFMAX3(minsf[i], SCALE_ONE_POS, sce->sf_idx[i] - qstep); + if (new_sf != sce->sf_idx[i]) { + sce->sf_idx[i] = new_sf; + changed = 1; + } + } + } + } + qstep >>= 1; + if (!qstep && tbits > toomanybits && sce->sf_idx[0] < 217 && changed) + qstep = 1; + } while (qstep); + + overdist = 1; + fflag = tbits < toofewbits; + for (i = 0; i < 2 && (overdist || recomprd); ++i) { + if (recomprd) { + /** Must recompute distortion */ + prev = -1; + tbits = 0; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = w*128; + for (g = 0; g < sce->ics.num_swb; g++) { + const float *coefs = sce->coeffs + start; + const float *scaled = s->scoefs + start; + int bits = 0; + int cb; + float dist = 0.0f; + float qenergy = 0.0f; + + if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) { + start += sce->ics.swb_sizes[g]; + if (sce->can_pns[w*16+g]) { + /** PNS isn't free */ + tbits += ff_pns_bits(sce, w, g); + } + continue; + } + cb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + int b; + float sqenergy; + dist += quantize_band_cost_cached(s, w + w2, g, coefs + w2*128, + scaled + w2*128, + sce->ics.swb_sizes[g], + sce->sf_idx[w*16+g], + cb, + 1.0f, + INFINITY, + &b, &sqenergy, + 0); + bits += b; + qenergy += sqenergy; + } + dists[w*16+g] = dist - bits; + qenergies[w*16+g] = qenergy; + if (prev != -1) { + int sfdiff = av_clip(sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO, 0, 2*SCALE_MAX_DIFF); + bits += ff_aac_scalefactor_bits[sfdiff]; + } + tbits += bits; + start += sce->ics.swb_sizes[g]; + prev = sce->sf_idx[w*16+g]; + } + } + } + if (!i && s->options.pns && its > maxits/2 && tbits > toofewbits) { + float maxoverdist = 0.0f; + float ovrfactor = 1.f+(maxits-its)*16.f/maxits; + overdist = recomprd = 0; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = start = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) { + if (!sce->zeroes[w*16+g] && sce->sf_idx[w*16+g] > SCALE_ONE_POS && dists[w*16+g] > uplims[w*16+g]*ovrfactor) { + float ovrdist = dists[w*16+g] / FFMAX(uplims[w*16+g],euplims[w*16+g]); + maxoverdist = FFMAX(maxoverdist, ovrdist); + overdist++; + } + } + } + if (overdist) { + /* We have overdistorted bands, trade for zeroes (that can be noise) + * Zero the bands in the lowest 1.25% spread-energy-threshold ranking + */ + float minspread = max_spread_thr_r; + float maxspread = min_spread_thr_r; + float zspread; + int zeroable = 0; + int zeroed = 0; + int maxzeroed, zloop; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = start = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) { + if (start >= pns_start_pos && !sce->zeroes[w*16+g] && sce->can_pns[w*16+g]) { + minspread = FFMIN(minspread, spread_thr_r[w*16+g]); + maxspread = FFMAX(maxspread, spread_thr_r[w*16+g]); + zeroable++; + } + } + } + zspread = (maxspread-minspread) * 0.0125f + minspread; + /* Don't PNS everything even if allowed. It suppresses bit starvation signals from RC, + * and forced the hand of the later search_for_pns step. + * Instead, PNS a fraction of the spread_thr_r range depending on how starved for bits we are, + * and leave further PNSing to search_for_pns if worthwhile. + */ + zspread = FFMIN3(min_spread_thr_r * 8.f, zspread, + ((toomanybits - tbits) * min_spread_thr_r + (tbits - toofewbits) * max_spread_thr_r) / (toomanybits - toofewbits + 1)); + maxzeroed = FFMIN(zeroable, FFMAX(1, (zeroable * its + maxits - 1) / (2 * maxits))); + for (zloop = 0; zloop < 2; zloop++) { + /* Two passes: first distorted stuff - two birds in one shot and all that, + * then anything viable. Viable means not zero, but either CB=zero-able + * (too high SF), not SF <= 1 (that means we'd be operating at very high + * quality, we don't want PNS when doing VHQ), PNS allowed, and within + * the lowest ranking percentile. + */ + float loopovrfactor = (zloop) ? 1.0f : ovrfactor; + int loopminsf = (zloop) ? (SCALE_ONE_POS - SCALE_DIV_512) : SCALE_ONE_POS; + int mcb; + for (g = sce->ics.num_swb-1; g > 0 && zeroed < maxzeroed; g--) { + if (sce->ics.swb_offset[g] < pns_start_pos) + continue; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + if (!sce->zeroes[w*16+g] && sce->can_pns[w*16+g] && spread_thr_r[w*16+g] <= zspread + && sce->sf_idx[w*16+g] > loopminsf + && (dists[w*16+g] > loopovrfactor*uplims[w*16+g] || !(mcb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g])) + || (mcb <= 1 && dists[w*16+g] > FFMIN(uplims[w*16+g], euplims[w*16+g]))) ) { + sce->zeroes[w*16+g] = 1; + sce->band_type[w*16+g] = 0; + zeroed++; + } + } + } + } + if (zeroed) + recomprd = fflag = 1; + } else { + overdist = 0; + } + } + } + + minscaler = SCALE_MAX_POS; + maxscaler = 0; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = 0; g < sce->ics.num_swb; g++) { + if (!sce->zeroes[w*16+g]) { + minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]); + maxscaler = FFMAX(maxscaler, sce->sf_idx[w*16+g]); + } + } + } + + minscaler = nminscaler = av_clip(minscaler, SCALE_ONE_POS - SCALE_DIV_512, SCALE_MAX_POS - SCALE_DIV_512); + prev = -1; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + /** Start with big steps, end up fine-tunning */ + int depth = (its > maxits/2) ? ((its > maxits*2/3) ? 1 : 3) : 10; + int edepth = depth+2; + float uplmax = its / (maxits*0.25f) + 1.0f; + uplmax *= (tbits > destbits) ? FFMIN(2.0f, tbits / (float)FFMAX(1,destbits)) : 1.0f; + start = w * 128; + for (g = 0; g < sce->ics.num_swb; g++) { + int prevsc = sce->sf_idx[w*16+g]; + if (prev < 0 && !sce->zeroes[w*16+g]) + prev = sce->sf_idx[0]; + if (!sce->zeroes[w*16+g]) { + const float *coefs = sce->coeffs + start; + const float *scaled = s->scoefs + start; + int cmb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); + int mindeltasf = FFMAX(0, prev - SCALE_MAX_DIFF); + int maxdeltasf = FFMIN(SCALE_MAX_POS - SCALE_DIV_512, prev + SCALE_MAX_DIFF); + if ((!cmb || dists[w*16+g] > uplims[w*16+g]) && sce->sf_idx[w*16+g] > FFMAX(mindeltasf, minsf[w*16+g])) { + /* Try to make sure there is some energy in every nonzero band + * NOTE: This algorithm must be forcibly imbalanced, pushing harder + * on holes or more distorted bands at first, otherwise there's + * no net gain (since the next iteration will offset all bands + * on the opposite direction to compensate for extra bits) + */ + for (i = 0; i < edepth && sce->sf_idx[w*16+g] > mindeltasf; ++i) { + int cb, bits; + float dist, qenergy; + int mb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1); + cb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); + dist = qenergy = 0.f; + bits = 0; + if (!cb) { + maxsf[w*16+g] = FFMIN(sce->sf_idx[w*16+g]-1, maxsf[w*16+g]); + } else if (i >= depth && dists[w*16+g] < euplims[w*16+g]) { + break; + } + /* !g is the DC band, it's important, since quantization error here + * applies to less than a cycle, it creates horrible intermodulation + * distortion if it doesn't stick to what psy requests + */ + if (!g && sce->ics.num_windows > 1 && dists[w*16+g] >= euplims[w*16+g]) + maxsf[w*16+g] = FFMIN(sce->sf_idx[w*16+g], maxsf[w*16+g]); + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + int b; + float sqenergy; + dist += quantize_band_cost_cached(s, w + w2, g, coefs + w2*128, + scaled + w2*128, + sce->ics.swb_sizes[g], + sce->sf_idx[w*16+g]-1, + cb, + 1.0f, + INFINITY, + &b, &sqenergy, + 0); + bits += b; + qenergy += sqenergy; + } + sce->sf_idx[w*16+g]--; + dists[w*16+g] = dist - bits; + qenergies[w*16+g] = qenergy; + if (mb && (sce->sf_idx[w*16+g] < mindeltasf || ( + (dists[w*16+g] < FFMIN(uplmax*uplims[w*16+g], euplims[w*16+g])) + && (fabsf(qenergies[w*16+g]-energies[w*16+g]) < euplims[w*16+g]) + ) )) { + break; + } + } + } else if (tbits > toofewbits && sce->sf_idx[w*16+g] < FFMIN(maxdeltasf, maxsf[w*16+g]) + && (dists[w*16+g] < FFMIN(euplims[w*16+g], uplims[w*16+g])) + && (fabsf(qenergies[w*16+g]-energies[w*16+g]) < euplims[w*16+g]) + ) { + /** Um... over target. Save bits for more important stuff. */ + for (i = 0; i < depth && sce->sf_idx[w*16+g] < maxdeltasf; ++i) { + int cb, bits; + float dist, qenergy; + cb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]+1); + if (cb > 0) { + dist = qenergy = 0.f; + bits = 0; + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + int b; + float sqenergy; + dist += quantize_band_cost_cached(s, w + w2, g, coefs + w2*128, + scaled + w2*128, + sce->ics.swb_sizes[g], + sce->sf_idx[w*16+g]+1, + cb, + 1.0f, + INFINITY, + &b, &sqenergy, + 0); + bits += b; + qenergy += sqenergy; + } + dist -= bits; + if (dist < FFMIN(euplims[w*16+g], uplims[w*16+g])) { + sce->sf_idx[w*16+g]++; + dists[w*16+g] = dist; + qenergies[w*16+g] = qenergy; + } else { + break; + } + } else { + maxsf[w*16+g] = FFMIN(sce->sf_idx[w*16+g], maxsf[w*16+g]); + break; + } + } + } + prev = sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], mindeltasf, maxdeltasf); + if (sce->sf_idx[w*16+g] != prevsc) + fflag = 1; + nminscaler = FFMIN(nminscaler, sce->sf_idx[w*16+g]); + sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); + } + start += sce->ics.swb_sizes[g]; + } + } + + /** SF difference limit violation risk. Must re-clamp. */ + prev = -1; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = 0; g < sce->ics.num_swb; g++) { + if (!sce->zeroes[w*16+g]) { + int prevsf = sce->sf_idx[w*16+g]; + if (prev < 0) + prev = prevsf; + sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], prev - SCALE_MAX_DIFF, prev + SCALE_MAX_DIFF); + sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); + prev = sce->sf_idx[w*16+g]; + if (!fflag && prevsf != sce->sf_idx[w*16+g]) + fflag = 1; + } + } + } + + its++; + } while (fflag && its < maxits); + + /** Scout out next nonzero bands */ + ff_init_nextband_map(sce, nextband); + + prev = -1; + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + /** Make sure proper codebooks are set */ + for (g = 0; g < sce->ics.num_swb; g++) { + if (!sce->zeroes[w*16+g]) { + sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); + if (sce->band_type[w*16+g] <= 0) { + if (!ff_sfdelta_can_remove_band(sce, nextband, prev, w*16+g)) { + /** Cannot zero out, make sure it's not attempted */ + sce->band_type[w*16+g] = 1; + } else { + sce->zeroes[w*16+g] = 1; + sce->band_type[w*16+g] = 0; + } + } + } else { + sce->band_type[w*16+g] = 0; + } + /** Check that there's no SF delta range violations */ + if (!sce->zeroes[w*16+g]) { + if (prev != -1) { + av_unused int sfdiff = sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO; + av_assert1(sfdiff >= 0 && sfdiff <= 2*SCALE_MAX_DIFF); + } else if (sce->zeroes[0]) { + /** Set global gain to something useful */ + sce->sf_idx[0] = sce->sf_idx[w*16+g]; + } + prev = sce->sf_idx[w*16+g]; + } + } + } +} + +#endif /* AVCODEC_AACCODER_TWOLOOP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec.c new file mode 100644 index 000000000..c606ad40a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec.c @@ -0,0 +1,591 @@ +/* + * AAC decoder + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * Copyright (c) 2008-2013 Alex Converse + * + * AAC LATM decoder + * Copyright (c) 2008-2010 Paul Kendall + * Copyright (c) 2010 Janne Grunau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC decoder + * @author Oded Shimon ( ods15 ods15 dyndns org ) + * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) + */ + +#define FFT_FLOAT 1 +#define FFT_FIXED_32 0 +#define USE_FIXED 0 + +#include "libavutil/float_dsp.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "internal.h" +#include "get_bits.h" +#include "fft.h" +#include "mdct15.h" +#include "lpc.h" +#include "kbdwin.h" +#include "sinewin.h" + +#include "aac.h" +#include "aactab.h" +#include "aacdectab.h" +#include "adts_header.h" +#include "cbrt_data.h" +#include "sbr.h" +#include "aacsbr.h" +#include "mpeg4audio.h" +#include "profiles.h" +#include "libavutil/intfloat.h" + +#include +#include +#include +#include + +#if ARCH_ARM +# include "arm/aac.h" +#elif ARCH_MIPS +# include "mips/aacdec_mips.h" +#endif + +static av_always_inline void reset_predict_state(PredictorState *ps) +{ + ps->r0 = 0.0f; + ps->r1 = 0.0f; + ps->cor0 = 0.0f; + ps->cor1 = 0.0f; + ps->var0 = 1.0f; + ps->var1 = 1.0f; +} + +#ifndef VMUL2 +static inline float *VMUL2(float *dst, const float *v, unsigned idx, + const float *scale) +{ + float s = *scale; + *dst++ = v[idx & 15] * s; + *dst++ = v[idx>>4 & 15] * s; + return dst; +} +#endif + +#ifndef VMUL4 +static inline float *VMUL4(float *dst, const float *v, unsigned idx, + const float *scale) +{ + float s = *scale; + *dst++ = v[idx & 3] * s; + *dst++ = v[idx>>2 & 3] * s; + *dst++ = v[idx>>4 & 3] * s; + *dst++ = v[idx>>6 & 3] * s; + return dst; +} +#endif + +#ifndef VMUL2S +static inline float *VMUL2S(float *dst, const float *v, unsigned idx, + unsigned sign, const float *scale) +{ + union av_intfloat32 s0, s1; + + s0.f = s1.f = *scale; + s0.i ^= sign >> 1 << 31; + s1.i ^= sign << 31; + + *dst++ = v[idx & 15] * s0.f; + *dst++ = v[idx>>4 & 15] * s1.f; + + return dst; +} +#endif + +#ifndef VMUL4S +static inline float *VMUL4S(float *dst, const float *v, unsigned idx, + unsigned sign, const float *scale) +{ + unsigned nz = idx >> 12; + union av_intfloat32 s = { .f = *scale }; + union av_intfloat32 t; + + t.i = s.i ^ (sign & 1U<<31); + *dst++ = v[idx & 3] * t.f; + + sign <<= nz & 1; nz >>= 1; + t.i = s.i ^ (sign & 1U<<31); + *dst++ = v[idx>>2 & 3] * t.f; + + sign <<= nz & 1; nz >>= 1; + t.i = s.i ^ (sign & 1U<<31); + *dst++ = v[idx>>4 & 3] * t.f; + + sign <<= nz & 1; + t.i = s.i ^ (sign & 1U<<31); + *dst++ = v[idx>>6 & 3] * t.f; + + return dst; +} +#endif + +static av_always_inline float flt16_round(float pf) +{ + union av_intfloat32 tmp; + tmp.f = pf; + tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U; + return tmp.f; +} + +static av_always_inline float flt16_even(float pf) +{ + union av_intfloat32 tmp; + tmp.f = pf; + tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U >> 16)) & 0xFFFF0000U; + return tmp.f; +} + +static av_always_inline float flt16_trunc(float pf) +{ + union av_intfloat32 pun; + pun.f = pf; + pun.i &= 0xFFFF0000U; + return pun.f; +} + +static av_always_inline void predict(PredictorState *ps, float *coef, + int output_enable) +{ + const float a = 0.953125; // 61.0 / 64 + const float alpha = 0.90625; // 29.0 / 32 + float e0, e1; + float pv; + float k1, k2; + float r0 = ps->r0, r1 = ps->r1; + float cor0 = ps->cor0, cor1 = ps->cor1; + float var0 = ps->var0, var1 = ps->var1; + + k1 = var0 > 1 ? cor0 * flt16_even(a / var0) : 0; + k2 = var1 > 1 ? cor1 * flt16_even(a / var1) : 0; + + pv = flt16_round(k1 * r0 + k2 * r1); + if (output_enable) + *coef += pv; + + e0 = *coef; + e1 = e0 - k1 * r0; + + ps->cor1 = flt16_trunc(alpha * cor1 + r1 * e1); + ps->var1 = flt16_trunc(alpha * var1 + 0.5f * (r1 * r1 + e1 * e1)); + ps->cor0 = flt16_trunc(alpha * cor0 + r0 * e0); + ps->var0 = flt16_trunc(alpha * var0 + 0.5f * (r0 * r0 + e0 * e0)); + + ps->r1 = flt16_trunc(a * (r0 - k1 * e0)); + ps->r0 = flt16_trunc(a * e0); +} + +/** + * Apply dependent channel coupling (applied before IMDCT). + * + * @param index index into coupling gain array + */ +static void apply_dependent_coupling(AACContext *ac, + SingleChannelElement *target, + ChannelElement *cce, int index) +{ + IndividualChannelStream *ics = &cce->ch[0].ics; + const uint16_t *offsets = ics->swb_offset; + float *dest = target->coeffs; + const float *src = cce->ch[0].coeffs; + int g, i, group, k, idx = 0; + if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) { + av_log(ac->avctx, AV_LOG_ERROR, + "Dependent coupling is not supported together with LTP\n"); + return; + } + for (g = 0; g < ics->num_window_groups; g++) { + for (i = 0; i < ics->max_sfb; i++, idx++) { + if (cce->ch[0].band_type[idx] != ZERO_BT) { + const float gain = cce->coup.gain[index][idx]; + for (group = 0; group < ics->group_len[g]; group++) { + for (k = offsets[i]; k < offsets[i + 1]; k++) { + // FIXME: SIMDify + dest[group * 128 + k] += gain * src[group * 128 + k]; + } + } + } + } + dest += ics->group_len[g] * 128; + src += ics->group_len[g] * 128; + } +} + +/** + * Apply independent channel coupling (applied after IMDCT). + * + * @param index index into coupling gain array + */ +static void apply_independent_coupling(AACContext *ac, + SingleChannelElement *target, + ChannelElement *cce, int index) +{ + const float gain = cce->coup.gain[index][0]; + const float *src = cce->ch[0].ret; + float *dest = target->ret; + const int len = 1024 << (ac->oc[1].m4ac.sbr == 1); + + ac->fdsp->vector_fmac_scalar(dest, src, gain, len); +} + +#include "aacdec_template.c" + +#define LOAS_SYNC_WORD 0x2b7 ///< 11 bits LOAS sync word + +struct LATMContext { + AACContext aac_ctx; ///< containing AACContext + int initialized; ///< initialized after a valid extradata was seen + + // parser data + int audio_mux_version_A; ///< LATM syntax version + int frame_length_type; ///< 0/1 variable/fixed frame length + int frame_length; ///< frame length for fixed frame length +}; + +static inline uint32_t latm_get_value(GetBitContext *b) +{ + int length = get_bits(b, 2); + + return get_bits_long(b, (length+1)*8); +} + +static int latm_decode_audio_specific_config(struct LATMContext *latmctx, + GetBitContext *gb, int asclen) +{ + AACContext *ac = &latmctx->aac_ctx; + AVCodecContext *avctx = ac->avctx; + MPEG4AudioConfig m4ac = { 0 }; + GetBitContext gbc; + int config_start_bit = get_bits_count(gb); + int sync_extension = 0; + int bits_consumed, esize, i; + + if (asclen > 0) { + sync_extension = 1; + asclen = FFMIN(asclen, get_bits_left(gb)); + init_get_bits(&gbc, gb->buffer, config_start_bit + asclen); + skip_bits_long(&gbc, config_start_bit); + } else if (asclen == 0) { + gbc = *gb; + } else { + return AVERROR_INVALIDDATA; + } + + if (get_bits_left(gb) <= 0) + return AVERROR_INVALIDDATA; + + bits_consumed = decode_audio_specific_config_gb(NULL, avctx, &m4ac, + &gbc, config_start_bit, + sync_extension); + + if (bits_consumed < config_start_bit) + return AVERROR_INVALIDDATA; + bits_consumed -= config_start_bit; + + if (asclen == 0) + asclen = bits_consumed; + + if (!latmctx->initialized || + ac->oc[1].m4ac.sample_rate != m4ac.sample_rate || + ac->oc[1].m4ac.chan_config != m4ac.chan_config) { + + if (latmctx->initialized) { + av_log(avctx, AV_LOG_INFO, "audio config changed (sample_rate=%d, chan_config=%d)\n", m4ac.sample_rate, m4ac.chan_config); + } else { + av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n"); + } + latmctx->initialized = 0; + + esize = (asclen + 7) / 8; + + if (avctx->extradata_size < esize) { + av_free(avctx->extradata); + avctx->extradata = av_malloc(esize + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + } + + avctx->extradata_size = esize; + gbc = *gb; + for (i = 0; i < esize; i++) { + avctx->extradata[i] = get_bits(&gbc, 8); + } + memset(avctx->extradata+esize, 0, AV_INPUT_BUFFER_PADDING_SIZE); + } + skip_bits_long(gb, asclen); + + return 0; +} + +static int read_stream_mux_config(struct LATMContext *latmctx, + GetBitContext *gb) +{ + int ret, audio_mux_version = get_bits(gb, 1); + + latmctx->audio_mux_version_A = 0; + if (audio_mux_version) + latmctx->audio_mux_version_A = get_bits(gb, 1); + + if (!latmctx->audio_mux_version_A) { + + if (audio_mux_version) + latm_get_value(gb); // taraFullness + + skip_bits(gb, 1); // allStreamSameTimeFraming + skip_bits(gb, 6); // numSubFrames + // numPrograms + if (get_bits(gb, 4)) { // numPrograms + avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple programs"); + return AVERROR_PATCHWELCOME; + } + + // for each program (which there is only one in DVB) + + // for each layer (which there is only one in DVB) + if (get_bits(gb, 3)) { // numLayer + avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple layers"); + return AVERROR_PATCHWELCOME; + } + + // for all but first stream: use_same_config = get_bits(gb, 1); + if (!audio_mux_version) { + if ((ret = latm_decode_audio_specific_config(latmctx, gb, 0)) < 0) + return ret; + } else { + int ascLen = latm_get_value(gb); + if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0) + return ret; + } + + latmctx->frame_length_type = get_bits(gb, 3); + switch (latmctx->frame_length_type) { + case 0: + skip_bits(gb, 8); // latmBufferFullness + break; + case 1: + latmctx->frame_length = get_bits(gb, 9); + break; + case 3: + case 4: + case 5: + skip_bits(gb, 6); // CELP frame length table index + break; + case 6: + case 7: + skip_bits(gb, 1); // HVXC frame length table index + break; + } + + if (get_bits(gb, 1)) { // other data + if (audio_mux_version) { + latm_get_value(gb); // other_data_bits + } else { + int esc; + do { + esc = get_bits(gb, 1); + skip_bits(gb, 8); + } while (esc); + } + } + + if (get_bits(gb, 1)) // crc present + skip_bits(gb, 8); // config_crc + } + + return 0; +} + +static int read_payload_length_info(struct LATMContext *ctx, GetBitContext *gb) +{ + uint8_t tmp; + + if (ctx->frame_length_type == 0) { + int mux_slot_length = 0; + do { + if (get_bits_left(gb) < 8) + return AVERROR_INVALIDDATA; + tmp = get_bits(gb, 8); + mux_slot_length += tmp; + } while (tmp == 255); + return mux_slot_length; + } else if (ctx->frame_length_type == 1) { + return ctx->frame_length; + } else if (ctx->frame_length_type == 3 || + ctx->frame_length_type == 5 || + ctx->frame_length_type == 7) { + skip_bits(gb, 2); // mux_slot_length_coded + } + return 0; +} + +static int read_audio_mux_element(struct LATMContext *latmctx, + GetBitContext *gb) +{ + int err; + uint8_t use_same_mux = get_bits(gb, 1); + if (!use_same_mux) { + if ((err = read_stream_mux_config(latmctx, gb)) < 0) + return err; + } else if (!latmctx->aac_ctx.avctx->extradata) { + av_log(latmctx->aac_ctx.avctx, AV_LOG_DEBUG, + "no decoder config found\n"); + return 1; + } + if (latmctx->audio_mux_version_A == 0) { + int mux_slot_length_bytes = read_payload_length_info(latmctx, gb); + if (mux_slot_length_bytes < 0 || mux_slot_length_bytes * 8LL > get_bits_left(gb)) { + av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "incomplete frame\n"); + return AVERROR_INVALIDDATA; + } else if (mux_slot_length_bytes * 8 + 256 < get_bits_left(gb)) { + av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, + "frame length mismatch %d << %d\n", + mux_slot_length_bytes * 8, get_bits_left(gb)); + return AVERROR_INVALIDDATA; + } + } + return 0; +} + + +static int latm_decode_frame(AVCodecContext *avctx, void *out, + int *got_frame_ptr, AVPacket *avpkt) +{ + struct LATMContext *latmctx = avctx->priv_data; + int muxlength, err; + GetBitContext gb; + + if ((err = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) + return err; + + // check for LOAS sync word + if (get_bits(&gb, 11) != LOAS_SYNC_WORD) + return AVERROR_INVALIDDATA; + + muxlength = get_bits(&gb, 13) + 3; + // not enough data, the parser should have sorted this out + if (muxlength > avpkt->size) + return AVERROR_INVALIDDATA; + + if ((err = read_audio_mux_element(latmctx, &gb))) + return (err < 0) ? err : avpkt->size; + + if (!latmctx->initialized) { + if (!avctx->extradata) { + *got_frame_ptr = 0; + return avpkt->size; + } else { + push_output_configuration(&latmctx->aac_ctx); + if ((err = decode_audio_specific_config( + &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1].m4ac, + avctx->extradata, avctx->extradata_size*8LL, 1)) < 0) { + pop_output_configuration(&latmctx->aac_ctx); + return err; + } + latmctx->initialized = 1; + } + } + + if (show_bits(&gb, 12) == 0xfff) { + av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, + "ADTS header detected, probably as result of configuration " + "misparsing\n"); + return AVERROR_INVALIDDATA; + } + + switch (latmctx->aac_ctx.oc[1].m4ac.object_type) { + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_LD: + case AOT_ER_AAC_ELD: + err = aac_decode_er_frame(avctx, out, got_frame_ptr, &gb); + break; + default: + err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt); + } + if (err < 0) + return err; + + return muxlength; +} + +static av_cold int latm_decode_init(AVCodecContext *avctx) +{ + struct LATMContext *latmctx = avctx->priv_data; + int ret = aac_decode_init(avctx); + + if (avctx->extradata_size > 0) + latmctx->initialized = !ret; + + return ret; +} + +AVCodec ff_aac_decoder = { + .name = "aac", + .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AAC, + .priv_data_size = sizeof(AACContext), + .init = aac_decode_init, + .close = aac_decode_close, + .decode = aac_decode_frame, + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE + }, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .channel_layouts = aac_channel_layout, + .flush = flush, + .priv_class = &aac_decoder_class, + .profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles), +}; + +/* + Note: This decoder filter is intended to decode LATM streams transferred + in MPEG transport streams which only contain one program. + To do a more complex LATM demuxing a separate LATM demuxer should be used. +*/ +AVCodec ff_aac_latm_decoder = { + .name = "aac_latm", + .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AAC_LATM, + .priv_data_size = sizeof(struct LATMContext), + .init = latm_decode_init, + .close = aac_decode_close, + .decode = latm_decode_frame, + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE + }, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .channel_layouts = aac_channel_layout, + .flush = flush, + .profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles), +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec_fixed.c new file mode 100644 index 000000000..1d0142fdb --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec_fixed.c @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2013 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * AAC decoder fixed-point implementation + * + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC decoder + * @author Oded Shimon ( ods15 ods15 dyndns org ) + * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) + * + * Fixed point implementation + * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com ) + */ + +#define FFT_FLOAT 0 +#define FFT_FIXED_32 1 +#define USE_FIXED 1 + +#include "libavutil/fixed_dsp.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "internal.h" +#include "get_bits.h" +#include "fft.h" +#include "lpc.h" +#include "kbdwin.h" +#include "sinewin.h" + +#include "aac.h" +#include "aactab.h" +#include "aacdectab.h" +#include "adts_header.h" +#include "cbrt_data.h" +#include "sbr.h" +#include "aacsbr.h" +#include "mpeg4audio.h" +#include "profiles.h" +#include "libavutil/intfloat.h" + +#include +#include + +static av_always_inline void reset_predict_state(PredictorState *ps) +{ + ps->r0.mant = 0; + ps->r0.exp = 0; + ps->r1.mant = 0; + ps->r1.exp = 0; + ps->cor0.mant = 0; + ps->cor0.exp = 0; + ps->cor1.mant = 0; + ps->cor1.exp = 0; + ps->var0.mant = 0x20000000; + ps->var0.exp = 1; + ps->var1.mant = 0x20000000; + ps->var1.exp = 1; +} + +static const int exp2tab[4] = { Q31(1.0000000000/2), Q31(1.1892071150/2), Q31(1.4142135624/2), Q31(1.6817928305/2) }; // 2^0, 2^0.25, 2^0.5, 2^0.75 + +static inline int *DEC_SPAIR(int *dst, unsigned idx) +{ + dst[0] = (idx & 15) - 4; + dst[1] = (idx >> 4 & 15) - 4; + + return dst + 2; +} + +static inline int *DEC_SQUAD(int *dst, unsigned idx) +{ + dst[0] = (idx & 3) - 1; + dst[1] = (idx >> 2 & 3) - 1; + dst[2] = (idx >> 4 & 3) - 1; + dst[3] = (idx >> 6 & 3) - 1; + + return dst + 4; +} + +static inline int *DEC_UPAIR(int *dst, unsigned idx, unsigned sign) +{ + dst[0] = (idx & 15) * (1 - (sign & 0xFFFFFFFE)); + dst[1] = (idx >> 4 & 15) * (1 - ((sign & 1) * 2)); + + return dst + 2; +} + +static inline int *DEC_UQUAD(int *dst, unsigned idx, unsigned sign) +{ + unsigned nz = idx >> 12; + + dst[0] = (idx & 3) * (1 + (((int)sign >> 31) * 2)); + sign <<= nz & 1; + nz >>= 1; + dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) * 2)); + sign <<= nz & 1; + nz >>= 1; + dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) * 2)); + sign <<= nz & 1; + nz >>= 1; + dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) * 2)); + + return dst + 4; +} + +static void vector_pow43(int *coefs, int len) +{ + int i, coef; + + for (i=0; i> 2); + + if (s > 31) { + for (i=0; i 0) { + round = 1 << (s-1); + for (i=0; i> 32); + dst[i] = ((int)(out+round) >> s) * ssign; + } + } else if (s > -32) { + s = s + 32; + round = 1U << (s-1); + for (i=0; i> s); + dst[i] = out * (unsigned)ssign; + } + } else { + av_log(log_context, AV_LOG_ERROR, "Overflow in subband_scale()\n"); + } +} + +static void noise_scale(int *coefs, int scale, int band_energy, int len) +{ + int s = -scale; + unsigned int round; + int i, out, c = exp2tab[s & 3]; + int nlz = 0; + + av_assert0(s >= 0); + while (band_energy > 0x7fff) { + band_energy >>= 1; + nlz++; + } + c /= band_energy; + s = 21 + nlz - (s >> 2); + + if (s > 31) { + for (i=0; i= 0) { + round = s ? 1 << (s-1) : 0; + for (i=0; i> 32); + coefs[i] = -((int)(out+round) >> s); + } + } + else { + s = s + 32; + if (s > 0) { + round = 1 << (s-1); + for (i=0; i> s); + coefs[i] = -out; + } + } else { + for (i=0; i> 31; + tmp.mant = (pf.mant ^ s) - s; + tmp.mant = (tmp.mant + 0x00200000U) & 0xFFC00000U; + tmp.mant = (tmp.mant ^ s) - s; + + return tmp; +} + +static av_always_inline SoftFloat flt16_even(SoftFloat pf) +{ + SoftFloat tmp; + int s; + + tmp.exp = pf.exp; + s = pf.mant >> 31; + tmp.mant = (pf.mant ^ s) - s; + tmp.mant = (tmp.mant + 0x001FFFFFU + (tmp.mant & 0x00400000U >> 16)) & 0xFFC00000U; + tmp.mant = (tmp.mant ^ s) - s; + + return tmp; +} + +static av_always_inline SoftFloat flt16_trunc(SoftFloat pf) +{ + SoftFloat pun; + int s; + + pun.exp = pf.exp; + s = pf.mant >> 31; + pun.mant = (pf.mant ^ s) - s; + pun.mant = pun.mant & 0xFFC00000U; + pun.mant = (pun.mant ^ s) - s; + + return pun; +} + +static av_always_inline void predict(PredictorState *ps, int *coef, + int output_enable) +{ + const SoftFloat a = { 1023410176, 0 }; // 61.0 / 64 + const SoftFloat alpha = { 973078528, 0 }; // 29.0 / 32 + SoftFloat e0, e1; + SoftFloat pv; + SoftFloat k1, k2; + SoftFloat r0 = ps->r0, r1 = ps->r1; + SoftFloat cor0 = ps->cor0, cor1 = ps->cor1; + SoftFloat var0 = ps->var0, var1 = ps->var1; + SoftFloat tmp; + + if (var0.exp > 1 || (var0.exp == 1 && var0.mant > 0x20000000)) { + k1 = av_mul_sf(cor0, flt16_even(av_div_sf(a, var0))); + } + else { + k1.mant = 0; + k1.exp = 0; + } + + if (var1.exp > 1 || (var1.exp == 1 && var1.mant > 0x20000000)) { + k2 = av_mul_sf(cor1, flt16_even(av_div_sf(a, var1))); + } + else { + k2.mant = 0; + k2.exp = 0; + } + + tmp = av_mul_sf(k1, r0); + pv = flt16_round(av_add_sf(tmp, av_mul_sf(k2, r1))); + if (output_enable) { + int shift = 28 - pv.exp; + + if (shift < 31) { + if (shift > 0) { + *coef += (unsigned)((pv.mant + (1 << (shift - 1))) >> shift); + } else + *coef += (unsigned)pv.mant << -shift; + } + } + + e0 = av_int2sf(*coef, 2); + e1 = av_sub_sf(e0, tmp); + + ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1))); + tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1)); + tmp.exp--; + ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp)); + ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0))); + tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0)); + tmp.exp--; + ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp)); + + ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0)))); + ps->r0 = flt16_trunc(av_mul_sf(a, e0)); +} + + +static const int cce_scale_fixed[8] = { + Q30(1.0), //2^(0/8) + Q30(1.0905077327), //2^(1/8) + Q30(1.1892071150), //2^(2/8) + Q30(1.2968395547), //2^(3/8) + Q30(1.4142135624), //2^(4/8) + Q30(1.5422108254), //2^(5/8) + Q30(1.6817928305), //2^(6/8) + Q30(1.8340080864), //2^(7/8) +}; + +/** + * Apply dependent channel coupling (applied before IMDCT). + * + * @param index index into coupling gain array + */ +static void apply_dependent_coupling_fixed(AACContext *ac, + SingleChannelElement *target, + ChannelElement *cce, int index) +{ + IndividualChannelStream *ics = &cce->ch[0].ics; + const uint16_t *offsets = ics->swb_offset; + int *dest = target->coeffs; + const int *src = cce->ch[0].coeffs; + int g, i, group, k, idx = 0; + if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) { + av_log(ac->avctx, AV_LOG_ERROR, + "Dependent coupling is not supported together with LTP\n"); + return; + } + for (g = 0; g < ics->num_window_groups; g++) { + for (i = 0; i < ics->max_sfb; i++, idx++) { + if (cce->ch[0].band_type[idx] != ZERO_BT) { + const int gain = cce->coup.gain[index][idx]; + int shift, round, c, tmp; + + if (gain < 0) { + c = -cce_scale_fixed[-gain & 7]; + shift = (-gain-1024) >> 3; + } + else { + c = cce_scale_fixed[gain & 7]; + shift = (gain-1024) >> 3; + } + + if (shift < -31) { + // Nothing to do + } else if (shift < 0) { + shift = -shift; + round = 1 << (shift - 1); + + for (group = 0; group < ics->group_len[g]; group++) { + for (k = offsets[i]; k < offsets[i + 1]; k++) { + tmp = (int)(((int64_t)src[group * 128 + k] * c + \ + (int64_t)0x1000000000) >> 37); + dest[group * 128 + k] += (tmp + (int64_t)round) >> shift; + } + } + } + else { + for (group = 0; group < ics->group_len[g]; group++) { + for (k = offsets[i]; k < offsets[i + 1]; k++) { + tmp = (int)(((int64_t)src[group * 128 + k] * c + \ + (int64_t)0x1000000000) >> 37); + dest[group * 128 + k] += tmp * (1U << shift); + } + } + } + } + } + dest += ics->group_len[g] * 128; + src += ics->group_len[g] * 128; + } +} + +/** + * Apply independent channel coupling (applied after IMDCT). + * + * @param index index into coupling gain array + */ +static void apply_independent_coupling_fixed(AACContext *ac, + SingleChannelElement *target, + ChannelElement *cce, int index) +{ + int i, c, shift, round, tmp; + const int gain = cce->coup.gain[index][0]; + const int *src = cce->ch[0].ret; + unsigned int *dest = target->ret; + const int len = 1024 << (ac->oc[1].m4ac.sbr == 1); + + c = cce_scale_fixed[gain & 7]; + shift = (gain-1024) >> 3; + if (shift < -31) { + return; + } else if (shift < 0) { + shift = -shift; + round = 1 << (shift - 1); + + for (i = 0; i < len; i++) { + tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37); + dest[i] += (tmp + round) >> shift; + } + } + else { + for (i = 0; i < len; i++) { + tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37); + dest[i] += tmp * (1U << shift); + } + } +} + +#include "aacdec_template.c" + +AVCodec ff_aac_fixed_decoder = { + .name = "aac_fixed", + .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AAC, + .priv_data_size = sizeof(AACContext), + .init = aac_decode_init, + .close = aac_decode_close, + .decode = aac_decode_frame, + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE + }, + .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .channel_layouts = aac_channel_layout, + .profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles), + .flush = flush, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec_template.c new file mode 100644 index 000000000..28765c768 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdec_template.c @@ -0,0 +1,3450 @@ +/* + * AAC decoder + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * Copyright (c) 2008-2013 Alex Converse + * + * AAC LATM decoder + * Copyright (c) 2008-2010 Paul Kendall + * Copyright (c) 2010 Janne Grunau + * + * AAC decoder fixed-point implementation + * Copyright (c) 2013 + * MIPS Technologies, Inc., California. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC decoder + * @author Oded Shimon ( ods15 ods15 dyndns org ) + * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) + * + * AAC decoder fixed-point implementation + * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com ) + * @author Nedeljko Babic ( nedeljko.babic imgtec com ) + */ + +/* + * supported tools + * + * Support? Name + * N (code in SoC repo) gain control + * Y block switching + * Y window shapes - standard + * N window shapes - Low Delay + * Y filterbank - standard + * N (code in SoC repo) filterbank - Scalable Sample Rate + * Y Temporal Noise Shaping + * Y Long Term Prediction + * Y intensity stereo + * Y channel coupling + * Y frequency domain prediction + * Y Perceptual Noise Substitution + * Y Mid/Side stereo + * N Scalable Inverse AAC Quantization + * N Frequency Selective Switch + * N upsampling filter + * Y quantization & coding - AAC + * N quantization & coding - TwinVQ + * N quantization & coding - BSAC + * N AAC Error Resilience tools + * N Error Resilience payload syntax + * N Error Protection tool + * N CELP + * N Silence Compression + * N HVXC + * N HVXC 4kbits/s VR + * N Structured Audio tools + * N Structured Audio Sample Bank Format + * N MIDI + * N Harmonic and Individual Lines plus Noise + * N Text-To-Speech Interface + * Y Spectral Band Replication + * Y (not in this code) Layer-1 + * Y (not in this code) Layer-2 + * Y (not in this code) Layer-3 + * N SinuSoidal Coding (Transient, Sinusoid, Noise) + * Y Parametric Stereo + * N Direct Stream Transfer + * Y (not in fixed point code) Enhanced AAC Low Delay (ER AAC ELD) + * + * Note: - HE AAC v1 comprises LC AAC with Spectral Band Replication. + * - HE AAC v2 comprises LC AAC with Spectral Band Replication and + Parametric Stereo. + */ + +#include "libavutil/thread.h" + +static VLC vlc_scalefactors; +static VLC vlc_spectral[11]; + +static int output_configure(AACContext *ac, + uint8_t layout_map[MAX_ELEM_ID*4][3], int tags, + enum OCStatus oc_type, int get_new_frame); + +#define overread_err "Input buffer exhausted before END element found\n" + +static int count_channels(uint8_t (*layout)[3], int tags) +{ + int i, sum = 0; + for (i = 0; i < tags; i++) { + int syn_ele = layout[i][0]; + int pos = layout[i][2]; + sum += (1 + (syn_ele == TYPE_CPE)) * + (pos != AAC_CHANNEL_OFF && pos != AAC_CHANNEL_CC); + } + return sum; +} + +/** + * Check for the channel element in the current channel position configuration. + * If it exists, make sure the appropriate element is allocated and map the + * channel order to match the internal FFmpeg channel layout. + * + * @param che_pos current channel position configuration + * @param type channel element type + * @param id channel element id + * @param channels count of the number of channels in the configuration + * + * @return Returns error status. 0 - OK, !0 - error + */ +static av_cold int che_configure(AACContext *ac, + enum ChannelPosition che_pos, + int type, int id, int *channels) +{ + if (*channels >= MAX_CHANNELS) + return AVERROR_INVALIDDATA; + if (che_pos) { + if (!ac->che[type][id]) { + if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) + return AVERROR(ENOMEM); + AAC_RENAME(ff_aac_sbr_ctx_init)(ac, &ac->che[type][id]->sbr, type); + } + if (type != TYPE_CCE) { + if (*channels >= MAX_CHANNELS - (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))) { + av_log(ac->avctx, AV_LOG_ERROR, "Too many channels\n"); + return AVERROR_INVALIDDATA; + } + ac->output_element[(*channels)++] = &ac->che[type][id]->ch[0]; + if (type == TYPE_CPE || + (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1)) { + ac->output_element[(*channels)++] = &ac->che[type][id]->ch[1]; + } + } + } else { + if (ac->che[type][id]) + AAC_RENAME(ff_aac_sbr_ctx_close)(&ac->che[type][id]->sbr); + av_freep(&ac->che[type][id]); + } + return 0; +} + +static int frame_configure_elements(AVCodecContext *avctx) +{ + AACContext *ac = avctx->priv_data; + int type, id, ch, ret; + + /* set channel pointers to internal buffers by default */ + for (type = 0; type < 4; type++) { + for (id = 0; id < MAX_ELEM_ID; id++) { + ChannelElement *che = ac->che[type][id]; + if (che) { + che->ch[0].ret = che->ch[0].ret_buf; + che->ch[1].ret = che->ch[1].ret_buf; + } + } + } + + /* get output buffer */ + av_frame_unref(ac->frame); + if (!avctx->channels) + return 1; + + ac->frame->nb_samples = 2048; + if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0) + return ret; + + /* map output channel pointers to AVFrame data */ + for (ch = 0; ch < avctx->channels; ch++) { + if (ac->output_element[ch]) + ac->output_element[ch]->ret = (INTFLOAT *)ac->frame->extended_data[ch]; + } + + return 0; +} + +struct elem_to_channel { + uint64_t av_position; + uint8_t syn_ele; + uint8_t elem_id; + uint8_t aac_position; +}; + +static int assign_pair(struct elem_to_channel e2c_vec[MAX_ELEM_ID], + uint8_t (*layout_map)[3], int offset, uint64_t left, + uint64_t right, int pos) +{ + if (layout_map[offset][0] == TYPE_CPE) { + e2c_vec[offset] = (struct elem_to_channel) { + .av_position = left | right, + .syn_ele = TYPE_CPE, + .elem_id = layout_map[offset][1], + .aac_position = pos + }; + return 1; + } else { + e2c_vec[offset] = (struct elem_to_channel) { + .av_position = left, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[offset][1], + .aac_position = pos + }; + e2c_vec[offset + 1] = (struct elem_to_channel) { + .av_position = right, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[offset + 1][1], + .aac_position = pos + }; + return 2; + } +} + +static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, + int *current) +{ + int num_pos_channels = 0; + int first_cpe = 0; + int sce_parity = 0; + int i; + for (i = *current; i < tags; i++) { + if (layout_map[i][2] != pos) + break; + if (layout_map[i][0] == TYPE_CPE) { + if (sce_parity) { + if (pos == AAC_CHANNEL_FRONT && !first_cpe) { + sce_parity = 0; + } else { + return -1; + } + } + num_pos_channels += 2; + first_cpe = 1; + } else { + num_pos_channels++; + sce_parity ^= 1; + } + } + if (sce_parity && + ((pos == AAC_CHANNEL_FRONT && first_cpe) || pos == AAC_CHANNEL_SIDE)) + return -1; + *current = i; + return num_pos_channels; +} + +static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) +{ + int i, n, total_non_cc_elements; + struct elem_to_channel e2c_vec[4 * MAX_ELEM_ID] = { { 0 } }; + int num_front_channels, num_side_channels, num_back_channels; + uint64_t layout; + + if (FF_ARRAY_ELEMS(e2c_vec) < tags) + return 0; + + i = 0; + num_front_channels = + count_paired_channels(layout_map, tags, AAC_CHANNEL_FRONT, &i); + if (num_front_channels < 0) + return 0; + num_side_channels = + count_paired_channels(layout_map, tags, AAC_CHANNEL_SIDE, &i); + if (num_side_channels < 0) + return 0; + num_back_channels = + count_paired_channels(layout_map, tags, AAC_CHANNEL_BACK, &i); + if (num_back_channels < 0) + return 0; + + if (num_side_channels == 0 && num_back_channels >= 4) { + num_side_channels = 2; + num_back_channels -= 2; + } + + i = 0; + if (num_front_channels & 1) { + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_FRONT_CENTER, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_FRONT + }; + i++; + num_front_channels--; + } + if (num_front_channels >= 4) { + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_FRONT_LEFT_OF_CENTER, + AV_CH_FRONT_RIGHT_OF_CENTER, + AAC_CHANNEL_FRONT); + num_front_channels -= 2; + } + if (num_front_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_FRONT_LEFT, + AV_CH_FRONT_RIGHT, + AAC_CHANNEL_FRONT); + num_front_channels -= 2; + } + while (num_front_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + UINT64_MAX, + UINT64_MAX, + AAC_CHANNEL_FRONT); + num_front_channels -= 2; + } + + if (num_side_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_SIDE_LEFT, + AV_CH_SIDE_RIGHT, + AAC_CHANNEL_FRONT); + num_side_channels -= 2; + } + while (num_side_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + UINT64_MAX, + UINT64_MAX, + AAC_CHANNEL_SIDE); + num_side_channels -= 2; + } + + while (num_back_channels >= 4) { + i += assign_pair(e2c_vec, layout_map, i, + UINT64_MAX, + UINT64_MAX, + AAC_CHANNEL_BACK); + num_back_channels -= 2; + } + if (num_back_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_BACK_LEFT, + AV_CH_BACK_RIGHT, + AAC_CHANNEL_BACK); + num_back_channels -= 2; + } + if (num_back_channels) { + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_BACK_CENTER, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_BACK + }; + i++; + num_back_channels--; + } + + if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_LOW_FREQUENCY, + .syn_ele = TYPE_LFE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_LFE + }; + i++; + } + while (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { + e2c_vec[i] = (struct elem_to_channel) { + .av_position = UINT64_MAX, + .syn_ele = TYPE_LFE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_LFE + }; + i++; + } + + // Must choose a stable sort + total_non_cc_elements = n = i; + do { + int next_n = 0; + for (i = 1; i < n; i++) + if (e2c_vec[i - 1].av_position > e2c_vec[i].av_position) { + FFSWAP(struct elem_to_channel, e2c_vec[i - 1], e2c_vec[i]); + next_n = i; + } + n = next_n; + } while (n > 0); + + layout = 0; + for (i = 0; i < total_non_cc_elements; i++) { + layout_map[i][0] = e2c_vec[i].syn_ele; + layout_map[i][1] = e2c_vec[i].elem_id; + layout_map[i][2] = e2c_vec[i].aac_position; + if (e2c_vec[i].av_position != UINT64_MAX) { + layout |= e2c_vec[i].av_position; + } + } + + return layout; +} + +/** + * Save current output configuration if and only if it has been locked. + */ +static int push_output_configuration(AACContext *ac) { + int pushed = 0; + + if (ac->oc[1].status == OC_LOCKED || ac->oc[0].status == OC_NONE) { + ac->oc[0] = ac->oc[1]; + pushed = 1; + } + ac->oc[1].status = OC_NONE; + return pushed; +} + +/** + * Restore the previous output configuration if and only if the current + * configuration is unlocked. + */ +static void pop_output_configuration(AACContext *ac) { + if (ac->oc[1].status != OC_LOCKED && ac->oc[0].status != OC_NONE) { + ac->oc[1] = ac->oc[0]; + ac->avctx->channels = ac->oc[1].channels; + ac->avctx->channel_layout = ac->oc[1].channel_layout; + output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags, + ac->oc[1].status, 0); + } +} + +/** + * Configure output channel order based on the current program + * configuration element. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int output_configure(AACContext *ac, + uint8_t layout_map[MAX_ELEM_ID * 4][3], int tags, + enum OCStatus oc_type, int get_new_frame) +{ + AVCodecContext *avctx = ac->avctx; + int i, channels = 0, ret; + uint64_t layout = 0; + uint8_t id_map[TYPE_END][MAX_ELEM_ID] = {{ 0 }}; + uint8_t type_counts[TYPE_END] = { 0 }; + + if (ac->oc[1].layout_map != layout_map) { + memcpy(ac->oc[1].layout_map, layout_map, tags * sizeof(layout_map[0])); + ac->oc[1].layout_map_tags = tags; + } + for (i = 0; i < tags; i++) { + int type = layout_map[i][0]; + int id = layout_map[i][1]; + id_map[type][id] = type_counts[type]++; + if (id_map[type][id] >= MAX_ELEM_ID) { + avpriv_request_sample(ac->avctx, "Too large remapped id"); + return AVERROR_PATCHWELCOME; + } + } + // Try to sniff a reasonable channel order, otherwise output the + // channels in the order the PCE declared them. + if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) + layout = sniff_channel_order(layout_map, tags); + for (i = 0; i < tags; i++) { + int type = layout_map[i][0]; + int id = layout_map[i][1]; + int iid = id_map[type][id]; + int position = layout_map[i][2]; + // Allocate or free elements depending on if they are in the + // current program configuration. + ret = che_configure(ac, position, type, iid, &channels); + if (ret < 0) + return ret; + ac->tag_che_map[type][id] = ac->che[type][iid]; + } + if (ac->oc[1].m4ac.ps == 1 && channels == 2) { + if (layout == AV_CH_FRONT_CENTER) { + layout = AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT; + } else { + layout = 0; + } + } + + if (layout) avctx->channel_layout = layout; + ac->oc[1].channel_layout = layout; + avctx->channels = ac->oc[1].channels = channels; + ac->oc[1].status = oc_type; + + if (get_new_frame) { + if ((ret = frame_configure_elements(ac->avctx)) < 0) + return ret; + } + + return 0; +} + +static void flush(AVCodecContext *avctx) +{ + AACContext *ac= avctx->priv_data; + int type, i, j; + + for (type = 3; type >= 0; type--) { + for (i = 0; i < MAX_ELEM_ID; i++) { + ChannelElement *che = ac->che[type][i]; + if (che) { + for (j = 0; j <= 1; j++) { + memset(che->ch[j].saved, 0, sizeof(che->ch[j].saved)); + } + } + } + } +} + +/** + * Set up channel positions based on a default channel configuration + * as specified in table 1.17. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int set_default_channel_config(AVCodecContext *avctx, + uint8_t (*layout_map)[3], + int *tags, + int channel_config) +{ + if (channel_config < 1 || (channel_config > 7 && channel_config < 11) || + channel_config > 12) { + av_log(avctx, AV_LOG_ERROR, + "invalid default channel configuration (%d)\n", + channel_config); + return AVERROR_INVALIDDATA; + } + *tags = tags_per_config[channel_config]; + memcpy(layout_map, aac_channel_layout_map[channel_config - 1], + *tags * sizeof(*layout_map)); + + /* + * AAC specification has 7.1(wide) as a default layout for 8-channel streams. + * However, at least Nero AAC encoder encodes 7.1 streams using the default + * channel config 7, mapping the side channels of the original audio stream + * to the second AAC_CHANNEL_FRONT pair in the AAC stream. Similarly, e.g. FAAD + * decodes the second AAC_CHANNEL_FRONT pair as side channels, therefore decoding + * the incorrect streams as if they were correct (and as the encoder intended). + * + * As actual intended 7.1(wide) streams are very rare, default to assuming a + * 7.1 layout was intended. + */ + if (channel_config == 7 && avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) { + av_log(avctx, AV_LOG_INFO, "Assuming an incorrectly encoded 7.1 channel layout" + " instead of a spec-compliant 7.1(wide) layout, use -strict %d to decode" + " according to the specification instead.\n", FF_COMPLIANCE_STRICT); + layout_map[2][2] = AAC_CHANNEL_SIDE; + } + + return 0; +} + +static ChannelElement *get_che(AACContext *ac, int type, int elem_id) +{ + /* For PCE based channel configurations map the channels solely based + * on tags. */ + if (!ac->oc[1].m4ac.chan_config) { + return ac->tag_che_map[type][elem_id]; + } + // Allow single CPE stereo files to be signalled with mono configuration. + if (!ac->tags_mapped && type == TYPE_CPE && + ac->oc[1].m4ac.chan_config == 1) { + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int layout_map_tags; + push_output_configuration(ac); + + av_log(ac->avctx, AV_LOG_DEBUG, "mono with CPE\n"); + + if (set_default_channel_config(ac->avctx, layout_map, + &layout_map_tags, 2) < 0) + return NULL; + if (output_configure(ac, layout_map, layout_map_tags, + OC_TRIAL_FRAME, 1) < 0) + return NULL; + + ac->oc[1].m4ac.chan_config = 2; + ac->oc[1].m4ac.ps = 0; + } + // And vice-versa + if (!ac->tags_mapped && type == TYPE_SCE && + ac->oc[1].m4ac.chan_config == 2) { + uint8_t layout_map[MAX_ELEM_ID * 4][3]; + int layout_map_tags; + push_output_configuration(ac); + + av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n"); + + if (set_default_channel_config(ac->avctx, layout_map, + &layout_map_tags, 1) < 0) + return NULL; + if (output_configure(ac, layout_map, layout_map_tags, + OC_TRIAL_FRAME, 1) < 0) + return NULL; + + ac->oc[1].m4ac.chan_config = 1; + if (ac->oc[1].m4ac.sbr) + ac->oc[1].m4ac.ps = -1; + } + /* For indexed channel configurations map the channels solely based + * on position. */ + switch (ac->oc[1].m4ac.chan_config) { + case 12: + case 7: + if (ac->tags_mapped == 3 && type == TYPE_CPE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2]; + } + case 11: + if (ac->tags_mapped == 2 && + ac->oc[1].m4ac.chan_config == 11 && + type == TYPE_SCE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1]; + } + case 6: + /* Some streams incorrectly code 5.1 audio as + * SCE[0] CPE[0] CPE[1] SCE[1] + * instead of + * SCE[0] CPE[0] CPE[1] LFE[0]. + * If we seem to have encountered such a stream, transfer + * the LFE[0] element to the SCE[1]'s mapping */ + if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) { + if (!ac->warned_remapping_once && (type != TYPE_LFE || elem_id != 0)) { + av_log(ac->avctx, AV_LOG_WARNING, + "This stream seems to incorrectly report its last channel as %s[%d], mapping to LFE[0]\n", + type == TYPE_SCE ? "SCE" : "LFE", elem_id); + ac->warned_remapping_once++; + } + ac->tags_mapped++; + return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0]; + } + case 5: + if (ac->tags_mapped == 2 && type == TYPE_CPE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1]; + } + case 4: + /* Some streams incorrectly code 4.0 audio as + * SCE[0] CPE[0] LFE[0] + * instead of + * SCE[0] CPE[0] SCE[1]. + * If we seem to have encountered such a stream, transfer + * the SCE[1] element to the LFE[0]'s mapping */ + if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) { + if (!ac->warned_remapping_once && (type != TYPE_SCE || elem_id != 1)) { + av_log(ac->avctx, AV_LOG_WARNING, + "This stream seems to incorrectly report its last channel as %s[%d], mapping to SCE[1]\n", + type == TYPE_SCE ? "SCE" : "LFE", elem_id); + ac->warned_remapping_once++; + } + ac->tags_mapped++; + return ac->tag_che_map[type][elem_id] = ac->che[TYPE_SCE][1]; + } + if (ac->tags_mapped == 2 && + ac->oc[1].m4ac.chan_config == 4 && + type == TYPE_SCE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1]; + } + case 3: + case 2: + if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) && + type == TYPE_CPE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0]; + } else if (ac->oc[1].m4ac.chan_config == 2) { + return NULL; + } + case 1: + if (!ac->tags_mapped && type == TYPE_SCE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][0]; + } + default: + return NULL; + } +} + +/** + * Decode an array of 4 bit element IDs, optionally interleaved with a + * stereo/mono switching bit. + * + * @param type speaker type/position for these channels + */ +static void decode_channel_map(uint8_t layout_map[][3], + enum ChannelPosition type, + GetBitContext *gb, int n) +{ + while (n--) { + enum RawDataBlockType syn_ele; + switch (type) { + case AAC_CHANNEL_FRONT: + case AAC_CHANNEL_BACK: + case AAC_CHANNEL_SIDE: + syn_ele = get_bits1(gb); + break; + case AAC_CHANNEL_CC: + skip_bits1(gb); + syn_ele = TYPE_CCE; + break; + case AAC_CHANNEL_LFE: + syn_ele = TYPE_LFE; + break; + default: + // AAC_CHANNEL_OFF has no channel map + av_assert0(0); + } + layout_map[0][0] = syn_ele; + layout_map[0][1] = get_bits(gb, 4); + layout_map[0][2] = type; + layout_map++; + } +} + +static inline void relative_align_get_bits(GetBitContext *gb, + int reference_position) { + int n = (reference_position - get_bits_count(gb) & 7); + if (n) + skip_bits(gb, n); +} + +/** + * Decode program configuration element; reference: table 4.2. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, + uint8_t (*layout_map)[3], + GetBitContext *gb, int byte_align_ref) +{ + int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc; + int sampling_index; + int comment_len; + int tags; + + skip_bits(gb, 2); // object_type + + sampling_index = get_bits(gb, 4); + if (m4ac->sampling_index != sampling_index) + av_log(avctx, AV_LOG_WARNING, + "Sample rate index in program config element does not " + "match the sample rate index configured by the container.\n"); + + num_front = get_bits(gb, 4); + num_side = get_bits(gb, 4); + num_back = get_bits(gb, 4); + num_lfe = get_bits(gb, 2); + num_assoc_data = get_bits(gb, 3); + num_cc = get_bits(gb, 4); + + if (get_bits1(gb)) + skip_bits(gb, 4); // mono_mixdown_tag + if (get_bits1(gb)) + skip_bits(gb, 4); // stereo_mixdown_tag + + if (get_bits1(gb)) + skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround + + if (get_bits_left(gb) < 5 * (num_front + num_side + num_back + num_cc) + 4 *(num_lfe + num_assoc_data + num_cc)) { + av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err); + return -1; + } + decode_channel_map(layout_map , AAC_CHANNEL_FRONT, gb, num_front); + tags = num_front; + decode_channel_map(layout_map + tags, AAC_CHANNEL_SIDE, gb, num_side); + tags += num_side; + decode_channel_map(layout_map + tags, AAC_CHANNEL_BACK, gb, num_back); + tags += num_back; + decode_channel_map(layout_map + tags, AAC_CHANNEL_LFE, gb, num_lfe); + tags += num_lfe; + + skip_bits_long(gb, 4 * num_assoc_data); + + decode_channel_map(layout_map + tags, AAC_CHANNEL_CC, gb, num_cc); + tags += num_cc; + + relative_align_get_bits(gb, byte_align_ref); + + /* comment field, first byte is length */ + comment_len = get_bits(gb, 8) * 8; + if (get_bits_left(gb) < comment_len) { + av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err); + return AVERROR_INVALIDDATA; + } + skip_bits_long(gb, comment_len); + return tags; +} + +/** + * Decode GA "General Audio" specific configuration; reference: table 4.1. + * + * @param ac pointer to AACContext, may be null + * @param avctx pointer to AVCCodecContext, used for logging + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, + GetBitContext *gb, + int get_bit_alignment, + MPEG4AudioConfig *m4ac, + int channel_config) +{ + int extension_flag, ret, ep_config, res_flags; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int tags = 0; + +#if USE_FIXED + if (get_bits1(gb)) { // frameLengthFlag + avpriv_report_missing_feature(avctx, "Fixed point 960/120 MDCT window"); + return AVERROR_PATCHWELCOME; + } + m4ac->frame_length_short = 0; +#else + m4ac->frame_length_short = get_bits1(gb); + if (m4ac->frame_length_short && m4ac->sbr == 1) { + avpriv_report_missing_feature(avctx, "SBR with 960 frame length"); + if (ac) ac->warned_960_sbr = 1; + m4ac->sbr = 0; + m4ac->ps = 0; + } +#endif + + if (get_bits1(gb)) // dependsOnCoreCoder + skip_bits(gb, 14); // coreCoderDelay + extension_flag = get_bits1(gb); + + if (m4ac->object_type == AOT_AAC_SCALABLE || + m4ac->object_type == AOT_ER_AAC_SCALABLE) + skip_bits(gb, 3); // layerNr + + if (channel_config == 0) { + skip_bits(gb, 4); // element_instance_tag + tags = decode_pce(avctx, m4ac, layout_map, gb, get_bit_alignment); + if (tags < 0) + return tags; + } else { + if ((ret = set_default_channel_config(avctx, layout_map, + &tags, channel_config))) + return ret; + } + + if (count_channels(layout_map, tags) > 1) { + m4ac->ps = 0; + } else if (m4ac->sbr == 1 && m4ac->ps == -1) + m4ac->ps = 1; + + if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0))) + return ret; + + if (extension_flag) { + switch (m4ac->object_type) { + case AOT_ER_BSAC: + skip_bits(gb, 5); // numOfSubFrame + skip_bits(gb, 11); // layer_length + break; + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_SCALABLE: + case AOT_ER_AAC_LD: + res_flags = get_bits(gb, 3); + if (res_flags) { + avpriv_report_missing_feature(avctx, + "AAC data resilience (flags %x)", + res_flags); + return AVERROR_PATCHWELCOME; + } + break; + } + skip_bits1(gb); // extensionFlag3 (TBD in version 3) + } + switch (m4ac->object_type) { + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_SCALABLE: + case AOT_ER_AAC_LD: + ep_config = get_bits(gb, 2); + if (ep_config) { + avpriv_report_missing_feature(avctx, + "epConfig %d", ep_config); + return AVERROR_PATCHWELCOME; + } + } + return 0; +} + +static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx, + GetBitContext *gb, + MPEG4AudioConfig *m4ac, + int channel_config) +{ + int ret, ep_config, res_flags; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int tags = 0; + const int ELDEXT_TERM = 0; + + m4ac->ps = 0; + m4ac->sbr = 0; +#if USE_FIXED + if (get_bits1(gb)) { // frameLengthFlag + avpriv_request_sample(avctx, "960/120 MDCT window"); + return AVERROR_PATCHWELCOME; + } +#else + m4ac->frame_length_short = get_bits1(gb); +#endif + res_flags = get_bits(gb, 3); + if (res_flags) { + avpriv_report_missing_feature(avctx, + "AAC data resilience (flags %x)", + res_flags); + return AVERROR_PATCHWELCOME; + } + + if (get_bits1(gb)) { // ldSbrPresentFlag + avpriv_report_missing_feature(avctx, + "Low Delay SBR"); + return AVERROR_PATCHWELCOME; + } + + while (get_bits(gb, 4) != ELDEXT_TERM) { + int len = get_bits(gb, 4); + if (len == 15) + len += get_bits(gb, 8); + if (len == 15 + 255) + len += get_bits(gb, 16); + if (get_bits_left(gb) < len * 8 + 4) { + av_log(avctx, AV_LOG_ERROR, overread_err); + return AVERROR_INVALIDDATA; + } + skip_bits_long(gb, 8 * len); + } + + if ((ret = set_default_channel_config(avctx, layout_map, + &tags, channel_config))) + return ret; + + if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0))) + return ret; + + ep_config = get_bits(gb, 2); + if (ep_config) { + avpriv_report_missing_feature(avctx, + "epConfig %d", ep_config); + return AVERROR_PATCHWELCOME; + } + return 0; +} + +/** + * Decode audio specific configuration; reference: table 1.13. + * + * @param ac pointer to AACContext, may be null + * @param avctx pointer to AVCCodecContext, used for logging + * @param m4ac pointer to MPEG4AudioConfig, used for parsing + * @param gb buffer holding an audio specific config + * @param get_bit_alignment relative alignment for byte align operations + * @param sync_extension look for an appended sync extension + * + * @return Returns error status or number of consumed bits. <0 - error + */ +static int decode_audio_specific_config_gb(AACContext *ac, + AVCodecContext *avctx, + MPEG4AudioConfig *m4ac, + GetBitContext *gb, + int get_bit_alignment, + int sync_extension) +{ + int i, ret; + GetBitContext gbc = *gb; + + if ((i = ff_mpeg4audio_get_config_gb(m4ac, &gbc, sync_extension)) < 0) + return AVERROR_INVALIDDATA; + + if (m4ac->sampling_index > 12) { + av_log(avctx, AV_LOG_ERROR, + "invalid sampling rate index %d\n", + m4ac->sampling_index); + return AVERROR_INVALIDDATA; + } + if (m4ac->object_type == AOT_ER_AAC_LD && + (m4ac->sampling_index < 3 || m4ac->sampling_index > 7)) { + av_log(avctx, AV_LOG_ERROR, + "invalid low delay sampling rate index %d\n", + m4ac->sampling_index); + return AVERROR_INVALIDDATA; + } + + skip_bits_long(gb, i); + + switch (m4ac->object_type) { + case AOT_AAC_MAIN: + case AOT_AAC_LC: + case AOT_AAC_SSR: + case AOT_AAC_LTP: + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LD: + if ((ret = decode_ga_specific_config(ac, avctx, gb, get_bit_alignment, + m4ac, m4ac->chan_config)) < 0) + return ret; + break; + case AOT_ER_AAC_ELD: + if ((ret = decode_eld_specific_config(ac, avctx, gb, + m4ac, m4ac->chan_config)) < 0) + return ret; + break; + default: + avpriv_report_missing_feature(avctx, + "Audio object type %s%d", + m4ac->sbr == 1 ? "SBR+" : "", + m4ac->object_type); + return AVERROR(ENOSYS); + } + + ff_dlog(avctx, + "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n", + m4ac->object_type, m4ac->chan_config, m4ac->sampling_index, + m4ac->sample_rate, m4ac->sbr, + m4ac->ps); + + return get_bits_count(gb); +} + +static int decode_audio_specific_config(AACContext *ac, + AVCodecContext *avctx, + MPEG4AudioConfig *m4ac, + const uint8_t *data, int64_t bit_size, + int sync_extension) +{ + int i, ret; + GetBitContext gb; + + if (bit_size < 0 || bit_size > INT_MAX) { + av_log(avctx, AV_LOG_ERROR, "Audio specific config size is invalid\n"); + return AVERROR_INVALIDDATA; + } + + ff_dlog(avctx, "audio specific config size %d\n", (int)bit_size >> 3); + for (i = 0; i < bit_size >> 3; i++) + ff_dlog(avctx, "%02x ", data[i]); + ff_dlog(avctx, "\n"); + + if ((ret = init_get_bits(&gb, data, bit_size)) < 0) + return ret; + + return decode_audio_specific_config_gb(ac, avctx, m4ac, &gb, 0, + sync_extension); +} + +/** + * linear congruential pseudorandom number generator + * + * @param previous_val pointer to the current state of the generator + * + * @return Returns a 32-bit pseudorandom integer + */ +static av_always_inline int lcg_random(unsigned previous_val) +{ + union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 }; + return v.s; +} + +static void reset_all_predictors(PredictorState *ps) +{ + int i; + for (i = 0; i < MAX_PREDICTORS; i++) + reset_predict_state(&ps[i]); +} + +static int sample_rate_idx (int rate) +{ + if (92017 <= rate) return 0; + else if (75132 <= rate) return 1; + else if (55426 <= rate) return 2; + else if (46009 <= rate) return 3; + else if (37566 <= rate) return 4; + else if (27713 <= rate) return 5; + else if (23004 <= rate) return 6; + else if (18783 <= rate) return 7; + else if (13856 <= rate) return 8; + else if (11502 <= rate) return 9; + else if (9391 <= rate) return 10; + else return 11; +} + +static void reset_predictor_group(PredictorState *ps, int group_num) +{ + int i; + for (i = group_num - 1; i < MAX_PREDICTORS; i += 30) + reset_predict_state(&ps[i]); +} + +#define AAC_INIT_VLC_STATIC(num, size) \ + INIT_VLC_STATIC(&vlc_spectral[num], 8, ff_aac_spectral_sizes[num], \ + ff_aac_spectral_bits[num], sizeof(ff_aac_spectral_bits[num][0]), \ + sizeof(ff_aac_spectral_bits[num][0]), \ + ff_aac_spectral_codes[num], sizeof(ff_aac_spectral_codes[num][0]), \ + sizeof(ff_aac_spectral_codes[num][0]), \ + size); + +static void aacdec_init(AACContext *ac); + +static av_cold void aac_static_table_init(void) +{ + AAC_INIT_VLC_STATIC( 0, 304); + AAC_INIT_VLC_STATIC( 1, 270); + AAC_INIT_VLC_STATIC( 2, 550); + AAC_INIT_VLC_STATIC( 3, 300); + AAC_INIT_VLC_STATIC( 4, 328); + AAC_INIT_VLC_STATIC( 5, 294); + AAC_INIT_VLC_STATIC( 6, 306); + AAC_INIT_VLC_STATIC( 7, 268); + AAC_INIT_VLC_STATIC( 8, 510); + AAC_INIT_VLC_STATIC( 9, 366); + AAC_INIT_VLC_STATIC(10, 462); + + AAC_RENAME(ff_aac_sbr_init)(); + + ff_aac_tableinit(); + + INIT_VLC_STATIC(&vlc_scalefactors, 7, + FF_ARRAY_ELEMS(ff_aac_scalefactor_code), + ff_aac_scalefactor_bits, + sizeof(ff_aac_scalefactor_bits[0]), + sizeof(ff_aac_scalefactor_bits[0]), + ff_aac_scalefactor_code, + sizeof(ff_aac_scalefactor_code[0]), + sizeof(ff_aac_scalefactor_code[0]), + 352); + + // window initialization + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_long_1024), 4.0, 1024); + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_short_128), 6.0, 128); +#if !USE_FIXED + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_long_960), 4.0, 960); + AAC_RENAME(ff_kbd_window_init)(AAC_RENAME(ff_aac_kbd_short_120), 6.0, 120); + AAC_RENAME(ff_sine_window_init)(AAC_RENAME(ff_sine_960), 960); + AAC_RENAME(ff_sine_window_init)(AAC_RENAME(ff_sine_120), 120); +#endif + AAC_RENAME(ff_init_ff_sine_windows)(10); + AAC_RENAME(ff_init_ff_sine_windows)( 9); + AAC_RENAME(ff_init_ff_sine_windows)( 7); + + AAC_RENAME(ff_cbrt_tableinit)(); +} + +static AVOnce aac_table_init = AV_ONCE_INIT; + +static av_cold int aac_decode_init(AVCodecContext *avctx) +{ + AACContext *ac = avctx->priv_data; + int ret; + + ret = ff_thread_once(&aac_table_init, &aac_static_table_init); + if (ret != 0) + return AVERROR_UNKNOWN; + + ac->avctx = avctx; + ac->oc[1].m4ac.sample_rate = avctx->sample_rate; + + aacdec_init(ac); +#if USE_FIXED + avctx->sample_fmt = AV_SAMPLE_FMT_S32P; +#else + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; +#endif /* USE_FIXED */ + + if (avctx->extradata_size > 0) { + if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, + avctx->extradata, + avctx->extradata_size * 8LL, + 1)) < 0) + return ret; + } else { + int sr, i; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int layout_map_tags; + + sr = sample_rate_idx(avctx->sample_rate); + ac->oc[1].m4ac.sampling_index = sr; + ac->oc[1].m4ac.channels = avctx->channels; + ac->oc[1].m4ac.sbr = -1; + ac->oc[1].m4ac.ps = -1; + + for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++) + if (ff_mpeg4audio_channels[i] == avctx->channels) + break; + if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) { + i = 0; + } + ac->oc[1].m4ac.chan_config = i; + + if (ac->oc[1].m4ac.chan_config) { + int ret = set_default_channel_config(avctx, layout_map, + &layout_map_tags, ac->oc[1].m4ac.chan_config); + if (!ret) + output_configure(ac, layout_map, layout_map_tags, + OC_GLOBAL_HDR, 0); + else if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + } + } + + if (avctx->channels > MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Too many channels\n"); + return AVERROR_INVALIDDATA; + } + +#if USE_FIXED + ac->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & AV_CODEC_FLAG_BITEXACT); +#else + ac->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); +#endif /* USE_FIXED */ + if (!ac->fdsp) { + return AVERROR(ENOMEM); + } + + ac->random_state = 0x1f2e3d4c; + + AAC_RENAME_32(ff_mdct_init)(&ac->mdct, 11, 1, 1.0 / RANGE15(1024.0)); + AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ld, 10, 1, 1.0 / RANGE15(512.0)); + AAC_RENAME_32(ff_mdct_init)(&ac->mdct_small, 8, 1, 1.0 / RANGE15(128.0)); + AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ltp, 11, 0, RANGE15(-2.0)); +#if !USE_FIXED + ret = ff_mdct15_init(&ac->mdct120, 1, 3, 1.0f/(16*1024*120*2)); + if (ret < 0) + return ret; + ret = ff_mdct15_init(&ac->mdct480, 1, 5, 1.0f/(16*1024*960)); + if (ret < 0) + return ret; + ret = ff_mdct15_init(&ac->mdct960, 1, 6, 1.0f/(16*1024*960*2)); + if (ret < 0) + return ret; +#endif + + return 0; +} + +/** + * Skip data_stream_element; reference: table 4.10. + */ +static int skip_data_stream_element(AACContext *ac, GetBitContext *gb) +{ + int byte_align = get_bits1(gb); + int count = get_bits(gb, 8); + if (count == 255) + count += get_bits(gb, 8); + if (byte_align) + align_get_bits(gb); + + if (get_bits_left(gb) < 8 * count) { + av_log(ac->avctx, AV_LOG_ERROR, "skip_data_stream_element: "overread_err); + return AVERROR_INVALIDDATA; + } + skip_bits_long(gb, 8 * count); + return 0; +} + +static int decode_prediction(AACContext *ac, IndividualChannelStream *ics, + GetBitContext *gb) +{ + int sfb; + if (get_bits1(gb)) { + ics->predictor_reset_group = get_bits(gb, 5); + if (ics->predictor_reset_group == 0 || + ics->predictor_reset_group > 30) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid Predictor Reset Group.\n"); + return AVERROR_INVALIDDATA; + } + } + for (sfb = 0; sfb < FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]); sfb++) { + ics->prediction_used[sfb] = get_bits1(gb); + } + return 0; +} + +/** + * Decode Long Term Prediction data; reference: table 4.xx. + */ +static void decode_ltp(LongTermPrediction *ltp, + GetBitContext *gb, uint8_t max_sfb) +{ + int sfb; + + ltp->lag = get_bits(gb, 11); + ltp->coef = ltp_coef[get_bits(gb, 3)]; + for (sfb = 0; sfb < FFMIN(max_sfb, MAX_LTP_LONG_SFB); sfb++) + ltp->used[sfb] = get_bits1(gb); +} + +/** + * Decode Individual Channel Stream info; reference: table 4.6. + */ +static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, + GetBitContext *gb) +{ + const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac; + const int aot = m4ac->object_type; + const int sampling_index = m4ac->sampling_index; + int ret_fail = AVERROR_INVALIDDATA; + + if (aot != AOT_ER_AAC_ELD) { + if (get_bits1(gb)) { + av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n"); + if (ac->avctx->err_recognition & AV_EF_BITSTREAM) + return AVERROR_INVALIDDATA; + } + ics->window_sequence[1] = ics->window_sequence[0]; + ics->window_sequence[0] = get_bits(gb, 2); + if (aot == AOT_ER_AAC_LD && + ics->window_sequence[0] != ONLY_LONG_SEQUENCE) { + av_log(ac->avctx, AV_LOG_ERROR, + "AAC LD is only defined for ONLY_LONG_SEQUENCE but " + "window sequence %d found.\n", ics->window_sequence[0]); + ics->window_sequence[0] = ONLY_LONG_SEQUENCE; + return AVERROR_INVALIDDATA; + } + ics->use_kb_window[1] = ics->use_kb_window[0]; + ics->use_kb_window[0] = get_bits1(gb); + } + ics->num_window_groups = 1; + ics->group_len[0] = 1; + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + int i; + ics->max_sfb = get_bits(gb, 4); + for (i = 0; i < 7; i++) { + if (get_bits1(gb)) { + ics->group_len[ics->num_window_groups - 1]++; + } else { + ics->num_window_groups++; + ics->group_len[ics->num_window_groups - 1] = 1; + } + } + ics->num_windows = 8; + if (m4ac->frame_length_short) { + ics->swb_offset = ff_swb_offset_120[sampling_index]; + ics->num_swb = ff_aac_num_swb_120[sampling_index]; + } else { + ics->swb_offset = ff_swb_offset_128[sampling_index]; + ics->num_swb = ff_aac_num_swb_128[sampling_index]; + } + ics->tns_max_bands = ff_tns_max_bands_128[sampling_index]; + ics->predictor_present = 0; + } else { + ics->max_sfb = get_bits(gb, 6); + ics->num_windows = 1; + if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) { + if (m4ac->frame_length_short) { + ics->swb_offset = ff_swb_offset_480[sampling_index]; + ics->num_swb = ff_aac_num_swb_480[sampling_index]; + ics->tns_max_bands = ff_tns_max_bands_480[sampling_index]; + } else { + ics->swb_offset = ff_swb_offset_512[sampling_index]; + ics->num_swb = ff_aac_num_swb_512[sampling_index]; + ics->tns_max_bands = ff_tns_max_bands_512[sampling_index]; + } + if (!ics->num_swb || !ics->swb_offset) { + ret_fail = AVERROR_BUG; + goto fail; + } + } else { + if (m4ac->frame_length_short) { + ics->num_swb = ff_aac_num_swb_960[sampling_index]; + ics->swb_offset = ff_swb_offset_960[sampling_index]; + } else { + ics->num_swb = ff_aac_num_swb_1024[sampling_index]; + ics->swb_offset = ff_swb_offset_1024[sampling_index]; + } + ics->tns_max_bands = ff_tns_max_bands_1024[sampling_index]; + } + if (aot != AOT_ER_AAC_ELD) { + ics->predictor_present = get_bits1(gb); + ics->predictor_reset_group = 0; + } + if (ics->predictor_present) { + if (aot == AOT_AAC_MAIN) { + if (decode_prediction(ac, ics, gb)) { + goto fail; + } + } else if (aot == AOT_AAC_LC || + aot == AOT_ER_AAC_LC) { + av_log(ac->avctx, AV_LOG_ERROR, + "Prediction is not allowed in AAC-LC.\n"); + goto fail; + } else { + if (aot == AOT_ER_AAC_LD) { + av_log(ac->avctx, AV_LOG_ERROR, + "LTP in ER AAC LD not yet implemented.\n"); + ret_fail = AVERROR_PATCHWELCOME; + goto fail; + } + if ((ics->ltp.present = get_bits(gb, 1))) + decode_ltp(&ics->ltp, gb, ics->max_sfb); + } + } + } + + if (ics->max_sfb > ics->num_swb) { + av_log(ac->avctx, AV_LOG_ERROR, + "Number of scalefactor bands in group (%d) " + "exceeds limit (%d).\n", + ics->max_sfb, ics->num_swb); + goto fail; + } + + return 0; +fail: + ics->max_sfb = 0; + return ret_fail; +} + +/** + * Decode band types (section_data payload); reference: table 4.46. + * + * @param band_type array of the used band type + * @param band_type_run_end array of the last scalefactor band of a band type run + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_band_types(AACContext *ac, enum BandType band_type[120], + int band_type_run_end[120], GetBitContext *gb, + IndividualChannelStream *ics) +{ + int g, idx = 0; + const int bits = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ? 3 : 5; + for (g = 0; g < ics->num_window_groups; g++) { + int k = 0; + while (k < ics->max_sfb) { + uint8_t sect_end = k; + int sect_len_incr; + int sect_band_type = get_bits(gb, 4); + if (sect_band_type == 12) { + av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n"); + return AVERROR_INVALIDDATA; + } + do { + sect_len_incr = get_bits(gb, bits); + sect_end += sect_len_incr; + if (get_bits_left(gb) < 0) { + av_log(ac->avctx, AV_LOG_ERROR, "decode_band_types: "overread_err); + return AVERROR_INVALIDDATA; + } + if (sect_end > ics->max_sfb) { + av_log(ac->avctx, AV_LOG_ERROR, + "Number of bands (%d) exceeds limit (%d).\n", + sect_end, ics->max_sfb); + return AVERROR_INVALIDDATA; + } + } while (sect_len_incr == (1 << bits) - 1); + for (; k < sect_end; k++) { + band_type [idx] = sect_band_type; + band_type_run_end[idx++] = sect_end; + } + } + } + return 0; +} + +/** + * Decode scalefactors; reference: table 4.47. + * + * @param global_gain first scalefactor value as scalefactors are differentially coded + * @param band_type array of the used band type + * @param band_type_run_end array of the last scalefactor band of a band type run + * @param sf array of scalefactors or intensity stereo positions + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_scalefactors(AACContext *ac, INTFLOAT sf[120], GetBitContext *gb, + unsigned int global_gain, + IndividualChannelStream *ics, + enum BandType band_type[120], + int band_type_run_end[120]) +{ + int g, i, idx = 0; + int offset[3] = { global_gain, global_gain - NOISE_OFFSET, 0 }; + int clipped_offset; + int noise_flag = 1; + for (g = 0; g < ics->num_window_groups; g++) { + for (i = 0; i < ics->max_sfb;) { + int run_end = band_type_run_end[idx]; + if (band_type[idx] == ZERO_BT) { + for (; i < run_end; i++, idx++) + sf[idx] = FIXR(0.); + } else if ((band_type[idx] == INTENSITY_BT) || + (band_type[idx] == INTENSITY_BT2)) { + for (; i < run_end; i++, idx++) { + offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO; + clipped_offset = av_clip(offset[2], -155, 100); + if (offset[2] != clipped_offset) { + avpriv_request_sample(ac->avctx, + "If you heard an audible artifact, there may be a bug in the decoder. " + "Clipped intensity stereo position (%d -> %d)", + offset[2], clipped_offset); + } +#if USE_FIXED + sf[idx] = 100 - clipped_offset; +#else + sf[idx] = ff_aac_pow2sf_tab[-clipped_offset + POW_SF2_ZERO]; +#endif /* USE_FIXED */ + } + } else if (band_type[idx] == NOISE_BT) { + for (; i < run_end; i++, idx++) { + if (noise_flag-- > 0) + offset[1] += get_bits(gb, NOISE_PRE_BITS) - NOISE_PRE; + else + offset[1] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO; + clipped_offset = av_clip(offset[1], -100, 155); + if (offset[1] != clipped_offset) { + avpriv_request_sample(ac->avctx, + "If you heard an audible artifact, there may be a bug in the decoder. " + "Clipped noise gain (%d -> %d)", + offset[1], clipped_offset); + } +#if USE_FIXED + sf[idx] = -(100 + clipped_offset); +#else + sf[idx] = -ff_aac_pow2sf_tab[clipped_offset + POW_SF2_ZERO]; +#endif /* USE_FIXED */ + } + } else { + for (; i < run_end; i++, idx++) { + offset[0] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO; + if (offset[0] > 255U) { + av_log(ac->avctx, AV_LOG_ERROR, + "Scalefactor (%d) out of range.\n", offset[0]); + return AVERROR_INVALIDDATA; + } +#if USE_FIXED + sf[idx] = -offset[0]; +#else + sf[idx] = -ff_aac_pow2sf_tab[offset[0] - 100 + POW_SF2_ZERO]; +#endif /* USE_FIXED */ + } + } + } + } + return 0; +} + +/** + * Decode pulse data; reference: table 4.7. + */ +static int decode_pulses(Pulse *pulse, GetBitContext *gb, + const uint16_t *swb_offset, int num_swb) +{ + int i, pulse_swb; + pulse->num_pulse = get_bits(gb, 2) + 1; + pulse_swb = get_bits(gb, 6); + if (pulse_swb >= num_swb) + return -1; + pulse->pos[0] = swb_offset[pulse_swb]; + pulse->pos[0] += get_bits(gb, 5); + if (pulse->pos[0] >= swb_offset[num_swb]) + return -1; + pulse->amp[0] = get_bits(gb, 4); + for (i = 1; i < pulse->num_pulse; i++) { + pulse->pos[i] = get_bits(gb, 5) + pulse->pos[i - 1]; + if (pulse->pos[i] >= swb_offset[num_swb]) + return -1; + pulse->amp[i] = get_bits(gb, 4); + } + return 0; +} + +/** + * Decode Temporal Noise Shaping data; reference: table 4.48. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_tns(AACContext *ac, TemporalNoiseShaping *tns, + GetBitContext *gb, const IndividualChannelStream *ics) +{ + int w, filt, i, coef_len, coef_res, coef_compress; + const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE; + const int tns_max_order = is8 ? 7 : ac->oc[1].m4ac.object_type == AOT_AAC_MAIN ? 20 : 12; + for (w = 0; w < ics->num_windows; w++) { + if ((tns->n_filt[w] = get_bits(gb, 2 - is8))) { + coef_res = get_bits1(gb); + + for (filt = 0; filt < tns->n_filt[w]; filt++) { + int tmp2_idx; + tns->length[w][filt] = get_bits(gb, 6 - 2 * is8); + + if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) { + av_log(ac->avctx, AV_LOG_ERROR, + "TNS filter order %d is greater than maximum %d.\n", + tns->order[w][filt], tns_max_order); + tns->order[w][filt] = 0; + return AVERROR_INVALIDDATA; + } + if (tns->order[w][filt]) { + tns->direction[w][filt] = get_bits1(gb); + coef_compress = get_bits1(gb); + coef_len = coef_res + 3 - coef_compress; + tmp2_idx = 2 * coef_compress + coef_res; + + for (i = 0; i < tns->order[w][filt]; i++) + tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)]; + } + } + } + } + return 0; +} + +/** + * Decode Mid/Side data; reference: table 4.54. + * + * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s; + * [1] mask is decoded from bitstream; [2] mask is all 1s; + * [3] reserved for scalable AAC + */ +static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb, + int ms_present) +{ + int idx; + int max_idx = cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb; + if (ms_present == 1) { + for (idx = 0; idx < max_idx; idx++) + cpe->ms_mask[idx] = get_bits1(gb); + } else if (ms_present == 2) { + memset(cpe->ms_mask, 1, max_idx * sizeof(cpe->ms_mask[0])); + } +} + +/** + * Decode spectral data; reference: table 4.50. + * Dequantize and scale spectral data; reference: 4.6.3.3. + * + * @param coef array of dequantized, scaled spectral data + * @param sf array of scalefactors or intensity stereo positions + * @param pulse_present set if pulses are present + * @param pulse pointer to pulse data struct + * @param band_type array of the used band type + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024], + GetBitContext *gb, const INTFLOAT sf[120], + int pulse_present, const Pulse *pulse, + const IndividualChannelStream *ics, + enum BandType band_type[120]) +{ + int i, k, g, idx = 0; + const int c = 1024 / ics->num_windows; + const uint16_t *offsets = ics->swb_offset; + INTFLOAT *coef_base = coef; + + for (g = 0; g < ics->num_windows; g++) + memset(coef + g * 128 + offsets[ics->max_sfb], 0, + sizeof(INTFLOAT) * (c - offsets[ics->max_sfb])); + + for (g = 0; g < ics->num_window_groups; g++) { + unsigned g_len = ics->group_len[g]; + + for (i = 0; i < ics->max_sfb; i++, idx++) { + const unsigned cbt_m1 = band_type[idx] - 1; + INTFLOAT *cfo = coef + offsets[i]; + int off_len = offsets[i + 1] - offsets[i]; + int group; + + if (cbt_m1 >= INTENSITY_BT2 - 1) { + for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) { + memset(cfo, 0, off_len * sizeof(*cfo)); + } + } else if (cbt_m1 == NOISE_BT - 1) { + for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) { + INTFLOAT band_energy; +#if USE_FIXED + for (k = 0; k < off_len; k++) { + ac->random_state = lcg_random(ac->random_state); + cfo[k] = ac->random_state >> 3; + } + + band_energy = ac->fdsp->scalarproduct_fixed(cfo, cfo, off_len); + band_energy = fixed_sqrt(band_energy, 31); + noise_scale(cfo, sf[idx], band_energy, off_len); +#else + float scale; + + for (k = 0; k < off_len; k++) { + ac->random_state = lcg_random(ac->random_state); + cfo[k] = ac->random_state; + } + + band_energy = ac->fdsp->scalarproduct_float(cfo, cfo, off_len); + scale = sf[idx] / sqrtf(band_energy); + ac->fdsp->vector_fmul_scalar(cfo, cfo, scale, off_len); +#endif /* USE_FIXED */ + } + } else { +#if !USE_FIXED + const float *vq = ff_aac_codebook_vector_vals[cbt_m1]; +#endif /* !USE_FIXED */ + const uint16_t *cb_vector_idx = ff_aac_codebook_vector_idx[cbt_m1]; + VLC_TYPE (*vlc_tab)[2] = vlc_spectral[cbt_m1].table; + OPEN_READER(re, gb); + + switch (cbt_m1 >> 1) { + case 0: + for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) { + INTFLOAT *cf = cfo; + int len = off_len; + + do { + int code; + unsigned cb_idx; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + cb_idx = cb_vector_idx[code]; +#if USE_FIXED + cf = DEC_SQUAD(cf, cb_idx); +#else + cf = VMUL4(cf, vq, cb_idx, sf + idx); +#endif /* USE_FIXED */ + } while (len -= 4); + } + break; + + case 1: + for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) { + INTFLOAT *cf = cfo; + int len = off_len; + + do { + int code; + unsigned nnz; + unsigned cb_idx; + uint32_t bits; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + cb_idx = cb_vector_idx[code]; + nnz = cb_idx >> 8 & 15; + bits = nnz ? GET_CACHE(re, gb) : 0; + LAST_SKIP_BITS(re, gb, nnz); +#if USE_FIXED + cf = DEC_UQUAD(cf, cb_idx, bits); +#else + cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx); +#endif /* USE_FIXED */ + } while (len -= 4); + } + break; + + case 2: + for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) { + INTFLOAT *cf = cfo; + int len = off_len; + + do { + int code; + unsigned cb_idx; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + cb_idx = cb_vector_idx[code]; +#if USE_FIXED + cf = DEC_SPAIR(cf, cb_idx); +#else + cf = VMUL2(cf, vq, cb_idx, sf + idx); +#endif /* USE_FIXED */ + } while (len -= 2); + } + break; + + case 3: + case 4: + for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) { + INTFLOAT *cf = cfo; + int len = off_len; + + do { + int code; + unsigned nnz; + unsigned cb_idx; + unsigned sign; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + cb_idx = cb_vector_idx[code]; + nnz = cb_idx >> 8 & 15; + sign = nnz ? SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12) : 0; + LAST_SKIP_BITS(re, gb, nnz); +#if USE_FIXED + cf = DEC_UPAIR(cf, cb_idx, sign); +#else + cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx); +#endif /* USE_FIXED */ + } while (len -= 2); + } + break; + + default: + for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) { +#if USE_FIXED + int *icf = cfo; + int v; +#else + float *cf = cfo; + uint32_t *icf = (uint32_t *) cf; +#endif /* USE_FIXED */ + int len = off_len; + + do { + int code; + unsigned nzt, nnz; + unsigned cb_idx; + uint32_t bits; + int j; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + + if (!code) { + *icf++ = 0; + *icf++ = 0; + continue; + } + + cb_idx = cb_vector_idx[code]; + nnz = cb_idx >> 12; + nzt = cb_idx >> 8; + bits = SHOW_UBITS(re, gb, nnz) << (32-nnz); + LAST_SKIP_BITS(re, gb, nnz); + + for (j = 0; j < 2; j++) { + if (nzt & 1< 8) { + av_log(ac->avctx, AV_LOG_ERROR, "error in spectral data, ESC overflow\n"); + return AVERROR_INVALIDDATA; + } + + SKIP_BITS(re, gb, b + 1); + b += 4; + n = (1 << b) + SHOW_UBITS(re, gb, b); + LAST_SKIP_BITS(re, gb, b); +#if USE_FIXED + v = n; + if (bits & 1U<<31) + v = -v; + *icf++ = v; +#else + *icf++ = ff_cbrt_tab[n] | (bits & 1U<<31); +#endif /* USE_FIXED */ + bits <<= 1; + } else { +#if USE_FIXED + v = cb_idx & 15; + if (bits & 1U<<31) + v = -v; + *icf++ = v; +#else + unsigned v = ((const uint32_t*)vq)[cb_idx & 15]; + *icf++ = (bits & 1U<<31) | v; +#endif /* USE_FIXED */ + bits <<= !!v; + } + cb_idx >>= 4; + } + } while (len -= 2); +#if !USE_FIXED + ac->fdsp->vector_fmul_scalar(cfo, cfo, sf[idx], off_len); +#endif /* !USE_FIXED */ + } + } + + CLOSE_READER(re, gb); + } + } + coef += g_len << 7; + } + + if (pulse_present) { + idx = 0; + for (i = 0; i < pulse->num_pulse; i++) { + INTFLOAT co = coef_base[ pulse->pos[i] ]; + while (offsets[idx + 1] <= pulse->pos[i]) + idx++; + if (band_type[idx] != NOISE_BT && sf[idx]) { + INTFLOAT ico = -pulse->amp[i]; +#if USE_FIXED + if (co) { + ico = co + (co > 0 ? -ico : ico); + } + coef_base[ pulse->pos[i] ] = ico; +#else + if (co) { + co /= sf[idx]; + ico = co / sqrtf(sqrtf(fabsf(co))) + (co > 0 ? -ico : ico); + } + coef_base[ pulse->pos[i] ] = cbrtf(fabsf(ico)) * ico * sf[idx]; +#endif /* USE_FIXED */ + } + } + } +#if USE_FIXED + coef = coef_base; + idx = 0; + for (g = 0; g < ics->num_window_groups; g++) { + unsigned g_len = ics->group_len[g]; + + for (i = 0; i < ics->max_sfb; i++, idx++) { + const unsigned cbt_m1 = band_type[idx] - 1; + int *cfo = coef + offsets[i]; + int off_len = offsets[i + 1] - offsets[i]; + int group; + + if (cbt_m1 < NOISE_BT - 1) { + for (group = 0; group < (int)g_len; group++, cfo+=128) { + ac->vector_pow43(cfo, off_len); + ac->subband_scale(cfo, cfo, sf[idx], 34, off_len, ac->avctx); + } + } + } + coef += g_len << 7; + } +#endif /* USE_FIXED */ + return 0; +} + +/** + * Apply AAC-Main style frequency domain prediction. + */ +static void apply_prediction(AACContext *ac, SingleChannelElement *sce) +{ + int sfb, k; + + if (!sce->ics.predictor_initialized) { + reset_all_predictors(sce->predictor_state); + sce->ics.predictor_initialized = 1; + } + + if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { + for (sfb = 0; + sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]; + sfb++) { + for (k = sce->ics.swb_offset[sfb]; + k < sce->ics.swb_offset[sfb + 1]; + k++) { + predict(&sce->predictor_state[k], &sce->coeffs[k], + sce->ics.predictor_present && + sce->ics.prediction_used[sfb]); + } + } + if (sce->ics.predictor_reset_group) + reset_predictor_group(sce->predictor_state, + sce->ics.predictor_reset_group); + } else + reset_all_predictors(sce->predictor_state); +} + +static void decode_gain_control(SingleChannelElement * sce, GetBitContext * gb) +{ + // wd_num, wd_test, aloc_size + static const uint8_t gain_mode[4][3] = { + {1, 0, 5}, // ONLY_LONG_SEQUENCE = 0, + {2, 1, 2}, // LONG_START_SEQUENCE, + {8, 0, 2}, // EIGHT_SHORT_SEQUENCE, + {2, 1, 5}, // LONG_STOP_SEQUENCE + }; + + const int mode = sce->ics.window_sequence[0]; + uint8_t bd, wd, ad; + + // FIXME: Store the gain control data on |sce| and do something with it. + uint8_t max_band = get_bits(gb, 2); + for (bd = 0; bd < max_band; bd++) { + for (wd = 0; wd < gain_mode[mode][0]; wd++) { + uint8_t adjust_num = get_bits(gb, 3); + for (ad = 0; ad < adjust_num; ad++) { + skip_bits(gb, 4 + ((wd == 0 && gain_mode[mode][1]) + ? 4 + : gain_mode[mode][2])); + } + } + } +} + +/** + * Decode an individual_channel_stream payload; reference: table 4.44. + * + * @param common_window Channels have independent [0], or shared [1], Individual Channel Stream information. + * @param scale_flag scalable [1] or non-scalable [0] AAC (Unused until scalable AAC is implemented.) + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_ics(AACContext *ac, SingleChannelElement *sce, + GetBitContext *gb, int common_window, int scale_flag) +{ + Pulse pulse; + TemporalNoiseShaping *tns = &sce->tns; + IndividualChannelStream *ics = &sce->ics; + INTFLOAT *out = sce->coeffs; + int global_gain, eld_syntax, er_syntax, pulse_present = 0; + int ret; + + eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD; + er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD; + + /* This assignment is to silence a GCC warning about the variable being used + * uninitialized when in fact it always is. + */ + pulse.num_pulse = 0; + + global_gain = get_bits(gb, 8); + + if (!common_window && !scale_flag) { + ret = decode_ics_info(ac, ics, gb); + if (ret < 0) + goto fail; + } + + if ((ret = decode_band_types(ac, sce->band_type, + sce->band_type_run_end, gb, ics)) < 0) + goto fail; + if ((ret = decode_scalefactors(ac, sce->sf, gb, global_gain, ics, + sce->band_type, sce->band_type_run_end)) < 0) + goto fail; + + pulse_present = 0; + if (!scale_flag) { + if (!eld_syntax && (pulse_present = get_bits1(gb))) { + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + av_log(ac->avctx, AV_LOG_ERROR, + "Pulse tool not allowed in eight short sequence.\n"); + ret = AVERROR_INVALIDDATA; + goto fail; + } + if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) { + av_log(ac->avctx, AV_LOG_ERROR, + "Pulse data corrupt or invalid.\n"); + ret = AVERROR_INVALIDDATA; + goto fail; + } + } + tns->present = get_bits1(gb); + if (tns->present && !er_syntax) { + ret = decode_tns(ac, tns, gb, ics); + if (ret < 0) + goto fail; + } + if (!eld_syntax && get_bits1(gb)) { + decode_gain_control(sce, gb); + if (!ac->warned_gain_control) { + avpriv_report_missing_feature(ac->avctx, "Gain control"); + ac->warned_gain_control = 1; + } + } + // I see no textual basis in the spec for this occurring after SSR gain + // control, but this is what both reference and real implmentations do + if (tns->present && er_syntax) { + ret = decode_tns(ac, tns, gb, ics); + if (ret < 0) + goto fail; + } + } + + ret = decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, + &pulse, ics, sce->band_type); + if (ret < 0) + goto fail; + + if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN && !common_window) + apply_prediction(ac, sce); + + return 0; +fail: + tns->present = 0; + return ret; +} + +/** + * Mid/Side stereo decoding; reference: 4.6.8.1.3. + */ +static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe) +{ + const IndividualChannelStream *ics = &cpe->ch[0].ics; + INTFLOAT *ch0 = cpe->ch[0].coeffs; + INTFLOAT *ch1 = cpe->ch[1].coeffs; + int g, i, group, idx = 0; + const uint16_t *offsets = ics->swb_offset; + for (g = 0; g < ics->num_window_groups; g++) { + for (i = 0; i < ics->max_sfb; i++, idx++) { + if (cpe->ms_mask[idx] && + cpe->ch[0].band_type[idx] < NOISE_BT && + cpe->ch[1].band_type[idx] < NOISE_BT) { +#if USE_FIXED + for (group = 0; group < ics->group_len[g]; group++) { + ac->fdsp->butterflies_fixed(ch0 + group * 128 + offsets[i], + ch1 + group * 128 + offsets[i], + offsets[i+1] - offsets[i]); +#else + for (group = 0; group < ics->group_len[g]; group++) { + ac->fdsp->butterflies_float(ch0 + group * 128 + offsets[i], + ch1 + group * 128 + offsets[i], + offsets[i+1] - offsets[i]); +#endif /* USE_FIXED */ + } + } + } + ch0 += ics->group_len[g] * 128; + ch1 += ics->group_len[g] * 128; + } +} + +/** + * intensity stereo decoding; reference: 4.6.8.2.3 + * + * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s; + * [1] mask is decoded from bitstream; [2] mask is all 1s; + * [3] reserved for scalable AAC + */ +static void apply_intensity_stereo(AACContext *ac, + ChannelElement *cpe, int ms_present) +{ + const IndividualChannelStream *ics = &cpe->ch[1].ics; + SingleChannelElement *sce1 = &cpe->ch[1]; + INTFLOAT *coef0 = cpe->ch[0].coeffs, *coef1 = cpe->ch[1].coeffs; + const uint16_t *offsets = ics->swb_offset; + int g, group, i, idx = 0; + int c; + INTFLOAT scale; + for (g = 0; g < ics->num_window_groups; g++) { + for (i = 0; i < ics->max_sfb;) { + if (sce1->band_type[idx] == INTENSITY_BT || + sce1->band_type[idx] == INTENSITY_BT2) { + const int bt_run_end = sce1->band_type_run_end[idx]; + for (; i < bt_run_end; i++, idx++) { + c = -1 + 2 * (sce1->band_type[idx] - 14); + if (ms_present) + c *= 1 - 2 * cpe->ms_mask[idx]; + scale = c * sce1->sf[idx]; + for (group = 0; group < ics->group_len[g]; group++) +#if USE_FIXED + ac->subband_scale(coef1 + group * 128 + offsets[i], + coef0 + group * 128 + offsets[i], + scale, + 23, + offsets[i + 1] - offsets[i] ,ac->avctx); +#else + ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[i], + coef0 + group * 128 + offsets[i], + scale, + offsets[i + 1] - offsets[i]); +#endif /* USE_FIXED */ + } + } else { + int bt_run_end = sce1->band_type_run_end[idx]; + idx += bt_run_end - i; + i = bt_run_end; + } + } + coef0 += ics->group_len[g] * 128; + coef1 += ics->group_len[g] * 128; + } +} + +/** + * Decode a channel_pair_element; reference: table 4.4. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe) +{ + int i, ret, common_window, ms_present = 0; + int eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD; + + common_window = eld_syntax || get_bits1(gb); + if (common_window) { + if (decode_ics_info(ac, &cpe->ch[0].ics, gb)) + return AVERROR_INVALIDDATA; + i = cpe->ch[1].ics.use_kb_window[0]; + cpe->ch[1].ics = cpe->ch[0].ics; + cpe->ch[1].ics.use_kb_window[1] = i; + if (cpe->ch[1].ics.predictor_present && + (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN)) + if ((cpe->ch[1].ics.ltp.present = get_bits(gb, 1))) + decode_ltp(&cpe->ch[1].ics.ltp, gb, cpe->ch[1].ics.max_sfb); + ms_present = get_bits(gb, 2); + if (ms_present == 3) { + av_log(ac->avctx, AV_LOG_ERROR, "ms_present = 3 is reserved.\n"); + return AVERROR_INVALIDDATA; + } else if (ms_present) + decode_mid_side_stereo(cpe, gb, ms_present); + } + if ((ret = decode_ics(ac, &cpe->ch[0], gb, common_window, 0))) + return ret; + if ((ret = decode_ics(ac, &cpe->ch[1], gb, common_window, 0))) + return ret; + + if (common_window) { + if (ms_present) + apply_mid_side_stereo(ac, cpe); + if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) { + apply_prediction(ac, &cpe->ch[0]); + apply_prediction(ac, &cpe->ch[1]); + } + } + + apply_intensity_stereo(ac, cpe, ms_present); + return 0; +} + +static const float cce_scale[] = { + 1.09050773266525765921, //2^(1/8) + 1.18920711500272106672, //2^(1/4) + M_SQRT2, + 2, +}; + +/** + * Decode coupling_channel_element; reference: table 4.8. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che) +{ + int num_gain = 0; + int c, g, sfb, ret; + int sign; + INTFLOAT scale; + SingleChannelElement *sce = &che->ch[0]; + ChannelCoupling *coup = &che->coup; + + coup->coupling_point = 2 * get_bits1(gb); + coup->num_coupled = get_bits(gb, 3); + for (c = 0; c <= coup->num_coupled; c++) { + num_gain++; + coup->type[c] = get_bits1(gb) ? TYPE_CPE : TYPE_SCE; + coup->id_select[c] = get_bits(gb, 4); + if (coup->type[c] == TYPE_CPE) { + coup->ch_select[c] = get_bits(gb, 2); + if (coup->ch_select[c] == 3) + num_gain++; + } else + coup->ch_select[c] = 2; + } + coup->coupling_point += get_bits1(gb) || (coup->coupling_point >> 1); + + sign = get_bits(gb, 1); +#if USE_FIXED + scale = get_bits(gb, 2); +#else + scale = cce_scale[get_bits(gb, 2)]; +#endif + + if ((ret = decode_ics(ac, sce, gb, 0, 0))) + return ret; + + for (c = 0; c < num_gain; c++) { + int idx = 0; + int cge = 1; + int gain = 0; + INTFLOAT gain_cache = FIXR10(1.); + if (c) { + cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb); + gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0; + gain_cache = GET_GAIN(scale, gain); +#if USE_FIXED + if ((abs(gain_cache)-1024) >> 3 > 30) + return AVERROR(ERANGE); +#endif + } + if (coup->coupling_point == AFTER_IMDCT) { + coup->gain[c][0] = gain_cache; + } else { + for (g = 0; g < sce->ics.num_window_groups; g++) { + for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) { + if (sce->band_type[idx] != ZERO_BT) { + if (!cge) { + int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; + if (t) { + int s = 1; + t = gain += t; + if (sign) { + s -= 2 * (t & 0x1); + t >>= 1; + } + gain_cache = GET_GAIN(scale, t) * s; +#if USE_FIXED + if ((abs(gain_cache)-1024) >> 3 > 30) + return AVERROR(ERANGE); +#endif + } + } + coup->gain[c][idx] = gain_cache; + } + } + } + } + } + return 0; +} + +/** + * Parse whether channels are to be excluded from Dynamic Range Compression; reference: table 4.53. + * + * @return Returns number of bytes consumed. + */ +static int decode_drc_channel_exclusions(DynamicRangeControl *che_drc, + GetBitContext *gb) +{ + int i; + int num_excl_chan = 0; + + do { + for (i = 0; i < 7; i++) + che_drc->exclude_mask[num_excl_chan++] = get_bits1(gb); + } while (num_excl_chan < MAX_CHANNELS - 7 && get_bits1(gb)); + + return num_excl_chan / 7; +} + +/** + * Decode dynamic range information; reference: table 4.52. + * + * @return Returns number of bytes consumed. + */ +static int decode_dynamic_range(DynamicRangeControl *che_drc, + GetBitContext *gb) +{ + int n = 1; + int drc_num_bands = 1; + int i; + + /* pce_tag_present? */ + if (get_bits1(gb)) { + che_drc->pce_instance_tag = get_bits(gb, 4); + skip_bits(gb, 4); // tag_reserved_bits + n++; + } + + /* excluded_chns_present? */ + if (get_bits1(gb)) { + n += decode_drc_channel_exclusions(che_drc, gb); + } + + /* drc_bands_present? */ + if (get_bits1(gb)) { + che_drc->band_incr = get_bits(gb, 4); + che_drc->interpolation_scheme = get_bits(gb, 4); + n++; + drc_num_bands += che_drc->band_incr; + for (i = 0; i < drc_num_bands; i++) { + che_drc->band_top[i] = get_bits(gb, 8); + n++; + } + } + + /* prog_ref_level_present? */ + if (get_bits1(gb)) { + che_drc->prog_ref_level = get_bits(gb, 7); + skip_bits1(gb); // prog_ref_level_reserved_bits + n++; + } + + for (i = 0; i < drc_num_bands; i++) { + che_drc->dyn_rng_sgn[i] = get_bits1(gb); + che_drc->dyn_rng_ctl[i] = get_bits(gb, 7); + n++; + } + + return n; +} + +static int decode_fill(AACContext *ac, GetBitContext *gb, int len) { + uint8_t buf[256]; + int i, major, minor; + + if (len < 13+7*8) + goto unknown; + + get_bits(gb, 13); len -= 13; + + for(i=0; i+1=8; i++, len-=8) + buf[i] = get_bits(gb, 8); + + buf[i] = 0; + if (ac->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(ac->avctx, AV_LOG_DEBUG, "FILL:%s\n", buf); + + if (sscanf(buf, "libfaac %d.%d", &major, &minor) == 2){ + ac->avctx->internal->skip_samples = 1024; + } + +unknown: + skip_bits_long(gb, len); + + return 0; +} + +/** + * Decode extension data (incomplete); reference: table 4.51. + * + * @param cnt length of TYPE_FIL syntactic element in bytes + * + * @return Returns number of bytes consumed + */ +static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt, + ChannelElement *che, enum RawDataBlockType elem_type) +{ + int crc_flag = 0; + int res = cnt; + int type = get_bits(gb, 4); + + if (ac->avctx->debug & FF_DEBUG_STARTCODE) + av_log(ac->avctx, AV_LOG_DEBUG, "extension type: %d len:%d\n", type, cnt); + + switch (type) { // extension type + case EXT_SBR_DATA_CRC: + crc_flag++; + case EXT_SBR_DATA: + if (!che) { + av_log(ac->avctx, AV_LOG_ERROR, "SBR was found before the first channel element.\n"); + return res; + } else if (ac->oc[1].m4ac.frame_length_short) { + if (!ac->warned_960_sbr) + avpriv_report_missing_feature(ac->avctx, + "SBR with 960 frame length"); + ac->warned_960_sbr = 1; + skip_bits_long(gb, 8 * cnt - 4); + return res; + } else if (!ac->oc[1].m4ac.sbr) { + av_log(ac->avctx, AV_LOG_ERROR, "SBR signaled to be not-present but was found in the bitstream.\n"); + skip_bits_long(gb, 8 * cnt - 4); + return res; + } else if (ac->oc[1].m4ac.sbr == -1 && ac->oc[1].status == OC_LOCKED) { + av_log(ac->avctx, AV_LOG_ERROR, "Implicit SBR was found with a first occurrence after the first frame.\n"); + skip_bits_long(gb, 8 * cnt - 4); + return res; + } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) { + ac->oc[1].m4ac.sbr = 1; + ac->oc[1].m4ac.ps = 1; + ac->avctx->profile = FF_PROFILE_AAC_HE_V2; + output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags, + ac->oc[1].status, 1); + } else { + ac->oc[1].m4ac.sbr = 1; + ac->avctx->profile = FF_PROFILE_AAC_HE; + } + res = AAC_RENAME(ff_decode_sbr_extension)(ac, &che->sbr, gb, crc_flag, cnt, elem_type); + break; + case EXT_DYNAMIC_RANGE: + res = decode_dynamic_range(&ac->che_drc, gb); + break; + case EXT_FILL: + decode_fill(ac, gb, 8 * cnt - 4); + break; + case EXT_FILL_DATA: + case EXT_DATA_ELEMENT: + default: + skip_bits_long(gb, 8 * cnt - 4); + break; + }; + return res; +} + +/** + * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3. + * + * @param decode 1 if tool is used normally, 0 if tool is used in LTP. + * @param coef spectral coefficients + */ +static void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns, + IndividualChannelStream *ics, int decode) +{ + const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb); + int w, filt, m, i; + int bottom, top, order, start, end, size, inc; + INTFLOAT lpc[TNS_MAX_ORDER]; + INTFLOAT tmp[TNS_MAX_ORDER+1]; + UINTFLOAT *coef = coef_param; + + if(!mmm) + return; + + for (w = 0; w < ics->num_windows; w++) { + bottom = ics->num_swb; + for (filt = 0; filt < tns->n_filt[w]; filt++) { + top = bottom; + bottom = FFMAX(0, top - tns->length[w][filt]); + order = tns->order[w][filt]; + if (order == 0) + continue; + + // tns_decode_coef + AAC_RENAME(compute_lpc_coefs)(tns->coef[w][filt], order, lpc, 0, 0, 0); + + start = ics->swb_offset[FFMIN(bottom, mmm)]; + end = ics->swb_offset[FFMIN( top, mmm)]; + if ((size = end - start) <= 0) + continue; + if (tns->direction[w][filt]) { + inc = -1; + start = end - 1; + } else { + inc = 1; + } + start += w * 128; + + if (decode) { + // ar filter + for (m = 0; m < size; m++, start += inc) + for (i = 1; i <= FFMIN(m, order); i++) + coef[start] -= AAC_MUL26((INTFLOAT)coef[start - i * inc], lpc[i - 1]); + } else { + // ma filter + for (m = 0; m < size; m++, start += inc) { + tmp[0] = coef[start]; + for (i = 1; i <= FFMIN(m, order); i++) + coef[start] += AAC_MUL26(tmp[i], lpc[i - 1]); + for (i = order; i > 0; i--) + tmp[i] = tmp[i - 1]; + } + } + } + } +} + +/** + * Apply windowing and MDCT to obtain the spectral + * coefficient from the predicted sample by LTP. + */ +static void windowing_and_mdct_ltp(AACContext *ac, INTFLOAT *out, + INTFLOAT *in, IndividualChannelStream *ics) +{ + const INTFLOAT *lwindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_long_1024) : AAC_RENAME(ff_sine_1024); + const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); + const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_long_1024) : AAC_RENAME(ff_sine_1024); + const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); + + if (ics->window_sequence[0] != LONG_STOP_SEQUENCE) { + ac->fdsp->vector_fmul(in, in, lwindow_prev, 1024); + } else { + memset(in, 0, 448 * sizeof(*in)); + ac->fdsp->vector_fmul(in + 448, in + 448, swindow_prev, 128); + } + if (ics->window_sequence[0] != LONG_START_SEQUENCE) { + ac->fdsp->vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024); + } else { + ac->fdsp->vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128); + memset(in + 1024 + 576, 0, 448 * sizeof(*in)); + } + ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in); +} + +/** + * Apply the long term prediction + */ +static void apply_ltp(AACContext *ac, SingleChannelElement *sce) +{ + const LongTermPrediction *ltp = &sce->ics.ltp; + const uint16_t *offsets = sce->ics.swb_offset; + int i, sfb; + + if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { + INTFLOAT *predTime = sce->ret; + INTFLOAT *predFreq = ac->buf_mdct; + int16_t num_samples = 2048; + + if (ltp->lag < 1024) + num_samples = ltp->lag + 1024; + for (i = 0; i < num_samples; i++) + predTime[i] = AAC_MUL30(sce->ltp_state[i + 2048 - ltp->lag], ltp->coef); + memset(&predTime[i], 0, (2048 - i) * sizeof(*predTime)); + + ac->windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics); + + if (sce->tns.present) + ac->apply_tns(predFreq, &sce->tns, &sce->ics, 0); + + for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++) + if (ltp->used[sfb]) + for (i = offsets[sfb]; i < offsets[sfb + 1]; i++) + sce->coeffs[i] += (UINTFLOAT)predFreq[i]; + } +} + +/** + * Update the LTP buffer for next frame + */ +static void update_ltp(AACContext *ac, SingleChannelElement *sce) +{ + IndividualChannelStream *ics = &sce->ics; + INTFLOAT *saved = sce->saved; + INTFLOAT *saved_ltp = sce->coeffs; + const INTFLOAT *lwindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_long_1024) : AAC_RENAME(ff_sine_1024); + const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); + int i; + + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + memcpy(saved_ltp, saved, 512 * sizeof(*saved_ltp)); + memset(saved_ltp + 576, 0, 448 * sizeof(*saved_ltp)); + ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64); + + for (i = 0; i < 64; i++) + saved_ltp[i + 512] = AAC_MUL31(ac->buf_mdct[1023 - i], swindow[63 - i]); + } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) { + memcpy(saved_ltp, ac->buf_mdct + 512, 448 * sizeof(*saved_ltp)); + memset(saved_ltp + 576, 0, 448 * sizeof(*saved_ltp)); + ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64); + + for (i = 0; i < 64; i++) + saved_ltp[i + 512] = AAC_MUL31(ac->buf_mdct[1023 - i], swindow[63 - i]); + } else { // LONG_STOP or ONLY_LONG + ac->fdsp->vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512); + + for (i = 0; i < 512; i++) + saved_ltp[i + 512] = AAC_MUL31(ac->buf_mdct[1023 - i], lwindow[511 - i]); + } + + memcpy(sce->ltp_state, sce->ltp_state+1024, 1024 * sizeof(*sce->ltp_state)); + memcpy(sce->ltp_state+1024, sce->ret, 1024 * sizeof(*sce->ltp_state)); + memcpy(sce->ltp_state+2048, saved_ltp, 1024 * sizeof(*sce->ltp_state)); +} + +/** + * Conduct IMDCT and windowing. + */ +static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce) +{ + IndividualChannelStream *ics = &sce->ics; + INTFLOAT *in = sce->coeffs; + INTFLOAT *out = sce->ret; + INTFLOAT *saved = sce->saved; + const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); + const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_long_1024) : AAC_RENAME(ff_sine_1024); + const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_short_128) : AAC_RENAME(ff_sine_128); + INTFLOAT *buf = ac->buf_mdct; + INTFLOAT *temp = ac->temp; + int i; + + // imdct + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + for (i = 0; i < 1024; i += 128) + ac->mdct_small.imdct_half(&ac->mdct_small, buf + i, in + i); + } else { + ac->mdct.imdct_half(&ac->mdct, buf, in); +#if USE_FIXED + for (i=0; i<1024; i++) + buf[i] = (buf[i] + 4) >> 3; +#endif /* USE_FIXED */ + } + + /* window overlapping + * NOTE: To simplify the overlapping code, all 'meaningless' short to long + * and long to short transitions are considered to be short to short + * transitions. This leaves just two cases (long to long and short to short) + * with a little special sauce for EIGHT_SHORT_SEQUENCE. + */ + if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) && + (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) { + ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 512); + } else { + memcpy( out, saved, 448 * sizeof(*out)); + + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + ac->fdsp->vector_fmul_window(out + 448 + 0*128, saved + 448, buf + 0*128, swindow_prev, 64); + ac->fdsp->vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow, 64); + ac->fdsp->vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow, 64); + ac->fdsp->vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow, 64); + ac->fdsp->vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, swindow, 64); + memcpy( out + 448 + 4*128, temp, 64 * sizeof(*out)); + } else { + ac->fdsp->vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64); + memcpy( out + 576, buf + 64, 448 * sizeof(*out)); + } + } + + // buffer update + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + memcpy( saved, temp + 64, 64 * sizeof(*saved)); + ac->fdsp->vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64); + ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64); + ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64); + memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(*saved)); + } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) { + memcpy( saved, buf + 512, 448 * sizeof(*saved)); + memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(*saved)); + } else { // LONG_STOP or ONLY_LONG + memcpy( saved, buf + 512, 512 * sizeof(*saved)); + } +} + +/** + * Conduct IMDCT and windowing. + */ +static void imdct_and_windowing_960(AACContext *ac, SingleChannelElement *sce) +{ +#if !USE_FIXED + IndividualChannelStream *ics = &sce->ics; + INTFLOAT *in = sce->coeffs; + INTFLOAT *out = sce->ret; + INTFLOAT *saved = sce->saved; + const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(ff_aac_kbd_short_120) : AAC_RENAME(ff_sine_120); + const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_long_960) : AAC_RENAME(ff_sine_960); + const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(ff_aac_kbd_short_120) : AAC_RENAME(ff_sine_120); + INTFLOAT *buf = ac->buf_mdct; + INTFLOAT *temp = ac->temp; + int i; + + // imdct + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + for (i = 0; i < 8; i++) + ac->mdct120->imdct_half(ac->mdct120, buf + i * 120, in + i * 128, 1); + } else { + ac->mdct960->imdct_half(ac->mdct960, buf, in, 1); + } + + /* window overlapping + * NOTE: To simplify the overlapping code, all 'meaningless' short to long + * and long to short transitions are considered to be short to short + * transitions. This leaves just two cases (long to long and short to short) + * with a little special sauce for EIGHT_SHORT_SEQUENCE. + */ + + if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) && + (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) { + ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 480); + } else { + memcpy( out, saved, 420 * sizeof(*out)); + + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + ac->fdsp->vector_fmul_window(out + 420 + 0*120, saved + 420, buf + 0*120, swindow_prev, 60); + ac->fdsp->vector_fmul_window(out + 420 + 1*120, buf + 0*120 + 60, buf + 1*120, swindow, 60); + ac->fdsp->vector_fmul_window(out + 420 + 2*120, buf + 1*120 + 60, buf + 2*120, swindow, 60); + ac->fdsp->vector_fmul_window(out + 420 + 3*120, buf + 2*120 + 60, buf + 3*120, swindow, 60); + ac->fdsp->vector_fmul_window(temp, buf + 3*120 + 60, buf + 4*120, swindow, 60); + memcpy( out + 420 + 4*120, temp, 60 * sizeof(*out)); + } else { + ac->fdsp->vector_fmul_window(out + 420, saved + 420, buf, swindow_prev, 60); + memcpy( out + 540, buf + 60, 420 * sizeof(*out)); + } + } + + // buffer update + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + memcpy( saved, temp + 60, 60 * sizeof(*saved)); + ac->fdsp->vector_fmul_window(saved + 60, buf + 4*120 + 60, buf + 5*120, swindow, 60); + ac->fdsp->vector_fmul_window(saved + 180, buf + 5*120 + 60, buf + 6*120, swindow, 60); + ac->fdsp->vector_fmul_window(saved + 300, buf + 6*120 + 60, buf + 7*120, swindow, 60); + memcpy( saved + 420, buf + 7*120 + 60, 60 * sizeof(*saved)); + } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) { + memcpy( saved, buf + 480, 420 * sizeof(*saved)); + memcpy( saved + 420, buf + 7*120 + 60, 60 * sizeof(*saved)); + } else { // LONG_STOP or ONLY_LONG + memcpy( saved, buf + 480, 480 * sizeof(*saved)); + } +#endif +} +static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce) +{ + IndividualChannelStream *ics = &sce->ics; + INTFLOAT *in = sce->coeffs; + INTFLOAT *out = sce->ret; + INTFLOAT *saved = sce->saved; + INTFLOAT *buf = ac->buf_mdct; +#if USE_FIXED + int i; +#endif /* USE_FIXED */ + + // imdct + ac->mdct.imdct_half(&ac->mdct_ld, buf, in); + +#if USE_FIXED + for (i = 0; i < 1024; i++) + buf[i] = (buf[i] + 2) >> 2; +#endif /* USE_FIXED */ + + // window overlapping + if (ics->use_kb_window[1]) { + // AAC LD uses a low overlap sine window instead of a KBD window + memcpy(out, saved, 192 * sizeof(*out)); + ac->fdsp->vector_fmul_window(out + 192, saved + 192, buf, AAC_RENAME(ff_sine_128), 64); + memcpy( out + 320, buf + 64, 192 * sizeof(*out)); + } else { + ac->fdsp->vector_fmul_window(out, saved, buf, AAC_RENAME(ff_sine_512), 256); + } + + // buffer update + memcpy(saved, buf + 256, 256 * sizeof(*saved)); +} + +static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce) +{ + INTFLOAT *in = sce->coeffs; + INTFLOAT *out = sce->ret; + INTFLOAT *saved = sce->saved; + INTFLOAT *buf = ac->buf_mdct; + int i; + const int n = ac->oc[1].m4ac.frame_length_short ? 480 : 512; + const int n2 = n >> 1; + const int n4 = n >> 2; + const INTFLOAT *const window = n == 480 ? AAC_RENAME(ff_aac_eld_window_480) : + AAC_RENAME(ff_aac_eld_window_512); + + // Inverse transform, mapped to the conventional IMDCT by + // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V., + // "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks," + // International Conference on Audio, Language and Image Processing, ICALIP 2008. + // URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950 + for (i = 0; i < n2; i+=2) { + INTFLOAT temp; + temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp; + temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp; + } +#if !USE_FIXED + if (n == 480) + ac->mdct480->imdct_half(ac->mdct480, buf, in, 1); + else +#endif + ac->mdct.imdct_half(&ac->mdct_ld, buf, in); + +#if USE_FIXED + for (i = 0; i < 1024; i++) + buf[i] = (buf[i] + 1) >> 1; +#endif /* USE_FIXED */ + + for (i = 0; i < n; i+=2) { + buf[i] = -buf[i]; + } + // Like with the regular IMDCT at this point we still have the middle half + // of a transform but with even symmetry on the left and odd symmetry on + // the right + + // window overlapping + // The spec says to use samples [0..511] but the reference decoder uses + // samples [128..639]. + for (i = n4; i < n2; i ++) { + out[i - n4] = AAC_MUL31( buf[ n2 - 1 - i] , window[i - n4]) + + AAC_MUL31( saved[ i + n2] , window[i + n - n4]) + + AAC_MUL31(-saved[n + n2 - 1 - i] , window[i + 2*n - n4]) + + AAC_MUL31(-saved[ 2*n + n2 + i] , window[i + 3*n - n4]); + } + for (i = 0; i < n2; i ++) { + out[n4 + i] = AAC_MUL31( buf[ i] , window[i + n2 - n4]) + + AAC_MUL31(-saved[ n - 1 - i] , window[i + n2 + n - n4]) + + AAC_MUL31(-saved[ n + i] , window[i + n2 + 2*n - n4]) + + AAC_MUL31( saved[2*n + n - 1 - i] , window[i + n2 + 3*n - n4]); + } + for (i = 0; i < n4; i ++) { + out[n2 + n4 + i] = AAC_MUL31( buf[ i + n2] , window[i + n - n4]) + + AAC_MUL31(-saved[n2 - 1 - i] , window[i + 2*n - n4]) + + AAC_MUL31(-saved[n + n2 + i] , window[i + 3*n - n4]); + } + + // buffer update + memmove(saved + n, saved, 2 * n * sizeof(*saved)); + memcpy( saved, buf, n * sizeof(*saved)); +} + +/** + * channel coupling transformation interface + * + * @param apply_coupling_method pointer to (in)dependent coupling function + */ +static void apply_channel_coupling(AACContext *ac, ChannelElement *cc, + enum RawDataBlockType type, int elem_id, + enum CouplingPoint coupling_point, + void (*apply_coupling_method)(AACContext *ac, SingleChannelElement *target, ChannelElement *cce, int index)) +{ + int i, c; + + for (i = 0; i < MAX_ELEM_ID; i++) { + ChannelElement *cce = ac->che[TYPE_CCE][i]; + int index = 0; + + if (cce && cce->coup.coupling_point == coupling_point) { + ChannelCoupling *coup = &cce->coup; + + for (c = 0; c <= coup->num_coupled; c++) { + if (coup->type[c] == type && coup->id_select[c] == elem_id) { + if (coup->ch_select[c] != 1) { + apply_coupling_method(ac, &cc->ch[0], cce, index); + if (coup->ch_select[c] != 0) + index++; + } + if (coup->ch_select[c] != 2) + apply_coupling_method(ac, &cc->ch[1], cce, index++); + } else + index += 1 + (coup->ch_select[c] == 3); + } + } + } +} + +/** + * Convert spectral data to samples, applying all supported tools as appropriate. + */ +static void spectral_to_sample(AACContext *ac, int samples) +{ + int i, type; + void (*imdct_and_window)(AACContext *ac, SingleChannelElement *sce); + switch (ac->oc[1].m4ac.object_type) { + case AOT_ER_AAC_LD: + imdct_and_window = imdct_and_windowing_ld; + break; + case AOT_ER_AAC_ELD: + imdct_and_window = imdct_and_windowing_eld; + break; + default: + if (ac->oc[1].m4ac.frame_length_short) + imdct_and_window = imdct_and_windowing_960; + else + imdct_and_window = ac->imdct_and_windowing; + } + for (type = 3; type >= 0; type--) { + for (i = 0; i < MAX_ELEM_ID; i++) { + ChannelElement *che = ac->che[type][i]; + if (che && che->present) { + if (type <= TYPE_CPE) + apply_channel_coupling(ac, che, type, i, BEFORE_TNS, AAC_RENAME(apply_dependent_coupling)); + if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) { + if (che->ch[0].ics.predictor_present) { + if (che->ch[0].ics.ltp.present) + ac->apply_ltp(ac, &che->ch[0]); + if (che->ch[1].ics.ltp.present && type == TYPE_CPE) + ac->apply_ltp(ac, &che->ch[1]); + } + } + if (che->ch[0].tns.present) + ac->apply_tns(che->ch[0].coeffs, &che->ch[0].tns, &che->ch[0].ics, 1); + if (che->ch[1].tns.present) + ac->apply_tns(che->ch[1].coeffs, &che->ch[1].tns, &che->ch[1].ics, 1); + if (type <= TYPE_CPE) + apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, AAC_RENAME(apply_dependent_coupling)); + if (type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) { + imdct_and_window(ac, &che->ch[0]); + if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) + ac->update_ltp(ac, &che->ch[0]); + if (type == TYPE_CPE) { + imdct_and_window(ac, &che->ch[1]); + if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) + ac->update_ltp(ac, &che->ch[1]); + } + if (ac->oc[1].m4ac.sbr > 0) { + AAC_RENAME(ff_sbr_apply)(ac, &che->sbr, type, che->ch[0].ret, che->ch[1].ret); + } + } + if (type <= TYPE_CCE) + apply_channel_coupling(ac, che, type, i, AFTER_IMDCT, AAC_RENAME(apply_independent_coupling)); + +#if USE_FIXED + { + int j; + /* preparation for resampler */ + for(j = 0; jch[0].ret[j] = (int32_t)av_clip64((int64_t)che->ch[0].ret[j]*128, INT32_MIN, INT32_MAX-0x8000)+0x8000; + if(type == TYPE_CPE) + che->ch[1].ret[j] = (int32_t)av_clip64((int64_t)che->ch[1].ret[j]*128, INT32_MIN, INT32_MAX-0x8000)+0x8000; + } + } +#endif /* USE_FIXED */ + che->present = 0; + } else if (che) { + av_log(ac->avctx, AV_LOG_VERBOSE, "ChannelElement %d.%d missing \n", type, i); + } + } + } +} + +static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) +{ + int size; + AACADTSHeaderInfo hdr_info; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int layout_map_tags, ret; + + size = ff_adts_header_parse(gb, &hdr_info); + if (size > 0) { + if (!ac->warned_num_aac_frames && hdr_info.num_aac_frames != 1) { + // This is 2 for "VLB " audio in NSV files. + // See samples/nsv/vlb_audio. + avpriv_report_missing_feature(ac->avctx, + "More than one AAC RDB per ADTS frame"); + ac->warned_num_aac_frames = 1; + } + push_output_configuration(ac); + if (hdr_info.chan_config) { + ac->oc[1].m4ac.chan_config = hdr_info.chan_config; + if ((ret = set_default_channel_config(ac->avctx, + layout_map, + &layout_map_tags, + hdr_info.chan_config)) < 0) + return ret; + if ((ret = output_configure(ac, layout_map, layout_map_tags, + FFMAX(ac->oc[1].status, + OC_TRIAL_FRAME), 0)) < 0) + return ret; + } else { + ac->oc[1].m4ac.chan_config = 0; + /** + * dual mono frames in Japanese DTV can have chan_config 0 + * WITHOUT specifying PCE. + * thus, set dual mono as default. + */ + if (ac->dmono_mode && ac->oc[0].status == OC_NONE) { + layout_map_tags = 2; + layout_map[0][0] = layout_map[1][0] = TYPE_SCE; + layout_map[0][2] = layout_map[1][2] = AAC_CHANNEL_FRONT; + layout_map[0][1] = 0; + layout_map[1][1] = 1; + if (output_configure(ac, layout_map, layout_map_tags, + OC_TRIAL_FRAME, 0)) + return -7; + } + } + ac->oc[1].m4ac.sample_rate = hdr_info.sample_rate; + ac->oc[1].m4ac.sampling_index = hdr_info.sampling_index; + ac->oc[1].m4ac.object_type = hdr_info.object_type; + ac->oc[1].m4ac.frame_length_short = 0; + if (ac->oc[0].status != OC_LOCKED || + ac->oc[0].m4ac.chan_config != hdr_info.chan_config || + ac->oc[0].m4ac.sample_rate != hdr_info.sample_rate) { + ac->oc[1].m4ac.sbr = -1; + ac->oc[1].m4ac.ps = -1; + } + if (!hdr_info.crc_absent) + skip_bits(gb, 16); + } + return size; +} + +static int aac_decode_er_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, GetBitContext *gb) +{ + AACContext *ac = avctx->priv_data; + const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac; + ChannelElement *che; + int err, i; + int samples = m4ac->frame_length_short ? 960 : 1024; + int chan_config = m4ac->chan_config; + int aot = m4ac->object_type; + + if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) + samples >>= 1; + + ac->frame = data; + + if ((err = frame_configure_elements(avctx)) < 0) + return err; + + // The FF_PROFILE_AAC_* defines are all object_type - 1 + // This may lead to an undefined profile being signaled + ac->avctx->profile = aot - 1; + + ac->tags_mapped = 0; + + if (chan_config < 0 || (chan_config >= 8 && chan_config < 11) || chan_config >= 13) { + avpriv_request_sample(avctx, "Unknown ER channel configuration %d", + chan_config); + return AVERROR_INVALIDDATA; + } + for (i = 0; i < tags_per_config[chan_config]; i++) { + const int elem_type = aac_channel_layout_map[chan_config-1][i][0]; + const int elem_id = aac_channel_layout_map[chan_config-1][i][1]; + if (!(che=get_che(ac, elem_type, elem_id))) { + av_log(ac->avctx, AV_LOG_ERROR, + "channel element %d.%d is not allocated\n", + elem_type, elem_id); + return AVERROR_INVALIDDATA; + } + che->present = 1; + if (aot != AOT_ER_AAC_ELD) + skip_bits(gb, 4); + switch (elem_type) { + case TYPE_SCE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + break; + case TYPE_CPE: + err = decode_cpe(ac, gb, che); + break; + case TYPE_LFE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + break; + } + if (err < 0) + return err; + } + + spectral_to_sample(ac, samples); + + if (!ac->frame->data[0] && samples) { + av_log(avctx, AV_LOG_ERROR, "no frame data found\n"); + return AVERROR_INVALIDDATA; + } + + ac->frame->nb_samples = samples; + ac->frame->sample_rate = avctx->sample_rate; + *got_frame_ptr = 1; + + skip_bits_long(gb, get_bits_left(gb)); + return 0; +} + +static int aac_decode_frame_int(AVCodecContext *avctx, void *data, + int *got_frame_ptr, GetBitContext *gb, AVPacket *avpkt) +{ + AACContext *ac = avctx->priv_data; + ChannelElement *che = NULL, *che_prev = NULL; + enum RawDataBlockType elem_type, che_prev_type = TYPE_END; + int err, elem_id; + int samples = 0, multiplier, audio_found = 0, pce_found = 0; + int is_dmono, sce_count = 0; + int payload_alignment; + uint8_t che_presence[4][MAX_ELEM_ID] = {{0}}; + + ac->frame = data; + + if (show_bits(gb, 12) == 0xfff) { + if ((err = parse_adts_frame_header(ac, gb)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n"); + goto fail; + } + if (ac->oc[1].m4ac.sampling_index > 12) { + av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index); + err = AVERROR_INVALIDDATA; + goto fail; + } + } + + if ((err = frame_configure_elements(avctx)) < 0) + goto fail; + + // The FF_PROFILE_AAC_* defines are all object_type - 1 + // This may lead to an undefined profile being signaled + ac->avctx->profile = ac->oc[1].m4ac.object_type - 1; + + payload_alignment = get_bits_count(gb); + ac->tags_mapped = 0; + // parse + while ((elem_type = get_bits(gb, 3)) != TYPE_END) { + elem_id = get_bits(gb, 4); + + if (avctx->debug & FF_DEBUG_STARTCODE) + av_log(avctx, AV_LOG_DEBUG, "Elem type:%x id:%x\n", elem_type, elem_id); + + if (!avctx->channels && elem_type != TYPE_PCE) { + err = AVERROR_INVALIDDATA; + goto fail; + } + + if (elem_type < TYPE_DSE) { + if (che_presence[elem_type][elem_id]) { + int error = che_presence[elem_type][elem_id] > 1; + av_log(ac->avctx, error ? AV_LOG_ERROR : AV_LOG_DEBUG, "channel element %d.%d duplicate\n", + elem_type, elem_id); + if (error) { + err = AVERROR_INVALIDDATA; + goto fail; + } + } + che_presence[elem_type][elem_id]++; + + if (!(che=get_che(ac, elem_type, elem_id))) { + av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n", + elem_type, elem_id); + err = AVERROR_INVALIDDATA; + goto fail; + } + samples = ac->oc[1].m4ac.frame_length_short ? 960 : 1024; + che->present = 1; + } + + switch (elem_type) { + + case TYPE_SCE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; + sce_count++; + break; + + case TYPE_CPE: + err = decode_cpe(ac, gb, che); + audio_found = 1; + break; + + case TYPE_CCE: + err = decode_cce(ac, gb, che); + break; + + case TYPE_LFE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; + break; + + case TYPE_DSE: + err = skip_data_stream_element(ac, gb); + break; + + case TYPE_PCE: { + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int tags; + + int pushed = push_output_configuration(ac); + if (pce_found && !pushed) { + err = AVERROR_INVALIDDATA; + goto fail; + } + + tags = decode_pce(avctx, &ac->oc[1].m4ac, layout_map, gb, + payload_alignment); + if (tags < 0) { + err = tags; + break; + } + if (pce_found) { + av_log(avctx, AV_LOG_ERROR, + "Not evaluating a further program_config_element as this construct is dubious at best.\n"); + pop_output_configuration(ac); + } else { + err = output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1); + if (!err) + ac->oc[1].m4ac.chan_config = 0; + pce_found = 1; + } + break; + } + + case TYPE_FIL: + if (elem_id == 15) + elem_id += get_bits(gb, 8) - 1; + if (get_bits_left(gb) < 8 * elem_id) { + av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err); + err = AVERROR_INVALIDDATA; + goto fail; + } + while (elem_id > 0) + elem_id -= decode_extension_payload(ac, gb, elem_id, che_prev, che_prev_type); + err = 0; /* FIXME */ + break; + + default: + err = AVERROR_BUG; /* should not happen, but keeps compiler happy */ + break; + } + + if (elem_type < TYPE_DSE) { + che_prev = che; + che_prev_type = elem_type; + } + + if (err) + goto fail; + + if (get_bits_left(gb) < 3) { + av_log(avctx, AV_LOG_ERROR, overread_err); + err = AVERROR_INVALIDDATA; + goto fail; + } + } + + if (!avctx->channels) { + *got_frame_ptr = 0; + return 0; + } + + multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0; + samples <<= multiplier; + + spectral_to_sample(ac, samples); + + if (ac->oc[1].status && audio_found) { + avctx->sample_rate = ac->oc[1].m4ac.sample_rate << multiplier; + avctx->frame_size = samples; + ac->oc[1].status = OC_LOCKED; + } + + if (multiplier) + avctx->internal->skip_samples_multiplier = 2; + + if (!ac->frame->data[0] && samples) { + av_log(avctx, AV_LOG_ERROR, "no frame data found\n"); + err = AVERROR_INVALIDDATA; + goto fail; + } + + if (samples) { + ac->frame->nb_samples = samples; + ac->frame->sample_rate = avctx->sample_rate; + } else + av_frame_unref(ac->frame); + *got_frame_ptr = !!samples; + + /* for dual-mono audio (SCE + SCE) */ + is_dmono = ac->dmono_mode && sce_count == 2 && + ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT); + if (is_dmono) { + if (ac->dmono_mode == 1) + ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0]; + else if (ac->dmono_mode == 2) + ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1]; + } + + return 0; +fail: + pop_output_configuration(ac); + return err; +} + +static int aac_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + AACContext *ac = avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + GetBitContext gb; + int buf_consumed; + int buf_offset; + int err; + int new_extradata_size; + const uint8_t *new_extradata = av_packet_get_side_data(avpkt, + AV_PKT_DATA_NEW_EXTRADATA, + &new_extradata_size); + int jp_dualmono_size; + const uint8_t *jp_dualmono = av_packet_get_side_data(avpkt, + AV_PKT_DATA_JP_DUALMONO, + &jp_dualmono_size); + + if (new_extradata) { + /* discard previous configuration */ + ac->oc[1].status = OC_NONE; + err = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, + new_extradata, + new_extradata_size * 8LL, 1); + if (err < 0) { + return err; + } + } + + ac->dmono_mode = 0; + if (jp_dualmono && jp_dualmono_size > 0) + ac->dmono_mode = 1 + *jp_dualmono; + if (ac->force_dmono_mode >= 0) + ac->dmono_mode = ac->force_dmono_mode; + + if (INT_MAX / 8 <= buf_size) + return AVERROR_INVALIDDATA; + + if ((err = init_get_bits8(&gb, buf, buf_size)) < 0) + return err; + + switch (ac->oc[1].m4ac.object_type) { + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_LD: + case AOT_ER_AAC_ELD: + err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb); + break; + default: + err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt); + } + if (err < 0) + return err; + + buf_consumed = (get_bits_count(&gb) + 7) >> 3; + for (buf_offset = buf_consumed; buf_offset < buf_size; buf_offset++) + if (buf[buf_offset]) + break; + + return buf_size > buf_offset ? buf_consumed : buf_size; +} + +static av_cold int aac_decode_close(AVCodecContext *avctx) +{ + AACContext *ac = avctx->priv_data; + int i, type; + + for (i = 0; i < MAX_ELEM_ID; i++) { + for (type = 0; type < 4; type++) { + if (ac->che[type][i]) + AAC_RENAME(ff_aac_sbr_ctx_close)(&ac->che[type][i]->sbr); + av_freep(&ac->che[type][i]); + } + } + + ff_mdct_end(&ac->mdct); + ff_mdct_end(&ac->mdct_small); + ff_mdct_end(&ac->mdct_ld); + ff_mdct_end(&ac->mdct_ltp); +#if !USE_FIXED + ff_mdct15_uninit(&ac->mdct120); + ff_mdct15_uninit(&ac->mdct480); + ff_mdct15_uninit(&ac->mdct960); +#endif + av_freep(&ac->fdsp); + return 0; +} + +static void aacdec_init(AACContext *c) +{ + c->imdct_and_windowing = imdct_and_windowing; + c->apply_ltp = apply_ltp; + c->apply_tns = apply_tns; + c->windowing_and_mdct_ltp = windowing_and_mdct_ltp; + c->update_ltp = update_ltp; +#if USE_FIXED + c->vector_pow43 = vector_pow43; + c->subband_scale = subband_scale; +#endif + +#if !USE_FIXED + if(ARCH_MIPS) + ff_aacdec_init_mips(c); +#endif /* !USE_FIXED */ +} +/** + * AVOptions for Japanese DTV specific extensions (ADTS only) + */ +#define AACDEC_FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM +static const AVOption options[] = { + {"dual_mono_mode", "Select the channel to decode for dual mono", + offsetof(AACContext, force_dmono_mode), AV_OPT_TYPE_INT, {.i64=-1}, -1, 2, + AACDEC_FLAGS, "dual_mono_mode"}, + + {"auto", "autoselection", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"}, + {"main", "Select Main/Left channel", 0, AV_OPT_TYPE_CONST, {.i64= 1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"}, + {"sub" , "Select Sub/Right channel", 0, AV_OPT_TYPE_CONST, {.i64= 2}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"}, + {"both", "Select both channels", 0, AV_OPT_TYPE_CONST, {.i64= 0}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"}, + + {NULL}, +}; + +static const AVClass aac_decoder_class = { + .class_name = "AAC decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdectab.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdectab.h new file mode 100644 index 000000000..baf51a74b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacdectab.h @@ -0,0 +1,74 @@ +/* + * AAC decoder data + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC decoder data + * @author Oded Shimon ( ods15 ods15 dyndns org ) + * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) + */ + +#ifndef AVCODEC_AACDECTAB_H +#define AVCODEC_AACDECTAB_H + +#include "libavutil/channel_layout.h" +#include "aac.h" + +#include + +static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 4, 5, 0, 5, 0 }; + +static const uint8_t aac_channel_layout_map[16][5][3] = { + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, }, + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, }, + { { 0, } }, + { { 0, } }, + { { 0, } }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, }, + { { 0, } }, + /* TODO: Add 7+1 TOP configuration */ +}; + +static const uint64_t aac_channel_layout[16] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_7POINT1_WIDE_BACK, + 0, + 0, + 0, + AV_CH_LAYOUT_6POINT1, + AV_CH_LAYOUT_7POINT1, + 0, + /* AV_CH_LAYOUT_7POINT1_TOP, */ +}; + +#endif /* AVCODEC_AACDECTAB_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc.c new file mode 100644 index 000000000..4d0abb107 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc.c @@ -0,0 +1,1165 @@ +/* + * AAC encoder + * Copyright (C) 2008 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder + */ + +/*********************************** + * TODOs: + * add sane pulse detection + ***********************************/ + +#include "libavutil/libm.h" +#include "libavutil/thread.h" +#include "libavutil/float_dsp.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "put_bits.h" +#include "internal.h" +#include "mpeg4audio.h" +#include "kbdwin.h" +#include "sinewin.h" + +#include "aac.h" +#include "aactab.h" +#include "aacenc.h" +#include "aacenctab.h" +#include "aacenc_utils.h" + +#include "psymodel.h" + +static AVOnce aac_table_init = AV_ONCE_INIT; + +static void put_pce(PutBitContext *pb, AVCodecContext *avctx) +{ + int i, j; + AACEncContext *s = avctx->priv_data; + AACPCEInfo *pce = &s->pce; + const int bitexact = avctx->flags & AV_CODEC_FLAG_BITEXACT; + const char *aux_data = bitexact ? "Lavc" : LIBAVCODEC_IDENT; + + put_bits(pb, 4, 0); + + put_bits(pb, 2, avctx->profile); + put_bits(pb, 4, s->samplerate_index); + + put_bits(pb, 4, pce->num_ele[0]); /* Front */ + put_bits(pb, 4, pce->num_ele[1]); /* Side */ + put_bits(pb, 4, pce->num_ele[2]); /* Back */ + put_bits(pb, 2, pce->num_ele[3]); /* LFE */ + put_bits(pb, 3, 0); /* Assoc data */ + put_bits(pb, 4, 0); /* CCs */ + + put_bits(pb, 1, 0); /* Stereo mixdown */ + put_bits(pb, 1, 0); /* Mono mixdown */ + put_bits(pb, 1, 0); /* Something else */ + + for (i = 0; i < 4; i++) { + for (j = 0; j < pce->num_ele[i]; j++) { + if (i < 3) + put_bits(pb, 1, pce->pairing[i][j]); + put_bits(pb, 4, pce->index[i][j]); + } + } + + avpriv_align_put_bits(pb); + put_bits(pb, 8, strlen(aux_data)); + avpriv_put_string(pb, aux_data, 0); +} + +/** + * Make AAC audio config object. + * @see 1.6.2.1 "Syntax - AudioSpecificConfig" + */ +static int put_audio_specific_config(AVCodecContext *avctx) +{ + PutBitContext pb; + AACEncContext *s = avctx->priv_data; + int channels = (!s->needs_pce)*(s->channels - (s->channels == 8 ? 1 : 0)); + const int max_size = 32; + + avctx->extradata = av_mallocz(max_size); + if (!avctx->extradata) + return AVERROR(ENOMEM); + + init_put_bits(&pb, avctx->extradata, max_size); + put_bits(&pb, 5, s->profile+1); //profile + put_bits(&pb, 4, s->samplerate_index); //sample rate index + put_bits(&pb, 4, channels); + //GASpecificConfig + put_bits(&pb, 1, 0); //frame length - 1024 samples + put_bits(&pb, 1, 0); //does not depend on core coder + put_bits(&pb, 1, 0); //is not extension + if (s->needs_pce) + put_pce(&pb, avctx); + + //Explicitly Mark SBR absent + put_bits(&pb, 11, 0x2b7); //sync extension + put_bits(&pb, 5, AOT_SBR); + put_bits(&pb, 1, 0); + flush_put_bits(&pb); + avctx->extradata_size = put_bits_count(&pb) >> 3; + + return 0; +} + +void ff_quantize_band_cost_cache_init(struct AACEncContext *s) +{ + ++s->quantize_band_cost_cache_generation; + if (s->quantize_band_cost_cache_generation == 0) { + memset(s->quantize_band_cost_cache, 0, sizeof(s->quantize_band_cost_cache)); + s->quantize_band_cost_cache_generation = 1; + } +} + +#define WINDOW_FUNC(type) \ +static void apply_ ##type ##_window(AVFloatDSPContext *fdsp, \ + SingleChannelElement *sce, \ + const float *audio) + +WINDOW_FUNC(only_long) +{ + const float *lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024; + const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024; + float *out = sce->ret_buf; + + fdsp->vector_fmul (out, audio, lwindow, 1024); + fdsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024); +} + +WINDOW_FUNC(long_start) +{ + const float *lwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024; + const float *swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; + float *out = sce->ret_buf; + + fdsp->vector_fmul(out, audio, lwindow, 1024); + memcpy(out + 1024, audio + 1024, sizeof(out[0]) * 448); + fdsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128); + memset(out + 1024 + 576, 0, sizeof(out[0]) * 448); +} + +WINDOW_FUNC(long_stop) +{ + const float *lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024; + const float *swindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128; + float *out = sce->ret_buf; + + memset(out, 0, sizeof(out[0]) * 448); + fdsp->vector_fmul(out + 448, audio + 448, swindow, 128); + memcpy(out + 576, audio + 576, sizeof(out[0]) * 448); + fdsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024); +} + +WINDOW_FUNC(eight_short) +{ + const float *swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; + const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128; + const float *in = audio + 448; + float *out = sce->ret_buf; + int w; + + for (w = 0; w < 8; w++) { + fdsp->vector_fmul (out, in, w ? pwindow : swindow, 128); + out += 128; + in += 128; + fdsp->vector_fmul_reverse(out, in, swindow, 128); + out += 128; + } +} + +static void (*const apply_window[4])(AVFloatDSPContext *fdsp, + SingleChannelElement *sce, + const float *audio) = { + [ONLY_LONG_SEQUENCE] = apply_only_long_window, + [LONG_START_SEQUENCE] = apply_long_start_window, + [EIGHT_SHORT_SEQUENCE] = apply_eight_short_window, + [LONG_STOP_SEQUENCE] = apply_long_stop_window +}; + +static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce, + float *audio) +{ + int i; + const float *output = sce->ret_buf; + + apply_window[sce->ics.window_sequence[0]](s->fdsp, sce, audio); + + if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) + s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output); + else + for (i = 0; i < 1024; i += 128) + s->mdct128.mdct_calc(&s->mdct128, &sce->coeffs[i], output + i*2); + memcpy(audio, audio + 1024, sizeof(audio[0]) * 1024); + memcpy(sce->pcoeffs, sce->coeffs, sizeof(sce->pcoeffs)); +} + +/** + * Encode ics_info element. + * @see Table 4.6 (syntax of ics_info) + */ +static void put_ics_info(AACEncContext *s, IndividualChannelStream *info) +{ + int w; + + put_bits(&s->pb, 1, 0); // ics_reserved bit + put_bits(&s->pb, 2, info->window_sequence[0]); + put_bits(&s->pb, 1, info->use_kb_window[0]); + if (info->window_sequence[0] != EIGHT_SHORT_SEQUENCE) { + put_bits(&s->pb, 6, info->max_sfb); + put_bits(&s->pb, 1, !!info->predictor_present); + } else { + put_bits(&s->pb, 4, info->max_sfb); + for (w = 1; w < 8; w++) + put_bits(&s->pb, 1, !info->group_len[w]); + } +} + +/** + * Encode MS data. + * @see 4.6.8.1 "Joint Coding - M/S Stereo" + */ +static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe) +{ + int i, w; + + put_bits(pb, 2, cpe->ms_mode); + if (cpe->ms_mode == 1) + for (w = 0; w < cpe->ch[0].ics.num_windows; w += cpe->ch[0].ics.group_len[w]) + for (i = 0; i < cpe->ch[0].ics.max_sfb; i++) + put_bits(pb, 1, cpe->ms_mask[w*16 + i]); +} + +/** + * Produce integer coefficients from scalefactors provided by the model. + */ +static void adjust_frame_information(ChannelElement *cpe, int chans) +{ + int i, w, w2, g, ch; + int maxsfb, cmaxsfb; + + for (ch = 0; ch < chans; ch++) { + IndividualChannelStream *ics = &cpe->ch[ch].ics; + maxsfb = 0; + cpe->ch[ch].pulse.num_pulse = 0; + for (w = 0; w < ics->num_windows; w += ics->group_len[w]) { + for (w2 = 0; w2 < ics->group_len[w]; w2++) { + for (cmaxsfb = ics->num_swb; cmaxsfb > 0 && cpe->ch[ch].zeroes[w*16+cmaxsfb-1]; cmaxsfb--) + ; + maxsfb = FFMAX(maxsfb, cmaxsfb); + } + } + ics->max_sfb = maxsfb; + + //adjust zero bands for window groups + for (w = 0; w < ics->num_windows; w += ics->group_len[w]) { + for (g = 0; g < ics->max_sfb; g++) { + i = 1; + for (w2 = w; w2 < w + ics->group_len[w]; w2++) { + if (!cpe->ch[ch].zeroes[w2*16 + g]) { + i = 0; + break; + } + } + cpe->ch[ch].zeroes[w*16 + g] = i; + } + } + } + + if (chans > 1 && cpe->common_window) { + IndividualChannelStream *ics0 = &cpe->ch[0].ics; + IndividualChannelStream *ics1 = &cpe->ch[1].ics; + int msc = 0; + ics0->max_sfb = FFMAX(ics0->max_sfb, ics1->max_sfb); + ics1->max_sfb = ics0->max_sfb; + for (w = 0; w < ics0->num_windows*16; w += 16) + for (i = 0; i < ics0->max_sfb; i++) + if (cpe->ms_mask[w+i]) + msc++; + if (msc == 0 || ics0->max_sfb == 0) + cpe->ms_mode = 0; + else + cpe->ms_mode = msc < ics0->max_sfb * ics0->num_windows ? 1 : 2; + } +} + +static void apply_intensity_stereo(ChannelElement *cpe) +{ + int w, w2, g, i; + IndividualChannelStream *ics = &cpe->ch[0].ics; + if (!cpe->common_window) + return; + for (w = 0; w < ics->num_windows; w += ics->group_len[w]) { + for (w2 = 0; w2 < ics->group_len[w]; w2++) { + int start = (w+w2) * 128; + for (g = 0; g < ics->num_swb; g++) { + int p = -1 + 2 * (cpe->ch[1].band_type[w*16+g] - 14); + float scale = cpe->ch[0].is_ener[w*16+g]; + if (!cpe->is_mask[w*16 + g]) { + start += ics->swb_sizes[g]; + continue; + } + if (cpe->ms_mask[w*16 + g]) + p *= -1; + for (i = 0; i < ics->swb_sizes[g]; i++) { + float sum = (cpe->ch[0].coeffs[start+i] + p*cpe->ch[1].coeffs[start+i])*scale; + cpe->ch[0].coeffs[start+i] = sum; + cpe->ch[1].coeffs[start+i] = 0.0f; + } + start += ics->swb_sizes[g]; + } + } + } +} + +static void apply_mid_side_stereo(ChannelElement *cpe) +{ + int w, w2, g, i; + IndividualChannelStream *ics = &cpe->ch[0].ics; + if (!cpe->common_window) + return; + for (w = 0; w < ics->num_windows; w += ics->group_len[w]) { + for (w2 = 0; w2 < ics->group_len[w]; w2++) { + int start = (w+w2) * 128; + for (g = 0; g < ics->num_swb; g++) { + /* ms_mask can be used for other purposes in PNS and I/S, + * so must not apply M/S if any band uses either, even if + * ms_mask is set. + */ + if (!cpe->ms_mask[w*16 + g] || cpe->is_mask[w*16 + g] + || cpe->ch[0].band_type[w*16 + g] >= NOISE_BT + || cpe->ch[1].band_type[w*16 + g] >= NOISE_BT) { + start += ics->swb_sizes[g]; + continue; + } + for (i = 0; i < ics->swb_sizes[g]; i++) { + float L = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) * 0.5f; + float R = L - cpe->ch[1].coeffs[start+i]; + cpe->ch[0].coeffs[start+i] = L; + cpe->ch[1].coeffs[start+i] = R; + } + start += ics->swb_sizes[g]; + } + } + } +} + +/** + * Encode scalefactor band coding type. + */ +static void encode_band_info(AACEncContext *s, SingleChannelElement *sce) +{ + int w; + + if (s->coder->set_special_band_scalefactors) + s->coder->set_special_band_scalefactors(s, sce); + + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) + s->coder->encode_window_bands_info(s, sce, w, sce->ics.group_len[w], s->lambda); +} + +/** + * Encode scalefactors. + */ +static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s, + SingleChannelElement *sce) +{ + int diff, off_sf = sce->sf_idx[0], off_pns = sce->sf_idx[0] - NOISE_OFFSET; + int off_is = 0, noise_flag = 1; + int i, w; + + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (i = 0; i < sce->ics.max_sfb; i++) { + if (!sce->zeroes[w*16 + i]) { + if (sce->band_type[w*16 + i] == NOISE_BT) { + diff = sce->sf_idx[w*16 + i] - off_pns; + off_pns = sce->sf_idx[w*16 + i]; + if (noise_flag-- > 0) { + put_bits(&s->pb, NOISE_PRE_BITS, diff + NOISE_PRE); + continue; + } + } else if (sce->band_type[w*16 + i] == INTENSITY_BT || + sce->band_type[w*16 + i] == INTENSITY_BT2) { + diff = sce->sf_idx[w*16 + i] - off_is; + off_is = sce->sf_idx[w*16 + i]; + } else { + diff = sce->sf_idx[w*16 + i] - off_sf; + off_sf = sce->sf_idx[w*16 + i]; + } + diff += SCALE_DIFF_ZERO; + av_assert0(diff >= 0 && diff <= 120); + put_bits(&s->pb, ff_aac_scalefactor_bits[diff], ff_aac_scalefactor_code[diff]); + } + } + } +} + +/** + * Encode pulse data. + */ +static void encode_pulses(AACEncContext *s, Pulse *pulse) +{ + int i; + + put_bits(&s->pb, 1, !!pulse->num_pulse); + if (!pulse->num_pulse) + return; + + put_bits(&s->pb, 2, pulse->num_pulse - 1); + put_bits(&s->pb, 6, pulse->start); + for (i = 0; i < pulse->num_pulse; i++) { + put_bits(&s->pb, 5, pulse->pos[i]); + put_bits(&s->pb, 4, pulse->amp[i]); + } +} + +/** + * Encode spectral coefficients processed by psychoacoustic model. + */ +static void encode_spectral_coeffs(AACEncContext *s, SingleChannelElement *sce) +{ + int start, i, w, w2; + + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = 0; + for (i = 0; i < sce->ics.max_sfb; i++) { + if (sce->zeroes[w*16 + i]) { + start += sce->ics.swb_sizes[i]; + continue; + } + for (w2 = w; w2 < w + sce->ics.group_len[w]; w2++) { + s->coder->quantize_and_encode_band(s, &s->pb, + &sce->coeffs[start + w2*128], + NULL, sce->ics.swb_sizes[i], + sce->sf_idx[w*16 + i], + sce->band_type[w*16 + i], + s->lambda, + sce->ics.window_clipping[w]); + } + start += sce->ics.swb_sizes[i]; + } + } +} + +/** + * Downscale spectral coefficients for near-clipping windows to avoid artifacts + */ +static void avoid_clipping(AACEncContext *s, SingleChannelElement *sce) +{ + int start, i, j, w; + + if (sce->ics.clip_avoidance_factor < 1.0f) { + for (w = 0; w < sce->ics.num_windows; w++) { + start = 0; + for (i = 0; i < sce->ics.max_sfb; i++) { + float *swb_coeffs = &sce->coeffs[start + w*128]; + for (j = 0; j < sce->ics.swb_sizes[i]; j++) + swb_coeffs[j] *= sce->ics.clip_avoidance_factor; + start += sce->ics.swb_sizes[i]; + } + } + } +} + +/** + * Encode one channel of audio data. + */ +static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, + SingleChannelElement *sce, + int common_window) +{ + put_bits(&s->pb, 8, sce->sf_idx[0]); + if (!common_window) { + put_ics_info(s, &sce->ics); + if (s->coder->encode_main_pred) + s->coder->encode_main_pred(s, sce); + if (s->coder->encode_ltp_info) + s->coder->encode_ltp_info(s, sce, 0); + } + encode_band_info(s, sce); + encode_scale_factors(avctx, s, sce); + encode_pulses(s, &sce->pulse); + put_bits(&s->pb, 1, !!sce->tns.present); + if (s->coder->encode_tns_info) + s->coder->encode_tns_info(s, sce); + put_bits(&s->pb, 1, 0); //ssr + encode_spectral_coeffs(s, sce); + return 0; +} + +/** + * Write some auxiliary information about the created AAC file. + */ +static void put_bitstream_info(AACEncContext *s, const char *name) +{ + int i, namelen, padbits; + + namelen = strlen(name) + 2; + put_bits(&s->pb, 3, TYPE_FIL); + put_bits(&s->pb, 4, FFMIN(namelen, 15)); + if (namelen >= 15) + put_bits(&s->pb, 8, namelen - 14); + put_bits(&s->pb, 4, 0); //extension type - filler + padbits = -put_bits_count(&s->pb) & 7; + avpriv_align_put_bits(&s->pb); + for (i = 0; i < namelen - 2; i++) + put_bits(&s->pb, 8, name[i]); + put_bits(&s->pb, 12 - padbits, 0); +} + +/* + * Copy input samples. + * Channels are reordered from libavcodec's default order to AAC order. + */ +static void copy_input_samples(AACEncContext *s, const AVFrame *frame) +{ + int ch; + int end = 2048 + (frame ? frame->nb_samples : 0); + const uint8_t *channel_map = s->reorder_map; + + /* copy and remap input samples */ + for (ch = 0; ch < s->channels; ch++) { + /* copy last 1024 samples of previous frame to the start of the current frame */ + memcpy(&s->planar_samples[ch][1024], &s->planar_samples[ch][2048], 1024 * sizeof(s->planar_samples[0][0])); + + /* copy new samples and zero any remaining samples */ + if (frame) { + memcpy(&s->planar_samples[ch][2048], + frame->extended_data[channel_map[ch]], + frame->nb_samples * sizeof(s->planar_samples[0][0])); + } + memset(&s->planar_samples[ch][end], 0, + (3072 - end) * sizeof(s->planar_samples[0][0])); + } +} + +static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + AACEncContext *s = avctx->priv_data; + float **samples = s->planar_samples, *samples2, *la, *overlap; + ChannelElement *cpe; + SingleChannelElement *sce; + IndividualChannelStream *ics; + int i, its, ch, w, chans, tag, start_ch, ret, frame_bits; + int target_bits, rate_bits, too_many_bits, too_few_bits; + int ms_mode = 0, is_mode = 0, tns_mode = 0, pred_mode = 0; + int chan_el_counter[4]; + FFPsyWindowInfo windows[AAC_MAX_CHANNELS]; + + /* add current frame to queue */ + if (frame) { + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) + return ret; + } else { + if (!s->afq.remaining_samples || (!s->afq.frame_alloc && !s->afq.frame_count)) + return 0; + } + + copy_input_samples(s, frame); + if (s->psypp) + ff_psy_preprocess(s->psypp, s->planar_samples, s->channels); + + if (!avctx->frame_number) + return 0; + + start_ch = 0; + for (i = 0; i < s->chan_map[0]; i++) { + FFPsyWindowInfo* wi = windows + start_ch; + tag = s->chan_map[i+1]; + chans = tag == TYPE_CPE ? 2 : 1; + cpe = &s->cpe[i]; + for (ch = 0; ch < chans; ch++) { + int k; + float clip_avoidance_factor; + sce = &cpe->ch[ch]; + ics = &sce->ics; + s->cur_channel = start_ch + ch; + overlap = &samples[s->cur_channel][0]; + samples2 = overlap + 1024; + la = samples2 + (448+64); + if (!frame) + la = NULL; + if (tag == TYPE_LFE) { + wi[ch].window_type[0] = wi[ch].window_type[1] = ONLY_LONG_SEQUENCE; + wi[ch].window_shape = 0; + wi[ch].num_windows = 1; + wi[ch].grouping[0] = 1; + wi[ch].clipping[0] = 0; + + /* Only the lowest 12 coefficients are used in a LFE channel. + * The expression below results in only the bottom 8 coefficients + * being used for 11.025kHz to 16kHz sample rates. + */ + ics->num_swb = s->samplerate_index >= 8 ? 1 : 3; + } else { + wi[ch] = s->psy.model->window(&s->psy, samples2, la, s->cur_channel, + ics->window_sequence[0]); + } + ics->window_sequence[1] = ics->window_sequence[0]; + ics->window_sequence[0] = wi[ch].window_type[0]; + ics->use_kb_window[1] = ics->use_kb_window[0]; + ics->use_kb_window[0] = wi[ch].window_shape; + ics->num_windows = wi[ch].num_windows; + ics->swb_sizes = s->psy.bands [ics->num_windows == 8]; + ics->num_swb = tag == TYPE_LFE ? ics->num_swb : s->psy.num_bands[ics->num_windows == 8]; + ics->max_sfb = FFMIN(ics->max_sfb, ics->num_swb); + ics->swb_offset = wi[ch].window_type[0] == EIGHT_SHORT_SEQUENCE ? + ff_swb_offset_128 [s->samplerate_index]: + ff_swb_offset_1024[s->samplerate_index]; + ics->tns_max_bands = wi[ch].window_type[0] == EIGHT_SHORT_SEQUENCE ? + ff_tns_max_bands_128 [s->samplerate_index]: + ff_tns_max_bands_1024[s->samplerate_index]; + + for (w = 0; w < ics->num_windows; w++) + ics->group_len[w] = wi[ch].grouping[w]; + + /* Calculate input sample maximums and evaluate clipping risk */ + clip_avoidance_factor = 0.0f; + for (w = 0; w < ics->num_windows; w++) { + const float *wbuf = overlap + w * 128; + const int wlen = 2048 / ics->num_windows; + float max = 0; + int j; + /* mdct input is 2 * output */ + for (j = 0; j < wlen; j++) + max = FFMAX(max, fabsf(wbuf[j])); + wi[ch].clipping[w] = max; + } + for (w = 0; w < ics->num_windows; w++) { + if (wi[ch].clipping[w] > CLIP_AVOIDANCE_FACTOR) { + ics->window_clipping[w] = 1; + clip_avoidance_factor = FFMAX(clip_avoidance_factor, wi[ch].clipping[w]); + } else { + ics->window_clipping[w] = 0; + } + } + if (clip_avoidance_factor > CLIP_AVOIDANCE_FACTOR) { + ics->clip_avoidance_factor = CLIP_AVOIDANCE_FACTOR / clip_avoidance_factor; + } else { + ics->clip_avoidance_factor = 1.0f; + } + + apply_window_and_mdct(s, sce, overlap); + + if (s->options.ltp && s->coder->update_ltp) { + s->coder->update_ltp(s, sce); + apply_window[sce->ics.window_sequence[0]](s->fdsp, sce, &sce->ltp_state[0]); + s->mdct1024.mdct_calc(&s->mdct1024, sce->lcoeffs, sce->ret_buf); + } + + for (k = 0; k < 1024; k++) { + if (!(fabs(cpe->ch[ch].coeffs[k]) < 1E16)) { // Ensure headroom for energy calculation + av_log(avctx, AV_LOG_ERROR, "Input contains (near) NaN/+-Inf\n"); + return AVERROR(EINVAL); + } + } + avoid_clipping(s, sce); + } + start_ch += chans; + } + if ((ret = ff_alloc_packet2(avctx, avpkt, 8192 * s->channels, 0)) < 0) + return ret; + frame_bits = its = 0; + do { + init_put_bits(&s->pb, avpkt->data, avpkt->size); + + if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & AV_CODEC_FLAG_BITEXACT)) + put_bitstream_info(s, LIBAVCODEC_IDENT); + start_ch = 0; + target_bits = 0; + memset(chan_el_counter, 0, sizeof(chan_el_counter)); + for (i = 0; i < s->chan_map[0]; i++) { + FFPsyWindowInfo* wi = windows + start_ch; + const float *coeffs[2]; + tag = s->chan_map[i+1]; + chans = tag == TYPE_CPE ? 2 : 1; + cpe = &s->cpe[i]; + cpe->common_window = 0; + memset(cpe->is_mask, 0, sizeof(cpe->is_mask)); + memset(cpe->ms_mask, 0, sizeof(cpe->ms_mask)); + put_bits(&s->pb, 3, tag); + put_bits(&s->pb, 4, chan_el_counter[tag]++); + for (ch = 0; ch < chans; ch++) { + sce = &cpe->ch[ch]; + coeffs[ch] = sce->coeffs; + sce->ics.predictor_present = 0; + sce->ics.ltp.present = 0; + memset(sce->ics.ltp.used, 0, sizeof(sce->ics.ltp.used)); + memset(sce->ics.prediction_used, 0, sizeof(sce->ics.prediction_used)); + memset(&sce->tns, 0, sizeof(TemporalNoiseShaping)); + for (w = 0; w < 128; w++) + if (sce->band_type[w] > RESERVED_BT) + sce->band_type[w] = 0; + } + s->psy.bitres.alloc = -1; + s->psy.bitres.bits = s->last_frame_pb_count / s->channels; + s->psy.model->analyze(&s->psy, start_ch, coeffs, wi); + if (s->psy.bitres.alloc > 0) { + /* Lambda unused here on purpose, we need to take psy's unscaled allocation */ + target_bits += s->psy.bitres.alloc + * (s->lambda / (avctx->global_quality ? avctx->global_quality : 120)); + s->psy.bitres.alloc /= chans; + } + s->cur_type = tag; + for (ch = 0; ch < chans; ch++) { + s->cur_channel = start_ch + ch; + if (s->options.pns && s->coder->mark_pns) + s->coder->mark_pns(s, avctx, &cpe->ch[ch]); + s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda); + } + if (chans > 1 + && wi[0].window_type[0] == wi[1].window_type[0] + && wi[0].window_shape == wi[1].window_shape) { + + cpe->common_window = 1; + for (w = 0; w < wi[0].num_windows; w++) { + if (wi[0].grouping[w] != wi[1].grouping[w]) { + cpe->common_window = 0; + break; + } + } + } + for (ch = 0; ch < chans; ch++) { /* TNS and PNS */ + sce = &cpe->ch[ch]; + s->cur_channel = start_ch + ch; + if (s->options.tns && s->coder->search_for_tns) + s->coder->search_for_tns(s, sce); + if (s->options.tns && s->coder->apply_tns_filt) + s->coder->apply_tns_filt(s, sce); + if (sce->tns.present) + tns_mode = 1; + if (s->options.pns && s->coder->search_for_pns) + s->coder->search_for_pns(s, avctx, sce); + } + s->cur_channel = start_ch; + if (s->options.intensity_stereo) { /* Intensity Stereo */ + if (s->coder->search_for_is) + s->coder->search_for_is(s, avctx, cpe); + if (cpe->is_mode) is_mode = 1; + apply_intensity_stereo(cpe); + } + if (s->options.pred) { /* Prediction */ + for (ch = 0; ch < chans; ch++) { + sce = &cpe->ch[ch]; + s->cur_channel = start_ch + ch; + if (s->options.pred && s->coder->search_for_pred) + s->coder->search_for_pred(s, sce); + if (cpe->ch[ch].ics.predictor_present) pred_mode = 1; + } + if (s->coder->adjust_common_pred) + s->coder->adjust_common_pred(s, cpe); + for (ch = 0; ch < chans; ch++) { + sce = &cpe->ch[ch]; + s->cur_channel = start_ch + ch; + if (s->options.pred && s->coder->apply_main_pred) + s->coder->apply_main_pred(s, sce); + } + s->cur_channel = start_ch; + } + if (s->options.mid_side) { /* Mid/Side stereo */ + if (s->options.mid_side == -1 && s->coder->search_for_ms) + s->coder->search_for_ms(s, cpe); + else if (cpe->common_window) + memset(cpe->ms_mask, 1, sizeof(cpe->ms_mask)); + apply_mid_side_stereo(cpe); + } + adjust_frame_information(cpe, chans); + if (s->options.ltp) { /* LTP */ + for (ch = 0; ch < chans; ch++) { + sce = &cpe->ch[ch]; + s->cur_channel = start_ch + ch; + if (s->coder->search_for_ltp) + s->coder->search_for_ltp(s, sce, cpe->common_window); + if (sce->ics.ltp.present) pred_mode = 1; + } + s->cur_channel = start_ch; + if (s->coder->adjust_common_ltp) + s->coder->adjust_common_ltp(s, cpe); + } + if (chans == 2) { + put_bits(&s->pb, 1, cpe->common_window); + if (cpe->common_window) { + put_ics_info(s, &cpe->ch[0].ics); + if (s->coder->encode_main_pred) + s->coder->encode_main_pred(s, &cpe->ch[0]); + if (s->coder->encode_ltp_info) + s->coder->encode_ltp_info(s, &cpe->ch[0], 1); + encode_ms_info(&s->pb, cpe); + if (cpe->ms_mode) ms_mode = 1; + } + } + for (ch = 0; ch < chans; ch++) { + s->cur_channel = start_ch + ch; + encode_individual_channel(avctx, s, &cpe->ch[ch], cpe->common_window); + } + start_ch += chans; + } + + if (avctx->flags & AV_CODEC_FLAG_QSCALE) { + /* When using a constant Q-scale, don't mess with lambda */ + break; + } + + /* rate control stuff + * allow between the nominal bitrate, and what psy's bit reservoir says to target + * but drift towards the nominal bitrate always + */ + frame_bits = put_bits_count(&s->pb); + rate_bits = avctx->bit_rate * 1024 / avctx->sample_rate; + rate_bits = FFMIN(rate_bits, 6144 * s->channels - 3); + too_many_bits = FFMAX(target_bits, rate_bits); + too_many_bits = FFMIN(too_many_bits, 6144 * s->channels - 3); + too_few_bits = FFMIN(FFMAX(rate_bits - rate_bits/4, target_bits), too_many_bits); + + /* When using ABR, be strict (but only for increasing) */ + too_few_bits = too_few_bits - too_few_bits/8; + too_many_bits = too_many_bits + too_many_bits/2; + + if ( its == 0 /* for steady-state Q-scale tracking */ + || (its < 5 && (frame_bits < too_few_bits || frame_bits > too_many_bits)) + || frame_bits >= 6144 * s->channels - 3 ) + { + float ratio = ((float)rate_bits) / frame_bits; + + if (frame_bits >= too_few_bits && frame_bits <= too_many_bits) { + /* + * This path is for steady-state Q-scale tracking + * When frame bits fall within the stable range, we still need to adjust + * lambda to maintain it like so in a stable fashion (large jumps in lambda + * create artifacts and should be avoided), but slowly + */ + ratio = sqrtf(sqrtf(ratio)); + ratio = av_clipf(ratio, 0.9f, 1.1f); + } else { + /* Not so fast though */ + ratio = sqrtf(ratio); + } + s->lambda = FFMIN(s->lambda * ratio, 65536.f); + + /* Keep iterating if we must reduce and lambda is in the sky */ + if (ratio > 0.9f && ratio < 1.1f) { + break; + } else { + if (is_mode || ms_mode || tns_mode || pred_mode) { + for (i = 0; i < s->chan_map[0]; i++) { + // Must restore coeffs + chans = tag == TYPE_CPE ? 2 : 1; + cpe = &s->cpe[i]; + for (ch = 0; ch < chans; ch++) + memcpy(cpe->ch[ch].coeffs, cpe->ch[ch].pcoeffs, sizeof(cpe->ch[ch].coeffs)); + } + } + its++; + } + } else { + break; + } + } while (1); + + if (s->options.ltp && s->coder->ltp_insert_new_frame) + s->coder->ltp_insert_new_frame(s); + + put_bits(&s->pb, 3, TYPE_END); + flush_put_bits(&s->pb); + + s->last_frame_pb_count = put_bits_count(&s->pb); + + s->lambda_sum += s->lambda; + s->lambda_count++; + + ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts, + &avpkt->duration); + + avpkt->size = put_bits_count(&s->pb) >> 3; + *got_packet_ptr = 1; + return 0; +} + +static av_cold int aac_encode_end(AVCodecContext *avctx) +{ + AACEncContext *s = avctx->priv_data; + + av_log(avctx, AV_LOG_INFO, "Qavg: %.3f\n", s->lambda_sum / s->lambda_count); + + ff_mdct_end(&s->mdct1024); + ff_mdct_end(&s->mdct128); + ff_psy_end(&s->psy); + ff_lpc_end(&s->lpc); + if (s->psypp) + ff_psy_preprocess_end(s->psypp); + av_freep(&s->buffer.samples); + av_freep(&s->cpe); + av_freep(&s->fdsp); + ff_af_queue_close(&s->afq); + return 0; +} + +static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) +{ + int ret = 0; + + s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!s->fdsp) + return AVERROR(ENOMEM); + + // window init + ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); + ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); + ff_init_ff_sine_windows(10); + ff_init_ff_sine_windows(7); + + if ((ret = ff_mdct_init(&s->mdct1024, 11, 0, 32768.0)) < 0) + return ret; + if ((ret = ff_mdct_init(&s->mdct128, 8, 0, 32768.0)) < 0) + return ret; + + return 0; +} + +static av_cold int alloc_buffers(AVCodecContext *avctx, AACEncContext *s) +{ + int ch; + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->buffer.samples, s->channels, 3 * 1024 * sizeof(s->buffer.samples[0]), alloc_fail); + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->cpe, s->chan_map[0], sizeof(ChannelElement), alloc_fail); + + for(ch = 0; ch < s->channels; ch++) + s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch; + + return 0; +alloc_fail: + return AVERROR(ENOMEM); +} + +static av_cold void aac_encode_init_tables(void) +{ + ff_aac_tableinit(); +} + +static av_cold int aac_encode_init(AVCodecContext *avctx) +{ + AACEncContext *s = avctx->priv_data; + int i, ret = 0; + const uint8_t *sizes[2]; + uint8_t grouping[AAC_MAX_CHANNELS]; + int lengths[2]; + + /* Constants */ + s->last_frame_pb_count = 0; + avctx->frame_size = 1024; + avctx->initial_padding = 1024; + s->lambda = avctx->global_quality > 0 ? avctx->global_quality : 120; + + /* Channel map and unspecified bitrate guessing */ + s->channels = avctx->channels; + + s->needs_pce = 1; + for (i = 0; i < FF_ARRAY_ELEMS(aac_normal_chan_layouts); i++) { + if (avctx->channel_layout == aac_normal_chan_layouts[i]) { + s->needs_pce = s->options.pce; + break; + } + } + + if (s->needs_pce) { + char buf[64]; + for (i = 0; i < FF_ARRAY_ELEMS(aac_pce_configs); i++) + if (avctx->channel_layout == aac_pce_configs[i].layout) + break; + av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); + ERROR_IF(i == FF_ARRAY_ELEMS(aac_pce_configs), "Unsupported channel layout \"%s\"\n", buf); + av_log(avctx, AV_LOG_INFO, "Using a PCE to encode channel layout \"%s\"\n", buf); + s->pce = aac_pce_configs[i]; + s->reorder_map = s->pce.reorder_map; + s->chan_map = s->pce.config_map; + } else { + s->reorder_map = aac_chan_maps[s->channels - 1]; + s->chan_map = aac_chan_configs[s->channels - 1]; + } + + if (!avctx->bit_rate) { + for (i = 1; i <= s->chan_map[0]; i++) { + avctx->bit_rate += s->chan_map[i] == TYPE_CPE ? 128000 : /* Pair */ + s->chan_map[i] == TYPE_LFE ? 16000 : /* LFE */ + 69000 ; /* SCE */ + } + } + + /* Samplerate */ + for (i = 0; i < 16; i++) + if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i]) + break; + s->samplerate_index = i; + ERROR_IF(s->samplerate_index == 16 || + s->samplerate_index >= ff_aac_swb_size_1024_len || + s->samplerate_index >= ff_aac_swb_size_128_len, + "Unsupported sample rate %d\n", avctx->sample_rate); + + /* Bitrate limiting */ + WARN_IF(1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * s->channels, + "Too many bits %f > %d per frame requested, clamping to max\n", + 1024.0 * avctx->bit_rate / avctx->sample_rate, + 6144 * s->channels); + avctx->bit_rate = (int64_t)FFMIN(6144 * s->channels / 1024.0 * avctx->sample_rate, + avctx->bit_rate); + + /* Profile and option setting */ + avctx->profile = avctx->profile == FF_PROFILE_UNKNOWN ? FF_PROFILE_AAC_LOW : + avctx->profile; + for (i = 0; i < FF_ARRAY_ELEMS(aacenc_profiles); i++) + if (avctx->profile == aacenc_profiles[i]) + break; + if (avctx->profile == FF_PROFILE_MPEG2_AAC_LOW) { + avctx->profile = FF_PROFILE_AAC_LOW; + ERROR_IF(s->options.pred, + "Main prediction unavailable in the \"mpeg2_aac_low\" profile\n"); + ERROR_IF(s->options.ltp, + "LTP prediction unavailable in the \"mpeg2_aac_low\" profile\n"); + WARN_IF(s->options.pns, + "PNS unavailable in the \"mpeg2_aac_low\" profile, turning off\n"); + s->options.pns = 0; + } else if (avctx->profile == FF_PROFILE_AAC_LTP) { + s->options.ltp = 1; + ERROR_IF(s->options.pred, + "Main prediction unavailable in the \"aac_ltp\" profile\n"); + } else if (avctx->profile == FF_PROFILE_AAC_MAIN) { + s->options.pred = 1; + ERROR_IF(s->options.ltp, + "LTP prediction unavailable in the \"aac_main\" profile\n"); + } else if (s->options.ltp) { + avctx->profile = FF_PROFILE_AAC_LTP; + WARN_IF(1, + "Chainging profile to \"aac_ltp\"\n"); + ERROR_IF(s->options.pred, + "Main prediction unavailable in the \"aac_ltp\" profile\n"); + } else if (s->options.pred) { + avctx->profile = FF_PROFILE_AAC_MAIN; + WARN_IF(1, + "Chainging profile to \"aac_main\"\n"); + ERROR_IF(s->options.ltp, + "LTP prediction unavailable in the \"aac_main\" profile\n"); + } + s->profile = avctx->profile; + + /* Coder limitations */ + s->coder = &ff_aac_coders[s->options.coder]; + if (s->options.coder == AAC_CODER_ANMR) { + ERROR_IF(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL, + "The ANMR coder is considered experimental, add -strict -2 to enable!\n"); + s->options.intensity_stereo = 0; + s->options.pns = 0; + } + ERROR_IF(s->options.ltp && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL, + "The LPT profile requires experimental compliance, add -strict -2 to enable!\n"); + + /* M/S introduces horrible artifacts with multichannel files, this is temporary */ + if (s->channels > 3) + s->options.mid_side = 0; + + if ((ret = dsp_init(avctx, s)) < 0) + goto fail; + + if ((ret = alloc_buffers(avctx, s)) < 0) + goto fail; + + if ((ret = put_audio_specific_config(avctx))) + goto fail; + + sizes[0] = ff_aac_swb_size_1024[s->samplerate_index]; + sizes[1] = ff_aac_swb_size_128[s->samplerate_index]; + lengths[0] = ff_aac_num_swb_1024[s->samplerate_index]; + lengths[1] = ff_aac_num_swb_128[s->samplerate_index]; + for (i = 0; i < s->chan_map[0]; i++) + grouping[i] = s->chan_map[i + 1] == TYPE_CPE; + if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, + s->chan_map[0], grouping)) < 0) + goto fail; + s->psypp = ff_psy_preprocess_init(avctx); + ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON); + s->random_state = 0x1f2e3d4c; + + s->abs_pow34 = abs_pow34_v; + s->quant_bands = quantize_bands; + + if (ARCH_X86) + ff_aac_dsp_init_x86(s); + + if (HAVE_MIPSDSP) + ff_aac_coder_init_mips(s); + + if ((ret = ff_thread_once(&aac_table_init, &aac_encode_init_tables)) != 0) + return AVERROR_UNKNOWN; + + ff_af_queue_init(avctx, &s->afq); + + return 0; +fail: + aac_encode_end(avctx); + return ret; +} + +#define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM +static const AVOption aacenc_options[] = { + {"aac_coder", "Coding algorithm", offsetof(AACEncContext, options.coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_FAST}, 0, AAC_CODER_NB-1, AACENC_FLAGS, "coder"}, + {"anmr", "ANMR method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_ANMR}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"}, + {"twoloop", "Two loop searching method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_TWOLOOP}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"}, + {"fast", "Default fast search", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"}, + {"aac_ms", "Force M/S stereo coding", offsetof(AACEncContext, options.mid_side), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AACENC_FLAGS}, + {"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS}, + {"aac_pns", "Perceptual noise substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS}, + {"aac_tns", "Temporal noise shaping", offsetof(AACEncContext, options.tns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS}, + {"aac_ltp", "Long term prediction", offsetof(AACEncContext, options.ltp), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS}, + {"aac_pred", "AAC-Main prediction", offsetof(AACEncContext, options.pred), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS}, + {"aac_pce", "Forces the use of PCEs", offsetof(AACEncContext, options.pce), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS}, + {NULL} +}; + +static const AVClass aacenc_class = { + .class_name = "AAC encoder", + .item_name = av_default_item_name, + .option = aacenc_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVCodecDefault aac_encode_defaults[] = { + { "b", "0" }, + { NULL } +}; + +AVCodec ff_aac_encoder = { + .name = "aac", + .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AAC, + .priv_data_size = sizeof(AACEncContext), + .init = aac_encode_init, + .encode2 = aac_encode_frame, + .close = aac_encode_end, + .defaults = aac_encode_defaults, + .supported_samplerates = mpeg4audio_sample_rates, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, + .priv_class = &aacenc_class, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc.h new file mode 100644 index 000000000..5a015ca92 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc.h @@ -0,0 +1,428 @@ +/* + * AAC encoder + * Copyright (C) 2008 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AACENC_H +#define AVCODEC_AACENC_H + +#include "libavutil/float_dsp.h" +#include "avcodec.h" +#include "put_bits.h" + +#include "aac.h" +#include "audio_frame_queue.h" +#include "psymodel.h" + +#include "lpc.h" + +typedef enum AACCoder { + AAC_CODER_ANMR = 0, + AAC_CODER_TWOLOOP, + AAC_CODER_FAST, + + AAC_CODER_NB, +}AACCoder; + +typedef struct AACEncOptions { + int coder; + int pns; + int tns; + int ltp; + int pce; + int pred; + int mid_side; + int intensity_stereo; +} AACEncOptions; + +struct AACEncContext; + +typedef struct AACCoefficientsEncoder { + void (*search_for_quantizers)(AVCodecContext *avctx, struct AACEncContext *s, + SingleChannelElement *sce, const float lambda); + void (*encode_window_bands_info)(struct AACEncContext *s, SingleChannelElement *sce, + int win, int group_len, const float lambda); + void (*quantize_and_encode_band)(struct AACEncContext *s, PutBitContext *pb, const float *in, float *out, int size, + int scale_idx, int cb, const float lambda, int rtz); + void (*encode_tns_info)(struct AACEncContext *s, SingleChannelElement *sce); + void (*encode_ltp_info)(struct AACEncContext *s, SingleChannelElement *sce, int common_window); + void (*encode_main_pred)(struct AACEncContext *s, SingleChannelElement *sce); + void (*adjust_common_pred)(struct AACEncContext *s, ChannelElement *cpe); + void (*adjust_common_ltp)(struct AACEncContext *s, ChannelElement *cpe); + void (*apply_main_pred)(struct AACEncContext *s, SingleChannelElement *sce); + void (*apply_tns_filt)(struct AACEncContext *s, SingleChannelElement *sce); + void (*update_ltp)(struct AACEncContext *s, SingleChannelElement *sce); + void (*ltp_insert_new_frame)(struct AACEncContext *s); + void (*set_special_band_scalefactors)(struct AACEncContext *s, SingleChannelElement *sce); + void (*search_for_pns)(struct AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce); + void (*mark_pns)(struct AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce); + void (*search_for_tns)(struct AACEncContext *s, SingleChannelElement *sce); + void (*search_for_ltp)(struct AACEncContext *s, SingleChannelElement *sce, int common_window); + void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe); + void (*search_for_is)(struct AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe); + void (*search_for_pred)(struct AACEncContext *s, SingleChannelElement *sce); +} AACCoefficientsEncoder; + +extern const AACCoefficientsEncoder ff_aac_coders[]; + +typedef struct AACQuantizeBandCostCacheEntry { + float rd; + float energy; + int bits; + char cb; + char rtz; + uint16_t generation; +} AACQuantizeBandCostCacheEntry; + +typedef struct AACPCEInfo { + int64_t layout; + int num_ele[4]; ///< front, side, back, lfe + int pairing[3][8]; ///< front, side, back + int index[4][8]; ///< front, side, back, lfe + uint8_t config_map[16]; ///< configs the encoder's channel specific settings + uint8_t reorder_map[16]; ///< maps channels from lavc to aac order +} AACPCEInfo; + +/** + * List of PCE (Program Configuration Element) for the channel layouts listed + * in channel_layout.h + * + * For those wishing in the future to add other layouts: + * + * - num_ele: number of elements in each group of front, side, back, lfe channels + * (an element is of type SCE (single channel), CPE (channel pair) for + * the first 3 groups; and is LFE for LFE group). + * + * - pairing: 0 for an SCE element or 1 for a CPE; does not apply to LFE group + * + * - index: there are three independent indices for SCE, CPE and LFE; + * they are incremented irrespective of the group to which the element belongs; + * they are not reset when going from one group to another + * + * Example: for 7.0 channel layout, + * .pairing = { { 1, 0 }, { 1 }, { 1 }, }, (3 CPE and 1 SCE in front group) + * .index = { { 0, 0 }, { 1 }, { 2 }, }, + * (index is 0 for the single SCE but goes from 0 to 2 for the CPEs) + * + * The index order impacts the channel ordering. But is otherwise arbitrary + * (the sequence could have been 2, 0, 1 instead of 0, 1, 2). + * + * Spec allows for discontinuous indices, e.g. if one has a total of two SCE, + * SCE.0 SCE.15 is OK per spec; BUT it won't be decoded by our AAC decoder + * which at this time requires that indices fully cover some range starting + * from 0 (SCE.1 SCE.0 is OK but not SCE.0 SCE.15). + * + * - config_map: total number of elements and their types. Beware, the way the + * types are ordered impacts the final channel ordering. + * + * - reorder_map: reorders the channels. + * + */ +static const AACPCEInfo aac_pce_configs[] = { + { + .layout = AV_CH_LAYOUT_MONO, + .num_ele = { 1, 0, 0, 0 }, + .pairing = { { 0 }, }, + .index = { { 0 }, }, + .config_map = { 1, TYPE_SCE, }, + .reorder_map = { 0 }, + }, + { + .layout = AV_CH_LAYOUT_STEREO, + .num_ele = { 1, 0, 0, 0 }, + .pairing = { { 1 }, }, + .index = { { 0 }, }, + .config_map = { 1, TYPE_CPE, }, + .reorder_map = { 0, 1 }, + }, + { + .layout = AV_CH_LAYOUT_2POINT1, + .num_ele = { 1, 0, 0, 1 }, + .pairing = { { 1 }, }, + .index = { { 0 },{ 0 },{ 0 },{ 0 } }, + .config_map = { 2, TYPE_CPE, TYPE_LFE }, + .reorder_map = { 0, 1, 2 }, + }, + { + .layout = AV_CH_LAYOUT_2_1, + .num_ele = { 1, 0, 1, 0 }, + .pairing = { { 1 },{ 0 },{ 0 } }, + .index = { { 0 },{ 0 },{ 0 }, }, + .config_map = { 2, TYPE_CPE, TYPE_SCE }, + .reorder_map = { 0, 1, 2 }, + }, + { + .layout = AV_CH_LAYOUT_SURROUND, + .num_ele = { 2, 0, 0, 0 }, + .pairing = { { 1, 0 }, }, + .index = { { 0, 0 }, }, + .config_map = { 2, TYPE_CPE, TYPE_SCE, }, + .reorder_map = { 0, 1, 2 }, + }, + { + .layout = AV_CH_LAYOUT_3POINT1, + .num_ele = { 2, 0, 0, 1 }, + .pairing = { { 1, 0 }, }, + .index = { { 0, 0 }, { 0 }, { 0 }, { 0 }, }, + .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_LFE }, + .reorder_map = { 0, 1, 2, 3 }, + }, + { + .layout = AV_CH_LAYOUT_4POINT0, + .num_ele = { 2, 0, 1, 0 }, + .pairing = { { 1, 0 }, { 0 }, { 0 }, }, + .index = { { 0, 0 }, { 0 }, { 1 } }, + .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3 }, + }, + { + .layout = AV_CH_LAYOUT_4POINT1, + .num_ele = { 2, 1, 1, 0 }, + .pairing = { { 1, 0 }, { 0 }, { 0 }, }, + .index = { { 0, 0 }, { 1 }, { 2 }, { 0 } }, + .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3, 4 }, + }, + { + .layout = AV_CH_LAYOUT_2_2, + .num_ele = { 1, 1, 0, 0 }, + .pairing = { { 1 }, { 1 }, }, + .index = { { 0 }, { 1 }, }, + .config_map = { 2, TYPE_CPE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3 }, + }, + { + .layout = AV_CH_LAYOUT_QUAD, + .num_ele = { 1, 0, 1, 0 }, + .pairing = { { 1 }, { 0 }, { 1 }, }, + .index = { { 0 }, { 0 }, { 1 } }, + .config_map = { 2, TYPE_CPE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3 }, + }, + { + .layout = AV_CH_LAYOUT_5POINT0, + .num_ele = { 2, 1, 0, 0 }, + .pairing = { { 1, 0 }, { 1 }, }, + .index = { { 0, 0 }, { 1 } }, + .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3, 4 }, + }, + { + .layout = AV_CH_LAYOUT_5POINT1, + .num_ele = { 2, 1, 1, 0 }, + .pairing = { { 1, 0 }, { 0 }, { 1 }, }, + .index = { { 0, 0 }, { 1 }, { 1 } }, + .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3, 4, 5 }, + }, + { + .layout = AV_CH_LAYOUT_5POINT0_BACK, + .num_ele = { 2, 0, 1, 0 }, + .pairing = { { 1, 0 }, { 0 }, { 1 } }, + .index = { { 0, 0 }, { 0 }, { 1 } }, + .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3, 4 }, + }, + { + .layout = AV_CH_LAYOUT_5POINT1_BACK, + .num_ele = { 2, 1, 1, 0 }, + .pairing = { { 1, 0 }, { 0 }, { 1 }, }, + .index = { { 0, 0 }, { 1 }, { 1 } }, + .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3, 4, 5 }, + }, + { + .layout = AV_CH_LAYOUT_6POINT0, + .num_ele = { 2, 1, 1, 0 }, + .pairing = { { 1, 0 }, { 1 }, { 0 }, }, + .index = { { 0, 0 }, { 1 }, { 1 } }, + .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3, 4, 5 }, + }, + { + .layout = AV_CH_LAYOUT_6POINT0_FRONT, + .num_ele = { 2, 1, 0, 0 }, + .pairing = { { 1, 1 }, { 1 } }, + .index = { { 1, 0 }, { 2 }, }, + .config_map = { 3, TYPE_CPE, TYPE_CPE, TYPE_CPE, }, + .reorder_map = { 0, 1, 2, 3, 4, 5 }, + }, + { + .layout = AV_CH_LAYOUT_HEXAGONAL, + .num_ele = { 2, 0, 2, 0 }, + .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, }, + .index = { { 0, 0 },{ 0 },{ 1, 1 } }, + .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, }, + .reorder_map = { 0, 1, 2, 3, 4, 5 }, + }, + { + .layout = AV_CH_LAYOUT_6POINT1, + .num_ele = { 2, 1, 2, 0 }, + .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, }, + .index = { { 0, 0 },{ 1 },{ 1, 2 } }, + .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6 }, + }, + { + .layout = AV_CH_LAYOUT_6POINT1_BACK, + .num_ele = { 2, 1, 2, 0 }, + .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, }, + .index = { { 0, 0 }, { 1 }, { 1, 2 } }, + .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6 }, + }, + { + .layout = AV_CH_LAYOUT_6POINT1_FRONT, + .num_ele = { 2, 1, 2, 0 }, + .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, }, + .index = { { 0, 0 }, { 1 }, { 1, 2 } }, + .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6 }, + }, + { + .layout = AV_CH_LAYOUT_7POINT0, + .num_ele = { 2, 1, 1, 0 }, + .pairing = { { 1, 0 }, { 1 }, { 1 }, }, + .index = { { 0, 0 }, { 1 }, { 2 }, }, + .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6 }, + }, + { + .layout = AV_CH_LAYOUT_7POINT0_FRONT, + .num_ele = { 2, 1, 1, 0 }, + .pairing = { { 1, 0 }, { 1 }, { 1 }, }, + .index = { { 0, 0 }, { 1 }, { 2 }, }, + .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6 }, + }, + { + .layout = AV_CH_LAYOUT_7POINT1, + .num_ele = { 2, 1, 2, 0 }, + .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, }, + .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } }, + .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 }, + }, + { + .layout = AV_CH_LAYOUT_7POINT1_WIDE, + .num_ele = { 2, 1, 2, 0 }, + .pairing = { { 1, 0 }, { 0 },{ 1, 1 }, }, + .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } }, + .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 }, + }, + { + .layout = AV_CH_LAYOUT_7POINT1_WIDE_BACK, + .num_ele = { 2, 1, 2, 0 }, + .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, }, + .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } }, + .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 }, + }, + { + .layout = AV_CH_LAYOUT_OCTAGONAL, + .num_ele = { 2, 1, 2, 0 }, + .pairing = { { 1, 0 }, { 1 }, { 1, 0 }, }, + .index = { { 0, 0 }, { 1 }, { 2, 1 } }, + .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 }, + }, + { /* Meant for order 2/mixed ambisonics */ + .layout = AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER, + .num_ele = { 2, 2, 2, 0 }, + .pairing = { { 1, 0 }, { 1, 0 }, { 1, 0 }, }, + .index = { { 0, 0 }, { 1, 1 }, { 2, 2 } }, + .config_map = { 6, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, + }, + { /* Meant for order 2/mixed ambisonics */ + .layout = AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_BACK_CENTER | + AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_TOP_CENTER, + .num_ele = { 2, 2, 2, 0 }, + .pairing = { { 1, 1 }, { 1, 0 }, { 1, 0 }, }, + .index = { { 0, 1 }, { 2, 0 }, { 3, 1 } }, + .config_map = { 6, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + }, + { + .layout = AV_CH_LAYOUT_HEXADECAGONAL, + .num_ele = { 4, 2, 4, 0 }, + .pairing = { { 1, 0, 1, 0 }, { 1, 1 }, { 1, 0, 1, 0 }, }, + .index = { { 0, 0, 1, 1 }, { 2, 3 }, { 4, 2, 5, 3 } }, + .config_map = { 10, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE }, + .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + }, +}; + +/** + * AAC encoder context + */ +typedef struct AACEncContext { + AVClass *av_class; + AACEncOptions options; ///< encoding options + PutBitContext pb; + FFTContext mdct1024; ///< long (1024 samples) frame transform context + FFTContext mdct128; ///< short (128 samples) frame transform context + AVFloatDSPContext *fdsp; + AACPCEInfo pce; ///< PCE data, if needed + float *planar_samples[16]; ///< saved preprocessed input + + int profile; ///< copied from avctx + int needs_pce; ///< flag for non-standard layout + LPCContext lpc; ///< used by TNS + int samplerate_index; ///< MPEG-4 samplerate index + int channels; ///< channel count + const uint8_t *reorder_map; ///< lavc to aac reorder map + const uint8_t *chan_map; ///< channel configuration map + + ChannelElement *cpe; ///< channel elements + FFPsyContext psy; + struct FFPsyPreprocessContext* psypp; + const AACCoefficientsEncoder *coder; + int cur_channel; ///< current channel for coder context + int random_state; + float lambda; + int last_frame_pb_count; ///< number of bits for the previous frame + float lambda_sum; ///< sum(lambda), for Qvg reporting + int lambda_count; ///< count(lambda), for Qvg reporting + enum RawDataBlockType cur_type; ///< channel group type cur_channel belongs to + + AudioFrameQueue afq; + DECLARE_ALIGNED(16, int, qcoefs)[96]; ///< quantized coefficients + DECLARE_ALIGNED(32, float, scoefs)[1024]; ///< scaled coefficients + + uint16_t quantize_band_cost_cache_generation; + AACQuantizeBandCostCacheEntry quantize_band_cost_cache[256][128]; ///< memoization area for quantize_band_cost + + void (*abs_pow34)(float *out, const float *in, const int size); + void (*quant_bands)(int *out, const float *in, const float *scaled, + int size, int is_signed, int maxval, const float Q34, + const float rounding); + + struct { + float *samples; + } buffer; +} AACEncContext; + +void ff_aac_dsp_init_x86(AACEncContext *s); +void ff_aac_coder_init_mips(AACEncContext *c); +void ff_quantize_band_cost_cache_init(struct AACEncContext *s); + + +#endif /* AVCODEC_AACENC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_is.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_is.c new file mode 100644 index 000000000..2f5b7eb8d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_is.c @@ -0,0 +1,158 @@ +/* + * AAC encoder intensity stereo + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder Intensity Stereo + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#include "aacenc.h" +#include "aacenc_utils.h" +#include "aacenc_is.h" +#include "aacenc_quantization.h" + +struct AACISError ff_aac_is_encoding_err(AACEncContext *s, ChannelElement *cpe, + int start, int w, int g, float ener0, + float ener1, float ener01, + int use_pcoeffs, int phase) +{ + int i, w2; + SingleChannelElement *sce0 = &cpe->ch[0]; + SingleChannelElement *sce1 = &cpe->ch[1]; + float *L = use_pcoeffs ? sce0->pcoeffs : sce0->coeffs; + float *R = use_pcoeffs ? sce1->pcoeffs : sce1->coeffs; + float *L34 = &s->scoefs[256*0], *R34 = &s->scoefs[256*1]; + float *IS = &s->scoefs[256*2], *I34 = &s->scoefs[256*3]; + float dist1 = 0.0f, dist2 = 0.0f; + struct AACISError is_error = {0}; + + if (ener01 <= 0 || ener0 <= 0) { + is_error.pass = 0; + return is_error; + } + + for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { + FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g]; + FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g]; + int is_band_type, is_sf_idx = FFMAX(1, sce0->sf_idx[w*16+g]-4); + float e01_34 = phase*pos_pow34(ener1/ener0); + float maxval, dist_spec_err = 0.0f; + float minthr = FFMIN(band0->threshold, band1->threshold); + for (i = 0; i < sce0->ics.swb_sizes[g]; i++) + IS[i] = (L[start+(w+w2)*128+i] + phase*R[start+(w+w2)*128+i])*sqrt(ener0/ener01); + s->abs_pow34(L34, &L[start+(w+w2)*128], sce0->ics.swb_sizes[g]); + s->abs_pow34(R34, &R[start+(w+w2)*128], sce0->ics.swb_sizes[g]); + s->abs_pow34(I34, IS, sce0->ics.swb_sizes[g]); + maxval = find_max_val(1, sce0->ics.swb_sizes[g], I34); + is_band_type = find_min_book(maxval, is_sf_idx); + dist1 += quantize_band_cost(s, &L[start + (w+w2)*128], L34, + sce0->ics.swb_sizes[g], + sce0->sf_idx[w*16+g], + sce0->band_type[w*16+g], + s->lambda / band0->threshold, INFINITY, NULL, NULL, 0); + dist1 += quantize_band_cost(s, &R[start + (w+w2)*128], R34, + sce1->ics.swb_sizes[g], + sce1->sf_idx[w*16+g], + sce1->band_type[w*16+g], + s->lambda / band1->threshold, INFINITY, NULL, NULL, 0); + dist2 += quantize_band_cost(s, IS, I34, sce0->ics.swb_sizes[g], + is_sf_idx, is_band_type, + s->lambda / minthr, INFINITY, NULL, NULL, 0); + for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { + dist_spec_err += (L34[i] - I34[i])*(L34[i] - I34[i]); + dist_spec_err += (R34[i] - I34[i]*e01_34)*(R34[i] - I34[i]*e01_34); + } + dist_spec_err *= s->lambda / minthr; + dist2 += dist_spec_err; + } + + is_error.pass = dist2 <= dist1; + is_error.phase = phase; + is_error.error = dist2 - dist1; + is_error.dist1 = dist1; + is_error.dist2 = dist2; + is_error.ener01 = ener01; + + return is_error; +} + +void ff_aac_search_for_is(AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe) +{ + SingleChannelElement *sce0 = &cpe->ch[0]; + SingleChannelElement *sce1 = &cpe->ch[1]; + int start = 0, count = 0, w, w2, g, i, prev_sf1 = -1, prev_bt = -1, prev_is = 0; + const float freq_mult = avctx->sample_rate/(1024.0f/sce0->ics.num_windows)/2.0f; + uint8_t nextband1[128]; + + if (!cpe->common_window) + return; + + /** Scout out next nonzero bands */ + ff_init_nextband_map(sce1, nextband1); + + for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) { + start = 0; + for (g = 0; g < sce0->ics.num_swb; g++) { + if (start*freq_mult > INT_STEREO_LOW_LIMIT*(s->lambda/170.0f) && + cpe->ch[0].band_type[w*16+g] != NOISE_BT && !cpe->ch[0].zeroes[w*16+g] && + cpe->ch[1].band_type[w*16+g] != NOISE_BT && !cpe->ch[1].zeroes[w*16+g] && + ff_sfdelta_can_remove_band(sce1, nextband1, prev_sf1, w*16+g)) { + float ener0 = 0.0f, ener1 = 0.0f, ener01 = 0.0f, ener01p = 0.0f; + struct AACISError ph_err1, ph_err2, *best; + for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { + for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { + float coef0 = sce0->coeffs[start+(w+w2)*128+i]; + float coef1 = sce1->coeffs[start+(w+w2)*128+i]; + ener0 += coef0*coef0; + ener1 += coef1*coef1; + ener01 += (coef0 + coef1)*(coef0 + coef1); + ener01p += (coef0 - coef1)*(coef0 - coef1); + } + } + ph_err1 = ff_aac_is_encoding_err(s, cpe, start, w, g, + ener0, ener1, ener01p, 0, -1); + ph_err2 = ff_aac_is_encoding_err(s, cpe, start, w, g, + ener0, ener1, ener01, 0, +1); + best = (ph_err1.pass && ph_err1.error < ph_err2.error) ? &ph_err1 : &ph_err2; + if (best->pass) { + cpe->is_mask[w*16+g] = 1; + cpe->ms_mask[w*16+g] = 0; + cpe->ch[0].is_ener[w*16+g] = sqrt(ener0 / best->ener01); + cpe->ch[1].is_ener[w*16+g] = ener0/ener1; + cpe->ch[1].band_type[w*16+g] = (best->phase > 0) ? INTENSITY_BT : INTENSITY_BT2; + if (prev_is && prev_bt != cpe->ch[1].band_type[w*16+g]) { + /** Flip M/S mask and pick the other CB, since it encodes more efficiently */ + cpe->ms_mask[w*16+g] = 1; + cpe->ch[1].band_type[w*16+g] = (best->phase > 0) ? INTENSITY_BT2 : INTENSITY_BT; + } + prev_bt = cpe->ch[1].band_type[w*16+g]; + count++; + } + } + if (!sce1->zeroes[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT) + prev_sf1 = sce1->sf_idx[w*16+g]; + prev_is = cpe->is_mask[w*16+g]; + start += sce0->ics.swb_sizes[g]; + } + } + cpe->is_mode = !!count; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_is.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_is.h new file mode 100644 index 000000000..269fd1a9c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_is.h @@ -0,0 +1,51 @@ +/* + * AAC encoder intensity stereo + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder Intensity Stereo + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#ifndef AVCODEC_AACENC_IS_H +#define AVCODEC_AACENC_IS_H + +#include "aacenc.h" + +/** Frequency in Hz for lower limit of intensity stereo **/ +#define INT_STEREO_LOW_LIMIT 6100 + +struct AACISError { + int pass; /* 1 if dist2 <= dist1 */ + int phase; /* -1 or +1 */ + float error; /* fabs(dist1 - dist2) */ + float dist1; /* From original coeffs */ + float dist2; /* From IS'd coeffs */ + float ener01; +}; + +struct AACISError ff_aac_is_encoding_err(AACEncContext *s, ChannelElement *cpe, + int start, int w, int g, float ener0, + float ener1, float ener01, + int use_pcoeffs, int phase); +void ff_aac_search_for_is(AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe); + +#endif /* AVCODEC_AACENC_IS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_ltp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_ltp.c new file mode 100644 index 000000000..f77f0b6a7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_ltp.c @@ -0,0 +1,236 @@ +/* + * AAC encoder long term prediction extension + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder long term prediction extension + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#include "aacenc_ltp.h" +#include "aacenc_quantization.h" +#include "aacenc_utils.h" + +/** + * Encode LTP data. + */ +void ff_aac_encode_ltp_info(AACEncContext *s, SingleChannelElement *sce, + int common_window) +{ + int i; + IndividualChannelStream *ics = &sce->ics; + if (s->profile != FF_PROFILE_AAC_LTP || !ics->predictor_present) + return; + if (common_window) + put_bits(&s->pb, 1, 0); + put_bits(&s->pb, 1, ics->ltp.present); + if (!ics->ltp.present) + return; + put_bits(&s->pb, 11, ics->ltp.lag); + put_bits(&s->pb, 3, ics->ltp.coef_idx); + for (i = 0; i < FFMIN(ics->max_sfb, MAX_LTP_LONG_SFB); i++) + put_bits(&s->pb, 1, ics->ltp.used[i]); +} + +void ff_aac_ltp_insert_new_frame(AACEncContext *s) +{ + int i, ch, tag, chans, cur_channel, start_ch = 0; + ChannelElement *cpe; + SingleChannelElement *sce; + for (i = 0; i < s->chan_map[0]; i++) { + cpe = &s->cpe[i]; + tag = s->chan_map[i+1]; + chans = tag == TYPE_CPE ? 2 : 1; + for (ch = 0; ch < chans; ch++) { + sce = &cpe->ch[ch]; + cur_channel = start_ch + ch; + /* New sample + overlap */ + memcpy(&sce->ltp_state[0], &sce->ltp_state[1024], 1024*sizeof(sce->ltp_state[0])); + memcpy(&sce->ltp_state[1024], &s->planar_samples[cur_channel][2048], 1024*sizeof(sce->ltp_state[0])); + memcpy(&sce->ltp_state[2048], &sce->ret_buf[0], 1024*sizeof(sce->ltp_state[0])); + sce->ics.ltp.lag = 0; + } + start_ch += chans; + } +} + +static void get_lag(float *buf, const float *new, LongTermPrediction *ltp) +{ + int i, j, lag = 0, max_corr = 0; + float max_ratio = 0.0f; + for (i = 0; i < 2048; i++) { + float corr, s0 = 0.0f, s1 = 0.0f; + const int start = FFMAX(0, i - 1024); + for (j = start; j < 2048; j++) { + const int idx = j - i + 1024; + s0 += new[j]*buf[idx]; + s1 += buf[idx]*buf[idx]; + } + corr = s1 > 0.0f ? s0/sqrt(s1) : 0.0f; + if (corr > max_corr) { + max_corr = corr; + lag = i; + max_ratio = corr/(2048-start); + } + } + ltp->lag = FFMAX(av_clip_uintp2(lag, 11), 0); + ltp->coef_idx = quant_array_idx(max_ratio, ltp_coef, 8); + ltp->coef = ltp_coef[ltp->coef_idx]; +} + +static void generate_samples(float *buf, LongTermPrediction *ltp) +{ + int i, samples_num = 2048; + if (!ltp->lag) { + ltp->present = 0; + return; + } else if (ltp->lag < 1024) { + samples_num = ltp->lag + 1024; + } + for (i = 0; i < samples_num; i++) + buf[i] = ltp->coef*buf[i + 2048 - ltp->lag]; + memset(&buf[i], 0, (2048 - i)*sizeof(float)); +} + +/** + * Process LTP parameters + * @see Patent WO2006070265A1 + */ +void ff_aac_update_ltp(AACEncContext *s, SingleChannelElement *sce) +{ + float *pred_signal = &sce->ltp_state[0]; + const float *samples = &s->planar_samples[s->cur_channel][1024]; + + if (s->profile != FF_PROFILE_AAC_LTP) + return; + + /* Calculate lag */ + get_lag(pred_signal, samples, &sce->ics.ltp); + generate_samples(pred_signal, &sce->ics.ltp); +} + +void ff_aac_adjust_common_ltp(AACEncContext *s, ChannelElement *cpe) +{ + int sfb, count = 0; + SingleChannelElement *sce0 = &cpe->ch[0]; + SingleChannelElement *sce1 = &cpe->ch[1]; + + if (!cpe->common_window || + sce0->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE || + sce1->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + sce0->ics.ltp.present = 0; + return; + } + + for (sfb = 0; sfb < FFMIN(sce0->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++) { + int sum = sce0->ics.ltp.used[sfb] + sce1->ics.ltp.used[sfb]; + if (sum != 2) { + sce0->ics.ltp.used[sfb] = 0; + } else { + count++; + } + } + + sce0->ics.ltp.present = !!count; + sce0->ics.predictor_present = !!count; +} + +/** + * Mark LTP sfb's + */ +void ff_aac_search_for_ltp(AACEncContext *s, SingleChannelElement *sce, + int common_window) +{ + int w, g, w2, i, start = 0, count = 0; + int saved_bits = -(15 + FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB)); + float *C34 = &s->scoefs[128*0], *PCD = &s->scoefs[128*1]; + float *PCD34 = &s->scoefs[128*2]; + const int max_ltp = FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); + + if (sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + if (sce->ics.ltp.lag) { + memset(&sce->ltp_state[0], 0, 3072*sizeof(sce->ltp_state[0])); + memset(&sce->ics.ltp, 0, sizeof(LongTermPrediction)); + } + return; + } + + if (!sce->ics.ltp.lag || s->lambda > 120.0f) + return; + + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = 0; + for (g = 0; g < sce->ics.num_swb; g++) { + int bits1 = 0, bits2 = 0; + float dist1 = 0.0f, dist2 = 0.0f; + if (w*16+g > max_ltp) { + start += sce->ics.swb_sizes[g]; + continue; + } + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + int bits_tmp1, bits_tmp2; + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; + for (i = 0; i < sce->ics.swb_sizes[g]; i++) + PCD[i] = sce->coeffs[start+(w+w2)*128+i] - sce->lcoeffs[start+(w+w2)*128+i]; + s->abs_pow34(C34, &sce->coeffs[start+(w+w2)*128], sce->ics.swb_sizes[g]); + s->abs_pow34(PCD34, PCD, sce->ics.swb_sizes[g]); + dist1 += quantize_band_cost(s, &sce->coeffs[start+(w+w2)*128], C34, sce->ics.swb_sizes[g], + sce->sf_idx[(w+w2)*16+g], sce->band_type[(w+w2)*16+g], + s->lambda/band->threshold, INFINITY, &bits_tmp1, NULL, 0); + dist2 += quantize_band_cost(s, PCD, PCD34, sce->ics.swb_sizes[g], + sce->sf_idx[(w+w2)*16+g], + sce->band_type[(w+w2)*16+g], + s->lambda/band->threshold, INFINITY, &bits_tmp2, NULL, 0); + bits1 += bits_tmp1; + bits2 += bits_tmp2; + } + if (dist2 < dist1 && bits2 < bits1) { + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) + for (i = 0; i < sce->ics.swb_sizes[g]; i++) + sce->coeffs[start+(w+w2)*128+i] -= sce->lcoeffs[start+(w+w2)*128+i]; + sce->ics.ltp.used[w*16+g] = 1; + saved_bits += bits1 - bits2; + count++; + } + start += sce->ics.swb_sizes[g]; + } + } + + sce->ics.ltp.present = !!count && (saved_bits >= 0); + sce->ics.predictor_present = !!sce->ics.ltp.present; + + /* Reset any marked sfbs */ + if (!sce->ics.ltp.present && !!count) { + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + start = 0; + for (g = 0; g < sce->ics.num_swb; g++) { + if (sce->ics.ltp.used[w*16+g]) { + for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { + for (i = 0; i < sce->ics.swb_sizes[g]; i++) { + sce->coeffs[start+(w+w2)*128+i] += sce->lcoeffs[start+(w+w2)*128+i]; + } + } + } + start += sce->ics.swb_sizes[g]; + } + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_ltp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_ltp.h new file mode 100644 index 000000000..727687842 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_ltp.h @@ -0,0 +1,41 @@ +/* + * AAC encoder long term prediction extension + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder long term prediction extension + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#ifndef AVCODEC_AACENC_LTP_H +#define AVCODEC_AACENC_LTP_H + +#include "aacenc.h" + +void ff_aac_encode_ltp_info(AACEncContext *s, SingleChannelElement *sce, + int common_window); +void ff_aac_update_ltp(AACEncContext *s, SingleChannelElement *sce); +void ff_aac_adjust_common_ltp(AACEncContext *s, ChannelElement *cpe); +void ff_aac_ltp_insert_new_frame(AACEncContext *s); +void ff_aac_search_for_ltp(AACEncContext *s, SingleChannelElement *sce, + int common_window); + +#endif /* AVCODEC_AACENC_LTP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_pred.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_pred.c new file mode 100644 index 000000000..d111192f0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_pred.c @@ -0,0 +1,347 @@ +/* + * AAC encoder main-type prediction + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder main-type prediction + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#include "aactab.h" +#include "aacenc_pred.h" +#include "aacenc_utils.h" +#include "aacenc_is.h" /* <- Needed for common window distortions */ +#include "aacenc_quantization.h" + +#define RESTORE_PRED(sce, sfb) \ + if (sce->ics.prediction_used[sfb]) {\ + sce->ics.prediction_used[sfb] = 0;\ + sce->band_type[sfb] = sce->band_alt[sfb];\ + } + +static inline float flt16_round(float pf) +{ + union av_intfloat32 tmp; + tmp.f = pf; + tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U; + return tmp.f; +} + +static inline float flt16_even(float pf) +{ + union av_intfloat32 tmp; + tmp.f = pf; + tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U >> 16)) & 0xFFFF0000U; + return tmp.f; +} + +static inline float flt16_trunc(float pf) +{ + union av_intfloat32 pun; + pun.f = pf; + pun.i &= 0xFFFF0000U; + return pun.f; +} + +static inline void predict(PredictorState *ps, float *coef, float *rcoef, int set) +{ + float k2; + const float a = 0.953125; // 61.0 / 64 + const float alpha = 0.90625; // 29.0 / 32 + const float k1 = ps->k1; + const float r0 = ps->r0, r1 = ps->r1; + const float cor0 = ps->cor0, cor1 = ps->cor1; + const float var0 = ps->var0, var1 = ps->var1; + const float e0 = *coef - ps->x_est; + const float e1 = e0 - k1 * r0; + + if (set) + *coef = e0; + + ps->cor1 = flt16_trunc(alpha * cor1 + r1 * e1); + ps->var1 = flt16_trunc(alpha * var1 + 0.5f * (r1 * r1 + e1 * e1)); + ps->cor0 = flt16_trunc(alpha * cor0 + r0 * e0); + ps->var0 = flt16_trunc(alpha * var0 + 0.5f * (r0 * r0 + e0 * e0)); + ps->r1 = flt16_trunc(a * (r0 - k1 * e0)); + ps->r0 = flt16_trunc(a * e0); + + /* Prediction for next frame */ + ps->k1 = ps->var0 > 1 ? ps->cor0 * flt16_even(a / ps->var0) : 0; + k2 = ps->var1 > 1 ? ps->cor1 * flt16_even(a / ps->var1) : 0; + *rcoef = ps->x_est = flt16_round(ps->k1*ps->r0 + k2*ps->r1); +} + +static inline void reset_predict_state(PredictorState *ps) +{ + ps->r0 = 0.0f; + ps->r1 = 0.0f; + ps->k1 = 0.0f; + ps->cor0 = 0.0f; + ps->cor1 = 0.0f; + ps->var0 = 1.0f; + ps->var1 = 1.0f; + ps->x_est = 0.0f; +} + +static inline void reset_all_predictors(PredictorState *ps) +{ + int i; + for (i = 0; i < MAX_PREDICTORS; i++) + reset_predict_state(&ps[i]); +} + +static inline void reset_predictor_group(SingleChannelElement *sce, int group_num) +{ + int i; + PredictorState *ps = sce->predictor_state; + for (i = group_num - 1; i < MAX_PREDICTORS; i += 30) + reset_predict_state(&ps[i]); +} + +void ff_aac_apply_main_pred(AACEncContext *s, SingleChannelElement *sce) +{ + int sfb, k; + const int pmax = FFMIN(sce->ics.max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]); + + if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { + for (sfb = 0; sfb < pmax; sfb++) { + for (k = sce->ics.swb_offset[sfb]; k < sce->ics.swb_offset[sfb + 1]; k++) { + predict(&sce->predictor_state[k], &sce->coeffs[k], &sce->prcoeffs[k], + sce->ics.predictor_present && sce->ics.prediction_used[sfb]); + } + } + if (sce->ics.predictor_reset_group) { + reset_predictor_group(sce, sce->ics.predictor_reset_group); + } + } else { + reset_all_predictors(sce->predictor_state); + } +} + +/* If inc = 0 you can check if this returns 0 to see if you can reset freely */ +static inline int update_counters(IndividualChannelStream *ics, int inc) +{ + int i; + for (i = 1; i < 31; i++) { + ics->predictor_reset_count[i] += inc; + if (ics->predictor_reset_count[i] > PRED_RESET_FRAME_MIN) + return i; /* Reset this immediately */ + } + return 0; +} + +void ff_aac_adjust_common_pred(AACEncContext *s, ChannelElement *cpe) +{ + int start, w, w2, g, i, count = 0; + SingleChannelElement *sce0 = &cpe->ch[0]; + SingleChannelElement *sce1 = &cpe->ch[1]; + const int pmax0 = FFMIN(sce0->ics.max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]); + const int pmax1 = FFMIN(sce1->ics.max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]); + const int pmax = FFMIN(pmax0, pmax1); + + if (!cpe->common_window || + sce0->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE || + sce1->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) + return; + + for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) { + start = 0; + for (g = 0; g < sce0->ics.num_swb; g++) { + int sfb = w*16+g; + int sum = sce0->ics.prediction_used[sfb] + sce1->ics.prediction_used[sfb]; + float ener0 = 0.0f, ener1 = 0.0f, ener01 = 0.0f; + struct AACISError ph_err1, ph_err2, *erf; + if (sfb < PRED_SFB_START || sfb > pmax || sum != 2) { + RESTORE_PRED(sce0, sfb); + RESTORE_PRED(sce1, sfb); + start += sce0->ics.swb_sizes[g]; + continue; + } + for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { + for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { + float coef0 = sce0->pcoeffs[start+(w+w2)*128+i]; + float coef1 = sce1->pcoeffs[start+(w+w2)*128+i]; + ener0 += coef0*coef0; + ener1 += coef1*coef1; + ener01 += (coef0 + coef1)*(coef0 + coef1); + } + } + ph_err1 = ff_aac_is_encoding_err(s, cpe, start, w, g, + ener0, ener1, ener01, 1, -1); + ph_err2 = ff_aac_is_encoding_err(s, cpe, start, w, g, + ener0, ener1, ener01, 1, +1); + erf = ph_err1.error < ph_err2.error ? &ph_err1 : &ph_err2; + if (erf->pass) { + sce0->ics.prediction_used[sfb] = 1; + sce1->ics.prediction_used[sfb] = 1; + count++; + } else { + RESTORE_PRED(sce0, sfb); + RESTORE_PRED(sce1, sfb); + } + start += sce0->ics.swb_sizes[g]; + } + } + + sce1->ics.predictor_present = sce0->ics.predictor_present = !!count; +} + +static void update_pred_resets(SingleChannelElement *sce) +{ + int i, max_group_id_c, max_frame = 0; + float avg_frame = 0.0f; + IndividualChannelStream *ics = &sce->ics; + + /* Update the counters and immediately update any frame behind schedule */ + if ((ics->predictor_reset_group = update_counters(&sce->ics, 1))) + return; + + for (i = 1; i < 31; i++) { + /* Count-based */ + if (ics->predictor_reset_count[i] > max_frame) { + max_group_id_c = i; + max_frame = ics->predictor_reset_count[i]; + } + avg_frame = (ics->predictor_reset_count[i] + avg_frame)/2; + } + + if (max_frame > PRED_RESET_MIN) { + ics->predictor_reset_group = max_group_id_c; + } else { + ics->predictor_reset_group = 0; + } +} + +void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce) +{ + int sfb, i, count = 0, cost_coeffs = 0, cost_pred = 0; + const int pmax = FFMIN(sce->ics.max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]); + float *O34 = &s->scoefs[128*0], *P34 = &s->scoefs[128*1]; + float *SENT = &s->scoefs[128*2], *S34 = &s->scoefs[128*3]; + float *QERR = &s->scoefs[128*4]; + + if (sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + sce->ics.predictor_present = 0; + return; + } + + if (!sce->ics.predictor_initialized) { + reset_all_predictors(sce->predictor_state); + sce->ics.predictor_initialized = 1; + memcpy(sce->prcoeffs, sce->coeffs, 1024*sizeof(float)); + for (i = 1; i < 31; i++) + sce->ics.predictor_reset_count[i] = i; + } + + update_pred_resets(sce); + memcpy(sce->band_alt, sce->band_type, sizeof(sce->band_type)); + + for (sfb = PRED_SFB_START; sfb < pmax; sfb++) { + int cost1, cost2, cb_p; + float dist1, dist2, dist_spec_err = 0.0f; + const int cb_n = sce->zeroes[sfb] ? 0 : sce->band_type[sfb]; + const int cb_min = sce->zeroes[sfb] ? 0 : 1; + const int cb_max = sce->zeroes[sfb] ? 0 : RESERVED_BT; + const int start_coef = sce->ics.swb_offset[sfb]; + const int num_coeffs = sce->ics.swb_offset[sfb + 1] - start_coef; + const FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[sfb]; + + if (start_coef + num_coeffs > MAX_PREDICTORS || + (s->cur_channel && sce->band_type[sfb] >= INTENSITY_BT2) || + sce->band_type[sfb] == NOISE_BT) + continue; + + /* Normal coefficients */ + s->abs_pow34(O34, &sce->coeffs[start_coef], num_coeffs); + dist1 = quantize_and_encode_band_cost(s, NULL, &sce->coeffs[start_coef], NULL, + O34, num_coeffs, sce->sf_idx[sfb], + cb_n, s->lambda / band->threshold, INFINITY, &cost1, NULL, 0); + cost_coeffs += cost1; + + /* Encoded coefficients - needed for #bits, band type and quant. error */ + for (i = 0; i < num_coeffs; i++) + SENT[i] = sce->coeffs[start_coef + i] - sce->prcoeffs[start_coef + i]; + s->abs_pow34(S34, SENT, num_coeffs); + if (cb_n < RESERVED_BT) + cb_p = av_clip(find_min_book(find_max_val(1, num_coeffs, S34), sce->sf_idx[sfb]), cb_min, cb_max); + else + cb_p = cb_n; + quantize_and_encode_band_cost(s, NULL, SENT, QERR, S34, num_coeffs, + sce->sf_idx[sfb], cb_p, s->lambda / band->threshold, INFINITY, + &cost2, NULL, 0); + + /* Reconstructed coefficients - needed for distortion measurements */ + for (i = 0; i < num_coeffs; i++) + sce->prcoeffs[start_coef + i] += QERR[i] != 0.0f ? (sce->prcoeffs[start_coef + i] - QERR[i]) : 0.0f; + s->abs_pow34(P34, &sce->prcoeffs[start_coef], num_coeffs); + if (cb_n < RESERVED_BT) + cb_p = av_clip(find_min_book(find_max_val(1, num_coeffs, P34), sce->sf_idx[sfb]), cb_min, cb_max); + else + cb_p = cb_n; + dist2 = quantize_and_encode_band_cost(s, NULL, &sce->prcoeffs[start_coef], NULL, + P34, num_coeffs, sce->sf_idx[sfb], + cb_p, s->lambda / band->threshold, INFINITY, NULL, NULL, 0); + for (i = 0; i < num_coeffs; i++) + dist_spec_err += (O34[i] - P34[i])*(O34[i] - P34[i]); + dist_spec_err *= s->lambda / band->threshold; + dist2 += dist_spec_err; + + if (dist2 <= dist1 && cb_p <= cb_n) { + cost_pred += cost2; + sce->ics.prediction_used[sfb] = 1; + sce->band_alt[sfb] = cb_n; + sce->band_type[sfb] = cb_p; + count++; + } else { + cost_pred += cost1; + sce->band_alt[sfb] = cb_p; + } + } + + if (count && cost_coeffs < cost_pred) { + count = 0; + for (sfb = PRED_SFB_START; sfb < pmax; sfb++) + RESTORE_PRED(sce, sfb); + memset(&sce->ics.prediction_used, 0, sizeof(sce->ics.prediction_used)); + } + + sce->ics.predictor_present = !!count; +} + +/** + * Encoder predictors data. + */ +void ff_aac_encode_main_pred(AACEncContext *s, SingleChannelElement *sce) +{ + int sfb; + IndividualChannelStream *ics = &sce->ics; + const int pmax = FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]); + + if (s->profile != FF_PROFILE_AAC_MAIN || + !ics->predictor_present) + return; + + put_bits(&s->pb, 1, !!ics->predictor_reset_group); + if (ics->predictor_reset_group) + put_bits(&s->pb, 5, ics->predictor_reset_group); + for (sfb = 0; sfb < pmax; sfb++) + put_bits(&s->pb, 1, ics->prediction_used[sfb]); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_pred.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_pred.h new file mode 100644 index 000000000..aa305f45a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_pred.h @@ -0,0 +1,47 @@ +/* + * AAC encoder main-type prediction + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder main-type prediction + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#ifndef AVCODEC_AACENC_PRED_H +#define AVCODEC_AACENC_PRED_H + +#include "aacenc.h" + +/* Every predictor group needs to get reset at least once in this many frames */ +#define PRED_RESET_FRAME_MIN 240 + +/* Any frame with less than this amount of frames since last reset is ok */ +#define PRED_RESET_MIN 64 + +/* Raise to filter any low frequency artifacts due to prediction */ +#define PRED_SFB_START 10 + +void ff_aac_apply_main_pred(AACEncContext *s, SingleChannelElement *sce); +void ff_aac_adjust_common_pred(AACEncContext *s, ChannelElement *cpe); +void ff_aac_search_for_pred(AACEncContext *s, SingleChannelElement *sce); +void ff_aac_encode_main_pred(AACEncContext *s, SingleChannelElement *sce); + +#endif /* AVCODEC_AACENC_PRED_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_quantization.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_quantization.h new file mode 100644 index 000000000..fc5a46b87 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_quantization.h @@ -0,0 +1,283 @@ +/* + * AAC encoder quantizer + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder quantizer + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#ifndef AVCODEC_AACENC_QUANTIZATION_H +#define AVCODEC_AACENC_QUANTIZATION_H + +#include "aactab.h" +#include "aacenc.h" +#include "aacenctab.h" +#include "aacenc_utils.h" + +/** + * Calculate rate distortion cost for quantizing with given codebook + * + * @return quantization distortion + */ +static av_always_inline float quantize_and_encode_band_cost_template( + struct AACEncContext *s, + PutBitContext *pb, const float *in, float *out, + const float *scaled, int size, int scale_idx, + int cb, const float lambda, const float uplim, + int *bits, float *energy, int BT_ZERO, int BT_UNSIGNED, + int BT_PAIR, int BT_ESC, int BT_NOISE, int BT_STEREO, + const float ROUNDING) +{ + const int q_idx = POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512; + const float Q = ff_aac_pow2sf_tab [q_idx]; + const float Q34 = ff_aac_pow34sf_tab[q_idx]; + const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512]; + const float CLIPPED_ESCAPE = 165140.0f*IQ; + int i, j; + float cost = 0; + float qenergy = 0; + const int dim = BT_PAIR ? 2 : 4; + int resbits = 0; + int off; + + if (BT_ZERO || BT_NOISE || BT_STEREO) { + for (i = 0; i < size; i++) + cost += in[i]*in[i]; + if (bits) + *bits = 0; + if (energy) + *energy = qenergy; + if (out) { + for (i = 0; i < size; i += dim) + for (j = 0; j < dim; j++) + out[i+j] = 0.0f; + } + return cost * lambda; + } + if (!scaled) { + s->abs_pow34(s->scoefs, in, size); + scaled = s->scoefs; + } + s->quant_bands(s->qcoefs, in, scaled, size, !BT_UNSIGNED, aac_cb_maxval[cb], Q34, ROUNDING); + if (BT_UNSIGNED) { + off = 0; + } else { + off = aac_cb_maxval[cb]; + } + for (i = 0; i < size; i += dim) { + const float *vec; + int *quants = s->qcoefs + i; + int curidx = 0; + int curbits; + float quantized, rd = 0.0f; + for (j = 0; j < dim; j++) { + curidx *= aac_cb_range[cb]; + curidx += quants[j] + off; + } + curbits = ff_aac_spectral_bits[cb-1][curidx]; + vec = &ff_aac_codebook_vectors[cb-1][curidx*dim]; + if (BT_UNSIGNED) { + for (j = 0; j < dim; j++) { + float t = fabsf(in[i+j]); + float di; + if (BT_ESC && vec[j] == 64.0f) { //FIXME: slow + if (t >= CLIPPED_ESCAPE) { + quantized = CLIPPED_ESCAPE; + curbits += 21; + } else { + int c = av_clip_uintp2(quant(t, Q, ROUNDING), 13); + quantized = c*cbrtf(c)*IQ; + curbits += av_log2(c)*2 - 4 + 1; + } + } else { + quantized = vec[j]*IQ; + } + di = t - quantized; + if (out) + out[i+j] = in[i+j] >= 0 ? quantized : -quantized; + if (vec[j] != 0.0f) + curbits++; + qenergy += quantized*quantized; + rd += di*di; + } + } else { + for (j = 0; j < dim; j++) { + quantized = vec[j]*IQ; + qenergy += quantized*quantized; + if (out) + out[i+j] = quantized; + rd += (in[i+j] - quantized)*(in[i+j] - quantized); + } + } + cost += rd * lambda + curbits; + resbits += curbits; + if (cost >= uplim) + return uplim; + if (pb) { + put_bits(pb, ff_aac_spectral_bits[cb-1][curidx], ff_aac_spectral_codes[cb-1][curidx]); + if (BT_UNSIGNED) + for (j = 0; j < dim; j++) + if (ff_aac_codebook_vectors[cb-1][curidx*dim+j] != 0.0f) + put_bits(pb, 1, in[i+j] < 0.0f); + if (BT_ESC) { + for (j = 0; j < 2; j++) { + if (ff_aac_codebook_vectors[cb-1][curidx*2+j] == 64.0f) { + int coef = av_clip_uintp2(quant(fabsf(in[i+j]), Q, ROUNDING), 13); + int len = av_log2(coef); + + put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2); + put_sbits(pb, len, coef); + } + } + } + } + } + + if (bits) + *bits = resbits; + if (energy) + *energy = qenergy; + return cost; +} + +static inline float quantize_and_encode_band_cost_NONE(struct AACEncContext *s, PutBitContext *pb, + const float *in, float *quant, const float *scaled, + int size, int scale_idx, int cb, + const float lambda, const float uplim, + int *bits, float *energy) { + av_assert0(0); + return 0.0f; +} + +#define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, ROUNDING) \ +static float quantize_and_encode_band_cost_ ## NAME( \ + struct AACEncContext *s, \ + PutBitContext *pb, const float *in, float *quant, \ + const float *scaled, int size, int scale_idx, \ + int cb, const float lambda, const float uplim, \ + int *bits, float *energy) { \ + return quantize_and_encode_band_cost_template( \ + s, pb, in, quant, scaled, size, scale_idx, \ + BT_ESC ? ESC_BT : cb, lambda, uplim, bits, energy, \ + BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, \ + ROUNDING); \ +} + +QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO, 1, 0, 0, 0, 0, 0, ROUND_STANDARD) +QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0, 0, 0, ROUND_STANDARD) +QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0, 0, 0, ROUND_STANDARD) +QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0, 0, 0, ROUND_STANDARD) +QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0, 0, 0, ROUND_STANDARD) +QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC, 0, 1, 1, 1, 0, 0, ROUND_STANDARD) +QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC_RTZ, 0, 1, 1, 1, 0, 0, ROUND_TO_ZERO) +QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NOISE, 0, 0, 0, 0, 1, 0, ROUND_STANDARD) +QUANTIZE_AND_ENCODE_BAND_COST_FUNC(STEREO,0, 0, 0, 0, 0, 1, ROUND_STANDARD) + +static float (*const quantize_and_encode_band_cost_arr[])( + struct AACEncContext *s, + PutBitContext *pb, const float *in, float *quant, + const float *scaled, int size, int scale_idx, + int cb, const float lambda, const float uplim, + int *bits, float *energy) = { + quantize_and_encode_band_cost_ZERO, + quantize_and_encode_band_cost_SQUAD, + quantize_and_encode_band_cost_SQUAD, + quantize_and_encode_band_cost_UQUAD, + quantize_and_encode_band_cost_UQUAD, + quantize_and_encode_band_cost_SPAIR, + quantize_and_encode_band_cost_SPAIR, + quantize_and_encode_band_cost_UPAIR, + quantize_and_encode_band_cost_UPAIR, + quantize_and_encode_band_cost_UPAIR, + quantize_and_encode_band_cost_UPAIR, + quantize_and_encode_band_cost_ESC, + quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */ + quantize_and_encode_band_cost_NOISE, + quantize_and_encode_band_cost_STEREO, + quantize_and_encode_band_cost_STEREO, +}; + +static float (*const quantize_and_encode_band_cost_rtz_arr[])( + struct AACEncContext *s, + PutBitContext *pb, const float *in, float *quant, + const float *scaled, int size, int scale_idx, + int cb, const float lambda, const float uplim, + int *bits, float *energy) = { + quantize_and_encode_band_cost_ZERO, + quantize_and_encode_band_cost_SQUAD, + quantize_and_encode_band_cost_SQUAD, + quantize_and_encode_band_cost_UQUAD, + quantize_and_encode_band_cost_UQUAD, + quantize_and_encode_band_cost_SPAIR, + quantize_and_encode_band_cost_SPAIR, + quantize_and_encode_band_cost_UPAIR, + quantize_and_encode_band_cost_UPAIR, + quantize_and_encode_band_cost_UPAIR, + quantize_and_encode_band_cost_UPAIR, + quantize_and_encode_band_cost_ESC_RTZ, + quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */ + quantize_and_encode_band_cost_NOISE, + quantize_and_encode_band_cost_STEREO, + quantize_and_encode_band_cost_STEREO, +}; + +#define quantize_and_encode_band_cost( \ + s, pb, in, quant, scaled, size, scale_idx, cb, \ + lambda, uplim, bits, energy, rtz) \ + ((rtz) ? quantize_and_encode_band_cost_rtz_arr : quantize_and_encode_band_cost_arr)[cb]( \ + s, pb, in, quant, scaled, size, scale_idx, cb, \ + lambda, uplim, bits, energy) + +static inline float quantize_band_cost(struct AACEncContext *s, const float *in, + const float *scaled, int size, int scale_idx, + int cb, const float lambda, const float uplim, + int *bits, float *energy, int rtz) +{ + return quantize_and_encode_band_cost(s, NULL, in, NULL, scaled, size, scale_idx, + cb, lambda, uplim, bits, energy, rtz); +} + +static inline int quantize_band_cost_bits(struct AACEncContext *s, const float *in, + const float *scaled, int size, int scale_idx, + int cb, const float lambda, const float uplim, + int *bits, float *energy, int rtz) +{ + int auxbits; + quantize_and_encode_band_cost(s, NULL, in, NULL, scaled, size, scale_idx, + cb, 0.0f, uplim, &auxbits, energy, rtz); + if (bits) { + *bits = auxbits; + } + return auxbits; +} + +static inline void quantize_and_encode_band(struct AACEncContext *s, PutBitContext *pb, + const float *in, float *out, int size, int scale_idx, + int cb, const float lambda, int rtz) +{ + quantize_and_encode_band_cost(s, pb, in, out, NULL, size, scale_idx, cb, lambda, + INFINITY, NULL, NULL, rtz); +} + +#include "aacenc_quantization_misc.h" + +#endif /* AVCODEC_AACENC_QUANTIZATION_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_quantization_misc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_quantization_misc.h new file mode 100644 index 000000000..28676ca8d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_quantization_misc.h @@ -0,0 +1,53 @@ +/* + * AAC encoder quantization + * Copyright (C) 2015 Claudio Freire + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder quantization misc reusable function templates + * @author Claudio Freire ( klaussfreire gmail com ) + */ + +#ifndef AVCODEC_AACENC_QUANTIZATION_MISC_H +#define AVCODEC_AACENC_QUANTIZATION_MISC_H + +static inline float quantize_band_cost_cached(struct AACEncContext *s, int w, int g, const float *in, + const float *scaled, int size, int scale_idx, + int cb, const float lambda, const float uplim, + int *bits, float *energy, int rtz) +{ + AACQuantizeBandCostCacheEntry *entry; + av_assert1(scale_idx >= 0 && scale_idx < 256); + entry = &s->quantize_band_cost_cache[scale_idx][w*16+g]; + if (entry->generation != s->quantize_band_cost_cache_generation || entry->cb != cb || entry->rtz != rtz) { + entry->rd = quantize_band_cost(s, in, scaled, size, scale_idx, + cb, lambda, uplim, &entry->bits, &entry->energy, rtz); + entry->cb = cb; + entry->rtz = rtz; + entry->generation = s->quantize_band_cost_cache_generation; + } + if (bits) + *bits = entry->bits; + if (energy) + *energy = entry->energy; + return entry->rd; +} + +#endif /* AVCODEC_AACENC_QUANTIZATION_MISC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_tns.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_tns.c new file mode 100644 index 000000000..2ffe1f8de --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_tns.c @@ -0,0 +1,215 @@ +/* + * AAC encoder TNS + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder temporal noise shaping + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#include "libavutil/libm.h" +#include "aacenc.h" +#include "aacenc_tns.h" +#include "aactab.h" +#include "aacenc_utils.h" +#include "aacenc_quantization.h" + +/* Could be set to 3 to save an additional bit at the cost of little quality */ +#define TNS_Q_BITS 4 + +/* Coefficient resolution in short windows */ +#define TNS_Q_BITS_IS8 4 + +/* We really need the bits we save here elsewhere */ +#define TNS_ENABLE_COEF_COMPRESSION + +/* TNS will only be used if the LPC gain is within these margins */ +#define TNS_GAIN_THRESHOLD_LOW 1.4f +#define TNS_GAIN_THRESHOLD_HIGH 1.16f*TNS_GAIN_THRESHOLD_LOW + +static inline int compress_coeffs(int *coef, int order, int c_bits) +{ + int i; + const int low_idx = c_bits ? 4 : 2; + const int shift_val = c_bits ? 8 : 4; + const int high_idx = c_bits ? 11 : 5; +#ifndef TNS_ENABLE_COEF_COMPRESSION + return 0; +#endif /* TNS_ENABLE_COEF_COMPRESSION */ + for (i = 0; i < order; i++) + if (coef[i] >= low_idx && coef[i] <= high_idx) + return 0; + for (i = 0; i < order; i++) + coef[i] -= (coef[i] > high_idx) ? shift_val : 0; + return 1; +} + +/** + * Encode TNS data. + * Coefficient compression is simply not lossless as it should be + * on any decoder tested and as such is not active. + */ +void ff_aac_encode_tns_info(AACEncContext *s, SingleChannelElement *sce) +{ + TemporalNoiseShaping *tns = &sce->tns; + int i, w, filt, coef_compress = 0, coef_len; + const int is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE; + const int c_bits = is8 ? TNS_Q_BITS_IS8 == 4 : TNS_Q_BITS == 4; + + if (!sce->tns.present) + return; + + for (i = 0; i < sce->ics.num_windows; i++) { + put_bits(&s->pb, 2 - is8, sce->tns.n_filt[i]); + if (!tns->n_filt[i]) + continue; + put_bits(&s->pb, 1, c_bits); + for (filt = 0; filt < tns->n_filt[i]; filt++) { + put_bits(&s->pb, 6 - 2 * is8, tns->length[i][filt]); + put_bits(&s->pb, 5 - 2 * is8, tns->order[i][filt]); + if (!tns->order[i][filt]) + continue; + put_bits(&s->pb, 1, tns->direction[i][filt]); + coef_compress = compress_coeffs(tns->coef_idx[i][filt], + tns->order[i][filt], c_bits); + put_bits(&s->pb, 1, coef_compress); + coef_len = c_bits + 3 - coef_compress; + for (w = 0; w < tns->order[i][filt]; w++) + put_bits(&s->pb, coef_len, tns->coef_idx[i][filt][w]); + } + } +} + +/* Apply TNS filter */ +void ff_aac_apply_tns(AACEncContext *s, SingleChannelElement *sce) +{ + TemporalNoiseShaping *tns = &sce->tns; + IndividualChannelStream *ics = &sce->ics; + int w, filt, m, i, top, order, bottom, start, end, size, inc; + const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb); + float lpc[TNS_MAX_ORDER]; + + for (w = 0; w < ics->num_windows; w++) { + bottom = ics->num_swb; + for (filt = 0; filt < tns->n_filt[w]; filt++) { + top = bottom; + bottom = FFMAX(0, top - tns->length[w][filt]); + order = tns->order[w][filt]; + if (order == 0) + continue; + + // tns_decode_coef + compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0); + + start = ics->swb_offset[FFMIN(bottom, mmm)]; + end = ics->swb_offset[FFMIN( top, mmm)]; + if ((size = end - start) <= 0) + continue; + if (tns->direction[w][filt]) { + inc = -1; + start = end - 1; + } else { + inc = 1; + } + start += w * 128; + + /* AR filter */ + for (m = 0; m < size; m++, start += inc) { + for (i = 1; i <= FFMIN(m, order); i++) { + sce->coeffs[start] += lpc[i-1]*sce->pcoeffs[start - i*inc]; + } + } + } + } +} + +/* + * c_bits - 1 if 4 bit coefficients, 0 if 3 bit coefficients + */ +static inline void quantize_coefs(double *coef, int *idx, float *lpc, int order, + int c_bits) +{ + int i; + const float *quant_arr = tns_tmp2_map[c_bits]; + for (i = 0; i < order; i++) { + idx[i] = quant_array_idx(coef[i], quant_arr, c_bits ? 16 : 8); + lpc[i] = quant_arr[idx[i]]; + } +} + +/* + * 3 bits per coefficient with 8 short windows + */ +void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce) +{ + TemporalNoiseShaping *tns = &sce->tns; + int w, g, count = 0; + double gain, coefs[MAX_LPC_ORDER]; + const int mmm = FFMIN(sce->ics.tns_max_bands, sce->ics.max_sfb); + const int is8 = sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE; + const int c_bits = is8 ? TNS_Q_BITS_IS8 == 4 : TNS_Q_BITS == 4; + const int sfb_start = av_clip(tns_min_sfb[is8][s->samplerate_index], 0, mmm); + const int sfb_end = av_clip(sce->ics.num_swb, 0, mmm); + const int order = is8 ? 7 : s->profile == FF_PROFILE_AAC_LOW ? 12 : TNS_MAX_ORDER; + const int slant = sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE ? 1 : + sce->ics.window_sequence[0] == LONG_START_SEQUENCE ? 0 : 2; + const int sfb_len = sfb_end - sfb_start; + const int coef_len = sce->ics.swb_offset[sfb_end] - sce->ics.swb_offset[sfb_start]; + + if (coef_len <= 0 || sfb_len <= 0) { + sce->tns.present = 0; + return; + } + + for (w = 0; w < sce->ics.num_windows; w++) { + float en[2] = {0.0f, 0.0f}; + int oc_start = 0, os_start = 0; + int coef_start = sce->ics.swb_offset[sfb_start]; + + for (g = sfb_start; g < sce->ics.num_swb && g <= sfb_end; g++) { + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[w*16+g]; + if (g > sfb_start + (sfb_len/2)) + en[1] += band->energy; + else + en[0] += band->energy; + } + + /* LPC */ + gain = ff_lpc_calc_ref_coefs_f(&s->lpc, &sce->coeffs[w*128 + coef_start], + coef_len, order, coefs); + + if (!order || !isfinite(gain) || gain < TNS_GAIN_THRESHOLD_LOW || gain > TNS_GAIN_THRESHOLD_HIGH) + continue; + + tns->n_filt[w] = is8 ? 1 : order != TNS_MAX_ORDER ? 2 : 3; + for (g = 0; g < tns->n_filt[w]; g++) { + tns->direction[w][g] = slant != 2 ? slant : en[g] < en[!g]; + tns->order[w][g] = g < tns->n_filt[w] ? order/tns->n_filt[w] : order - oc_start; + tns->length[w][g] = g < tns->n_filt[w] ? sfb_len/tns->n_filt[w] : sfb_len - os_start; + quantize_coefs(&coefs[oc_start], tns->coef_idx[w][g], tns->coef[w][g], + tns->order[w][g], c_bits); + oc_start += tns->order[w][g]; + os_start += tns->length[w][g]; + } + count++; + } + sce->tns.present = !!count; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_tns.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_tns.h new file mode 100644 index 000000000..466738dd1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_tns.h @@ -0,0 +1,37 @@ +/* + * AAC encoder TNS + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder temporal noise shaping + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#ifndef AVCODEC_AACENC_TNS_H +#define AVCODEC_AACENC_TNS_H + +#include "aacenc.h" + +void ff_aac_encode_tns_info(AACEncContext *s, SingleChannelElement *sce); +void ff_aac_apply_tns(AACEncContext *s, SingleChannelElement *sce); +void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce); + +#endif /* AVCODEC_AACENC_TNS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_utils.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_utils.h new file mode 100644 index 000000000..bef4c103f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenc_utils.h @@ -0,0 +1,279 @@ +/* + * AAC encoder utilities + * Copyright (C) 2015 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder utilities + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#ifndef AVCODEC_AACENC_UTILS_H +#define AVCODEC_AACENC_UTILS_H + +#include "libavutil/ffmath.h" +#include "aac.h" +#include "aacenctab.h" +#include "aactab.h" + +#define ROUND_STANDARD 0.4054f +#define ROUND_TO_ZERO 0.1054f +#define C_QUANT 0.4054f + +static inline void abs_pow34_v(float *out, const float *in, const int size) +{ + int i; + for (i = 0; i < size; i++) { + float a = fabsf(in[i]); + out[i] = sqrtf(a * sqrtf(a)); + } +} + +static inline float pos_pow34(float a) +{ + return sqrtf(a * sqrtf(a)); +} + +/** + * Quantize one coefficient. + * @return absolute value of the quantized coefficient + * @see 3GPP TS26.403 5.6.2 "Scalefactor determination" + */ +static inline int quant(float coef, const float Q, const float rounding) +{ + float a = coef * Q; + return sqrtf(a * sqrtf(a)) + rounding; +} + +static inline void quantize_bands(int *out, const float *in, const float *scaled, + int size, int is_signed, int maxval, const float Q34, + const float rounding) +{ + int i; + for (i = 0; i < size; i++) { + float qc = scaled[i] * Q34; + int tmp = (int)FFMIN(qc + rounding, (float)maxval); + if (is_signed && in[i] < 0.0f) { + tmp = -tmp; + } + out[i] = tmp; + } +} + +static inline float find_max_val(int group_len, int swb_size, const float *scaled) +{ + float maxval = 0.0f; + int w2, i; + for (w2 = 0; w2 < group_len; w2++) { + for (i = 0; i < swb_size; i++) { + maxval = FFMAX(maxval, scaled[w2*128+i]); + } + } + return maxval; +} + +static inline int find_min_book(float maxval, int sf) +{ + float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - sf + SCALE_ONE_POS - SCALE_DIV_512]; + int qmaxval, cb; + qmaxval = maxval * Q34 + C_QUANT; + if (qmaxval >= (FF_ARRAY_ELEMS(aac_maxval_cb))) + cb = 11; + else + cb = aac_maxval_cb[qmaxval]; + return cb; +} + +static inline float find_form_factor(int group_len, int swb_size, float thresh, + const float *scaled, float nzslope) { + const float iswb_size = 1.0f / swb_size; + const float iswb_sizem1 = 1.0f / (swb_size - 1); + const float ethresh = thresh; + float form = 0.0f, weight = 0.0f; + int w2, i; + for (w2 = 0; w2 < group_len; w2++) { + float e = 0.0f, e2 = 0.0f, var = 0.0f, maxval = 0.0f; + float nzl = 0; + for (i = 0; i < swb_size; i++) { + float s = fabsf(scaled[w2*128+i]); + maxval = FFMAX(maxval, s); + e += s; + e2 += s *= s; + /* We really don't want a hard non-zero-line count, since + * even below-threshold lines do add up towards band spectral power. + * So, fall steeply towards zero, but smoothly + */ + if (s >= ethresh) { + nzl += 1.0f; + } else { + if (nzslope == 2.f) + nzl += (s / ethresh) * (s / ethresh); + else + nzl += ff_fast_powf(s / ethresh, nzslope); + } + } + if (e2 > thresh) { + float frm; + e *= iswb_size; + + /** compute variance */ + for (i = 0; i < swb_size; i++) { + float d = fabsf(scaled[w2*128+i]) - e; + var += d*d; + } + var = sqrtf(var * iswb_sizem1); + + e2 *= iswb_size; + frm = e / FFMIN(e+4*var,maxval); + form += e2 * sqrtf(frm) / FFMAX(0.5f,nzl); + weight += e2; + } + } + if (weight > 0) { + return form / weight; + } else { + return 1.0f; + } +} + +/** Return the minimum scalefactor where the quantized coef does not clip. */ +static inline uint8_t coef2minsf(float coef) +{ + return av_clip_uint8(log2f(coef)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512); +} + +/** Return the maximum scalefactor where the quantized coef is not zero. */ +static inline uint8_t coef2maxsf(float coef) +{ + return av_clip_uint8(log2f(coef)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512); +} + +/* + * Returns the closest possible index to an array of float values, given a value. + */ +static inline int quant_array_idx(const float val, const float *arr, const int num) +{ + int i, index = 0; + float quant_min_err = INFINITY; + for (i = 0; i < num; i++) { + float error = (val - arr[i])*(val - arr[i]); + if (error < quant_min_err) { + quant_min_err = error; + index = i; + } + } + return index; +} + +/** + * approximates exp10f(-3.0f*(0.5f + 0.5f * cosf(FFMIN(b,15.5f) / 15.5f))) + */ +static av_always_inline float bval2bmax(float b) +{ + return 0.001f + 0.0035f * (b*b*b) / (15.5f*15.5f*15.5f); +} + +/* + * Compute a nextband map to be used with SF delta constraint utilities. + * The nextband array should contain 128 elements, and positions that don't + * map to valid, nonzero bands of the form w*16+g (with w being the initial + * window of the window group, only) are left indetermined. + */ +static inline void ff_init_nextband_map(const SingleChannelElement *sce, uint8_t *nextband) +{ + unsigned char prevband = 0; + int w, g; + /** Just a safe default */ + for (g = 0; g < 128; g++) + nextband[g] = g; + + /** Now really navigate the nonzero band chain */ + for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { + for (g = 0; g < sce->ics.num_swb; g++) { + if (!sce->zeroes[w*16+g] && sce->band_type[w*16+g] < RESERVED_BT) + prevband = nextband[prevband] = w*16+g; + } + } + nextband[prevband] = prevband; /* terminate */ +} + +/* + * Updates nextband to reflect a removed band (equivalent to + * calling ff_init_nextband_map after marking a band as zero) + */ +static inline void ff_nextband_remove(uint8_t *nextband, int prevband, int band) +{ + nextband[prevband] = nextband[band]; +} + +/* + * Checks whether the specified band could be removed without inducing + * scalefactor delta that violates SF delta encoding constraints. + * prev_sf has to be the scalefactor of the previous nonzero, nonspecial + * band, in encoding order, or negative if there was no such band. + */ +static inline int ff_sfdelta_can_remove_band(const SingleChannelElement *sce, + const uint8_t *nextband, int prev_sf, int band) +{ + return prev_sf >= 0 + && sce->sf_idx[nextband[band]] >= (prev_sf - SCALE_MAX_DIFF) + && sce->sf_idx[nextband[band]] <= (prev_sf + SCALE_MAX_DIFF); +} + +/* + * Checks whether the specified band's scalefactor could be replaced + * with another one without violating SF delta encoding constraints. + * prev_sf has to be the scalefactor of the previous nonzero, nonsepcial + * band, in encoding order, or negative if there was no such band. + */ +static inline int ff_sfdelta_can_replace(const SingleChannelElement *sce, + const uint8_t *nextband, int prev_sf, int new_sf, int band) +{ + return new_sf >= (prev_sf - SCALE_MAX_DIFF) + && new_sf <= (prev_sf + SCALE_MAX_DIFF) + && sce->sf_idx[nextband[band]] >= (new_sf - SCALE_MAX_DIFF) + && sce->sf_idx[nextband[band]] <= (new_sf + SCALE_MAX_DIFF); +} + +/** + * linear congruential pseudorandom number generator + * + * @param previous_val pointer to the current state of the generator + * + * @return Returns a 32-bit pseudorandom integer + */ +static av_always_inline int lcg_random(unsigned previous_val) +{ + union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 }; + return v.s; +} + +#define ERROR_IF(cond, ...) \ + if (cond) { \ + av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \ + return AVERROR(EINVAL); \ + } + +#define WARN_IF(cond, ...) \ + if (cond) { \ + av_log(avctx, AV_LOG_WARNING, __VA_ARGS__); \ + } + +#endif /* AVCODEC_AACENC_UTILS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacencdsp.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacencdsp.asm new file mode 100644 index 000000000..97af571ec --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacencdsp.asm @@ -0,0 +1,86 @@ +;****************************************************************************** +;* SIMD optimized AAC encoder DSP functions +;* +;* Copyright (C) 2016 Rostislav Pehlivanov +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA + +float_abs_mask: times 4 dd 0x7fffffff + +SECTION .text + +;******************************************************************* +;void ff_abs_pow34(float *out, const float *in, const int size); +;******************************************************************* +INIT_XMM sse +cglobal abs_pow34, 3, 3, 3, out, in, size + mova m2, [float_abs_mask] + shl sizeq, 2 + add inq, sizeq + add outq, sizeq + neg sizeq +.loop: + andps m0, m2, [inq+sizeq] + sqrtps m1, m0 + mulps m0, m1 + sqrtps m0, m0 + mova [outq+sizeq], m0 + add sizeq, mmsize + jl .loop + RET + +;******************************************************************* +;void ff_aac_quantize_bands(int *out, const float *in, const float *scaled, +; int size, int is_signed, int maxval, const float Q34, +; const float rounding) +;******************************************************************* +INIT_XMM sse2 +cglobal aac_quantize_bands, 5, 5, 6, out, in, scaled, size, is_signed, maxval, Q34, rounding +%if UNIX64 == 0 + movss m0, Q34m + movss m1, roundingm + cvtsi2ss m3, dword maxvalm +%else + cvtsi2ss m3, maxvald +%endif + shufps m0, m0, 0 + shufps m1, m1, 0 + shufps m3, m3, 0 + shl is_signedd, 31 + movd m4, is_signedd + shufps m4, m4, 0 + shl sized, 2 + add inq, sizeq + add outq, sizeq + add scaledq, sizeq + neg sizeq +.loop: + mulps m2, m0, [scaledq+sizeq] + addps m2, m1 + minps m2, m3 + andps m5, m4, [inq+sizeq] + orps m2, m5 + cvttps2dq m2, m2 + mova [outq+sizeq], m2 + add sizeq, mmsize + jl .loop + RET diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacencdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacencdsp_init.c new file mode 100644 index 000000000..d761c3c5e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacencdsp_init.c @@ -0,0 +1,43 @@ +/* + * AAC encoder assembly optimizations + * Copyright (C) 2016 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/float_dsp.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/aacenc.h" + +void ff_abs_pow34_sse(float *out, const float *in, const int size); + +void ff_aac_quantize_bands_sse2(int *out, const float *in, const float *scaled, + int size, int is_signed, int maxval, const float Q34, + const float rounding); + +av_cold void ff_aac_dsp_init_x86(AACEncContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) + s->abs_pow34 = ff_abs_pow34_sse; + + if (EXTERNAL_SSE2(cpu_flags)) + s->quant_bands = ff_aac_quantize_bands_sse2; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenctab.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenctab.c new file mode 100644 index 000000000..f3d70fbe3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenctab.c @@ -0,0 +1,108 @@ +/* + * AAC encoder data + * Copyright (c) 2015 Rostislav Pehlivanov ( atomnuker gmail com ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "aacenctab.h" + +static const uint8_t swb_size_128_96[] = { + 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 +}; + +static const uint8_t swb_size_128_64[] = { + 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 +}; + +static const uint8_t swb_size_128_48[] = { + 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 +}; + +static const uint8_t swb_size_128_24[] = { + 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20 +}; + +static const uint8_t swb_size_128_16[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 +}; + +static const uint8_t swb_size_128_8[] = { + 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20 +}; + +static const uint8_t swb_size_1024_96[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + +static const uint8_t swb_size_1024_64[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, + 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 +}; + +static const uint8_t swb_size_1024_48[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 96 +}; + +static const uint8_t swb_size_1024_32[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 +}; + +static const uint8_t swb_size_1024_24[] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28, + 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64 +}; + +static const uint8_t swb_size_1024_16[] = { + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, + 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64 +}; + +static const uint8_t swb_size_1024_8[] = { + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 16, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, 28, + 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80 +}; + +const uint8_t *ff_aac_swb_size_128[] = { + swb_size_128_96, swb_size_128_96, swb_size_128_64, + swb_size_128_48, swb_size_128_48, swb_size_128_48, + swb_size_128_24, swb_size_128_24, swb_size_128_16, + swb_size_128_16, swb_size_128_16, swb_size_128_8, + swb_size_128_8 +}; + +const uint8_t *ff_aac_swb_size_1024[] = { + swb_size_1024_96, swb_size_1024_96, swb_size_1024_64, + swb_size_1024_48, swb_size_1024_48, swb_size_1024_32, + swb_size_1024_24, swb_size_1024_24, swb_size_1024_16, + swb_size_1024_16, swb_size_1024_16, swb_size_1024_8, + swb_size_1024_8 +}; + +const int ff_aac_swb_size_128_len = FF_ARRAY_ELEMS(ff_aac_swb_size_128); +const int ff_aac_swb_size_1024_len = FF_ARRAY_ELEMS(ff_aac_swb_size_1024); diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenctab.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenctab.h new file mode 100644 index 000000000..64932d709 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacenctab.h @@ -0,0 +1,139 @@ +/* + * AAC encoder data + * Copyright (c) 2015 Rostislav Pehlivanov ( atomnuker gmail com ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder data + * @author Rostislav Pehlivanov ( atomnuker gmail com ) + */ + +#ifndef AVCODEC_AACENCTAB_H +#define AVCODEC_AACENCTAB_H + +#include "aac.h" + +/** Total number of usable codebooks **/ +#define CB_TOT 12 + +/** Total number of codebooks, including special ones **/ +#define CB_TOT_ALL 15 + +#define AAC_MAX_CHANNELS 16 + +extern const uint8_t *ff_aac_swb_size_1024[]; +extern const int ff_aac_swb_size_1024_len; +extern const uint8_t *ff_aac_swb_size_128[]; +extern const int ff_aac_swb_size_128_len; + +/* Supported layouts without using a PCE */ +static const int64_t aac_normal_chan_layouts[7] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_7POINT1, +}; + +/** default channel configurations */ +static const uint8_t aac_chan_configs[AAC_MAX_CHANNELS][6] = { + {1, TYPE_SCE}, // 1 channel - single channel element + {1, TYPE_CPE}, // 2 channels - channel pair + {2, TYPE_SCE, TYPE_CPE}, // 3 channels - center + stereo + {3, TYPE_SCE, TYPE_CPE, TYPE_SCE}, // 4 channels - front center + stereo + back center + {3, TYPE_SCE, TYPE_CPE, TYPE_CPE}, // 5 channels - front center + stereo + back stereo + {4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE + {0}, // 7 channels - invalid without PCE + {5, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 8 channels - front center + front stereo + side stereo + back stereo + LFE +}; + +/** + * Table to remap channels from libavcodec's default order to AAC order. + */ +static const uint8_t aac_chan_maps[AAC_MAX_CHANNELS][AAC_MAX_CHANNELS] = { + { 0 }, + { 0, 1 }, + { 2, 0, 1 }, + { 2, 0, 1, 3 }, + { 2, 0, 1, 3, 4 }, + { 2, 0, 1, 4, 5, 3 }, + { 0 }, + { 2, 0, 1, 6, 7, 4, 5, 3 }, +}; + +/* duplicated from avpriv_mpeg4audio_sample_rates to avoid shared build + * failures */ +static const int mpeg4audio_sample_rates[16] = { + 96000, 88200, 64000, 48000, 44100, 32000, + 24000, 22050, 16000, 12000, 11025, 8000, 7350 +}; + +/** bits needed to code codebook run value for long windows */ +static const uint8_t run_value_bits_long[64] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15 +}; + +/** bits needed to code codebook run value for short windows */ +static const uint8_t run_value_bits_short[16] = { + 3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9 +}; + +/* TNS starting SFBs for long and short windows */ +static const uint8_t tns_min_sfb_short[16] = { + 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12, 12, 12, 12, 12 +}; + +static const uint8_t tns_min_sfb_long[16] = { + 12, 13, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31, 31, 31, 31, 31 +}; + +static const uint8_t * const tns_min_sfb[2] = { + tns_min_sfb_long, tns_min_sfb_short +}; + +static const uint8_t * const run_value_bits[2] = { + run_value_bits_long, run_value_bits_short +}; + +/** Map to convert values from BandCodingPath index to a codebook index **/ +static const uint8_t aac_cb_out_map[CB_TOT_ALL] = {0,1,2,3,4,5,6,7,8,9,10,11,13,14,15}; +/** Inverse map to convert from codebooks to BandCodingPath indices **/ +static const uint8_t aac_cb_in_map[CB_TOT_ALL+1] = {0,1,2,3,4,5,6,7,8,9,10,11,0,12,13,14}; + +static const uint8_t aac_cb_range [12] = {0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17}; +static const uint8_t aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16}; + +static const unsigned char aac_maxval_cb[] = { + 0, 1, 3, 5, 5, 7, 7, 7, 9, 9, 9, 9, 9, 11 +}; + +static const int aacenc_profiles[] = { + FF_PROFILE_AAC_MAIN, + FF_PROFILE_AAC_LOW, + FF_PROFILE_AAC_LTP, + FF_PROFILE_MPEG2_AAC_LOW, +}; + +#endif /* AVCODEC_AACENCTAB_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps.c new file mode 100644 index 000000000..d5dca64b0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps.c @@ -0,0 +1,1046 @@ +/* + * MPEG-4 Parametric Stereo decoding functions + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Note: Rounding-to-nearest used unless otherwise stated + * + */ + +#include +#include "libavutil/common.h" +#include "libavutil/mathematics.h" +#include "avcodec.h" +#include "get_bits.h" +#include "aacps.h" +#if USE_FIXED +#include "aacps_fixed_tablegen.h" +#else +#include "libavutil/internal.h" +#include "aacps_tablegen.h" +#endif /* USE_FIXED */ +#include "aacpsdata.c" + +#define PS_BASELINE 0 ///< Operate in Baseline PS mode + ///< Baseline implies 10 or 20 stereo bands, + ///< mixing mode A, and no ipd/opd + +#define numQMFSlots 32 //numTimeSlots * RATE + +static const int8_t num_env_tab[2][4] = { + { 0, 1, 2, 4, }, + { 1, 2, 3, 4, }, +}; + +static const int8_t nr_iidicc_par_tab[] = { + 10, 20, 34, 10, 20, 34, +}; + +static const int8_t nr_iidopd_par_tab[] = { + 5, 11, 17, 5, 11, 17, +}; + +enum { + huff_iid_df1, + huff_iid_dt1, + huff_iid_df0, + huff_iid_dt0, + huff_icc_df, + huff_icc_dt, + huff_ipd_df, + huff_ipd_dt, + huff_opd_df, + huff_opd_dt, +}; + +static const int huff_iid[] = { + huff_iid_df0, + huff_iid_df1, + huff_iid_dt0, + huff_iid_dt1, +}; + +static VLC vlc_ps[10]; + +#define READ_PAR_DATA(PAR, OFFSET, MASK, ERR_CONDITION) \ +/** \ + * Read Inter-channel Intensity Difference/Inter-Channel Coherence/ \ + * Inter-channel Phase Difference/Overall Phase Difference parameters from the \ + * bitstream. \ + * \ + * @param avctx contains the current codec context \ + * @param gb pointer to the input bitstream \ + * @param ps pointer to the Parametric Stereo context \ + * @param PAR pointer to the parameter to be read \ + * @param e envelope to decode \ + * @param dt 1: time delta-coded, 0: frequency delta-coded \ + */ \ +static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, \ + int8_t (*PAR)[PS_MAX_NR_IIDICC], int table_idx, int e, int dt) \ +{ \ + int b, num = ps->nr_ ## PAR ## _par; \ + VLC_TYPE (*vlc_table)[2] = vlc_ps[table_idx].table; \ + if (dt) { \ + int e_prev = e ? e - 1 : ps->num_env_old - 1; \ + e_prev = FFMAX(e_prev, 0); \ + for (b = 0; b < num; b++) { \ + int val = PAR[e_prev][b] + get_vlc2(gb, vlc_table, 9, 3) - OFFSET; \ + if (MASK) val &= MASK; \ + PAR[e][b] = val; \ + if (ERR_CONDITION) \ + goto err; \ + } \ + } else { \ + int val = 0; \ + for (b = 0; b < num; b++) { \ + val += get_vlc2(gb, vlc_table, 9, 3) - OFFSET; \ + if (MASK) val &= MASK; \ + PAR[e][b] = val; \ + if (ERR_CONDITION) \ + goto err; \ + } \ + } \ + return 0; \ +err: \ + av_log(avctx, AV_LOG_ERROR, "illegal "#PAR"\n"); \ + return AVERROR_INVALIDDATA; \ +} + +READ_PAR_DATA(iid, huff_offset[table_idx], 0, FFABS(ps->iid_par[e][b]) > 7 + 8 * ps->iid_quant) +READ_PAR_DATA(icc, huff_offset[table_idx], 0, ps->icc_par[e][b] > 7U) +READ_PAR_DATA(ipdopd, 0, 0x07, 0) + +static int ps_read_extension_data(GetBitContext *gb, PSContext *ps, int ps_extension_id) +{ + int e; + int count = get_bits_count(gb); + + if (ps_extension_id) + return 0; + + ps->enable_ipdopd = get_bits1(gb); + if (ps->enable_ipdopd) { + for (e = 0; e < ps->num_env; e++) { + int dt = get_bits1(gb); + read_ipdopd_data(NULL, gb, ps, ps->ipd_par, dt ? huff_ipd_dt : huff_ipd_df, e, dt); + dt = get_bits1(gb); + read_ipdopd_data(NULL, gb, ps, ps->opd_par, dt ? huff_opd_dt : huff_opd_df, e, dt); + } + } + skip_bits1(gb); //reserved_ps + return get_bits_count(gb) - count; +} + +static void ipdopd_reset(int8_t *ipd_hist, int8_t *opd_hist) +{ + int i; + for (i = 0; i < PS_MAX_NR_IPDOPD; i++) { + opd_hist[i] = 0; + ipd_hist[i] = 0; + } +} + +int AAC_RENAME(ff_ps_read_data)(AVCodecContext *avctx, GetBitContext *gb_host, PSContext *ps, int bits_left) +{ + int e; + int bit_count_start = get_bits_count(gb_host); + int header; + int bits_consumed; + GetBitContext gbc = *gb_host, *gb = &gbc; + + header = get_bits1(gb); + if (header) { //enable_ps_header + ps->enable_iid = get_bits1(gb); + if (ps->enable_iid) { + int iid_mode = get_bits(gb, 3); + if (iid_mode > 5) { + av_log(avctx, AV_LOG_ERROR, "iid_mode %d is reserved.\n", + iid_mode); + goto err; + } + ps->nr_iid_par = nr_iidicc_par_tab[iid_mode]; + ps->iid_quant = iid_mode > 2; + ps->nr_ipdopd_par = nr_iidopd_par_tab[iid_mode]; + } + ps->enable_icc = get_bits1(gb); + if (ps->enable_icc) { + ps->icc_mode = get_bits(gb, 3); + if (ps->icc_mode > 5) { + av_log(avctx, AV_LOG_ERROR, "icc_mode %d is reserved.\n", + ps->icc_mode); + goto err; + } + ps->nr_icc_par = nr_iidicc_par_tab[ps->icc_mode]; + } + ps->enable_ext = get_bits1(gb); + } + + ps->frame_class = get_bits1(gb); + ps->num_env_old = ps->num_env; + ps->num_env = num_env_tab[ps->frame_class][get_bits(gb, 2)]; + + ps->border_position[0] = -1; + if (ps->frame_class) { + for (e = 1; e <= ps->num_env; e++) { + ps->border_position[e] = get_bits(gb, 5); + if (ps->border_position[e] < ps->border_position[e-1]) { + av_log(avctx, AV_LOG_ERROR, "border_position non monotone.\n"); + goto err; + } + } + } else + for (e = 1; e <= ps->num_env; e++) + ps->border_position[e] = (e * numQMFSlots >> ff_log2_tab[ps->num_env]) - 1; + + if (ps->enable_iid) { + for (e = 0; e < ps->num_env; e++) { + int dt = get_bits1(gb); + if (read_iid_data(avctx, gb, ps, ps->iid_par, huff_iid[2*dt+ps->iid_quant], e, dt)) + goto err; + } + } else + memset(ps->iid_par, 0, sizeof(ps->iid_par)); + + if (ps->enable_icc) + for (e = 0; e < ps->num_env; e++) { + int dt = get_bits1(gb); + if (read_icc_data(avctx, gb, ps, ps->icc_par, dt ? huff_icc_dt : huff_icc_df, e, dt)) + goto err; + } + else + memset(ps->icc_par, 0, sizeof(ps->icc_par)); + + if (ps->enable_ext) { + int cnt = get_bits(gb, 4); + if (cnt == 15) { + cnt += get_bits(gb, 8); + } + cnt *= 8; + while (cnt > 7) { + int ps_extension_id = get_bits(gb, 2); + cnt -= 2 + ps_read_extension_data(gb, ps, ps_extension_id); + } + if (cnt < 0) { + av_log(avctx, AV_LOG_ERROR, "ps extension overflow %d\n", cnt); + goto err; + } + skip_bits(gb, cnt); + } + + ps->enable_ipdopd &= !PS_BASELINE; + + //Fix up envelopes + if (!ps->num_env || ps->border_position[ps->num_env] < numQMFSlots - 1) { + //Create a fake envelope + int source = ps->num_env ? ps->num_env - 1 : ps->num_env_old - 1; + int b; + if (source >= 0 && source != ps->num_env) { + if (ps->enable_iid) { + memcpy(ps->iid_par+ps->num_env, ps->iid_par+source, sizeof(ps->iid_par[0])); + } + if (ps->enable_icc) { + memcpy(ps->icc_par+ps->num_env, ps->icc_par+source, sizeof(ps->icc_par[0])); + } + if (ps->enable_ipdopd) { + memcpy(ps->ipd_par+ps->num_env, ps->ipd_par+source, sizeof(ps->ipd_par[0])); + memcpy(ps->opd_par+ps->num_env, ps->opd_par+source, sizeof(ps->opd_par[0])); + } + } + if (ps->enable_iid){ + for (b = 0; b < ps->nr_iid_par; b++) { + if (FFABS(ps->iid_par[ps->num_env][b]) > 7 + 8 * ps->iid_quant) { + av_log(avctx, AV_LOG_ERROR, "iid_par invalid\n"); + goto err; + } + } + } + if (ps->enable_icc){ + for (b = 0; b < ps->nr_iid_par; b++) { + if (ps->icc_par[ps->num_env][b] > 7U) { + av_log(avctx, AV_LOG_ERROR, "icc_par invalid\n"); + goto err; + } + } + } + ps->num_env++; + ps->border_position[ps->num_env] = numQMFSlots - 1; + } + + + ps->is34bands_old = ps->is34bands; + if (!PS_BASELINE && (ps->enable_iid || ps->enable_icc)) + ps->is34bands = (ps->enable_iid && ps->nr_iid_par == 34) || + (ps->enable_icc && ps->nr_icc_par == 34); + + //Baseline + if (!ps->enable_ipdopd) { + memset(ps->ipd_par, 0, sizeof(ps->ipd_par)); + memset(ps->opd_par, 0, sizeof(ps->opd_par)); + } + + if (header) + ps->start = 1; + + bits_consumed = get_bits_count(gb) - bit_count_start; + if (bits_consumed <= bits_left) { + skip_bits_long(gb_host, bits_consumed); + return bits_consumed; + } + av_log(avctx, AV_LOG_ERROR, "Expected to read %d PS bits actually read %d.\n", bits_left, bits_consumed); +err: + ps->start = 0; + skip_bits_long(gb_host, bits_left); + memset(ps->iid_par, 0, sizeof(ps->iid_par)); + memset(ps->icc_par, 0, sizeof(ps->icc_par)); + memset(ps->ipd_par, 0, sizeof(ps->ipd_par)); + memset(ps->opd_par, 0, sizeof(ps->opd_par)); + return bits_left; +} + +/** Split one subband into 2 subsubbands with a symmetric real filter. + * The filter must have its non-center even coefficients equal to zero. */ +static void hybrid2_re(INTFLOAT (*in)[2], INTFLOAT (*out)[32][2], const INTFLOAT filter[8], int len, int reverse) +{ + int i, j; + for (i = 0; i < len; i++, in++) { + INT64FLOAT re_in = AAC_MUL31(filter[6], in[6][0]); //real inphase + INT64FLOAT re_op = 0.0f; //real out of phase + INT64FLOAT im_in = AAC_MUL31(filter[6], in[6][1]); //imag inphase + INT64FLOAT im_op = 0.0f; //imag out of phase + for (j = 0; j < 6; j += 2) { + re_op += (INT64FLOAT)filter[j+1] * (in[j+1][0] + in[12-j-1][0]); + im_op += (INT64FLOAT)filter[j+1] * (in[j+1][1] + in[12-j-1][1]); + } + +#if USE_FIXED + re_op = (re_op + 0x40000000) >> 31; + im_op = (im_op + 0x40000000) >> 31; +#endif /* USE_FIXED */ + + out[ reverse][i][0] = (INTFLOAT)(re_in + re_op); + out[ reverse][i][1] = (INTFLOAT)(im_in + im_op); + out[!reverse][i][0] = (INTFLOAT)(re_in - re_op); + out[!reverse][i][1] = (INTFLOAT)(im_in - im_op); + } +} + +/** Split one subband into 6 subsubbands with a complex filter */ +static void hybrid6_cx(PSDSPContext *dsp, INTFLOAT (*in)[2], INTFLOAT (*out)[32][2], + TABLE_CONST INTFLOAT (*filter)[8][2], int len) +{ + int i; + int N = 8; + LOCAL_ALIGNED_16(INTFLOAT, temp, [8], [2]); + + for (i = 0; i < len; i++, in++) { + dsp->hybrid_analysis(temp, in, (const INTFLOAT (*)[8][2]) filter, 1, N); + out[0][i][0] = temp[6][0]; + out[0][i][1] = temp[6][1]; + out[1][i][0] = temp[7][0]; + out[1][i][1] = temp[7][1]; + out[2][i][0] = temp[0][0]; + out[2][i][1] = temp[0][1]; + out[3][i][0] = temp[1][0]; + out[3][i][1] = temp[1][1]; + out[4][i][0] = temp[2][0] + temp[5][0]; + out[4][i][1] = temp[2][1] + temp[5][1]; + out[5][i][0] = temp[3][0] + temp[4][0]; + out[5][i][1] = temp[3][1] + temp[4][1]; + } +} + +static void hybrid4_8_12_cx(PSDSPContext *dsp, + INTFLOAT (*in)[2], INTFLOAT (*out)[32][2], + TABLE_CONST INTFLOAT (*filter)[8][2], int N, int len) +{ + int i; + + for (i = 0; i < len; i++, in++) { + dsp->hybrid_analysis(out[0] + i, in, (const INTFLOAT (*)[8][2]) filter, 32, N); + } +} + +static void hybrid_analysis(PSDSPContext *dsp, INTFLOAT out[91][32][2], + INTFLOAT in[5][44][2], INTFLOAT L[2][38][64], + int is34, int len) +{ + int i, j; + for (i = 0; i < 5; i++) { + for (j = 0; j < 38; j++) { + in[i][j+6][0] = L[0][j][i]; + in[i][j+6][1] = L[1][j][i]; + } + } + if (is34) { + hybrid4_8_12_cx(dsp, in[0], out, f34_0_12, 12, len); + hybrid4_8_12_cx(dsp, in[1], out+12, f34_1_8, 8, len); + hybrid4_8_12_cx(dsp, in[2], out+20, f34_2_4, 4, len); + hybrid4_8_12_cx(dsp, in[3], out+24, f34_2_4, 4, len); + hybrid4_8_12_cx(dsp, in[4], out+28, f34_2_4, 4, len); + dsp->hybrid_analysis_ileave(out + 27, L, 5, len); + } else { + hybrid6_cx(dsp, in[0], out, f20_0_8, len); + hybrid2_re(in[1], out+6, g1_Q2, len, 1); + hybrid2_re(in[2], out+8, g1_Q2, len, 0); + dsp->hybrid_analysis_ileave(out + 7, L, 3, len); + } + //update in_buf + for (i = 0; i < 5; i++) { + memcpy(in[i], in[i]+32, 6 * sizeof(in[i][0])); + } +} + +static void hybrid_synthesis(PSDSPContext *dsp, INTFLOAT out[2][38][64], + INTFLOAT in[91][32][2], int is34, int len) +{ + int i, n; + if (is34) { + for (n = 0; n < len; n++) { + memset(out[0][n], 0, 5*sizeof(out[0][n][0])); + memset(out[1][n], 0, 5*sizeof(out[1][n][0])); + for (i = 0; i < 12; i++) { + out[0][n][0] += in[ i][n][0]; + out[1][n][0] += in[ i][n][1]; + } + for (i = 0; i < 8; i++) { + out[0][n][1] += in[12+i][n][0]; + out[1][n][1] += in[12+i][n][1]; + } + for (i = 0; i < 4; i++) { + out[0][n][2] += in[20+i][n][0]; + out[1][n][2] += in[20+i][n][1]; + out[0][n][3] += in[24+i][n][0]; + out[1][n][3] += in[24+i][n][1]; + out[0][n][4] += in[28+i][n][0]; + out[1][n][4] += in[28+i][n][1]; + } + } + dsp->hybrid_synthesis_deint(out, in + 27, 5, len); + } else { + for (n = 0; n < len; n++) { + out[0][n][0] = in[0][n][0] + in[1][n][0] + in[2][n][0] + + in[3][n][0] + in[4][n][0] + in[5][n][0]; + out[1][n][0] = in[0][n][1] + in[1][n][1] + in[2][n][1] + + in[3][n][1] + in[4][n][1] + in[5][n][1]; + out[0][n][1] = in[6][n][0] + in[7][n][0]; + out[1][n][1] = in[6][n][1] + in[7][n][1]; + out[0][n][2] = in[8][n][0] + in[9][n][0]; + out[1][n][2] = in[8][n][1] + in[9][n][1]; + } + dsp->hybrid_synthesis_deint(out, in + 7, 3, len); + } +} + +/// All-pass filter decay slope +#define DECAY_SLOPE Q30(0.05f) +/// Number of frequency bands that can be addressed by the parameter index, b(k) +static const int NR_PAR_BANDS[] = { 20, 34 }; +static const int NR_IPDOPD_BANDS[] = { 11, 17 }; +/// Number of frequency bands that can be addressed by the sub subband index, k +static const int NR_BANDS[] = { 71, 91 }; +/// Start frequency band for the all-pass filter decay slope +static const int DECAY_CUTOFF[] = { 10, 32 }; +/// Number of all-pass filer bands +static const int NR_ALLPASS_BANDS[] = { 30, 50 }; +/// First stereo band using the short one sample delay +static const int SHORT_DELAY_BAND[] = { 42, 62 }; + +/** Table 8.46 */ +static void map_idx_10_to_20(int8_t *par_mapped, const int8_t *par, int full) +{ + int b; + if (full) + b = 9; + else { + b = 4; + par_mapped[10] = 0; + } + for (; b >= 0; b--) { + par_mapped[2*b+1] = par_mapped[2*b] = par[b]; + } +} + +static void map_idx_34_to_20(int8_t *par_mapped, const int8_t *par, int full) +{ + par_mapped[ 0] = (2*par[ 0] + par[ 1]) / 3; + par_mapped[ 1] = ( par[ 1] + 2*par[ 2]) / 3; + par_mapped[ 2] = (2*par[ 3] + par[ 4]) / 3; + par_mapped[ 3] = ( par[ 4] + 2*par[ 5]) / 3; + par_mapped[ 4] = ( par[ 6] + par[ 7]) / 2; + par_mapped[ 5] = ( par[ 8] + par[ 9]) / 2; + par_mapped[ 6] = par[10]; + par_mapped[ 7] = par[11]; + par_mapped[ 8] = ( par[12] + par[13]) / 2; + par_mapped[ 9] = ( par[14] + par[15]) / 2; + par_mapped[10] = par[16]; + if (full) { + par_mapped[11] = par[17]; + par_mapped[12] = par[18]; + par_mapped[13] = par[19]; + par_mapped[14] = ( par[20] + par[21]) / 2; + par_mapped[15] = ( par[22] + par[23]) / 2; + par_mapped[16] = ( par[24] + par[25]) / 2; + par_mapped[17] = ( par[26] + par[27]) / 2; + par_mapped[18] = ( par[28] + par[29] + par[30] + par[31]) / 4; + par_mapped[19] = ( par[32] + par[33]) / 2; + } +} + +static void map_val_34_to_20(INTFLOAT par[PS_MAX_NR_IIDICC]) +{ +#if USE_FIXED + par[ 0] = (int)(((int64_t)(par[ 0] + (unsigned)(par[ 1]>>1)) * 1431655765 + \ + 0x40000000) >> 31); + par[ 1] = (int)(((int64_t)((par[ 1]>>1) + (unsigned)par[ 2]) * 1431655765 + \ + 0x40000000) >> 31); + par[ 2] = (int)(((int64_t)(par[ 3] + (unsigned)(par[ 4]>>1)) * 1431655765 + \ + 0x40000000) >> 31); + par[ 3] = (int)(((int64_t)((par[ 4]>>1) + (unsigned)par[ 5]) * 1431655765 + \ + 0x40000000) >> 31); +#else + par[ 0] = (2*par[ 0] + par[ 1]) * 0.33333333f; + par[ 1] = ( par[ 1] + 2*par[ 2]) * 0.33333333f; + par[ 2] = (2*par[ 3] + par[ 4]) * 0.33333333f; + par[ 3] = ( par[ 4] + 2*par[ 5]) * 0.33333333f; +#endif /* USE_FIXED */ + par[ 4] = AAC_HALF_SUM(par[ 6], par[ 7]); + par[ 5] = AAC_HALF_SUM(par[ 8], par[ 9]); + par[ 6] = par[10]; + par[ 7] = par[11]; + par[ 8] = AAC_HALF_SUM(par[12], par[13]); + par[ 9] = AAC_HALF_SUM(par[14], par[15]); + par[10] = par[16]; + par[11] = par[17]; + par[12] = par[18]; + par[13] = par[19]; + par[14] = AAC_HALF_SUM(par[20], par[21]); + par[15] = AAC_HALF_SUM(par[22], par[23]); + par[16] = AAC_HALF_SUM(par[24], par[25]); + par[17] = AAC_HALF_SUM(par[26], par[27]); +#if USE_FIXED + par[18] = (((par[28]+2)>>2) + ((par[29]+2)>>2) + ((par[30]+2)>>2) + ((par[31]+2)>>2)); +#else + par[18] = ( par[28] + par[29] + par[30] + par[31]) * 0.25f; +#endif /* USE_FIXED */ + par[19] = AAC_HALF_SUM(par[32], par[33]); +} + +static void map_idx_10_to_34(int8_t *par_mapped, const int8_t *par, int full) +{ + if (full) { + par_mapped[33] = par[9]; + par_mapped[32] = par[9]; + par_mapped[31] = par[9]; + par_mapped[30] = par[9]; + par_mapped[29] = par[9]; + par_mapped[28] = par[9]; + par_mapped[27] = par[8]; + par_mapped[26] = par[8]; + par_mapped[25] = par[8]; + par_mapped[24] = par[8]; + par_mapped[23] = par[7]; + par_mapped[22] = par[7]; + par_mapped[21] = par[7]; + par_mapped[20] = par[7]; + par_mapped[19] = par[6]; + par_mapped[18] = par[6]; + par_mapped[17] = par[5]; + par_mapped[16] = par[5]; + } else { + par_mapped[16] = 0; + } + par_mapped[15] = par[4]; + par_mapped[14] = par[4]; + par_mapped[13] = par[4]; + par_mapped[12] = par[4]; + par_mapped[11] = par[3]; + par_mapped[10] = par[3]; + par_mapped[ 9] = par[2]; + par_mapped[ 8] = par[2]; + par_mapped[ 7] = par[2]; + par_mapped[ 6] = par[2]; + par_mapped[ 5] = par[1]; + par_mapped[ 4] = par[1]; + par_mapped[ 3] = par[1]; + par_mapped[ 2] = par[0]; + par_mapped[ 1] = par[0]; + par_mapped[ 0] = par[0]; +} + +static void map_idx_20_to_34(int8_t *par_mapped, const int8_t *par, int full) +{ + if (full) { + par_mapped[33] = par[19]; + par_mapped[32] = par[19]; + par_mapped[31] = par[18]; + par_mapped[30] = par[18]; + par_mapped[29] = par[18]; + par_mapped[28] = par[18]; + par_mapped[27] = par[17]; + par_mapped[26] = par[17]; + par_mapped[25] = par[16]; + par_mapped[24] = par[16]; + par_mapped[23] = par[15]; + par_mapped[22] = par[15]; + par_mapped[21] = par[14]; + par_mapped[20] = par[14]; + par_mapped[19] = par[13]; + par_mapped[18] = par[12]; + par_mapped[17] = par[11]; + } + par_mapped[16] = par[10]; + par_mapped[15] = par[ 9]; + par_mapped[14] = par[ 9]; + par_mapped[13] = par[ 8]; + par_mapped[12] = par[ 8]; + par_mapped[11] = par[ 7]; + par_mapped[10] = par[ 6]; + par_mapped[ 9] = par[ 5]; + par_mapped[ 8] = par[ 5]; + par_mapped[ 7] = par[ 4]; + par_mapped[ 6] = par[ 4]; + par_mapped[ 5] = par[ 3]; + par_mapped[ 4] = (par[ 2] + par[ 3]) / 2; + par_mapped[ 3] = par[ 2]; + par_mapped[ 2] = par[ 1]; + par_mapped[ 1] = (par[ 0] + par[ 1]) / 2; + par_mapped[ 0] = par[ 0]; +} + +static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC]) +{ + par[33] = par[19]; + par[32] = par[19]; + par[31] = par[18]; + par[30] = par[18]; + par[29] = par[18]; + par[28] = par[18]; + par[27] = par[17]; + par[26] = par[17]; + par[25] = par[16]; + par[24] = par[16]; + par[23] = par[15]; + par[22] = par[15]; + par[21] = par[14]; + par[20] = par[14]; + par[19] = par[13]; + par[18] = par[12]; + par[17] = par[11]; + par[16] = par[10]; + par[15] = par[ 9]; + par[14] = par[ 9]; + par[13] = par[ 8]; + par[12] = par[ 8]; + par[11] = par[ 7]; + par[10] = par[ 6]; + par[ 9] = par[ 5]; + par[ 8] = par[ 5]; + par[ 7] = par[ 4]; + par[ 6] = par[ 4]; + par[ 5] = par[ 3]; + par[ 4] = AAC_HALF_SUM(par[ 2], par[ 3]); + par[ 3] = par[ 2]; + par[ 2] = par[ 1]; + par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]); +} + +static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34) +{ + LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]); + LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]); + INTFLOAT *peak_decay_nrg = ps->peak_decay_nrg; + INTFLOAT *power_smooth = ps->power_smooth; + INTFLOAT *peak_decay_diff_smooth = ps->peak_decay_diff_smooth; + INTFLOAT (*delay)[PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2] = ps->delay; + INTFLOAT (*ap_delay)[PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2] = ps->ap_delay; +#if !USE_FIXED + const float transient_impact = 1.5f; + const float a_smooth = 0.25f; ///< Smoothing coefficient +#endif /* USE_FIXED */ + const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20; + int i, k, m, n; + int n0 = 0, nL = 32; + const INTFLOAT peak_decay_factor = Q31(0.76592833836465f); + + memset(power, 0, 34 * sizeof(*power)); + + if (is34 != ps->is34bands_old) { + memset(ps->peak_decay_nrg, 0, sizeof(ps->peak_decay_nrg)); + memset(ps->power_smooth, 0, sizeof(ps->power_smooth)); + memset(ps->peak_decay_diff_smooth, 0, sizeof(ps->peak_decay_diff_smooth)); + memset(ps->delay, 0, sizeof(ps->delay)); + memset(ps->ap_delay, 0, sizeof(ps->ap_delay)); + } + + for (k = 0; k < NR_BANDS[is34]; k++) { + int i = k_to_i[k]; + ps->dsp.add_squares(power[i], s[k], nL - n0); + } + + //Transient detection +#if USE_FIXED + for (i = 0; i < NR_PAR_BANDS[is34]; i++) { + for (n = n0; n < nL; n++) { + int decayed_peak; + decayed_peak = (int)(((int64_t)peak_decay_factor * \ + peak_decay_nrg[i] + 0x40000000) >> 31); + peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]); + power_smooth[i] += (power[i][n] + 2LL - power_smooth[i]) >> 2; + peak_decay_diff_smooth[i] += (peak_decay_nrg[i] + 2LL - power[i][n] - \ + peak_decay_diff_smooth[i]) >> 2; + + if (peak_decay_diff_smooth[i]) { + transient_gain[i][n] = FFMIN(power_smooth[i]*43691LL / peak_decay_diff_smooth[i], 1<<16); + } else + transient_gain[i][n] = 1 << 16; + } + } +#else + for (i = 0; i < NR_PAR_BANDS[is34]; i++) { + for (n = n0; n < nL; n++) { + float decayed_peak = peak_decay_factor * peak_decay_nrg[i]; + float denom; + peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]); + power_smooth[i] += a_smooth * (power[i][n] - power_smooth[i]); + peak_decay_diff_smooth[i] += a_smooth * (peak_decay_nrg[i] - power[i][n] - peak_decay_diff_smooth[i]); + denom = transient_impact * peak_decay_diff_smooth[i]; + transient_gain[i][n] = (denom > power_smooth[i]) ? + power_smooth[i] / denom : 1.0f; + } + } + +#endif /* USE_FIXED */ + //Decorrelation and transient reduction + // PS_AP_LINKS - 1 + // ----- + // | | Q_fract_allpass[k][m]*z^-link_delay[m] - a[m]*g_decay_slope[k] + //H[k][z] = z^-2 * phi_fract[k] * | | ---------------------------------------------------------------- + // | | 1 - a[m]*g_decay_slope[k]*Q_fract_allpass[k][m]*z^-link_delay[m] + // m = 0 + //d[k][z] (out) = transient_gain_mapped[k][z] * H[k][z] * s[k][z] + for (k = 0; k < NR_ALLPASS_BANDS[is34]; k++) { + int b = k_to_i[k]; +#if USE_FIXED + int g_decay_slope; + + if (k - DECAY_CUTOFF[is34] <= 0) { + g_decay_slope = 1 << 30; + } + else if (k - DECAY_CUTOFF[is34] >= 20) { + g_decay_slope = 0; + } + else { + g_decay_slope = (1 << 30) - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]); + } +#else + float g_decay_slope = 1.f - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]); + g_decay_slope = av_clipf(g_decay_slope, 0.f, 1.f); +#endif /* USE_FIXED */ + memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0])); + memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0])); + for (m = 0; m < PS_AP_LINKS; m++) { + memcpy(ap_delay[k][m], ap_delay[k][m]+numQMFSlots, 5*sizeof(ap_delay[k][m][0])); + } + ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k], + phi_fract[is34][k], + (const INTFLOAT (*)[2]) Q_fract_allpass[is34][k], + transient_gain[b], g_decay_slope, nL - n0); + } + for (; k < SHORT_DELAY_BAND[is34]; k++) { + int i = k_to_i[k]; + memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0])); + memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0])); + //H = delay 14 + ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 14, + transient_gain[i], nL - n0); + } + for (; k < NR_BANDS[is34]; k++) { + int i = k_to_i[k]; + memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0])); + memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0])); + //H = delay 1 + ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 1, + transient_gain[i], nL - n0); + } +} + +static void remap34(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC], + int8_t (*par)[PS_MAX_NR_IIDICC], + int num_par, int num_env, int full) +{ + int8_t (*par_mapped)[PS_MAX_NR_IIDICC] = *p_par_mapped; + int e; + if (num_par == 20 || num_par == 11) { + for (e = 0; e < num_env; e++) { + map_idx_20_to_34(par_mapped[e], par[e], full); + } + } else if (num_par == 10 || num_par == 5) { + for (e = 0; e < num_env; e++) { + map_idx_10_to_34(par_mapped[e], par[e], full); + } + } else { + *p_par_mapped = par; + } +} + +static void remap20(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC], + int8_t (*par)[PS_MAX_NR_IIDICC], + int num_par, int num_env, int full) +{ + int8_t (*par_mapped)[PS_MAX_NR_IIDICC] = *p_par_mapped; + int e; + if (num_par == 34 || num_par == 17) { + for (e = 0; e < num_env; e++) { + map_idx_34_to_20(par_mapped[e], par[e], full); + } + } else if (num_par == 10 || num_par == 5) { + for (e = 0; e < num_env; e++) { + map_idx_10_to_20(par_mapped[e], par[e], full); + } + } else { + *p_par_mapped = par; + } +} + +static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)[32][2], int is34) +{ + int e, b, k; + + INTFLOAT (*H11)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H11; + INTFLOAT (*H12)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H12; + INTFLOAT (*H21)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H21; + INTFLOAT (*H22)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H22; + int8_t *opd_hist = ps->opd_hist; + int8_t *ipd_hist = ps->ipd_hist; + int8_t iid_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; + int8_t icc_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; + int8_t ipd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; + int8_t opd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; + int8_t (*iid_mapped)[PS_MAX_NR_IIDICC] = iid_mapped_buf; + int8_t (*icc_mapped)[PS_MAX_NR_IIDICC] = icc_mapped_buf; + int8_t (*ipd_mapped)[PS_MAX_NR_IIDICC] = ipd_mapped_buf; + int8_t (*opd_mapped)[PS_MAX_NR_IIDICC] = opd_mapped_buf; + const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20; + TABLE_CONST INTFLOAT (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB; + + //Remapping + if (ps->num_env_old) { + memcpy(H11[0][0], H11[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[0][0][0])); + memcpy(H11[1][0], H11[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[1][0][0])); + memcpy(H12[0][0], H12[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[0][0][0])); + memcpy(H12[1][0], H12[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[1][0][0])); + memcpy(H21[0][0], H21[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[0][0][0])); + memcpy(H21[1][0], H21[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[1][0][0])); + memcpy(H22[0][0], H22[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[0][0][0])); + memcpy(H22[1][0], H22[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[1][0][0])); + } + + if (is34) { + remap34(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1); + remap34(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1); + if (ps->enable_ipdopd) { + remap34(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0); + remap34(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0); + } + if (!ps->is34bands_old) { + map_val_20_to_34(H11[0][0]); + map_val_20_to_34(H11[1][0]); + map_val_20_to_34(H12[0][0]); + map_val_20_to_34(H12[1][0]); + map_val_20_to_34(H21[0][0]); + map_val_20_to_34(H21[1][0]); + map_val_20_to_34(H22[0][0]); + map_val_20_to_34(H22[1][0]); + ipdopd_reset(ipd_hist, opd_hist); + } + } else { + remap20(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1); + remap20(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1); + if (ps->enable_ipdopd) { + remap20(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0); + remap20(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0); + } + if (ps->is34bands_old) { + map_val_34_to_20(H11[0][0]); + map_val_34_to_20(H11[1][0]); + map_val_34_to_20(H12[0][0]); + map_val_34_to_20(H12[1][0]); + map_val_34_to_20(H21[0][0]); + map_val_34_to_20(H21[1][0]); + map_val_34_to_20(H22[0][0]); + map_val_34_to_20(H22[1][0]); + ipdopd_reset(ipd_hist, opd_hist); + } + } + + //Mixing + for (e = 0; e < ps->num_env; e++) { + for (b = 0; b < NR_PAR_BANDS[is34]; b++) { + INTFLOAT h11, h12, h21, h22; + h11 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][0]; + h12 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][1]; + h21 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][2]; + h22 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][3]; + + if (!PS_BASELINE && ps->enable_ipdopd && b < NR_IPDOPD_BANDS[is34]) { + //The spec say says to only run this smoother when enable_ipdopd + //is set but the reference decoder appears to run it constantly + INTFLOAT h11i, h12i, h21i, h22i; + INTFLOAT ipd_adj_re, ipd_adj_im; + int opd_idx = opd_hist[b] * 8 + opd_mapped[e][b]; + int ipd_idx = ipd_hist[b] * 8 + ipd_mapped[e][b]; + INTFLOAT opd_re = pd_re_smooth[opd_idx]; + INTFLOAT opd_im = pd_im_smooth[opd_idx]; + INTFLOAT ipd_re = pd_re_smooth[ipd_idx]; + INTFLOAT ipd_im = pd_im_smooth[ipd_idx]; + opd_hist[b] = opd_idx & 0x3F; + ipd_hist[b] = ipd_idx & 0x3F; + + ipd_adj_re = AAC_MADD30(opd_re, ipd_re, opd_im, ipd_im); + ipd_adj_im = AAC_MSUB30(opd_im, ipd_re, opd_re, ipd_im); + h11i = AAC_MUL30(h11, opd_im); + h11 = AAC_MUL30(h11, opd_re); + h12i = AAC_MUL30(h12, ipd_adj_im); + h12 = AAC_MUL30(h12, ipd_adj_re); + h21i = AAC_MUL30(h21, opd_im); + h21 = AAC_MUL30(h21, opd_re); + h22i = AAC_MUL30(h22, ipd_adj_im); + h22 = AAC_MUL30(h22, ipd_adj_re); + H11[1][e+1][b] = h11i; + H12[1][e+1][b] = h12i; + H21[1][e+1][b] = h21i; + H22[1][e+1][b] = h22i; + } + H11[0][e+1][b] = h11; + H12[0][e+1][b] = h12; + H21[0][e+1][b] = h21; + H22[0][e+1][b] = h22; + } + for (k = 0; k < NR_BANDS[is34]; k++) { + LOCAL_ALIGNED_16(INTFLOAT, h, [2], [4]); + LOCAL_ALIGNED_16(INTFLOAT, h_step, [2], [4]); + int start = ps->border_position[e]; + int stop = ps->border_position[e+1]; + INTFLOAT width = Q30(1.f) / ((stop - start) ? (stop - start) : 1); +#if USE_FIXED + width = FFMIN(2U*width, INT_MAX); +#endif + b = k_to_i[k]; + h[0][0] = H11[0][e][b]; + h[0][1] = H12[0][e][b]; + h[0][2] = H21[0][e][b]; + h[0][3] = H22[0][e][b]; + if (!PS_BASELINE && ps->enable_ipdopd) { + //Is this necessary? ps_04_new seems unchanged + if ((is34 && k <= 13 && k >= 9) || (!is34 && k <= 1)) { + h[1][0] = -H11[1][e][b]; + h[1][1] = -H12[1][e][b]; + h[1][2] = -H21[1][e][b]; + h[1][3] = -H22[1][e][b]; + } else { + h[1][0] = H11[1][e][b]; + h[1][1] = H12[1][e][b]; + h[1][2] = H21[1][e][b]; + h[1][3] = H22[1][e][b]; + } + } + //Interpolation + h_step[0][0] = AAC_MSUB31_V3(H11[0][e+1][b], h[0][0], width); + h_step[0][1] = AAC_MSUB31_V3(H12[0][e+1][b], h[0][1], width); + h_step[0][2] = AAC_MSUB31_V3(H21[0][e+1][b], h[0][2], width); + h_step[0][3] = AAC_MSUB31_V3(H22[0][e+1][b], h[0][3], width); + if (!PS_BASELINE && ps->enable_ipdopd) { + h_step[1][0] = AAC_MSUB31_V3(H11[1][e+1][b], h[1][0], width); + h_step[1][1] = AAC_MSUB31_V3(H12[1][e+1][b], h[1][1], width); + h_step[1][2] = AAC_MSUB31_V3(H21[1][e+1][b], h[1][2], width); + h_step[1][3] = AAC_MSUB31_V3(H22[1][e+1][b], h[1][3], width); + } + if (stop - start) + ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd]( + l[k] + 1 + start, r[k] + 1 + start, + h, h_step, stop - start); + } + } +} + +int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top) +{ + INTFLOAT (*Lbuf)[32][2] = ps->Lbuf; + INTFLOAT (*Rbuf)[32][2] = ps->Rbuf; + const int len = 32; + int is34 = ps->is34bands; + + top += NR_BANDS[is34] - 64; + memset(ps->delay+top, 0, (NR_BANDS[is34] - top)*sizeof(ps->delay[0])); + if (top < NR_ALLPASS_BANDS[is34]) + memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0])); + + hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len); + decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34); + stereo_processing(ps, Lbuf, Rbuf, is34); + hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len); + hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len); + + return 0; +} + +#define PS_INIT_VLC_STATIC(num, size) \ + INIT_VLC_STATIC(&vlc_ps[num], 9, ps_tmp[num].table_size / ps_tmp[num].elem_size, \ + ps_tmp[num].ps_bits, 1, 1, \ + ps_tmp[num].ps_codes, ps_tmp[num].elem_size, ps_tmp[num].elem_size, \ + size); + +#define PS_VLC_ROW(name) \ + { name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) } + +av_cold void AAC_RENAME(ff_ps_init)(void) { + // Syntax initialization + static const struct { + const void *ps_codes, *ps_bits; + const unsigned int table_size, elem_size; + } ps_tmp[] = { + PS_VLC_ROW(huff_iid_df1), + PS_VLC_ROW(huff_iid_dt1), + PS_VLC_ROW(huff_iid_df0), + PS_VLC_ROW(huff_iid_dt0), + PS_VLC_ROW(huff_icc_df), + PS_VLC_ROW(huff_icc_dt), + PS_VLC_ROW(huff_ipd_df), + PS_VLC_ROW(huff_ipd_dt), + PS_VLC_ROW(huff_opd_df), + PS_VLC_ROW(huff_opd_dt), + }; + + PS_INIT_VLC_STATIC(0, 1544); + PS_INIT_VLC_STATIC(1, 832); + PS_INIT_VLC_STATIC(2, 1024); + PS_INIT_VLC_STATIC(3, 1036); + PS_INIT_VLC_STATIC(4, 544); + PS_INIT_VLC_STATIC(5, 544); + PS_INIT_VLC_STATIC(6, 512); + PS_INIT_VLC_STATIC(7, 512); + PS_INIT_VLC_STATIC(8, 512); + PS_INIT_VLC_STATIC(9, 512); + + ps_tableinit(); +} + +av_cold void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps) +{ + AAC_RENAME(ff_psdsp_init)(&ps->dsp); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps.h new file mode 100644 index 000000000..61edce354 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps.h @@ -0,0 +1,86 @@ +/* + * MPEG-4 Parametric Stereo definitions and declarations + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AACPS_H +#define AVCODEC_AACPS_H + +#include + +#include "aacpsdsp.h" +#include "avcodec.h" +#include "get_bits.h" + +#define PS_MAX_NUM_ENV 5 +#define PS_MAX_NR_IIDICC 34 +#define PS_MAX_NR_IPDOPD 17 +#define PS_MAX_SSB 91 +#define PS_MAX_AP_BANDS 50 +#define PS_QMF_TIME_SLOTS 32 +#define PS_MAX_DELAY 14 +#define PS_AP_LINKS 3 +#define PS_MAX_AP_DELAY 5 + +typedef struct PSContext { + int start; + int enable_iid; + int iid_quant; + int nr_iid_par; + int nr_ipdopd_par; + int enable_icc; + int icc_mode; + int nr_icc_par; + int enable_ext; + int frame_class; + int num_env_old; + int num_env; + int enable_ipdopd; + int border_position[PS_MAX_NUM_ENV+1]; + int8_t iid_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Inter-channel Intensity Difference Parameters + int8_t icc_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Inter-Channel Coherence Parameters + /* ipd/opd is iid/icc sized so that the same functions can handle both */ + int8_t ipd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Inter-channel Phase Difference Parameters + int8_t opd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; ///< Overall Phase Difference Parameters + int is34bands; + int is34bands_old; + + DECLARE_ALIGNED(16, INTFLOAT, in_buf)[5][44][2]; + DECLARE_ALIGNED(16, INTFLOAT, delay)[PS_MAX_SSB][PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2]; + DECLARE_ALIGNED(16, INTFLOAT, ap_delay)[PS_MAX_AP_BANDS][PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2]; + DECLARE_ALIGNED(16, INTFLOAT, peak_decay_nrg)[34]; + DECLARE_ALIGNED(16, INTFLOAT, power_smooth)[34]; + DECLARE_ALIGNED(16, INTFLOAT, peak_decay_diff_smooth)[34]; + DECLARE_ALIGNED(16, INTFLOAT, H11)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC]; + DECLARE_ALIGNED(16, INTFLOAT, H12)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC]; + DECLARE_ALIGNED(16, INTFLOAT, H21)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC]; + DECLARE_ALIGNED(16, INTFLOAT, H22)[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC]; + DECLARE_ALIGNED(16, INTFLOAT, Lbuf)[91][32][2]; + DECLARE_ALIGNED(16, INTFLOAT, Rbuf)[91][32][2]; + int8_t opd_hist[PS_MAX_NR_IIDICC]; + int8_t ipd_hist[PS_MAX_NR_IIDICC]; + PSDSPContext dsp; +} PSContext; + +void AAC_RENAME(ff_ps_init)(void); +void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps); +int AAC_RENAME(ff_ps_read_data)(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, int bits_left); +int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top); + +#endif /* AVCODEC_AACPS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed.c new file mode 100644 index 000000000..46af21339 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed.c @@ -0,0 +1,24 @@ +/* + * MPEG-4 Parametric Stereo decoding functions + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 1 + +#include "aacps.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed_tablegen.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed_tablegen.c new file mode 100644 index 000000000..9e306991f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed_tablegen.c @@ -0,0 +1,24 @@ +/* + * Generate a header file for hardcoded Parametric Stereo tables + * + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 1 +#include "aacps_tablegen_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed_tablegen.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed_tablegen.h new file mode 100644 index 000000000..8b82deb59 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_fixed_tablegen.h @@ -0,0 +1,403 @@ +/* + * Header file for hardcoded Parametric Stereo tables + * + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Note: Rounding-to-nearest used unless otherwise stated + * + */ + +#ifndef AVCODEC_AACPS_FIXED_TABLEGEN_H +#define AVCODEC_AACPS_FIXED_TABLEGEN_H + +#include +#include + +#if CONFIG_HARDCODED_TABLES +#define ps_tableinit() +#define TABLE_CONST const +#include "libavcodec/aacps_fixed_tables.h" +#else +#include "libavutil/common.h" +#include "libavutil/mathematics.h" +#include "libavutil/mem.h" + +#include "aac_defines.h" +#include "libavutil/softfloat.h" +#define NR_ALLPASS_BANDS20 30 +#define NR_ALLPASS_BANDS34 50 +#define PS_AP_LINKS 3 +#define TABLE_CONST +static int pd_re_smooth[8*8*8]; +static int pd_im_smooth[8*8*8]; +static int HA[46][8][4]; +static int HB[46][8][4]; +static DECLARE_ALIGNED(16, int, f20_0_8) [ 8][8][2]; +static DECLARE_ALIGNED(16, int, f34_0_12)[12][8][2]; +static DECLARE_ALIGNED(16, int, f34_1_8) [ 8][8][2]; +static DECLARE_ALIGNED(16, int, f34_2_4) [ 4][8][2]; +static TABLE_CONST DECLARE_ALIGNED(16, int, Q_fract_allpass)[2][50][3][2]; +static DECLARE_ALIGNED(16, int, phi_fract)[2][50][2]; + +static const int g0_Q8[] = { + Q31(0.00746082949812f), Q31(0.02270420949825f), Q31(0.04546865930473f), Q31(0.07266113929591f), + Q31(0.09885108575264f), Q31(0.11793710567217f), Q31(0.125f) +}; + +static const int g0_Q12[] = { + Q31(0.04081179924692f), Q31(0.03812810994926f), Q31(0.05144908135699f), Q31(0.06399831151592f), + Q31(0.07428313801106f), Q31(0.08100347892914f), Q31(0.08333333333333f) +}; + +static const int g1_Q8[] = { + Q31(0.01565675600122f), Q31(0.03752716391991f), Q31(0.05417891378782f), Q31(0.08417044116767f), + Q31(0.10307344158036f), Q31(0.12222452249753f), Q31(0.125f) +}; + +static const int g2_Q4[] = { + Q31(-0.05908211155639f), Q31(-0.04871498374946f), Q31(0.0f), Q31(0.07778723915851f), + Q31( 0.16486303567403f), Q31( 0.23279856662996f), Q31(0.25f) +}; + +static const int sintbl_4[4] = { 0, 1073741824, 0, -1073741824 }; +static const int costbl_4[4] = { 1073741824, 0, -1073741824, 0 }; +static const int sintbl_8[8] = { 0, 759250125, 1073741824, 759250125, + 0, -759250125, -1073741824, -759250125 }; +static const int costbl_8[8] = { 1073741824, 759250125, 0, -759250125, + -1073741824, -759250125, 0, 759250125 }; +static const int sintbl_12[12] = { 0, 536870912, 929887697, 1073741824, + 929887697, 536870912, 0, -536870912, + -929887697, -1073741824, -929887697, -536870912 }; +static const int costbl_12[12] = { 1073741824, 929887697, 536870912, 0, + -536870912, -929887697, -1073741824, -929887697, + -536870912, 0, 536870912, 929887697 }; + +static void make_filters_from_proto(int (*filter)[8][2], const int *proto, int bands) +{ + + const int *sinptr, *cosptr; + int s, c, sinhalf, coshalf; + int q, n; + + if (bands == 4) { + sinptr = sintbl_4; + cosptr = costbl_4; + sinhalf = 759250125; + coshalf = 759250125; + } else if (bands == 8) { + sinptr = sintbl_8; + cosptr = costbl_8; + sinhalf = 410903207; + coshalf = 992008094; + } else { + sinptr = sintbl_12; + cosptr = costbl_12; + sinhalf = 277904834; + coshalf = 1037154959; + } + + for (q = 0; q < bands; q++) { + for (n = 0; n < 7; n++) { + int theta = (q*(n-6) + (n>>1) - 3) % bands; + + if (theta < 0) + theta += bands; + s = sinptr[theta]; + c = cosptr[theta]; + + if (n & 1) { + theta = (int)(((int64_t)c * coshalf - (int64_t)s * sinhalf + 0x20000000) >> 30); + s = (int)(((int64_t)s * coshalf + (int64_t)c * sinhalf + 0x20000000) >> 30); + c = theta; + } + filter[q][n][0] = (int)(((int64_t)proto[n] * c + 0x20000000) >> 30); + filter[q][n][1] = -(int)(((int64_t)proto[n] * s + 0x20000000) >> 30); + } + } +} + +static void ps_tableinit(void) +{ + static const int ipdopd_sin[] = { Q30(0), Q30(M_SQRT1_2), Q30(1), Q30( M_SQRT1_2), Q30( 0), Q30(-M_SQRT1_2), Q30(-1), Q30(-M_SQRT1_2) }; + static const int ipdopd_cos[] = { Q30(1), Q30(M_SQRT1_2), Q30(0), Q30(-M_SQRT1_2), Q30(-1), Q30(-M_SQRT1_2), Q30( 0), Q30( M_SQRT1_2) }; + int pd0, pd1, pd2; + int idx; + + static const int alpha_tab[] = + { + Q30(1.5146213770f/M_PI), Q30(1.5181334019f/M_PI), Q30(1.5234849453f/M_PI), Q30(1.5369486809f/M_PI), Q30(1.5500687361f/M_PI), Q30(1.5679757595f/M_PI), + Q30(1.4455626011f/M_PI), Q30(1.4531552792f/M_PI), Q30(1.4648091793f/M_PI), Q30(1.4945238829f/M_PI), Q30(1.5239057541f/M_PI), Q30(1.5644006729f/M_PI), + Q30(1.3738563061f/M_PI), Q30(1.3851221800f/M_PI), Q30(1.4026404619f/M_PI), Q30(1.4484288692f/M_PI), Q30(1.4949874878f/M_PI), Q30(1.5604078770f/M_PI), + Q30(1.2645189762f/M_PI), Q30(1.2796478271f/M_PI), Q30(1.3038636446f/M_PI), Q30(1.3710125685f/M_PI), Q30(1.4443849325f/M_PI), Q30(1.5532352924f/M_PI), + Q30(1.1507037878f/M_PI), Q30(1.1669205427f/M_PI), Q30(1.1938756704f/M_PI), Q30(1.2754167318f/M_PI), Q30(1.3761177063f/M_PI), Q30(1.5429240465f/M_PI), + Q30(1.0079245567f/M_PI), Q30(1.0208238363f/M_PI), Q30(1.0433073044f/M_PI), Q30(1.1208510399f/M_PI), Q30(1.2424604893f/M_PI), Q30(1.5185726881f/M_PI), + Q30(0.8995233774f/M_PI), Q30(0.9069069624f/M_PI), Q30(0.9201194048f/M_PI), Q30(0.9698365927f/M_PI), Q30(1.0671583414f/M_PI), Q30(1.4647934437f/M_PI), + Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), + Q30(0.6712729335f/M_PI), Q30(0.6638893485f/M_PI), Q30(0.6506769061f/M_PI), Q30(0.6009597182f/M_PI), Q30(0.5036380291f/M_PI), Q30(0.1060028747f/M_PI), + Q30(0.5628717542f/M_PI), Q30(0.5499725342f/M_PI), Q30(0.5274890065f/M_PI), Q30(0.4499453008f/M_PI), Q30(0.3283358216f/M_PI), Q30(0.0522236861f/M_PI), + Q30(0.4200925827f/M_PI), Q30(0.4038758278f/M_PI), Q30(0.3769206405f/M_PI), Q30(0.2953795493f/M_PI), Q30(0.1946786791f/M_PI), Q30(0.0278722942f/M_PI), + Q30(0.3062773645f/M_PI), Q30(0.2911485136f/M_PI), Q30(0.2669326365f/M_PI), Q30(0.1997837722f/M_PI), Q30(0.1264114529f/M_PI), Q30(0.0175609849f/M_PI), + Q30(0.1969399750f/M_PI), Q30(0.1856741160f/M_PI), Q30(0.1681558639f/M_PI), Q30(0.1223674342f/M_PI), Q30(0.0758088827f/M_PI), Q30(0.0103884479f/M_PI), + Q30(0.1252337098f/M_PI), Q30(0.1176410317f/M_PI), Q30(0.1059871912f/M_PI), Q30(0.0762724727f/M_PI), Q30(0.0468905345f/M_PI), Q30(0.0063956482f/M_PI), + Q30(0.0561749674f/M_PI), Q30(0.0526629239f/M_PI), Q30(0.0473113805f/M_PI), Q30(0.0338476151f/M_PI), Q30(0.0207276177f/M_PI), Q30(0.0028205961f/M_PI), + Q30(1.5676341057f/M_PI), Q30(1.5678333044f/M_PI), Q30(1.5681363344f/M_PI), Q30(1.5688960552f/M_PI), Q30(1.5696337223f/M_PI), Q30(1.5706381798f/M_PI), + Q30(1.5651730299f/M_PI), Q30(1.5655272007f/M_PI), Q30(1.5660660267f/M_PI), Q30(1.5674170256f/M_PI), Q30(1.5687289238f/M_PI), Q30(1.5705151558f/M_PI), + Q30(1.5607966185f/M_PI), Q30(1.5614265203f/M_PI), Q30(1.5623844862f/M_PI), Q30(1.5647867918f/M_PI), Q30(1.5671195984f/M_PI), Q30(1.5702962875f/M_PI), + Q30(1.5530153513f/M_PI), Q30(1.5541347265f/M_PI), Q30(1.5558375120f/M_PI), Q30(1.5601085424f/M_PI), Q30(1.5642569065f/M_PI), Q30(1.5699069500f/M_PI), + Q30(1.5391840935f/M_PI), Q30(1.5411708355f/M_PI), Q30(1.5441943407f/M_PI), Q30(1.5517836809f/M_PI), Q30(1.5591609478f/M_PI), Q30(1.5692136288f/M_PI), + Q30(1.5146213770f/M_PI), Q30(1.5181334019f/M_PI), Q30(1.5234849453f/M_PI), Q30(1.5369486809f/M_PI), Q30(1.5500687361f/M_PI), Q30(1.5679757595f/M_PI), + Q30(1.4915299416f/M_PI), Q30(1.4964480400f/M_PI), Q30(1.5039558411f/M_PI), Q30(1.5229074955f/M_PI), Q30(1.5414420366f/M_PI), Q30(1.5667995214f/M_PI), + Q30(1.4590617418f/M_PI), Q30(1.4658898115f/M_PI), Q30(1.4763505459f/M_PI), Q30(1.5029321909f/M_PI), Q30(1.5291173458f/M_PI), Q30(1.5651149750f/M_PI), + Q30(1.4136143923f/M_PI), Q30(1.4229322672f/M_PI), Q30(1.4373078346f/M_PI), Q30(1.4743183851f/M_PI), Q30(1.5113102198f/M_PI), Q30(1.5626684427f/M_PI), + Q30(1.3505556583f/M_PI), Q30(1.3628427982f/M_PI), Q30(1.3820509911f/M_PI), Q30(1.4327841997f/M_PI), Q30(1.4850014448f/M_PI), Q30(1.5590143204f/M_PI), + Q30(1.2645189762f/M_PI), Q30(1.2796478271f/M_PI), Q30(1.3038636446f/M_PI), Q30(1.3710125685f/M_PI), Q30(1.4443849325f/M_PI), Q30(1.5532352924f/M_PI), + Q30(1.1919227839f/M_PI), Q30(1.2081253529f/M_PI), Q30(1.2346779108f/M_PI), Q30(1.3123005629f/M_PI), Q30(1.4034168720f/M_PI), Q30(1.5471596718f/M_PI), + Q30(1.1061993837f/M_PI), Q30(1.1219338179f/M_PI), Q30(1.1484941244f/M_PI), Q30(1.2320860624f/M_PI), Q30(1.3421301842f/M_PI), Q30(1.5373806953f/M_PI), + Q30(1.0079245567f/M_PI), Q30(1.0208238363f/M_PI), Q30(1.0433073044f/M_PI), Q30(1.1208510399f/M_PI), Q30(1.2424604893f/M_PI), Q30(1.5185726881f/M_PI), + Q30(0.8995233774f/M_PI), Q30(0.9069069624f/M_PI), Q30(0.9201194048f/M_PI), Q30(0.9698365927f/M_PI), Q30(1.0671583414f/M_PI), Q30(1.4647934437f/M_PI), + Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), Q30(0.7853981853f/M_PI), + Q30(0.6712729335f/M_PI), Q30(0.6638893485f/M_PI), Q30(0.6506769061f/M_PI), Q30(0.6009597182f/M_PI), Q30(0.5036380291f/M_PI), Q30(0.1060028747f/M_PI), + Q30(0.5628717542f/M_PI), Q30(0.5499725342f/M_PI), Q30(0.5274890065f/M_PI), Q30(0.4499453008f/M_PI), Q30(0.3283358216f/M_PI), Q30(0.0522236861f/M_PI), + Q30(0.4645969570f/M_PI), Q30(0.4488625824f/M_PI), Q30(0.4223022461f/M_PI), Q30(0.3387103081f/M_PI), Q30(0.2286661267f/M_PI), Q30(0.0334156826f/M_PI), + Q30(0.3788735867f/M_PI), Q30(0.3626709878f/M_PI), Q30(0.3361184299f/M_PI), Q30(0.2584958076f/M_PI), Q30(0.1673794836f/M_PI), Q30(0.0236366931f/M_PI), + Q30(0.3062773645f/M_PI), Q30(0.2911485136f/M_PI), Q30(0.2669326365f/M_PI), Q30(0.1997837722f/M_PI), Q30(0.1264114529f/M_PI), Q30(0.0175609849f/M_PI), + Q30(0.2202406377f/M_PI), Q30(0.2079535723f/M_PI), Q30(0.1887452900f/M_PI), Q30(0.1380121708f/M_PI), Q30(0.0857949182f/M_PI), Q30(0.0117820343f/M_PI), + Q30(0.1571819335f/M_PI), Q30(0.1478640437f/M_PI), Q30(0.1334884763f/M_PI), Q30(0.0964778885f/M_PI), Q30(0.0594860613f/M_PI), Q30(0.0081279324f/M_PI), + Q30(0.1117345318f/M_PI), Q30(0.1049065739f/M_PI), Q30(0.0944457650f/M_PI), Q30(0.0678641573f/M_PI), Q30(0.0416790098f/M_PI), Q30(0.0056813755f/M_PI), + Q30(0.0792663917f/M_PI), Q30(0.0743482932f/M_PI), Q30(0.0668405443f/M_PI), Q30(0.0478888862f/M_PI), Q30(0.0293543357f/M_PI), Q30(0.0039967746f/M_PI), + Q30(0.0561749674f/M_PI), Q30(0.0526629239f/M_PI), Q30(0.0473113805f/M_PI), Q30(0.0338476151f/M_PI), Q30(0.0207276177f/M_PI), Q30(0.0028205961f/M_PI), + Q30(0.0316122435f/M_PI), Q30(0.0296254847f/M_PI), Q30(0.0266019460f/M_PI), Q30(0.0190126132f/M_PI), Q30(0.0116353342f/M_PI), Q30(0.0015827164f/M_PI), + Q30(0.0177809205f/M_PI), Q30(0.0166615788f/M_PI), Q30(0.0149587989f/M_PI), Q30(0.0106877899f/M_PI), Q30(0.0065393616f/M_PI), Q30(0.0008894200f/M_PI), + Q30(0.0099996664f/M_PI), Q30(0.0093698399f/M_PI), Q30(0.0084118480f/M_PI), Q30(0.0060095116f/M_PI), Q30(0.0036767013f/M_PI), Q30(0.0005000498f/M_PI), + Q30(0.0056233541f/M_PI), Q30(0.0052691097f/M_PI), Q30(0.0047303112f/M_PI), Q30(0.0033792770f/M_PI), Q30(0.0020674451f/M_PI), Q30(0.0002811795f/M_PI), + Q30(0.0031622672f/M_PI), Q30(0.0029630491f/M_PI), Q30(0.0026600463f/M_PI), Q30(0.0019002859f/M_PI), Q30(0.0011625893f/M_PI), Q30(0.0001581155f/M_PI) + }; + + static const int gamma_tab[] = + { + Q30(0.0000000000f/M_PI), Q30(0.0195873566f/M_PI), Q30(0.0303316917f/M_PI), Q30(0.0448668823f/M_PI), Q30(0.0522258915f/M_PI), Q30(0.0561044961f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0433459543f/M_PI), Q30(0.0672172382f/M_PI), Q30(0.0997167900f/M_PI), Q30(0.1162951663f/M_PI), Q30(0.1250736862f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0672341362f/M_PI), Q30(0.1045235619f/M_PI), Q30(0.1558904350f/M_PI), Q30(0.1824723780f/M_PI), Q30(0.1966800541f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1011129096f/M_PI), Q30(0.1580764502f/M_PI), Q30(0.2387557179f/M_PI), Q30(0.2820728719f/M_PI), Q30(0.3058380187f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1315985769f/M_PI), Q30(0.2072522491f/M_PI), Q30(0.3188187480f/M_PI), Q30(0.3825501204f/M_PI), Q30(0.4193951190f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1603866369f/M_PI), Q30(0.2549437582f/M_PI), Q30(0.4029446840f/M_PI), Q30(0.4980689585f/M_PI), Q30(0.5615641475f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1736015975f/M_PI), Q30(0.2773745656f/M_PI), Q30(0.4461984038f/M_PI), Q30(0.5666890144f/M_PI), Q30(0.6686112881f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1784276664f/M_PI), Q30(0.2856673002f/M_PI), Q30(0.4630723596f/M_PI), Q30(0.5971632004f/M_PI), Q30(0.7603877187f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1736015975f/M_PI), Q30(0.2773745656f/M_PI), Q30(0.4461984038f/M_PI), Q30(0.5666890144f/M_PI), Q30(0.6686112881f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1603866369f/M_PI), Q30(0.2549437582f/M_PI), Q30(0.4029446840f/M_PI), Q30(0.4980689585f/M_PI), Q30(0.5615641475f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1315985769f/M_PI), Q30(0.2072522491f/M_PI), Q30(0.3188187480f/M_PI), Q30(0.3825501204f/M_PI), Q30(0.4193951190f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1011129096f/M_PI), Q30(0.1580764502f/M_PI), Q30(0.2387557179f/M_PI), Q30(0.2820728719f/M_PI), Q30(0.3058380187f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0672341362f/M_PI), Q30(0.1045235619f/M_PI), Q30(0.1558904350f/M_PI), Q30(0.1824723780f/M_PI), Q30(0.1966800541f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0433459543f/M_PI), Q30(0.0672172382f/M_PI), Q30(0.0997167900f/M_PI), Q30(0.1162951663f/M_PI), Q30(0.1250736862f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0195873566f/M_PI), Q30(0.0303316917f/M_PI), Q30(0.0448668823f/M_PI), Q30(0.0522258915f/M_PI), Q30(0.0561044961f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0011053939f/M_PI), Q30(0.0017089852f/M_PI), Q30(0.0025254129f/M_PI), Q30(0.0029398468f/M_PI), Q30(0.0031597170f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0019607407f/M_PI), Q30(0.0030395309f/M_PI), Q30(0.0044951206f/M_PI), Q30(0.0052305623f/M_PI), Q30(0.0056152637f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0034913034f/M_PI), Q30(0.0054070661f/M_PI), Q30(0.0079917293f/M_PI), Q30(0.0092999367f/M_PI), Q30(0.0099875759f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0062100487f/M_PI), Q30(0.0096135242f/M_PI), Q30(0.0142110568f/M_PI), Q30(0.0165348612f/M_PI), Q30(0.0177587029f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0110366223f/M_PI), Q30(0.0170863140f/M_PI), Q30(0.0252620988f/M_PI), Q30(0.0293955617f/M_PI), Q30(0.0315726399f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0195873566f/M_PI), Q30(0.0303316917f/M_PI), Q30(0.0448668823f/M_PI), Q30(0.0522258915f/M_PI), Q30(0.0561044961f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0275881495f/M_PI), Q30(0.0427365713f/M_PI), Q30(0.0632618815f/M_PI), Q30(0.0736731067f/M_PI), Q30(0.0791663304f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0387469754f/M_PI), Q30(0.0600636788f/M_PI), Q30(0.0890387669f/M_PI), Q30(0.1037906483f/M_PI), Q30(0.1115923747f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0541138873f/M_PI), Q30(0.0839984417f/M_PI), Q30(0.1248718798f/M_PI), Q30(0.1458375156f/M_PI), Q30(0.1569785923f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0747506917f/M_PI), Q30(0.1163287833f/M_PI), Q30(0.1738867164f/M_PI), Q30(0.2038587779f/M_PI), Q30(0.2199459076f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1011129096f/M_PI), Q30(0.1580764502f/M_PI), Q30(0.2387557179f/M_PI), Q30(0.2820728719f/M_PI), Q30(0.3058380187f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1212290376f/M_PI), Q30(0.1903949380f/M_PI), Q30(0.2907958031f/M_PI), Q30(0.3466993868f/M_PI), Q30(0.3782821596f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1418247074f/M_PI), Q30(0.2240308374f/M_PI), Q30(0.3474813402f/M_PI), Q30(0.4202919006f/M_PI), Q30(0.4637607038f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1603866369f/M_PI), Q30(0.2549437582f/M_PI), Q30(0.4029446840f/M_PI), Q30(0.4980689585f/M_PI), Q30(0.5615641475f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1736015975f/M_PI), Q30(0.2773745656f/M_PI), Q30(0.4461984038f/M_PI), Q30(0.5666890144f/M_PI), Q30(0.6686112881f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1784276664f/M_PI), Q30(0.2856673002f/M_PI), Q30(0.4630723596f/M_PI), Q30(0.5971632004f/M_PI), Q30(0.7603877187f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1736015975f/M_PI), Q30(0.2773745656f/M_PI), Q30(0.4461984038f/M_PI), Q30(0.5666890144f/M_PI), Q30(0.6686112881f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1603866369f/M_PI), Q30(0.2549437582f/M_PI), Q30(0.4029446840f/M_PI), Q30(0.4980689585f/M_PI), Q30(0.5615641475f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1418247074f/M_PI), Q30(0.2240308374f/M_PI), Q30(0.3474813402f/M_PI), Q30(0.4202919006f/M_PI), Q30(0.4637607038f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1212290376f/M_PI), Q30(0.1903949380f/M_PI), Q30(0.2907958031f/M_PI), Q30(0.3466993868f/M_PI), Q30(0.3782821596f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.1011129096f/M_PI), Q30(0.1580764502f/M_PI), Q30(0.2387557179f/M_PI), Q30(0.2820728719f/M_PI), Q30(0.3058380187f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0747506917f/M_PI), Q30(0.1163287833f/M_PI), Q30(0.1738867164f/M_PI), Q30(0.2038587779f/M_PI), Q30(0.2199459076f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0541138873f/M_PI), Q30(0.0839984417f/M_PI), Q30(0.1248718798f/M_PI), Q30(0.1458375156f/M_PI), Q30(0.1569785923f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0387469754f/M_PI), Q30(0.0600636788f/M_PI), Q30(0.0890387669f/M_PI), Q30(0.1037906483f/M_PI), Q30(0.1115923747f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0275881495f/M_PI), Q30(0.0427365713f/M_PI), Q30(0.0632618815f/M_PI), Q30(0.0736731067f/M_PI), Q30(0.0791663304f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0195873566f/M_PI), Q30(0.0303316917f/M_PI), Q30(0.0448668823f/M_PI), Q30(0.0522258915f/M_PI), Q30(0.0561044961f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0110366223f/M_PI), Q30(0.0170863140f/M_PI), Q30(0.0252620988f/M_PI), Q30(0.0293955617f/M_PI), Q30(0.0315726399f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0062100487f/M_PI), Q30(0.0096135242f/M_PI), Q30(0.0142110568f/M_PI), Q30(0.0165348612f/M_PI), Q30(0.0177587029f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0034913034f/M_PI), Q30(0.0054070661f/M_PI), Q30(0.0079917293f/M_PI), Q30(0.0092999367f/M_PI), Q30(0.0099875759f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0019607407f/M_PI), Q30(0.0030395309f/M_PI), Q30(0.0044951206f/M_PI), Q30(0.0052305623f/M_PI), Q30(0.0056152637f/M_PI), + Q30(0.0000000000f/M_PI), Q30(0.0011053939f/M_PI), Q30(0.0017089852f/M_PI), Q30(0.0025254129f/M_PI), Q30(0.0029398468f/M_PI), Q30(0.0031597170f/M_PI) + }; + + static const int iid_par_dequant_c1[] = { + //iid_par_dequant_default + Q30(1.41198278375959f), Q30(1.40313815268360f), Q30(1.38687670404960f), Q30(1.34839972492648f), + Q30(1.29124937110028f), Q30(1.19603741667993f), Q30(1.10737240362323f), Q30(1), + Q30(0.87961716655242f), Q30(0.75464859232732f), Q30(0.57677990744575f), Q30(0.42640143271122f), + Q30(0.27671828230984f), Q30(0.17664462766713f), Q30(0.07940162697653f), + //iid_par_dequant_fine + Q30(1.41420649135832f), Q30(1.41419120222364f), Q30(1.41414285699784f), Q30(1.41399000859438f), + Q30(1.41350698548044f), Q30(1.41198278375959f), Q30(1.40977302262355f), Q30(1.40539479488545f), + Q30(1.39677960498402f), Q30(1.38005309967827f), Q30(1.34839972492648f), Q30(1.31392017367631f), + Q30(1.26431008149654f), Q30(1.19603741667993f), Q30(1.10737240362323f), Q30(1), + Q30(0.87961716655242f), Q30(0.75464859232732f), Q30(0.63365607219232f), Q30(0.52308104267543f), + Q30(0.42640143271122f), Q30(0.30895540465965f), Q30(0.22137464873077f), Q30(0.15768788954414f), + Q30(0.11198225164225f), Q30(0.07940162697653f), Q30(0.04469901562677f), Q30(0.02514469318284f), + Q30(0.01414142856998f), Q30(0.00795258154731f), Q30(0.00447211359449f), + }; + + static const int acos_icc_invq[] = { + Q31(0), Q31(0.178427635f/M_PI), Q31(0.28566733f/M_PI), Q31(0.46307236f/M_PI), Q31(0.59716315f/M_PI), Q31(0.78539816f/M_PI), Q31(1.10030855f/M_PI), Q31(1.57079633f/M_PI) + }; + int iid, icc; + + int k, m; + static const int8_t f_center_20[] = { + -3, -1, 1, 3, 5, 7, 10, 14, 18, 22, + }; + static const int32_t f_center_34[] = { + Q31( 2/768.0),Q31( 6/768.0),Q31(10/768.0),Q31(14/768.0),Q31( 18/768.0),Q31( 22/768.0),Q31( 26/768.0),Q31(30/768.0), + Q31( 34/768.0),Q31(-10/768.0),Q31(-6/768.0),Q31(-2/768.0),Q31( 51/768.0),Q31( 57/768.0),Q31( 15/768.0),Q31(21/768.0), + Q31( 27/768.0),Q31( 33/768.0),Q31(39/768.0),Q31(45/768.0),Q31( 54/768.0),Q31( 66/768.0),Q31( 78/768.0),Q31(42/768.0), + Q31(102/768.0),Q31( 66/768.0),Q31(78/768.0),Q31(90/768.0),Q31(102/768.0),Q31(114/768.0),Q31(126/768.0),Q31(90/768.0) + }; + static const int fractional_delay_links[] = { Q31(0.43f), Q31(0.75f), Q31(0.347f) }; + const int fractional_delay_gain = Q31(0.39f); + + for (pd0 = 0; pd0 < 8; pd0++) { + int pd0_re = (ipdopd_cos[pd0]+2)>>2; + int pd0_im = (ipdopd_sin[pd0]+2)>>2; + for (pd1 = 0; pd1 < 8; pd1++) { + int pd1_re = ipdopd_cos[pd1] >> 1; + int pd1_im = ipdopd_sin[pd1] >> 1; + for (pd2 = 0; pd2 < 8; pd2++) { + int shift, round; + int pd2_re = ipdopd_cos[pd2]; + int pd2_im = ipdopd_sin[pd2]; + int re_smooth = pd0_re + pd1_re + pd2_re; + int im_smooth = pd0_im + pd1_im + pd2_im; + + SoftFloat pd_mag = av_int2sf(((ipdopd_cos[(pd0-pd1)&7]+8)>>4) + ((ipdopd_cos[(pd0-pd2)&7]+4)>>3) + + ((ipdopd_cos[(pd1-pd2)&7]+2)>>2) + 0x15000000, 28); + pd_mag = av_div_sf(FLOAT_1, av_sqrt_sf(pd_mag)); + shift = 30 - pd_mag.exp; + round = 1 << (shift-1); + pd_re_smooth[pd0*64+pd1*8+pd2] = (int)(((int64_t)re_smooth * pd_mag.mant + round) >> shift); + pd_im_smooth[pd0*64+pd1*8+pd2] = (int)(((int64_t)im_smooth * pd_mag.mant + round) >> shift); + } + } + } + + idx = 0; + for (iid = 0; iid < 46; iid++) { + int c1, c2; + + c1 = iid_par_dequant_c1[iid]; + if (iid < 15) + c2 = iid_par_dequant_c1[14-iid]; + else + c2 = iid_par_dequant_c1[60-iid]; + + for (icc = 0; icc < 8; icc++) { + /*if (PS_BASELINE || ps->icc_mode < 3)*/{ + int alpha, beta; + int ca, sa, cb, sb; + + alpha = acos_icc_invq[icc]; + beta = (int)(((int64_t)alpha * 1518500250 + 0x40000000) >> 31); + alpha >>= 1; + beta = (int)(((int64_t)beta * (c1 - c2) + 0x40000000) >> 31); + av_sincos_sf(beta + alpha, &sa, &ca); + av_sincos_sf(beta - alpha, &sb, &cb); + + HA[iid][icc][0] = (int)(((int64_t)c2 * ca + 0x20000000) >> 30); + HA[iid][icc][1] = (int)(((int64_t)c1 * cb + 0x20000000) >> 30); + HA[iid][icc][2] = (int)(((int64_t)c2 * sa + 0x20000000) >> 30); + HA[iid][icc][3] = (int)(((int64_t)c1 * sb + 0x20000000) >> 30); + } /* else */ { + int alpha_int, gamma_int; + int alpha_c_int, alpha_s_int, gamma_c_int, gamma_s_int; + + alpha_int = alpha_tab[idx]; + gamma_int = gamma_tab[idx]; + + av_sincos_sf(alpha_int, &alpha_s_int, &alpha_c_int); + av_sincos_sf(gamma_int, &gamma_s_int, &gamma_c_int); + + alpha_c_int = (int)(((int64_t)alpha_c_int * 1518500250 + 0x20000000) >> 30); + alpha_s_int = (int)(((int64_t)alpha_s_int * 1518500250 + 0x20000000) >> 30); + + HB[iid][icc][0] = (int)(((int64_t)alpha_c_int * gamma_c_int + 0x20000000) >> 30); + HB[iid][icc][1] = (int)(((int64_t)alpha_s_int * gamma_c_int + 0x20000000) >> 30); + HB[iid][icc][2] = -(int)(((int64_t)alpha_s_int * gamma_s_int + 0x20000000) >> 30); + HB[iid][icc][3] = (int)(((int64_t)alpha_c_int * gamma_s_int + 0x20000000) >> 30); + } + + if (icc < 5 || icc > 6) + idx++; + } + } + + for (k = 0; k < NR_ALLPASS_BANDS20; k++) { + int theta; + int64_t f_center; + int c, s; + + if (k < FF_ARRAY_ELEMS(f_center_20)) + f_center = f_center_20[k]; + else + f_center = (k << 3) - 52; + + for (m = 0; m < PS_AP_LINKS; m++) { + theta = (int)(((int64_t)fractional_delay_links[m] * f_center + 8) >> 4); + av_sincos_sf(-theta, &s, &c); + Q_fract_allpass[0][k][m][0] = c; + Q_fract_allpass[0][k][m][1] = s; + } + + theta = (int)(((int64_t)fractional_delay_gain * f_center + 8) >> 4); + av_sincos_sf(-theta, &s, &c); + phi_fract[0][k][0] = c; + phi_fract[0][k][1] = s; + } + + for (k = 0; k < NR_ALLPASS_BANDS34; k++) { + int theta, f_center; + int c, s; + + if (k < FF_ARRAY_ELEMS(f_center_34)) + f_center = f_center_34[k]; + else + f_center = ((int64_t)k << 26) - (53 << 25); + + for (m = 0; m < PS_AP_LINKS; m++) { + theta = (int)(((int64_t)fractional_delay_links[m] * f_center + 0x10000000) >> 27); + av_sincos_sf(-theta, &s, &c); + Q_fract_allpass[1][k][m][0] = c; + Q_fract_allpass[1][k][m][1] = s; + } + + theta = (int)(((int64_t)fractional_delay_gain * f_center + 0x10000000) >> 27); + av_sincos_sf(-theta, &s, &c); + phi_fract[1][k][0] = c; + phi_fract[1][k][1] = s; + } + + make_filters_from_proto(f20_0_8, g0_Q8, 8); + make_filters_from_proto(f34_0_12, g0_Q12, 12); + make_filters_from_proto(f34_1_8, g1_Q8, 8); + make_filters_from_proto(f34_2_4, g2_Q4, 4); +} +#endif /* CONFIG_HARDCODED_TABLES */ + +#endif /* AVCODEC_AACPS_FIXED_TABLEGEN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_float.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_float.c new file mode 100644 index 000000000..73259c10f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_float.c @@ -0,0 +1,24 @@ +/* + * MPEG-4 Parametric Stereo decoding functions + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 0 + +#include "aacps.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen.c new file mode 100644 index 000000000..26a6752fa --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen.c @@ -0,0 +1,24 @@ +/* + * Generate a header file for hardcoded Parametric Stereo tables + * + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 0 +#include "aacps_tablegen_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen.h new file mode 100644 index 000000000..0ac4f68d6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen.h @@ -0,0 +1,217 @@ +/* + * Header file for hardcoded Parametric Stereo tables + * + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AACPS_TABLEGEN_H +#define AVCODEC_AACPS_TABLEGEN_H + +#include +#include + +#if CONFIG_HARDCODED_TABLES +#define ps_tableinit() +#define TABLE_CONST const +#include "libavcodec/aacps_tables.h" +#else +#include "libavutil/common.h" +#include "libavutil/libm.h" +#include "libavutil/mathematics.h" +#include "libavutil/mem.h" +#define NR_ALLPASS_BANDS20 30 +#define NR_ALLPASS_BANDS34 50 +#define PS_AP_LINKS 3 +#define TABLE_CONST +static float pd_re_smooth[8*8*8]; +static float pd_im_smooth[8*8*8]; +static float HA[46][8][4]; +static float HB[46][8][4]; +static DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2]; +static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2]; +static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2]; +static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2]; +static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2]; +static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2]; + +static const float g0_Q8[] = { + 0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f, + 0.09885108575264f, 0.11793710567217f, 0.125f +}; + +static const float g0_Q12[] = { + 0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f, + 0.07428313801106f, 0.08100347892914f, 0.08333333333333f +}; + +static const float g1_Q8[] = { + 0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f, + 0.10307344158036f, 0.12222452249753f, 0.125f +}; + +static const float g2_Q4[] = { + -0.05908211155639f, -0.04871498374946f, 0.0f, 0.07778723915851f, + 0.16486303567403f, 0.23279856662996f, 0.25f +}; + +static av_cold void make_filters_from_proto(float (*filter)[8][2], const float *proto, int bands) +{ + int q, n; + for (q = 0; q < bands; q++) { + for (n = 0; n < 7; n++) { + double theta = 2 * M_PI * (q + 0.5) * (n - 6) / bands; + filter[q][n][0] = proto[n] * cos(theta); + filter[q][n][1] = proto[n] * -sin(theta); + } + } +} + +static av_cold void ps_tableinit(void) +{ + static const float ipdopd_sin[] = { 0, M_SQRT1_2, 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2 }; + static const float ipdopd_cos[] = { 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2, 0, M_SQRT1_2 }; + int pd0, pd1, pd2; + + static const float iid_par_dequant[] = { + //iid_par_dequant_default + 0.05623413251903, 0.12589254117942, 0.19952623149689, 0.31622776601684, + 0.44668359215096, 0.63095734448019, 0.79432823472428, 1, + 1.25892541179417, 1.58489319246111, 2.23872113856834, 3.16227766016838, + 5.01187233627272, 7.94328234724282, 17.7827941003892, + //iid_par_dequant_fine + 0.00316227766017, 0.00562341325190, 0.01, 0.01778279410039, + 0.03162277660168, 0.05623413251903, 0.07943282347243, 0.11220184543020, + 0.15848931924611, 0.22387211385683, 0.31622776601684, 0.39810717055350, + 0.50118723362727, 0.63095734448019, 0.79432823472428, 1, + 1.25892541179417, 1.58489319246111, 1.99526231496888, 2.51188643150958, + 3.16227766016838, 4.46683592150963, 6.30957344480193, 8.91250938133745, + 12.5892541179417, 17.7827941003892, 31.6227766016838, 56.2341325190349, + 100, 177.827941003892, 316.227766016837, + }; + static const float icc_invq[] = { + 1, 0.937, 0.84118, 0.60092, 0.36764, 0, -0.589, -1 + }; + static const float acos_icc_invq[] = { + 0, 0.35685527, 0.57133466, 0.92614472, 1.1943263, M_PI/2, 2.2006171, M_PI + }; + int iid, icc; + + int k, m; + static const int8_t f_center_20[] = { + -3, -1, 1, 3, 5, 7, 10, 14, 18, 22, + }; + static const int8_t f_center_34[] = { + 2, 6, 10, 14, 18, 22, 26, 30, + 34,-10, -6, -2, 51, 57, 15, 21, + 27, 33, 39, 45, 54, 66, 78, 42, + 102, 66, 78, 90,102,114,126, 90, + }; + static const float fractional_delay_links[] = { 0.43f, 0.75f, 0.347f }; + const float fractional_delay_gain = 0.39f; + + for (pd0 = 0; pd0 < 8; pd0++) { + float pd0_re = ipdopd_cos[pd0]; + float pd0_im = ipdopd_sin[pd0]; + for (pd1 = 0; pd1 < 8; pd1++) { + float pd1_re = ipdopd_cos[pd1]; + float pd1_im = ipdopd_sin[pd1]; + for (pd2 = 0; pd2 < 8; pd2++) { + float pd2_re = ipdopd_cos[pd2]; + float pd2_im = ipdopd_sin[pd2]; + float re_smooth = 0.25f * pd0_re + 0.5f * pd1_re + pd2_re; + float im_smooth = 0.25f * pd0_im + 0.5f * pd1_im + pd2_im; + float pd_mag = 1 / hypot(im_smooth, re_smooth); + pd_re_smooth[pd0*64+pd1*8+pd2] = re_smooth * pd_mag; + pd_im_smooth[pd0*64+pd1*8+pd2] = im_smooth * pd_mag; + } + } + } + + for (iid = 0; iid < 46; iid++) { + float c = iid_par_dequant[iid]; ///< Linear Inter-channel Intensity Difference + float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c); + float c2 = c * c1; + for (icc = 0; icc < 8; icc++) { + /*if (PS_BASELINE || ps->icc_mode < 3)*/ { + float alpha = 0.5f * acos_icc_invq[icc]; + float beta = alpha * (c1 - c2) * (float)M_SQRT1_2; + HA[iid][icc][0] = c2 * cosf(beta + alpha); + HA[iid][icc][1] = c1 * cosf(beta - alpha); + HA[iid][icc][2] = c2 * sinf(beta + alpha); + HA[iid][icc][3] = c1 * sinf(beta - alpha); + } /* else */ { + float alpha, gamma, mu, rho; + float alpha_c, alpha_s, gamma_c, gamma_s; + rho = FFMAX(icc_invq[icc], 0.05f); + alpha = 0.5f * atan2f(2.0f * c * rho, c*c - 1.0f); + mu = c + 1.0f / c; + mu = sqrtf(1 + (4 * rho * rho - 4)/(mu * mu)); + gamma = atanf(sqrtf((1.0f - mu)/(1.0f + mu))); + if (alpha < 0) alpha += M_PI/2; + alpha_c = cosf(alpha); + alpha_s = sinf(alpha); + gamma_c = cosf(gamma); + gamma_s = sinf(gamma); + HB[iid][icc][0] = M_SQRT2 * alpha_c * gamma_c; + HB[iid][icc][1] = M_SQRT2 * alpha_s * gamma_c; + HB[iid][icc][2] = -M_SQRT2 * alpha_s * gamma_s; + HB[iid][icc][3] = M_SQRT2 * alpha_c * gamma_s; + } + } + } + + for (k = 0; k < NR_ALLPASS_BANDS20; k++) { + double f_center, theta; + if (k < FF_ARRAY_ELEMS(f_center_20)) + f_center = f_center_20[k] * 0.125; + else + f_center = k - 6.5f; + for (m = 0; m < PS_AP_LINKS; m++) { + theta = -M_PI * fractional_delay_links[m] * f_center; + Q_fract_allpass[0][k][m][0] = cos(theta); + Q_fract_allpass[0][k][m][1] = sin(theta); + } + theta = -M_PI*fractional_delay_gain*f_center; + phi_fract[0][k][0] = cos(theta); + phi_fract[0][k][1] = sin(theta); + } + for (k = 0; k < NR_ALLPASS_BANDS34; k++) { + double f_center, theta; + if (k < FF_ARRAY_ELEMS(f_center_34)) + f_center = f_center_34[k] / 24.0; + else + f_center = k - 26.5f; + for (m = 0; m < PS_AP_LINKS; m++) { + theta = -M_PI * fractional_delay_links[m] * f_center; + Q_fract_allpass[1][k][m][0] = cos(theta); + Q_fract_allpass[1][k][m][1] = sin(theta); + } + theta = -M_PI*fractional_delay_gain*f_center; + phi_fract[1][k][0] = cos(theta); + phi_fract[1][k][1] = sin(theta); + } + + make_filters_from_proto(f20_0_8, g0_Q8, 8); + make_filters_from_proto(f34_0_12, g0_Q12, 12); + make_filters_from_proto(f34_1_8, g1_Q8, 8); + make_filters_from_proto(f34_2_4, g2_Q4, 4); +} +#endif /* CONFIG_HARDCODED_TABLES */ + +#endif /* AVCODEC_AACPS_TABLEGEN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen_template.c new file mode 100644 index 000000000..341bd4440 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacps_tablegen_template.c @@ -0,0 +1,107 @@ +/* + * Generate a header file for hardcoded Parametric Stereo tables + * + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#define CONFIG_HARDCODED_TABLES 0 +#include "aac_defines.h" + +#if USE_FIXED +#define TYPE_NAME "int32_t" +typedef int32_t INT32FLOAT; +#define ARRAY_RENAME(x) write_int32_t_ ## x +#define ARRAY_URENAME(x) write_uint32_t_ ## x +#include "aacps_fixed_tablegen.h" +#else +#define TYPE_NAME "float" +typedef float INT32FLOAT; +#define ARRAY_RENAME(x) write_float_ ## x +#define ARRAY_URENAME(x) write_float_ ## x +#include "aacps_tablegen.h" +#endif /* USE_FIXED */ +#include "tableprint.h" + +void ARRAY_RENAME(3d_array) (const void *p, int b, int c, int d) +{ + int i; + const INT32FLOAT *f = p; + for (i = 0; i < b; i++) { + printf("{\n"); + ARRAY_URENAME(2d_array)(f, c, d); + printf("},\n"); + f += c * d; + } +} + +void ARRAY_RENAME(4d_array) (const void *p, int a, int b, int c, int d) +{ + int i; + const INT32FLOAT *f = p; + for (i = 0; i < a; i++) { + printf("{\n"); + ARRAY_RENAME(3d_array)(f, b, c, d); + printf("},\n"); + f += b * c * d; + } +} + +int main(void) +{ + ps_tableinit(); + + write_fileheader(); + + printf("static const %s pd_re_smooth[8*8*8] = {\n", TYPE_NAME); + ARRAY_RENAME(array)(pd_re_smooth, 8*8*8); + printf("};\n"); + printf("static const %s pd_im_smooth[8*8*8] = {\n", TYPE_NAME); + ARRAY_RENAME(array)(pd_im_smooth, 8*8*8); + printf("};\n"); + + printf("static const %s HA[46][8][4] = {\n", TYPE_NAME); + ARRAY_RENAME(3d_array)(HA, 46, 8, 4); + printf("};\n"); + printf("static const %s HB[46][8][4] = {\n", TYPE_NAME); + ARRAY_RENAME(3d_array)(HB, 46, 8, 4); + printf("};\n"); + + printf("static const DECLARE_ALIGNED(16, %s, f20_0_8)[8][8][2] = {\n", TYPE_NAME); + ARRAY_RENAME(3d_array)(f20_0_8, 8, 8, 2); + printf("};\n"); + printf("static const DECLARE_ALIGNED(16, %s, f34_0_12)[12][8][2] = {\n", TYPE_NAME); + ARRAY_RENAME(3d_array)(f34_0_12, 12, 8, 2); + printf("};\n"); + printf("static const DECLARE_ALIGNED(16, %s, f34_1_8)[8][8][2] = {\n", TYPE_NAME); + ARRAY_RENAME(3d_array)(f34_1_8, 8, 8, 2); + printf("};\n"); + printf("static const DECLARE_ALIGNED(16, %s, f34_2_4)[4][8][2] = {\n", TYPE_NAME); + ARRAY_RENAME(3d_array)(f34_2_4, 4, 8, 2); + printf("};\n"); + + printf("static const DECLARE_ALIGNED(16, %s, Q_fract_allpass)[2][50][3][2] = {\n", TYPE_NAME); + ARRAY_RENAME(4d_array)(Q_fract_allpass, 2, 50, 3, 2); + printf("};\n"); + printf("static const DECLARE_ALIGNED(16, %s, phi_fract)[2][50][2] = {\n", TYPE_NAME); + ARRAY_RENAME(3d_array)(phi_fract, 2, 50, 2); + printf("};\n"); + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdata.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdata.c new file mode 100644 index 000000000..5c1a1b0f8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdata.c @@ -0,0 +1,163 @@ +/* + * MPEG-4 Parametric Stereo data tables + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static const uint8_t huff_iid_df1_bits[] = { + 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 16, 16, 15, 14, 14, + 13, 12, 12, 11, 10, 10, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18, 17, 18, 18, + 18, 18, 18, 18, 18, 18, 18, +}; + +static const uint32_t huff_iid_df1_codes[] = { + 0x01FEB4, 0x01FEB5, 0x01FD76, 0x01FD77, 0x01FD74, 0x01FD75, 0x01FE8A, + 0x01FE8B, 0x01FE88, 0x00FE80, 0x01FEB6, 0x00FE82, 0x00FEB8, 0x007F42, + 0x007FAE, 0x003FAF, 0x001FD1, 0x001FE9, 0x000FE9, 0x0007EA, 0x0007FB, + 0x0003FB, 0x0001FB, 0x0001FF, 0x00007C, 0x00003C, 0x00001C, 0x00000C, + 0x000000, 0x000001, 0x000001, 0x000002, 0x000001, 0x00000D, 0x00001D, + 0x00003D, 0x00007D, 0x0000FC, 0x0001FC, 0x0003FC, 0x0003F4, 0x0007EB, + 0x000FEA, 0x001FEA, 0x001FD6, 0x003FD0, 0x007FAF, 0x007F43, 0x00FEB9, + 0x00FE83, 0x01FEB7, 0x00FE81, 0x01FE89, 0x01FE8E, 0x01FE8F, 0x01FE8C, + 0x01FE8D, 0x01FEB2, 0x01FEB3, 0x01FEB0, 0x01FEB1, +}; + +static const uint8_t huff_iid_dt1_bits[] = { + 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 13, + 13, 13, 12, 12, 11, 10, 9, 9, 7, 6, 5, 3, 1, 2, 5, 6, 7, 8, + 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, +}; + +static const uint16_t huff_iid_dt1_codes[] = { + 0x004ED4, 0x004ED5, 0x004ECE, 0x004ECF, 0x004ECC, 0x004ED6, 0x004ED8, + 0x004F46, 0x004F60, 0x002718, 0x002719, 0x002764, 0x002765, 0x00276D, + 0x0027B1, 0x0013B7, 0x0013D6, 0x0009C7, 0x0009E9, 0x0009ED, 0x0004EE, + 0x0004F7, 0x000278, 0x000139, 0x00009A, 0x00009F, 0x000020, 0x000011, + 0x00000A, 0x000003, 0x000001, 0x000000, 0x00000B, 0x000012, 0x000021, + 0x00004C, 0x00009B, 0x00013A, 0x000279, 0x000270, 0x0004EF, 0x0004E2, + 0x0009EA, 0x0009D8, 0x0013D7, 0x0013D0, 0x0027B2, 0x0027A2, 0x00271A, + 0x00271B, 0x004F66, 0x004F67, 0x004F61, 0x004F47, 0x004ED9, 0x004ED7, + 0x004ECD, 0x004ED2, 0x004ED3, 0x004ED0, 0x004ED1, +}; + +static const uint8_t huff_iid_df0_bits[] = { + 17, 17, 17, 17, 16, 15, 13, 10, 9, 7, 6, 5, 4, 3, 1, 3, 4, 5, + 6, 6, 8, 11, 13, 14, 14, 15, 17, 18, 18, +}; + +static const uint32_t huff_iid_df0_codes[] = { + 0x01FFFB, 0x01FFFC, 0x01FFFD, 0x01FFFA, 0x00FFFC, 0x007FFC, 0x001FFD, + 0x0003FE, 0x0001FE, 0x00007E, 0x00003C, 0x00001D, 0x00000D, 0x000005, + 0x000000, 0x000004, 0x00000C, 0x00001C, 0x00003D, 0x00003E, 0x0000FE, + 0x0007FE, 0x001FFC, 0x003FFC, 0x003FFD, 0x007FFD, 0x01FFFE, 0x03FFFE, + 0x03FFFF, +}; + +static const uint8_t huff_iid_dt0_bits[] = { + 19, 19, 19, 20, 20, 20, 17, 15, 12, 10, 8, 6, 4, 2, 1, 3, 5, 7, + 9, 11, 13, 14, 17, 19, 20, 20, 20, 20, 20, +}; + +static const uint32_t huff_iid_dt0_codes[] = { + 0x07FFF9, 0x07FFFA, 0x07FFFB, 0x0FFFF8, 0x0FFFF9, 0x0FFFFA, 0x01FFFD, + 0x007FFE, 0x000FFE, 0x0003FE, 0x0000FE, 0x00003E, 0x00000E, 0x000002, + 0x000000, 0x000006, 0x00001E, 0x00007E, 0x0001FE, 0x0007FE, 0x001FFE, + 0x003FFE, 0x01FFFC, 0x07FFF8, 0x0FFFFB, 0x0FFFFC, 0x0FFFFD, 0x0FFFFE, + 0x0FFFFF, +}; + +static const uint8_t huff_icc_df_bits[] = { + 14, 14, 12, 10, 7, 5, 3, 1, 2, 4, 6, 8, 9, 11, 13, +}; + +static const uint16_t huff_icc_df_codes[] = { + 0x3FFF, 0x3FFE, 0x0FFE, 0x03FE, 0x007E, 0x001E, 0x0006, 0x0000, + 0x0002, 0x000E, 0x003E, 0x00FE, 0x01FE, 0x07FE, 0x1FFE, +}; + +static const uint8_t huff_icc_dt_bits[] = { + 14, 13, 11, 9, 7, 5, 3, 1, 2, 4, 6, 8, 10, 12, 14, +}; + +static const uint16_t huff_icc_dt_codes[] = { + 0x3FFE, 0x1FFE, 0x07FE, 0x01FE, 0x007E, 0x001E, 0x0006, 0x0000, + 0x0002, 0x000E, 0x003E, 0x00FE, 0x03FE, 0x0FFE, 0x3FFF, +}; + +static const uint8_t huff_ipd_df_bits[] = { + 1, 3, 4, 4, 4, 4, 4, 4, +}; + +static const uint8_t huff_ipd_df_codes[] = { + 0x01, 0x00, 0x06, 0x04, 0x02, 0x03, 0x05, 0x07, +}; + +static const uint8_t huff_ipd_dt_bits[] = { + 1, 3, 4, 5, 5, 4, 4, 3, +}; + +static const uint8_t huff_ipd_dt_codes[] = { + 0x01, 0x02, 0x02, 0x03, 0x02, 0x00, 0x03, 0x03, +}; + +static const uint8_t huff_opd_df_bits[] = { + 1, 3, 4, 4, 5, 5, 4, 3, +}; + +static const uint8_t huff_opd_df_codes[] = { + 0x01, 0x01, 0x06, 0x04, 0x0F, 0x0E, 0x05, 0x00, +}; + +static const uint8_t huff_opd_dt_bits[] = { + 1, 3, 4, 5, 5, 4, 4, 3, +}; + +static const uint8_t huff_opd_dt_codes[] = { + 0x01, 0x02, 0x01, 0x07, 0x06, 0x00, 0x02, 0x03, +}; + +static const int8_t huff_offset[] = { + 30, 30, + 14, 14, + 7, 7, + 0, 0, + 0, 0, +}; + +///Table 8.48 +static const int8_t k_to_i_20[] = { + 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, + 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19 +}; +///Table 8.49 +static const int8_t k_to_i_34[] = { + 0, 1, 2, 3, 4, 5, 6, 6, 7, 2, 1, 0, 10, 10, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 9, 14, 11, 12, 13, 14, 15, 16, 13, 16, 17, 18, 19, 20, 21, + 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, + 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 +}; + +static const INTFLOAT g1_Q2[] = { + Q31(0.0f), Q31(0.01899487526049f), Q31(0.0f), Q31(-0.07293139167538f), + Q31(0.0f), Q31(0.30596630545168f), Q31(0.5f) +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp.asm new file mode 100644 index 000000000..4acd087c8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp.asm @@ -0,0 +1,487 @@ +;****************************************************************************** +;* SIMD optimized MPEG-4 Parametric Stereo decoding functions +;* +;* Copyright (C) 2015 James Almer +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA + +ps_p1m1p1m1: dd 0, 0x80000000, 0, 0x80000000 + +SECTION .text + +;************************************************************************* +;void ff_ps_add_squares_(float *dst, const float (*src)[2], int n); +;************************************************************************* +%macro PS_ADD_SQUARES 1 +cglobal ps_add_squares, 3, 3, %1, dst, src, n + shl nd, 3 + add srcq, nq + neg nq + +align 16 +.loop: + movaps m0, [srcq+nq] + movaps m1, [srcq+nq+mmsize] + mulps m0, m0 + mulps m1, m1 + HADDPS m0, m1, m2 + addps m0, [dstq] + movaps [dstq], m0 + add dstq, mmsize + add nq, mmsize*2 + jl .loop + REP_RET +%endmacro + +INIT_XMM sse +PS_ADD_SQUARES 2 +INIT_XMM sse3 +PS_ADD_SQUARES 3 + +;******************************************************************* +;void ff_ps_mul_pair_single_sse(float (*dst)[2], float (*src0)[2], +; float *src1, int n); +;******************************************************************* +INIT_XMM sse +cglobal ps_mul_pair_single, 4, 4, 4, dst, src1, src2, n + shl nd, 3 + add src1q, nq + add dstq, nq + neg nq + +align 16 +.loop: + movu m0, [src1q+nq] + movu m1, [src1q+nq+mmsize] + mova m2, [src2q] + mova m3, m2 + unpcklps m2, m2 + unpckhps m3, m3 + mulps m0, m2 + mulps m1, m3 + mova [dstq+nq], m0 + mova [dstq+nq+mmsize], m1 + add src2q, mmsize + add nq, mmsize*2 + jl .loop + REP_RET + +;*********************************************************************** +;void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2], +; float h[2][4], float h_step[2][4], +; int len); +;*********************************************************************** +INIT_XMM sse3 +cglobal ps_stereo_interpolate, 5, 5, 6, l, r, h, h_step, n + movaps m0, [hq] + movaps m1, [h_stepq] + unpcklps m4, m0, m0 + unpckhps m0, m0 + unpcklps m5, m1, m1 + unpckhps m1, m1 + shl nd, 3 + add lq, nq + add rq, nq + neg nq + +align 16 +.loop: + addps m4, m5 + addps m0, m1 + movddup m2, [lq+nq] + movddup m3, [rq+nq] + mulps m2, m4 + mulps m3, m0 + addps m2, m3 + movsd [lq+nq], m2 + movhps [rq+nq], m2 + add nq, 8 + jl .loop + REP_RET + +;*************************************************************************** +;void ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2], +; float h[2][4], float h_step[2][4], +; int len); +;*************************************************************************** +INIT_XMM sse3 +cglobal ps_stereo_interpolate_ipdopd, 5, 5, 10, l, r, h, h_step, n + movaps m0, [hq] + movaps m1, [hq+mmsize] +%if ARCH_X86_64 + movaps m8, [h_stepq] + movaps m9, [h_stepq+mmsize] + %define H_STEP0 m8 + %define H_STEP1 m9 +%else + %define H_STEP0 [h_stepq] + %define H_STEP1 [h_stepq+mmsize] +%endif + shl nd, 3 + add lq, nq + add rq, nq + neg nq + +align 16 +.loop: + addps m0, H_STEP0 + addps m1, H_STEP1 + movddup m2, [lq+nq] + movddup m3, [rq+nq] + shufps m4, m2, m2, q2301 + shufps m5, m3, m3, q2301 + unpcklps m6, m0, m0 + unpckhps m7, m0, m0 + mulps m2, m6 + mulps m3, m7 + unpcklps m6, m1, m1 + unpckhps m7, m1, m1 + mulps m4, m6 + mulps m5, m7 + addps m2, m3 + addsubps m2, m4 + addsubps m2, m5 + movsd [lq+nq], m2 + movhps [rq+nq], m2 + add nq, 8 + jl .loop + REP_RET + +;********************************************************** +;void ps_hybrid_analysis_ileave_sse(float out[2][38][64], +; float (*in)[32][2], +; int i, int len) +;********************************************************** +INIT_XMM sse +cglobal ps_hybrid_analysis_ileave, 3, 7, 5, out, in, i, len, in0, in1, tmp + movsxdifnidn iq, id + mov lend, 32 << 3 + lea inq, [inq+iq*4] + mov tmpd, id + shl tmpd, 8 + add outq, tmpq + mov tmpd, 64 + sub tmpd, id + mov id, tmpd + + test id, 1 + jne .loop4 + test id, 2 + jne .loop8 + +align 16 +.loop16: + mov in0q, inq + mov in1q, 38*64*4 + add in1q, in0q + mov tmpd, lend + +.inner_loop16: + movaps m0, [in0q] + movaps m1, [in1q] + movaps m2, [in0q+lenq] + movaps m3, [in1q+lenq] + TRANSPOSE4x4PS 0, 1, 2, 3, 4 + movaps [outq], m0 + movaps [outq+lenq], m1 + movaps [outq+lenq*2], m2 + movaps [outq+3*32*2*4], m3 + lea in0q, [in0q+lenq*2] + lea in1q, [in1q+lenq*2] + add outq, mmsize + sub tmpd, mmsize + jg .inner_loop16 + add inq, 16 + add outq, 3*32*2*4 + sub id, 4 + jg .loop16 + RET + +align 16 +.loop8: + mov in0q, inq + mov in1q, 38*64*4 + add in1q, in0q + mov tmpd, lend + +.inner_loop8: + movlps m0, [in0q] + movlps m1, [in1q] + movhps m0, [in0q+lenq] + movhps m1, [in1q+lenq] + SBUTTERFLYPS 0, 1, 2 + SBUTTERFLYPD 0, 1, 2 + movaps [outq], m0 + movaps [outq+lenq], m1 + lea in0q, [in0q+lenq*2] + lea in1q, [in1q+lenq*2] + add outq, mmsize + sub tmpd, mmsize + jg .inner_loop8 + add inq, 8 + add outq, lenq + sub id, 2 + jg .loop16 + RET + +align 16 +.loop4: + mov in0q, inq + mov in1q, 38*64*4 + add in1q, in0q + mov tmpd, lend + +.inner_loop4: + movss m0, [in0q] + movss m1, [in1q] + movss m2, [in0q+lenq] + movss m3, [in1q+lenq] + movlhps m0, m1 + movlhps m2, m3 + shufps m0, m2, q2020 + movaps [outq], m0 + lea in0q, [in0q+lenq*2] + lea in1q, [in1q+lenq*2] + add outq, mmsize + sub tmpd, mmsize + jg .inner_loop4 + add inq, 4 + sub id, 1 + test id, 2 + jne .loop8 + cmp id, 4 + jge .loop16 + RET + +;*********************************************************** +;void ps_hybrid_synthesis_deint_sse4(float out[2][38][64], +; float (*in)[32][2], +; int i, int len) +;*********************************************************** +%macro HYBRID_SYNTHESIS_DEINT 0 +cglobal ps_hybrid_synthesis_deint, 3, 7, 5, out, in, i, len, out0, out1, tmp +%if cpuflag(sse4) +%define MOVH movsd +%else +%define MOVH movlps +%endif + movsxdifnidn iq, id + mov lend, 32 << 3 + lea outq, [outq+iq*4] + mov tmpd, id + shl tmpd, 8 + add inq, tmpq + mov tmpd, 64 + sub tmpd, id + mov id, tmpd + + test id, 1 + jne .loop4 + test id, 2 + jne .loop8 + +align 16 +.loop16: + mov out0q, outq + mov out1q, 38*64*4 + add out1q, out0q + mov tmpd, lend + +.inner_loop16: + movaps m0, [inq] + movaps m1, [inq+lenq] + movaps m2, [inq+lenq*2] + movaps m3, [inq+3*32*2*4] + TRANSPOSE4x4PS 0, 1, 2, 3, 4 + movaps [out0q], m0 + movaps [out1q], m1 + movaps [out0q+lenq], m2 + movaps [out1q+lenq], m3 + lea out0q, [out0q+lenq*2] + lea out1q, [out1q+lenq*2] + add inq, mmsize + sub tmpd, mmsize + jg .inner_loop16 + add outq, 16 + add inq, 3*32*2*4 + sub id, 4 + jg .loop16 + RET + +align 16 +.loop8: + mov out0q, outq + mov out1q, 38*64*4 + add out1q, out0q + mov tmpd, lend + +.inner_loop8: + movaps m0, [inq] + movaps m1, [inq+lenq] + SBUTTERFLYPS 0, 1, 2 + SBUTTERFLYPD 0, 1, 2 + MOVH [out0q], m0 + MOVH [out1q], m1 + movhps [out0q+lenq], m0 + movhps [out1q+lenq], m1 + lea out0q, [out0q+lenq*2] + lea out1q, [out1q+lenq*2] + add inq, mmsize + sub tmpd, mmsize + jg .inner_loop8 + add outq, 8 + add inq, lenq + sub id, 2 + jg .loop16 + RET + +align 16 +.loop4: + mov out0q, outq + mov out1q, 38*64*4 + add out1q, out0q + mov tmpd, lend + +.inner_loop4: + movaps m0, [inq] + movss [out0q], m0 +%if cpuflag(sse4) + extractps [out1q], m0, 1 + extractps [out0q+lenq], m0, 2 + extractps [out1q+lenq], m0, 3 +%else + movhlps m1, m0 + movss [out0q+lenq], m1 + shufps m0, m0, 0xb1 + movss [out1q], m0 + movhlps m1, m0 + movss [out1q+lenq], m1 +%endif + lea out0q, [out0q+lenq*2] + lea out1q, [out1q+lenq*2] + add inq, mmsize + sub tmpd, mmsize + jg .inner_loop4 + add outq, 4 + sub id, 1 + test id, 2 + jne .loop8 + cmp id, 4 + jge .loop16 + RET +%endmacro + +INIT_XMM sse +HYBRID_SYNTHESIS_DEINT +INIT_XMM sse4 +HYBRID_SYNTHESIS_DEINT + +;******************************************************************* +;void ff_ps_hybrid_analysis_(float (*out)[2], float (*in)[2], +; const float (*filter)[8][2], +; ptrdiff_t stride, int n); +;******************************************************************* +%macro PS_HYBRID_ANALYSIS_LOOP 3 + movu %1, [inq+mmsize*%3] + movu m1, [inq+mmsize*(5-%3)+8] +%if cpuflag(sse3) + pshufd %2, %1, q2301 + pshufd m4, m1, q0123 + pshufd m1, m1, q1032 + pshufd m2, [filterq+nq+mmsize*%3], q2301 + addsubps %2, m4 + addsubps %1, m1 +%else + mova m2, [filterq+nq+mmsize*%3] + mova %2, %1 + mova m4, m1 + shufps %2, %2, q2301 + shufps m4, m4, q0123 + shufps m1, m1, q1032 + shufps m2, m2, q2301 + xorps m4, m7 + xorps m1, m7 + subps %2, m4 + subps %1, m1 +%endif + mulps %2, m2 + mulps %1, m2 +%if %3 + addps m3, %2 + addps m0, %1 +%endif +%endmacro + +%macro PS_HYBRID_ANALYSIS 0 +cglobal ps_hybrid_analysis, 5, 5, 8, out, in, filter, stride, n +%if cpuflag(sse3) +%define MOVH movsd +%else +%define MOVH movlps +%endif + shl strideq, 3 + shl nd, 6 + add filterq, nq + neg nq + mova m7, [ps_p1m1p1m1] + +align 16 +.loop: + PS_HYBRID_ANALYSIS_LOOP m0, m3, 0 + PS_HYBRID_ANALYSIS_LOOP m5, m6, 1 + PS_HYBRID_ANALYSIS_LOOP m5, m6, 2 + +%if cpuflag(sse3) + pshufd m3, m3, q2301 + xorps m0, m7 + hsubps m3, m0 + pshufd m1, m3, q0020 + pshufd m3, m3, q0031 + addps m1, m3 + movsd m2, [inq+6*8] +%else + mova m1, m3 + mova m2, m0 + shufps m1, m1, q2301 + shufps m2, m2, q2301 + subps m1, m3 + addps m2, m0 + unpcklps m3, m1, m2 + unpckhps m1, m2 + addps m1, m3 + movu m2, [inq+6*8] ; faster than movlps and no risk of overread +%endif + movss m3, [filterq+nq+8*6] + SPLATD m3 + mulps m2, m3 + addps m1, m2 + MOVH [outq], m1 + add outq, strideq + add nq, 64 + jl .loop + REP_RET +%endmacro + +INIT_XMM sse +PS_HYBRID_ANALYSIS +INIT_XMM sse3 +PS_HYBRID_ANALYSIS diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp.h new file mode 100644 index 000000000..917ac5303 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AACPSDSP_H +#define AVCODEC_AACPSDSP_H + +#include + +#include "aac_defines.h" + +#define PS_QMF_TIME_SLOTS 32 +#define PS_AP_LINKS 3 +#define PS_MAX_AP_DELAY 5 + +typedef struct PSDSPContext { + void (*add_squares)(INTFLOAT *dst, const INTFLOAT (*src)[2], int n); + void (*mul_pair_single)(INTFLOAT (*dst)[2], INTFLOAT (*src0)[2], INTFLOAT *src1, + int n); + void (*hybrid_analysis)(INTFLOAT (*out)[2], INTFLOAT (*in)[2], + const INTFLOAT (*filter)[8][2], + ptrdiff_t stride, int n); + void (*hybrid_analysis_ileave)(INTFLOAT (*out)[32][2], INTFLOAT L[2][38][64], + int i, int len); + void (*hybrid_synthesis_deint)(INTFLOAT out[2][38][64], INTFLOAT (*in)[32][2], + int i, int len); + void (*decorrelate)(INTFLOAT (*out)[2], INTFLOAT (*delay)[2], + INTFLOAT (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2], + const INTFLOAT phi_fract[2], const INTFLOAT (*Q_fract)[2], + const INTFLOAT *transient_gain, + INTFLOAT g_decay_slope, + int len); + void (*stereo_interpolate[2])(INTFLOAT (*l)[2], INTFLOAT (*r)[2], + INTFLOAT h[2][4], INTFLOAT h_step[2][4], + int len); +} PSDSPContext; + +void AAC_RENAME(ff_psdsp_init)(PSDSPContext *s); +void ff_psdsp_init_arm(PSDSPContext *s); +void ff_psdsp_init_aarch64(PSDSPContext *s); +void ff_psdsp_init_mips(PSDSPContext *s); +void ff_psdsp_init_x86(PSDSPContext *s); + +#endif /* AVCODEC_AACPSDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_fixed.c new file mode 100644 index 000000000..241329511 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_fixed.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 1 + +#include "aacpsdsp_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_float.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_float.c new file mode 100644 index 000000000..99aa650ac --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_float.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 0 + +#include "aacpsdsp_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_init.c new file mode 100644 index 000000000..21f00efa2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_init.c @@ -0,0 +1,72 @@ +/* + * SIMD optimized MPEG-4 Parametric Stereo decoding functions + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" + +#include "libavutil/x86/cpu.h" +#include "libavutil/attributes.h" +#include "libavcodec/aacpsdsp.h" + +void ff_ps_add_squares_sse (float *dst, const float (*src)[2], int n); +void ff_ps_add_squares_sse3 (float *dst, const float (*src)[2], int n); +void ff_ps_mul_pair_single_sse (float (*dst)[2], float (*src0)[2], + float *src1, int n); +void ff_ps_hybrid_analysis_sse (float (*out)[2], float (*in)[2], + const float (*filter)[8][2], + ptrdiff_t stride, int n); +void ff_ps_hybrid_analysis_sse3(float (*out)[2], float (*in)[2], + const float (*filter)[8][2], + ptrdiff_t stride, int n); +void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len); +void ff_ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len); +void ff_ps_hybrid_synthesis_deint_sse(float out[2][38][64], float (*in)[32][2], + int i, int len); +void ff_ps_hybrid_synthesis_deint_sse4(float out[2][38][64], float (*in)[32][2], + int i, int len); +void ff_ps_hybrid_analysis_ileave_sse(float (*out)[32][2], float L[2][38][64], + int i, int len); + +av_cold void ff_psdsp_init_x86(PSDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + s->add_squares = ff_ps_add_squares_sse; + s->mul_pair_single = ff_ps_mul_pair_single_sse; + s->hybrid_analysis_ileave = ff_ps_hybrid_analysis_ileave_sse; + s->hybrid_synthesis_deint = ff_ps_hybrid_synthesis_deint_sse; + s->hybrid_analysis = ff_ps_hybrid_analysis_sse; + } + if (EXTERNAL_SSE3(cpu_flags)) { + s->add_squares = ff_ps_add_squares_sse3; + s->stereo_interpolate[0] = ff_ps_stereo_interpolate_sse3; + s->stereo_interpolate[1] = ff_ps_stereo_interpolate_ipdopd_sse3; + s->hybrid_analysis = ff_ps_hybrid_analysis_sse3; + } + if (EXTERNAL_SSE4(cpu_flags)) { + s->hybrid_synthesis_deint = ff_ps_hybrid_synthesis_deint_sse4; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_template.c new file mode 100644 index 000000000..eef8adc7e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsdsp_template.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Note: Rounding-to-nearest used unless otherwise stated + * + */ +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "aacpsdsp.h" + +static void ps_add_squares_c(INTFLOAT *dst, const INTFLOAT (*src)[2], int n) +{ + int i; + for (i = 0; i < n; i++) + dst[i] += (UINTFLOAT)AAC_MADD28(src[i][0], src[i][0], src[i][1], src[i][1]); +} + +static void ps_mul_pair_single_c(INTFLOAT (*dst)[2], INTFLOAT (*src0)[2], INTFLOAT *src1, + int n) +{ + int i; + for (i = 0; i < n; i++) { + dst[i][0] = AAC_MUL16(src0[i][0], src1[i]); + dst[i][1] = AAC_MUL16(src0[i][1], src1[i]); + } +} + +static void ps_hybrid_analysis_c(INTFLOAT (*out)[2], INTFLOAT (*in)[2], + const INTFLOAT (*filter)[8][2], + ptrdiff_t stride, int n) +{ + int i, j; + + for (i = 0; i < n; i++) { + INT64FLOAT sum_re = (INT64FLOAT)filter[i][6][0] * in[6][0]; + INT64FLOAT sum_im = (INT64FLOAT)filter[i][6][0] * in[6][1]; + + for (j = 0; j < 6; j++) { + INT64FLOAT in0_re = in[j][0]; + INT64FLOAT in0_im = in[j][1]; + INT64FLOAT in1_re = in[12-j][0]; + INT64FLOAT in1_im = in[12-j][1]; + sum_re += (INT64FLOAT)filter[i][j][0] * (in0_re + in1_re) - + (INT64FLOAT)filter[i][j][1] * (in0_im - in1_im); + sum_im += (INT64FLOAT)filter[i][j][0] * (in0_im + in1_im) + + (INT64FLOAT)filter[i][j][1] * (in0_re - in1_re); + } +#if USE_FIXED + out[i * stride][0] = (int)((sum_re + 0x40000000) >> 31); + out[i * stride][1] = (int)((sum_im + 0x40000000) >> 31); +#else + out[i * stride][0] = sum_re; + out[i * stride][1] = sum_im; +#endif /* USE_FIXED */ + } +} + +static void ps_hybrid_analysis_ileave_c(INTFLOAT (*out)[32][2], INTFLOAT L[2][38][64], + int i, int len) +{ + int j; + + for (; i < 64; i++) { + for (j = 0; j < len; j++) { + out[i][j][0] = L[0][j][i]; + out[i][j][1] = L[1][j][i]; + } + } +} + +static void ps_hybrid_synthesis_deint_c(INTFLOAT out[2][38][64], + INTFLOAT (*in)[32][2], + int i, int len) +{ + int n; + + for (; i < 64; i++) { + for (n = 0; n < len; n++) { + out[0][n][i] = in[i][n][0]; + out[1][n][i] = in[i][n][1]; + } + } +} + +static void ps_decorrelate_c(INTFLOAT (*out)[2], INTFLOAT (*delay)[2], + INTFLOAT (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2], + const INTFLOAT phi_fract[2], const INTFLOAT (*Q_fract)[2], + const INTFLOAT *transient_gain, + INTFLOAT g_decay_slope, + int len) +{ + static const INTFLOAT a[] = { Q31(0.65143905753106f), + Q31(0.56471812200776f), + Q31(0.48954165955695f) }; + INTFLOAT ag[PS_AP_LINKS]; + int m, n; + + for (m = 0; m < PS_AP_LINKS; m++) + ag[m] = AAC_MUL30(a[m], g_decay_slope); + + for (n = 0; n < len; n++) { + INTFLOAT in_re = AAC_MSUB30(delay[n][0], phi_fract[0], delay[n][1], phi_fract[1]); + INTFLOAT in_im = AAC_MADD30(delay[n][0], phi_fract[1], delay[n][1], phi_fract[0]); + for (m = 0; m < PS_AP_LINKS; m++) { + INTFLOAT a_re = AAC_MUL31(ag[m], in_re); + INTFLOAT a_im = AAC_MUL31(ag[m], in_im); + INTFLOAT link_delay_re = ap_delay[m][n+2-m][0]; + INTFLOAT link_delay_im = ap_delay[m][n+2-m][1]; + INTFLOAT fractional_delay_re = Q_fract[m][0]; + INTFLOAT fractional_delay_im = Q_fract[m][1]; + INTFLOAT apd_re = in_re; + INTFLOAT apd_im = in_im; + in_re = AAC_MSUB30(link_delay_re, fractional_delay_re, + link_delay_im, fractional_delay_im); + in_re -= (UINTFLOAT)a_re; + in_im = AAC_MADD30(link_delay_re, fractional_delay_im, + link_delay_im, fractional_delay_re); + in_im -= (UINTFLOAT)a_im; + ap_delay[m][n+5][0] = apd_re + (UINTFLOAT)AAC_MUL31(ag[m], in_re); + ap_delay[m][n+5][1] = apd_im + (UINTFLOAT)AAC_MUL31(ag[m], in_im); + } + out[n][0] = AAC_MUL16(transient_gain[n], in_re); + out[n][1] = AAC_MUL16(transient_gain[n], in_im); + } +} + +static void ps_stereo_interpolate_c(INTFLOAT (*l)[2], INTFLOAT (*r)[2], + INTFLOAT h[2][4], INTFLOAT h_step[2][4], + int len) +{ + INTFLOAT h0 = h[0][0]; + INTFLOAT h1 = h[0][1]; + INTFLOAT h2 = h[0][2]; + INTFLOAT h3 = h[0][3]; + UINTFLOAT hs0 = h_step[0][0]; + UINTFLOAT hs1 = h_step[0][1]; + UINTFLOAT hs2 = h_step[0][2]; + UINTFLOAT hs3 = h_step[0][3]; + int n; + + for (n = 0; n < len; n++) { + //l is s, r is d + INTFLOAT l_re = l[n][0]; + INTFLOAT l_im = l[n][1]; + INTFLOAT r_re = r[n][0]; + INTFLOAT r_im = r[n][1]; + h0 += hs0; + h1 += hs1; + h2 += hs2; + h3 += hs3; + l[n][0] = AAC_MADD30(h0, l_re, h2, r_re); + l[n][1] = AAC_MADD30(h0, l_im, h2, r_im); + r[n][0] = AAC_MADD30(h1, l_re, h3, r_re); + r[n][1] = AAC_MADD30(h1, l_im, h3, r_im); + } +} + +static void ps_stereo_interpolate_ipdopd_c(INTFLOAT (*l)[2], INTFLOAT (*r)[2], + INTFLOAT h[2][4], INTFLOAT h_step[2][4], + int len) +{ + INTFLOAT h00 = h[0][0], h10 = h[1][0]; + INTFLOAT h01 = h[0][1], h11 = h[1][1]; + INTFLOAT h02 = h[0][2], h12 = h[1][2]; + INTFLOAT h03 = h[0][3], h13 = h[1][3]; + UINTFLOAT hs00 = h_step[0][0], hs10 = h_step[1][0]; + UINTFLOAT hs01 = h_step[0][1], hs11 = h_step[1][1]; + UINTFLOAT hs02 = h_step[0][2], hs12 = h_step[1][2]; + UINTFLOAT hs03 = h_step[0][3], hs13 = h_step[1][3]; + int n; + + for (n = 0; n < len; n++) { + //l is s, r is d + INTFLOAT l_re = l[n][0]; + INTFLOAT l_im = l[n][1]; + INTFLOAT r_re = r[n][0]; + INTFLOAT r_im = r[n][1]; + h00 += hs00; + h01 += hs01; + h02 += hs02; + h03 += hs03; + h10 += hs10; + h11 += hs11; + h12 += hs12; + h13 += hs13; + + l[n][0] = AAC_MSUB30_V8(h00, l_re, h02, r_re, h10, l_im, h12, r_im); + l[n][1] = AAC_MADD30_V8(h00, l_im, h02, r_im, h10, l_re, h12, r_re); + r[n][0] = AAC_MSUB30_V8(h01, l_re, h03, r_re, h11, l_im, h13, r_im); + r[n][1] = AAC_MADD30_V8(h01, l_im, h03, r_im, h11, l_re, h13, r_re); + } +} + +av_cold void AAC_RENAME(ff_psdsp_init)(PSDSPContext *s) +{ + s->add_squares = ps_add_squares_c; + s->mul_pair_single = ps_mul_pair_single_c; + s->hybrid_analysis = ps_hybrid_analysis_c; + s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_c; + s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_c; + s->decorrelate = ps_decorrelate_c; + s->stereo_interpolate[0] = ps_stereo_interpolate_c; + s->stereo_interpolate[1] = ps_stereo_interpolate_ipdopd_c; + +#if !USE_FIXED + if (ARCH_ARM) + ff_psdsp_init_arm(s); + if (ARCH_AARCH64) + ff_psdsp_init_aarch64(s); + if (ARCH_MIPS) + ff_psdsp_init_mips(s); + if (ARCH_X86) + ff_psdsp_init_x86(s); +#endif /* !USE_FIXED */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsy.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsy.c new file mode 100644 index 000000000..fca692cb1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacpsy.c @@ -0,0 +1,1025 @@ +/* + * AAC encoder psychoacoustic model + * Copyright (C) 2008 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC encoder psychoacoustic model + */ + +#include "libavutil/attributes.h" +#include "libavutil/ffmath.h" + +#include "avcodec.h" +#include "aactab.h" +#include "psymodel.h" + +/*********************************** + * TODOs: + * try other bitrate controlling mechanism (maybe use ratecontrol.c?) + * control quality for quality-based output + **********************************/ + +/** + * constants for 3GPP AAC psychoacoustic model + * @{ + */ +#define PSY_3GPP_THR_SPREAD_HI 1.5f // spreading factor for low-to-hi threshold spreading (15 dB/Bark) +#define PSY_3GPP_THR_SPREAD_LOW 3.0f // spreading factor for hi-to-low threshold spreading (30 dB/Bark) +/* spreading factor for low-to-hi energy spreading, long block, > 22kbps/channel (20dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_HI_L1 2.0f +/* spreading factor for low-to-hi energy spreading, long block, <= 22kbps/channel (15dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_HI_L2 1.5f +/* spreading factor for low-to-hi energy spreading, short block (15 dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_HI_S 1.5f +/* spreading factor for hi-to-low energy spreading, long block (30dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_LOW_L 3.0f +/* spreading factor for hi-to-low energy spreading, short block (20dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_LOW_S 2.0f + +#define PSY_3GPP_RPEMIN 0.01f +#define PSY_3GPP_RPELEV 2.0f + +#define PSY_3GPP_C1 3.0f /* log2(8) */ +#define PSY_3GPP_C2 1.3219281f /* log2(2.5) */ +#define PSY_3GPP_C3 0.55935729f /* 1 - C2 / C1 */ + +#define PSY_SNR_1DB 7.9432821e-1f /* -1dB */ +#define PSY_SNR_25DB 3.1622776e-3f /* -25dB */ + +#define PSY_3GPP_SAVE_SLOPE_L -0.46666667f +#define PSY_3GPP_SAVE_SLOPE_S -0.36363637f +#define PSY_3GPP_SAVE_ADD_L -0.84285712f +#define PSY_3GPP_SAVE_ADD_S -0.75f +#define PSY_3GPP_SPEND_SLOPE_L 0.66666669f +#define PSY_3GPP_SPEND_SLOPE_S 0.81818181f +#define PSY_3GPP_SPEND_ADD_L -0.35f +#define PSY_3GPP_SPEND_ADD_S -0.26111111f +#define PSY_3GPP_CLIP_LO_L 0.2f +#define PSY_3GPP_CLIP_LO_S 0.2f +#define PSY_3GPP_CLIP_HI_L 0.95f +#define PSY_3GPP_CLIP_HI_S 0.75f + +#define PSY_3GPP_AH_THR_LONG 0.5f +#define PSY_3GPP_AH_THR_SHORT 0.63f + +#define PSY_PE_FORGET_SLOPE 511 + +enum { + PSY_3GPP_AH_NONE, + PSY_3GPP_AH_INACTIVE, + PSY_3GPP_AH_ACTIVE +}; + +#define PSY_3GPP_BITS_TO_PE(bits) ((bits) * 1.18f) +#define PSY_3GPP_PE_TO_BITS(bits) ((bits) / 1.18f) + +/* LAME psy model constants */ +#define PSY_LAME_FIR_LEN 21 ///< LAME psy model FIR order +#define AAC_BLOCK_SIZE_LONG 1024 ///< long block size +#define AAC_BLOCK_SIZE_SHORT 128 ///< short block size +#define AAC_NUM_BLOCKS_SHORT 8 ///< number of blocks in a short sequence +#define PSY_LAME_NUM_SUBBLOCKS 3 ///< Number of sub-blocks in each short block + +/** + * @} + */ + +/** + * information for single band used by 3GPP TS26.403-inspired psychoacoustic model + */ +typedef struct AacPsyBand{ + float energy; ///< band energy + float thr; ///< energy threshold + float thr_quiet; ///< threshold in quiet + float nz_lines; ///< number of non-zero spectral lines + float active_lines; ///< number of active spectral lines + float pe; ///< perceptual entropy + float pe_const; ///< constant part of the PE calculation + float norm_fac; ///< normalization factor for linearization + int avoid_holes; ///< hole avoidance flag +}AacPsyBand; + +/** + * single/pair channel context for psychoacoustic model + */ +typedef struct AacPsyChannel{ + AacPsyBand band[128]; ///< bands information + AacPsyBand prev_band[128]; ///< bands information from the previous frame + + float win_energy; ///< sliding average of channel energy + float iir_state[2]; ///< hi-pass IIR filter state + uint8_t next_grouping; ///< stored grouping scheme for the next frame (in case of 8 short window sequence) + enum WindowSequence next_window_seq; ///< window sequence to be used in the next frame + /* LAME psy model specific members */ + float attack_threshold; ///< attack threshold for this channel + float prev_energy_subshort[AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS]; + int prev_attack; ///< attack value for the last short block in the previous sequence +}AacPsyChannel; + +/** + * psychoacoustic model frame type-dependent coefficients + */ +typedef struct AacPsyCoeffs{ + float ath; ///< absolute threshold of hearing per bands + float barks; ///< Bark value for each spectral band in long frame + float spread_low[2]; ///< spreading factor for low-to-high threshold spreading in long frame + float spread_hi [2]; ///< spreading factor for high-to-low threshold spreading in long frame + float min_snr; ///< minimal SNR +}AacPsyCoeffs; + +/** + * 3GPP TS26.403-inspired psychoacoustic model specific data + */ +typedef struct AacPsyContext{ + int chan_bitrate; ///< bitrate per channel + int frame_bits; ///< average bits per frame + int fill_level; ///< bit reservoir fill level + struct { + float min; ///< minimum allowed PE for bit factor calculation + float max; ///< maximum allowed PE for bit factor calculation + float previous; ///< allowed PE of the previous frame + float correction; ///< PE correction factor + } pe; + AacPsyCoeffs psy_coef[2][64]; + AacPsyChannel *ch; + float global_quality; ///< normalized global quality taken from avctx +}AacPsyContext; + +/** + * LAME psy model preset struct + */ +typedef struct PsyLamePreset { + int quality; ///< Quality to map the rest of the vaules to. + /* This is overloaded to be both kbps per channel in ABR mode, and + * requested quality in constant quality mode. + */ + float st_lrm; ///< short threshold for L, R, and M channels +} PsyLamePreset; + +/** + * LAME psy model preset table for ABR + */ +static const PsyLamePreset psy_abr_map[] = { +/* TODO: Tuning. These were taken from LAME. */ +/* kbps/ch st_lrm */ + { 8, 6.60}, + { 16, 6.60}, + { 24, 6.60}, + { 32, 6.60}, + { 40, 6.60}, + { 48, 6.60}, + { 56, 6.60}, + { 64, 6.40}, + { 80, 6.00}, + { 96, 5.60}, + {112, 5.20}, + {128, 5.20}, + {160, 5.20} +}; + +/** +* LAME psy model preset table for constant quality +*/ +static const PsyLamePreset psy_vbr_map[] = { +/* vbr_q st_lrm */ + { 0, 4.20}, + { 1, 4.20}, + { 2, 4.20}, + { 3, 4.20}, + { 4, 4.20}, + { 5, 4.20}, + { 6, 4.20}, + { 7, 4.20}, + { 8, 4.20}, + { 9, 4.20}, + {10, 4.20} +}; + +/** + * LAME psy model FIR coefficient table + */ +static const float psy_fir_coeffs[] = { + -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2, + -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2, + -5.52212e-17 * 2, -0.313819 * 2 +}; + +#if ARCH_MIPS +# include "mips/aacpsy_mips.h" +#endif /* ARCH_MIPS */ + +/** + * Calculate the ABR attack threshold from the above LAME psymodel table. + */ +static float lame_calc_attack_threshold(int bitrate) +{ + /* Assume max bitrate to start with */ + int lower_range = 12, upper_range = 12; + int lower_range_kbps = psy_abr_map[12].quality; + int upper_range_kbps = psy_abr_map[12].quality; + int i; + + /* Determine which bitrates the value specified falls between. + * If the loop ends without breaking our above assumption of 320kbps was correct. + */ + for (i = 1; i < 13; i++) { + if (FFMAX(bitrate, psy_abr_map[i].quality) != bitrate) { + upper_range = i; + upper_range_kbps = psy_abr_map[i ].quality; + lower_range = i - 1; + lower_range_kbps = psy_abr_map[i - 1].quality; + break; /* Upper range found */ + } + } + + /* Determine which range the value specified is closer to */ + if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) + return psy_abr_map[lower_range].st_lrm; + return psy_abr_map[upper_range].st_lrm; +} + +/** + * LAME psy model specific initialization + */ +static av_cold void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx) +{ + int i, j; + + for (i = 0; i < avctx->channels; i++) { + AacPsyChannel *pch = &ctx->ch[i]; + + if (avctx->flags & AV_CODEC_FLAG_QSCALE) + pch->attack_threshold = psy_vbr_map[avctx->global_quality / FF_QP2LAMBDA].st_lrm; + else + pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->channels / 1000); + + for (j = 0; j < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; j++) + pch->prev_energy_subshort[j] = 10.0f; + } +} + +/** + * Calculate Bark value for given line. + */ +static av_cold float calc_bark(float f) +{ + return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f)); +} + +#define ATH_ADD 4 +/** + * Calculate ATH value for given frequency. + * Borrowed from Lame. + */ +static av_cold float ath(float f, float add) +{ + f /= 1000.0f; + return 3.64 * pow(f, -0.8) + - 6.8 * exp(-0.6 * (f - 3.4) * (f - 3.4)) + + 6.0 * exp(-0.15 * (f - 8.7) * (f - 8.7)) + + (0.6 + 0.04 * add) * 0.001 * f * f * f * f; +} + +static av_cold int psy_3gpp_init(FFPsyContext *ctx) { + AacPsyContext *pctx; + float bark; + int i, j, g, start; + float prev, minscale, minath, minsnr, pe_min; + int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels); + + const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx); + const float num_bark = calc_bark((float)bandwidth); + + ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext)); + if (!ctx->model_priv_data) + return AVERROR(ENOMEM); + pctx = ctx->model_priv_data; + pctx->global_quality = (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) * 0.01f; + + if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) { + /* Use the target average bitrate to compute spread parameters */ + chan_bitrate = (int)(chan_bitrate / 120.0 * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120)); + } + + pctx->chan_bitrate = chan_bitrate; + pctx->frame_bits = FFMIN(2560, chan_bitrate * AAC_BLOCK_SIZE_LONG / ctx->avctx->sample_rate); + pctx->pe.min = 8.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f); + pctx->pe.max = 12.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f); + ctx->bitres.size = 6144 - pctx->frame_bits; + ctx->bitres.size -= ctx->bitres.size % 8; + pctx->fill_level = ctx->bitres.size; + minath = ath(3410 - 0.733 * ATH_ADD, ATH_ADD); + for (j = 0; j < 2; j++) { + AacPsyCoeffs *coeffs = pctx->psy_coef[j]; + const uint8_t *band_sizes = ctx->bands[j]; + float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f); + float avg_chan_bits = chan_bitrate * (j ? 128.0f : 1024.0f) / ctx->avctx->sample_rate; + /* reference encoder uses 2.4% here instead of 60% like the spec says */ + float bark_pe = 0.024f * PSY_3GPP_BITS_TO_PE(avg_chan_bits) / num_bark; + float en_spread_low = j ? PSY_3GPP_EN_SPREAD_LOW_S : PSY_3GPP_EN_SPREAD_LOW_L; + /* High energy spreading for long blocks <= 22kbps/channel and short blocks are the same. */ + float en_spread_hi = (j || (chan_bitrate <= 22.0f)) ? PSY_3GPP_EN_SPREAD_HI_S : PSY_3GPP_EN_SPREAD_HI_L1; + + i = 0; + prev = 0.0; + for (g = 0; g < ctx->num_bands[j]; g++) { + i += band_sizes[g]; + bark = calc_bark((i-1) * line_to_frequency); + coeffs[g].barks = (bark + prev) / 2.0; + prev = bark; + } + for (g = 0; g < ctx->num_bands[j] - 1; g++) { + AacPsyCoeffs *coeff = &coeffs[g]; + float bark_width = coeffs[g+1].barks - coeffs->barks; + coeff->spread_low[0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_LOW); + coeff->spread_hi [0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_HI); + coeff->spread_low[1] = ff_exp10(-bark_width * en_spread_low); + coeff->spread_hi [1] = ff_exp10(-bark_width * en_spread_hi); + pe_min = bark_pe * bark_width; + minsnr = exp2(pe_min / band_sizes[g]) - 1.5f; + coeff->min_snr = av_clipf(1.0f / minsnr, PSY_SNR_25DB, PSY_SNR_1DB); + } + start = 0; + for (g = 0; g < ctx->num_bands[j]; g++) { + minscale = ath(start * line_to_frequency, ATH_ADD); + for (i = 1; i < band_sizes[g]; i++) + minscale = FFMIN(minscale, ath((start + i) * line_to_frequency, ATH_ADD)); + coeffs[g].ath = minscale - minath; + start += band_sizes[g]; + } + } + + pctx->ch = av_mallocz_array(ctx->avctx->channels, sizeof(AacPsyChannel)); + if (!pctx->ch) { + av_freep(&ctx->model_priv_data); + return AVERROR(ENOMEM); + } + + lame_window_init(pctx, ctx->avctx); + + return 0; +} + +/** + * IIR filter used in block switching decision + */ +static float iir_filter(int in, float state[2]) +{ + float ret; + + ret = 0.7548f * (in - state[0]) + 0.5095f * state[1]; + state[0] = in; + state[1] = ret; + return ret; +} + +/** + * window grouping information stored as bits (0 - new group, 1 - group continues) + */ +static const uint8_t window_grouping[9] = { + 0xB6, 0x6C, 0xD8, 0xB2, 0x66, 0xC6, 0x96, 0x36, 0x36 +}; + +/** + * Tell encoder which window types to use. + * @see 3GPP TS26.403 5.4.1 "Blockswitching" + */ +static av_unused FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx, + const int16_t *audio, + const int16_t *la, + int channel, int prev_type) +{ + int i, j; + int br = ((AacPsyContext*)ctx->model_priv_data)->chan_bitrate; + int attack_ratio = br <= 16000 ? 18 : 10; + AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; + AacPsyChannel *pch = &pctx->ch[channel]; + uint8_t grouping = 0; + int next_type = pch->next_window_seq; + FFPsyWindowInfo wi = { { 0 } }; + + if (la) { + float s[8], v; + int switch_to_eight = 0; + float sum = 0.0, sum2 = 0.0; + int attack_n = 0; + int stay_short = 0; + for (i = 0; i < 8; i++) { + for (j = 0; j < 128; j++) { + v = iir_filter(la[i*128+j], pch->iir_state); + sum += v*v; + } + s[i] = sum; + sum2 += sum; + } + for (i = 0; i < 8; i++) { + if (s[i] > pch->win_energy * attack_ratio) { + attack_n = i + 1; + switch_to_eight = 1; + break; + } + } + pch->win_energy = pch->win_energy*7/8 + sum2/64; + + wi.window_type[1] = prev_type; + switch (prev_type) { + case ONLY_LONG_SEQUENCE: + wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; + next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE; + break; + case LONG_START_SEQUENCE: + wi.window_type[0] = EIGHT_SHORT_SEQUENCE; + grouping = pch->next_grouping; + next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; + break; + case LONG_STOP_SEQUENCE: + wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; + next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE; + break; + case EIGHT_SHORT_SEQUENCE: + stay_short = next_type == EIGHT_SHORT_SEQUENCE || switch_to_eight; + wi.window_type[0] = stay_short ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; + grouping = next_type == EIGHT_SHORT_SEQUENCE ? pch->next_grouping : 0; + next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; + break; + } + + pch->next_grouping = window_grouping[attack_n]; + pch->next_window_seq = next_type; + } else { + for (i = 0; i < 3; i++) + wi.window_type[i] = prev_type; + grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0; + } + + wi.window_shape = 1; + if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) { + wi.num_windows = 1; + wi.grouping[0] = 1; + } else { + int lastgrp = 0; + wi.num_windows = 8; + for (i = 0; i < 8; i++) { + if (!((grouping >> i) & 1)) + lastgrp = i; + wi.grouping[lastgrp]++; + } + } + + return wi; +} + +/* 5.6.1.2 "Calculation of Bit Demand" */ +static int calc_bit_demand(AacPsyContext *ctx, float pe, int bits, int size, + int short_window) +{ + const float bitsave_slope = short_window ? PSY_3GPP_SAVE_SLOPE_S : PSY_3GPP_SAVE_SLOPE_L; + const float bitsave_add = short_window ? PSY_3GPP_SAVE_ADD_S : PSY_3GPP_SAVE_ADD_L; + const float bitspend_slope = short_window ? PSY_3GPP_SPEND_SLOPE_S : PSY_3GPP_SPEND_SLOPE_L; + const float bitspend_add = short_window ? PSY_3GPP_SPEND_ADD_S : PSY_3GPP_SPEND_ADD_L; + const float clip_low = short_window ? PSY_3GPP_CLIP_LO_S : PSY_3GPP_CLIP_LO_L; + const float clip_high = short_window ? PSY_3GPP_CLIP_HI_S : PSY_3GPP_CLIP_HI_L; + float clipped_pe, bit_save, bit_spend, bit_factor, fill_level, forgetful_min_pe; + + ctx->fill_level += ctx->frame_bits - bits; + ctx->fill_level = av_clip(ctx->fill_level, 0, size); + fill_level = av_clipf((float)ctx->fill_level / size, clip_low, clip_high); + clipped_pe = av_clipf(pe, ctx->pe.min, ctx->pe.max); + bit_save = (fill_level + bitsave_add) * bitsave_slope; + assert(bit_save <= 0.3f && bit_save >= -0.05000001f); + bit_spend = (fill_level + bitspend_add) * bitspend_slope; + assert(bit_spend <= 0.5f && bit_spend >= -0.1f); + /* The bit factor graph in the spec is obviously incorrect. + * bit_spend + ((bit_spend - bit_spend))... + * The reference encoder subtracts everything from 1, but also seems incorrect. + * 1 - bit_save + ((bit_spend + bit_save))... + * Hopefully below is correct. + */ + bit_factor = 1.0f - bit_save + ((bit_spend - bit_save) / (ctx->pe.max - ctx->pe.min)) * (clipped_pe - ctx->pe.min); + /* NOTE: The reference encoder attempts to center pe max/min around the current pe. + * Here we do that by slowly forgetting pe.min when pe stays in a range that makes + * it unlikely (ie: above the mean) + */ + ctx->pe.max = FFMAX(pe, ctx->pe.max); + forgetful_min_pe = ((ctx->pe.min * PSY_PE_FORGET_SLOPE) + + FFMAX(ctx->pe.min, pe * (pe / ctx->pe.max))) / (PSY_PE_FORGET_SLOPE + 1); + ctx->pe.min = FFMIN(pe, forgetful_min_pe); + + /* NOTE: allocate a minimum of 1/8th average frame bits, to avoid + * reservoir starvation from producing zero-bit frames + */ + return FFMIN( + ctx->frame_bits * bit_factor, + FFMAX(ctx->frame_bits + size - bits, ctx->frame_bits / 8)); +} + +static float calc_pe_3gpp(AacPsyBand *band) +{ + float pe, a; + + band->pe = 0.0f; + band->pe_const = 0.0f; + band->active_lines = 0.0f; + if (band->energy > band->thr) { + a = log2f(band->energy); + pe = a - log2f(band->thr); + band->active_lines = band->nz_lines; + if (pe < PSY_3GPP_C1) { + pe = pe * PSY_3GPP_C3 + PSY_3GPP_C2; + a = a * PSY_3GPP_C3 + PSY_3GPP_C2; + band->active_lines *= PSY_3GPP_C3; + } + band->pe = pe * band->nz_lines; + band->pe_const = a * band->nz_lines; + } + + return band->pe; +} + +static float calc_reduction_3gpp(float a, float desired_pe, float pe, + float active_lines) +{ + float thr_avg, reduction; + + if(active_lines == 0.0) + return 0; + + thr_avg = exp2f((a - pe) / (4.0f * active_lines)); + reduction = exp2f((a - desired_pe) / (4.0f * active_lines)) - thr_avg; + + return FFMAX(reduction, 0.0f); +} + +static float calc_reduced_thr_3gpp(AacPsyBand *band, float min_snr, + float reduction) +{ + float thr = band->thr; + + if (band->energy > thr) { + thr = sqrtf(thr); + thr = sqrtf(thr) + reduction; + thr *= thr; + thr *= thr; + + /* This deviates from the 3GPP spec to match the reference encoder. + * It performs min(thr_reduced, max(thr, energy/min_snr)) only for bands + * that have hole avoidance on (active or inactive). It always reduces the + * threshold of bands with hole avoidance off. + */ + if (thr > band->energy * min_snr && band->avoid_holes != PSY_3GPP_AH_NONE) { + thr = FFMAX(band->thr, band->energy * min_snr); + band->avoid_holes = PSY_3GPP_AH_ACTIVE; + } + } + + return thr; +} + +#ifndef calc_thr_3gpp +static void calc_thr_3gpp(const FFPsyWindowInfo *wi, const int num_bands, AacPsyChannel *pch, + const uint8_t *band_sizes, const float *coefs, const int cutoff) +{ + int i, w, g; + int start = 0, wstart = 0; + for (w = 0; w < wi->num_windows*16; w += 16) { + wstart = 0; + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + float form_factor = 0.0f; + float Temp; + band->energy = 0.0f; + if (wstart < cutoff) { + for (i = 0; i < band_sizes[g]; i++) { + band->energy += coefs[start+i] * coefs[start+i]; + form_factor += sqrtf(fabs(coefs[start+i])); + } + } + Temp = band->energy > 0 ? sqrtf((float)band_sizes[g] / band->energy) : 0; + band->thr = band->energy * 0.001258925f; + band->nz_lines = form_factor * sqrtf(Temp); + + start += band_sizes[g]; + wstart += band_sizes[g]; + } + } +} +#endif /* calc_thr_3gpp */ + +#ifndef psy_hp_filter +static void psy_hp_filter(const float *firbuf, float *hpfsmpl, const float *psy_fir_coeffs) +{ + int i, j; + for (i = 0; i < AAC_BLOCK_SIZE_LONG; i++) { + float sum1, sum2; + sum1 = firbuf[i + (PSY_LAME_FIR_LEN - 1) / 2]; + sum2 = 0.0; + for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) { + sum1 += psy_fir_coeffs[j] * (firbuf[i + j] + firbuf[i + PSY_LAME_FIR_LEN - j]); + sum2 += psy_fir_coeffs[j + 1] * (firbuf[i + j + 1] + firbuf[i + PSY_LAME_FIR_LEN - j - 1]); + } + /* NOTE: The LAME psymodel expects it's input in the range -32768 to 32768. + * Tuning this for normalized floats would be difficult. */ + hpfsmpl[i] = (sum1 + sum2) * 32768.0f; + } +} +#endif /* psy_hp_filter */ + +/** + * Calculate band thresholds as suggested in 3GPP TS26.403 + */ +static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel, + const float *coefs, const FFPsyWindowInfo *wi) +{ + AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; + AacPsyChannel *pch = &pctx->ch[channel]; + int i, w, g; + float desired_bits, desired_pe, delta_pe, reduction= NAN, spread_en[128] = {0}; + float a = 0.0f, active_lines = 0.0f, norm_fac = 0.0f; + float pe = pctx->chan_bitrate > 32000 ? 0.0f : FFMAX(50.0f, 100.0f - pctx->chan_bitrate * 100.0f / 32000.0f); + const int num_bands = ctx->num_bands[wi->num_windows == 8]; + const uint8_t *band_sizes = ctx->bands[wi->num_windows == 8]; + AacPsyCoeffs *coeffs = pctx->psy_coef[wi->num_windows == 8]; + const float avoid_hole_thr = wi->num_windows == 8 ? PSY_3GPP_AH_THR_SHORT : PSY_3GPP_AH_THR_LONG; + const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx); + const int cutoff = bandwidth * 2048 / wi->num_windows / ctx->avctx->sample_rate; + + //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation" + calc_thr_3gpp(wi, num_bands, pch, band_sizes, coefs, cutoff); + + //modify thresholds and energies - spread, threshold in quiet, pre-echo control + for (w = 0; w < wi->num_windows*16; w += 16) { + AacPsyBand *bands = &pch->band[w]; + + /* 5.4.2.3 "Spreading" & 5.4.3 "Spread Energy Calculation" */ + spread_en[0] = bands[0].energy; + for (g = 1; g < num_bands; g++) { + bands[g].thr = FFMAX(bands[g].thr, bands[g-1].thr * coeffs[g].spread_hi[0]); + spread_en[w+g] = FFMAX(bands[g].energy, spread_en[w+g-1] * coeffs[g].spread_hi[1]); + } + for (g = num_bands - 2; g >= 0; g--) { + bands[g].thr = FFMAX(bands[g].thr, bands[g+1].thr * coeffs[g].spread_low[0]); + spread_en[w+g] = FFMAX(spread_en[w+g], spread_en[w+g+1] * coeffs[g].spread_low[1]); + } + //5.4.2.4 "Threshold in quiet" + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &bands[g]; + + band->thr_quiet = band->thr = FFMAX(band->thr, coeffs[g].ath); + //5.4.2.5 "Pre-echo control" + if (!(wi->window_type[0] == LONG_STOP_SEQUENCE || (!w && wi->window_type[1] == LONG_START_SEQUENCE))) + band->thr = FFMAX(PSY_3GPP_RPEMIN*band->thr, FFMIN(band->thr, + PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet)); + + /* 5.6.1.3.1 "Preparatory steps of the perceptual entropy calculation" */ + pe += calc_pe_3gpp(band); + a += band->pe_const; + active_lines += band->active_lines; + + /* 5.6.1.3.3 "Selection of the bands for avoidance of holes" */ + if (spread_en[w+g] * avoid_hole_thr > band->energy || coeffs[g].min_snr > 1.0f) + band->avoid_holes = PSY_3GPP_AH_NONE; + else + band->avoid_holes = PSY_3GPP_AH_INACTIVE; + } + } + + /* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */ + ctx->ch[channel].entropy = pe; + if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) { + /* (2.5 * 120) achieves almost transparent rate, and we want to give + * ample room downwards, so we make that equivalent to QSCALE=2.4 + */ + desired_pe = pe * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) / (2 * 2.5f * 120.0f); + desired_bits = FFMIN(2560, PSY_3GPP_PE_TO_BITS(desired_pe)); + desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); // reflect clipping + + /* PE slope smoothing */ + if (ctx->bitres.bits > 0) { + desired_bits = FFMIN(2560, PSY_3GPP_PE_TO_BITS(desired_pe)); + desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); // reflect clipping + } + + pctx->pe.max = FFMAX(pe, pctx->pe.max); + pctx->pe.min = FFMIN(pe, pctx->pe.min); + } else { + desired_bits = calc_bit_demand(pctx, pe, ctx->bitres.bits, ctx->bitres.size, wi->num_windows == 8); + desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); + + /* NOTE: PE correction is kept simple. During initial testing it had very + * little effect on the final bitrate. Probably a good idea to come + * back and do more testing later. + */ + if (ctx->bitres.bits > 0) + desired_pe *= av_clipf(pctx->pe.previous / PSY_3GPP_BITS_TO_PE(ctx->bitres.bits), + 0.85f, 1.15f); + } + pctx->pe.previous = PSY_3GPP_BITS_TO_PE(desired_bits); + ctx->bitres.alloc = desired_bits; + + if (desired_pe < pe) { + /* 5.6.1.3.4 "First Estimation of the reduction value" */ + for (w = 0; w < wi->num_windows*16; w += 16) { + reduction = calc_reduction_3gpp(a, desired_pe, pe, active_lines); + pe = 0.0f; + a = 0.0f; + active_lines = 0.0f; + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction); + /* recalculate PE */ + pe += calc_pe_3gpp(band); + a += band->pe_const; + active_lines += band->active_lines; + } + } + + /* 5.6.1.3.5 "Second Estimation of the reduction value" */ + for (i = 0; i < 2; i++) { + float pe_no_ah = 0.0f, desired_pe_no_ah; + active_lines = a = 0.0f; + for (w = 0; w < wi->num_windows*16; w += 16) { + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + if (band->avoid_holes != PSY_3GPP_AH_ACTIVE) { + pe_no_ah += band->pe; + a += band->pe_const; + active_lines += band->active_lines; + } + } + } + desired_pe_no_ah = FFMAX(desired_pe - (pe - pe_no_ah), 0.0f); + if (active_lines > 0.0f) + reduction = calc_reduction_3gpp(a, desired_pe_no_ah, pe_no_ah, active_lines); + + pe = 0.0f; + for (w = 0; w < wi->num_windows*16; w += 16) { + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + if (active_lines > 0.0f) + band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction); + pe += calc_pe_3gpp(band); + if (band->thr > 0.0f) + band->norm_fac = band->active_lines / band->thr; + else + band->norm_fac = 0.0f; + norm_fac += band->norm_fac; + } + } + delta_pe = desired_pe - pe; + if (fabs(delta_pe) > 0.05f * desired_pe) + break; + } + + if (pe < 1.15f * desired_pe) { + /* 6.6.1.3.6 "Final threshold modification by linearization" */ + norm_fac = 1.0f / norm_fac; + for (w = 0; w < wi->num_windows*16; w += 16) { + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + if (band->active_lines > 0.5f) { + float delta_sfb_pe = band->norm_fac * norm_fac * delta_pe; + float thr = band->thr; + + thr *= exp2f(delta_sfb_pe / band->active_lines); + if (thr > coeffs[g].min_snr * band->energy && band->avoid_holes == PSY_3GPP_AH_INACTIVE) + thr = FFMAX(band->thr, coeffs[g].min_snr * band->energy); + band->thr = thr; + } + } + } + } else { + /* 5.6.1.3.7 "Further perceptual entropy reduction" */ + g = num_bands; + while (pe > desired_pe && g--) { + for (w = 0; w < wi->num_windows*16; w+= 16) { + AacPsyBand *band = &pch->band[w+g]; + if (band->avoid_holes != PSY_3GPP_AH_NONE && coeffs[g].min_snr < PSY_SNR_1DB) { + coeffs[g].min_snr = PSY_SNR_1DB; + band->thr = band->energy * PSY_SNR_1DB; + pe += band->active_lines * 1.5f - band->pe; + } + } + } + /* TODO: allow more holes (unused without mid/side) */ + } + } + + for (w = 0; w < wi->num_windows*16; w += 16) { + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + FFPsyBand *psy_band = &ctx->ch[channel].psy_bands[w+g]; + + psy_band->threshold = band->thr; + psy_band->energy = band->energy; + psy_band->spread = band->active_lines * 2.0f / band_sizes[g]; + psy_band->bits = PSY_3GPP_PE_TO_BITS(band->pe); + } + } + + memcpy(pch->prev_band, pch->band, sizeof(pch->band)); +} + +static void psy_3gpp_analyze(FFPsyContext *ctx, int channel, + const float **coeffs, const FFPsyWindowInfo *wi) +{ + int ch; + FFPsyChannelGroup *group = ff_psy_find_group(ctx, channel); + + for (ch = 0; ch < group->num_ch; ch++) + psy_3gpp_analyze_channel(ctx, channel + ch, coeffs[ch], &wi[ch]); +} + +static av_cold void psy_3gpp_end(FFPsyContext *apc) +{ + AacPsyContext *pctx = (AacPsyContext*) apc->model_priv_data; + av_freep(&pctx->ch); + av_freep(&apc->model_priv_data); +} + +static void lame_apply_block_type(AacPsyChannel *ctx, FFPsyWindowInfo *wi, int uselongblock) +{ + int blocktype = ONLY_LONG_SEQUENCE; + if (uselongblock) { + if (ctx->next_window_seq == EIGHT_SHORT_SEQUENCE) + blocktype = LONG_STOP_SEQUENCE; + } else { + blocktype = EIGHT_SHORT_SEQUENCE; + if (ctx->next_window_seq == ONLY_LONG_SEQUENCE) + ctx->next_window_seq = LONG_START_SEQUENCE; + if (ctx->next_window_seq == LONG_STOP_SEQUENCE) + ctx->next_window_seq = EIGHT_SHORT_SEQUENCE; + } + + wi->window_type[0] = ctx->next_window_seq; + ctx->next_window_seq = blocktype; +} + +static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio, + const float *la, int channel, int prev_type) +{ + AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; + AacPsyChannel *pch = &pctx->ch[channel]; + int grouping = 0; + int uselongblock = 1; + int attacks[AAC_NUM_BLOCKS_SHORT + 1] = { 0 }; + int i; + FFPsyWindowInfo wi = { { 0 } }; + + if (la) { + float hpfsmpl[AAC_BLOCK_SIZE_LONG]; + const float *pf = hpfsmpl; + float attack_intensity[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS]; + float energy_subshort[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS]; + float energy_short[AAC_NUM_BLOCKS_SHORT + 1] = { 0 }; + const float *firbuf = la + (AAC_BLOCK_SIZE_SHORT/4 - PSY_LAME_FIR_LEN); + int att_sum = 0; + + /* LAME comment: apply high pass filter of fs/4 */ + psy_hp_filter(firbuf, hpfsmpl, psy_fir_coeffs); + + /* Calculate the energies of each sub-shortblock */ + for (i = 0; i < PSY_LAME_NUM_SUBBLOCKS; i++) { + energy_subshort[i] = pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS)]; + assert(pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)] > 0); + attack_intensity[i] = energy_subshort[i] / pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)]; + energy_short[0] += energy_subshort[i]; + } + + for (i = 0; i < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; i++) { + const float *const pfe = pf + AAC_BLOCK_SIZE_LONG / (AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS); + float p = 1.0f; + for (; pf < pfe; pf++) + p = FFMAX(p, fabsf(*pf)); + pch->prev_energy_subshort[i] = energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS] = p; + energy_short[1 + i / PSY_LAME_NUM_SUBBLOCKS] += p; + /* NOTE: The indexes below are [i + 3 - 2] in the LAME source. + * Obviously the 3 and 2 have some significance, or this would be just [i + 1] + * (which is what we use here). What the 3 stands for is ambiguous, as it is both + * number of short blocks, and the number of sub-short blocks. + * It seems that LAME is comparing each sub-block to sub-block + 1 in the + * previous block. + */ + if (p > energy_subshort[i + 1]) + p = p / energy_subshort[i + 1]; + else if (energy_subshort[i + 1] > p * 10.0f) + p = energy_subshort[i + 1] / (p * 10.0f); + else + p = 0.0; + attack_intensity[i + PSY_LAME_NUM_SUBBLOCKS] = p; + } + + /* compare energy between sub-short blocks */ + for (i = 0; i < (AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS; i++) + if (!attacks[i / PSY_LAME_NUM_SUBBLOCKS]) + if (attack_intensity[i] > pch->attack_threshold) + attacks[i / PSY_LAME_NUM_SUBBLOCKS] = (i % PSY_LAME_NUM_SUBBLOCKS) + 1; + + /* should have energy change between short blocks, in order to avoid periodic signals */ + /* Good samples to show the effect are Trumpet test songs */ + /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */ + /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */ + for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++) { + const float u = energy_short[i - 1]; + const float v = energy_short[i]; + const float m = FFMAX(u, v); + if (m < 40000) { /* (2) */ + if (u < 1.7f * v && v < 1.7f * u) { /* (1) */ + if (i == 1 && attacks[0] < attacks[i]) + attacks[0] = 0; + attacks[i] = 0; + } + } + att_sum += attacks[i]; + } + + if (attacks[0] <= pch->prev_attack) + attacks[0] = 0; + + att_sum += attacks[0]; + /* 3 below indicates the previous attack happened in the last sub-block of the previous sequence */ + if (pch->prev_attack == 3 || att_sum) { + uselongblock = 0; + + for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++) + if (attacks[i] && attacks[i-1]) + attacks[i] = 0; + } + } else { + /* We have no lookahead info, so just use same type as the previous sequence. */ + uselongblock = !(prev_type == EIGHT_SHORT_SEQUENCE); + } + + lame_apply_block_type(pch, &wi, uselongblock); + + wi.window_type[1] = prev_type; + if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) { + + wi.num_windows = 1; + wi.grouping[0] = 1; + if (wi.window_type[0] == LONG_START_SEQUENCE) + wi.window_shape = 0; + else + wi.window_shape = 1; + + } else { + int lastgrp = 0; + + wi.num_windows = 8; + wi.window_shape = 0; + for (i = 0; i < 8; i++) { + if (!((pch->next_grouping >> i) & 1)) + lastgrp = i; + wi.grouping[lastgrp]++; + } + } + + /* Determine grouping, based on the location of the first attack, and save for + * the next frame. + * FIXME: Move this to analysis. + * TODO: Tune groupings depending on attack location + * TODO: Handle more than one attack in a group + */ + for (i = 0; i < 9; i++) { + if (attacks[i]) { + grouping = i; + break; + } + } + pch->next_grouping = window_grouping[grouping]; + + pch->prev_attack = attacks[8]; + + return wi; +} + +const FFPsyModel ff_aac_psy_model = +{ + .name = "3GPP TS 26.403-inspired model", + .init = psy_3gpp_init, + .window = psy_lame_window, + .analyze = psy_3gpp_analyze, + .end = psy_3gpp_end, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr.c new file mode 100644 index 000000000..1d2a8d472 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr.c @@ -0,0 +1,370 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2009-2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC Spectral Band Replication decoding functions + * @author Robert Swain ( rob opendot cl ) + */ +#define USE_FIXED 0 + +#include "aac.h" +#include "sbr.h" +#include "aacsbr.h" +#include "aacsbrdata.h" +#include "aacsbr_tablegen.h" +#include "fft.h" +#include "internal.h" +#include "aacps.h" +#include "sbrdsp.h" +#include "libavutil/internal.h" +#include "libavutil/libm.h" +#include "libavutil/avassert.h" + +#include +#include +#include + +#if ARCH_MIPS +#include "mips/aacsbr_mips.h" +#endif /* ARCH_MIPS */ + +static VLC vlc_sbr[10]; +static void aacsbr_func_ptr_init(AACSBRContext *c); + +static void make_bands(int16_t* bands, int start, int stop, int num_bands) +{ + int k, previous, present; + float base, prod; + + base = powf((float)stop / start, 1.0f / num_bands); + prod = start; + previous = start; + + for (k = 0; k < num_bands-1; k++) { + prod *= base; + present = lrintf(prod); + bands[k] = present - previous; + previous = present; + } + bands[num_bands-1] = stop - previous; +} + +/// Dequantization and stereo decoding (14496-3 sp04 p203) +static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) +{ + int k, e; + int ch; + static const double exp2_tab[2] = {1, M_SQRT2}; + if (id_aac == TYPE_CPE && sbr->bs_coupling) { + int pan_offset = sbr->data[0].bs_amp_res ? 12 : 24; + for (e = 1; e <= sbr->data[0].bs_num_env; e++) { + for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) { + float temp1, temp2, fac; + if (sbr->data[0].bs_amp_res) { + temp1 = ff_exp2fi(sbr->data[0].env_facs_q[e][k] + 7); + temp2 = ff_exp2fi(pan_offset - sbr->data[1].env_facs_q[e][k]); + } + else { + temp1 = ff_exp2fi((sbr->data[0].env_facs_q[e][k]>>1) + 7) * + exp2_tab[sbr->data[0].env_facs_q[e][k] & 1]; + temp2 = ff_exp2fi((pan_offset - sbr->data[1].env_facs_q[e][k])>>1) * + exp2_tab[(pan_offset - sbr->data[1].env_facs_q[e][k]) & 1]; + } + if (temp1 > 1E20) { + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + temp1 = 1; + } + fac = temp1 / (1.0f + temp2); + sbr->data[0].env_facs[e][k] = fac; + sbr->data[1].env_facs[e][k] = fac * temp2; + } + } + for (e = 1; e <= sbr->data[0].bs_num_noise; e++) { + for (k = 0; k < sbr->n_q; k++) { + float temp1 = ff_exp2fi(NOISE_FLOOR_OFFSET - sbr->data[0].noise_facs_q[e][k] + 1); + float temp2 = ff_exp2fi(12 - sbr->data[1].noise_facs_q[e][k]); + float fac; + av_assert0(temp1 <= 1E20); + fac = temp1 / (1.0f + temp2); + sbr->data[0].noise_facs[e][k] = fac; + sbr->data[1].noise_facs[e][k] = fac * temp2; + } + } + } else { // SCE or one non-coupled CPE + for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) { + for (e = 1; e <= sbr->data[ch].bs_num_env; e++) + for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){ + if (sbr->data[ch].bs_amp_res) + sbr->data[ch].env_facs[e][k] = ff_exp2fi(sbr->data[ch].env_facs_q[e][k] + 6); + else + sbr->data[ch].env_facs[e][k] = ff_exp2fi((sbr->data[ch].env_facs_q[e][k]>>1) + 6) + * exp2_tab[sbr->data[ch].env_facs_q[e][k] & 1]; + if (sbr->data[ch].env_facs[e][k] > 1E20) { + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + sbr->data[ch].env_facs[e][k] = 1; + } + } + + for (e = 1; e <= sbr->data[ch].bs_num_noise; e++) + for (k = 0; k < sbr->n_q; k++) + sbr->data[ch].noise_facs[e][k] = + ff_exp2fi(NOISE_FLOOR_OFFSET - sbr->data[ch].noise_facs_q[e][k]); + } + } +} + +/** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering + * (14496-3 sp04 p214) + * Warning: This routine does not seem numerically stable. + */ +static void sbr_hf_inverse_filter(SBRDSPContext *dsp, + float (*alpha0)[2], float (*alpha1)[2], + const float X_low[32][40][2], int k0) +{ + int k; + for (k = 0; k < k0; k++) { + LOCAL_ALIGNED_16(float, phi, [3], [2][2]); + float dk; + + dsp->autocorrelate(X_low[k], phi); + + dk = phi[2][1][0] * phi[1][0][0] - + (phi[1][1][0] * phi[1][1][0] + phi[1][1][1] * phi[1][1][1]) / 1.000001f; + + if (!dk) { + alpha1[k][0] = 0; + alpha1[k][1] = 0; + } else { + float temp_real, temp_im; + temp_real = phi[0][0][0] * phi[1][1][0] - + phi[0][0][1] * phi[1][1][1] - + phi[0][1][0] * phi[1][0][0]; + temp_im = phi[0][0][0] * phi[1][1][1] + + phi[0][0][1] * phi[1][1][0] - + phi[0][1][1] * phi[1][0][0]; + + alpha1[k][0] = temp_real / dk; + alpha1[k][1] = temp_im / dk; + } + + if (!phi[1][0][0]) { + alpha0[k][0] = 0; + alpha0[k][1] = 0; + } else { + float temp_real, temp_im; + temp_real = phi[0][0][0] + alpha1[k][0] * phi[1][1][0] + + alpha1[k][1] * phi[1][1][1]; + temp_im = phi[0][0][1] + alpha1[k][1] * phi[1][1][0] - + alpha1[k][0] * phi[1][1][1]; + + alpha0[k][0] = -temp_real / phi[1][0][0]; + alpha0[k][1] = -temp_im / phi[1][0][0]; + } + + if (alpha1[k][0] * alpha1[k][0] + alpha1[k][1] * alpha1[k][1] >= 16.0f || + alpha0[k][0] * alpha0[k][0] + alpha0[k][1] * alpha0[k][1] >= 16.0f) { + alpha1[k][0] = 0; + alpha1[k][1] = 0; + alpha0[k][0] = 0; + alpha0[k][1] = 0; + } + } +} + +/// Chirp Factors (14496-3 sp04 p214) +static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data) +{ + int i; + float new_bw; + static const float bw_tab[] = { 0.0f, 0.75f, 0.9f, 0.98f }; + + for (i = 0; i < sbr->n_q; i++) { + if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1) { + new_bw = 0.6f; + } else + new_bw = bw_tab[ch_data->bs_invf_mode[0][i]]; + + if (new_bw < ch_data->bw_array[i]) { + new_bw = 0.75f * new_bw + 0.25f * ch_data->bw_array[i]; + } else + new_bw = 0.90625f * new_bw + 0.09375f * ch_data->bw_array[i]; + ch_data->bw_array[i] = new_bw < 0.015625f ? 0.0f : new_bw; + } +} + +/** + * Calculation of levels of additional HF signal components (14496-3 sp04 p219) + * and Calculation of gain (14496-3 sp04 p219) + */ +static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr, + SBRData *ch_data, const int e_a[2]) +{ + int e, k, m; + // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off) + static const float limgain[4] = { 0.70795, 1.0, 1.41254, 10000000000 }; + + for (e = 0; e < ch_data->bs_num_env; e++) { + int delta = !((e == e_a[1]) || (e == e_a[0])); + for (k = 0; k < sbr->n_lim; k++) { + float gain_boost, gain_max; + float sum[2] = { 0.0f, 0.0f }; + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + const float temp = sbr->e_origmapped[e][m] / (1.0f + sbr->q_mapped[e][m]); + sbr->q_m[e][m] = sqrtf(temp * sbr->q_mapped[e][m]); + sbr->s_m[e][m] = sqrtf(temp * ch_data->s_indexmapped[e + 1][m]); + if (!sbr->s_mapped[e][m]) { + sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] / + ((1.0f + sbr->e_curr[e][m]) * + (1.0f + sbr->q_mapped[e][m] * delta))); + } else { + sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] * sbr->q_mapped[e][m] / + ((1.0f + sbr->e_curr[e][m]) * + (1.0f + sbr->q_mapped[e][m]))); + } + sbr->gain[e][m] += FLT_MIN; + } + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + sum[0] += sbr->e_origmapped[e][m]; + sum[1] += sbr->e_curr[e][m]; + } + gain_max = limgain[sbr->bs_limiter_gains] * sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); + gain_max = FFMIN(100000.f, gain_max); + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + float q_m_max = sbr->q_m[e][m] * gain_max / sbr->gain[e][m]; + sbr->q_m[e][m] = FFMIN(sbr->q_m[e][m], q_m_max); + sbr->gain[e][m] = FFMIN(sbr->gain[e][m], gain_max); + } + sum[0] = sum[1] = 0.0f; + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + sum[0] += sbr->e_origmapped[e][m]; + sum[1] += sbr->e_curr[e][m] * sbr->gain[e][m] * sbr->gain[e][m] + + sbr->s_m[e][m] * sbr->s_m[e][m] + + (delta && !sbr->s_m[e][m]) * sbr->q_m[e][m] * sbr->q_m[e][m]; + } + gain_boost = sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); + gain_boost = FFMIN(1.584893192f, gain_boost); + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + sbr->gain[e][m] *= gain_boost; + sbr->q_m[e][m] *= gain_boost; + sbr->s_m[e][m] *= gain_boost; + } + } + } +} + +/// Assembling HF Signals (14496-3 sp04 p220) +static void sbr_hf_assemble(float Y1[38][64][2], + const float X_high[64][40][2], + SpectralBandReplication *sbr, SBRData *ch_data, + const int e_a[2]) +{ + int e, i, j, m; + const int h_SL = 4 * !sbr->bs_smoothing_mode; + const int kx = sbr->kx[1]; + const int m_max = sbr->m[1]; + static const float h_smooth[5] = { + 0.33333333333333, + 0.30150283239582, + 0.21816949906249, + 0.11516383427084, + 0.03183050093751, + }; + float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp; + int indexnoise = ch_data->f_indexnoise; + int indexsine = ch_data->f_indexsine; + + if (sbr->reset) { + for (i = 0; i < h_SL; i++) { + memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0])); + memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0])); + } + } else if (h_SL) { + for (i = 0; i < 4; i++) { + memcpy(g_temp[i + 2 * ch_data->t_env[0]], + g_temp[i + 2 * ch_data->t_env_num_env_old], + sizeof(g_temp[0])); + memcpy(q_temp[i + 2 * ch_data->t_env[0]], + q_temp[i + 2 * ch_data->t_env_num_env_old], + sizeof(q_temp[0])); + } + } + + for (e = 0; e < ch_data->bs_num_env; e++) { + for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { + memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0])); + memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0])); + } + } + + for (e = 0; e < ch_data->bs_num_env; e++) { + for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { + LOCAL_ALIGNED_16(float, g_filt_tab, [48]); + LOCAL_ALIGNED_16(float, q_filt_tab, [48]); + float *g_filt, *q_filt; + + if (h_SL && e != e_a[0] && e != e_a[1]) { + g_filt = g_filt_tab; + q_filt = q_filt_tab; + for (m = 0; m < m_max; m++) { + const int idx1 = i + h_SL; + g_filt[m] = 0.0f; + q_filt[m] = 0.0f; + for (j = 0; j <= h_SL; j++) { + g_filt[m] += g_temp[idx1 - j][m] * h_smooth[j]; + q_filt[m] += q_temp[idx1 - j][m] * h_smooth[j]; + } + } + } else { + g_filt = g_temp[i + h_SL]; + q_filt = q_temp[i]; + } + + sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max, + i + ENVELOPE_ADJUSTMENT_OFFSET); + + if (e != e_a[0] && e != e_a[1]) { + sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e], + q_filt, indexnoise, + kx, m_max); + } else { + int idx = indexsine&1; + int A = (1-((indexsine+(kx & 1))&2)); + int B = (A^(-idx)) + idx; + float *out = &Y1[i][kx][idx]; + float *in = sbr->s_m[e]; + for (m = 0; m+1 < m_max; m+=2) { + out[2*m ] += in[m ] * A; + out[2*m+2] += in[m+1] * B; + } + if(m_max&1) + out[2*m ] += in[m ] * A; + } + indexnoise = (indexnoise + m_max) & 0x1ff; + indexsine = (indexsine + 1) & 3; + } + } + ch_data->f_indexnoise = indexnoise; + ch_data->f_indexsine = indexsine; +} + +#include "aacsbr_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr.h new file mode 100644 index 000000000..dd8b66c7b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr.h @@ -0,0 +1,96 @@ +/* + * AAC Spectral Band Replication function declarations + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC Spectral Band Replication function declarations + * @author Robert Swain ( rob opendot cl ) + */ + +#ifndef AVCODEC_AACSBR_H +#define AVCODEC_AACSBR_H + +#include "get_bits.h" +#include "aac.h" +#include "sbr.h" + +#define ENVELOPE_ADJUSTMENT_OFFSET 2 +#define NOISE_FLOOR_OFFSET 6 + +/** + * SBR VLC tables + */ +enum { + T_HUFFMAN_ENV_1_5DB, + F_HUFFMAN_ENV_1_5DB, + T_HUFFMAN_ENV_BAL_1_5DB, + F_HUFFMAN_ENV_BAL_1_5DB, + T_HUFFMAN_ENV_3_0DB, + F_HUFFMAN_ENV_3_0DB, + T_HUFFMAN_ENV_BAL_3_0DB, + F_HUFFMAN_ENV_BAL_3_0DB, + T_HUFFMAN_NOISE_3_0DB, + T_HUFFMAN_NOISE_BAL_3_0DB, +}; + +/** + * bs_frame_class - frame class of current SBR frame (14496-3 sp04 p98) + */ +enum { + FIXFIX, + FIXVAR, + VARFIX, + VARVAR, +}; + +enum { + EXTENSION_ID_PS = 2, +}; + +static const int8_t vlc_sbr_lav[10] = + { 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 }; + +#define SBR_INIT_VLC_STATIC(num, size) \ + INIT_VLC_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size, \ + sbr_tmp[num].sbr_bits , 1, 1, \ + sbr_tmp[num].sbr_codes, sbr_tmp[num].elem_size, sbr_tmp[num].elem_size, \ + size) + +#define SBR_VLC_ROW(name) \ + { name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) } + +/** Initialize SBR. */ +void AAC_RENAME(ff_aac_sbr_init)(void); +/** Initialize one SBR context. */ +void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr, int id_aac); +/** Close one SBR context. */ +void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr); +/** Decode one SBR element. */ +int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb, int crc, int cnt, int id_aac); +/** Apply one SBR element to one AAC element. */ +void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int id_aac, + INTFLOAT* L, INTFLOAT *R); + +void ff_aacsbr_func_ptr_init_mips(AACSBRContext *c); + +#endif /* AVCODEC_AACSBR_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_fixed.c new file mode 100644 index 000000000..59cbba10f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_fixed.c @@ -0,0 +1,613 @@ +/* + * Copyright (c) 2013 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * AAC Spectral Band Replication decoding functions (fixed-point) + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2009-2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC Spectral Band Replication decoding functions (fixed-point) + * Note: Rounding-to-nearest used unless otherwise stated + * @author Robert Swain ( rob opendot cl ) + * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com ) + */ +#define USE_FIXED 1 + +#include "aac.h" +#include "sbr.h" +#include "aacsbr.h" +#include "aacsbrdata.h" +#include "aacsbr_fixed_tablegen.h" +#include "fft.h" +#include "aacps.h" +#include "sbrdsp.h" +#include "libavutil/internal.h" +#include "libavutil/libm.h" +#include "libavutil/avassert.h" + +#include +#include +#include + +static VLC vlc_sbr[10]; +static void aacsbr_func_ptr_init(AACSBRContext *c); +static const int CONST_LN2 = Q31(0.6931471806/256); // ln(2)/256 +static const int CONST_RECIP_LN2 = Q31(0.7213475204); // 0.5/ln(2) +static const int CONST_076923 = Q31(0.76923076923076923077f); + +static const int fixed_log_table[10] = +{ + Q31(1.0/2), Q31(1.0/3), Q31(1.0/4), Q31(1.0/5), Q31(1.0/6), + Q31(1.0/7), Q31(1.0/8), Q31(1.0/9), Q31(1.0/10), Q31(1.0/11) +}; + +static int fixed_log(int x) +{ + int i, ret, xpow, tmp; + + ret = x; + xpow = x; + for (i=0; i<10; i+=2){ + xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31); + tmp = (int)(((int64_t)xpow * fixed_log_table[i] + 0x40000000) >> 31); + ret -= tmp; + + xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31); + tmp = (int)(((int64_t)xpow * fixed_log_table[i+1] + 0x40000000) >> 31); + ret += tmp; + } + + return ret; +} + +static const int fixed_exp_table[7] = +{ + Q31(1.0/2), Q31(1.0/6), Q31(1.0/24), Q31(1.0/120), + Q31(1.0/720), Q31(1.0/5040), Q31(1.0/40320) +}; + +static int fixed_exp(int x) +{ + int i, ret, xpow, tmp; + + ret = 0x800000 + x; + xpow = x; + for (i=0; i<7; i++){ + xpow = (int)(((int64_t)xpow * x + 0x400000) >> 23); + tmp = (int)(((int64_t)xpow * fixed_exp_table[i] + 0x40000000) >> 31); + ret += tmp; + } + + return ret; +} + +static void make_bands(int16_t* bands, int start, int stop, int num_bands) +{ + int k, previous, present; + int base, prod, nz = 0; + + base = (stop << 23) / start; + while (base < 0x40000000){ + base <<= 1; + nz++; + } + base = fixed_log(base - 0x80000000); + base = (((base + 0x80) >> 8) + (8-nz)*CONST_LN2) / num_bands; + base = fixed_exp(base); + + previous = start; + prod = start << 23; + + for (k = 0; k < num_bands-1; k++) { + prod = (int)(((int64_t)prod * base + 0x400000) >> 23); + present = (prod + 0x400000) >> 23; + bands[k] = present - previous; + previous = present; + } + bands[num_bands-1] = stop - previous; +} + +/// Dequantization and stereo decoding (14496-3 sp04 p203) +static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) +{ + int k, e; + int ch; + + if (id_aac == TYPE_CPE && sbr->bs_coupling) { + int alpha = sbr->data[0].bs_amp_res ? 2 : 1; + int pan_offset = sbr->data[0].bs_amp_res ? 12 : 24; + for (e = 1; e <= sbr->data[0].bs_num_env; e++) { + for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) { + SoftFloat temp1, temp2, fac; + + temp1.exp = sbr->data[0].env_facs_q[e][k] * alpha + 14; + if (temp1.exp & 1) + temp1.mant = 759250125; + else + temp1.mant = 0x20000000; + temp1.exp = (temp1.exp >> 1) + 1; + if (temp1.exp > 66) { // temp1 > 1E20 + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + temp1 = FLOAT_1; + } + + temp2.exp = (pan_offset - sbr->data[1].env_facs_q[e][k]) * alpha; + if (temp2.exp & 1) + temp2.mant = 759250125; + else + temp2.mant = 0x20000000; + temp2.exp = (temp2.exp >> 1) + 1; + fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2)); + sbr->data[0].env_facs[e][k] = fac; + sbr->data[1].env_facs[e][k] = av_mul_sf(fac, temp2); + } + } + for (e = 1; e <= sbr->data[0].bs_num_noise; e++) { + for (k = 0; k < sbr->n_q; k++) { + SoftFloat temp1, temp2, fac; + + temp1.exp = NOISE_FLOOR_OFFSET - \ + sbr->data[0].noise_facs_q[e][k] + 2; + temp1.mant = 0x20000000; + av_assert0(temp1.exp <= 66); + temp2.exp = 12 - sbr->data[1].noise_facs_q[e][k] + 1; + temp2.mant = 0x20000000; + fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2)); + sbr->data[0].noise_facs[e][k] = fac; + sbr->data[1].noise_facs[e][k] = av_mul_sf(fac, temp2); + } + } + } else { // SCE or one non-coupled CPE + for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) { + int alpha = sbr->data[ch].bs_amp_res ? 2 : 1; + for (e = 1; e <= sbr->data[ch].bs_num_env; e++) + for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){ + SoftFloat temp1; + + temp1.exp = alpha * sbr->data[ch].env_facs_q[e][k] + 12; + if (temp1.exp & 1) + temp1.mant = 759250125; + else + temp1.mant = 0x20000000; + temp1.exp = (temp1.exp >> 1) + 1; + if (temp1.exp > 66) { // temp1 > 1E20 + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + temp1 = FLOAT_1; + } + sbr->data[ch].env_facs[e][k] = temp1; + } + for (e = 1; e <= sbr->data[ch].bs_num_noise; e++) + for (k = 0; k < sbr->n_q; k++){ + sbr->data[ch].noise_facs[e][k].exp = NOISE_FLOOR_OFFSET - \ + sbr->data[ch].noise_facs_q[e][k] + 1; + sbr->data[ch].noise_facs[e][k].mant = 0x20000000; + } + } + } +} + +/** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering + * (14496-3 sp04 p214) + * Warning: This routine does not seem numerically stable. + */ +static void sbr_hf_inverse_filter(SBRDSPContext *dsp, + int (*alpha0)[2], int (*alpha1)[2], + const int X_low[32][40][2], int k0) +{ + int k; + int shift, round; + + for (k = 0; k < k0; k++) { + SoftFloat phi[3][2][2]; + SoftFloat a00, a01, a10, a11; + SoftFloat dk; + + dsp->autocorrelate(X_low[k], phi); + + dk = av_sub_sf(av_mul_sf(phi[2][1][0], phi[1][0][0]), + av_mul_sf(av_add_sf(av_mul_sf(phi[1][1][0], phi[1][1][0]), + av_mul_sf(phi[1][1][1], phi[1][1][1])), FLOAT_0999999)); + + if (!dk.mant) { + a10 = FLOAT_0; + a11 = FLOAT_0; + } else { + SoftFloat temp_real, temp_im; + temp_real = av_sub_sf(av_sub_sf(av_mul_sf(phi[0][0][0], phi[1][1][0]), + av_mul_sf(phi[0][0][1], phi[1][1][1])), + av_mul_sf(phi[0][1][0], phi[1][0][0])); + temp_im = av_sub_sf(av_add_sf(av_mul_sf(phi[0][0][0], phi[1][1][1]), + av_mul_sf(phi[0][0][1], phi[1][1][0])), + av_mul_sf(phi[0][1][1], phi[1][0][0])); + + a10 = av_div_sf(temp_real, dk); + a11 = av_div_sf(temp_im, dk); + } + + if (!phi[1][0][0].mant) { + a00 = FLOAT_0; + a01 = FLOAT_0; + } else { + SoftFloat temp_real, temp_im; + temp_real = av_add_sf(phi[0][0][0], + av_add_sf(av_mul_sf(a10, phi[1][1][0]), + av_mul_sf(a11, phi[1][1][1]))); + temp_im = av_add_sf(phi[0][0][1], + av_sub_sf(av_mul_sf(a11, phi[1][1][0]), + av_mul_sf(a10, phi[1][1][1]))); + + temp_real.mant = -temp_real.mant; + temp_im.mant = -temp_im.mant; + a00 = av_div_sf(temp_real, phi[1][0][0]); + a01 = av_div_sf(temp_im, phi[1][0][0]); + } + + shift = a00.exp; + if (shift >= 3) + alpha0[k][0] = 0x7fffffff; + else if (shift <= -30) + alpha0[k][0] = 0; + else { + shift = 1-shift; + if (shift <= 0) + alpha0[k][0] = a00.mant * (1<<-shift); + else { + round = 1 << (shift-1); + alpha0[k][0] = (a00.mant + round) >> shift; + } + } + + shift = a01.exp; + if (shift >= 3) + alpha0[k][1] = 0x7fffffff; + else if (shift <= -30) + alpha0[k][1] = 0; + else { + shift = 1-shift; + if (shift <= 0) + alpha0[k][1] = a01.mant * (1<<-shift); + else { + round = 1 << (shift-1); + alpha0[k][1] = (a01.mant + round) >> shift; + } + } + shift = a10.exp; + if (shift >= 3) + alpha1[k][0] = 0x7fffffff; + else if (shift <= -30) + alpha1[k][0] = 0; + else { + shift = 1-shift; + if (shift <= 0) + alpha1[k][0] = a10.mant * (1<<-shift); + else { + round = 1 << (shift-1); + alpha1[k][0] = (a10.mant + round) >> shift; + } + } + + shift = a11.exp; + if (shift >= 3) + alpha1[k][1] = 0x7fffffff; + else if (shift <= -30) + alpha1[k][1] = 0; + else { + shift = 1-shift; + if (shift <= 0) + alpha1[k][1] = a11.mant * (1<<-shift); + else { + round = 1 << (shift-1); + alpha1[k][1] = (a11.mant + round) >> shift; + } + } + + shift = (int)(((int64_t)(alpha1[k][0]>>1) * (alpha1[k][0]>>1) + \ + (int64_t)(alpha1[k][1]>>1) * (alpha1[k][1]>>1) + \ + 0x40000000) >> 31); + if (shift >= 0x20000000){ + alpha1[k][0] = 0; + alpha1[k][1] = 0; + alpha0[k][0] = 0; + alpha0[k][1] = 0; + } + + shift = (int)(((int64_t)(alpha0[k][0]>>1) * (alpha0[k][0]>>1) + \ + (int64_t)(alpha0[k][1]>>1) * (alpha0[k][1]>>1) + \ + 0x40000000) >> 31); + if (shift >= 0x20000000){ + alpha1[k][0] = 0; + alpha1[k][1] = 0; + alpha0[k][0] = 0; + alpha0[k][1] = 0; + } + } +} + +/// Chirp Factors (14496-3 sp04 p214) +static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data) +{ + int i; + int new_bw; + static const int bw_tab[] = { 0, 1610612736, 1932735283, 2104533975 }; + int64_t accu; + + for (i = 0; i < sbr->n_q; i++) { + if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1) + new_bw = 1288490189; + else + new_bw = bw_tab[ch_data->bs_invf_mode[0][i]]; + + if (new_bw < ch_data->bw_array[i]){ + accu = (int64_t)new_bw * 1610612736; + accu += (int64_t)ch_data->bw_array[i] * 0x20000000; + new_bw = (int)((accu + 0x40000000) >> 31); + } else { + accu = (int64_t)new_bw * 1946157056; + accu += (int64_t)ch_data->bw_array[i] * 201326592; + new_bw = (int)((accu + 0x40000000) >> 31); + } + ch_data->bw_array[i] = new_bw < 0x2000000 ? 0 : new_bw; + } +} + +/** + * Calculation of levels of additional HF signal components (14496-3 sp04 p219) + * and Calculation of gain (14496-3 sp04 p219) + */ +static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr, + SBRData *ch_data, const int e_a[2]) +{ + int e, k, m; + // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off) + static const SoftFloat limgain[4] = { { 760155524, 0 }, { 0x20000000, 1 }, + { 758351638, 1 }, { 625000000, 34 } }; + + for (e = 0; e < ch_data->bs_num_env; e++) { + int delta = !((e == e_a[1]) || (e == e_a[0])); + for (k = 0; k < sbr->n_lim; k++) { + SoftFloat gain_boost, gain_max; + SoftFloat sum[2]; + sum[0] = sum[1] = FLOAT_0; + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + const SoftFloat temp = av_div_sf(sbr->e_origmapped[e][m], + av_add_sf(FLOAT_1, sbr->q_mapped[e][m])); + sbr->q_m[e][m] = av_sqrt_sf(av_mul_sf(temp, sbr->q_mapped[e][m])); + sbr->s_m[e][m] = av_sqrt_sf(av_mul_sf(temp, av_int2sf(ch_data->s_indexmapped[e + 1][m], 0))); + if (!sbr->s_mapped[e][m]) { + if (delta) { + sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m], + av_mul_sf(av_add_sf(FLOAT_1, sbr->e_curr[e][m]), + av_add_sf(FLOAT_1, sbr->q_mapped[e][m])))); + } else { + sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m], + av_add_sf(FLOAT_1, sbr->e_curr[e][m]))); + } + } else { + sbr->gain[e][m] = av_sqrt_sf( + av_div_sf( + av_mul_sf(sbr->e_origmapped[e][m], sbr->q_mapped[e][m]), + av_mul_sf( + av_add_sf(FLOAT_1, sbr->e_curr[e][m]), + av_add_sf(FLOAT_1, sbr->q_mapped[e][m])))); + } + sbr->gain[e][m] = av_add_sf(sbr->gain[e][m], FLOAT_MIN); + } + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]); + sum[1] = av_add_sf(sum[1], sbr->e_curr[e][m]); + } + gain_max = av_mul_sf(limgain[sbr->bs_limiter_gains], + av_sqrt_sf( + av_div_sf( + av_add_sf(FLOAT_EPSILON, sum[0]), + av_add_sf(FLOAT_EPSILON, sum[1])))); + if (av_gt_sf(gain_max, FLOAT_100000)) + gain_max = FLOAT_100000; + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + SoftFloat q_m_max = av_div_sf( + av_mul_sf(sbr->q_m[e][m], gain_max), + sbr->gain[e][m]); + if (av_gt_sf(sbr->q_m[e][m], q_m_max)) + sbr->q_m[e][m] = q_m_max; + if (av_gt_sf(sbr->gain[e][m], gain_max)) + sbr->gain[e][m] = gain_max; + } + sum[0] = sum[1] = FLOAT_0; + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]); + sum[1] = av_add_sf(sum[1], + av_mul_sf( + av_mul_sf(sbr->e_curr[e][m], + sbr->gain[e][m]), + sbr->gain[e][m])); + sum[1] = av_add_sf(sum[1], + av_mul_sf(sbr->s_m[e][m], sbr->s_m[e][m])); + if (delta && !sbr->s_m[e][m].mant) + sum[1] = av_add_sf(sum[1], + av_mul_sf(sbr->q_m[e][m], sbr->q_m[e][m])); + } + gain_boost = av_sqrt_sf( + av_div_sf( + av_add_sf(FLOAT_EPSILON, sum[0]), + av_add_sf(FLOAT_EPSILON, sum[1]))); + if (av_gt_sf(gain_boost, FLOAT_1584893192)) + gain_boost = FLOAT_1584893192; + + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + sbr->gain[e][m] = av_mul_sf(sbr->gain[e][m], gain_boost); + sbr->q_m[e][m] = av_mul_sf(sbr->q_m[e][m], gain_boost); + sbr->s_m[e][m] = av_mul_sf(sbr->s_m[e][m], gain_boost); + } + } + } +} + +/// Assembling HF Signals (14496-3 sp04 p220) +static void sbr_hf_assemble(int Y1[38][64][2], + const int X_high[64][40][2], + SpectralBandReplication *sbr, SBRData *ch_data, + const int e_a[2]) +{ + int e, i, j, m; + const int h_SL = 4 * !sbr->bs_smoothing_mode; + const int kx = sbr->kx[1]; + const int m_max = sbr->m[1]; + static const SoftFloat h_smooth[5] = { + { 715827883, -1 }, + { 647472402, -1 }, + { 937030863, -2 }, + { 989249804, -3 }, + { 546843842, -4 }, + }; + SoftFloat (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp; + int indexnoise = ch_data->f_indexnoise; + int indexsine = ch_data->f_indexsine; + + if (sbr->reset) { + for (i = 0; i < h_SL; i++) { + memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0])); + memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0])); + } + } else if (h_SL) { + for (i = 0; i < 4; i++) { + memcpy(g_temp[i + 2 * ch_data->t_env[0]], + g_temp[i + 2 * ch_data->t_env_num_env_old], + sizeof(g_temp[0])); + memcpy(q_temp[i + 2 * ch_data->t_env[0]], + q_temp[i + 2 * ch_data->t_env_num_env_old], + sizeof(q_temp[0])); + } + } + + for (e = 0; e < ch_data->bs_num_env; e++) { + for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { + memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0])); + memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0])); + } + } + + for (e = 0; e < ch_data->bs_num_env; e++) { + for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { + SoftFloat g_filt_tab[48]; + SoftFloat q_filt_tab[48]; + SoftFloat *g_filt, *q_filt; + + if (h_SL && e != e_a[0] && e != e_a[1]) { + g_filt = g_filt_tab; + q_filt = q_filt_tab; + for (m = 0; m < m_max; m++) { + const int idx1 = i + h_SL; + g_filt[m].mant = g_filt[m].exp = 0; + q_filt[m].mant = q_filt[m].exp = 0; + for (j = 0; j <= h_SL; j++) { + g_filt[m] = av_add_sf(g_filt[m], + av_mul_sf(g_temp[idx1 - j][m], + h_smooth[j])); + q_filt[m] = av_add_sf(q_filt[m], + av_mul_sf(q_temp[idx1 - j][m], + h_smooth[j])); + } + } + } else { + g_filt = g_temp[i + h_SL]; + q_filt = q_temp[i]; + } + + sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max, + i + ENVELOPE_ADJUSTMENT_OFFSET); + + if (e != e_a[0] && e != e_a[1]) { + sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e], + q_filt, indexnoise, + kx, m_max); + } else { + int idx = indexsine&1; + int A = (1-((indexsine+(kx & 1))&2)); + int B = (A^(-idx)) + idx; + unsigned *out = &Y1[i][kx][idx]; + int shift; + unsigned round; + + SoftFloat *in = sbr->s_m[e]; + for (m = 0; m+1 < m_max; m+=2) { + int shift2; + shift = 22 - in[m ].exp; + shift2= 22 - in[m+1].exp; + if (shift < 1 || shift2 < 1) { + av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_assemble, shift=%d,%d\n", shift, shift2); + return; + } + if (shift < 32) { + round = 1 << (shift-1); + out[2*m ] += (int)(in[m ].mant * A + round) >> shift; + } + + if (shift2 < 32) { + round = 1 << (shift2-1); + out[2*m+2] += (int)(in[m+1].mant * B + round) >> shift2; + } + } + if(m_max&1) + { + shift = 22 - in[m ].exp; + if (shift < 1) { + av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_assemble, shift=%d\n", shift); + return; + } else if (shift < 32) { + round = 1 << (shift-1); + out[2*m ] += (int)(in[m ].mant * A + round) >> shift; + } + } + } + indexnoise = (indexnoise + m_max) & 0x1ff; + indexsine = (indexsine + 1) & 3; + } + } + ch_data->f_indexnoise = indexnoise; + ch_data->f_indexsine = indexsine; +} + +#include "aacsbr_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_fixed_tablegen.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_fixed_tablegen.h new file mode 100644 index 000000000..3fcf0204c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_fixed_tablegen.h @@ -0,0 +1,28 @@ +/* + * Header file for hardcoded AAC SBR windows + * + * Copyright (c) 2014 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AACSBR_FIXED_TABLEGEN_H +#define AVCODEC_AACSBR_FIXED_TABLEGEN_H + +#include "aacsbr_tablegen_common.h" + +#endif /* AVCODEC_AACSBR_FIXED_TABLEGEN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_tablegen.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_tablegen.h new file mode 100644 index 000000000..242a96355 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_tablegen.h @@ -0,0 +1,28 @@ +/* + * Header file for hardcoded AAC SBR windows + * + * Copyright (c) 2014 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AACSBR_TABLEGEN_H +#define AVCODEC_AACSBR_TABLEGEN_H + +#include "aacsbr_tablegen_common.h" + +#endif /* AVCODEC_AACSBR_TABLEGEN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_tablegen_common.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_tablegen_common.h new file mode 100644 index 000000000..8e0dd9e1f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_tablegen_common.h @@ -0,0 +1,114 @@ +/* + * Header file for hardcoded AAC SBR windows + * + * Copyright (c) 2014 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AACSBR_TABLEGEN_COMMON_H +#define AVCODEC_AACSBR_TABLEGEN_COMMON_H +#include "aac_defines.h" +#include "libavutil/mem.h" + +///< window coefficients for analysis/synthesis QMF banks +static DECLARE_ALIGNED(32, INTFLOAT, sbr_qmf_window_ds)[320]; +static DECLARE_ALIGNED(32, INTFLOAT, sbr_qmf_window_us)[640] = { + Q31( 0.0000000000f), Q31(-0.0005525286f), Q31(-0.0005617692f), Q31(-0.0004947518f), + Q31(-0.0004875227f), Q31(-0.0004893791f), Q31(-0.0005040714f), Q31(-0.0005226564f), + Q31(-0.0005466565f), Q31(-0.0005677802f), Q31(-0.0005870930f), Q31(-0.0006132747f), + Q31(-0.0006312493f), Q31(-0.0006540333f), Q31(-0.0006777690f), Q31(-0.0006941614f), + Q31(-0.0007157736f), Q31(-0.0007255043f), Q31(-0.0007440941f), Q31(-0.0007490598f), + Q31(-0.0007681371f), Q31(-0.0007724848f), Q31(-0.0007834332f), Q31(-0.0007779869f), + Q31(-0.0007803664f), Q31(-0.0007801449f), Q31(-0.0007757977f), Q31(-0.0007630793f), + Q31(-0.0007530001f), Q31(-0.0007319357f), Q31(-0.0007215391f), Q31(-0.0006917937f), + Q31(-0.0006650415f), Q31(-0.0006341594f), Q31(-0.0005946118f), Q31(-0.0005564576f), + Q31(-0.0005145572f), Q31(-0.0004606325f), Q31(-0.0004095121f), Q31(-0.0003501175f), + Q31(-0.0002896981f), Q31(-0.0002098337f), Q31(-0.0001446380f), Q31(-0.0000617334f), + Q31( 0.0000134949f), Q31( 0.0001094383f), Q31( 0.0002043017f), Q31( 0.0002949531f), + Q31( 0.0004026540f), Q31( 0.0005107388f), Q31( 0.0006239376f), Q31( 0.0007458025f), + Q31( 0.0008608443f), Q31( 0.0009885988f), Q31( 0.0011250155f), Q31( 0.0012577884f), + Q31( 0.0013902494f), Q31( 0.0015443219f), Q31( 0.0016868083f), Q31( 0.0018348265f), + Q31( 0.0019841140f), Q31( 0.0021461583f), Q31( 0.0023017254f), Q31( 0.0024625616f), + Q31( 0.0026201758f), Q31( 0.0027870464f), Q31( 0.0029469447f), Q31( 0.0031125420f), + Q31( 0.0032739613f), Q31( 0.0034418874f), Q31( 0.0036008268f), Q31( 0.0037603922f), + Q31( 0.0039207432f), Q31( 0.0040819753f), Q31( 0.0042264269f), Q31( 0.0043730719f), + Q31( 0.0045209852f), Q31( 0.0046606460f), Q31( 0.0047932560f), Q31( 0.0049137603f), + Q31( 0.0050393022f), Q31( 0.0051407353f), Q31( 0.0052461166f), Q31( 0.0053471681f), + Q31( 0.0054196775f), Q31( 0.0054876040f), Q31( 0.0055475714f), Q31( 0.0055938023f), + Q31( 0.0056220643f), Q31( 0.0056455196f), Q31( 0.0056389199f), Q31( 0.0056266114f), + Q31( 0.0055917128f), Q31( 0.0055404363f), Q31( 0.0054753783f), Q31( 0.0053838975f), + Q31( 0.0052715758f), Q31( 0.0051382275f), Q31( 0.0049839687f), Q31( 0.0048109469f), + Q31( 0.0046039530f), Q31( 0.0043801861f), Q31( 0.0041251642f), Q31( 0.0038456408f), + Q31( 0.0035401246f), Q31( 0.0032091885f), Q31( 0.0028446757f), Q31( 0.0024508540f), + Q31( 0.0020274176f), Q31( 0.0015784682f), Q31( 0.0010902329f), Q31( 0.0005832264f), + Q31( 0.0000276045f), Q31(-0.0005464280f), Q31(-0.0011568135f), Q31(-0.0018039472f), + Q31(-0.0024826723f), Q31(-0.0031933778f), Q31(-0.0039401124f), Q31(-0.0047222596f), + Q31(-0.0055337211f), Q31(-0.0063792293f), Q31(-0.0072615816f), Q31(-0.0081798233f), + Q31(-0.0091325329f), Q31(-0.0101150215f), Q31(-0.0111315548f), Q31(-0.0121849995f), + Q31( 0.0132718220f), Q31( 0.0143904666f), Q31( 0.0155405553f), Q31( 0.0167324712f), + Q31( 0.0179433381f), Q31( 0.0191872431f), Q31( 0.0204531793f), Q31( 0.0217467550f), + Q31( 0.0230680169f), Q31( 0.0244160992f), Q31( 0.0257875847f), Q31( 0.0271859429f), + Q31( 0.0286072173f), Q31( 0.0300502657f), Q31( 0.0315017608f), Q31( 0.0329754081f), + Q31( 0.0344620948f), Q31( 0.0359697560f), Q31( 0.0374812850f), Q31( 0.0390053679f), + Q31( 0.0405349170f), Q31( 0.0420649094f), Q31( 0.0436097542f), Q31( 0.0451488405f), + Q31( 0.0466843027f), Q31( 0.0482165720f), Q31( 0.0497385755f), Q31( 0.0512556155f), + Q31( 0.0527630746f), Q31( 0.0542452768f), Q31( 0.0557173648f), Q31( 0.0571616450f), + Q31( 0.0585915683f), Q31( 0.0599837480f), Q31( 0.0613455171f), Q31( 0.0626857808f), + Q31( 0.0639715898f), Q31( 0.0652247106f), Q31( 0.0664367512f), Q31( 0.0676075985f), + Q31( 0.0687043828f), Q31( 0.0697630244f), Q31( 0.0707628710f), Q31( 0.0717002673f), + Q31( 0.0725682583f), Q31( 0.0733620255f), Q31( 0.0741003642f), Q31( 0.0747452558f), + Q31( 0.0753137336f), Q31( 0.0758008358f), Q31( 0.0761992479f), Q31( 0.0764992170f), + Q31( 0.0767093490f), Q31( 0.0768173975f), Q31( 0.0768230011f), Q31( 0.0767204924f), + Q31( 0.0765050718f), Q31( 0.0761748321f), Q31( 0.0757305756f), Q31( 0.0751576255f), + Q31( 0.0744664394f), Q31( 0.0736406005f), Q31( 0.0726774642f), Q31( 0.0715826364f), + Q31( 0.0703533073f), Q31( 0.0689664013f), Q31( 0.0674525021f), Q31( 0.0657690668f), + Q31( 0.0639444805f), Q31( 0.0619602779f), Q31( 0.0598166570f), Q31( 0.0575152691f), + Q31( 0.0550460034f), Q31( 0.0524093821f), Q31( 0.0495978676f), Q31( 0.0466303305f), + Q31( 0.0434768782f), Q31( 0.0401458278f), Q31( 0.0366418116f), Q31( 0.0329583930f), + Q31( 0.0290824006f), Q31( 0.0250307561f), Q31( 0.0207997072f), Q31( 0.0163701258f), + Q31( 0.0117623832f), Q31( 0.0069636862f), Q31( 0.0019765601f), Q31(-0.0032086896f), + Q31(-0.0085711749f), Q31(-0.0141288827f), Q31(-0.0198834129f), Q31(-0.0258227288f), + Q31(-0.0319531274f), Q31(-0.0382776572f), Q31(-0.0447806821f), Q31(-0.0514804176f), + Q31(-0.0583705326f), Q31(-0.0654409853f), Q31(-0.0726943300f), Q31(-0.0801372934f), + Q31(-0.0877547536f), Q31(-0.0955533352f), Q31(-0.1035329531f), Q31(-0.1116826931f), + Q31(-0.1200077984f), Q31(-0.1285002850f), Q31(-0.1371551761f), Q31(-0.1459766491f), + Q31(-0.1549607071f), Q31(-0.1640958855f), Q31(-0.1733808172f), Q31(-0.1828172548f), + Q31(-0.1923966745f), Q31(-0.2021250176f), Q31(-0.2119735853f), Q31(-0.2219652696f), + Q31(-0.2320690870f), Q31(-0.2423016884f), Q31(-0.2526480309f), Q31(-0.2631053299f), + Q31(-0.2736634040f), Q31(-0.2843214189f), Q31(-0.2950716717f), Q31(-0.3059098575f), + Q31(-0.3168278913f), Q31(-0.3278113727f), Q31(-0.3388722693f), Q31(-0.3499914122f), + Q31( 0.3611589903f), Q31( 0.3723795546f), Q31( 0.3836350013f), Q31( 0.3949211761f), + Q31( 0.4062317676f), Q31( 0.4175696896f), Q31( 0.4289119920f), Q31( 0.4402553754f), + Q31( 0.4515996535f), Q31( 0.4629308085f), Q31( 0.4742453214f), Q31( 0.4855253091f), + Q31( 0.4967708254f), Q31( 0.5079817500f), Q31( 0.5191234970f), Q31( 0.5302240895f), + Q31( 0.5412553448f), Q31( 0.5522051258f), Q31( 0.5630789140f), Q31( 0.5738524131f), + Q31( 0.5845403235f), Q31( 0.5951123086f), Q31( 0.6055783538f), Q31( 0.6159109932f), + Q31( 0.6261242695f), Q31( 0.6361980107f), Q31( 0.6461269695f), Q31( 0.6559016302f), + Q31( 0.6655139880f), Q31( 0.6749663190f), Q31( 0.6842353293f), Q31( 0.6933282376f), + Q31( 0.7022388719f), Q31( 0.7109410426f), Q31( 0.7194462634f), Q31( 0.7277448900f), + Q31( 0.7358211758f), Q31( 0.7436827863f), Q31( 0.7513137456f), Q31( 0.7587080760f), + Q31( 0.7658674865f), Q31( 0.7727780881f), Q31( 0.7794287519f), Q31( 0.7858353120f), + Q31( 0.7919735841f), Q31( 0.7978466413f), Q31( 0.8034485751f), Q31( 0.8087695004f), + Q31( 0.8138191270f), Q31( 0.8185776004f), Q31( 0.8230419890f), Q31( 0.8272275347f), + Q31( 0.8311038457f), Q31( 0.8346937361f), Q31( 0.8379717337f), Q31( 0.8409541392f), + Q31( 0.8436238281f), Q31( 0.8459818469f), Q31( 0.8480315777f), Q31( 0.8497805198f), + Q31( 0.8511971524f), Q31( 0.8523047035f), Q31( 0.8531020949f), Q31( 0.8535720573f), + Q31( 0.8537385600f), +}; + +#endif /* AVCODEC_AACSBR_TABLEGEN_COMMON_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_template.c new file mode 100644 index 000000000..821615f2a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbr_template.c @@ -0,0 +1,1583 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2009-2010 Alex Converse + * + * Fixed point code + * Copyright (c) 2013 + * MIPS Technologies, Inc., California. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC Spectral Band Replication decoding functions + * @author Robert Swain ( rob opendot cl ) + * @author Stanislav Ocovaj ( stanislav.ocovaj@imgtec.com ) + * @author Zoran Basaric ( zoran.basaric@imgtec.com ) + */ + +#include "libavutil/qsort.h" + +static av_cold void aacsbr_tableinit(void) +{ + int n; + for (n = 1; n < 320; n++) + sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n]; + sbr_qmf_window_us[384] = -sbr_qmf_window_us[384]; + sbr_qmf_window_us[512] = -sbr_qmf_window_us[512]; + + for (n = 0; n < 320; n++) + sbr_qmf_window_ds[n] = sbr_qmf_window_us[2*n]; +} + +av_cold void AAC_RENAME(ff_aac_sbr_init)(void) +{ + static const struct { + const void *sbr_codes, *sbr_bits; + const unsigned int table_size, elem_size; + } sbr_tmp[] = { + SBR_VLC_ROW(t_huffman_env_1_5dB), + SBR_VLC_ROW(f_huffman_env_1_5dB), + SBR_VLC_ROW(t_huffman_env_bal_1_5dB), + SBR_VLC_ROW(f_huffman_env_bal_1_5dB), + SBR_VLC_ROW(t_huffman_env_3_0dB), + SBR_VLC_ROW(f_huffman_env_3_0dB), + SBR_VLC_ROW(t_huffman_env_bal_3_0dB), + SBR_VLC_ROW(f_huffman_env_bal_3_0dB), + SBR_VLC_ROW(t_huffman_noise_3_0dB), + SBR_VLC_ROW(t_huffman_noise_bal_3_0dB), + }; + + // SBR VLC table initialization + SBR_INIT_VLC_STATIC(0, 1098); + SBR_INIT_VLC_STATIC(1, 1092); + SBR_INIT_VLC_STATIC(2, 768); + SBR_INIT_VLC_STATIC(3, 1026); + SBR_INIT_VLC_STATIC(4, 1058); + SBR_INIT_VLC_STATIC(5, 1052); + SBR_INIT_VLC_STATIC(6, 544); + SBR_INIT_VLC_STATIC(7, 544); + SBR_INIT_VLC_STATIC(8, 592); + SBR_INIT_VLC_STATIC(9, 512); + + aacsbr_tableinit(); + + AAC_RENAME(ff_ps_init)(); +} + +/** Places SBR in pure upsampling mode. */ +static void sbr_turnoff(SpectralBandReplication *sbr) { + sbr->start = 0; + sbr->ready_for_dequant = 0; + // Init defults used in pure upsampling mode + sbr->kx[1] = 32; //Typo in spec, kx' inits to 32 + sbr->m[1] = 0; + // Reset values for first SBR header + sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1; + memset(&sbr->spectrum_params, -1, sizeof(SpectrumParameters)); +} + +av_cold void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr, int id_aac) +{ + if(sbr->mdct.mdct_bits) + return; + sbr->kx[0] = sbr->kx[1]; + sbr->id_aac = id_aac; + sbr_turnoff(sbr); + sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); + sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); + /* SBR requires samples to be scaled to +/-32768.0 to work correctly. + * mdct scale factors are adjusted to scale up from +/-1.0 at analysis + * and scale back down at synthesis. */ + AAC_RENAME_32(ff_mdct_init)(&sbr->mdct, 7, 1, 1.0 / (64 * 32768.0)); + AAC_RENAME_32(ff_mdct_init)(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0); + AAC_RENAME(ff_ps_ctx_init)(&sbr->ps); + AAC_RENAME(ff_sbrdsp_init)(&sbr->dsp); + aacsbr_func_ptr_init(&sbr->c); +} + +av_cold void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr) +{ + AAC_RENAME_32(ff_mdct_end)(&sbr->mdct); + AAC_RENAME_32(ff_mdct_end)(&sbr->mdct_ana); +} + +static int qsort_comparison_function_int16(const void *a, const void *b) +{ + return *(const int16_t *)a - *(const int16_t *)b; +} + +static inline int in_table_int16(const int16_t *table, int last_el, int16_t needle) +{ + int i; + for (i = 0; i <= last_el; i++) + if (table[i] == needle) + return 1; + return 0; +} + +/// Limiter Frequency Band Table (14496-3 sp04 p198) +static void sbr_make_f_tablelim(SpectralBandReplication *sbr) +{ + int k; + if (sbr->bs_limiter_bands > 0) { + static const INTFLOAT bands_warped[3] = { Q23(1.32715174233856803909f), //2^(0.49/1.2) + Q23(1.18509277094158210129f), //2^(0.49/2) + Q23(1.11987160404675912501f) }; //2^(0.49/3) + const INTFLOAT lim_bands_per_octave_warped = bands_warped[sbr->bs_limiter_bands - 1]; + int16_t patch_borders[7]; + uint16_t *in = sbr->f_tablelim + 1, *out = sbr->f_tablelim; + + patch_borders[0] = sbr->kx[1]; + for (k = 1; k <= sbr->num_patches; k++) + patch_borders[k] = patch_borders[k-1] + sbr->patch_num_subbands[k-1]; + + memcpy(sbr->f_tablelim, sbr->f_tablelow, + (sbr->n[0] + 1) * sizeof(sbr->f_tablelow[0])); + if (sbr->num_patches > 1) + memcpy(sbr->f_tablelim + sbr->n[0] + 1, patch_borders + 1, + (sbr->num_patches - 1) * sizeof(patch_borders[0])); + + AV_QSORT(sbr->f_tablelim, sbr->num_patches + sbr->n[0], + uint16_t, + qsort_comparison_function_int16); + + sbr->n_lim = sbr->n[0] + sbr->num_patches - 1; + while (out < sbr->f_tablelim + sbr->n_lim) { +#if USE_FIXED + if ((*in << 23) >= *out * lim_bands_per_octave_warped) { +#else + if (*in >= *out * lim_bands_per_octave_warped) { +#endif /* USE_FIXED */ + *++out = *in++; + } else if (*in == *out || + !in_table_int16(patch_borders, sbr->num_patches, *in)) { + in++; + sbr->n_lim--; + } else if (!in_table_int16(patch_borders, sbr->num_patches, *out)) { + *out = *in++; + sbr->n_lim--; + } else { + *++out = *in++; + } + } + } else { + sbr->f_tablelim[0] = sbr->f_tablelow[0]; + sbr->f_tablelim[1] = sbr->f_tablelow[sbr->n[0]]; + sbr->n_lim = 1; + } +} + +static unsigned int read_sbr_header(SpectralBandReplication *sbr, GetBitContext *gb) +{ + unsigned int cnt = get_bits_count(gb); + uint8_t bs_header_extra_1; + uint8_t bs_header_extra_2; + int old_bs_limiter_bands = sbr->bs_limiter_bands; + SpectrumParameters old_spectrum_params; + + sbr->start = 1; + sbr->ready_for_dequant = 0; + + // Save last spectrum parameters variables to compare to new ones + memcpy(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters)); + + sbr->bs_amp_res_header = get_bits1(gb); + sbr->spectrum_params.bs_start_freq = get_bits(gb, 4); + sbr->spectrum_params.bs_stop_freq = get_bits(gb, 4); + sbr->spectrum_params.bs_xover_band = get_bits(gb, 3); + skip_bits(gb, 2); // bs_reserved + + bs_header_extra_1 = get_bits1(gb); + bs_header_extra_2 = get_bits1(gb); + + if (bs_header_extra_1) { + sbr->spectrum_params.bs_freq_scale = get_bits(gb, 2); + sbr->spectrum_params.bs_alter_scale = get_bits1(gb); + sbr->spectrum_params.bs_noise_bands = get_bits(gb, 2); + } else { + sbr->spectrum_params.bs_freq_scale = 2; + sbr->spectrum_params.bs_alter_scale = 1; + sbr->spectrum_params.bs_noise_bands = 2; + } + + // Check if spectrum parameters changed + if (memcmp(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters))) + sbr->reset = 1; + + if (bs_header_extra_2) { + sbr->bs_limiter_bands = get_bits(gb, 2); + sbr->bs_limiter_gains = get_bits(gb, 2); + sbr->bs_interpol_freq = get_bits1(gb); + sbr->bs_smoothing_mode = get_bits1(gb); + } else { + sbr->bs_limiter_bands = 2; + sbr->bs_limiter_gains = 2; + sbr->bs_interpol_freq = 1; + sbr->bs_smoothing_mode = 1; + } + + if (sbr->bs_limiter_bands != old_bs_limiter_bands && !sbr->reset) + sbr_make_f_tablelim(sbr); + + return get_bits_count(gb) - cnt; +} + +static int array_min_int16(const int16_t *array, int nel) +{ + int i, min = array[0]; + for (i = 1; i < nel; i++) + min = FFMIN(array[i], min); + return min; +} + +static int check_n_master(AVCodecContext *avctx, int n_master, int bs_xover_band) +{ + // Requirements (14496-3 sp04 p205) + if (n_master <= 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid n_master: %d\n", n_master); + return -1; + } + if (bs_xover_band >= n_master) { + av_log(avctx, AV_LOG_ERROR, + "Invalid bitstream, crossover band index beyond array bounds: %d\n", + bs_xover_band); + return -1; + } + return 0; +} + +/// Master Frequency Band Table (14496-3 sp04 p194) +static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr, + SpectrumParameters *spectrum) +{ + unsigned int temp, max_qmf_subbands = 0; + unsigned int start_min, stop_min; + int k; + const int8_t *sbr_offset_ptr; + int16_t stop_dk[13]; + + switch (sbr->sample_rate) { + case 16000: + sbr_offset_ptr = sbr_offset[0]; + break; + case 22050: + sbr_offset_ptr = sbr_offset[1]; + break; + case 24000: + sbr_offset_ptr = sbr_offset[2]; + break; + case 32000: + sbr_offset_ptr = sbr_offset[3]; + break; + case 44100: case 48000: case 64000: + sbr_offset_ptr = sbr_offset[4]; + break; + case 88200: case 96000: case 128000: case 176400: case 192000: + sbr_offset_ptr = sbr_offset[5]; + break; + default: + av_log(ac->avctx, AV_LOG_ERROR, + "Unsupported sample rate for SBR: %d\n", sbr->sample_rate); + return -1; + } + + if (sbr->sample_rate < 32000) { + temp = 3000; + } else if (sbr->sample_rate < 64000) { + temp = 4000; + } else + temp = 5000; + + start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate; + stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate; + + sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq]; + + if (spectrum->bs_stop_freq < 14) { + sbr->k[2] = stop_min; + make_bands(stop_dk, stop_min, 64, 13); + AV_QSORT(stop_dk, 13, int16_t, qsort_comparison_function_int16); + for (k = 0; k < spectrum->bs_stop_freq; k++) + sbr->k[2] += stop_dk[k]; + } else if (spectrum->bs_stop_freq == 14) { + sbr->k[2] = 2*sbr->k[0]; + } else if (spectrum->bs_stop_freq == 15) { + sbr->k[2] = 3*sbr->k[0]; + } else { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bs_stop_freq: %d\n", spectrum->bs_stop_freq); + return -1; + } + sbr->k[2] = FFMIN(64, sbr->k[2]); + + // Requirements (14496-3 sp04 p205) + if (sbr->sample_rate <= 32000) { + max_qmf_subbands = 48; + } else if (sbr->sample_rate == 44100) { + max_qmf_subbands = 35; + } else if (sbr->sample_rate >= 48000) + max_qmf_subbands = 32; + else + av_assert0(0); + + if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream, too many QMF subbands: %d\n", sbr->k[2] - sbr->k[0]); + return -1; + } + + if (!spectrum->bs_freq_scale) { + int dk, k2diff; + + dk = spectrum->bs_alter_scale + 1; + sbr->n_master = ((sbr->k[2] - sbr->k[0] + (dk&2)) >> dk) << 1; + if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band)) + return -1; + + for (k = 1; k <= sbr->n_master; k++) + sbr->f_master[k] = dk; + + k2diff = sbr->k[2] - sbr->k[0] - sbr->n_master * dk; + if (k2diff < 0) { + sbr->f_master[1]--; + sbr->f_master[2]-= (k2diff < -1); + } else if (k2diff) { + sbr->f_master[sbr->n_master]++; + } + + sbr->f_master[0] = sbr->k[0]; + for (k = 1; k <= sbr->n_master; k++) + sbr->f_master[k] += sbr->f_master[k - 1]; + + } else { + int half_bands = 7 - spectrum->bs_freq_scale; // bs_freq_scale = {1,2,3} + int two_regions, num_bands_0; + int vdk0_max, vdk1_min; + int16_t vk0[49]; +#if USE_FIXED + int tmp, nz = 0; +#endif /* USE_FIXED */ + + if (49 * sbr->k[2] > 110 * sbr->k[0]) { + two_regions = 1; + sbr->k[1] = 2 * sbr->k[0]; + } else { + two_regions = 0; + sbr->k[1] = sbr->k[2]; + } + +#if USE_FIXED + tmp = (sbr->k[1] << 23) / sbr->k[0]; + while (tmp < 0x40000000) { + tmp <<= 1; + nz++; + } + tmp = fixed_log(tmp - 0x80000000); + tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30); + tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands; + num_bands_0 = ((tmp + 0x400000) >> 23) * 2; +#else + num_bands_0 = lrintf(half_bands * log2f(sbr->k[1] / (float)sbr->k[0])) * 2; +#endif /* USE_FIXED */ + + if (num_bands_0 <= 0) { // Requirements (14496-3 sp04 p205) + av_log(ac->avctx, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0); + return -1; + } + + vk0[0] = 0; + + make_bands(vk0+1, sbr->k[0], sbr->k[1], num_bands_0); + + AV_QSORT(vk0 + 1, num_bands_0, int16_t, qsort_comparison_function_int16); + vdk0_max = vk0[num_bands_0]; + + vk0[0] = sbr->k[0]; + for (k = 1; k <= num_bands_0; k++) { + if (vk0[k] <= 0) { // Requirements (14496-3 sp04 p205) + av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk0[%d]: %d\n", k, vk0[k]); + return -1; + } + vk0[k] += vk0[k-1]; + } + + if (two_regions) { + int16_t vk1[49]; +#if USE_FIXED + int num_bands_1; + + tmp = (sbr->k[2] << 23) / sbr->k[1]; + nz = 0; + while (tmp < 0x40000000) { + tmp <<= 1; + nz++; + } + tmp = fixed_log(tmp - 0x80000000); + tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30); + tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands; + if (spectrum->bs_alter_scale) + tmp = (int)(((int64_t)tmp * CONST_076923 + 0x40000000) >> 31); + num_bands_1 = ((tmp + 0x400000) >> 23) * 2; +#else + float invwarp = spectrum->bs_alter_scale ? 0.76923076923076923077f + : 1.0f; // bs_alter_scale = {0,1} + int num_bands_1 = lrintf(half_bands * invwarp * + log2f(sbr->k[2] / (float)sbr->k[1])) * 2; +#endif /* USE_FIXED */ + make_bands(vk1+1, sbr->k[1], sbr->k[2], num_bands_1); + + vdk1_min = array_min_int16(vk1 + 1, num_bands_1); + + if (vdk1_min < vdk0_max) { + int change; + AV_QSORT(vk1 + 1, num_bands_1, int16_t, qsort_comparison_function_int16); + change = FFMIN(vdk0_max - vk1[1], (vk1[num_bands_1] - vk1[1]) >> 1); + vk1[1] += change; + vk1[num_bands_1] -= change; + } + + AV_QSORT(vk1 + 1, num_bands_1, int16_t, qsort_comparison_function_int16); + + vk1[0] = sbr->k[1]; + for (k = 1; k <= num_bands_1; k++) { + if (vk1[k] <= 0) { // Requirements (14496-3 sp04 p205) + av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk1[%d]: %d\n", k, vk1[k]); + return -1; + } + vk1[k] += vk1[k-1]; + } + + sbr->n_master = num_bands_0 + num_bands_1; + if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band)) + return -1; + memcpy(&sbr->f_master[0], vk0, + (num_bands_0 + 1) * sizeof(sbr->f_master[0])); + memcpy(&sbr->f_master[num_bands_0 + 1], vk1 + 1, + num_bands_1 * sizeof(sbr->f_master[0])); + + } else { + sbr->n_master = num_bands_0; + if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band)) + return -1; + memcpy(sbr->f_master, vk0, (num_bands_0 + 1) * sizeof(sbr->f_master[0])); + } + } + + return 0; +} + +/// High Frequency Generation - Patch Construction (14496-3 sp04 p216 fig. 4.46) +static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr) +{ + int i, k, last_k = -1, last_msb = -1, sb = 0; + int msb = sbr->k[0]; + int usb = sbr->kx[1]; + int goal_sb = ((1000 << 11) + (sbr->sample_rate >> 1)) / sbr->sample_rate; + + sbr->num_patches = 0; + + if (goal_sb < sbr->kx[1] + sbr->m[1]) { + for (k = 0; sbr->f_master[k] < goal_sb; k++) ; + } else + k = sbr->n_master; + + do { + int odd = 0; + if (k == last_k && msb == last_msb) { + av_log(ac->avctx, AV_LOG_ERROR, "patch construction failed\n"); + return AVERROR_INVALIDDATA; + } + last_k = k; + last_msb = msb; + for (i = k; i == k || sb > (sbr->k[0] - 1 + msb - odd); i--) { + sb = sbr->f_master[i]; + odd = (sb + sbr->k[0]) & 1; + } + + // Requirements (14496-3 sp04 p205) sets the maximum number of patches to 5. + // After this check the final number of patches can still be six which is + // illegal however the Coding Technologies decoder check stream has a final + // count of 6 patches + if (sbr->num_patches > 5) { + av_log(ac->avctx, AV_LOG_ERROR, "Too many patches: %d\n", sbr->num_patches); + return -1; + } + + sbr->patch_num_subbands[sbr->num_patches] = FFMAX(sb - usb, 0); + sbr->patch_start_subband[sbr->num_patches] = sbr->k[0] - odd - sbr->patch_num_subbands[sbr->num_patches]; + + if (sbr->patch_num_subbands[sbr->num_patches] > 0) { + usb = sb; + msb = sb; + sbr->num_patches++; + } else + msb = sbr->kx[1]; + + if (sbr->f_master[k] - sb < 3) + k = sbr->n_master; + } while (sb != sbr->kx[1] + sbr->m[1]); + + if (sbr->num_patches > 1 && + sbr->patch_num_subbands[sbr->num_patches - 1] < 3) + sbr->num_patches--; + + return 0; +} + +/// Derived Frequency Band Tables (14496-3 sp04 p197) +static int sbr_make_f_derived(AACContext *ac, SpectralBandReplication *sbr) +{ + int k, temp; +#if USE_FIXED + int nz = 0; +#endif /* USE_FIXED */ + + sbr->n[1] = sbr->n_master - sbr->spectrum_params.bs_xover_band; + sbr->n[0] = (sbr->n[1] + 1) >> 1; + + memcpy(sbr->f_tablehigh, &sbr->f_master[sbr->spectrum_params.bs_xover_band], + (sbr->n[1] + 1) * sizeof(sbr->f_master[0])); + sbr->m[1] = sbr->f_tablehigh[sbr->n[1]] - sbr->f_tablehigh[0]; + sbr->kx[1] = sbr->f_tablehigh[0]; + + // Requirements (14496-3 sp04 p205) + if (sbr->kx[1] + sbr->m[1] > 64) { + av_log(ac->avctx, AV_LOG_ERROR, + "Stop frequency border too high: %d\n", sbr->kx[1] + sbr->m[1]); + return -1; + } + if (sbr->kx[1] > 32) { + av_log(ac->avctx, AV_LOG_ERROR, "Start frequency border too high: %d\n", sbr->kx[1]); + return -1; + } + + sbr->f_tablelow[0] = sbr->f_tablehigh[0]; + temp = sbr->n[1] & 1; + for (k = 1; k <= sbr->n[0]; k++) + sbr->f_tablelow[k] = sbr->f_tablehigh[2 * k - temp]; +#if USE_FIXED + temp = (sbr->k[2] << 23) / sbr->kx[1]; + while (temp < 0x40000000) { + temp <<= 1; + nz++; + } + temp = fixed_log(temp - 0x80000000); + temp = (int)(((int64_t)temp * CONST_RECIP_LN2 + 0x20000000) >> 30); + temp = (((temp + 0x80) >> 8) + ((8 - nz) << 23)) * sbr->spectrum_params.bs_noise_bands; + + sbr->n_q = (temp + 0x400000) >> 23; + if (sbr->n_q < 1) + sbr->n_q = 1; +#else + sbr->n_q = FFMAX(1, lrintf(sbr->spectrum_params.bs_noise_bands * + log2f(sbr->k[2] / (float)sbr->kx[1]))); // 0 <= bs_noise_bands <= 3 +#endif /* USE_FIXED */ + + if (sbr->n_q > 5) { + av_log(ac->avctx, AV_LOG_ERROR, "Too many noise floor scale factors: %d\n", sbr->n_q); + return -1; + } + + sbr->f_tablenoise[0] = sbr->f_tablelow[0]; + temp = 0; + for (k = 1; k <= sbr->n_q; k++) { + temp += (sbr->n[0] - temp) / (sbr->n_q + 1 - k); + sbr->f_tablenoise[k] = sbr->f_tablelow[temp]; + } + + if (sbr_hf_calc_npatches(ac, sbr) < 0) + return -1; + + sbr_make_f_tablelim(sbr); + + sbr->data[0].f_indexnoise = 0; + sbr->data[1].f_indexnoise = 0; + + return 0; +} + +static av_always_inline void get_bits1_vector(GetBitContext *gb, uint8_t *vec, + int elements) +{ + int i; + for (i = 0; i < elements; i++) { + vec[i] = get_bits1(gb); + } +} + +/** ceil(log2(index+1)) */ +static const int8_t ceil_log2[] = { + 0, 1, 2, 2, 3, 3, +}; + +static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb, SBRData *ch_data) +{ + int i; + int bs_pointer = 0; + // frameLengthFlag ? 15 : 16; 960 sample length frames unsupported; this value is numTimeSlots + int abs_bord_trail = 16; + int num_rel_lead, num_rel_trail; + unsigned bs_num_env_old = ch_data->bs_num_env; + int bs_frame_class, bs_num_env; + + ch_data->bs_freq_res[0] = ch_data->bs_freq_res[ch_data->bs_num_env]; + ch_data->bs_amp_res = sbr->bs_amp_res_header; + ch_data->t_env_num_env_old = ch_data->t_env[bs_num_env_old]; + + switch (bs_frame_class = get_bits(gb, 2)) { + case FIXFIX: + bs_num_env = 1 << get_bits(gb, 2); + if (bs_num_env > 4) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n", + bs_num_env); + return -1; + } + ch_data->bs_num_env = bs_num_env; + num_rel_lead = ch_data->bs_num_env - 1; + if (ch_data->bs_num_env == 1) + ch_data->bs_amp_res = 0; + + + ch_data->t_env[0] = 0; + ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; + + abs_bord_trail = (abs_bord_trail + (ch_data->bs_num_env >> 1)) / + ch_data->bs_num_env; + for (i = 0; i < num_rel_lead; i++) + ch_data->t_env[i + 1] = ch_data->t_env[i] + abs_bord_trail; + + ch_data->bs_freq_res[1] = get_bits1(gb); + for (i = 1; i < ch_data->bs_num_env; i++) + ch_data->bs_freq_res[i + 1] = ch_data->bs_freq_res[1]; + break; + case FIXVAR: + abs_bord_trail += get_bits(gb, 2); + num_rel_trail = get_bits(gb, 2); + ch_data->bs_num_env = num_rel_trail + 1; + ch_data->t_env[0] = 0; + ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; + + for (i = 0; i < num_rel_trail; i++) + ch_data->t_env[ch_data->bs_num_env - 1 - i] = + ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2; + + bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]); + + for (i = 0; i < ch_data->bs_num_env; i++) + ch_data->bs_freq_res[ch_data->bs_num_env - i] = get_bits1(gb); + break; + case VARFIX: + ch_data->t_env[0] = get_bits(gb, 2); + num_rel_lead = get_bits(gb, 2); + ch_data->bs_num_env = num_rel_lead + 1; + ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; + + for (i = 0; i < num_rel_lead; i++) + ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2; + + bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]); + + get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env); + break; + case VARVAR: + ch_data->t_env[0] = get_bits(gb, 2); + abs_bord_trail += get_bits(gb, 2); + num_rel_lead = get_bits(gb, 2); + num_rel_trail = get_bits(gb, 2); + bs_num_env = num_rel_lead + num_rel_trail + 1; + + if (bs_num_env > 5) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream, too many SBR envelopes in VARVAR type SBR frame: %d\n", + bs_num_env); + return -1; + } + ch_data->bs_num_env = bs_num_env; + + ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; + + for (i = 0; i < num_rel_lead; i++) + ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2; + for (i = 0; i < num_rel_trail; i++) + ch_data->t_env[ch_data->bs_num_env - 1 - i] = + ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2; + + bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]); + + get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env); + break; + } + ch_data->bs_frame_class = bs_frame_class; + + av_assert0(bs_pointer >= 0); + if (bs_pointer > ch_data->bs_num_env + 1) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream, bs_pointer points to a middle noise border outside the time borders table: %d\n", + bs_pointer); + return -1; + } + + for (i = 1; i <= ch_data->bs_num_env; i++) { + if (ch_data->t_env[i-1] >= ch_data->t_env[i]) { + av_log(ac->avctx, AV_LOG_ERROR, "Not strictly monotone time borders\n"); + return -1; + } + } + + ch_data->bs_num_noise = (ch_data->bs_num_env > 1) + 1; + + ch_data->t_q[0] = ch_data->t_env[0]; + ch_data->t_q[ch_data->bs_num_noise] = ch_data->t_env[ch_data->bs_num_env]; + if (ch_data->bs_num_noise > 1) { + int idx; + if (ch_data->bs_frame_class == FIXFIX) { + idx = ch_data->bs_num_env >> 1; + } else if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR + idx = ch_data->bs_num_env - FFMAX(bs_pointer - 1, 1); + } else { // VARFIX + if (!bs_pointer) + idx = 1; + else if (bs_pointer == 1) + idx = ch_data->bs_num_env - 1; + else // bs_pointer > 1 + idx = bs_pointer - 1; + } + ch_data->t_q[1] = ch_data->t_env[idx]; + } + + ch_data->e_a[0] = -(ch_data->e_a[1] != bs_num_env_old); // l_APrev + ch_data->e_a[1] = -1; + if ((ch_data->bs_frame_class & 1) && bs_pointer) { // FIXVAR or VARVAR and bs_pointer != 0 + ch_data->e_a[1] = ch_data->bs_num_env + 1 - bs_pointer; + } else if ((ch_data->bs_frame_class == 2) && (bs_pointer > 1)) // VARFIX and bs_pointer > 1 + ch_data->e_a[1] = bs_pointer - 1; + + return 0; +} + +static void copy_sbr_grid(SBRData *dst, const SBRData *src) { + //These variables are saved from the previous frame rather than copied + dst->bs_freq_res[0] = dst->bs_freq_res[dst->bs_num_env]; + dst->t_env_num_env_old = dst->t_env[dst->bs_num_env]; + dst->e_a[0] = -(dst->e_a[1] != dst->bs_num_env); + + //These variables are read from the bitstream and therefore copied + memcpy(dst->bs_freq_res+1, src->bs_freq_res+1, sizeof(dst->bs_freq_res)-sizeof(*dst->bs_freq_res)); + memcpy(dst->t_env, src->t_env, sizeof(dst->t_env)); + memcpy(dst->t_q, src->t_q, sizeof(dst->t_q)); + dst->bs_num_env = src->bs_num_env; + dst->bs_amp_res = src->bs_amp_res; + dst->bs_num_noise = src->bs_num_noise; + dst->bs_frame_class = src->bs_frame_class; + dst->e_a[1] = src->e_a[1]; +} + +/// Read how the envelope and noise floor data is delta coded +static void read_sbr_dtdf(SpectralBandReplication *sbr, GetBitContext *gb, + SBRData *ch_data) +{ + get_bits1_vector(gb, ch_data->bs_df_env, ch_data->bs_num_env); + get_bits1_vector(gb, ch_data->bs_df_noise, ch_data->bs_num_noise); +} + +/// Read inverse filtering data +static void read_sbr_invf(SpectralBandReplication *sbr, GetBitContext *gb, + SBRData *ch_data) +{ + int i; + + memcpy(ch_data->bs_invf_mode[1], ch_data->bs_invf_mode[0], 5 * sizeof(uint8_t)); + for (i = 0; i < sbr->n_q; i++) + ch_data->bs_invf_mode[0][i] = get_bits(gb, 2); +} + +static int read_sbr_envelope(AACContext *ac, SpectralBandReplication *sbr, GetBitContext *gb, + SBRData *ch_data, int ch) +{ + int bits; + int i, j, k; + VLC_TYPE (*t_huff)[2], (*f_huff)[2]; + int t_lav, f_lav; + const int delta = (ch == 1 && sbr->bs_coupling == 1) + 1; + const int odd = sbr->n[1] & 1; + + if (sbr->bs_coupling && ch) { + if (ch_data->bs_amp_res) { + bits = 5; + t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_3_0DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_3_0DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB]; + } else { + bits = 6; + t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_1_5DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_1_5DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_1_5DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_1_5DB]; + } + } else { + if (ch_data->bs_amp_res) { + bits = 6; + t_huff = vlc_sbr[T_HUFFMAN_ENV_3_0DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_3_0DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB]; + } else { + bits = 7; + t_huff = vlc_sbr[T_HUFFMAN_ENV_1_5DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_1_5DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_1_5DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_1_5DB]; + } + } + + for (i = 0; i < ch_data->bs_num_env; i++) { + if (ch_data->bs_df_env[i]) { + // bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame + if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) { + for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) { + ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i][j] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav); + if (ch_data->env_facs_q[i + 1][j] > 127U) { + av_log(ac->avctx, AV_LOG_ERROR, "env_facs_q %d is invalid\n", ch_data->env_facs_q[i + 1][j]); + return AVERROR_INVALIDDATA; + } + } + } else if (ch_data->bs_freq_res[i + 1]) { + for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) { + k = (j + odd) >> 1; // find k such that f_tablelow[k] <= f_tablehigh[j] < f_tablelow[k + 1] + ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav); + if (ch_data->env_facs_q[i + 1][j] > 127U) { + av_log(ac->avctx, AV_LOG_ERROR, "env_facs_q %d is invalid\n", ch_data->env_facs_q[i + 1][j]); + return AVERROR_INVALIDDATA; + } + } + } else { + for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) { + k = j ? 2*j - odd : 0; // find k such that f_tablehigh[k] == f_tablelow[j] + ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav); + if (ch_data->env_facs_q[i + 1][j] > 127U) { + av_log(ac->avctx, AV_LOG_ERROR, "env_facs_q %d is invalid\n", ch_data->env_facs_q[i + 1][j]); + return AVERROR_INVALIDDATA; + } + } + } + } else { + ch_data->env_facs_q[i + 1][0] = delta * get_bits(gb, bits); // bs_env_start_value_balance + for (j = 1; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) { + ch_data->env_facs_q[i + 1][j] = ch_data->env_facs_q[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav); + if (ch_data->env_facs_q[i + 1][j] > 127U) { + av_log(ac->avctx, AV_LOG_ERROR, "env_facs_q %d is invalid\n", ch_data->env_facs_q[i + 1][j]); + return AVERROR_INVALIDDATA; + } + } + } + } + + //assign 0th elements of env_facs_q from last elements + memcpy(ch_data->env_facs_q[0], ch_data->env_facs_q[ch_data->bs_num_env], + sizeof(ch_data->env_facs_q[0])); + + return 0; +} + +static int read_sbr_noise(AACContext *ac, SpectralBandReplication *sbr, GetBitContext *gb, + SBRData *ch_data, int ch) +{ + int i, j; + VLC_TYPE (*t_huff)[2], (*f_huff)[2]; + int t_lav, f_lav; + int delta = (ch == 1 && sbr->bs_coupling == 1) + 1; + + if (sbr->bs_coupling && ch) { + t_huff = vlc_sbr[T_HUFFMAN_NOISE_BAL_3_0DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_BAL_3_0DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB]; + } else { + t_huff = vlc_sbr[T_HUFFMAN_NOISE_3_0DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_3_0DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB]; + } + + for (i = 0; i < ch_data->bs_num_noise; i++) { + if (ch_data->bs_df_noise[i]) { + for (j = 0; j < sbr->n_q; j++) { + ch_data->noise_facs_q[i + 1][j] = ch_data->noise_facs_q[i][j] + delta * (get_vlc2(gb, t_huff, 9, 2) - t_lav); + if (ch_data->noise_facs_q[i + 1][j] > 30U) { + av_log(ac->avctx, AV_LOG_ERROR, "noise_facs_q %d is invalid\n", ch_data->noise_facs_q[i + 1][j]); + return AVERROR_INVALIDDATA; + } + } + } else { + ch_data->noise_facs_q[i + 1][0] = delta * get_bits(gb, 5); // bs_noise_start_value_balance or bs_noise_start_value_level + for (j = 1; j < sbr->n_q; j++) { + ch_data->noise_facs_q[i + 1][j] = ch_data->noise_facs_q[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav); + if (ch_data->noise_facs_q[i + 1][j] > 30U) { + av_log(ac->avctx, AV_LOG_ERROR, "noise_facs_q %d is invalid\n", ch_data->noise_facs_q[i + 1][j]); + return AVERROR_INVALIDDATA; + } + } + } + } + + //assign 0th elements of noise_facs_q from last elements + memcpy(ch_data->noise_facs_q[0], ch_data->noise_facs_q[ch_data->bs_num_noise], + sizeof(ch_data->noise_facs_q[0])); + return 0; +} + +static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb, + int bs_extension_id, int *num_bits_left) +{ + switch (bs_extension_id) { + case EXTENSION_ID_PS: + if (!ac->oc[1].m4ac.ps) { + av_log(ac->avctx, AV_LOG_ERROR, "Parametric Stereo signaled to be not-present but was found in the bitstream.\n"); + skip_bits_long(gb, *num_bits_left); // bs_fill_bits + *num_bits_left = 0; + } else { + *num_bits_left -= AAC_RENAME(ff_ps_read_data)(ac->avctx, gb, &sbr->ps, *num_bits_left); + ac->avctx->profile = FF_PROFILE_AAC_HE_V2; + } + break; + default: + // some files contain 0-padding + if (bs_extension_id || *num_bits_left > 16 || show_bits(gb, *num_bits_left)) + avpriv_request_sample(ac->avctx, "Reserved SBR extensions"); + skip_bits_long(gb, *num_bits_left); // bs_fill_bits + *num_bits_left = 0; + break; + } +} + +static int read_sbr_single_channel_element(AACContext *ac, + SpectralBandReplication *sbr, + GetBitContext *gb) +{ + int ret; + + if (get_bits1(gb)) // bs_data_extra + skip_bits(gb, 4); // bs_reserved + + if (read_sbr_grid(ac, sbr, gb, &sbr->data[0])) + return -1; + read_sbr_dtdf(sbr, gb, &sbr->data[0]); + read_sbr_invf(sbr, gb, &sbr->data[0]); + if((ret = read_sbr_envelope(ac, sbr, gb, &sbr->data[0], 0)) < 0) + return ret; + if((ret = read_sbr_noise(ac, sbr, gb, &sbr->data[0], 0)) < 0) + return ret; + + if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb))) + get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]); + + return 0; +} + +static int read_sbr_channel_pair_element(AACContext *ac, + SpectralBandReplication *sbr, + GetBitContext *gb) +{ + int ret; + + if (get_bits1(gb)) // bs_data_extra + skip_bits(gb, 8); // bs_reserved + + if ((sbr->bs_coupling = get_bits1(gb))) { + if (read_sbr_grid(ac, sbr, gb, &sbr->data[0])) + return -1; + copy_sbr_grid(&sbr->data[1], &sbr->data[0]); + read_sbr_dtdf(sbr, gb, &sbr->data[0]); + read_sbr_dtdf(sbr, gb, &sbr->data[1]); + read_sbr_invf(sbr, gb, &sbr->data[0]); + memcpy(sbr->data[1].bs_invf_mode[1], sbr->data[1].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0])); + memcpy(sbr->data[1].bs_invf_mode[0], sbr->data[0].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0])); + if((ret = read_sbr_envelope(ac, sbr, gb, &sbr->data[0], 0)) < 0) + return ret; + if((ret = read_sbr_noise(ac, sbr, gb, &sbr->data[0], 0)) < 0) + return ret; + if((ret = read_sbr_envelope(ac, sbr, gb, &sbr->data[1], 1)) < 0) + return ret; + if((ret = read_sbr_noise(ac, sbr, gb, &sbr->data[1], 1)) < 0) + return ret; + } else { + if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]) || + read_sbr_grid(ac, sbr, gb, &sbr->data[1])) + return -1; + read_sbr_dtdf(sbr, gb, &sbr->data[0]); + read_sbr_dtdf(sbr, gb, &sbr->data[1]); + read_sbr_invf(sbr, gb, &sbr->data[0]); + read_sbr_invf(sbr, gb, &sbr->data[1]); + if((ret = read_sbr_envelope(ac, sbr, gb, &sbr->data[0], 0)) < 0) + return ret; + if((ret = read_sbr_envelope(ac, sbr, gb, &sbr->data[1], 1)) < 0) + return ret; + if((ret = read_sbr_noise(ac, sbr, gb, &sbr->data[0], 0)) < 0) + return ret; + if((ret = read_sbr_noise(ac, sbr, gb, &sbr->data[1], 1)) < 0) + return ret; + } + + if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb))) + get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]); + if ((sbr->data[1].bs_add_harmonic_flag = get_bits1(gb))) + get_bits1_vector(gb, sbr->data[1].bs_add_harmonic, sbr->n[1]); + + return 0; +} + +static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb, int id_aac) +{ + unsigned int cnt = get_bits_count(gb); + + sbr->id_aac = id_aac; + sbr->ready_for_dequant = 1; + + if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) { + if (read_sbr_single_channel_element(ac, sbr, gb)) { + sbr_turnoff(sbr); + return get_bits_count(gb) - cnt; + } + } else if (id_aac == TYPE_CPE) { + if (read_sbr_channel_pair_element(ac, sbr, gb)) { + sbr_turnoff(sbr); + return get_bits_count(gb) - cnt; + } + } else { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream - cannot apply SBR to element type %d\n", id_aac); + sbr_turnoff(sbr); + return get_bits_count(gb) - cnt; + } + if (get_bits1(gb)) { // bs_extended_data + int num_bits_left = get_bits(gb, 4); // bs_extension_size + if (num_bits_left == 15) + num_bits_left += get_bits(gb, 8); // bs_esc_count + + num_bits_left <<= 3; + while (num_bits_left > 7) { + num_bits_left -= 2; + read_sbr_extension(ac, sbr, gb, get_bits(gb, 2), &num_bits_left); // bs_extension_id + } + if (num_bits_left < 0) { + av_log(ac->avctx, AV_LOG_ERROR, "SBR Extension over read.\n"); + } + if (num_bits_left > 0) + skip_bits(gb, num_bits_left); + } + + return get_bits_count(gb) - cnt; +} + +static void sbr_reset(AACContext *ac, SpectralBandReplication *sbr) +{ + int err; + err = sbr_make_f_master(ac, sbr, &sbr->spectrum_params); + if (err >= 0) + err = sbr_make_f_derived(ac, sbr); + if (err < 0) { + av_log(ac->avctx, AV_LOG_ERROR, + "SBR reset failed. Switching SBR to pure upsampling mode.\n"); + sbr_turnoff(sbr); + } +} + +/** + * Decode Spectral Band Replication extension data; reference: table 4.55. + * + * @param crc flag indicating the presence of CRC checksum + * @param cnt length of TYPE_FIL syntactic element in bytes + * + * @return Returns number of bytes consumed from the TYPE_FIL element. + */ +int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb_host, int crc, int cnt, int id_aac) +{ + unsigned int num_sbr_bits = 0, num_align_bits; + unsigned bytes_read; + GetBitContext gbc = *gb_host, *gb = &gbc; + skip_bits_long(gb_host, cnt*8 - 4); + + sbr->reset = 0; + + if (!sbr->sample_rate) + sbr->sample_rate = 2 * ac->oc[1].m4ac.sample_rate; //TODO use the nominal sample rate for arbitrary sample rate support + if (!ac->oc[1].m4ac.ext_sample_rate) + ac->oc[1].m4ac.ext_sample_rate = 2 * ac->oc[1].m4ac.sample_rate; + + if (crc) { + skip_bits(gb, 10); // bs_sbr_crc_bits; TODO - implement CRC check + num_sbr_bits += 10; + } + + //Save some state from the previous frame. + sbr->kx[0] = sbr->kx[1]; + sbr->m[0] = sbr->m[1]; + sbr->kx_and_m_pushed = 1; + + num_sbr_bits++; + if (get_bits1(gb)) // bs_header_flag + num_sbr_bits += read_sbr_header(sbr, gb); + + if (sbr->reset) + sbr_reset(ac, sbr); + + if (sbr->start) + num_sbr_bits += read_sbr_data(ac, sbr, gb, id_aac); + + num_align_bits = ((cnt << 3) - 4 - num_sbr_bits) & 7; + bytes_read = ((num_sbr_bits + num_align_bits + 4) >> 3); + + if (bytes_read > cnt) { + av_log(ac->avctx, AV_LOG_ERROR, + "Expected to read %d SBR bytes actually read %d.\n", cnt, bytes_read); + sbr_turnoff(sbr); + } + return cnt; +} + +/** + * Analysis QMF Bank (14496-3 sp04 p206) + * + * @param x pointer to the beginning of the first sample window + * @param W array of complex-valued samples split into subbands + */ +#ifndef sbr_qmf_analysis +#if USE_FIXED +static void sbr_qmf_analysis(AVFixedDSPContext *dsp, FFTContext *mdct, +#else +static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct, +#endif /* USE_FIXED */ + SBRDSPContext *sbrdsp, const INTFLOAT *in, INTFLOAT *x, + INTFLOAT z[320], INTFLOAT W[2][32][32][2], int buf_idx) +{ + int i; +#if USE_FIXED + int j; +#endif + memcpy(x , x+1024, (320-32)*sizeof(x[0])); + memcpy(x+288, in, 1024*sizeof(x[0])); + for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames + // are not supported + dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320); + sbrdsp->sum64x5(z); + sbrdsp->qmf_pre_shuffle(z); +#if USE_FIXED + for (j = 64; j < 128; j++) { + if (z[j] > 1<<24) { + av_log(NULL, AV_LOG_WARNING, + "sbr_qmf_analysis: value %09d too large, setting to %09d\n", + z[j], 1<<24); + z[j] = 1<<24; + } else if (z[j] < -(1<<24)) { + av_log(NULL, AV_LOG_WARNING, + "sbr_qmf_analysis: value %09d too small, setting to %09d\n", + z[j], -(1<<24)); + z[j] = -(1<<24); + } + } +#endif + mdct->imdct_half(mdct, z, z+64); + sbrdsp->qmf_post_shuffle(W[buf_idx][i], z); + x += 32; + } +} +#endif + +/** + * Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank + * (14496-3 sp04 p206) + */ +#ifndef sbr_qmf_synthesis +static void sbr_qmf_synthesis(FFTContext *mdct, +#if USE_FIXED + SBRDSPContext *sbrdsp, AVFixedDSPContext *dsp, +#else + SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp, +#endif /* USE_FIXED */ + INTFLOAT *out, INTFLOAT X[2][38][64], + INTFLOAT mdct_buf[2][64], + INTFLOAT *v0, int *v_off, const unsigned int div) +{ + int i, n; + const INTFLOAT *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us; + const int step = 128 >> div; + INTFLOAT *v; + for (i = 0; i < 32; i++) { + if (*v_off < step) { + int saved_samples = (1280 - 128) >> div; + memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(INTFLOAT)); + *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - step; + } else { + *v_off -= step; + } + v = v0 + *v_off; + if (div) { + for (n = 0; n < 32; n++) { + X[0][i][ n] = -X[0][i][n]; + X[0][i][32+n] = X[1][i][31-n]; + } + mdct->imdct_half(mdct, mdct_buf[0], X[0][i]); + sbrdsp->qmf_deint_neg(v, mdct_buf[0]); + } else { + sbrdsp->neg_odd_64(X[1][i]); + mdct->imdct_half(mdct, mdct_buf[0], X[0][i]); + mdct->imdct_half(mdct, mdct_buf[1], X[1][i]); + sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]); + } + dsp->vector_fmul (out, v , sbr_qmf_window , 64 >> div); + dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 512 >> div), sbr_qmf_window + (256 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 704 >> div), sbr_qmf_window + (320 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 768 >> div), sbr_qmf_window + (384 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 960 >> div), sbr_qmf_window + (448 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + (1024 >> div), sbr_qmf_window + (512 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + (1216 >> div), sbr_qmf_window + (576 >> div), out , 64 >> div); + out += 64 >> div; + } +} +#endif + +/// Generate the subband filtered lowband +static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr, + INTFLOAT X_low[32][40][2], const INTFLOAT W[2][32][32][2], + int buf_idx) +{ + int i, k; + const int t_HFGen = 8; + const int i_f = 32; + memset(X_low, 0, 32*sizeof(*X_low)); + for (k = 0; k < sbr->kx[1]; k++) { + for (i = t_HFGen; i < i_f + t_HFGen; i++) { + X_low[k][i][0] = W[buf_idx][i - t_HFGen][k][0]; + X_low[k][i][1] = W[buf_idx][i - t_HFGen][k][1]; + } + } + buf_idx = 1-buf_idx; + for (k = 0; k < sbr->kx[0]; k++) { + for (i = 0; i < t_HFGen; i++) { + X_low[k][i][0] = W[buf_idx][i + i_f - t_HFGen][k][0]; + X_low[k][i][1] = W[buf_idx][i + i_f - t_HFGen][k][1]; + } + } + return 0; +} + +/// High Frequency Generator (14496-3 sp04 p215) +static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr, + INTFLOAT X_high[64][40][2], const INTFLOAT X_low[32][40][2], + const INTFLOAT (*alpha0)[2], const INTFLOAT (*alpha1)[2], + const INTFLOAT bw_array[5], const uint8_t *t_env, + int bs_num_env) +{ + int j, x; + int g = 0; + int k = sbr->kx[1]; + for (j = 0; j < sbr->num_patches; j++) { + for (x = 0; x < sbr->patch_num_subbands[j]; x++, k++) { + const int p = sbr->patch_start_subband[j] + x; + while (g <= sbr->n_q && k >= sbr->f_tablenoise[g]) + g++; + g--; + + if (g < 0) { + av_log(ac->avctx, AV_LOG_ERROR, + "ERROR : no subband found for frequency %d\n", k); + return -1; + } + + sbr->dsp.hf_gen(X_high[k] + ENVELOPE_ADJUSTMENT_OFFSET, + X_low[p] + ENVELOPE_ADJUSTMENT_OFFSET, + alpha0[p], alpha1[p], bw_array[g], + 2 * t_env[0], 2 * t_env[bs_num_env]); + } + } + if (k < sbr->m[1] + sbr->kx[1]) + memset(X_high + k, 0, (sbr->m[1] + sbr->kx[1] - k) * sizeof(*X_high)); + + return 0; +} + +/// Generate the subband filtered lowband +static int sbr_x_gen(SpectralBandReplication *sbr, INTFLOAT X[2][38][64], + const INTFLOAT Y0[38][64][2], const INTFLOAT Y1[38][64][2], + const INTFLOAT X_low[32][40][2], int ch) +{ + int k, i; + const int i_f = 32; + const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0); + memset(X, 0, 2*sizeof(*X)); + for (k = 0; k < sbr->kx[0]; k++) { + for (i = 0; i < i_Temp; i++) { + X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0]; + X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1]; + } + } + for (; k < sbr->kx[0] + sbr->m[0]; k++) { + for (i = 0; i < i_Temp; i++) { + X[0][i][k] = Y0[i + i_f][k][0]; + X[1][i][k] = Y0[i + i_f][k][1]; + } + } + + for (k = 0; k < sbr->kx[1]; k++) { + for (i = i_Temp; i < 38; i++) { + X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0]; + X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1]; + } + } + for (; k < sbr->kx[1] + sbr->m[1]; k++) { + for (i = i_Temp; i < i_f; i++) { + X[0][i][k] = Y1[i][k][0]; + X[1][i][k] = Y1[i][k][1]; + } + } + return 0; +} + +/** High Frequency Adjustment (14496-3 sp04 p217) and Mapping + * (14496-3 sp04 p217) + */ +static int sbr_mapping(AACContext *ac, SpectralBandReplication *sbr, + SBRData *ch_data, int e_a[2]) +{ + int e, i, m; + + memset(ch_data->s_indexmapped[1], 0, 7*sizeof(ch_data->s_indexmapped[1])); + for (e = 0; e < ch_data->bs_num_env; e++) { + const unsigned int ilim = sbr->n[ch_data->bs_freq_res[e + 1]]; + uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; + int k; + + if (sbr->kx[1] != table[0]) { + av_log(ac->avctx, AV_LOG_ERROR, "kx != f_table{high,low}[0]. " + "Derived frequency tables were not regenerated.\n"); + sbr_turnoff(sbr); + return AVERROR_BUG; + } + for (i = 0; i < ilim; i++) + for (m = table[i]; m < table[i + 1]; m++) + sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i]; + + // ch_data->bs_num_noise > 1 => 2 noise floors + k = (ch_data->bs_num_noise > 1) && (ch_data->t_env[e] >= ch_data->t_q[1]); + for (i = 0; i < sbr->n_q; i++) + for (m = sbr->f_tablenoise[i]; m < sbr->f_tablenoise[i + 1]; m++) + sbr->q_mapped[e][m - sbr->kx[1]] = ch_data->noise_facs[k+1][i]; + + for (i = 0; i < sbr->n[1]; i++) { + if (ch_data->bs_add_harmonic_flag) { + const unsigned int m_midpoint = + (sbr->f_tablehigh[i] + sbr->f_tablehigh[i + 1]) >> 1; + + ch_data->s_indexmapped[e + 1][m_midpoint - sbr->kx[1]] = ch_data->bs_add_harmonic[i] * + (e >= e_a[1] || (ch_data->s_indexmapped[0][m_midpoint - sbr->kx[1]] == 1)); + } + } + + for (i = 0; i < ilim; i++) { + int additional_sinusoid_present = 0; + for (m = table[i]; m < table[i + 1]; m++) { + if (ch_data->s_indexmapped[e + 1][m - sbr->kx[1]]) { + additional_sinusoid_present = 1; + break; + } + } + memset(&sbr->s_mapped[e][table[i] - sbr->kx[1]], additional_sinusoid_present, + (table[i + 1] - table[i]) * sizeof(sbr->s_mapped[e][0])); + } + } + + memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0])); + return 0; +} + +/// Estimation of current envelope (14496-3 sp04 p218) +static void sbr_env_estimate(AAC_FLOAT (*e_curr)[48], INTFLOAT X_high[64][40][2], + SpectralBandReplication *sbr, SBRData *ch_data) +{ + int e, m; + int kx1 = sbr->kx[1]; + + if (sbr->bs_interpol_freq) { + for (e = 0; e < ch_data->bs_num_env; e++) { +#if USE_FIXED + const SoftFloat recip_env_size = av_int2sf(0x20000000 / (ch_data->t_env[e + 1] - ch_data->t_env[e]), 30); +#else + const float recip_env_size = 0.5f / (ch_data->t_env[e + 1] - ch_data->t_env[e]); +#endif /* USE_FIXED */ + int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; + int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; + + for (m = 0; m < sbr->m[1]; m++) { + AAC_FLOAT sum = sbr->dsp.sum_square(X_high[m+kx1] + ilb, iub - ilb); +#if USE_FIXED + e_curr[e][m] = av_mul_sf(sum, recip_env_size); +#else + e_curr[e][m] = sum * recip_env_size; +#endif /* USE_FIXED */ + } + } + } else { + int k, p; + + for (e = 0; e < ch_data->bs_num_env; e++) { + const int env_size = 2 * (ch_data->t_env[e + 1] - ch_data->t_env[e]); + int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; + int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; + const uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; + + for (p = 0; p < sbr->n[ch_data->bs_freq_res[e + 1]]; p++) { +#if USE_FIXED + SoftFloat sum = FLOAT_0; + const SoftFloat den = av_int2sf(0x20000000 / (env_size * (table[p + 1] - table[p])), 29); + for (k = table[p]; k < table[p + 1]; k++) { + sum = av_add_sf(sum, sbr->dsp.sum_square(X_high[k] + ilb, iub - ilb)); + } + sum = av_mul_sf(sum, den); +#else + float sum = 0.0f; + const int den = env_size * (table[p + 1] - table[p]); + + for (k = table[p]; k < table[p + 1]; k++) { + sum += sbr->dsp.sum_square(X_high[k] + ilb, iub - ilb); + } + sum /= den; +#endif /* USE_FIXED */ + for (k = table[p]; k < table[p + 1]; k++) { + e_curr[e][k - kx1] = sum; + } + } + } + } +} + +void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int id_aac, + INTFLOAT* L, INTFLOAT* R) +{ + int downsampled = ac->oc[1].m4ac.ext_sample_rate < sbr->sample_rate; + int ch; + int nch = (id_aac == TYPE_CPE) ? 2 : 1; + int err; + + if (id_aac != sbr->id_aac) { + av_log(ac->avctx, id_aac == TYPE_LFE ? AV_LOG_VERBOSE : AV_LOG_WARNING, + "element type mismatch %d != %d\n", id_aac, sbr->id_aac); + sbr_turnoff(sbr); + } + + if (sbr->start && !sbr->ready_for_dequant) { + av_log(ac->avctx, AV_LOG_ERROR, + "No quantized data read for sbr_dequant.\n"); + sbr_turnoff(sbr); + } + + if (!sbr->kx_and_m_pushed) { + sbr->kx[0] = sbr->kx[1]; + sbr->m[0] = sbr->m[1]; + } else { + sbr->kx_and_m_pushed = 0; + } + + if (sbr->start) { + sbr_dequant(sbr, id_aac); + sbr->ready_for_dequant = 0; + } + for (ch = 0; ch < nch; ch++) { + /* decode channel */ + sbr_qmf_analysis(ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples, + (INTFLOAT*)sbr->qmf_filter_scratch, + sbr->data[ch].W, sbr->data[ch].Ypos); + sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low, + (const INTFLOAT (*)[32][32][2]) sbr->data[ch].W, + sbr->data[ch].Ypos); + sbr->data[ch].Ypos ^= 1; + if (sbr->start) { + sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, + (const INTFLOAT (*)[40][2]) sbr->X_low, sbr->k[0]); + sbr_chirp(sbr, &sbr->data[ch]); + av_assert0(sbr->data[ch].bs_num_env > 0); + sbr_hf_gen(ac, sbr, sbr->X_high, + (const INTFLOAT (*)[40][2]) sbr->X_low, + (const INTFLOAT (*)[2]) sbr->alpha0, + (const INTFLOAT (*)[2]) sbr->alpha1, + sbr->data[ch].bw_array, sbr->data[ch].t_env, + sbr->data[ch].bs_num_env); + + // hf_adj + err = sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); + if (!err) { + sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]); + sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); + sbr->c.sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos], + (const INTFLOAT (*)[40][2]) sbr->X_high, + sbr, &sbr->data[ch], + sbr->data[ch].e_a); + } + } + + /* synthesis */ + sbr->c.sbr_x_gen(sbr, sbr->X[ch], + (const INTFLOAT (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos], + (const INTFLOAT (*)[64][2]) sbr->data[ch].Y[ sbr->data[ch].Ypos], + (const INTFLOAT (*)[40][2]) sbr->X_low, ch); + } + + if (ac->oc[1].m4ac.ps == 1) { + if (sbr->ps.start) { + AAC_RENAME(ff_ps_apply)(ac->avctx, &sbr->ps, sbr->X[0], sbr->X[1], sbr->kx[1] + sbr->m[1]); + } else { + memcpy(sbr->X[1], sbr->X[0], sizeof(sbr->X[0])); + } + nch = 2; + } + + sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp, + L, sbr->X[0], sbr->qmf_filter_scratch, + sbr->data[0].synthesis_filterbank_samples, + &sbr->data[0].synthesis_filterbank_samples_offset, + downsampled); + if (nch == 2) + sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp, + R, sbr->X[1], sbr->qmf_filter_scratch, + sbr->data[1].synthesis_filterbank_samples, + &sbr->data[1].synthesis_filterbank_samples_offset, + downsampled); +} + +static void aacsbr_func_ptr_init(AACSBRContext *c) +{ + c->sbr_lf_gen = sbr_lf_gen; + c->sbr_hf_assemble = sbr_hf_assemble; + c->sbr_x_gen = sbr_x_gen; + c->sbr_hf_inverse_filter = sbr_hf_inverse_filter; + +#if !USE_FIXED + if(ARCH_MIPS) + ff_aacsbr_func_ptr_init_mips(c); +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbrdata.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbrdata.h new file mode 100644 index 000000000..4ff8fae91 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aacsbrdata.h @@ -0,0 +1,535 @@ +/* + * AAC Spectral Band Replication decoding data + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC Spectral Band Replication decoding data + * @author Robert Swain ( rob opendot cl ) + */ + +#ifndef AVCODEC_AACSBRDATA_H +#define AVCODEC_AACSBRDATA_H + +#include +#include "libavutil/mem.h" +#include "aac_defines.h" + +///< Huffman tables for SBR + +static const uint8_t t_huffman_env_1_5dB_bits[121] = { + 18, 18, 18, 18, 18, 18, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 17, 18, 16, 17, 18, 17, + 16, 16, 16, 16, 15, 14, 14, 13, + 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 3, 2, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 12, 13, 14, + 14, 15, 16, 17, 16, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, +}; + +static const uint32_t t_huffman_env_1_5dB_codes[121] = { + 0x3ffd6, 0x3ffd7, 0x3ffd8, 0x3ffd9, 0x3ffda, 0x3ffdb, 0x7ffb8, 0x7ffb9, + 0x7ffba, 0x7ffbb, 0x7ffbc, 0x7ffbd, 0x7ffbe, 0x7ffbf, 0x7ffc0, 0x7ffc1, + 0x7ffc2, 0x7ffc3, 0x7ffc4, 0x7ffc5, 0x7ffc6, 0x7ffc7, 0x7ffc8, 0x7ffc9, + 0x7ffca, 0x7ffcb, 0x7ffcc, 0x7ffcd, 0x7ffce, 0x7ffcf, 0x7ffd0, 0x7ffd1, + 0x7ffd2, 0x7ffd3, 0x1ffe6, 0x3ffd4, 0x0fff0, 0x1ffe9, 0x3ffd5, 0x1ffe7, + 0x0fff1, 0x0ffec, 0x0ffed, 0x0ffee, 0x07ff4, 0x03ff9, 0x03ff7, 0x01ffa, + 0x01ff9, 0x00ffb, 0x007fc, 0x003fc, 0x001fd, 0x000fd, 0x0007d, 0x0003d, + 0x0001d, 0x0000d, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000c, 0x0001c, + 0x0003c, 0x0007c, 0x000fc, 0x001fc, 0x003fd, 0x00ffa, 0x01ff8, 0x03ff6, + 0x03ff8, 0x07ff5, 0x0ffef, 0x1ffe8, 0x0fff2, 0x7ffd4, 0x7ffd5, 0x7ffd6, + 0x7ffd7, 0x7ffd8, 0x7ffd9, 0x7ffda, 0x7ffdb, 0x7ffdc, 0x7ffdd, 0x7ffde, + 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, 0x7ffe4, 0x7ffe5, 0x7ffe6, + 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, 0x7ffec, 0x7ffed, 0x7ffee, + 0x7ffef, 0x7fff0, 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, + 0x7fff7, 0x7fff8, 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, + 0x7ffff, +}; + +static const uint8_t f_huffman_env_1_5dB_bits[121] = { + 19, 19, 20, 20, 20, 20, 20, 20, + 20, 19, 20, 20, 20, 20, 19, 20, + 19, 19, 20, 18, 20, 20, 20, 19, + 20, 20, 20, 19, 20, 19, 18, 19, + 18, 18, 17, 18, 17, 17, 17, 16, + 16, 16, 15, 15, 14, 13, 13, 12, + 12, 11, 10, 9, 9, 8, 7, 6, + 5, 4, 3, 2, 2, 3, 4, 5, + 6, 8, 8, 9, 10, 11, 11, 11, + 12, 12, 13, 13, 14, 14, 16, 16, + 17, 17, 18, 18, 18, 18, 18, 18, + 18, 20, 19, 20, 20, 20, 20, 20, + 20, 19, 20, 20, 20, 20, 19, 20, + 18, 20, 20, 19, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, +}; + +static const uint32_t f_huffman_env_1_5dB_codes[121] = { + 0x7ffe7, 0x7ffe8, 0xfffd2, 0xfffd3, 0xfffd4, 0xfffd5, 0xfffd6, 0xfffd7, + 0xfffd8, 0x7ffda, 0xfffd9, 0xfffda, 0xfffdb, 0xfffdc, 0x7ffdb, 0xfffdd, + 0x7ffdc, 0x7ffdd, 0xfffde, 0x3ffe4, 0xfffdf, 0xfffe0, 0xfffe1, 0x7ffde, + 0xfffe2, 0xfffe3, 0xfffe4, 0x7ffdf, 0xfffe5, 0x7ffe0, 0x3ffe8, 0x7ffe1, + 0x3ffe0, 0x3ffe9, 0x1ffef, 0x3ffe5, 0x1ffec, 0x1ffed, 0x1ffee, 0x0fff4, + 0x0fff3, 0x0fff0, 0x07ff7, 0x07ff6, 0x03ffa, 0x01ffa, 0x01ff9, 0x00ffa, + 0x00ff8, 0x007f9, 0x003fb, 0x001fc, 0x001fa, 0x000fb, 0x0007c, 0x0003c, + 0x0001c, 0x0000c, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000d, 0x0001d, + 0x0003d, 0x000fa, 0x000fc, 0x001fb, 0x003fa, 0x007f8, 0x007fa, 0x007fb, + 0x00ff9, 0x00ffb, 0x01ff8, 0x01ffb, 0x03ff8, 0x03ff9, 0x0fff1, 0x0fff2, + 0x1ffea, 0x1ffeb, 0x3ffe1, 0x3ffe2, 0x3ffea, 0x3ffe3, 0x3ffe6, 0x3ffe7, + 0x3ffeb, 0xfffe6, 0x7ffe2, 0xfffe7, 0xfffe8, 0xfffe9, 0xfffea, 0xfffeb, + 0xfffec, 0x7ffe3, 0xfffed, 0xfffee, 0xfffef, 0xffff0, 0x7ffe4, 0xffff1, + 0x3ffec, 0xffff2, 0xffff3, 0x7ffe5, 0x7ffe6, 0xffff4, 0xffff5, 0xffff6, + 0xffff7, 0xffff8, 0xffff9, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, + 0xfffff, +}; + +static const uint8_t t_huffman_env_bal_1_5dB_bits[49] = { + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 12, 11, 9, 7, 5, 3, + 1, 2, 4, 6, 8, 11, 12, 15, + 16, 16, 16, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, +}; + +static const uint32_t t_huffman_env_bal_1_5dB_codes[49] = { + 0x0ffe4, 0x0ffe5, 0x0ffe6, 0x0ffe7, 0x0ffe8, 0x0ffe9, 0x0ffea, 0x0ffeb, + 0x0ffec, 0x0ffed, 0x0ffee, 0x0ffef, 0x0fff0, 0x0fff1, 0x0fff2, 0x0fff3, + 0x0fff4, 0x0ffe2, 0x00ffc, 0x007fc, 0x001fe, 0x0007e, 0x0001e, 0x00006, + 0x00000, 0x00002, 0x0000e, 0x0003e, 0x000fe, 0x007fd, 0x00ffd, 0x07ff0, + 0x0ffe3, 0x0fff5, 0x0fff6, 0x0fff7, 0x0fff8, 0x0fff9, 0x0fffa, 0x1fff6, + 0x1fff7, 0x1fff8, 0x1fff9, 0x1fffa, 0x1fffb, 0x1fffc, 0x1fffd, 0x1fffe, + 0x1ffff, +}; + +static const uint8_t f_huffman_env_bal_1_5dB_bits[49] = { + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 16, + 17, 14, 11, 11, 8, 7, 4, 2, + 1, 3, 5, 6, 9, 11, 12, 15, + 16, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, + 19, +}; + +static const uint32_t f_huffman_env_bal_1_5dB_codes[49] = { + 0x3ffe2, 0x3ffe3, 0x3ffe4, 0x3ffe5, 0x3ffe6, 0x3ffe7, 0x3ffe8, 0x3ffe9, + 0x3ffea, 0x3ffeb, 0x3ffec, 0x3ffed, 0x3ffee, 0x3ffef, 0x3fff0, 0x0fff7, + 0x1fff0, 0x03ffc, 0x007fe, 0x007fc, 0x000fe, 0x0007e, 0x0000e, 0x00002, + 0x00000, 0x00006, 0x0001e, 0x0003e, 0x001fe, 0x007fd, 0x00ffe, 0x07ffa, + 0x0fff6, 0x3fff1, 0x3fff2, 0x3fff3, 0x3fff4, 0x3fff5, 0x3fff6, 0x3fff7, + 0x3fff8, 0x3fff9, 0x3fffa, 0x3fffb, 0x3fffc, 0x3fffd, 0x3fffe, 0x7fffe, + 0x7ffff, +}; + +static const uint8_t t_huffman_env_3_0dB_bits[63] = { + 18, 18, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 17, 16, 16, 16, 14, 14, 14, + 13, 12, 11, 8, 6, 4, 2, 1, + 3, 5, 7, 9, 11, 13, 14, 14, + 15, 16, 17, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, +}; + +static const uint32_t t_huffman_env_3_0dB_codes[63] = { + 0x3ffed, 0x3ffee, 0x7ffde, 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, + 0x7ffe4, 0x7ffe5, 0x7ffe6, 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, + 0x7ffec, 0x1fff4, 0x0fff7, 0x0fff9, 0x0fff8, 0x03ffb, 0x03ffa, 0x03ff8, + 0x01ffa, 0x00ffc, 0x007fc, 0x000fe, 0x0003e, 0x0000e, 0x00002, 0x00000, + 0x00006, 0x0001e, 0x0007e, 0x001fe, 0x007fd, 0x01ffb, 0x03ff9, 0x03ffc, + 0x07ffa, 0x0fff6, 0x1fff5, 0x3ffec, 0x7ffed, 0x7ffee, 0x7ffef, 0x7fff0, + 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, 0x7fff7, 0x7fff8, + 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, 0x7ffff, +}; + +static const uint8_t f_huffman_env_3_0dB_bits[63] = { + 20, 20, 20, 20, 20, 20, 20, 18, + 19, 19, 19, 19, 18, 18, 20, 19, + 17, 18, 17, 16, 16, 15, 14, 12, + 11, 10, 9, 8, 6, 4, 2, 1, + 3, 5, 8, 9, 10, 11, 12, 13, + 14, 15, 15, 16, 16, 17, 17, 18, + 18, 18, 20, 19, 19, 19, 20, 19, + 19, 20, 20, 20, 20, 20, 20, +}; + +static const uint32_t f_huffman_env_3_0dB_codes[63] = { + 0xffff0, 0xffff1, 0xffff2, 0xffff3, 0xffff4, 0xffff5, 0xffff6, 0x3fff3, + 0x7fff5, 0x7ffee, 0x7ffef, 0x7fff6, 0x3fff4, 0x3fff2, 0xffff7, 0x7fff0, + 0x1fff5, 0x3fff0, 0x1fff4, 0x0fff7, 0x0fff6, 0x07ff8, 0x03ffb, 0x00ffd, + 0x007fd, 0x003fd, 0x001fd, 0x000fd, 0x0003e, 0x0000e, 0x00002, 0x00000, + 0x00006, 0x0001e, 0x000fc, 0x001fc, 0x003fc, 0x007fc, 0x00ffc, 0x01ffc, + 0x03ffa, 0x07ff9, 0x07ffa, 0x0fff8, 0x0fff9, 0x1fff6, 0x1fff7, 0x3fff5, + 0x3fff6, 0x3fff1, 0xffff8, 0x7fff1, 0x7fff2, 0x7fff3, 0xffff9, 0x7fff7, + 0x7fff4, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, 0xfffff, +}; + +static const uint8_t t_huffman_env_bal_3_0dB_bits[25] = { + 13, 13, 13, 13, 13, 13, 13, 12, + 8, 7, 4, 3, 1, 2, 5, 6, + 9, 13, 13, 13, 13, 13, 13, 14, + 14, +}; + +static const uint16_t t_huffman_env_bal_3_0dB_codes[25] = { + 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x0ff8, + 0x00fe, 0x007e, 0x000e, 0x0006, 0x0000, 0x0002, 0x001e, 0x003e, + 0x01fe, 0x1ff9, 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, + 0x3fff, +}; + +static const uint8_t f_huffman_env_bal_3_0dB_bits[25] = { + 13, 13, 13, 13, 13, 14, 14, 11, + 8, 7, 4, 2, 1, 3, 5, 6, + 9, 12, 13, 14, 14, 14, 14, 14, + 14, +}; + +static const uint16_t f_huffman_env_bal_3_0dB_codes[25] = { + 0x1ff7, 0x1ff8, 0x1ff9, 0x1ffa, 0x1ffb, 0x3ff8, 0x3ff9, 0x07fc, + 0x00fe, 0x007e, 0x000e, 0x0002, 0x0000, 0x0006, 0x001e, 0x003e, + 0x01fe, 0x0ffa, 0x1ff6, 0x3ffa, 0x3ffb, 0x3ffc, 0x3ffd, 0x3ffe, + 0x3fff, +}; + +static const uint8_t t_huffman_noise_3_0dB_bits[63] = { + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 11, 8, 6, 4, 3, 1, + 2, 5, 8, 10, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 14, 14, +}; + +static const uint16_t t_huffman_noise_3_0dB_codes[63] = { + 0x1fce, 0x1fcf, 0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5, + 0x1fd6, 0x1fd7, 0x1fd8, 0x1fd9, 0x1fda, 0x1fdb, 0x1fdc, 0x1fdd, + 0x1fde, 0x1fdf, 0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5, + 0x1fe6, 0x1fe7, 0x07f2, 0x00fd, 0x003e, 0x000e, 0x0006, 0x0000, + 0x0002, 0x001e, 0x00fc, 0x03f8, 0x1fcc, 0x1fe8, 0x1fe9, 0x1fea, + 0x1feb, 0x1fec, 0x1fcd, 0x1fed, 0x1fee, 0x1fef, 0x1ff0, 0x1ff1, + 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x1ff9, + 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, 0x3fff, +}; + +static const uint8_t t_huffman_noise_bal_3_0dB_bits[25] = { + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 5, 2, 1, 3, 6, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, +}; + +static const uint8_t t_huffman_noise_bal_3_0dB_codes[25] = { + 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0x1c, 0x02, 0x00, 0x06, 0x3a, 0xf6, + 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, + 0xff, +}; + +static const int8_t sbr_offset[6][16] = { + {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, // fs_sbr = 16000 Hz + {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}, // fs_sbr = 22050 Hz + {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}, // fs_sbr = 24000 Hz + {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}, // fs_sbr = 32000 Hz + {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}, // 44100 Hz <= fs_sbr <= 64000 Hz + {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}, // 64000 Hz < fs_sbr +}; + +/* First eight entries repeated at end to simplify SIMD implementations. */ +const DECLARE_ALIGNED(16, INTFLOAT, AAC_RENAME(ff_sbr_noise_table))[][2] = { +{Q31(-0.99948153278296f), Q31(-0.59483417516607f)}, {Q31( 0.97113454393991f), Q31(-0.67528515225647f)}, +{Q31( 0.14130051758487f), Q31(-0.95090983575689f)}, {Q31(-0.47005496701697f), Q31(-0.37340549728647f)}, +{Q31( 0.80705063769351f), Q31( 0.29653668284408f)}, {Q31(-0.38981478896926f), Q31( 0.89572605717087f)}, +{Q31(-0.01053049862020f), Q31(-0.66959058036166f)}, {Q31(-0.91266367957293f), Q31(-0.11522938140034f)}, +{Q31( 0.54840422910309f), Q31( 0.75221367176302f)}, {Q31( 0.40009252867955f), Q31(-0.98929400334421f)}, +{Q31(-0.99867974711855f), Q31(-0.88147068645358f)}, {Q31(-0.95531076805040f), Q31( 0.90908757154593f)}, +{Q31(-0.45725933317144f), Q31(-0.56716323646760f)}, {Q31(-0.72929675029275f), Q31(-0.98008272727324f)}, +{Q31( 0.75622801399036f), Q31( 0.20950329995549f)}, {Q31( 0.07069442601050f), Q31(-0.78247898470706f)}, +{Q31( 0.74496252926055f), Q31(-0.91169004445807f)}, {Q31(-0.96440182703856f), Q31(-0.94739918296622f)}, +{Q31( 0.30424629369539f), Q31(-0.49438267012479f)}, {Q31( 0.66565033746925f), Q31( 0.64652935542491f)}, +{Q31( 0.91697008020594f), Q31( 0.17514097332009f)}, {Q31(-0.70774918760427f), Q31( 0.52548653416543f)}, +{Q31(-0.70051415345560f), Q31(-0.45340028808763f)}, {Q31(-0.99496513054797f), Q31(-0.90071908066973f)}, +{Q31( 0.98164490790123f), Q31(-0.77463155528697f)}, {Q31(-0.54671580548181f), Q31(-0.02570928536004f)}, +{Q31(-0.01689629065389f), Q31( 0.00287506445732f)}, {Q31(-0.86110349531986f), Q31( 0.42548583726477f)}, +{Q31(-0.98892980586032f), Q31(-0.87881132267556f)}, {Q31( 0.51756627678691f), Q31( 0.66926784710139f)}, +{Q31(-0.99635026409640f), Q31(-0.58107730574765f)}, {Q31(-0.99969370862163f), Q31( 0.98369989360250f)}, +{Q31( 0.55266258627194f), Q31( 0.59449057465591f)}, {Q31( 0.34581177741673f), Q31( 0.94879421061866f)}, +{Q31( 0.62664209577999f), Q31(-0.74402970906471f)}, {Q31(-0.77149701404973f), Q31(-0.33883658042801f)}, +{Q31(-0.91592244254432f), Q31( 0.03687901376713f)}, {Q31(-0.76285492357887f), Q31(-0.91371867919124f)}, +{Q31( 0.79788337195331f), Q31(-0.93180971199849f)}, {Q31( 0.54473080610200f), Q31(-0.11919206037186f)}, +{Q31(-0.85639281671058f), Q31( 0.42429854760451f)}, {Q31(-0.92882402971423f), Q31( 0.27871809078609f)}, +{Q31(-0.11708371046774f), Q31(-0.99800843444966f)}, {Q31( 0.21356749817493f), Q31(-0.90716295627033f)}, +{Q31(-0.76191692573909f), Q31( 0.99768118356265f)}, {Q31( 0.98111043100884f), Q31(-0.95854459734407f)}, +{Q31(-0.85913269895572f), Q31( 0.95766566168880f)}, {Q31(-0.93307242253692f), Q31( 0.49431757696466f)}, +{Q31( 0.30485754879632f), Q31(-0.70540034357529f)}, {Q31( 0.85289650925190f), Q31( 0.46766131791044f)}, +{Q31( 0.91328082618125f), Q31(-0.99839597361769f)}, {Q31(-0.05890199924154f), Q31( 0.70741827819497f)}, +{Q31( 0.28398686150148f), Q31( 0.34633555702188f)}, {Q31( 0.95258164539612f), Q31(-0.54893416026939f)}, +{Q31(-0.78566324168507f), Q31(-0.75568541079691f)}, {Q31(-0.95789495447877f), Q31(-0.20423194696966f)}, +{Q31( 0.82411158711197f), Q31( 0.96654618432562f)}, {Q31(-0.65185446735885f), Q31(-0.88734990773289f)}, +{Q31(-0.93643603134666f), Q31( 0.99870790442385f)}, {Q31( 0.91427159529618f), Q31(-0.98290505544444f)}, +{Q31(-0.70395684036886f), Q31( 0.58796798221039f)}, {Q31( 0.00563771969365f), Q31( 0.61768196727244f)}, +{Q31( 0.89065051931895f), Q31( 0.52783352697585f)}, {Q31(-0.68683707712762f), Q31( 0.80806944710339f)}, +{Q31( 0.72165342518718f), Q31(-0.69259857349564f)}, {Q31(-0.62928247730667f), Q31( 0.13627037407335f)}, +{Q31( 0.29938434065514f), Q31(-0.46051329682246f)}, {Q31(-0.91781958879280f), Q31(-0.74012716684186f)}, +{Q31( 0.99298717043688f), Q31( 0.40816610075661f)}, {Q31( 0.82368298622748f), Q31(-0.74036047190173f)}, +{Q31(-0.98512833386833f), Q31(-0.99972330709594f)}, {Q31(-0.95915368242257f), Q31(-0.99237800466040f)}, +{Q31(-0.21411126572790f), Q31(-0.93424819052545f)}, {Q31(-0.68821476106884f), Q31(-0.26892306315457f)}, +{Q31( 0.91851997982317f), Q31( 0.09358228901785f)}, {Q31(-0.96062769559127f), Q31( 0.36099095133739f)}, +{Q31( 0.51646184922287f), Q31(-0.71373332873917f)}, {Q31( 0.61130721139669f), Q31( 0.46950141175917f)}, +{Q31( 0.47336129371299f), Q31(-0.27333178296162f)}, {Q31( 0.90998308703519f), Q31( 0.96715662938132f)}, +{Q31( 0.44844799194357f), Q31( 0.99211574628306f)}, {Q31( 0.66614891079092f), Q31( 0.96590176169121f)}, +{Q31( 0.74922239129237f), Q31(-0.89879858826087f)}, {Q31(-0.99571588506485f), Q31( 0.52785521494349f)}, +{Q31( 0.97401082477563f), Q31(-0.16855870075190f)}, {Q31( 0.72683747733879f), Q31(-0.48060774432251f)}, +{Q31( 0.95432193457128f), Q31( 0.68849603408441f)}, {Q31(-0.72962208425191f), Q31(-0.76608443420917f)}, +{Q31(-0.85359479233537f), Q31( 0.88738125901579f)}, {Q31(-0.81412430338535f), Q31(-0.97480768049637f)}, +{Q31(-0.87930772356786f), Q31( 0.74748307690436f)}, {Q31(-0.71573331064977f), Q31(-0.98570608178923f)}, +{Q31( 0.83524300028228f), Q31( 0.83702537075163f)}, {Q31(-0.48086065601423f), Q31(-0.98848504923531f)}, +{Q31( 0.97139128574778f), Q31( 0.80093621198236f)}, {Q31( 0.51992825347895f), Q31( 0.80247631400510f)}, +{Q31(-0.00848591195325f), Q31(-0.76670128000486f)}, {Q31(-0.70294374303036f), Q31( 0.55359910445577f)}, +{Q31(-0.95894428168140f), Q31(-0.43265504344783f)}, {Q31( 0.97079252950321f), Q31( 0.09325857238682f)}, +{Q31(-0.92404293670797f), Q31( 0.85507704027855f)}, {Q31(-0.69506469500450f), Q31( 0.98633412625459f)}, +{Q31( 0.26559203620024f), Q31( 0.73314307966524f)}, {Q31( 0.28038443336943f), Q31( 0.14537913654427f)}, +{Q31(-0.74138124825523f), Q31( 0.99310339807762f)}, {Q31(-0.01752795995444f), Q31(-0.82616635284178f)}, +{Q31(-0.55126773094930f), Q31(-0.98898543862153f)}, {Q31( 0.97960898850996f), Q31(-0.94021446752851f)}, +{Q31(-0.99196309146936f), Q31( 0.67019017358456f)}, {Q31(-0.67684928085260f), Q31( 0.12631491649378f)}, +{Q31( 0.09140039465500f), Q31(-0.20537731453108f)}, {Q31(-0.71658965751996f), Q31(-0.97788200391224f)}, +{Q31( 0.81014640078925f), Q31( 0.53722648362443f)}, {Q31( 0.40616991671205f), Q31(-0.26469008598449f)}, +{Q31(-0.67680188682972f), Q31( 0.94502052337695f)}, {Q31( 0.86849774348749f), Q31(-0.18333598647899f)}, +{Q31(-0.99500381284851f), Q31(-0.02634122068550f)}, {Q31( 0.84329189340667f), Q31( 0.10406957462213f)}, +{Q31(-0.09215968531446f), Q31( 0.69540012101253f)}, {Q31( 0.99956173327206f), Q31(-0.12358542001404f)}, +{Q31(-0.79732779473535f), Q31(-0.91582524736159f)}, {Q31( 0.96349973642406f), Q31( 0.96640458041000f)}, +{Q31(-0.79942778496547f), Q31( 0.64323902822857f)}, {Q31(-0.11566039853896f), Q31( 0.28587846253726f)}, +{Q31(-0.39922954514662f), Q31( 0.94129601616966f)}, {Q31( 0.99089197565987f), Q31(-0.92062625581587f)}, +{Q31( 0.28631285179909f), Q31(-0.91035047143603f)}, {Q31(-0.83302725605608f), Q31(-0.67330410892084f)}, +{Q31( 0.95404443402072f), Q31( 0.49162765398743f)}, {Q31(-0.06449863579434f), Q31( 0.03250560813135f)}, +{Q31(-0.99575054486311f), Q31( 0.42389784469507f)}, {Q31(-0.65501142790847f), Q31( 0.82546114655624f)}, +{Q31(-0.81254441908887f), Q31(-0.51627234660629f)}, {Q31(-0.99646369485481f), Q31( 0.84490533520752f)}, +{Q31( 0.00287840603348f), Q31( 0.64768261158166f)}, {Q31( 0.70176989408455f), Q31(-0.20453028573322f)}, +{Q31( 0.96361882270190f), Q31( 0.40706967140989f)}, {Q31(-0.68883758192426f), Q31( 0.91338958840772f)}, +{Q31(-0.34875585502238f), Q31( 0.71472290693300f)}, {Q31( 0.91980081243087f), Q31( 0.66507455644919f)}, +{Q31(-0.99009048343881f), Q31( 0.85868021604848f)}, {Q31( 0.68865791458395f), Q31( 0.55660316809678f)}, +{Q31(-0.99484402129368f), Q31(-0.20052559254934f)}, {Q31( 0.94214511408023f), Q31(-0.99696425367461f)}, +{Q31(-0.67414626793544f), Q31( 0.49548221180078f)}, {Q31(-0.47339353684664f), Q31(-0.85904328834047f)}, +{Q31( 0.14323651387360f), Q31(-0.94145598222488f)}, {Q31(-0.29268293575672f), Q31( 0.05759224927952f)}, +{Q31( 0.43793861458754f), Q31(-0.78904969892724f)}, {Q31(-0.36345126374441f), Q31( 0.64874435357162f)}, +{Q31(-0.08750604656825f), Q31( 0.97686944362527f)}, {Q31(-0.96495267812511f), Q31(-0.53960305946511f)}, +{Q31( 0.55526940659947f), Q31( 0.78891523734774f)}, {Q31( 0.73538215752630f), Q31( 0.96452072373404f)}, +{Q31(-0.30889773919437f), Q31(-0.80664389776860f)}, {Q31( 0.03574995626194f), Q31(-0.97325616900959f)}, +{Q31( 0.98720684660488f), Q31( 0.48409133691962f)}, {Q31(-0.81689296271203f), Q31(-0.90827703628298f)}, +{Q31( 0.67866860118215f), Q31( 0.81284503870856f)}, {Q31(-0.15808569732583f), Q31( 0.85279555024382f)}, +{Q31( 0.80723395114371f), Q31(-0.24717418514605f)}, {Q31( 0.47788757329038f), Q31(-0.46333147839295f)}, +{Q31( 0.96367554763201f), Q31( 0.38486749303242f)}, {Q31(-0.99143875716818f), Q31(-0.24945277239809f)}, +{Q31( 0.83081876925833f), Q31(-0.94780851414763f)}, {Q31(-0.58753191905341f), Q31( 0.01290772389163f)}, +{Q31( 0.95538108220960f), Q31(-0.85557052096538f)}, {Q31(-0.96490920476211f), Q31(-0.64020970923102f)}, +{Q31(-0.97327101028521f), Q31( 0.12378128133110f)}, {Q31( 0.91400366022124f), Q31( 0.57972471346930f)}, +{Q31(-0.99925837363824f), Q31( 0.71084847864067f)}, {Q31(-0.86875903507313f), Q31(-0.20291699203564f)}, +{Q31(-0.26240034795124f), Q31(-0.68264554369108f)}, {Q31(-0.24664412953388f), Q31(-0.87642273115183f)}, +{Q31( 0.02416275806869f), Q31( 0.27192914288905f)}, {Q31( 0.82068619590515f), Q31(-0.85087787994476f)}, +{Q31( 0.88547373760759f), Q31(-0.89636802901469f)}, {Q31(-0.18173078152226f), Q31(-0.26152145156800f)}, +{Q31( 0.09355476558534f), Q31( 0.54845123045604f)}, {Q31(-0.54668414224090f), Q31( 0.95980774020221f)}, +{Q31( 0.37050990604091f), Q31(-0.59910140383171f)}, {Q31(-0.70373594262891f), Q31( 0.91227665827081f)}, +{Q31(-0.34600785879594f), Q31(-0.99441426144200f)}, {Q31(-0.68774481731008f), Q31(-0.30238837956299f)}, +{Q31(-0.26843291251234f), Q31( 0.83115668004362f)}, {Q31( 0.49072334613242f), Q31(-0.45359708737775f)}, +{Q31( 0.38975993093975f), Q31( 0.95515358099121f)}, {Q31(-0.97757125224150f), Q31( 0.05305894580606f)}, +{Q31(-0.17325552859616f), Q31(-0.92770672250494f)}, {Q31( 0.99948035025744f), Q31( 0.58285545563426f)}, +{Q31(-0.64946246527458f), Q31( 0.68645507104960f)}, {Q31(-0.12016920576437f), Q31(-0.57147322153312f)}, +{Q31(-0.58947456517751f), Q31(-0.34847132454388f)}, {Q31(-0.41815140454465f), Q31( 0.16276422358861f)}, +{Q31( 0.99885650204884f), Q31( 0.11136095490444f)}, {Q31(-0.56649614128386f), Q31(-0.90494866361587f)}, +{Q31( 0.94138021032330f), Q31( 0.35281916733018f)}, {Q31(-0.75725076534641f), Q31( 0.53650549640587f)}, +{Q31( 0.20541973692630f), Q31(-0.94435144369918f)}, {Q31( 0.99980371023351f), Q31( 0.79835913565599f)}, +{Q31( 0.29078277605775f), Q31( 0.35393777921520f)}, {Q31(-0.62858772103030f), Q31( 0.38765693387102f)}, +{Q31( 0.43440904467688f), Q31(-0.98546330463232f)}, {Q31(-0.98298583762390f), Q31( 0.21021524625209f)}, +{Q31( 0.19513029146934f), Q31(-0.94239832251867f)}, {Q31(-0.95476662400101f), Q31( 0.98364554179143f)}, +{Q31( 0.93379635304810f), Q31(-0.70881994583682f)}, {Q31(-0.85235410573336f), Q31(-0.08342347966410f)}, +{Q31(-0.86425093011245f), Q31(-0.45795025029466f)}, {Q31( 0.38879779059045f), Q31( 0.97274429344593f)}, +{Q31( 0.92045124735495f), Q31(-0.62433652524220f)}, {Q31( 0.89162532251878f), Q31( 0.54950955570563f)}, +{Q31(-0.36834336949252f), Q31( 0.96458298020975f)}, {Q31( 0.93891760988045f), Q31(-0.89968353740388f)}, +{Q31( 0.99267657565094f), Q31(-0.03757034316958f)}, {Q31(-0.94063471614176f), Q31( 0.41332338538963f)}, +{Q31( 0.99740224117019f), Q31(-0.16830494996370f)}, {Q31(-0.35899413170555f), Q31(-0.46633226649613f)}, +{Q31( 0.05237237274947f), Q31(-0.25640361602661f)}, {Q31( 0.36703583957424f), Q31(-0.38653265641875f)}, +{Q31( 0.91653180367913f), Q31(-0.30587628726597f)}, {Q31( 0.69000803499316f), Q31( 0.90952171386132f)}, +{Q31(-0.38658751133527f), Q31( 0.99501571208985f)}, {Q31(-0.29250814029851f), Q31( 0.37444994344615f)}, +{Q31(-0.60182204677608f), Q31( 0.86779651036123f)}, {Q31(-0.97418588163217f), Q31( 0.96468523666475f)}, +{Q31( 0.88461574003963f), Q31( 0.57508405276414f)}, {Q31( 0.05198933055162f), Q31( 0.21269661669964f)}, +{Q31(-0.53499621979720f), Q31( 0.97241553731237f)}, {Q31(-0.49429560226497f), Q31( 0.98183865291903f)}, +{Q31(-0.98935142339139f), Q31(-0.40249159006933f)}, {Q31(-0.98081380091130f), Q31(-0.72856895534041f)}, +{Q31(-0.27338148835532f), Q31( 0.99950922447209f)}, {Q31( 0.06310802338302f), Q31(-0.54539587529618f)}, +{Q31(-0.20461677199539f), Q31(-0.14209977628489f)}, {Q31( 0.66223843141647f), Q31( 0.72528579940326f)}, +{Q31(-0.84764345483665f), Q31( 0.02372316801261f)}, {Q31(-0.89039863483811f), Q31( 0.88866581484602f)}, +{Q31( 0.95903308477986f), Q31( 0.76744927173873f)}, {Q31( 0.73504123909879f), Q31(-0.03747203173192f)}, +{Q31(-0.31744434966056f), Q31(-0.36834111883652f)}, {Q31(-0.34110827591623f), Q31( 0.40211222807691f)}, +{Q31( 0.47803883714199f), Q31(-0.39423219786288f)}, {Q31( 0.98299195879514f), Q31( 0.01989791390047f)}, +{Q31(-0.30963073129751f), Q31(-0.18076720599336f)}, {Q31( 0.99992588229018f), Q31(-0.26281872094289f)}, +{Q31(-0.93149731080767f), Q31(-0.98313162570490f)}, {Q31( 0.99923472302773f), Q31(-0.80142993767554f)}, +{Q31(-0.26024169633417f), Q31(-0.75999759855752f)}, {Q31(-0.35712514743563f), Q31( 0.19298963768574f)}, +{Q31(-0.99899084509530f), Q31( 0.74645156992493f)}, {Q31( 0.86557171579452f), Q31( 0.55593866696299f)}, +{Q31( 0.33408042438752f), Q31( 0.86185953874709f)}, {Q31( 0.99010736374716f), Q31( 0.04602397576623f)}, +{Q31(-0.66694269691195f), Q31(-0.91643611810148f)}, {Q31( 0.64016792079480f), Q31( 0.15649530836856f)}, +{Q31( 0.99570534804836f), Q31( 0.45844586038111f)}, {Q31(-0.63431466947340f), Q31( 0.21079116459234f)}, +{Q31(-0.07706847005931f), Q31(-0.89581437101329f)}, {Q31( 0.98590090577724f), Q31( 0.88241721133981f)}, +{Q31( 0.80099335254678f), Q31(-0.36851896710853f)}, {Q31( 0.78368131392666f), Q31( 0.45506999802597f)}, +{Q31( 0.08707806671691f), Q31( 0.80938994918745f)}, {Q31(-0.86811883080712f), Q31( 0.39347308654705f)}, +{Q31(-0.39466529740375f), Q31(-0.66809432114456f)}, {Q31( 0.97875325649683f), Q31(-0.72467840967746f)}, +{Q31(-0.95038560288864f), Q31( 0.89563219587625f)}, {Q31( 0.17005239424212f), Q31( 0.54683053962658f)}, +{Q31(-0.76910792026848f), Q31(-0.96226617549298f)}, {Q31( 0.99743281016846f), Q31( 0.42697157037567f)}, +{Q31( 0.95437383549973f), Q31( 0.97002324109952f)}, {Q31( 0.99578905365569f), Q31(-0.54106826257356f)}, +{Q31( 0.28058259829990f), Q31(-0.85361420634036f)}, {Q31( 0.85256524470573f), Q31(-0.64567607735589f)}, +{Q31(-0.50608540105128f), Q31(-0.65846015480300f)}, {Q31(-0.97210735183243f), Q31(-0.23095213067791f)}, +{Q31( 0.95424048234441f), Q31(-0.99240147091219f)}, {Q31(-0.96926570524023f), Q31( 0.73775654896574f)}, +{Q31( 0.30872163214726f), Q31( 0.41514960556126f)}, {Q31(-0.24523839572639f), Q31( 0.63206633394807f)}, +{Q31(-0.33813265086024f), Q31(-0.38661779441897f)}, {Q31(-0.05826828420146f), Q31(-0.06940774188029f)}, +{Q31(-0.22898461455054f), Q31( 0.97054853316316f)}, {Q31(-0.18509915019881f), Q31( 0.47565762892084f)}, +{Q31(-0.10488238045009f), Q31(-0.87769947402394f)}, {Q31(-0.71886586182037f), Q31( 0.78030982480538f)}, +{Q31( 0.99793873738654f), Q31( 0.90041310491497f)}, {Q31( 0.57563307626120f), Q31(-0.91034337352097f)}, +{Q31( 0.28909646383717f), Q31( 0.96307783970534f)}, {Q31( 0.42188998312520f), Q31( 0.48148651230437f)}, +{Q31( 0.93335049681047f), Q31(-0.43537023883588f)}, {Q31(-0.97087374418267f), Q31( 0.86636445711364f)}, +{Q31( 0.36722871286923f), Q31( 0.65291654172961f)}, {Q31(-0.81093025665696f), Q31( 0.08778370229363f)}, +{Q31(-0.26240603062237f), Q31(-0.92774095379098f)}, {Q31( 0.83996497984604f), Q31( 0.55839849139647f)}, +{Q31(-0.99909615720225f), Q31(-0.96024605713970f)}, {Q31( 0.74649464155061f), Q31( 0.12144893606462f)}, +{Q31(-0.74774595569805f), Q31(-0.26898062008959f)}, {Q31( 0.95781667469567f), Q31(-0.79047927052628f)}, +{Q31( 0.95472308713099f), Q31(-0.08588776019550f)}, {Q31( 0.48708332746299f), Q31( 0.99999041579432f)}, +{Q31( 0.46332038247497f), Q31( 0.10964126185063f)}, {Q31(-0.76497004940162f), Q31( 0.89210929242238f)}, +{Q31( 0.57397389364339f), Q31( 0.35289703373760f)}, {Q31( 0.75374316974495f), Q31( 0.96705214651335f)}, +{Q31(-0.59174397685714f), Q31(-0.89405370422752f)}, {Q31( 0.75087906691890f), Q31(-0.29612672982396f)}, +{Q31(-0.98607857336230f), Q31( 0.25034911730023f)}, {Q31(-0.40761056640505f), Q31(-0.90045573444695f)}, +{Q31( 0.66929266740477f), Q31( 0.98629493401748f)}, {Q31(-0.97463695257310f), Q31(-0.00190223301301f)}, +{Q31( 0.90145509409859f), Q31( 0.99781390365446f)}, {Q31(-0.87259289048043f), Q31( 0.99233587353666f)}, +{Q31(-0.91529461447692f), Q31(-0.15698707534206f)}, {Q31(-0.03305738840705f), Q31(-0.37205262859764f)}, +{Q31( 0.07223051368337f), Q31(-0.88805001733626f)}, {Q31( 0.99498012188353f), Q31( 0.97094358113387f)}, +{Q31(-0.74904939500519f), Q31( 0.99985483641521f)}, {Q31( 0.04585228574211f), Q31( 0.99812337444082f)}, +{Q31(-0.89054954257993f), Q31(-0.31791913188064f)}, {Q31(-0.83782144651251f), Q31( 0.97637632547466f)}, +{Q31( 0.33454804933804f), Q31(-0.86231516800408f)}, {Q31(-0.99707579362824f), Q31( 0.93237990079441f)}, +{Q31(-0.22827527843994f), Q31( 0.18874759397997f)}, {Q31( 0.67248046289143f), Q31(-0.03646211390569f)}, +{Q31(-0.05146538187944f), Q31(-0.92599700120679f)}, {Q31( 0.99947295749905f), Q31( 0.93625229707912f)}, +{Q31( 0.66951124390363f), Q31( 0.98905825623893f)}, {Q31(-0.99602956559179f), Q31(-0.44654715757688f)}, +{Q31( 0.82104905483590f), Q31( 0.99540741724928f)}, {Q31( 0.99186510988782f), Q31( 0.72023001312947f)}, +{Q31(-0.65284592392918f), Q31( 0.52186723253637f)}, {Q31( 0.93885443798188f), Q31(-0.74895312615259f)}, +{Q31( 0.96735248738388f), Q31( 0.90891816978629f)}, {Q31(-0.22225968841114f), Q31( 0.57124029781228f)}, +{Q31(-0.44132783753414f), Q31(-0.92688840659280f)}, {Q31(-0.85694974219574f), Q31( 0.88844532719844f)}, +{Q31( 0.91783042091762f), Q31(-0.46356892383970f)}, {Q31( 0.72556974415690f), Q31(-0.99899555770747f)}, +{Q31(-0.99711581834508f), Q31( 0.58211560180426f)}, {Q31( 0.77638976371966f), Q31( 0.94321834873819f)}, +{Q31( 0.07717324253925f), Q31( 0.58638399856595f)}, {Q31(-0.56049829194163f), Q31( 0.82522301569036f)}, +{Q31( 0.98398893639988f), Q31( 0.39467440420569f)}, {Q31( 0.47546946844938f), Q31( 0.68613044836811f)}, +{Q31( 0.65675089314631f), Q31( 0.18331637134880f)}, {Q31( 0.03273375457980f), Q31(-0.74933109564108f)}, +{Q31(-0.38684144784738f), Q31( 0.51337349030406f)}, {Q31(-0.97346267944545f), Q31(-0.96549364384098f)}, +{Q31(-0.53282156061942f), Q31(-0.91423265091354f)}, {Q31( 0.99817310731176f), Q31( 0.61133572482148f)}, +{Q31(-0.50254500772635f), Q31(-0.88829338134294f)}, {Q31( 0.01995873238855f), Q31( 0.85223515096765f)}, +{Q31( 0.99930381973804f), Q31( 0.94578896296649f)}, {Q31( 0.82907767600783f), Q31(-0.06323442598128f)}, +{Q31(-0.58660709669728f), Q31( 0.96840773806582f)}, {Q31(-0.17573736667267f), Q31(-0.48166920859485f)}, +{Q31( 0.83434292401346f), Q31(-0.13023450646997f)}, {Q31( 0.05946491307025f), Q31( 0.20511047074866f)}, +{Q31( 0.81505484574602f), Q31(-0.94685947861369f)}, {Q31(-0.44976380954860f), Q31( 0.40894572671545f)}, +{Q31(-0.89746474625671f), Q31( 0.99846578838537f)}, {Q31( 0.39677256130792f), Q31(-0.74854668609359f)}, +{Q31(-0.07588948563079f), Q31( 0.74096214084170f)}, {Q31( 0.76343198951445f), Q31( 0.41746629422634f)}, +{Q31(-0.74490104699626f), Q31( 0.94725911744610f)}, {Q31( 0.64880119792759f), Q31( 0.41336660830571f)}, +{Q31( 0.62319537462542f), Q31(-0.93098313552599f)}, {Q31( 0.42215817594807f), Q31(-0.07712787385208f)}, +{Q31( 0.02704554141885f), Q31(-0.05417518053666f)}, {Q31( 0.80001773566818f), Q31( 0.91542195141039f)}, +{Q31(-0.79351832348816f), Q31(-0.36208897989136f)}, {Q31( 0.63872359151636f), Q31( 0.08128252493444f)}, +{Q31( 0.52890520960295f), Q31( 0.60048872455592f)}, {Q31( 0.74238552914587f), Q31( 0.04491915291044f)}, +{Q31( 0.99096131449250f), Q31(-0.19451182854402f)}, {Q31(-0.80412329643109f), Q31(-0.88513818199457f)}, +{Q31(-0.64612616129736f), Q31( 0.72198674804544f)}, {Q31( 0.11657770663191f), Q31(-0.83662833815041f)}, +{Q31(-0.95053182488101f), Q31(-0.96939905138082f)}, {Q31(-0.62228872928622f), Q31( 0.82767262846661f)}, +{Q31( 0.03004475787316f), Q31(-0.99738896333384f)}, {Q31(-0.97987214341034f), Q31( 0.36526129686425f)}, +{Q31(-0.99986980746200f), Q31(-0.36021610299715f)}, {Q31( 0.89110648599879f), Q31(-0.97894250343044f)}, +{Q31( 0.10407960510582f), Q31( 0.77357793811619f)}, {Q31( 0.95964737821728f), Q31(-0.35435818285502f)}, +{Q31( 0.50843233159162f), Q31( 0.96107691266205f)}, {Q31( 0.17006334670615f), Q31(-0.76854025314829f)}, +{Q31( 0.25872675063360f), Q31( 0.99893303933816f)}, {Q31(-0.01115998681937f), Q31( 0.98496019742444f)}, +{Q31(-0.79598702973261f), Q31( 0.97138411318894f)}, {Q31(-0.99264708948101f), Q31(-0.99542822402536f)}, +{Q31(-0.99829663752818f), Q31( 0.01877138824311f)}, {Q31(-0.70801016548184f), Q31( 0.33680685948117f)}, +{Q31(-0.70467057786826f), Q31( 0.93272777501857f)}, {Q31( 0.99846021905254f), Q31(-0.98725746254433f)}, +{Q31(-0.63364968534650f), Q31(-0.16473594423746f)}, {Q31(-0.16258217500792f), Q31(-0.95939125400802f)}, +{Q31(-0.43645594360633f), Q31(-0.94805030113284f)}, {Q31(-0.99848471702976f), Q31( 0.96245166923809f)}, +{Q31(-0.16796458968998f), Q31(-0.98987511890470f)}, {Q31(-0.87979225745213f), Q31(-0.71725725041680f)}, +{Q31( 0.44183099021786f), Q31(-0.93568974498761f)}, {Q31( 0.93310180125532f), Q31(-0.99913308068246f)}, +{Q31(-0.93941931782002f), Q31(-0.56409379640356f)}, {Q31(-0.88590003188677f), Q31( 0.47624600491382f)}, +{Q31( 0.99971463703691f), Q31(-0.83889954253462f)}, {Q31(-0.75376385639978f), Q31( 0.00814643438625f)}, +{Q31( 0.93887685615875f), Q31(-0.11284528204636f)}, {Q31( 0.85126435782309f), Q31( 0.52349251543547f)}, +{Q31( 0.39701421446381f), Q31( 0.81779634174316f)}, {Q31(-0.37024464187437f), Q31(-0.87071656222959f)}, +{Q31(-0.36024828242896f), Q31( 0.34655735648287f)}, {Q31(-0.93388812549209f), Q31(-0.84476541096429f)}, +{Q31(-0.65298804552119f), Q31(-0.18439575450921f)}, {Q31( 0.11960319006843f), Q31( 0.99899346780168f)}, +{Q31( 0.94292565553160f), Q31( 0.83163906518293f)}, {Q31( 0.75081145286948f), Q31(-0.35533223142265f)}, +{Q31( 0.56721979748394f), Q31(-0.24076836414499f)}, {Q31( 0.46857766746029f), Q31(-0.30140233457198f)}, +{Q31( 0.97312313923635f), Q31(-0.99548191630031f)}, {Q31(-0.38299976567017f), Q31( 0.98516909715427f)}, +{Q31( 0.41025800019463f), Q31( 0.02116736935734f)}, {Q31( 0.09638062008048f), Q31( 0.04411984381457f)}, +{Q31(-0.85283249275397f), Q31( 0.91475563922421f)}, {Q31( 0.88866808958124f), Q31(-0.99735267083226f)}, +{Q31(-0.48202429536989f), Q31(-0.96805608884164f)}, {Q31( 0.27572582416567f), Q31( 0.58634753335832f)}, +{Q31(-0.65889129659168f), Q31( 0.58835634138583f)}, {Q31( 0.98838086953732f), Q31( 0.99994349600236f)}, +{Q31(-0.20651349620689f), Q31( 0.54593044066355f)}, {Q31(-0.62126416356920f), Q31(-0.59893681700392f)}, +{Q31( 0.20320105410437f), Q31(-0.86879180355289f)}, {Q31(-0.97790548600584f), Q31( 0.96290806999242f)}, +{Q31( 0.11112534735126f), Q31( 0.21484763313301f)}, {Q31(-0.41368337314182f), Q31( 0.28216837680365f)}, +{Q31( 0.24133038992960f), Q31( 0.51294362630238f)}, {Q31(-0.66393410674885f), Q31(-0.08249679629081f)}, +{Q31(-0.53697829178752f), Q31(-0.97649903936228f)}, {Q31(-0.97224737889348f), Q31( 0.22081333579837f)}, +{Q31( 0.87392477144549f), Q31(-0.12796173740361f)}, {Q31( 0.19050361015753f), Q31( 0.01602615387195f)}, +{Q31(-0.46353441212724f), Q31(-0.95249041539006f)}, {Q31(-0.07064096339021f), Q31(-0.94479803205886f)}, +{Q31(-0.92444085484466f), Q31(-0.10457590187436f)}, {Q31(-0.83822593578728f), Q31(-0.01695043208885f)}, +{Q31( 0.75214681811150f), Q31(-0.99955681042665f)}, {Q31(-0.42102998829339f), Q31( 0.99720941999394f)}, +{Q31(-0.72094786237696f), Q31(-0.35008961934255f)}, {Q31( 0.78843311019251f), Q31( 0.52851398958271f)}, +{Q31( 0.97394027897442f), Q31(-0.26695944086561f)}, {Q31( 0.99206463477946f), Q31(-0.57010120849429f)}, +{Q31( 0.76789609461795f), Q31(-0.76519356730966f)}, {Q31(-0.82002421836409f), Q31(-0.73530179553767f)}, +{Q31( 0.81924990025724f), Q31( 0.99698425250579f)}, {Q31(-0.26719850873357f), Q31( 0.68903369776193f)}, +{Q31(-0.43311260380975f), Q31( 0.85321815947490f)}, {Q31( 0.99194979673836f), Q31( 0.91876249766422f)}, +{Q31(-0.80692001248487f), Q31(-0.32627540663214f)}, {Q31( 0.43080003649976f), Q31(-0.21919095636638f)}, +{Q31( 0.67709491937357f), Q31(-0.95478075822906f)}, {Q31( 0.56151770568316f), Q31(-0.70693811747778f)}, +{Q31( 0.10831862810749f), Q31(-0.08628837174592f)}, {Q31( 0.91229417540436f), Q31(-0.65987351408410f)}, +{Q31(-0.48972893932274f), Q31( 0.56289246362686f)}, {Q31(-0.89033658689697f), Q31(-0.71656563987082f)}, +{Q31( 0.65269447475094f), Q31( 0.65916004833932f)}, {Q31( 0.67439478141121f), Q31(-0.81684380846796f)}, +{Q31(-0.47770832416973f), Q31(-0.16789556203025f)}, {Q31(-0.99715979260878f), Q31(-0.93565784007648f)}, +{Q31(-0.90889593602546f), Q31( 0.62034397054380f)}, {Q31(-0.06618622548177f), Q31(-0.23812217221359f)}, +{Q31( 0.99430266919728f), Q31( 0.18812555317553f)}, {Q31( 0.97686402381843f), Q31(-0.28664534366620f)}, +{Q31( 0.94813650221268f), Q31(-0.97506640027128f)}, {Q31(-0.95434497492853f), Q31(-0.79607978501983f)}, +{Q31(-0.49104783137150f), Q31( 0.32895214359663f)}, {Q31( 0.99881175120751f), Q31( 0.88993983831354f)}, +{Q31( 0.50449166760303f), Q31(-0.85995072408434f)}, {Q31( 0.47162891065108f), Q31(-0.18680204049569f)}, +{Q31(-0.62081581361840f), Q31( 0.75000676218956f)}, {Q31(-0.43867015250812f), Q31( 0.99998069244322f)}, +{Q31( 0.98630563232075f), Q31(-0.53578899600662f)}, {Q31(-0.61510362277374f), Q31(-0.89515019899997f)}, +{Q31(-0.03841517601843f), Q31(-0.69888815681179f)}, {Q31(-0.30102157304644f), Q31(-0.07667808922205f)}, +{Q31( 0.41881284182683f), Q31( 0.02188098922282f)}, {Q31(-0.86135454941237f), Q31( 0.98947480909359f)}, +{Q31( 0.67226861393788f), Q31(-0.13494389011014f)}, {Q31(-0.70737398842068f), Q31(-0.76547349325992f)}, +{Q31( 0.94044946687963f), Q31( 0.09026201157416f)}, {Q31(-0.82386352534327f), Q31( 0.08924768823676f)}, +{Q31(-0.32070666698656f), Q31( 0.50143421908753f)}, {Q31( 0.57593163224487f), Q31(-0.98966422921509f)}, +{Q31(-0.36326018419965f), Q31( 0.07440243123228f)}, {Q31( 0.99979044674350f), Q31(-0.14130287347405f)}, +{Q31(-0.92366023326932f), Q31(-0.97979298068180f)}, {Q31(-0.44607178518598f), Q31(-0.54233252016394f)}, +{Q31( 0.44226800932956f), Q31( 0.71326756742752f)}, {Q31( 0.03671907158312f), Q31( 0.63606389366675f)}, +{Q31( 0.52175424682195f), Q31(-0.85396826735705f)}, {Q31(-0.94701139690956f), Q31(-0.01826348194255f)}, +{Q31(-0.98759606946049f), Q31( 0.82288714303073f)}, {Q31( 0.87434794743625f), Q31( 0.89399495655433f)}, +{Q31(-0.93412041758744f), Q31( 0.41374052024363f)}, {Q31( 0.96063943315511f), Q31( 0.93116709541280f)}, +{Q31( 0.97534253457837f), Q31( 0.86150930812689f)}, {Q31( 0.99642466504163f), Q31( 0.70190043427512f)}, +{Q31(-0.94705089665984f), Q31(-0.29580042814306f)}, {Q31( 0.91599807087376f), Q31(-0.98147830385781f)}, +// Start of duplicated table +{Q31(-0.99948153278296f), Q31(-0.59483417516607f)}, {Q31( 0.97113454393991f), Q31(-0.67528515225647f)}, +{Q31( 0.14130051758487f), Q31(-0.95090983575689f)}, {Q31(-0.47005496701697f), Q31(-0.37340549728647f)}, +{Q31( 0.80705063769351f), Q31( 0.29653668284408f)}, {Q31(-0.38981478896926f), Q31( 0.89572605717087f)}, +{Q31(-0.01053049862020f), Q31(-0.66959058036166f)}, {Q31(-0.91266367957293f), Q31(-0.11522938140034f)}, +}; + +#endif /* AVCODEC_AACSBRDATA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aactab.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aactab.c new file mode 100644 index 000000000..df551b058 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aactab.c @@ -0,0 +1,3282 @@ +/* + * AAC data + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC data + * @author Oded Shimon ( ods15 ods15 dyndns org ) + * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) + */ + +#include "libavutil/mem.h" +#include "aac.h" + +#include + +float ff_aac_pow2sf_tab[428]; +float ff_aac_pow34sf_tab[428]; + +DECLARE_ALIGNED(32, float, ff_aac_kbd_long_1024)[1024]; +DECLARE_ALIGNED(32, float, ff_aac_kbd_short_128)[128]; +DECLARE_ALIGNED(32, float, ff_aac_kbd_long_960)[960]; +DECLARE_ALIGNED(32, float, ff_aac_kbd_short_120)[120]; +DECLARE_ALIGNED(32, int, ff_aac_kbd_long_1024_fixed)[1024]; +DECLARE_ALIGNED(32, int, ff_aac_kbd_short_128_fixed)[128]; + +const uint8_t ff_aac_num_swb_1024[] = { + 41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40, 40 +}; + +const uint8_t ff_aac_num_swb_960[] = { + 40, 40, 46, 49, 49, 49, 46, 46, 42, 42, 42, 40, 40 +}; + +const uint8_t ff_aac_num_swb_512[] = { + 0, 0, 0, 36, 36, 37, 31, 31, 0, 0, 0, 0, 0 +}; + +const uint8_t ff_aac_num_swb_480[] = { + 0, 0, 0, 35, 35, 37, 30, 30, 0, 0, 0, 0, 0 +}; + +const uint8_t ff_aac_num_swb_128[] = { + 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15 +}; + +const uint8_t ff_aac_num_swb_120[] = { + 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15 +}; + +const uint8_t ff_aac_pred_sfb_max[] = { + 33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34, 34 +}; + +const uint32_t ff_aac_scalefactor_code[121] = { + 0x3ffe8, 0x3ffe6, 0x3ffe7, 0x3ffe5, 0x7fff5, 0x7fff1, 0x7ffed, 0x7fff6, + 0x7ffee, 0x7ffef, 0x7fff0, 0x7fffc, 0x7fffd, 0x7ffff, 0x7fffe, 0x7fff7, + 0x7fff8, 0x7fffb, 0x7fff9, 0x3ffe4, 0x7fffa, 0x3ffe3, 0x1ffef, 0x1fff0, + 0x0fff5, 0x1ffee, 0x0fff2, 0x0fff3, 0x0fff4, 0x0fff1, 0x07ff6, 0x07ff7, + 0x03ff9, 0x03ff5, 0x03ff7, 0x03ff3, 0x03ff6, 0x03ff2, 0x01ff7, 0x01ff5, + 0x00ff9, 0x00ff7, 0x00ff6, 0x007f9, 0x00ff4, 0x007f8, 0x003f9, 0x003f7, + 0x003f5, 0x001f8, 0x001f7, 0x000fa, 0x000f8, 0x000f6, 0x00079, 0x0003a, + 0x00038, 0x0001a, 0x0000b, 0x00004, 0x00000, 0x0000a, 0x0000c, 0x0001b, + 0x00039, 0x0003b, 0x00078, 0x0007a, 0x000f7, 0x000f9, 0x001f6, 0x001f9, + 0x003f4, 0x003f6, 0x003f8, 0x007f5, 0x007f4, 0x007f6, 0x007f7, 0x00ff5, + 0x00ff8, 0x01ff4, 0x01ff6, 0x01ff8, 0x03ff8, 0x03ff4, 0x0fff0, 0x07ff4, + 0x0fff6, 0x07ff5, 0x3ffe2, 0x7ffd9, 0x7ffda, 0x7ffdb, 0x7ffdc, 0x7ffdd, + 0x7ffde, 0x7ffd8, 0x7ffd2, 0x7ffd3, 0x7ffd4, 0x7ffd5, 0x7ffd6, 0x7fff2, + 0x7ffdf, 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, 0x7ffe6, 0x7ffe0, + 0x7ffe1, 0x7ffe2, 0x7ffe3, 0x7ffe4, 0x7ffe5, 0x7ffd7, 0x7ffec, 0x7fff4, + 0x7fff3, +}; + +const uint8_t ff_aac_scalefactor_bits[121] = { + 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 18, 19, 18, 17, 17, 16, 17, 16, 16, 16, 16, 15, 15, + 14, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 11, 12, 11, 10, 10, + 10, 9, 9, 8, 8, 8, 7, 6, 6, 5, 4, 3, 1, 4, 4, 5, + 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, + 12, 13, 13, 13, 14, 14, 16, 15, 16, 15, 18, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, +}; + +static const uint16_t codes1[81] = { + 0x7f8, 0x1f1, 0x7fd, 0x3f5, 0x068, 0x3f0, 0x7f7, 0x1ec, + 0x7f5, 0x3f1, 0x072, 0x3f4, 0x074, 0x011, 0x076, 0x1eb, + 0x06c, 0x3f6, 0x7fc, 0x1e1, 0x7f1, 0x1f0, 0x061, 0x1f6, + 0x7f2, 0x1ea, 0x7fb, 0x1f2, 0x069, 0x1ed, 0x077, 0x017, + 0x06f, 0x1e6, 0x064, 0x1e5, 0x067, 0x015, 0x062, 0x012, + 0x000, 0x014, 0x065, 0x016, 0x06d, 0x1e9, 0x063, 0x1e4, + 0x06b, 0x013, 0x071, 0x1e3, 0x070, 0x1f3, 0x7fe, 0x1e7, + 0x7f3, 0x1ef, 0x060, 0x1ee, 0x7f0, 0x1e2, 0x7fa, 0x3f3, + 0x06a, 0x1e8, 0x075, 0x010, 0x073, 0x1f4, 0x06e, 0x3f7, + 0x7f6, 0x1e0, 0x7f9, 0x3f2, 0x066, 0x1f5, 0x7ff, 0x1f7, + 0x7f4, +}; + +static const uint8_t bits1[81] = { + 11, 9, 11, 10, 7, 10, 11, 9, 11, 10, 7, 10, 7, 5, 7, 9, + 7, 10, 11, 9, 11, 9, 7, 9, 11, 9, 11, 9, 7, 9, 7, 5, + 7, 9, 7, 9, 7, 5, 7, 5, 1, 5, 7, 5, 7, 9, 7, 9, + 7, 5, 7, 9, 7, 9, 11, 9, 11, 9, 7, 9, 11, 9, 11, 10, + 7, 9, 7, 5, 7, 9, 7, 10, 11, 9, 11, 10, 7, 9, 11, 9, + 11, +}; + +static const uint16_t codes2[81] = { + 0x1f3, 0x06f, 0x1fd, 0x0eb, 0x023, 0x0ea, 0x1f7, 0x0e8, + 0x1fa, 0x0f2, 0x02d, 0x070, 0x020, 0x006, 0x02b, 0x06e, + 0x028, 0x0e9, 0x1f9, 0x066, 0x0f8, 0x0e7, 0x01b, 0x0f1, + 0x1f4, 0x06b, 0x1f5, 0x0ec, 0x02a, 0x06c, 0x02c, 0x00a, + 0x027, 0x067, 0x01a, 0x0f5, 0x024, 0x008, 0x01f, 0x009, + 0x000, 0x007, 0x01d, 0x00b, 0x030, 0x0ef, 0x01c, 0x064, + 0x01e, 0x00c, 0x029, 0x0f3, 0x02f, 0x0f0, 0x1fc, 0x071, + 0x1f2, 0x0f4, 0x021, 0x0e6, 0x0f7, 0x068, 0x1f8, 0x0ee, + 0x022, 0x065, 0x031, 0x002, 0x026, 0x0ed, 0x025, 0x06a, + 0x1fb, 0x072, 0x1fe, 0x069, 0x02e, 0x0f6, 0x1ff, 0x06d, + 0x1f6, +}; + +static const uint8_t bits2[81] = { + 9, 7, 9, 8, 6, 8, 9, 8, 9, 8, 6, 7, 6, 5, 6, 7, + 6, 8, 9, 7, 8, 8, 6, 8, 9, 7, 9, 8, 6, 7, 6, 5, + 6, 7, 6, 8, 6, 5, 6, 5, 3, 5, 6, 5, 6, 8, 6, 7, + 6, 5, 6, 8, 6, 8, 9, 7, 9, 8, 6, 8, 8, 7, 9, 8, + 6, 7, 6, 4, 6, 8, 6, 7, 9, 7, 9, 7, 6, 8, 9, 7, + 9, +}; + +static const uint16_t codes3[81] = { + 0x0000, 0x0009, 0x00ef, 0x000b, 0x0019, 0x00f0, 0x01eb, 0x01e6, + 0x03f2, 0x000a, 0x0035, 0x01ef, 0x0034, 0x0037, 0x01e9, 0x01ed, + 0x01e7, 0x03f3, 0x01ee, 0x03ed, 0x1ffa, 0x01ec, 0x01f2, 0x07f9, + 0x07f8, 0x03f8, 0x0ff8, 0x0008, 0x0038, 0x03f6, 0x0036, 0x0075, + 0x03f1, 0x03eb, 0x03ec, 0x0ff4, 0x0018, 0x0076, 0x07f4, 0x0039, + 0x0074, 0x03ef, 0x01f3, 0x01f4, 0x07f6, 0x01e8, 0x03ea, 0x1ffc, + 0x00f2, 0x01f1, 0x0ffb, 0x03f5, 0x07f3, 0x0ffc, 0x00ee, 0x03f7, + 0x7ffe, 0x01f0, 0x07f5, 0x7ffd, 0x1ffb, 0x3ffa, 0xffff, 0x00f1, + 0x03f0, 0x3ffc, 0x01ea, 0x03ee, 0x3ffb, 0x0ff6, 0x0ffa, 0x7ffc, + 0x07f2, 0x0ff5, 0xfffe, 0x03f4, 0x07f7, 0x7ffb, 0x0ff7, 0x0ff9, + 0x7ffa, +}; + +static const uint8_t bits3[81] = { + 1, 4, 8, 4, 5, 8, 9, 9, 10, 4, 6, 9, 6, 6, 9, 9, + 9, 10, 9, 10, 13, 9, 9, 11, 11, 10, 12, 4, 6, 10, 6, 7, + 10, 10, 10, 12, 5, 7, 11, 6, 7, 10, 9, 9, 11, 9, 10, 13, + 8, 9, 12, 10, 11, 12, 8, 10, 15, 9, 11, 15, 13, 14, 16, 8, + 10, 14, 9, 10, 14, 12, 12, 15, 11, 12, 16, 10, 11, 15, 12, 12, + 15, +}; + +static const uint16_t codes4[81] = { + 0x007, 0x016, 0x0f6, 0x018, 0x008, 0x0ef, 0x1ef, 0x0f3, + 0x7f8, 0x019, 0x017, 0x0ed, 0x015, 0x001, 0x0e2, 0x0f0, + 0x070, 0x3f0, 0x1ee, 0x0f1, 0x7fa, 0x0ee, 0x0e4, 0x3f2, + 0x7f6, 0x3ef, 0x7fd, 0x005, 0x014, 0x0f2, 0x009, 0x004, + 0x0e5, 0x0f4, 0x0e8, 0x3f4, 0x006, 0x002, 0x0e7, 0x003, + 0x000, 0x06b, 0x0e3, 0x069, 0x1f3, 0x0eb, 0x0e6, 0x3f6, + 0x06e, 0x06a, 0x1f4, 0x3ec, 0x1f0, 0x3f9, 0x0f5, 0x0ec, + 0x7fb, 0x0ea, 0x06f, 0x3f7, 0x7f9, 0x3f3, 0xfff, 0x0e9, + 0x06d, 0x3f8, 0x06c, 0x068, 0x1f5, 0x3ee, 0x1f2, 0x7f4, + 0x7f7, 0x3f1, 0xffe, 0x3ed, 0x1f1, 0x7f5, 0x7fe, 0x3f5, + 0x7fc, +}; + +static const uint8_t bits4[81] = { + 4, 5, 8, 5, 4, 8, 9, 8, 11, 5, 5, 8, 5, 4, 8, 8, + 7, 10, 9, 8, 11, 8, 8, 10, 11, 10, 11, 4, 5, 8, 4, 4, + 8, 8, 8, 10, 4, 4, 8, 4, 4, 7, 8, 7, 9, 8, 8, 10, + 7, 7, 9, 10, 9, 10, 8, 8, 11, 8, 7, 10, 11, 10, 12, 8, + 7, 10, 7, 7, 9, 10, 9, 11, 11, 10, 12, 10, 9, 11, 11, 10, + 11, +}; + +static const uint16_t codes5[81] = { + 0x1fff, 0x0ff7, 0x07f4, 0x07e8, 0x03f1, 0x07ee, 0x07f9, 0x0ff8, + 0x1ffd, 0x0ffd, 0x07f1, 0x03e8, 0x01e8, 0x00f0, 0x01ec, 0x03ee, + 0x07f2, 0x0ffa, 0x0ff4, 0x03ef, 0x01f2, 0x00e8, 0x0070, 0x00ec, + 0x01f0, 0x03ea, 0x07f3, 0x07eb, 0x01eb, 0x00ea, 0x001a, 0x0008, + 0x0019, 0x00ee, 0x01ef, 0x07ed, 0x03f0, 0x00f2, 0x0073, 0x000b, + 0x0000, 0x000a, 0x0071, 0x00f3, 0x07e9, 0x07ef, 0x01ee, 0x00ef, + 0x0018, 0x0009, 0x001b, 0x00eb, 0x01e9, 0x07ec, 0x07f6, 0x03eb, + 0x01f3, 0x00ed, 0x0072, 0x00e9, 0x01f1, 0x03ed, 0x07f7, 0x0ff6, + 0x07f0, 0x03e9, 0x01ed, 0x00f1, 0x01ea, 0x03ec, 0x07f8, 0x0ff9, + 0x1ffc, 0x0ffc, 0x0ff5, 0x07ea, 0x03f3, 0x03f2, 0x07f5, 0x0ffb, + 0x1ffe, +}; + +static const uint8_t bits5[81] = { + 13, 12, 11, 11, 10, 11, 11, 12, 13, 12, 11, 10, 9, 8, 9, 10, + 11, 12, 12, 10, 9, 8, 7, 8, 9, 10, 11, 11, 9, 8, 5, 4, + 5, 8, 9, 11, 10, 8, 7, 4, 1, 4, 7, 8, 11, 11, 9, 8, + 5, 4, 5, 8, 9, 11, 11, 10, 9, 8, 7, 8, 9, 10, 11, 12, + 11, 10, 9, 8, 9, 10, 11, 12, 13, 12, 12, 11, 10, 10, 11, 12, + 13, +}; + +static const uint16_t codes6[81] = { + 0x7fe, 0x3fd, 0x1f1, 0x1eb, 0x1f4, 0x1ea, 0x1f0, 0x3fc, + 0x7fd, 0x3f6, 0x1e5, 0x0ea, 0x06c, 0x071, 0x068, 0x0f0, + 0x1e6, 0x3f7, 0x1f3, 0x0ef, 0x032, 0x027, 0x028, 0x026, + 0x031, 0x0eb, 0x1f7, 0x1e8, 0x06f, 0x02e, 0x008, 0x004, + 0x006, 0x029, 0x06b, 0x1ee, 0x1ef, 0x072, 0x02d, 0x002, + 0x000, 0x003, 0x02f, 0x073, 0x1fa, 0x1e7, 0x06e, 0x02b, + 0x007, 0x001, 0x005, 0x02c, 0x06d, 0x1ec, 0x1f9, 0x0ee, + 0x030, 0x024, 0x02a, 0x025, 0x033, 0x0ec, 0x1f2, 0x3f8, + 0x1e4, 0x0ed, 0x06a, 0x070, 0x069, 0x074, 0x0f1, 0x3fa, + 0x7ff, 0x3f9, 0x1f6, 0x1ed, 0x1f8, 0x1e9, 0x1f5, 0x3fb, + 0x7fc, +}; + +static const uint8_t bits6[81] = { + 11, 10, 9, 9, 9, 9, 9, 10, 11, 10, 9, 8, 7, 7, 7, 8, + 9, 10, 9, 8, 6, 6, 6, 6, 6, 8, 9, 9, 7, 6, 4, 4, + 4, 6, 7, 9, 9, 7, 6, 4, 4, 4, 6, 7, 9, 9, 7, 6, + 4, 4, 4, 6, 7, 9, 9, 8, 6, 6, 6, 6, 6, 8, 9, 10, + 9, 8, 7, 7, 7, 7, 8, 10, 11, 10, 9, 9, 9, 9, 9, 10, + 11, +}; + +static const uint16_t codes7[64] = { + 0x000, 0x005, 0x037, 0x074, 0x0f2, 0x1eb, 0x3ed, 0x7f7, + 0x004, 0x00c, 0x035, 0x071, 0x0ec, 0x0ee, 0x1ee, 0x1f5, + 0x036, 0x034, 0x072, 0x0ea, 0x0f1, 0x1e9, 0x1f3, 0x3f5, + 0x073, 0x070, 0x0eb, 0x0f0, 0x1f1, 0x1f0, 0x3ec, 0x3fa, + 0x0f3, 0x0ed, 0x1e8, 0x1ef, 0x3ef, 0x3f1, 0x3f9, 0x7fb, + 0x1ed, 0x0ef, 0x1ea, 0x1f2, 0x3f3, 0x3f8, 0x7f9, 0x7fc, + 0x3ee, 0x1ec, 0x1f4, 0x3f4, 0x3f7, 0x7f8, 0xffd, 0xffe, + 0x7f6, 0x3f0, 0x3f2, 0x3f6, 0x7fa, 0x7fd, 0xffc, 0xfff, +}; + +static const uint8_t bits7[64] = { + 1, 3, 6, 7, 8, 9, 10, 11, 3, 4, 6, 7, 8, 8, 9, 9, + 6, 6, 7, 8, 8, 9, 9, 10, 7, 7, 8, 8, 9, 9, 10, 10, + 8, 8, 9, 9, 10, 10, 10, 11, 9, 8, 9, 9, 10, 10, 11, 11, + 10, 9, 9, 10, 10, 11, 12, 12, 11, 10, 10, 10, 11, 11, 12, 12, +}; + +static const uint16_t codes8[64] = { + 0x00e, 0x005, 0x010, 0x030, 0x06f, 0x0f1, 0x1fa, 0x3fe, + 0x003, 0x000, 0x004, 0x012, 0x02c, 0x06a, 0x075, 0x0f8, + 0x00f, 0x002, 0x006, 0x014, 0x02e, 0x069, 0x072, 0x0f5, + 0x02f, 0x011, 0x013, 0x02a, 0x032, 0x06c, 0x0ec, 0x0fa, + 0x071, 0x02b, 0x02d, 0x031, 0x06d, 0x070, 0x0f2, 0x1f9, + 0x0ef, 0x068, 0x033, 0x06b, 0x06e, 0x0ee, 0x0f9, 0x3fc, + 0x1f8, 0x074, 0x073, 0x0ed, 0x0f0, 0x0f6, 0x1f6, 0x1fd, + 0x3fd, 0x0f3, 0x0f4, 0x0f7, 0x1f7, 0x1fb, 0x1fc, 0x3ff, +}; + +static const uint8_t bits8[64] = { + 5, 4, 5, 6, 7, 8, 9, 10, 4, 3, 4, 5, 6, 7, 7, 8, + 5, 4, 4, 5, 6, 7, 7, 8, 6, 5, 5, 6, 6, 7, 8, 8, + 7, 6, 6, 6, 7, 7, 8, 9, 8, 7, 6, 7, 7, 8, 8, 10, + 9, 7, 7, 8, 8, 8, 9, 9, 10, 8, 8, 8, 9, 9, 9, 10, +}; + +static const uint16_t codes9[169] = { + 0x0000, 0x0005, 0x0037, 0x00e7, 0x01de, 0x03ce, 0x03d9, 0x07c8, + 0x07cd, 0x0fc8, 0x0fdd, 0x1fe4, 0x1fec, 0x0004, 0x000c, 0x0035, + 0x0072, 0x00ea, 0x00ed, 0x01e2, 0x03d1, 0x03d3, 0x03e0, 0x07d8, + 0x0fcf, 0x0fd5, 0x0036, 0x0034, 0x0071, 0x00e8, 0x00ec, 0x01e1, + 0x03cf, 0x03dd, 0x03db, 0x07d0, 0x0fc7, 0x0fd4, 0x0fe4, 0x00e6, + 0x0070, 0x00e9, 0x01dd, 0x01e3, 0x03d2, 0x03dc, 0x07cc, 0x07ca, + 0x07de, 0x0fd8, 0x0fea, 0x1fdb, 0x01df, 0x00eb, 0x01dc, 0x01e6, + 0x03d5, 0x03de, 0x07cb, 0x07dd, 0x07dc, 0x0fcd, 0x0fe2, 0x0fe7, + 0x1fe1, 0x03d0, 0x01e0, 0x01e4, 0x03d6, 0x07c5, 0x07d1, 0x07db, + 0x0fd2, 0x07e0, 0x0fd9, 0x0feb, 0x1fe3, 0x1fe9, 0x07c4, 0x01e5, + 0x03d7, 0x07c6, 0x07cf, 0x07da, 0x0fcb, 0x0fda, 0x0fe3, 0x0fe9, + 0x1fe6, 0x1ff3, 0x1ff7, 0x07d3, 0x03d8, 0x03e1, 0x07d4, 0x07d9, + 0x0fd3, 0x0fde, 0x1fdd, 0x1fd9, 0x1fe2, 0x1fea, 0x1ff1, 0x1ff6, + 0x07d2, 0x03d4, 0x03da, 0x07c7, 0x07d7, 0x07e2, 0x0fce, 0x0fdb, + 0x1fd8, 0x1fee, 0x3ff0, 0x1ff4, 0x3ff2, 0x07e1, 0x03df, 0x07c9, + 0x07d6, 0x0fca, 0x0fd0, 0x0fe5, 0x0fe6, 0x1feb, 0x1fef, 0x3ff3, + 0x3ff4, 0x3ff5, 0x0fe0, 0x07ce, 0x07d5, 0x0fc6, 0x0fd1, 0x0fe1, + 0x1fe0, 0x1fe8, 0x1ff0, 0x3ff1, 0x3ff8, 0x3ff6, 0x7ffc, 0x0fe8, + 0x07df, 0x0fc9, 0x0fd7, 0x0fdc, 0x1fdc, 0x1fdf, 0x1fed, 0x1ff5, + 0x3ff9, 0x3ffb, 0x7ffd, 0x7ffe, 0x1fe7, 0x0fcc, 0x0fd6, 0x0fdf, + 0x1fde, 0x1fda, 0x1fe5, 0x1ff2, 0x3ffa, 0x3ff7, 0x3ffc, 0x3ffd, + 0x7fff, +}; + +static const uint8_t bits9[169] = { + 1, 3, 6, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 3, 4, 6, + 7, 8, 8, 9, 10, 10, 10, 11, 12, 12, 6, 6, 7, 8, 8, 9, + 10, 10, 10, 11, 12, 12, 12, 8, 7, 8, 9, 9, 10, 10, 11, 11, + 11, 12, 12, 13, 9, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, + 13, 10, 9, 9, 10, 11, 11, 11, 12, 11, 12, 12, 13, 13, 11, 9, + 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 11, 10, 10, 11, 11, + 12, 12, 13, 13, 13, 13, 13, 13, 11, 10, 10, 11, 11, 11, 12, 12, + 13, 13, 14, 13, 14, 11, 10, 11, 11, 12, 12, 12, 12, 13, 13, 14, + 14, 14, 12, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 12, + 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15, 13, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, +}; + +static const uint16_t codes10[169] = { + 0x022, 0x008, 0x01d, 0x026, 0x05f, 0x0d3, 0x1cf, 0x3d0, + 0x3d7, 0x3ed, 0x7f0, 0x7f6, 0xffd, 0x007, 0x000, 0x001, + 0x009, 0x020, 0x054, 0x060, 0x0d5, 0x0dc, 0x1d4, 0x3cd, + 0x3de, 0x7e7, 0x01c, 0x002, 0x006, 0x00c, 0x01e, 0x028, + 0x05b, 0x0cd, 0x0d9, 0x1ce, 0x1dc, 0x3d9, 0x3f1, 0x025, + 0x00b, 0x00a, 0x00d, 0x024, 0x057, 0x061, 0x0cc, 0x0dd, + 0x1cc, 0x1de, 0x3d3, 0x3e7, 0x05d, 0x021, 0x01f, 0x023, + 0x027, 0x059, 0x064, 0x0d8, 0x0df, 0x1d2, 0x1e2, 0x3dd, + 0x3ee, 0x0d1, 0x055, 0x029, 0x056, 0x058, 0x062, 0x0ce, + 0x0e0, 0x0e2, 0x1da, 0x3d4, 0x3e3, 0x7eb, 0x1c9, 0x05e, + 0x05a, 0x05c, 0x063, 0x0ca, 0x0da, 0x1c7, 0x1ca, 0x1e0, + 0x3db, 0x3e8, 0x7ec, 0x1e3, 0x0d2, 0x0cb, 0x0d0, 0x0d7, + 0x0db, 0x1c6, 0x1d5, 0x1d8, 0x3ca, 0x3da, 0x7ea, 0x7f1, + 0x1e1, 0x0d4, 0x0cf, 0x0d6, 0x0de, 0x0e1, 0x1d0, 0x1d6, + 0x3d1, 0x3d5, 0x3f2, 0x7ee, 0x7fb, 0x3e9, 0x1cd, 0x1c8, + 0x1cb, 0x1d1, 0x1d7, 0x1df, 0x3cf, 0x3e0, 0x3ef, 0x7e6, + 0x7f8, 0xffa, 0x3eb, 0x1dd, 0x1d3, 0x1d9, 0x1db, 0x3d2, + 0x3cc, 0x3dc, 0x3ea, 0x7ed, 0x7f3, 0x7f9, 0xff9, 0x7f2, + 0x3ce, 0x1e4, 0x3cb, 0x3d8, 0x3d6, 0x3e2, 0x3e5, 0x7e8, + 0x7f4, 0x7f5, 0x7f7, 0xffb, 0x7fa, 0x3ec, 0x3df, 0x3e1, + 0x3e4, 0x3e6, 0x3f0, 0x7e9, 0x7ef, 0xff8, 0xffe, 0xffc, + 0xfff, +}; + +static const uint8_t bits10[169] = { + 6, 5, 6, 6, 7, 8, 9, 10, 10, 10, 11, 11, 12, 5, 4, 4, + 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 6, 4, 5, 5, 6, 6, + 7, 8, 8, 9, 9, 10, 10, 6, 5, 5, 5, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 7, 6, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, + 10, 8, 7, 6, 7, 7, 7, 8, 8, 8, 9, 10, 10, 11, 9, 7, + 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 9, 8, 8, 8, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 9, 8, 8, 8, 8, 8, 9, 9, + 10, 10, 10, 11, 11, 10, 9, 9, 9, 9, 9, 9, 10, 10, 10, 11, + 11, 12, 10, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 11, + 10, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 11, 10, 10, 10, + 10, 10, 10, 11, 11, 12, 12, 12, 12, +}; + +static const uint16_t codes11[289] = { + 0x000, 0x006, 0x019, 0x03d, 0x09c, 0x0c6, 0x1a7, 0x390, + 0x3c2, 0x3df, 0x7e6, 0x7f3, 0xffb, 0x7ec, 0xffa, 0xffe, + 0x38e, 0x005, 0x001, 0x008, 0x014, 0x037, 0x042, 0x092, + 0x0af, 0x191, 0x1a5, 0x1b5, 0x39e, 0x3c0, 0x3a2, 0x3cd, + 0x7d6, 0x0ae, 0x017, 0x007, 0x009, 0x018, 0x039, 0x040, + 0x08e, 0x0a3, 0x0b8, 0x199, 0x1ac, 0x1c1, 0x3b1, 0x396, + 0x3be, 0x3ca, 0x09d, 0x03c, 0x015, 0x016, 0x01a, 0x03b, + 0x044, 0x091, 0x0a5, 0x0be, 0x196, 0x1ae, 0x1b9, 0x3a1, + 0x391, 0x3a5, 0x3d5, 0x094, 0x09a, 0x036, 0x038, 0x03a, + 0x041, 0x08c, 0x09b, 0x0b0, 0x0c3, 0x19e, 0x1ab, 0x1bc, + 0x39f, 0x38f, 0x3a9, 0x3cf, 0x093, 0x0bf, 0x03e, 0x03f, + 0x043, 0x045, 0x09e, 0x0a7, 0x0b9, 0x194, 0x1a2, 0x1ba, + 0x1c3, 0x3a6, 0x3a7, 0x3bb, 0x3d4, 0x09f, 0x1a0, 0x08f, + 0x08d, 0x090, 0x098, 0x0a6, 0x0b6, 0x0c4, 0x19f, 0x1af, + 0x1bf, 0x399, 0x3bf, 0x3b4, 0x3c9, 0x3e7, 0x0a8, 0x1b6, + 0x0ab, 0x0a4, 0x0aa, 0x0b2, 0x0c2, 0x0c5, 0x198, 0x1a4, + 0x1b8, 0x38c, 0x3a4, 0x3c4, 0x3c6, 0x3dd, 0x3e8, 0x0ad, + 0x3af, 0x192, 0x0bd, 0x0bc, 0x18e, 0x197, 0x19a, 0x1a3, + 0x1b1, 0x38d, 0x398, 0x3b7, 0x3d3, 0x3d1, 0x3db, 0x7dd, + 0x0b4, 0x3de, 0x1a9, 0x19b, 0x19c, 0x1a1, 0x1aa, 0x1ad, + 0x1b3, 0x38b, 0x3b2, 0x3b8, 0x3ce, 0x3e1, 0x3e0, 0x7d2, + 0x7e5, 0x0b7, 0x7e3, 0x1bb, 0x1a8, 0x1a6, 0x1b0, 0x1b2, + 0x1b7, 0x39b, 0x39a, 0x3ba, 0x3b5, 0x3d6, 0x7d7, 0x3e4, + 0x7d8, 0x7ea, 0x0ba, 0x7e8, 0x3a0, 0x1bd, 0x1b4, 0x38a, + 0x1c4, 0x392, 0x3aa, 0x3b0, 0x3bc, 0x3d7, 0x7d4, 0x7dc, + 0x7db, 0x7d5, 0x7f0, 0x0c1, 0x7fb, 0x3c8, 0x3a3, 0x395, + 0x39d, 0x3ac, 0x3ae, 0x3c5, 0x3d8, 0x3e2, 0x3e6, 0x7e4, + 0x7e7, 0x7e0, 0x7e9, 0x7f7, 0x190, 0x7f2, 0x393, 0x1be, + 0x1c0, 0x394, 0x397, 0x3ad, 0x3c3, 0x3c1, 0x3d2, 0x7da, + 0x7d9, 0x7df, 0x7eb, 0x7f4, 0x7fa, 0x195, 0x7f8, 0x3bd, + 0x39c, 0x3ab, 0x3a8, 0x3b3, 0x3b9, 0x3d0, 0x3e3, 0x3e5, + 0x7e2, 0x7de, 0x7ed, 0x7f1, 0x7f9, 0x7fc, 0x193, 0xffd, + 0x3dc, 0x3b6, 0x3c7, 0x3cc, 0x3cb, 0x3d9, 0x3da, 0x7d3, + 0x7e1, 0x7ee, 0x7ef, 0x7f5, 0x7f6, 0xffc, 0xfff, 0x19d, + 0x1c2, 0x0b5, 0x0a1, 0x096, 0x097, 0x095, 0x099, 0x0a0, + 0x0a2, 0x0ac, 0x0a9, 0x0b1, 0x0b3, 0x0bb, 0x0c0, 0x18f, + 0x004, +}; + +static const uint8_t bits11[289] = { + 4, 5, 6, 7, 8, 8, 9, 10, 10, 10, 11, 11, 12, 11, 12, 12, + 10, 5, 4, 5, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, + 11, 8, 6, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, + 10, 10, 8, 7, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, + 10, 10, 10, 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 10, 10, 10, 10, 8, 8, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 8, 9, 8, 8, 8, 8, 8, 8, 8, 9, 9, + 9, 10, 10, 10, 10, 10, 8, 9, 8, 8, 8, 8, 8, 8, 9, 9, + 9, 10, 10, 10, 10, 10, 10, 8, 10, 9, 8, 8, 9, 9, 9, 9, + 9, 10, 10, 10, 10, 10, 10, 11, 8, 10, 9, 9, 9, 9, 9, 9, + 9, 10, 10, 10, 10, 10, 10, 11, 11, 8, 11, 9, 9, 9, 9, 9, + 9, 10, 10, 10, 10, 10, 11, 10, 11, 11, 8, 11, 10, 9, 9, 10, + 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 8, 11, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 9, 11, 10, 9, + 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 9, 11, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 9, 12, + 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, + 5, +}; + +const uint16_t * const ff_aac_spectral_codes[11] = { + codes1, codes2, codes3, codes4, codes5, codes6, codes7, codes8, + codes9, codes10, codes11, +}; + +const uint8_t * const ff_aac_spectral_bits[11] = { + bits1, bits2, bits3, bits4, bits5, bits6, bits7, bits8, + bits9, bits10, bits11, +}; + +const uint16_t ff_aac_spectral_sizes[11] = { + 81, 81, 81, 81, 81, 81, 64, 64, 169, 169, 289, +}; + +/* NOTE: + * 64.0f is a special value indicating the existence of an escape code in the + * bitstream. + */ +static const DECLARE_ALIGNED(16, float, codebook_vector0)[324] = { + -1.0000000, -1.0000000, -1.0000000, -1.0000000, + -1.0000000, -1.0000000, -1.0000000, 0.0000000, + -1.0000000, -1.0000000, -1.0000000, 1.0000000, + -1.0000000, -1.0000000, 0.0000000, -1.0000000, + -1.0000000, -1.0000000, 0.0000000, 0.0000000, + -1.0000000, -1.0000000, 0.0000000, 1.0000000, + -1.0000000, -1.0000000, 1.0000000, -1.0000000, + -1.0000000, -1.0000000, 1.0000000, 0.0000000, + -1.0000000, -1.0000000, 1.0000000, 1.0000000, + -1.0000000, 0.0000000, -1.0000000, -1.0000000, + -1.0000000, 0.0000000, -1.0000000, 0.0000000, + -1.0000000, 0.0000000, -1.0000000, 1.0000000, + -1.0000000, 0.0000000, 0.0000000, -1.0000000, + -1.0000000, 0.0000000, 0.0000000, 0.0000000, + -1.0000000, 0.0000000, 0.0000000, 1.0000000, + -1.0000000, 0.0000000, 1.0000000, -1.0000000, + -1.0000000, 0.0000000, 1.0000000, 0.0000000, + -1.0000000, 0.0000000, 1.0000000, 1.0000000, + -1.0000000, 1.0000000, -1.0000000, -1.0000000, + -1.0000000, 1.0000000, -1.0000000, 0.0000000, + -1.0000000, 1.0000000, -1.0000000, 1.0000000, + -1.0000000, 1.0000000, 0.0000000, -1.0000000, + -1.0000000, 1.0000000, 0.0000000, 0.0000000, + -1.0000000, 1.0000000, 0.0000000, 1.0000000, + -1.0000000, 1.0000000, 1.0000000, -1.0000000, + -1.0000000, 1.0000000, 1.0000000, 0.0000000, + -1.0000000, 1.0000000, 1.0000000, 1.0000000, + 0.0000000, -1.0000000, -1.0000000, -1.0000000, + 0.0000000, -1.0000000, -1.0000000, 0.0000000, + 0.0000000, -1.0000000, -1.0000000, 1.0000000, + 0.0000000, -1.0000000, 0.0000000, -1.0000000, + 0.0000000, -1.0000000, 0.0000000, 0.0000000, + 0.0000000, -1.0000000, 0.0000000, 1.0000000, + 0.0000000, -1.0000000, 1.0000000, -1.0000000, + 0.0000000, -1.0000000, 1.0000000, 0.0000000, + 0.0000000, -1.0000000, 1.0000000, 1.0000000, + 0.0000000, 0.0000000, -1.0000000, -1.0000000, + 0.0000000, 0.0000000, -1.0000000, 0.0000000, + 0.0000000, 0.0000000, -1.0000000, 1.0000000, + 0.0000000, 0.0000000, 0.0000000, -1.0000000, + 0.0000000, 0.0000000, 0.0000000, 0.0000000, + 0.0000000, 0.0000000, 0.0000000, 1.0000000, + 0.0000000, 0.0000000, 1.0000000, -1.0000000, + 0.0000000, 0.0000000, 1.0000000, 0.0000000, + 0.0000000, 0.0000000, 1.0000000, 1.0000000, + 0.0000000, 1.0000000, -1.0000000, -1.0000000, + 0.0000000, 1.0000000, -1.0000000, 0.0000000, + 0.0000000, 1.0000000, -1.0000000, 1.0000000, + 0.0000000, 1.0000000, 0.0000000, -1.0000000, + 0.0000000, 1.0000000, 0.0000000, 0.0000000, + 0.0000000, 1.0000000, 0.0000000, 1.0000000, + 0.0000000, 1.0000000, 1.0000000, -1.0000000, + 0.0000000, 1.0000000, 1.0000000, 0.0000000, + 0.0000000, 1.0000000, 1.0000000, 1.0000000, + 1.0000000, -1.0000000, -1.0000000, -1.0000000, + 1.0000000, -1.0000000, -1.0000000, 0.0000000, + 1.0000000, -1.0000000, -1.0000000, 1.0000000, + 1.0000000, -1.0000000, 0.0000000, -1.0000000, + 1.0000000, -1.0000000, 0.0000000, 0.0000000, + 1.0000000, -1.0000000, 0.0000000, 1.0000000, + 1.0000000, -1.0000000, 1.0000000, -1.0000000, + 1.0000000, -1.0000000, 1.0000000, 0.0000000, + 1.0000000, -1.0000000, 1.0000000, 1.0000000, + 1.0000000, 0.0000000, -1.0000000, -1.0000000, + 1.0000000, 0.0000000, -1.0000000, 0.0000000, + 1.0000000, 0.0000000, -1.0000000, 1.0000000, + 1.0000000, 0.0000000, 0.0000000, -1.0000000, + 1.0000000, 0.0000000, 0.0000000, 0.0000000, + 1.0000000, 0.0000000, 0.0000000, 1.0000000, + 1.0000000, 0.0000000, 1.0000000, -1.0000000, + 1.0000000, 0.0000000, 1.0000000, 0.0000000, + 1.0000000, 0.0000000, 1.0000000, 1.0000000, + 1.0000000, 1.0000000, -1.0000000, -1.0000000, + 1.0000000, 1.0000000, -1.0000000, 0.0000000, + 1.0000000, 1.0000000, -1.0000000, 1.0000000, + 1.0000000, 1.0000000, 0.0000000, -1.0000000, + 1.0000000, 1.0000000, 0.0000000, 0.0000000, + 1.0000000, 1.0000000, 0.0000000, 1.0000000, + 1.0000000, 1.0000000, 1.0000000, -1.0000000, + 1.0000000, 1.0000000, 1.0000000, 0.0000000, + 1.0000000, 1.0000000, 1.0000000, 1.0000000, +}; + +static const DECLARE_ALIGNED(16, float, codebook_vector2)[324] = { + 0.0000000, 0.0000000, 0.0000000, 0.0000000, + 0.0000000, 0.0000000, 0.0000000, 1.0000000, + 0.0000000, 0.0000000, 0.0000000, 2.5198421, + 0.0000000, 0.0000000, 1.0000000, 0.0000000, + 0.0000000, 0.0000000, 1.0000000, 1.0000000, + 0.0000000, 0.0000000, 1.0000000, 2.5198421, + 0.0000000, 0.0000000, 2.5198421, 0.0000000, + 0.0000000, 0.0000000, 2.5198421, 1.0000000, + 0.0000000, 0.0000000, 2.5198421, 2.5198421, + 0.0000000, 1.0000000, 0.0000000, 0.0000000, + 0.0000000, 1.0000000, 0.0000000, 1.0000000, + 0.0000000, 1.0000000, 0.0000000, 2.5198421, + 0.0000000, 1.0000000, 1.0000000, 0.0000000, + 0.0000000, 1.0000000, 1.0000000, 1.0000000, + 0.0000000, 1.0000000, 1.0000000, 2.5198421, + 0.0000000, 1.0000000, 2.5198421, 0.0000000, + 0.0000000, 1.0000000, 2.5198421, 1.0000000, + 0.0000000, 1.0000000, 2.5198421, 2.5198421, + 0.0000000, 2.5198421, 0.0000000, 0.0000000, + 0.0000000, 2.5198421, 0.0000000, 1.0000000, + 0.0000000, 2.5198421, 0.0000000, 2.5198421, + 0.0000000, 2.5198421, 1.0000000, 0.0000000, + 0.0000000, 2.5198421, 1.0000000, 1.0000000, + 0.0000000, 2.5198421, 1.0000000, 2.5198421, + 0.0000000, 2.5198421, 2.5198421, 0.0000000, + 0.0000000, 2.5198421, 2.5198421, 1.0000000, + 0.0000000, 2.5198421, 2.5198421, 2.5198421, + 1.0000000, 0.0000000, 0.0000000, 0.0000000, + 1.0000000, 0.0000000, 0.0000000, 1.0000000, + 1.0000000, 0.0000000, 0.0000000, 2.5198421, + 1.0000000, 0.0000000, 1.0000000, 0.0000000, + 1.0000000, 0.0000000, 1.0000000, 1.0000000, + 1.0000000, 0.0000000, 1.0000000, 2.5198421, + 1.0000000, 0.0000000, 2.5198421, 0.0000000, + 1.0000000, 0.0000000, 2.5198421, 1.0000000, + 1.0000000, 0.0000000, 2.5198421, 2.5198421, + 1.0000000, 1.0000000, 0.0000000, 0.0000000, + 1.0000000, 1.0000000, 0.0000000, 1.0000000, + 1.0000000, 1.0000000, 0.0000000, 2.5198421, + 1.0000000, 1.0000000, 1.0000000, 0.0000000, + 1.0000000, 1.0000000, 1.0000000, 1.0000000, + 1.0000000, 1.0000000, 1.0000000, 2.5198421, + 1.0000000, 1.0000000, 2.5198421, 0.0000000, + 1.0000000, 1.0000000, 2.5198421, 1.0000000, + 1.0000000, 1.0000000, 2.5198421, 2.5198421, + 1.0000000, 2.5198421, 0.0000000, 0.0000000, + 1.0000000, 2.5198421, 0.0000000, 1.0000000, + 1.0000000, 2.5198421, 0.0000000, 2.5198421, + 1.0000000, 2.5198421, 1.0000000, 0.0000000, + 1.0000000, 2.5198421, 1.0000000, 1.0000000, + 1.0000000, 2.5198421, 1.0000000, 2.5198421, + 1.0000000, 2.5198421, 2.5198421, 0.0000000, + 1.0000000, 2.5198421, 2.5198421, 1.0000000, + 1.0000000, 2.5198421, 2.5198421, 2.5198421, + 2.5198421, 0.0000000, 0.0000000, 0.0000000, + 2.5198421, 0.0000000, 0.0000000, 1.0000000, + 2.5198421, 0.0000000, 0.0000000, 2.5198421, + 2.5198421, 0.0000000, 1.0000000, 0.0000000, + 2.5198421, 0.0000000, 1.0000000, 1.0000000, + 2.5198421, 0.0000000, 1.0000000, 2.5198421, + 2.5198421, 0.0000000, 2.5198421, 0.0000000, + 2.5198421, 0.0000000, 2.5198421, 1.0000000, + 2.5198421, 0.0000000, 2.5198421, 2.5198421, + 2.5198421, 1.0000000, 0.0000000, 0.0000000, + 2.5198421, 1.0000000, 0.0000000, 1.0000000, + 2.5198421, 1.0000000, 0.0000000, 2.5198421, + 2.5198421, 1.0000000, 1.0000000, 0.0000000, + 2.5198421, 1.0000000, 1.0000000, 1.0000000, + 2.5198421, 1.0000000, 1.0000000, 2.5198421, + 2.5198421, 1.0000000, 2.5198421, 0.0000000, + 2.5198421, 1.0000000, 2.5198421, 1.0000000, + 2.5198421, 1.0000000, 2.5198421, 2.5198421, + 2.5198421, 2.5198421, 0.0000000, 0.0000000, + 2.5198421, 2.5198421, 0.0000000, 1.0000000, + 2.5198421, 2.5198421, 0.0000000, 2.5198421, + 2.5198421, 2.5198421, 1.0000000, 0.0000000, + 2.5198421, 2.5198421, 1.0000000, 1.0000000, + 2.5198421, 2.5198421, 1.0000000, 2.5198421, + 2.5198421, 2.5198421, 2.5198421, 0.0000000, + 2.5198421, 2.5198421, 2.5198421, 1.0000000, + 2.5198421, 2.5198421, 2.5198421, 2.5198421, +}; + +static const DECLARE_ALIGNED(16, float, codebook_vector4)[162] = { + -6.3496042, -6.3496042, -6.3496042, -4.3267487, + -6.3496042, -2.5198421, -6.3496042, -1.0000000, + -6.3496042, 0.0000000, -6.3496042, 1.0000000, + -6.3496042, 2.5198421, -6.3496042, 4.3267487, + -6.3496042, 6.3496042, -4.3267487, -6.3496042, + -4.3267487, -4.3267487, -4.3267487, -2.5198421, + -4.3267487, -1.0000000, -4.3267487, 0.0000000, + -4.3267487, 1.0000000, -4.3267487, 2.5198421, + -4.3267487, 4.3267487, -4.3267487, 6.3496042, + -2.5198421, -6.3496042, -2.5198421, -4.3267487, + -2.5198421, -2.5198421, -2.5198421, -1.0000000, + -2.5198421, 0.0000000, -2.5198421, 1.0000000, + -2.5198421, 2.5198421, -2.5198421, 4.3267487, + -2.5198421, 6.3496042, -1.0000000, -6.3496042, + -1.0000000, -4.3267487, -1.0000000, -2.5198421, + -1.0000000, -1.0000000, -1.0000000, 0.0000000, + -1.0000000, 1.0000000, -1.0000000, 2.5198421, + -1.0000000, 4.3267487, -1.0000000, 6.3496042, + 0.0000000, -6.3496042, 0.0000000, -4.3267487, + 0.0000000, -2.5198421, 0.0000000, -1.0000000, + 0.0000000, 0.0000000, 0.0000000, 1.0000000, + 0.0000000, 2.5198421, 0.0000000, 4.3267487, + 0.0000000, 6.3496042, 1.0000000, -6.3496042, + 1.0000000, -4.3267487, 1.0000000, -2.5198421, + 1.0000000, -1.0000000, 1.0000000, 0.0000000, + 1.0000000, 1.0000000, 1.0000000, 2.5198421, + 1.0000000, 4.3267487, 1.0000000, 6.3496042, + 2.5198421, -6.3496042, 2.5198421, -4.3267487, + 2.5198421, -2.5198421, 2.5198421, -1.0000000, + 2.5198421, 0.0000000, 2.5198421, 1.0000000, + 2.5198421, 2.5198421, 2.5198421, 4.3267487, + 2.5198421, 6.3496042, 4.3267487, -6.3496042, + 4.3267487, -4.3267487, 4.3267487, -2.5198421, + 4.3267487, -1.0000000, 4.3267487, 0.0000000, + 4.3267487, 1.0000000, 4.3267487, 2.5198421, + 4.3267487, 4.3267487, 4.3267487, 6.3496042, + 6.3496042, -6.3496042, 6.3496042, -4.3267487, + 6.3496042, -2.5198421, 6.3496042, -1.0000000, + 6.3496042, 0.0000000, 6.3496042, 1.0000000, + 6.3496042, 2.5198421, 6.3496042, 4.3267487, + 6.3496042, 6.3496042, +}; + +static const DECLARE_ALIGNED(16, float, codebook_vector6)[128] = { + 0.0000000, 0.0000000, 0.0000000, 1.0000000, + 0.0000000, 2.5198421, 0.0000000, 4.3267487, + 0.0000000, 6.3496042, 0.0000000, 8.5498797, + 0.0000000, 10.9027236, 0.0000000, 13.3905183, + 1.0000000, 0.0000000, 1.0000000, 1.0000000, + 1.0000000, 2.5198421, 1.0000000, 4.3267487, + 1.0000000, 6.3496042, 1.0000000, 8.5498797, + 1.0000000, 10.9027236, 1.0000000, 13.3905183, + 2.5198421, 0.0000000, 2.5198421, 1.0000000, + 2.5198421, 2.5198421, 2.5198421, 4.3267487, + 2.5198421, 6.3496042, 2.5198421, 8.5498797, + 2.5198421, 10.9027236, 2.5198421, 13.3905183, + 4.3267487, 0.0000000, 4.3267487, 1.0000000, + 4.3267487, 2.5198421, 4.3267487, 4.3267487, + 4.3267487, 6.3496042, 4.3267487, 8.5498797, + 4.3267487, 10.9027236, 4.3267487, 13.3905183, + 6.3496042, 0.0000000, 6.3496042, 1.0000000, + 6.3496042, 2.5198421, 6.3496042, 4.3267487, + 6.3496042, 6.3496042, 6.3496042, 8.5498797, + 6.3496042, 10.9027236, 6.3496042, 13.3905183, + 8.5498797, 0.0000000, 8.5498797, 1.0000000, + 8.5498797, 2.5198421, 8.5498797, 4.3267487, + 8.5498797, 6.3496042, 8.5498797, 8.5498797, + 8.5498797, 10.9027236, 8.5498797, 13.3905183, + 10.9027236, 0.0000000, 10.9027236, 1.0000000, + 10.9027236, 2.5198421, 10.9027236, 4.3267487, + 10.9027236, 6.3496042, 10.9027236, 8.5498797, + 10.9027236, 10.9027236, 10.9027236, 13.3905183, + 13.3905183, 0.0000000, 13.3905183, 1.0000000, + 13.3905183, 2.5198421, 13.3905183, 4.3267487, + 13.3905183, 6.3496042, 13.3905183, 8.5498797, + 13.3905183, 10.9027236, 13.3905183, 13.3905183, +}; + +static const DECLARE_ALIGNED(16, float, codebook_vector8)[338] = { + 0.0000000, 0.0000000, 0.0000000, 1.0000000, + 0.0000000, 2.5198421, 0.0000000, 4.3267487, + 0.0000000, 6.3496042, 0.0000000, 8.5498797, + 0.0000000, 10.9027236, 0.0000000, 13.3905183, + 0.0000000, 16.0000000, 0.0000000, 18.7207544, + 0.0000000, 21.5443469, 0.0000000, 24.4637810, + 0.0000000, 27.4731418, 1.0000000, 0.0000000, + 1.0000000, 1.0000000, 1.0000000, 2.5198421, + 1.0000000, 4.3267487, 1.0000000, 6.3496042, + 1.0000000, 8.5498797, 1.0000000, 10.9027236, + 1.0000000, 13.3905183, 1.0000000, 16.0000000, + 1.0000000, 18.7207544, 1.0000000, 21.5443469, + 1.0000000, 24.4637810, 1.0000000, 27.4731418, + 2.5198421, 0.0000000, 2.5198421, 1.0000000, + 2.5198421, 2.5198421, 2.5198421, 4.3267487, + 2.5198421, 6.3496042, 2.5198421, 8.5498797, + 2.5198421, 10.9027236, 2.5198421, 13.3905183, + 2.5198421, 16.0000000, 2.5198421, 18.7207544, + 2.5198421, 21.5443469, 2.5198421, 24.4637810, + 2.5198421, 27.4731418, 4.3267487, 0.0000000, + 4.3267487, 1.0000000, 4.3267487, 2.5198421, + 4.3267487, 4.3267487, 4.3267487, 6.3496042, + 4.3267487, 8.5498797, 4.3267487, 10.9027236, + 4.3267487, 13.3905183, 4.3267487, 16.0000000, + 4.3267487, 18.7207544, 4.3267487, 21.5443469, + 4.3267487, 24.4637810, 4.3267487, 27.4731418, + 6.3496042, 0.0000000, 6.3496042, 1.0000000, + 6.3496042, 2.5198421, 6.3496042, 4.3267487, + 6.3496042, 6.3496042, 6.3496042, 8.5498797, + 6.3496042, 10.9027236, 6.3496042, 13.3905183, + 6.3496042, 16.0000000, 6.3496042, 18.7207544, + 6.3496042, 21.5443469, 6.3496042, 24.4637810, + 6.3496042, 27.4731418, 8.5498797, 0.0000000, + 8.5498797, 1.0000000, 8.5498797, 2.5198421, + 8.5498797, 4.3267487, 8.5498797, 6.3496042, + 8.5498797, 8.5498797, 8.5498797, 10.9027236, + 8.5498797, 13.3905183, 8.5498797, 16.0000000, + 8.5498797, 18.7207544, 8.5498797, 21.5443469, + 8.5498797, 24.4637810, 8.5498797, 27.4731418, + 10.9027236, 0.0000000, 10.9027236, 1.0000000, + 10.9027236, 2.5198421, 10.9027236, 4.3267487, + 10.9027236, 6.3496042, 10.9027236, 8.5498797, + 10.9027236, 10.9027236, 10.9027236, 13.3905183, + 10.9027236, 16.0000000, 10.9027236, 18.7207544, + 10.9027236, 21.5443469, 10.9027236, 24.4637810, + 10.9027236, 27.4731418, 13.3905183, 0.0000000, + 13.3905183, 1.0000000, 13.3905183, 2.5198421, + 13.3905183, 4.3267487, 13.3905183, 6.3496042, + 13.3905183, 8.5498797, 13.3905183, 10.9027236, + 13.3905183, 13.3905183, 13.3905183, 16.0000000, + 13.3905183, 18.7207544, 13.3905183, 21.5443469, + 13.3905183, 24.4637810, 13.3905183, 27.4731418, + 16.0000000, 0.0000000, 16.0000000, 1.0000000, + 16.0000000, 2.5198421, 16.0000000, 4.3267487, + 16.0000000, 6.3496042, 16.0000000, 8.5498797, + 16.0000000, 10.9027236, 16.0000000, 13.3905183, + 16.0000000, 16.0000000, 16.0000000, 18.7207544, + 16.0000000, 21.5443469, 16.0000000, 24.4637810, + 16.0000000, 27.4731418, 18.7207544, 0.0000000, + 18.7207544, 1.0000000, 18.7207544, 2.5198421, + 18.7207544, 4.3267487, 18.7207544, 6.3496042, + 18.7207544, 8.5498797, 18.7207544, 10.9027236, + 18.7207544, 13.3905183, 18.7207544, 16.0000000, + 18.7207544, 18.7207544, 18.7207544, 21.5443469, + 18.7207544, 24.4637810, 18.7207544, 27.4731418, + 21.5443469, 0.0000000, 21.5443469, 1.0000000, + 21.5443469, 2.5198421, 21.5443469, 4.3267487, + 21.5443469, 6.3496042, 21.5443469, 8.5498797, + 21.5443469, 10.9027236, 21.5443469, 13.3905183, + 21.5443469, 16.0000000, 21.5443469, 18.7207544, + 21.5443469, 21.5443469, 21.5443469, 24.4637810, + 21.5443469, 27.4731418, 24.4637810, 0.0000000, + 24.4637810, 1.0000000, 24.4637810, 2.5198421, + 24.4637810, 4.3267487, 24.4637810, 6.3496042, + 24.4637810, 8.5498797, 24.4637810, 10.9027236, + 24.4637810, 13.3905183, 24.4637810, 16.0000000, + 24.4637810, 18.7207544, 24.4637810, 21.5443469, + 24.4637810, 24.4637810, 24.4637810, 27.4731418, + 27.4731418, 0.0000000, 27.4731418, 1.0000000, + 27.4731418, 2.5198421, 27.4731418, 4.3267487, + 27.4731418, 6.3496042, 27.4731418, 8.5498797, + 27.4731418, 10.9027236, 27.4731418, 13.3905183, + 27.4731418, 16.0000000, 27.4731418, 18.7207544, + 27.4731418, 21.5443469, 27.4731418, 24.4637810, + 27.4731418, 27.4731418, +}; + +static const DECLARE_ALIGNED(16, float, codebook_vector10)[578] = { + 0.0000000, 0.0000000, 0.0000000, 1.0000000, + 0.0000000, 2.5198421, 0.0000000, 4.3267487, + 0.0000000, 6.3496042, 0.0000000, 8.5498797, + 0.0000000, 10.9027236, 0.0000000, 13.3905183, + 0.0000000, 16.0000000, 0.0000000, 18.7207544, + 0.0000000, 21.5443469, 0.0000000, 24.4637810, + 0.0000000, 27.4731418, 0.0000000, 30.5673509, + 0.0000000, 33.7419917, 0.0000000, 36.9931811, + 0.0000000, 64.0f, 1.0000000, 0.0000000, + 1.0000000, 1.0000000, 1.0000000, 2.5198421, + 1.0000000, 4.3267487, 1.0000000, 6.3496042, + 1.0000000, 8.5498797, 1.0000000, 10.9027236, + 1.0000000, 13.3905183, 1.0000000, 16.0000000, + 1.0000000, 18.7207544, 1.0000000, 21.5443469, + 1.0000000, 24.4637810, 1.0000000, 27.4731418, + 1.0000000, 30.5673509, 1.0000000, 33.7419917, + 1.0000000, 36.9931811, 1.0000000, 64.0f, + 2.5198421, 0.0000000, 2.5198421, 1.0000000, + 2.5198421, 2.5198421, 2.5198421, 4.3267487, + 2.5198421, 6.3496042, 2.5198421, 8.5498797, + 2.5198421, 10.9027236, 2.5198421, 13.3905183, + 2.5198421, 16.0000000, 2.5198421, 18.7207544, + 2.5198421, 21.5443469, 2.5198421, 24.4637810, + 2.5198421, 27.4731418, 2.5198421, 30.5673509, + 2.5198421, 33.7419917, 2.5198421, 36.9931811, + 2.5198421, 64.0f, 4.3267487, 0.0000000, + 4.3267487, 1.0000000, 4.3267487, 2.5198421, + 4.3267487, 4.3267487, 4.3267487, 6.3496042, + 4.3267487, 8.5498797, 4.3267487, 10.9027236, + 4.3267487, 13.3905183, 4.3267487, 16.0000000, + 4.3267487, 18.7207544, 4.3267487, 21.5443469, + 4.3267487, 24.4637810, 4.3267487, 27.4731418, + 4.3267487, 30.5673509, 4.3267487, 33.7419917, + 4.3267487, 36.9931811, 4.3267487, 64.0f, + 6.3496042, 0.0000000, 6.3496042, 1.0000000, + 6.3496042, 2.5198421, 6.3496042, 4.3267487, + 6.3496042, 6.3496042, 6.3496042, 8.5498797, + 6.3496042, 10.9027236, 6.3496042, 13.3905183, + 6.3496042, 16.0000000, 6.3496042, 18.7207544, + 6.3496042, 21.5443469, 6.3496042, 24.4637810, + 6.3496042, 27.4731418, 6.3496042, 30.5673509, + 6.3496042, 33.7419917, 6.3496042, 36.9931811, + 6.3496042, 64.0f, 8.5498797, 0.0000000, + 8.5498797, 1.0000000, 8.5498797, 2.5198421, + 8.5498797, 4.3267487, 8.5498797, 6.3496042, + 8.5498797, 8.5498797, 8.5498797, 10.9027236, + 8.5498797, 13.3905183, 8.5498797, 16.0000000, + 8.5498797, 18.7207544, 8.5498797, 21.5443469, + 8.5498797, 24.4637810, 8.5498797, 27.4731418, + 8.5498797, 30.5673509, 8.5498797, 33.7419917, + 8.5498797, 36.9931811, 8.5498797, 64.0f, + 10.9027236, 0.0000000, 10.9027236, 1.0000000, + 10.9027236, 2.5198421, 10.9027236, 4.3267487, + 10.9027236, 6.3496042, 10.9027236, 8.5498797, + 10.9027236, 10.9027236, 10.9027236, 13.3905183, + 10.9027236, 16.0000000, 10.9027236, 18.7207544, + 10.9027236, 21.5443469, 10.9027236, 24.4637810, + 10.9027236, 27.4731418, 10.9027236, 30.5673509, + 10.9027236, 33.7419917, 10.9027236, 36.9931811, + 10.9027236, 64.0f, 13.3905183, 0.0000000, + 13.3905183, 1.0000000, 13.3905183, 2.5198421, + 13.3905183, 4.3267487, 13.3905183, 6.3496042, + 13.3905183, 8.5498797, 13.3905183, 10.9027236, + 13.3905183, 13.3905183, 13.3905183, 16.0000000, + 13.3905183, 18.7207544, 13.3905183, 21.5443469, + 13.3905183, 24.4637810, 13.3905183, 27.4731418, + 13.3905183, 30.5673509, 13.3905183, 33.7419917, + 13.3905183, 36.9931811, 13.3905183, 64.0f, + 16.0000000, 0.0000000, 16.0000000, 1.0000000, + 16.0000000, 2.5198421, 16.0000000, 4.3267487, + 16.0000000, 6.3496042, 16.0000000, 8.5498797, + 16.0000000, 10.9027236, 16.0000000, 13.3905183, + 16.0000000, 16.0000000, 16.0000000, 18.7207544, + 16.0000000, 21.5443469, 16.0000000, 24.4637810, + 16.0000000, 27.4731418, 16.0000000, 30.5673509, + 16.0000000, 33.7419917, 16.0000000, 36.9931811, + 16.0000000, 64.0f, 18.7207544, 0.0000000, + 18.7207544, 1.0000000, 18.7207544, 2.5198421, + 18.7207544, 4.3267487, 18.7207544, 6.3496042, + 18.7207544, 8.5498797, 18.7207544, 10.9027236, + 18.7207544, 13.3905183, 18.7207544, 16.0000000, + 18.7207544, 18.7207544, 18.7207544, 21.5443469, + 18.7207544, 24.4637810, 18.7207544, 27.4731418, + 18.7207544, 30.5673509, 18.7207544, 33.7419917, + 18.7207544, 36.9931811, 18.7207544, 64.0f, + 21.5443469, 0.0000000, 21.5443469, 1.0000000, + 21.5443469, 2.5198421, 21.5443469, 4.3267487, + 21.5443469, 6.3496042, 21.5443469, 8.5498797, + 21.5443469, 10.9027236, 21.5443469, 13.3905183, + 21.5443469, 16.0000000, 21.5443469, 18.7207544, + 21.5443469, 21.5443469, 21.5443469, 24.4637810, + 21.5443469, 27.4731418, 21.5443469, 30.5673509, + 21.5443469, 33.7419917, 21.5443469, 36.9931811, + 21.5443469, 64.0f, 24.4637810, 0.0000000, + 24.4637810, 1.0000000, 24.4637810, 2.5198421, + 24.4637810, 4.3267487, 24.4637810, 6.3496042, + 24.4637810, 8.5498797, 24.4637810, 10.9027236, + 24.4637810, 13.3905183, 24.4637810, 16.0000000, + 24.4637810, 18.7207544, 24.4637810, 21.5443469, + 24.4637810, 24.4637810, 24.4637810, 27.4731418, + 24.4637810, 30.5673509, 24.4637810, 33.7419917, + 24.4637810, 36.9931811, 24.4637810, 64.0f, + 27.4731418, 0.0000000, 27.4731418, 1.0000000, + 27.4731418, 2.5198421, 27.4731418, 4.3267487, + 27.4731418, 6.3496042, 27.4731418, 8.5498797, + 27.4731418, 10.9027236, 27.4731418, 13.3905183, + 27.4731418, 16.0000000, 27.4731418, 18.7207544, + 27.4731418, 21.5443469, 27.4731418, 24.4637810, + 27.4731418, 27.4731418, 27.4731418, 30.5673509, + 27.4731418, 33.7419917, 27.4731418, 36.9931811, + 27.4731418, 64.0f, 30.5673509, 0.0000000, + 30.5673509, 1.0000000, 30.5673509, 2.5198421, + 30.5673509, 4.3267487, 30.5673509, 6.3496042, + 30.5673509, 8.5498797, 30.5673509, 10.9027236, + 30.5673509, 13.3905183, 30.5673509, 16.0000000, + 30.5673509, 18.7207544, 30.5673509, 21.5443469, + 30.5673509, 24.4637810, 30.5673509, 27.4731418, + 30.5673509, 30.5673509, 30.5673509, 33.7419917, + 30.5673509, 36.9931811, 30.5673509, 64.0f, + 33.7419917, 0.0000000, 33.7419917, 1.0000000, + 33.7419917, 2.5198421, 33.7419917, 4.3267487, + 33.7419917, 6.3496042, 33.7419917, 8.5498797, + 33.7419917, 10.9027236, 33.7419917, 13.3905183, + 33.7419917, 16.0000000, 33.7419917, 18.7207544, + 33.7419917, 21.5443469, 33.7419917, 24.4637810, + 33.7419917, 27.4731418, 33.7419917, 30.5673509, + 33.7419917, 33.7419917, 33.7419917, 36.9931811, + 33.7419917, 64.0f, 36.9931811, 0.0000000, + 36.9931811, 1.0000000, 36.9931811, 2.5198421, + 36.9931811, 4.3267487, 36.9931811, 6.3496042, + 36.9931811, 8.5498797, 36.9931811, 10.9027236, + 36.9931811, 13.3905183, 36.9931811, 16.0000000, + 36.9931811, 18.7207544, 36.9931811, 21.5443469, + 36.9931811, 24.4637810, 36.9931811, 27.4731418, + 36.9931811, 30.5673509, 36.9931811, 33.7419917, + 36.9931811, 36.9931811, 36.9931811, 64.0f, + 64.0f, 0.0000000, 64.0f, 1.0000000, + 64.0f, 2.5198421, 64.0f, 4.3267487, + 64.0f, 6.3496042, 64.0f, 8.5498797, + 64.0f, 10.9027236, 64.0f, 13.3905183, + 64.0f, 16.0000000, 64.0f, 18.7207544, + 64.0f, 21.5443469, 64.0f, 24.4637810, + 64.0f, 27.4731418, 64.0f, 30.5673509, + 64.0f, 33.7419917, 64.0f, 36.9931811, + 64.0f, 64.0f, +}; + +const float * const ff_aac_codebook_vectors[] = { + codebook_vector0, codebook_vector0, codebook_vector2, + codebook_vector2, codebook_vector4, codebook_vector4, + codebook_vector6, codebook_vector6, codebook_vector8, + codebook_vector8, codebook_vector10, +}; + +static const float codebook_vector0_vals[] = { + -1.0000000, 0.0000000, 1.0000000 +}; + +/* + * bits 0:1, 2:3, 4:5, 6:7 index into _vals array + * 8:11 number of non-zero values + * 12:15 bit mask of non-zero values + */ +static const uint16_t codebook_vector02_idx[] = { + 0x0000, 0x8140, 0x8180, 0x4110, 0xc250, 0xc290, 0x4120, 0xc260, 0xc2a0, + 0x2104, 0xa244, 0xa284, 0x6214, 0xe354, 0xe394, 0x6224, 0xe364, 0xe3a4, + 0x2108, 0xa248, 0xa288, 0x6218, 0xe358, 0xe398, 0x6228, 0xe368, 0xe3a8, + 0x1101, 0x9241, 0x9281, 0x5211, 0xd351, 0xd391, 0x5221, 0xd361, 0xd3a1, + 0x3205, 0xb345, 0xb385, 0x7315, 0xf455, 0xf495, 0x7325, 0xf465, 0xf4a5, + 0x3209, 0xb349, 0xb389, 0x7319, 0xf459, 0xf499, 0x7329, 0xf469, 0xf4a9, + 0x1102, 0x9242, 0x9282, 0x5212, 0xd352, 0xd392, 0x5222, 0xd362, 0xd3a2, + 0x3206, 0xb346, 0xb386, 0x7316, 0xf456, 0xf496, 0x7326, 0xf466, 0xf4a6, + 0x320a, 0xb34a, 0xb38a, 0x731a, 0xf45a, 0xf49a, 0x732a, 0xf46a, 0xf4aa, +}; + +static const float codebook_vector4_vals[] = { + -6.3496042, -4.3267487, + -2.5198421, -1.0000000, + 0.0000000, 1.0000000, + 2.5198421, 4.3267487, + 6.3496042, +}; + +/* + * bits 0:3, 4:7 index into _vals array + */ +static const uint16_t codebook_vector4_idx[] = { + 0x0000, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080, + 0x0001, 0x0011, 0x0021, 0x0031, 0x0041, 0x0051, 0x0061, 0x0071, 0x0081, + 0x0002, 0x0012, 0x0022, 0x0032, 0x0042, 0x0052, 0x0062, 0x0072, 0x0082, + 0x0003, 0x0013, 0x0023, 0x0033, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083, + 0x0004, 0x0014, 0x0024, 0x0034, 0x0044, 0x0054, 0x0064, 0x0074, 0x0084, + 0x0005, 0x0015, 0x0025, 0x0035, 0x0045, 0x0055, 0x0065, 0x0075, 0x0085, + 0x0006, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0076, 0x0086, + 0x0007, 0x0017, 0x0027, 0x0037, 0x0047, 0x0057, 0x0067, 0x0077, 0x0087, + 0x0008, 0x0018, 0x0028, 0x0038, 0x0048, 0x0058, 0x0068, 0x0078, 0x0088, +}; + +/* + * bits 0:3, 4:7 index into _vals array + * 8:11 number of non-zero values + * 12:15 1: only second value non-zero + * 0: other cases + */ +static const uint16_t codebook_vector6_idx[] = { + 0x0000, 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, + 0x1101, 0x0211, 0x0221, 0x0231, 0x0241, 0x0251, 0x0261, 0x0271, + 0x1102, 0x0212, 0x0222, 0x0232, 0x0242, 0x0252, 0x0262, 0x0272, + 0x1103, 0x0213, 0x0223, 0x0233, 0x0243, 0x0253, 0x0263, 0x0273, + 0x1104, 0x0214, 0x0224, 0x0234, 0x0244, 0x0254, 0x0264, 0x0274, + 0x1105, 0x0215, 0x0225, 0x0235, 0x0245, 0x0255, 0x0265, 0x0275, + 0x1106, 0x0216, 0x0226, 0x0236, 0x0246, 0x0256, 0x0266, 0x0276, + 0x1107, 0x0217, 0x0227, 0x0237, 0x0247, 0x0257, 0x0267, 0x0277, +}; + +/* + * bits 0:3, 4:7 index into _vals array + * 8:11 number of non-zero values + * 12:15 1: only second value non-zero + * 0: other cases + */ +static const uint16_t codebook_vector8_idx[] = { + 0x0000, 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, + 0x0170, 0x0180, 0x0190, 0x01a0, 0x01b0, 0x01c0, + 0x1101, 0x0211, 0x0221, 0x0231, 0x0241, 0x0251, 0x0261, + 0x0271, 0x0281, 0x0291, 0x02a1, 0x02b1, 0x02c1, + 0x1102, 0x0212, 0x0222, 0x0232, 0x0242, 0x0252, 0x0262, + 0x0272, 0x0282, 0x0292, 0x02a2, 0x02b2, 0x02c2, + 0x1103, 0x0213, 0x0223, 0x0233, 0x0243, 0x0253, 0x0263, + 0x0273, 0x0283, 0x0293, 0x02a3, 0x02b3, 0x02c3, + 0x1104, 0x0214, 0x0224, 0x0234, 0x0244, 0x0254, 0x0264, + 0x0274, 0x0284, 0x0294, 0x02a4, 0x02b4, 0x02c4, + 0x1105, 0x0215, 0x0225, 0x0235, 0x0245, 0x0255, 0x0265, + 0x0275, 0x0285, 0x0295, 0x02a5, 0x02b5, 0x02c5, + 0x1106, 0x0216, 0x0226, 0x0236, 0x0246, 0x0256, 0x0266, + 0x0276, 0x0286, 0x0296, 0x02a6, 0x02b6, 0x02c6, + 0x1107, 0x0217, 0x0227, 0x0237, 0x0247, 0x0257, 0x0267, + 0x0277, 0x0287, 0x0297, 0x02a7, 0x02b7, 0x02c7, + 0x1108, 0x0218, 0x0228, 0x0238, 0x0248, 0x0258, 0x0268, + 0x0278, 0x0288, 0x0298, 0x02a8, 0x02b8, 0x02c8, + 0x1109, 0x0219, 0x0229, 0x0239, 0x0249, 0x0259, 0x0269, + 0x0279, 0x0289, 0x0299, 0x02a9, 0x02b9, 0x02c9, + 0x110a, 0x021a, 0x022a, 0x023a, 0x024a, 0x025a, 0x026a, + 0x027a, 0x028a, 0x029a, 0x02aa, 0x02ba, 0x02ca, + 0x110b, 0x021b, 0x022b, 0x023b, 0x024b, 0x025b, 0x026b, + 0x027b, 0x028b, 0x029b, 0x02ab, 0x02bb, 0x02cb, + 0x110c, 0x021c, 0x022c, 0x023c, 0x024c, 0x025c, 0x026c, + 0x027c, 0x028c, 0x029c, 0x02ac, 0x02bc, 0x02cc, +}; + +static const float codebook_vector10_vals[] = { + 0.0000000, 1.0000000, + 2.5198421, 4.3267487, + 6.3496042, 8.5498797, + 10.9027236, 13.3905183, + 16.0000000, 18.7207544, + 21.5443469, 24.4637810, + 27.4731418, 30.5673509, + 33.7419917, 36.9931811, +}; + +/* + * bits 0:3, 4:7 index into _vals array + * 8:9 bit mask of escape-coded entries + * 12:15 number of non-zero values + */ +static const uint16_t codebook_vector10_idx[] = { + 0x0000, 0x1010, 0x1020, 0x1030, 0x1040, 0x1050, 0x1060, 0x1070, + 0x1080, 0x1090, 0x10a0, 0x10b0, 0x10c0, 0x10d0, 0x10e0, 0x10f0, 0x1200, + 0x1001, 0x2011, 0x2021, 0x2031, 0x2041, 0x2051, 0x2061, 0x2071, + 0x2081, 0x2091, 0x20a1, 0x20b1, 0x20c1, 0x20d1, 0x20e1, 0x20f1, 0x2201, + 0x1002, 0x2012, 0x2022, 0x2032, 0x2042, 0x2052, 0x2062, 0x2072, + 0x2082, 0x2092, 0x20a2, 0x20b2, 0x20c2, 0x20d2, 0x20e2, 0x20f2, 0x2202, + 0x1003, 0x2013, 0x2023, 0x2033, 0x2043, 0x2053, 0x2063, 0x2073, + 0x2083, 0x2093, 0x20a3, 0x20b3, 0x20c3, 0x20d3, 0x20e3, 0x20f3, 0x2203, + 0x1004, 0x2014, 0x2024, 0x2034, 0x2044, 0x2054, 0x2064, 0x2074, + 0x2084, 0x2094, 0x20a4, 0x20b4, 0x20c4, 0x20d4, 0x20e4, 0x20f4, 0x2204, + 0x1005, 0x2015, 0x2025, 0x2035, 0x2045, 0x2055, 0x2065, 0x2075, + 0x2085, 0x2095, 0x20a5, 0x20b5, 0x20c5, 0x20d5, 0x20e5, 0x20f5, 0x2205, + 0x1006, 0x2016, 0x2026, 0x2036, 0x2046, 0x2056, 0x2066, 0x2076, + 0x2086, 0x2096, 0x20a6, 0x20b6, 0x20c6, 0x20d6, 0x20e6, 0x20f6, 0x2206, + 0x1007, 0x2017, 0x2027, 0x2037, 0x2047, 0x2057, 0x2067, 0x2077, + 0x2087, 0x2097, 0x20a7, 0x20b7, 0x20c7, 0x20d7, 0x20e7, 0x20f7, 0x2207, + 0x1008, 0x2018, 0x2028, 0x2038, 0x2048, 0x2058, 0x2068, 0x2078, + 0x2088, 0x2098, 0x20a8, 0x20b8, 0x20c8, 0x20d8, 0x20e8, 0x20f8, 0x2208, + 0x1009, 0x2019, 0x2029, 0x2039, 0x2049, 0x2059, 0x2069, 0x2079, + 0x2089, 0x2099, 0x20a9, 0x20b9, 0x20c9, 0x20d9, 0x20e9, 0x20f9, 0x2209, + 0x100a, 0x201a, 0x202a, 0x203a, 0x204a, 0x205a, 0x206a, 0x207a, + 0x208a, 0x209a, 0x20aa, 0x20ba, 0x20ca, 0x20da, 0x20ea, 0x20fa, 0x220a, + 0x100b, 0x201b, 0x202b, 0x203b, 0x204b, 0x205b, 0x206b, 0x207b, + 0x208b, 0x209b, 0x20ab, 0x20bb, 0x20cb, 0x20db, 0x20eb, 0x20fb, 0x220b, + 0x100c, 0x201c, 0x202c, 0x203c, 0x204c, 0x205c, 0x206c, 0x207c, + 0x208c, 0x209c, 0x20ac, 0x20bc, 0x20cc, 0x20dc, 0x20ec, 0x20fc, 0x220c, + 0x100d, 0x201d, 0x202d, 0x203d, 0x204d, 0x205d, 0x206d, 0x207d, + 0x208d, 0x209d, 0x20ad, 0x20bd, 0x20cd, 0x20dd, 0x20ed, 0x20fd, 0x220d, + 0x100e, 0x201e, 0x202e, 0x203e, 0x204e, 0x205e, 0x206e, 0x207e, + 0x208e, 0x209e, 0x20ae, 0x20be, 0x20ce, 0x20de, 0x20ee, 0x20fe, 0x220e, + 0x100f, 0x201f, 0x202f, 0x203f, 0x204f, 0x205f, 0x206f, 0x207f, + 0x208f, 0x209f, 0x20af, 0x20bf, 0x20cf, 0x20df, 0x20ef, 0x20ff, 0x220f, + 0x1100, 0x2110, 0x2120, 0x2130, 0x2140, 0x2150, 0x2160, 0x2170, + 0x2180, 0x2190, 0x21a0, 0x21b0, 0x21c0, 0x21d0, 0x21e0, 0x21f0, 0x2300, +}; + +const float *const ff_aac_codebook_vector_vals[] = { + codebook_vector0_vals, codebook_vector0_vals, + codebook_vector10_vals, codebook_vector10_vals, + codebook_vector4_vals, codebook_vector4_vals, + codebook_vector10_vals, codebook_vector10_vals, + codebook_vector10_vals, codebook_vector10_vals, + codebook_vector10_vals, +}; + +const uint16_t *const ff_aac_codebook_vector_idx[] = { + codebook_vector02_idx, codebook_vector02_idx, + codebook_vector02_idx, codebook_vector02_idx, + codebook_vector4_idx, codebook_vector4_idx, + codebook_vector6_idx, codebook_vector6_idx, + codebook_vector8_idx, codebook_vector8_idx, + codebook_vector10_idx, +}; + +/* @name swb_offsets + * Sample offset into the window indicating the beginning of a scalefactor + * window band + * + * scalefactor window band - term for scalefactor bands within a window, + * given in Table 4.110 to Table 4.128. + * + * scalefactor band - a set of spectral coefficients which are scaled by one + * scalefactor. In case of EIGHT_SHORT_SEQUENCE and grouping a scalefactor band + * may contain several scalefactor window bands of corresponding frequency. For + * all other window_sequences scalefactor bands and scalefactor window bands are + * identical. + * @{ + */ + +static const uint16_t swb_offset_1024_96[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 64, + 72, 80, 88, 96, 108, 120, 132, 144, + 156, 172, 188, 212, 240, 276, 320, 384, + 448, 512, 576, 640, 704, 768, 832, 896, + 960, 1024 +}; + +static const uint16_t swb_offset_128_96[] = { + 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128 +}; + +static const uint16_t swb_offset_1024_64[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 64, + 72, 80, 88, 100, 112, 124, 140, 156, + 172, 192, 216, 240, 268, 304, 344, 384, + 424, 464, 504, 544, 584, 624, 664, 704, + 744, 784, 824, 864, 904, 944, 984, 1024 +}; + +static const uint16_t swb_offset_1024_48[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 48, 56, 64, 72, 80, + 88, 96, 108, 120, 132, 144, 160, 176, + 196, 216, 240, 264, 292, 320, 352, 384, + 416, 448, 480, 512, 544, 576, 608, 640, + 672, 704, 736, 768, 800, 832, 864, 896, + 928, 1024 +}; + +static const uint16_t swb_offset_512_48[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, + 68, 76, 84, 92, 100, 112, 124, 136, + 148, 164, 184, 208, 236, 268, 300, 332, + 364, 396, 428, 460, 512 +}; + +static const uint16_t swb_offset_480_48[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 64, + 72, 80, 88, 96, 108, 120, 132, 144, + 156, 172, 188, 212, 240, 272, 304, 336, + 368, 400, 432, 480 +}; + +static const uint16_t swb_offset_128_48[] = { + 0, 4, 8, 12, 16, 20, 28, 36, + 44, 56, 68, 80, 96, 112, 128 +}; + +static const uint16_t swb_offset_1024_32[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 48, 56, 64, 72, 80, + 88, 96, 108, 120, 132, 144, 160, 176, + 196, 216, 240, 264, 292, 320, 352, 384, + 416, 448, 480, 512, 544, 576, 608, 640, + 672, 704, 736, 768, 800, 832, 864, 896, + 928, 960, 992, 1024 +}; + +static const uint16_t swb_offset_512_32[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 64, + 72, 80, 88, 96, 108, 120, 132, 144, + 160, 176, 192, 212, 236, 260, 288, 320, + 352, 384, 416, 448, 480, 512 +}; + +static const uint16_t swb_offset_480_32[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, + 64, 72, 80, 88, 96, 104, 112, 124, + 136, 148, 164, 180, 200, 224, 256, 288, + 320, 352, 384, 416, 448, 480 + }; + +static const uint16_t swb_offset_1024_24[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 52, 60, 68, 76, + 84, 92, 100, 108, 116, 124, 136, 148, + 160, 172, 188, 204, 220, 240, 260, 284, + 308, 336, 364, 396, 432, 468, 508, 552, + 600, 652, 704, 768, 832, 896, 960, 1024 +}; + +static const uint16_t swb_offset_512_24[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 52, 60, 68, 80, + 92, 104, 120, 140, 164, 192, 224, 256, + 288, 320, 352, 384, 416, 448, 480, 512, +}; + +static const uint16_t swb_offset_480_24[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 52, 60, 68, 80, + 92, 104, 120, 140, 164, 192, 224, 256, + 288, 320, 352, 384, 416, 448, 480 +}; + +static const uint16_t swb_offset_128_24[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 36, 44, 52, 64, 76, 92, 108, 128 +}; + +static const uint16_t swb_offset_1024_16[] = { + 0, 8, 16, 24, 32, 40, 48, 56, + 64, 72, 80, 88, 100, 112, 124, 136, + 148, 160, 172, 184, 196, 212, 228, 244, + 260, 280, 300, 320, 344, 368, 396, 424, + 456, 492, 532, 572, 616, 664, 716, 772, + 832, 896, 960, 1024 +}; + +static const uint16_t swb_offset_128_16[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 40, 48, 60, 72, 88, 108, 128 +}; + +static const uint16_t swb_offset_1024_8[] = { + 0, 12, 24, 36, 48, 60, 72, 84, + 96, 108, 120, 132, 144, 156, 172, 188, + 204, 220, 236, 252, 268, 288, 308, 328, + 348, 372, 396, 420, 448, 476, 508, 544, + 580, 620, 664, 712, 764, 820, 880, 944, + 1024 +}; + +static const uint16_t swb_offset_128_8[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 36, 44, 52, 60, 72, 88, 108, 128 +}; + +static const uint16_t swb_offset_960_96[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, + 108, 120, 132, 144, 156, 172, 188, 212, 240, 276, + 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, + 960 +}; + +static const uint16_t swb_offset_960_64[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 44, 48, 52, 56, 64, 72, 80, 88, 100, + 112, 124, 140, 156, 172, 192, 216, 240, 268, 304, + 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, + 744, 784, 824, 864, 904, 944, 960 +}; + +static const uint16_t swb_offset_960_48[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 48, 56, 64, 72, 80, 88, 96, 108, 120, + 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, + 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, + 672, 704, 736, 768, 800, 832, 864, 896, 928, 960 +}; + +static const uint16_t swb_offset_960_32[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 48, 56, 64, 72, 80, 88, 96, 108, 120, + 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, + 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, + 672, 704, 736, 768, 800, 832, 864, 896, 928, 960 +}; + +static const uint16_t swb_offset_960_24[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, + 40, 44, 52, 60, 68, 76, 84, 92, 100, 108, + 116, 124, 136, 148, 160, 172, 188, 204, 220, 240, + 260, 284, 308, 336, 364, 396, 432, 468, 508, 552, + 600, 652, 704, 768, 832, 896, 960 +}; + +static const uint16_t swb_offset_960_16[] = +{ + 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, + 80, 88, 100, 112, 124, 136, 148, 160, 172, 184, + 196, 212, 228, 244, 260, 280, 300, 320, 344, 368, + 396, 424, 456, 492, 532, 572, 616, 664, 716, 772, + 832, 896, 960 +}; + +static const uint16_t swb_offset_960_8[] = +{ + 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, + 120, 132, 144, 156, 172, 188, 204, 220, 236, 252, + 268, 288, 308, 328, 348, 372, 396, 420, 448, 476, + 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, + 960 +}; + + +static const uint16_t swb_offset_120_96[] = +{ + 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 120 +}; + +static const uint16_t swb_offset_120_64[] = +{ + 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 120 +}; + +static const uint16_t swb_offset_120_48[] = +{ + 0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 120 +}; + +static const uint16_t swb_offset_120_24[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 120 +}; + +static const uint16_t swb_offset_120_16[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 120 +}; + +static const uint16_t swb_offset_120_8[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 120 +}; + +const uint16_t * const ff_swb_offset_1024[] = { + swb_offset_1024_96, swb_offset_1024_96, swb_offset_1024_64, + swb_offset_1024_48, swb_offset_1024_48, swb_offset_1024_32, + swb_offset_1024_24, swb_offset_1024_24, swb_offset_1024_16, + swb_offset_1024_16, swb_offset_1024_16, swb_offset_1024_8, + swb_offset_1024_8 +}; + +const uint16_t * const ff_swb_offset_960[] = { + swb_offset_960_96, swb_offset_960_96, swb_offset_960_64, + swb_offset_960_48, swb_offset_960_48, swb_offset_960_32, + swb_offset_960_24, swb_offset_960_24, swb_offset_960_16, + swb_offset_960_16, swb_offset_960_16, swb_offset_960_8, + swb_offset_960_8 +}; + +const uint16_t * const ff_swb_offset_512[] = { + NULL, NULL, NULL, + swb_offset_512_48, swb_offset_512_48, swb_offset_512_32, + swb_offset_512_24, swb_offset_512_24, NULL, + NULL, NULL, NULL, + NULL +}; + +const uint16_t * const ff_swb_offset_480[] = { + NULL, NULL, NULL, + swb_offset_480_48, swb_offset_480_48, swb_offset_480_32, + swb_offset_480_24, swb_offset_480_24, NULL, + NULL, NULL, NULL, + NULL +}; + +const uint16_t * const ff_swb_offset_128[] = { + /* The last entry on the following row is swb_offset_128_64 but is a + duplicate of swb_offset_128_96. */ + swb_offset_128_96, swb_offset_128_96, swb_offset_128_96, + swb_offset_128_48, swb_offset_128_48, swb_offset_128_48, + swb_offset_128_24, swb_offset_128_24, swb_offset_128_16, + swb_offset_128_16, swb_offset_128_16, swb_offset_128_8, + swb_offset_128_8 +}; + +const uint16_t * const ff_swb_offset_120[] = { + swb_offset_120_96, swb_offset_120_96, swb_offset_120_96, + swb_offset_120_48, swb_offset_120_48, swb_offset_120_48, + swb_offset_120_24, swb_offset_120_24, swb_offset_120_16, + swb_offset_120_16, swb_offset_120_16, swb_offset_120_8, + swb_offset_120_8 +}; + +// @} + +/* @name ff_tns_max_bands + * The maximum number of scalefactor bands on which TNS can operate for the long + * and short transforms respectively. The index to these tables is related to + * the sample rate of the audio. + * @{ + */ +const uint8_t ff_tns_max_bands_1024[] = { + 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39, 39 +}; + +const uint8_t ff_tns_max_bands_512[] = { + 0, 0, 0, 31, 32, 37, 31, 31, 0, 0, 0, 0, 0 +}; + +const uint8_t ff_tns_max_bands_480[] = { + 0, 0, 0, 31, 32, 37, 30, 30, 0, 0, 0, 0, 0 +}; + +const uint8_t ff_tns_max_bands_128[] = { + 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 +}; +// @} + +const DECLARE_ALIGNED(32, float, ff_aac_eld_window_512)[1920] = { + 0.00338834, 0.00567745, 0.00847677, 0.01172641, + 0.01532555, 0.01917664, 0.02318809, 0.02729259, + 0.03144503, 0.03560261, 0.03972499, 0.04379783, + 0.04783094, 0.05183357, 0.05581342, 0.05977723, + 0.06373173, 0.06768364, 0.07163937, 0.07559976, + 0.07956096, 0.08352024, 0.08747623, 0.09143035, + 0.09538618, 0.09934771, 0.10331917, 0.10730456, + 0.11130697, 0.11532867, 0.11937133, 0.12343922, + 0.12753911, 0.13167705, 0.13585812, 0.14008529, + 0.14435986, 0.14868291, 0.15305531, 0.15747594, + 0.16194193, 0.16645070, 0.17099991, 0.17558633, + 0.18020600, 0.18485548, 0.18953191, 0.19423322, + 0.19895800, 0.20370512, 0.20847374, 0.21326312, + 0.21807244, 0.22290083, 0.22774742, 0.23261210, + 0.23749542, 0.24239767, 0.24731889, 0.25225887, + 0.25721719, 0.26219330, 0.26718648, 0.27219630, + 0.27722262, 0.28226514, 0.28732336, 0.29239628, + 0.29748247, 0.30258055, 0.30768914, 0.31280508, + 0.31792385, 0.32304172, 0.32815579, 0.33326397, + 0.33836470, 0.34345661, 0.34853868, 0.35361188, + 0.35867865, 0.36374072, 0.36879900, 0.37385347, + 0.37890349, 0.38394836, 0.38898730, 0.39401912, + 0.39904236, 0.40405575, 0.40905820, 0.41404819, + 0.41902398, 0.42398423, 0.42892805, 0.43385441, + 0.43876210, 0.44365014, 0.44851786, 0.45336632, + 0.45819759, 0.46301302, 0.46781309, 0.47259722, + 0.47736435, 0.48211365, 0.48684450, 0.49155594, + 0.49624679, 0.50091636, 0.50556440, 0.51019132, + 0.51479771, 0.51938391, 0.52394998, 0.52849587, + 0.53302151, 0.53752680, 0.54201160, 0.54647575, + 0.55091916, 0.55534181, 0.55974376, 0.56412513, + 0.56848615, 0.57282710, 0.57714834, 0.58145030, + 0.58492489, 0.58918511, 0.59342326, 0.59763936, + 0.60183347, 0.60600561, 0.61015581, 0.61428412, + 0.61839056, 0.62247517, 0.62653799, 0.63057912, + 0.63459872, 0.63859697, 0.64257403, 0.64653001, + 0.65046495, 0.65437887, 0.65827181, 0.66214383, + 0.66599499, 0.66982535, 0.67363499, 0.67742394, + 0.68119219, 0.68493972, 0.68866653, 0.69237258, + 0.69605778, 0.69972207, 0.70336537, 0.70698758, + 0.71058862, 0.71416837, 0.71772674, 0.72126361, + 0.72477889, 0.72827246, 0.73174419, 0.73519392, + 0.73862141, 0.74202643, 0.74540874, 0.74876817, + 0.75210458, 0.75541785, 0.75870785, 0.76197437, + 0.76521709, 0.76843570, 0.77162988, 0.77479939, + 0.77794403, 0.78106359, 0.78415789, 0.78722670, + 0.79026979, 0.79328694, 0.79627791, 0.79924244, + 0.80218027, 0.80509112, 0.80797472, 0.81083081, + 0.81365915, 0.81645949, 0.81923160, 0.82197528, + 0.82469037, 0.82737673, 0.83003419, 0.83266262, + 0.83526186, 0.83783176, 0.84037217, 0.84288297, + 0.84536401, 0.84781517, 0.85023632, 0.85262739, + 0.85498836, 0.85731921, 0.85961993, 0.86189052, + 0.86413101, 0.86634140, 0.86852173, 0.87067211, + 0.87279275, 0.87488384, 0.87694559, 0.87897824, + 0.88098206, 0.88295729, 0.88490423, 0.88682332, + 0.88871519, 0.89058048, 0.89241983, 0.89423391, + 0.89602338, 0.89778893, 0.89953126, 0.90125142, + 0.90295086, 0.90463104, 0.90629341, 0.90793946, + 0.90957067, 0.91118856, 0.91279464, 0.91439073, + 0.91597898, 0.91756153, 0.91914049, 0.92071690, + 0.92229070, 0.92386182, 0.92542993, 0.92698946, + 0.92852960, 0.93003929, 0.93150727, 0.93291739, + 0.93424863, 0.93547974, 0.93658982, 0.93756587, + 0.93894072, 0.93922780, 0.93955477, 0.93991290, + 0.94029104, 0.94067794, 0.94106258, 0.94144084, + 0.94181549, 0.94218963, 0.94256628, 0.94294662, + 0.94332998, 0.94371562, 0.94410280, 0.94449122, + 0.94488106, 0.94527249, 0.94566568, 0.94606074, + 0.94645772, 0.94685665, 0.94725759, 0.94766054, + 0.94806547, 0.94847234, 0.94888115, 0.94929190, + 0.94970469, 0.95011960, 0.95053672, 0.95095604, + 0.95137751, 0.95180105, 0.95222658, 0.95265413, + 0.95308380, 0.95351571, 0.95394994, 0.95438653, + 0.95482538, 0.95526643, 0.95570958, 0.95615486, + 0.95660234, 0.95705214, 0.95750433, 0.95795892, + 0.95841582, 0.95887493, 0.95933616, 0.95979949, + 0.96026500, 0.96073277, 0.96120286, 0.96167526, + 0.96214986, 0.96262655, 0.96310522, 0.96358586, + 0.96406853, 0.96455330, 0.96504026, 0.96552936, + 0.96602051, 0.96651360, 0.96700850, 0.96750520, + 0.96800376, 0.96850424, 0.96900670, 0.96951112, + 0.97001738, 0.97052533, 0.97103488, 0.97154597, + 0.97205867, 0.97257304, 0.97308915, 0.97360694, + 0.97412631, 0.97464711, 0.97516923, 0.97569262, + 0.97621735, 0.97674350, 0.97727111, 0.97780016, + 0.97833051, 0.97886205, 0.97939463, 0.97992823, + 0.98046291, 0.98099875, 0.98153580, 0.98207405, + 0.98261337, 0.98315364, 0.98369474, 0.98423664, + 0.98477941, 0.98532311, 0.98586780, 0.98641348, + 0.98696003, 0.98750734, 0.98805530, 0.98860389, + 0.98915320, 0.98970328, 0.99025423, 0.99080602, + 0.99135855, 0.99191171, 0.99246541, 0.99301962, + 0.99357443, 0.99412992, 0.99468617, 0.99524320, + 0.99580092, 0.99635926, 0.99691814, 0.99747748, + 0.99803721, 0.99859725, 0.99915752, 0.99971793, + 1.00028215, 1.00084319, 1.00140472, 1.00196665, + 1.00252889, 1.00309139, 1.00365404, 1.00421679, + 1.00477954, 1.00534221, 1.00590474, 1.00646713, + 1.00702945, 1.00759179, 1.00815424, 1.00871678, + 1.00927930, 1.00984169, 1.01040384, 1.01096575, + 1.01152747, 1.01208910, 1.01265070, 1.01321226, + 1.01377365, 1.01433478, 1.01489551, 1.01545584, + 1.01601582, 1.01657553, 1.01713502, 1.01769427, + 1.01825316, 1.01881154, 1.01936929, 1.01992639, + 1.02048289, 1.02103888, 1.02159441, 1.02214945, + 1.02270387, 1.02325751, 1.02381025, 1.02436204, + 1.02491295, 1.02546304, 1.02601238, 1.02656092, + 1.02710853, 1.02765508, 1.02820041, 1.02874449, + 1.02928737, 1.02982913, 1.03036981, 1.03090937, + 1.03144768, 1.03198460, 1.03252000, 1.03305384, + 1.03358617, 1.03411707, 1.03464659, 1.03517470, + 1.03570128, 1.03622620, 1.03674934, 1.03727066, + 1.03779024, 1.03830815, 1.03882446, 1.03933914, + 1.03985206, 1.04036312, 1.04087217, 1.04137920, + 1.04188428, 1.04238748, 1.04288888, 1.04338845, + 1.04388610, 1.04438170, 1.04487515, 1.04536645, + 1.04585569, 1.04634297, 1.04682838, 1.04731192, + 1.04779350, 1.04827303, 1.04875042, 1.04922568, + 1.04969891, 1.05017022, 1.05063974, 1.05110746, + 1.05157332, 1.05203721, 1.05249907, 1.05295889, + 1.05341676, 1.05387277, 1.05432700, 1.05477948, + 1.05523018, 1.05567906, 1.05612608, 1.05657124, + 1.05701459, 1.05745616, 1.05789601, 1.05833426, + 1.05877109, 1.05920669, 1.05964125, 1.06007444, + 1.06050542, 1.06093335, 1.06135746, 1.06177909, + 1.06220164, 1.06262858, 1.06306309, 1.06350050, + 1.06392837, 1.06433391, 1.06470443, 1.06502996, + 1.06481076, 1.06469765, 1.06445004, 1.06408002, + 1.06361382, 1.06307719, 1.06249453, 1.06188365, + 1.06125612, 1.06062291, 1.05999418, 1.05937132, + 1.05874726, 1.05811486, 1.05746728, 1.05680000, + 1.05611070, 1.05539715, 1.05465735, 1.05389329, + 1.05311083, 1.05231578, 1.05151372, 1.05070811, + 1.04990044, 1.04909210, 1.04828434, 1.04747647, + 1.04666590, 1.04585003, 1.04502628, 1.04419009, + 1.04333499, 1.04245452, 1.04154244, 1.04059452, + 1.03960846, 1.03858207, 1.03751326, 1.03640189, + 1.03524976, 1.03405868, 1.03283047, 1.03156812, + 1.03027574, 1.02895743, 1.02761717, 1.02625804, + 1.02488222, 1.02349184, 1.02208892, 1.02067450, + 1.01924861, 1.01781123, 1.01636229, 1.01490045, + 1.01342315, 1.01192778, 1.01041175, 1.00887284, + 1.00730915, 1.00571882, 1.00409996, 1.00245032, + 1.00076734, 0.99904842, 0.99729101, 0.99549380, + 0.99365664, 0.99177946, 0.98986234, 0.98791024, + 0.98593294, 0.98394037, 0.98194226, 0.97994532, + 0.97795324, 0.97596955, 0.97399748, 0.97203326, + 0.97006624, 0.96808546, 0.96608018, 0.96404416, + 0.96197556, 0.95987276, 0.95773420, 0.95556018, + 0.95335291, 0.95111462, 0.94884764, 0.94655663, + 0.94424858, 0.94193055, 0.93960953, 0.93729154, + 0.93498157, 0.93268456, 0.93040503, 0.92813771, + 0.92586755, 0.92357910, 0.92125731, 0.91889642, + 0.91649998, 0.91407191, 0.91161623, 0.90913975, + 0.90665202, 0.90416271, 0.90168115, 0.89920934, + 0.89674189, 0.89427312, 0.89179743, 0.88931147, + 0.88681415, 0.88430445, 0.88178141, 0.87924528, + 0.87669753, 0.87413966, 0.87157318, 0.86899958, + 0.86642037, 0.86383703, 0.86125106, 0.85866393, + 0.85604236, 0.85344385, 0.85083093, 0.84820550, + 0.84556943, 0.84292458, 0.84027278, 0.83761586, + 0.83495565, 0.83229393, 0.82963243, 0.82697135, + 0.82430933, 0.82164496, 0.81897669, 0.81630017, + 0.81360822, 0.81089355, 0.80814924, 0.80537741, + 0.80258920, 0.79979611, 0.79700954, 0.79423813, + 0.79148780, 0.78876432, 0.78607290, 0.78340590, + 0.78074288, 0.77806279, 0.77534514, 0.77258187, + 0.76977737, 0.76693654, 0.76406441, 0.76116851, + 0.75825892, 0.75534582, 0.75243924, 0.74954634, + 0.74667135, 0.74381840, 0.74099145, 0.73819147, + 0.73541641, 0.73266408, 0.72993193, 0.72720913, + 0.72447661, 0.72171494, 0.71890515, 0.71603932, + 0.71312056, 0.71015250, 0.70713900, 0.70409084, + 0.70102565, 0.69796137, 0.69491556, 0.69189772, + 0.68890931, 0.68595141, 0.68302498, 0.68012852, + 0.67725801, 0.67440936, 0.67157841, 0.66876081, + 0.66595195, 0.66314722, 0.66034194, 0.65753027, + 0.65470525, 0.65185984, 0.64898709, 0.64608214, + 0.64314221, 0.64016460, 0.63714680, 0.63409034, + 0.63100082, 0.62788400, 0.62474577, 0.62159473, + 0.61844225, 0.61529977, 0.61217866, 0.60908811, + 0.60603510, 0.60302654, 0.60006916, 0.59716588, + 0.59431580, 0.59151787, 0.58877068, 0.58606495, + 0.58338353, 0.58070891, 0.57802356, 0.57530864, + 0.57254404, 0.56970958, 0.56678577, 0.56376860, + 0.56066951, 0.55750064, 0.55427451, 0.55101301, + 0.54774732, 0.54450907, 0.54132936, 0.53822744, + 0.53521072, 0.53228613, 0.52945979, 0.52671997, + 0.52403708, 0.52138072, 0.51872085, 0.51603570, + 0.51331170, 0.51053560, 0.50769466, 0.50478931, + 0.50183308, 0.49884001, 0.49582406, 0.49279905, + 0.48985748, 0.48679641, 0.48379429, 0.48085363, + 0.47796576, 0.47512151, 0.47231151, 0.46952402, + 0.46674486, 0.46395978, 0.46115496, 0.45832607, + 0.45547830, 0.45261727, 0.44974866, 0.44688011, + 0.44402125, 0.44118178, 0.43837094, 0.43558772, + 0.43282082, 0.43005847, 0.42728913, 0.42450572, + 0.42170567, 0.41888658, 0.41604633, 0.41318897, + 0.41032472, 0.40746405, 0.40461724, 0.40178943, + 0.39898066, 0.39619073, 0.39341940, 0.39066519, + 0.38792536, 0.38519713, 0.38247773, 0.37976476, + 0.37705620, 0.37435006, 0.37164438, 0.36893869, + 0.36623396, 0.36353124, 0.36083153, 0.35813533, + 0.35544262, 0.35275338, 0.35006755, 0.34738530, + 0.34470699, 0.34203296, 0.33936359, 0.33669922, + 0.33404027, 0.33138711, 0.32874013, 0.32609944, + 0.32346493, 0.32083645, 0.31821388, 0.31559703, + 0.31298573, 0.31037987, 0.30777941, 0.30518446, + 0.30259525, 0.30001202, 0.29743499, 0.29486428, + 0.29229989, 0.28974179, 0.28718997, 0.28464452, + 0.28210562, 0.27957346, 0.27704820, 0.27452992, + 0.27201854, 0.26951399, 0.26701622, 0.26452533, + 0.26204158, 0.25956526, 0.25709662, 0.25463583, + 0.25218294, 0.24973798, 0.24730100, 0.24487207, + 0.24245133, 0.24003893, 0.23763500, 0.23523959, + 0.23285262, 0.23047401, 0.22810369, 0.22574170, + 0.22338818, 0.22104329, 0.21870719, 0.21637986, + 0.21406117, 0.21175095, 0.20944904, 0.20715535, + 0.20486987, 0.20259261, 0.20032356, 0.19806259, + 0.19580944, 0.19356385, 0.19132556, 0.18909442, + 0.18687040, 0.18465350, 0.18244372, 0.18024164, + 0.17804841, 0.17586521, 0.17369322, 0.17153360, + 0.16938755, 0.16725622, 0.16514081, 0.16304247, + 0.16098974, 0.15896561, 0.15696026, 0.15497259, + 0.15300151, 0.15104590, 0.14910466, 0.14717666, + 0.14526081, 0.14335599, 0.14146111, 0.13957570, + 0.13769993, 0.13583399, 0.13397806, 0.13213229, + 0.13029682, 0.12847178, 0.12665729, 0.12485353, + 0.12306074, 0.12127916, 0.11950900, 0.11775043, + 0.11600347, 0.11426820, 0.11254464, 0.11083292, + 0.10913318, 0.10744559, 0.10577028, 0.10410733, + 0.10245672, 0.10081842, 0.09919240, 0.09757872, + 0.09597750, 0.09438884, 0.09281288, 0.09124964, + 0.08969907, 0.08816111, 0.08663570, 0.08512288, + 0.08362274, 0.08213540, 0.08066096, 0.07919944, + 0.07775076, 0.07631484, 0.07489161, 0.07348108, + 0.07208335, 0.07069851, 0.06932666, 0.06796781, + 0.06662187, 0.06528874, 0.06396833, 0.06266065, + 0.06136578, 0.06008380, 0.05881480, 0.05755876, + 0.05631557, 0.05508511, 0.05386728, 0.05266206, + 0.05146951, 0.05028971, 0.04912272, 0.04796855, + 0.04682709, 0.04569825, 0.04458194, 0.04347817, + 0.04238704, 0.04130868, 0.04024318, 0.03919056, + 0.03815071, 0.03712352, 0.03610890, 0.03510679, + 0.03411720, 0.03314013, 0.03217560, 0.03122343, + 0.03028332, 0.02935494, 0.02843799, 0.02753230, + 0.02663788, 0.02575472, 0.02488283, 0.02402232, + 0.02317341, 0.02233631, 0.02151124, 0.02069866, + 0.01989922, 0.01911359, 0.01834241, 0.01758563, + 0.01684248, 0.01611219, 0.01539397, 0.01468726, + 0.01399167, 0.01330687, 0.01263250, 0.01196871, + 0.01131609, 0.01067527, 0.01004684, 0.00943077, + 0.00882641, 0.00823307, 0.00765011, 0.00707735, + 0.00651513, 0.00596377, 0.00542364, 0.00489514, + 0.00437884, 0.00387530, 0.00338509, 0.00290795, + 0.00244282, 0.00198860, 0.00154417, 0.00110825, + 0.00067934, 0.00025589, -0.00016357, -0.00057897, + -0.00098865, -0.00139089, -0.00178397, -0.00216547, + -0.00253230, -0.00288133, -0.00320955, -0.00351626, + -0.00380315, -0.00407198, -0.00432457, -0.00456373, + -0.00479326, -0.00501699, -0.00523871, -0.00546066, + -0.00568360, -0.00590821, -0.00613508, -0.00636311, + -0.00658944, -0.00681117, -0.00702540, -0.00722982, + -0.00742268, -0.00760226, -0.00776687, -0.00791580, + -0.00804933, -0.00816774, -0.00827139, -0.00836122, + -0.00843882, -0.00850583, -0.00856383, -0.00861430, + -0.00865853, -0.00869781, -0.00873344, -0.00876633, + -0.00879707, -0.00882622, -0.00885433, -0.00888132, + -0.00890652, -0.00892925, -0.00894881, -0.00896446, + -0.00897541, -0.00898088, -0.00898010, -0.00897234, + -0.00895696, -0.00893330, -0.00890076, -0.00885914, + -0.00880875, -0.00874987, -0.00868282, -0.00860825, + -0.00852716, -0.00844055, -0.00834941, -0.00825485, + -0.00815807, -0.00806025, -0.00796253, -0.00786519, + -0.00776767, -0.00766937, -0.00756971, -0.00746790, + -0.00736305, -0.00725422, -0.00714055, -0.00702161, + -0.00689746, -0.00676816, -0.00663381, -0.00649489, + -0.00635230, -0.00620694, -0.00605969, -0.00591116, + -0.00576167, -0.00561155, -0.00546110, -0.00531037, + -0.00515917, -0.00500732, -0.00485462, -0.00470075, + -0.00454530, -0.00438786, -0.00422805, -0.00406594, + -0.00390204, -0.00373686, -0.00357091, -0.00340448, + -0.00323770, -0.00307066, -0.00290344, -0.00273610, + -0.00256867, -0.00240117, -0.00223365, -0.00206614, + -0.00189866, -0.00173123, -0.00156390, -0.00139674, + -0.00122989, -0.00106351, -0.00089772, -0.00073267, + -0.00056849, -0.00040530, -0.00024324, -0.00008241, + 0.00008214, 0.00024102, 0.00039922, 0.00055660, + 0.00071299, 0.00086826, 0.00102224, 0.00117480, + 0.00132579, 0.00147507, 0.00162252, 0.00176804, + 0.00191161, 0.00205319, 0.00219277, 0.00233029, + 0.00246567, 0.00259886, 0.00272975, 0.00285832, + 0.00298453, 0.00310839, 0.00322990, 0.00334886, + 0.00346494, 0.00357778, 0.00368706, 0.00379273, + 0.00389501, 0.00399411, 0.00409020, 0.00418350, + 0.00427419, 0.00436249, 0.00444858, 0.00453250, + 0.00461411, 0.00469328, 0.00476988, 0.00484356, + 0.00491375, 0.00497987, 0.00504139, 0.00509806, + 0.00514990, 0.00519693, 0.00523920, 0.00527700, + 0.00531083, 0.00534122, 0.00536864, 0.00539357, + 0.00541649, 0.00543785, 0.00545809, 0.00547713, + 0.00549441, 0.00550936, 0.00552146, 0.00553017, + 0.00553494, 0.00553524, 0.00553058, 0.00552065, + 0.00550536, 0.00548459, 0.00545828, 0.00542662, + 0.00539007, 0.00534910, 0.00530415, 0.00525568, + 0.00520417, 0.00515009, 0.00509387, 0.00503595, + 0.00497674, 0.00491665, 0.00485605, 0.00479503, + 0.00473336, 0.00467082, 0.00460721, 0.00454216, + 0.00447517, 0.00440575, 0.00433344, 0.00425768, + 0.00417786, 0.00409336, 0.00400363, 0.00390837, + 0.00380759, 0.00370130, 0.00358952, 0.00347268, + 0.00335157, 0.00322699, 0.00309975, 0.00297088, + 0.00284164, 0.00271328, 0.00258700, 0.00246328, + 0.00234195, 0.00222281, 0.00210562, 0.00198958, + 0.00187331, 0.00175546, 0.00163474, 0.00151020, + 0.00138130, 0.00124750, 0.00110831, 0.00096411, + 0.00081611, 0.00066554, 0.00051363, 0.00036134, + 0.00020940, 0.00005853, -0.00009058, -0.00023783, + -0.00038368, -0.00052861, -0.00067310, -0.00081757, + -0.00096237, -0.00110786, -0.00125442, -0.00140210, + -0.00155065, -0.00169984, -0.00184940, -0.00199910, + -0.00214872, -0.00229798, -0.00244664, -0.00259462, + -0.00274205, -0.00288912, -0.00303596, -0.00318259, + -0.00332890, -0.00347480, -0.00362024, -0.00376519, + -0.00390962, -0.00405345, -0.00419658, -0.00433902, + -0.00448085, -0.00462219, -0.00476309, -0.00490357, + -0.00504361, -0.00518321, -0.00532243, -0.00546132, + -0.00559988, -0.00573811, -0.00587602, -0.00601363, + -0.00615094, -0.00628795, -0.00642466, -0.00656111, + -0.00669737, -0.00683352, -0.00696963, -0.00710578, + -0.00724208, -0.00737862, -0.00751554, -0.00765295, + -0.00779098, -0.00792976, -0.00806941, -0.00821006, + -0.00835183, -0.00849485, -0.00863926, -0.00878522, + -0.00893293, -0.00908260, -0.00923444, -0.00938864, + -0.00954537, -0.00970482, -0.00986715, -0.01003173, + -0.01019711, -0.01036164, -0.01052357, -0.01068184, + -0.01083622, -0.01098652, -0.01113252, -0.01127409, + -0.01141114, -0.01154358, -0.01167135, -0.01179439, + -0.01191268, -0.01202619, -0.01213493, -0.01223891, + -0.01233817, -0.01243275, -0.01252272, -0.01260815, + -0.01268915, -0.01276583, -0.01283832, -0.01290685, + -0.01297171, -0.01303320, -0.01309168, -0.01314722, + -0.01319969, -0.01324889, -0.01329466, -0.01333693, + -0.01337577, -0.01341125, -0.01344345, -0.01347243, + -0.01349823, -0.01352089, -0.01354045, -0.01355700, + -0.01357068, -0.01358164, -0.01359003, -0.01359587, + -0.01359901, -0.01359931, -0.01359661, -0.01359087, + -0.01358219, -0.01357065, -0.01355637, -0.01353935, + -0.01351949, -0.01349670, -0.01347088, -0.01344214, + -0.01341078, -0.01337715, -0.01334158, -0.01330442, + -0.01326601, -0.01322671, -0.01318689, -0.01314692, + -0.01310123, -0.01306470, -0.01302556, -0.01298381, + -0.01293948, -0.01289255, -0.01284305, -0.01279095, + -0.01273625, -0.01267893, -0.01261897, -0.01255632, + -0.01249096, -0.01242283, -0.01235190, -0.01227827, + -0.01220213, -0.01212366, -0.01204304, -0.01196032, + -0.01187543, -0.01178829, -0.01169884, -0.01160718, + -0.01151352, -0.01141809, -0.01132111, -0.01122272, + -0.01112304, -0.01102217, -0.01092022, -0.01081730, + -0.01071355, -0.01060912, -0.01050411, -0.01039854, + -0.01029227, -0.01018521, -0.01007727, -0.00996859, + -0.00985959, -0.00975063, -0.00964208, -0.00953420, + -0.00942723, -0.00932135, -0.00921677, -0.00911364, + -0.00901208, -0.00891220, -0.00881412, -0.00871792, + -0.00862369, -0.00853153, -0.00844149, -0.00835360, + -0.00826785, -0.00818422, -0.00810267, -0.00802312, + -0.00794547, -0.00786959, -0.00779533, -0.00772165, + -0.00764673, -0.00756886, -0.00748649, -0.00739905, + -0.00730681, -0.00721006, -0.00710910, -0.00700419, + -0.00689559, -0.00678354, -0.00666829, -0.00655007, + -0.00642916, -0.00630579, -0.00618022, -0.00605267, + -0.00592333, -0.00579240, -0.00566006, -0.00552651, + -0.00539194, -0.00525653, -0.00512047, -0.00498390, + -0.00484693, -0.00470969, -0.00457228, -0.00443482, + -0.00429746, -0.00416034, -0.00402359, -0.00388738, + -0.00375185, -0.00361718, -0.00348350, -0.00335100, + -0.00321991, -0.00309043, -0.00296276, -0.00283698, + -0.00271307, -0.00259098, -0.00247066, -0.00235210, + -0.00223531, -0.00212030, -0.00200709, -0.00189576, + -0.00178647, -0.00167936, -0.00157457, -0.00147216, + -0.00137205, -0.00127418, -0.00117849, -0.00108498, + -0.00099375, -0.00090486, -0.00081840, -0.00073444, + -0.00065309, -0.00057445, -0.00049860, -0.00042551, + -0.00035503, -0.00028700, -0.00022125, -0.00015761, + -0.00009588, -0.00003583, 0.00002272, 0.00007975, + 0.00013501, 0.00018828, 0.00023933, 0.00028784, + 0.00033342, 0.00037572, 0.00041438, 0.00044939, + 0.00048103, 0.00050958, 0.00053533, 0.00055869, + 0.00058015, 0.00060022, 0.00061935, 0.00063781, + 0.00065568, 0.00067303, 0.00068991, 0.00070619, + 0.00072155, 0.00073567, 0.00074826, 0.00075912, + 0.00076811, 0.00077509, 0.00077997, 0.00078275, + 0.00078351, 0.00078237, 0.00077943, 0.00077484, + 0.00076884, 0.00076160, 0.00075335, 0.00074423, + 0.00073442, 0.00072404, 0.00071323, 0.00070209, + 0.00069068, 0.00067906, 0.00066728, 0.00065534, + 0.00064321, 0.00063086, 0.00061824, 0.00060534, + 0.00059211, 0.00057855, 0.00056462, 0.00055033, + 0.00053566, 0.00052063, 0.00050522, 0.00048949, + 0.00047349, 0.00045728, 0.00044092, 0.00042447, + 0.00040803, 0.00039166, 0.00037544, 0.00035943, + 0.00034371, 0.00032833, 0.00031333, 0.00029874, + 0.00028452, 0.00027067, 0.00025715, 0.00024395, + 0.00023104, 0.00021842, 0.00020606, 0.00019398, + 0.00018218, 0.00017069, 0.00015953, 0.00014871, + 0.00013827, 0.00012823, 0.00011861, 0.00010942, + 0.00010067, 0.00009236, 0.00008448, 0.00007703, + 0.00006999, 0.00006337, 0.00005714, 0.00005129, + 0.00004583, 0.00004072, 0.00003597, 0.00003157, + 0.00002752, 0.00002380, 0.00002042, 0.00001736, + 0.00001461, 0.00001215, 0.00000998, 0.00000807, + 0.00000641, 0.00000499, 0.00000378, 0.00000278, + 0.00000196, 0.00000132, 0.00000082, 0.00000046, + 0.00000020, 0.00000005, -0.00000003, -0.00000006, + -0.00000004, -0.00000001, 0.00000001, 0.00000001, + 0.00000001, 0.00000001, -0.00000001, -0.00000004, + -0.00000005, -0.00000003, 0.00000005, 0.00000020, + 0.00000043, 0.00000077, 0.00000123, 0.00000183, + 0.00000257, 0.00000348, 0.00000455, 0.00000581, + 0.00000727, 0.00000893, 0.00001080, 0.00001290, + 0.00001522, 0.00001778, 0.00002057, 0.00002362, + 0.00002691, 0.00003044, 0.00003422, 0.00003824, + 0.00004250, 0.00004701, 0.00005176, 0.00005676, + 0.00006200, 0.00006749, 0.00007322, 0.00007920, + 0.00008541, 0.00009186, 0.00009854, 0.00010543, + 0.00011251, 0.00011975, 0.00012714, 0.00013465, + 0.00014227, 0.00014997, 0.00015775, 0.00016558, + 0.00017348, 0.00018144, 0.00018947, 0.00019756, + 0.00020573, 0.00021399, 0.00022233, 0.00023076, + 0.00023924, 0.00024773, 0.00025621, 0.00026462, + 0.00027293, 0.00028108, 0.00028904, 0.00029675, + 0.00030419, 0.00031132, 0.00031810, 0.00032453, + 0.00033061, 0.00033632, 0.00034169, 0.00034672, + 0.00035142, 0.00035580, 0.00035988, 0.00036369, + 0.00036723, 0.00037053, 0.00037361, 0.00037647, + 0.00037909, 0.00038145, 0.00038352, 0.00038527, + 0.00038663, 0.00038757, 0.00038801, 0.00038790, + 0.00038717, 0.00038572, 0.00038350, 0.00038044, + 0.00037651, 0.00037170, 0.00036597, 0.00035936, + 0.00035191, 0.00034370, 0.00033480, 0.00032531, + 0.00031537, 0.00030512, 0.00029470, 0.00028417, + 0.00027354, 0.00026279, 0.00025191, 0.00024081, + 0.00022933, 0.00021731, 0.00020458, 0.00019101, + 0.00017654, 0.00016106, 0.00014452, 0.00012694, + 0.00010848, 0.00008929, 0.00006953, 0.00004935, + 0.00002884, 0.00000813, -0.00001268, -0.00003357, + -0.00005457, -0.00007574, -0.00009714, -0.00011882, + -0.00014082, -0.00016318, -0.00018595, -0.00020912, + -0.00023265, -0.00025650, -0.00028060, -0.00030492, + -0.00032941, -0.00035400, -0.00037865, -0.00040333, + -0.00042804, -0.00045279, -0.00047759, -0.00050243, + -0.00052728, -0.00055209, -0.00057685, -0.00060153, + -0.00062611, -0.00065056, -0.00067485, -0.00069895, + -0.00072287, -0.00074660, -0.00077013, -0.00079345, + -0.00081653, -0.00083936, -0.00086192, -0.00088421, + -0.00090619, -0.00092786, -0.00094919, -0.00097017, + -0.00099077, -0.00101098, -0.00103077, -0.00105012, + -0.00106904, -0.00108750, -0.00110549, -0.00112301, + -0.00114005, -0.00115660, -0.00117265, -0.00118821, + -0.00120325, -0.00121779, -0.00123180, -0.00124528, + -0.00125822, -0.00127061, -0.00128243, -0.00129368, + -0.00130435, -0.00131445, -0.00132395, -0.00133285, + -0.00134113, -0.00134878, -0.00135577, -0.00136215, + -0.00136797, -0.00137333, -0.00137834, -0.00138305, + -0.00138748, -0.00139163, -0.00139551, -0.00139913, + -0.00140249, -0.00140559, -0.00140844, -0.00141102, + -0.00141334, -0.00141538, -0.00141714, -0.00141861, + -0.00141978, -0.00142064, -0.00142117, -0.00142138, + -0.00142125, -0.00142077, -0.00141992, -0.00141870, + -0.00141710, -0.00141510, -0.00141268, -0.00140986, + -0.00140663, -0.00140301, -0.00139900, -0.00139460, + -0.00138981, -0.00138464, -0.00137908, -0.00137313, + -0.00136680, -0.00136010, -0.00135301, -0.00134555, + -0.00133772, -0.00132952, -0.00132095, -0.00131201, + -0.00130272, -0.00129307, -0.00128309, -0.00127277, + -0.00126211, -0.00125113, -0.00123981, -0.00122817, + -0.00121622, -0.00120397, -0.00119141, -0.00117859, + -0.00116552, -0.00115223, -0.00113877, -0.00112517, + -0.00111144, -0.00109764, -0.00108377, -0.00106989, +}; + +/* Q30 representation of ff_aac_eld_window_512 table */ +const DECLARE_ALIGNED(32, int, ff_aac_eld_window_512_fixed)[1920] = { + 0x003783ba, 0x005d04f4, 0x008ae226, 0x00c02021, + 0x00fb1804, 0x013a30a8, 0x017be9e6, 0x01bf296c, + 0x02033204, 0x0247502c, 0x028adab0, 0x02cd9568, + 0x030fa980, 0x03513dc0, 0x03927274, 0x03d363e0, + 0x04142e40, 0x0454edc0, 0x0495bd48, 0x04d6a060, + 0x051786d8, 0x05586548, 0x059935e8, 0x05d9feb0, + 0x061acea0, 0x065bb680, 0x069cc800, 0x06de13f0, + 0x071fa748, 0x07618b80, 0x07a3c7a8, 0x07e66da0, + 0x082999d0, 0x086d6590, 0x08b1e640, 0x08f72850, + 0x093d3120, 0x09840550, 0x09cba880, 0x0a1415f0, + 0x0a5d41b0, 0x0aa720d0, 0x0af1a9a0, 0x0b3cce70, + 0x0b887ec0, 0x0bd4ac10, 0x0c214a70, 0x0c6e5130, + 0x0cbbba50, 0x0d098130, 0x0d57a240, 0x0da61a60, + 0x0df4e620, 0x0e4401d0, 0x0e9369f0, 0x0ee31de0, + 0x0f332000, 0x0f837180, 0x0fd412a0, 0x10250260, + 0x10763f20, 0x10c7c660, 0x11199560, 0x116baa00, + 0x11be0400, 0x1210a1c0, 0x12638180, 0x12b69ee0, + 0x1309f3e0, 0x135d7ac0, 0x13b12dc0, 0x1404ffa0, + 0x1458dd40, 0x14acb720, 0x15008120, 0x15543260, + 0x15a7c460, 0x15fb3160, 0x164e7520, 0x16a193c0, + 0x16f49740, 0x17478720, 0x179a6720, 0x17ed3720, + 0x183ff460, 0x18929c20, 0x18e52b00, 0x19379c00, + 0x1989e900, 0x19dc0ca0, 0x1a2e0280, 0x1a7fc400, + 0x1ad14a00, 0x1b228ec0, 0x1b738ea0, 0x1bc44540, + 0x1c14ada0, 0x1c64c380, 0x1cb48440, 0x1d03f420, + 0x1d531c00, 0x1da20160, 0x1df0a660, 0x1e3f0860, + 0x1e8d2340, 0x1edaf340, 0x1f2875e0, 0x1f75a700, + 0x1fc281e0, 0x200f0380, 0x205b2ac0, 0x20a6f980, + 0x20f27200, 0x213d9600, 0x21886580, 0x21d2e040, + 0x221d0640, 0x2266d6c0, 0x22b05180, 0x22f97580, + 0x23424280, 0x238ab880, 0x23d2d780, 0x241aa040, + 0x246213c0, 0x24a93300, 0x24efff80, 0x25367b40, + 0x256f68c0, 0x25b53580, 0x25faa580, 0x263fb940, + 0x26847080, 0x26c8cbc0, 0x270ccb00, 0x27506e40, + 0x2793b600, 0x27d6a200, 0x281932c0, 0x285b6880, + 0x289d4400, 0x28dec5c0, 0x291feec0, 0x2960bf80, + 0x29a137c0, 0x29e15800, 0x2a212000, 0x2a609080, + 0x2a9fa980, 0x2ade6b40, 0x2b1cd600, 0x2b5aea00, + 0x2b98a740, 0x2bd60d80, 0x2c131cc0, 0x2c4fd500, + 0x2c8c3600, 0x2cc83f00, 0x2d03f040, 0x2d3f48c0, + 0x2d7a48c0, 0x2db4ef40, 0x2def3c40, 0x2e292ec0, + 0x2e62c700, 0x2e9c0400, 0x2ed4e580, 0x2f0d6ac0, + 0x2f4592c0, 0x2f7d5c80, 0x2fb4c6c0, 0x2febd140, + 0x30227b40, 0x3058c400, 0x308eab40, 0x30c43040, + 0x30f95100, 0x312e0d00, 0x31626240, 0x31965040, + 0x31c9d5c0, 0x31fcf240, 0x322fa480, 0x3261ec00, + 0x3293c7c0, 0x32c53680, 0x32f63780, 0x3326c9c0, + 0x3356ec00, 0x33869d00, 0x33b5db80, 0x33e4a700, + 0x3412fdc0, 0x3440df40, 0x346e4a80, 0x349b3e40, + 0x34c7ba00, 0x34f3bd80, 0x351f47c0, 0x354a5840, + 0x3574ee40, 0x359f0900, 0x35c8a840, 0x35f1cb80, + 0x361a71c0, 0x36429a80, 0x366a4580, 0x36917280, + 0x36b82100, 0x36de5180, 0x37040340, 0x372936c0, + 0x374dec40, 0x37722340, 0x3795dc40, 0x37b91780, + 0x37dbd600, 0x37fe18c0, 0x381fe080, 0x38412e00, + 0x38620280, 0x38825f40, 0x38a24540, 0x38c1b680, + 0x38e0b5c0, 0x38ff4540, 0x391d6800, 0x393b20c0, + 0x39587280, 0x39755fc0, 0x3991eb80, 0x39ae1a80, + 0x39c9f280, 0x39e57980, 0x3a00b600, 0x3a1bae00, + 0x3a366800, 0x3a50e9c0, 0x3a6b3a40, 0x3a8560c0, + 0x3a9f6640, 0x3ab95400, 0x3ad332c0, 0x3aed0680, + 0x3b06cf80, 0x3b208d40, 0x3b3a3e80, 0x3b53cb80, + 0x3b6d0780, 0x3b85c380, 0x3b9dd0c0, 0x3bb4eb40, + 0x3bcabac0, 0x3bdee680, 0x3bf11680, 0x3c011440, + 0x3c179ac0, 0x3c1c4f00, 0x3c21aa40, 0x3c278880, + 0x3c2dba80, 0x3c341140, 0x3c3a5e80, 0x3c409100, + 0x3c46b480, 0x3c4cd5c0, 0x3c530180, 0x3c593cc0, + 0x3c5f84c0, 0x3c65d640, 0x3c6c2e40, 0x3c728b40, + 0x3c78ee80, 0x3c7f5840, 0x3c85c940, 0x3c8c4240, + 0x3c92c380, 0x3c994cc0, 0x3c9fde40, 0x3ca67880, + 0x3cad1ac0, 0x3cb3c540, 0x3cba7800, 0x3cc132c0, + 0x3cc7f640, 0x3ccec280, 0x3cd59800, 0x3cdc76c0, + 0x3ce35e80, 0x3cea4f00, 0x3cf147c0, 0x3cf84900, + 0x3cff5340, 0x3d0666c0, 0x3d0d8400, 0x3d14ab40, + 0x3d1bdc00, 0x3d2315c0, 0x3d2a5880, 0x3d31a440, + 0x3d38f900, 0x3d405780, 0x3d47c040, 0x3d4f3300, + 0x3d56af40, 0x3d5e3500, 0x3d65c380, 0x3d6d5ac0, + 0x3d74fb40, 0x3d7ca540, 0x3d845900, 0x3d8c1680, + 0x3d93dd00, 0x3d9bac80, 0x3da38400, 0x3dab6400, + 0x3db34c80, 0x3dbb3dc0, 0x3dc33840, 0x3dcb3bc0, + 0x3dd347c0, 0x3ddb5bc0, 0x3de37780, 0x3deb9b00, + 0x3df3c600, 0x3dfbf940, 0x3e0434c0, 0x3e0c7840, + 0x3e14c3c0, 0x3e1d1640, 0x3e256f80, 0x3e2dcf40, + 0x3e363580, 0x3e3ea300, 0x3e4717c0, 0x3e4f9380, + 0x3e581600, 0x3e609e40, 0x3e692c40, 0x3e71bf80, + 0x3e7a5840, 0x3e82f740, 0x3e8b9c40, 0x3e944700, + 0x3e9cf780, 0x3ea5ad00, 0x3eae66c0, 0x3eb72500, + 0x3ebfe780, 0x3ec8af00, 0x3ed17b80, 0x3eda4d00, + 0x3ee32340, 0x3eebfd40, 0x3ef4dac0, 0x3efdbbc0, + 0x3f06a040, 0x3f0f88c0, 0x3f187540, 0x3f216600, + 0x3f2a5a80, 0x3f335200, 0x3f3c4c40, 0x3f454940, + 0x3f4e4940, 0x3f574c80, 0x3f605340, 0x3f695dc0, + 0x3f726b40, 0x3f7b7b40, 0x3f848dc0, 0x3f8da240, + 0x3f96b940, 0x3f9fd300, 0x3fa8f040, 0x3fb21080, + 0x3fbb33c0, 0x3fc459c0, 0x3fcd81c0, 0x3fd6abc0, + 0x3fdfd780, 0x3fe90480, 0x3ff23280, 0x3ffb6100, + 0x40049f80, 0x400dd080, 0x40170400, 0x40203880, + 0x40296f00, 0x4032a600, 0x403bde00, 0x40451680, + 0x404e4f00, 0x40578700, 0x4060be80, 0x4069f500, + 0x40732b80, 0x407c6280, 0x40859980, 0x408ed100, + 0x40980800, 0x40a13f00, 0x40aa7500, 0x40b3a980, + 0x40bcdd80, 0x40c61180, 0x40cf4500, 0x40d87800, + 0x40e1ab00, 0x40eadc80, 0x40f40c80, 0x40fd3a80, + 0x41066700, 0x410f9300, 0x4118bd80, 0x4121e700, + 0x412b0f80, 0x41343580, 0x413d5880, 0x41467980, + 0x414f9780, 0x4158b380, 0x4161cd80, 0x416ae580, + 0x4173fb00, 0x417d0d00, 0x41861b80, 0x418f2600, + 0x41982c80, 0x41a12f80, 0x41aa3000, 0x41b32c80, + 0x41bc2580, 0x41c51a00, 0x41ce0900, 0x41d6f300, + 0x41dfd800, 0x41e8b880, 0x41f19400, 0x41fa6b80, + 0x42033d00, 0x420c0900, 0x4214cf00, 0x421d8e00, + 0x42264680, 0x422ef980, 0x4237a680, 0x42404d80, + 0x4248ee00, 0x42518780, 0x425a1a00, 0x4262a480, + 0x426b2800, 0x4273a400, 0x427c1980, 0x42848880, + 0x428cef80, 0x42954f00, 0x429da680, 0x42a5f500, + 0x42ae3b80, 0x42b67a00, 0x42beb100, 0x42c6e080, + 0x42cf0780, 0x42d72680, 0x42df3c00, 0x42e74880, + 0x42ef4c80, 0x42f74880, 0x42ff3c80, 0x43072880, + 0x430f0c80, 0x4316e800, 0x431eba00, 0x43268380, + 0x432e4480, 0x4335fd00, 0x433dae80, 0x43455800, + 0x434cfa00, 0x43549400, 0x435c2500, 0x4363ad80, + 0x436b2e00, 0x4372a700, 0x437a1800, 0x43818200, + 0x4388e400, 0x43903f00, 0x43979200, 0x439edd00, + 0x43a62080, 0x43ad5c80, 0x43b49180, 0x43bbbf80, + 0x43c2e800, 0x43ca0b00, 0x43d12980, 0x43d84280, + 0x43df5200, 0x43e65500, 0x43ed4800, 0x43f43080, + 0x43fb1c80, 0x44021b80, 0x44093a00, 0x44106480, + 0x44176700, 0x441e0c00, 0x44241e00, 0x44297380, + 0x4425dc00, 0x44240180, 0x441ff300, 0x4419e300, + 0x44123f80, 0x44097500, 0x43ffe900, 0x43f5e700, + 0x43eb9f00, 0x43e13f00, 0x43d6f200, 0x43ccbd80, + 0x43c28400, 0x43b82780, 0x43ad8b00, 0x43a29c80, + 0x43975180, 0x438ba080, 0x437f8180, 0x4372fd00, + 0x43662b00, 0x43592480, 0x434c0000, 0x433ecd00, + 0x43319180, 0x43245300, 0x43171700, 0x4309da80, + 0x42fc9300, 0x42ef3500, 0x42e1b600, 0x42d40280, + 0x42c60000, 0x42b79300, 0x42a8a180, 0x42991a00, + 0x4288f200, 0x42782100, 0x42669e00, 0x42546880, + 0x42418800, 0x422e0480, 0x4219e500, 0x42053680, + 0x41f00980, 0x41da7080, 0x41c47b00, 0x41ae3600, + 0x4197ab80, 0x4180e400, 0x4169e780, 0x4152bb00, + 0x413b5e80, 0x4123d180, 0x410c1480, 0x40f42100, + 0x40dbed00, 0x40c36c80, 0x40aa9600, 0x40915f80, + 0x4077c100, 0x405db280, 0x40432c80, 0x40282580, + 0x400c9280, 0x3ff068c0, 0x3fd39dc0, 0x3fb62bc0, + 0x3f981200, 0x3f795080, 0x3f59e780, 0x3f39ebc0, + 0x3f198680, 0x3ef8e100, 0x3ed82440, 0x3eb76c80, + 0x3e96c940, 0x3e764900, 0x3e55f980, 0x3e35cb00, + 0x3e1590c0, 0x3df51cc0, 0x3dd44200, 0x3db2e640, + 0x3d910200, 0x3d6e8e40, 0x3d4b8480, 0x3d27e600, + 0x3d03bc00, 0x3cdf0fc0, 0x3cb9eb80, 0x3c946240, + 0x3c6e9180, 0x3c489700, 0x3c229000, 0x3bfc95c0, + 0x3bd6bd00, 0x3bb11a80, 0x3b8bc180, 0x3b669bc0, + 0x3b416a00, 0x3b1beb80, 0x3af5e140, 0x3acf3300, + 0x3aa7ef80, 0x3a802780, 0x3a57eb80, 0x3a2f5880, + 0x3a069640, 0x39ddcd40, 0x39b524c0, 0x398ca540, + 0x39643800, 0x393bc540, 0x39133580, 0x38ea7ac0, + 0x38c19040, 0x389871c0, 0x386f1b40, 0x38458e00, + 0x381bd000, 0x37f1e780, 0x37c7db00, 0x379db080, + 0x37736e80, 0x37491b00, 0x371ebcc0, 0x36f45980, + 0x36c96600, 0x369ed300, 0x36740380, 0x3648ffc0, + 0x361dcf40, 0x35f27a00, 0x35c70780, 0x359b7f80, + 0x356fe9c0, 0x35444dc0, 0x3518b280, 0x34ed1940, + 0x34c17c00, 0x3495d4c0, 0x346a1d40, 0x343e4300, + 0x34122840, 0x33e5ae00, 0x33b8b780, 0x338b4dc0, + 0x335d9f00, 0x332fdc00, 0x33023440, 0x32d4cc40, + 0x32a7bc80, 0x327b1d40, 0x324f04c0, 0x32235280, + 0x31f7b100, 0x31cbc7c0, 0x319f4140, 0x3171fb40, + 0x31440840, 0x31157d00, 0x30e66e80, 0x30b6fc40, + 0x30875080, 0x30579600, 0x3027f700, 0x2ff89140, + 0x2fc976c0, 0x2f9ab880, 0x2f6c6780, 0x2f3e8780, + 0x2f111000, 0x2ee3f800, 0x2eb73480, 0x2e8a9840, + 0x2e5dd340, 0x2e3093c0, 0x2e028ac0, 0x2dd39680, + 0x2da3c480, 0x2d732380, 0x2d41c400, 0x2d0fd300, + 0x2cdd9ac0, 0x2cab6640, 0x2c797f00, 0x2c480d40, + 0x2c171700, 0x2be6a0c0, 0x2bb6ae80, 0x2b8739c0, + 0x2b583200, 0x2b298600, 0x2afb2400, 0x2accfa40, + 0x2a9ef500, 0x2a710100, 0x2a430ac0, 0x2a14f9c0, + 0x29e6b0c0, 0x29b81240, 0x29890140, 0x29596900, + 0x29293e00, 0x28f87500, 0x28c70340, 0x2894efc0, + 0x28625140, 0x282f4040, 0x27fbd5c0, 0x27c83540, + 0x27948ec0, 0x27611240, 0x272def80, 0x26fb4cc0, + 0x26c94780, 0x2697fcc0, 0x26678880, 0x2637f740, + 0x26094540, 0x25db6dc0, 0x25ae6b40, 0x25821680, + 0x255627c0, 0x252a55c0, 0x24fe5680, 0x24d1db40, + 0x24a48fc0, 0x24761f40, 0x244637c0, 0x2414c900, + 0x23e20240, 0x23ae1740, 0x23793bc0, 0x2343cc00, + 0x230e4ac0, 0x22d93c80, 0x22a52400, 0x22725180, + 0x2240e480, 0x2210f9c0, 0x21e2ab40, 0x21b5c7c0, + 0x2189d2c0, 0x215e4d40, 0x2132b900, 0x2106ba80, + 0x20da1940, 0x20ac9d80, 0x207e11c0, 0x204e77c0, + 0x201e0880, 0x1fecfea0, 0x1fbb94e0, 0x1f8a0500, + 0x1f59d340, 0x1f27ac20, 0x1ef67c60, 0x1ec64e40, + 0x1e96fdc0, 0x1e686400, 0x1e3a5a00, 0x1e0cae80, + 0x1ddf25e0, 0x1db18460, 0x1d839020, 0x1d5536e0, + 0x1d268e80, 0x1cf7ae60, 0x1cc8aea0, 0x1c99af00, + 0x1c6ad820, 0x1c3c5280, 0x1c0e4500, 0x1be0ab60, + 0x1bb35620, 0x1b861400, 0x1b58b480, 0x1b2b1a00, + 0x1afd39c0, 0x1acf09a0, 0x1aa080c0, 0x1a71b020, + 0x1a42c2a0, 0x1a13e420, 0x19e53fc0, 0x19b6eb00, + 0x1988e620, 0x195b3060, 0x192dc8a0, 0x1900a8a0, + 0x18d3c4e0, 0x18a711e0, 0x187a83e0, 0x184e10e0, + 0x1821b060, 0x17f55a00, 0x17c90580, 0x179cb100, + 0x177060a0, 0x17441880, 0x1717dd20, 0x16ebb080, + 0x16bf9260, 0x169382e0, 0x166781c0, 0x163b8f80, + 0x160fade0, 0x15e3de40, 0x15b82220, 0x158c7ae0, + 0x1560ea80, 0x15357240, 0x150a1400, 0x14ded020, + 0x14b3a640, 0x148895a0, 0x145d9dc0, 0x1432bde0, + 0x1407f540, 0x13dd4380, 0x13b2a860, 0x13882460, + 0x135db880, 0x133365a0, 0x13092cc0, 0x12df0e60, + 0x12b50aa0, 0x128b2120, 0x12615200, 0x12379da0, + 0x120e04c0, 0x11e48820, 0x11bb2860, 0x1191e600, + 0x1168c080, 0x113fb7a0, 0x1116cb40, 0x10edfba0, + 0x10c54a00, 0x109cb7a0, 0x10744560, 0x104bf420, + 0x1023c3e0, 0x0ffbb500, 0x0fd3c790, 0x0fabfbe0, + 0x0f845290, 0x0f5ccc40, 0x0f356970, 0x0f0e2a60, + 0x0ee70eb0, 0x0ec01610, 0x0e994040, 0x0e728d50, + 0x0e4bfdf0, 0x0e2592c0, 0x0dff4c70, 0x0dd92af0, + 0x0db32da0, 0x0d8d53e0, 0x0d679cf0, 0x0d420880, + 0x0d1c9680, 0x0cf74700, 0x0cd219f0, 0x0cad0eb0, + 0x0c882450, 0x0c6359a0, 0x0c3ead90, 0x0c1a1f80, + 0x0bf5af40, 0x0bd15cf0, 0x0bad2870, 0x0b891440, + 0x0b652530, 0x0b416020, 0x0b1dca30, 0x0afa6810, + 0x0ad73ee0, 0x0ab45370, 0x0a91aac0, 0x0a6f49b0, + 0x0a4da7f0, 0x0a2c7e20, 0x0a0ba310, 0x09eb1220, + 0x09cac6e0, 0x09aabc70, 0x098aee40, 0x096b57a0, + 0x094bf400, 0x092cbea0, 0x090db2e0, 0x08eecef0, + 0x08d01360, 0x08b18110, 0x089318b0, 0x0874db00, + 0x0856c880, 0x0838e1b0, 0x081b2730, 0x07fd99a8, + 0x07e03a28, 0x07c309a8, 0x07a60910, 0x07893918, + 0x076c99d0, 0x07502b90, 0x0733ee70, 0x0717e2f8, + 0x06fc09b8, 0x06e06378, 0x06c4f0b8, 0x06a9b1c8, + 0x068ea6a0, 0x0673cf18, 0x06592b18, 0x063ebad0, + 0x06247ed0, 0x060a7780, 0x05f0a570, 0x05d708b8, + 0x05bda128, 0x05a46e80, 0x058b7078, 0x0572a740, + 0x055a1330, 0x0541b4d8, 0x05298c98, 0x05119a88, + 0x04f9de50, 0x04e257a0, 0x04cb0630, 0x04b3ea00, + 0x049d0378, 0x04865308, 0x046fd918, 0x045995a8, + 0x04438860, 0x042db0d0, 0x04180ea0, 0x0402a1d0, + 0x03ed6abc, 0x03d869b8, 0x03c39f28, 0x03af0af0, + 0x039aaca0, 0x038683b4, 0x03728fc0, 0x035ed0b0, + 0x034b46c4, 0x0337f254, 0x0324d3a0, 0x0311eab0, + 0x02ff370c, 0x02ecb85c, 0x02da6e34, 0x02c858a8, + 0x02b67820, 0x02a4cd28, 0x02935820, 0x02821920, + 0x02710fac, 0x02603b54, 0x024f9bb4, 0x023f308c, + 0x022ef9e8, 0x021ef7c8, 0x020f2a40, 0x01ff908e, + 0x01f02974, 0x01e0f38a, 0x01d1ed94, 0x01c316d6, + 0x01b46f5e, 0x01a5f720, 0x0197ae28, 0x018994ea, + 0x017bac54, 0x016df546, 0x016070ae, 0x01532078, + 0x01460760, 0x01392834, 0x012c85a4, 0x01201f7a, + 0x0113f27c, 0x0107fb6c, 0x00fc36fd, 0x00f0a2d5, + 0x00e53d51, 0x00da050f, 0x00cef88c, 0x00c41869, + 0x00b9671f, 0x00aee754, 0x00a49b80, 0x009a8384, + 0x00909ca6, 0x0086e400, 0x007d56e3, 0x0073f48e, + 0x006abe70, 0x0061b5de, 0x0058dc65, 0x005033b4, + 0x0047be30, 0x003f7e30, 0x00377619, 0x002fa4d4, + 0x002805ee, 0x002094cb, 0x00194cb8, 0x00122856, + 0x000b215c, 0x00043148, 0xfffd51f0, 0xfff683a0, + 0xffefcd4d, 0xffe9362f, 0xffe2c57d, 0xffdc855c, + 0xffd682c4, 0xffd0cad4, 0xffcb6a2c, 0xffc663bc, + 0xffc1b06f, 0xffbd48e1, 0xffb92570, 0xffb53a54, + 0xffb1779c, 0xffadcd38, 0xffaa2b42, 0xffa68855, + 0xffa2e141, 0xff9f332c, 0xff9b7b9c, 0xff97bf2e, + 0xff9409e2, 0xff9067e2, 0xff8ce556, 0xff898bf0, + 0xff866306, 0xff8371d0, 0xff80bf63, 0xff7e4eba, + 0xff7c1eaa, 0xff7a2e04, 0xff787b47, 0xff770280, + 0xff75bd06, 0xff74a3f7, 0xff73b0b2, 0xff72dd02, + 0xff72237e, 0xff717ebe, 0xff70e94c, 0xff705f59, + 0xff6fde6a, 0xff6f6426, 0xff6eee40, 0xff6e7d0b, + 0xff6e1359, 0xff6db403, 0xff6d61f8, 0xff6d2054, + 0xff6cf267, 0xff6cdb76, 0xff6cdebb, 0xff6cff47, + 0xff6d3fc9, 0xff6da306, 0xff6e2b82, 0xff6eda13, + 0xff6fad6d, 0xff70a463, 0xff71bd9d, 0xff72f662, + 0xff744a80, 0xff75b5c4, 0xff773409, 0xff78c0a6, + 0xff7a5693, 0xff7bf0dc, 0xff7d8abb, 0xff7f2301, + 0xff80bc08, 0xff825854, 0xff83fa56, 0xff85a55c, + 0xff875d22, 0xff892598, 0xff8b025d, 0xff8cf53c, + 0xff8efdf4, 0xff911c48, 0xff934fc9, 0xff959675, + 0xff97ec86, 0xff9a4e35, 0xff9cb7d2, 0xff9f26cc, + 0xffa199ce, 0xffa40f74, 0xffa6867c, 0xffa8feb2, + 0xffab78e0, 0xffadf5c7, 0xffb07640, 0xffb2fba0, + 0xffb587a2, 0xffb81bfb, 0xffbaba46, 0xffbd6236, + 0xffc011a8, 0xffc2c679, 0xffc57e84, 0xffc83894, + 0xffcaf41a, 0xffcdb0b8, 0xffd06e17, 0xffd32bf7, + 0xffd5ea38, 0xffd8a8c3, 0xffdb6764, 0xffde25fb, + 0xffe0e471, 0xffe3a2b2, 0xffe66087, 0xffe91da6, + 0xffebd978, 0xffee9351, 0xfff14ab0, 0xfff3fef6, + 0xfff6af94, 0xfff95c0c, 0xfffc03c7, 0xfffea659, + 0x00015885, 0x0003f2e9, 0x00068a73, 0x00091e8d, + 0x000bae7f, 0x000e39bf, 0x0010bf96, 0x00133f78, + 0x0015b8c4, 0x00182ae4, 0x001a9558, 0x001cf7b2, + 0x001f51e0, 0x0021a3b4, 0x0023ed25, 0x00262df2, + 0x002865c5, 0x002a9469, 0x002cb967, 0x002ed4aa, + 0x0030e607, 0x0032ed88, 0x0034eb2f, 0x0036de23, + 0x0038c503, 0x003a9e4c, 0x003c68a6, 0x003e23dd, + 0x003fd0db, 0x00417083, 0x0043038b, 0x00448adf, + 0x00460740, 0x0047799c, 0x0048e2b2, 0x004a42af, + 0x004b98fb, 0x004ce50b, 0x004e2654, 0x004f5b5d, + 0x005081c3, 0x00519716, 0x00529920, 0x005386d0, + 0x0054603f, 0x00552581, 0x0055d6cc, 0x00567558, + 0x0057033c, 0x005782b4, 0x0057f5b6, 0x00585e46, + 0x0058be68, 0x005917ff, 0x00596ce4, 0x0059bcc0, + 0x005a053a, 0x005a43ee, 0x005a76ae, 0x005a9b37, + 0x005aaf38, 0x005ab07a, 0x005a9cef, 0x005a7349, + 0x005a3328, 0x0059dc0a, 0x00596db0, 0x0058e8e5, + 0x00584f98, 0x0057a3c0, 0x0056e738, 0x00561bec, + 0x005543df, 0x0054610b, 0x0053753e, 0x0052824e, + 0x005189f6, 0x00508dec, 0x004f8fc0, 0x004e8fd0, + 0x004d8d26, 0x004c86d7, 0x004b7c0a, 0x004a6b33, + 0x00495239, 0x00482f0e, 0x0046ffc4, 0x0045c201, + 0x00447337, 0x004310cc, 0x00419871, 0x004008e4, + 0x003e6231, 0x003ca460, 0x003acf8a, 0x0038e57a, + 0x0036e981, 0x0034defa, 0x0032c94b, 0x0030acc6, + 0x002e8eb4, 0x002c7452, 0x002a62aa, 0x00285bbf, + 0x00265eda, 0x00246b24, 0x00227f9c, 0x002098e7, + 0x001eb13b, 0x001cc2ef, 0x001ac899, 0x0018be3d, + 0x0016a198, 0x00147065, 0x00122897, 0x000fcbc5, + 0x000d5f03, 0x000ae77a, 0x00086a52, 0x0005eb92, + 0x00036e4a, 0x0000f57e, 0xfffe8414, 0xfffc1a78, + 0xfff9b6bb, 0xfff756d9, 0xfff4f8d0, 0xfff29add, + 0xfff03b87, 0xffedd94c, 0xffeb7295, 0xffe9072b, + 0xffe6981a, 0xffe4265b, 0xffe1b30e, 0xffdf3f2b, + 0xffdccb9e, 0xffda5993, 0xffd7ea0c, 0xffd57d60, + 0xffd31302, 0xffd0aa27, 0xffce4243, 0xffcbdb40, + 0xffc97595, 0xffc711a2, 0xffc4af9d, 0xffc24fa6, + 0xffbff1de, 0xffbd9699, 0xffbb3e44, 0xffb8e8d5, + 0xffb695f4, 0xffb44522, 0xffb1f627, 0xffafa8f0, + 0xffad5d91, 0xffab140a, 0xffa8cc1c, 0xffa68590, + 0xffa44066, 0xffa1fca0, 0xff9fba30, 0xff9d7902, + 0xff9b3916, 0xff98fa6d, 0xff96bd06, 0xff9480b6, + 0xff924532, 0xff900a24, 0xff8dcf41, 0xff8b9433, + 0xff895884, 0xff871bd3, 0xff84dd8a, 0xff829d34, + 0xff805a43, 0xff7e142d, 0xff7bca71, 0xff797c83, + 0xff7729e3, 0xff74d204, 0xff727451, 0xff70101e, + 0xff6da493, 0xff6b30d1, 0xff68b3f4, 0xff662d31, + 0xff639bd1, 0xff60ff09, 0xff5e562c, 0xff5ba3e0, + 0xff58ee39, 0xff563c22, 0xff5394f3, 0xff50fd1e, + 0xff4e7599, 0xff4bff32, 0xff499ad4, 0xff47490a, + 0xff450a36, 0xff42deb7, 0xff40c6cf, 0xff3ec2be, + 0xff3cd299, 0xff3af681, 0xff392e6a, 0xff377a4a, + 0xff35d9f7, 0xff344d44, 0xff32d3e8, 0xff316d96, + 0xff3019d9, 0xff2ed83a, 0xff2da82f, 0xff2c88bf, + 0xff2b78b4, 0xff2a76cc, 0xff298184, 0xff289890, + 0xff27bc7d, 0xff26ee21, 0xff262e28, 0xff257cdc, + 0xff24d9f4, 0xff244524, 0xff23be15, 0xff234488, + 0xff22d852, 0xff227947, 0xff22273d, 0xff21e1d2, + 0xff21a871, 0xff217a79, 0xff215748, 0xff213eca, + 0xff21319e, 0xff21305c, 0xff213baf, 0xff2153c2, + 0xff21782b, 0xff21a892, 0xff21e477, 0xff222bda, + 0xff227f26, 0xff22debd, 0xff234b09, 0xff23c394, + 0xff24471d, 0xff24d42b, 0xff25695c, 0xff260538, + 0xff26a652, 0xff274b28, 0xff27f22d, 0xff2899d2, + 0xff295975, 0xff29f2ad, 0xff2a96d7, 0xff2b45f4, + 0xff2bffe3, 0xff2cc4ba, 0xff2d9458, 0xff2e6ede, + 0xff2f544c, 0xff3044b7, 0xff314034, 0xff3246fa, + 0xff33591e, 0xff3476e0, 0xff35a060, 0xff36d534, + 0xff38148f, 0xff395daf, 0xff3aafd4, 0xff3c0ac8, + 0xff3d6ed6, 0xff3edc54, 0xff405382, 0xff41d3f5, + 0xff435ccc, 0xff44ed0f, 0xff4683d3, 0xff482080, + 0xff49c297, 0xff4b69ab, 0xff4d1547, 0xff4ec4f5, + 0xff50781d, 0xff522e20, 0xff53e692, 0xff55a15d, + 0xff575f17, 0xff592022, 0xff5ae4de, 0xff5cacb4, + 0xff5e75e2, 0xff603ee5, 0xff62062f, 0xff63caab, + 0xff658b55, 0xff67476d, 0xff68fe11, 0xff6aaea0, + 0xff6c5899, 0xff6dfb86, 0xff6f96e7, 0xff712a65, + 0xff72b59f, 0xff74382b, 0xff75b1d3, 0xff772276, + 0xff788a20, 0xff79e8e5, 0xff7b3ef0, 0xff7c8c98, + 0xff7dd249, 0xff7f108c, 0xff804804, 0xff817d0e, + 0xff82b74a, 0xff83fde6, 0xff855762, 0xff86c622, + 0xff884904, 0xff89ded1, 0xff8b8646, 0xff8d3e4c, + 0xff8f05cc, 0xff90dbc6, 0xff92bf2a, 0xff94af04, + 0xff96aa26, 0xff98af9a, 0xff9abe48, 0xff9cd543, + 0xff9ef3c1, 0xffa118ea, 0xffa343fd, 0xffa57423, + 0xffa7a890, 0xffa9e084, 0xffac1b31, 0xffae5802, + 0xffb09680, 0xffb2d621, 0xffb51678, 0xffb75704, + 0xffb99726, 0xffbbd645, 0xffbe13d7, 0xffc04f26, + 0xffc2879a, 0xffc4bc72, 0xffc6ed24, 0xffc918e3, + 0xffcb3eb8, 0xffcd5dcc, 0xffcf7549, 0xffd184d8, + 0xffd38c8f, 0xffd58ca4, 0xffd7854d, 0xffd97694, + 0xffdb606e, 0xffdd42d1, 0xffdf1da8, 0xffe0f09b, + 0xffe2bb00, 0xffe47c41, 0xffe633c6, 0xffe7e150, + 0xffe98534, 0xffeb1fb4, 0xffecb10e, 0xffee3944, + 0xffefb7e9, 0xfff12cbe, 0xfff29762, 0xfff3f789, + 0xfff54cbe, 0xfff69695, 0xfff7d4b8, 0xfff90748, + 0xfffa2ee5, 0xfffb4c3c, 0xfffc6003, 0xfffd6af0, + 0xfffe6dda, 0xffff69b8, 0x00005f4b, 0x00014e7f, + 0x00023646, 0x000315b4, 0x0003ebd3, 0x0004b74a, + 0x00057677, 0x000627e2, 0x0006ca09, 0x00075ce1, + 0x0007e196, 0x00085955, 0x0008c556, 0x00092751, + 0x00098153, 0x0009d581, 0x000a25be, 0x000a732b, + 0x000abe1f, 0x000b06e4, 0x000b4db1, 0x000b91fa, + 0x000bd266, 0x000c0da0, 0x000c426e, 0x000c6ffb, + 0x000c95b0, 0x000cb2f7, 0x000cc76e, 0x000cd317, + 0x000cd647, 0x000cd17f, 0x000cc52b, 0x000cb1ea, + 0x000c98c0, 0x000c7a62, 0x000c57c7, 0x000c3187, + 0x000c0862, 0x000bdcd8, 0x000baf81, 0x000b80c7, + 0x000b50ec, 0x000b202f, 0x000aeec6, 0x000abcb2, + 0x000a89d2, 0x000a5605, 0x000a2116, 0x0009eafb, + 0x0009b37d, 0x00097a9d, 0x00094030, 0x00090440, + 0x0008c6b9, 0x000887ae, 0x0008470c, 0x00080512, + 0x0007c1f6, 0x00077df9, 0x0007395a, 0x0006f45b, + 0x0006af67, 0x00066abe, 0x000626b6, 0x0005e38f, + 0x0005a1a0, 0x0005611e, 0x00052234, 0x0004e502, + 0x0004a95d, 0x00046f46, 0x00043691, 0x0003ff33, + 0x0003c90d, 0x0003941f, 0x00036047, 0x00032d9c, + 0x0002fc1e, 0x0002cbed, 0x00029d1e, 0x00026fbc, + 0x000243f2, 0x000219d6, 0x0001f17d, 0x0001caf1, + 0x0001a63e, 0x00018363, 0x00016256, 0x00014316, + 0x0001258f, 0x000109cb, 0x0000efaa, 0x0000d720, + 0x0000c03a, 0x0000aacb, 0x000096de, 0x0000846a, + 0x0000736d, 0x000063d3, 0x000055a6, 0x000048d0, + 0x00003d47, 0x000032f6, 0x000029dc, 0x000021d9, + 0x00001ae3, 0x000014ee, 0x00000fdb, 0x00000ba9, + 0x00000839, 0x00000589, 0x00000370, 0x000001ee, + 0x000000d7, 0x00000036, 0xffffffe0, 0xffffffc0, + 0xffffffd5, 0xfffffff5, 0x0000000b, 0x0000000b, + 0x0000000b, 0x0000000b, 0xfffffff5, 0xffffffd5, + 0xffffffca, 0xffffffe0, 0x00000036, 0x000000d7, + 0x000001ce, 0x0000033b, 0x00000529, 0x000007ad, + 0x00000ac8, 0x00000e99, 0x00001316, 0x0000185e, + 0x00001e7e, 0x00002575, 0x00002d4c, 0x0000361b, + 0x00003fd6, 0x00004a93, 0x00005647, 0x00006312, + 0x000070de, 0x00007fad, 0x00008f87, 0x0000a064, + 0x0000b242, 0x0000c52d, 0x0000d919, 0x0000ee12, + 0x0001040c, 0x00011b13, 0x0001331b, 0x00014c30, + 0x0001663c, 0x0001814a, 0x00019d4f, 0x0001ba35, + 0x0001d7e7, 0x0001f645, 0x00021544, 0x000234c3, + 0x000254b9, 0x00027505, 0x000295a7, 0x0002b67e, + 0x0002d7a1, 0x0002f904, 0x00031ab2, 0x00033ca0, + 0x00035ee5, 0x0003818a, 0x0003a485, 0x0003c7e1, + 0x0003eb72, 0x00040f0e, 0x0004329f, 0x000455e6, + 0x000478c0, 0x00049aef, 0x0004bc52, 0x0004dca9, + 0x0004fbde, 0x000519c5, 0x00053635, 0x0005512d, + 0x00056aae, 0x000582a1, 0x00059927, 0x0005ae40, + 0x0005c1f6, 0x0005d455, 0x0005e572, 0x0005f56d, + 0x00060446, 0x0006121e, 0x00061f09, 0x00062b08, + 0x00063605, 0x00063feb, 0x00064899, 0x00064ff0, + 0x000655a5, 0x00065996, 0x00065b6f, 0x00065af8, + 0x000657e9, 0x000651d4, 0x00064884, 0x00063bae, + 0x00062b33, 0x00061706, 0x0005fefd, 0x0005e344, + 0x0005c404, 0x0005a195, 0x00057c41, 0x00055473, + 0x00052ac2, 0x0004ffc4, 0x0004d410, 0x0004a7e5, + 0x00047b4f, 0x00044e39, 0x00042096, 0x0003f208, + 0x0003c1e1, 0x00038f77, 0x00035a12, 0x00032127, + 0x0002e476, 0x0002a389, 0x00025e29, 0x0002146d, + 0x0001c700, 0x00017682, 0x000123a1, 0x0000cefd, + 0x000078f7, 0x0000221a, 0xffffcad1, 0xffff7332, + 0xffff1b1e, 0xfffec253, 0xfffe6891, 0xfffe0da2, + 0xfffdb15c, 0xfffd5393, 0xfffcf412, 0xfffc92e3, + 0xfffc3032, 0xfffbcc29, 0xfffb6714, 0xfffb0113, + 0xfffa9a5b, 0xfffa3337, 0xfff9cbd4, 0xfff96450, + 0xfff8fcac, 0xfff894dc, 0xfff82cd8, 0xfff7c4a8, + 0xfff75c6d, 0xfff6f45e, 0xfff68c84, 0xfff62500, + 0xfff5bde8, 0xfff5575a, 0xfff4f179, 0xfff48c64, + 0xfff42810, 0xfff3c488, 0xfff361d7, 0xfff30008, + 0xfff29f3a, 0xfff23f78, 0xfff1e0d8, 0xfff1835b, + 0xfff1272a, 0xfff0cc46, 0xfff072cf, 0xfff01ad0, + 0xffefc469, 0xffef6fa4, 0xffef1ca3, 0xffeecb7a, + 0xffee7c1f, 0xffee2eb2, 0xffede33d, 0xffed99c1, + 0xffed5249, 0xffed0cde, 0xffecc98d, 0xffec8849, + 0xffec4934, 0xffec0c38, 0xffebd175, 0xffeb98eb, + 0xffeb62a4, 0xffeb2ead, 0xffeafd19, 0xffeacdea, + 0xffeaa129, 0xffea76cc, 0xffea4ef4, 0xffea299f, + 0xffea06e5, 0xffe9e6ce, 0xffe9c97d, 0xffe9aebb, + 0xffe99651, 0xffe97fd6, 0xffe96ad3, 0xffe95711, + 0xffe9447d, 0xffe93315, 0xffe922ce, 0xffe913a0, + 0xffe90588, 0xffe8f887, 0xffe8ec93, 0xffe8e1c1, + 0xffe8d806, 0xffe8cf77, 0xffe8c816, 0xffe8c1eb, + 0xffe8bd03, 0xffe8b967, 0xffe8b72e, 0xffe8b64d, + 0xffe8b6d8, 0xffe8b8dc, 0xffe8bc6c, 0xffe8c18a, + 0xffe8c840, 0xffe8d0a4, 0xffe8daca, 0xffe8e69e, + 0xffe8f42a, 0xffe9035a, 0xffe9142b, 0xffe926a0, + 0xffe93ab7, 0xffe95066, 0xffe967b8, 0xffe980ad, + 0xffe99b3a, 0xffe9b754, 0xffe9d511, 0xffe9f45b, + 0xffea1532, 0xffea3797, 0xffea5b89, 0xffea8108, + 0xffeaa7ff, 0xffead079, 0xffeafa55, 0xffeb259e, + 0xffeb5254, 0xffeb8061, 0xffebafdc, 0xffebe0ae, + 0xffec12ce, 0xffec462f, 0xffec7add, 0xffecb0a3, + 0xffece774, 0xffed1f32, 0xffed57a7, 0xffed90b2, + 0xffedca48, 0xffee042a, 0xffee3e57, 0xffee788e, +}; + +const DECLARE_ALIGNED(32, float, ff_aac_eld_window_480)[1800] = { + 0.00101191, 0.00440397, 0.00718669, 0.01072130, + 0.01459757, 0.01875954, 0.02308987, 0.02751541, + 0.03198130, 0.03643738, 0.04085290, 0.04522835, + 0.04957620, 0.05390454, 0.05821503, 0.06251214, + 0.06680463, 0.07109582, 0.07538014, 0.07965207, + 0.08390857, 0.08815177, 0.09238785, 0.09662163, + 0.10085860, 0.10510892, 0.10938110, 0.11367819, + 0.11800355, 0.12236410, 0.12676834, 0.13122384, + 0.13573476, 0.14030106, 0.14492340, 0.14960315, + 0.15433828, 0.15912396, 0.16395663, 0.16883310, + 0.17374837, 0.17869679, 0.18367394, 0.18867661, + 0.19370368, 0.19875413, 0.20382641, 0.20892055, + 0.21403775, 0.21917761, 0.22433899, 0.22952250, + 0.23472991, 0.23996189, 0.24521859, 0.25049930, + 0.25580312, 0.26112942, 0.26647748, 0.27184703, + 0.27723785, 0.28264967, 0.28808086, 0.29352832, + 0.29898979, 0.30446379, 0.30994292, 0.31541664, + 0.32087942, 0.32632772, 0.33176291, 0.33718641, + 0.34259612, 0.34799346, 0.35338857, 0.35878843, + 0.36419504, 0.36960630, 0.37501567, 0.38042067, + 0.38582069, 0.39121276, 0.39659312, 0.40195993, + 0.40731155, 0.41264382, 0.41795277, 0.42323670, + 0.42849480, 0.43372753, 0.43893452, 0.44411398, + 0.44927117, 0.45441882, 0.45956191, 0.46470167, + 0.46983016, 0.47493636, 0.48001827, 0.48507480, + 0.49010240, 0.49509781, 0.50005986, 0.50499037, + 0.50989790, 0.51478708, 0.51965805, 0.52450975, + 0.52933955, 0.53414668, 0.53893113, 0.54369178, + 0.54842731, 0.55313757, 0.55782259, 0.56248253, + 0.56711762, 0.57172819, 0.57631468, 0.58087761, + 0.58719976, 0.59173064, 0.59623644, 0.60071719, + 0.60517294, 0.60960372, 0.61400958, 0.61839056, + 0.62274670, 0.62707805, 0.63138475, 0.63566700, + 0.63992500, 0.64415895, 0.64836893, 0.65255499, + 0.65671715, 0.66085548, 0.66497005, 0.66906094, + 0.67312824, 0.67717199, 0.68119219, 0.68518882, + 0.68916187, 0.69311129, 0.69703698, 0.70093884, + 0.70481679, 0.70867071, 0.71250047, 0.71630596, + 0.72008705, 0.72384360, 0.72757549, 0.73128256, + 0.73496463, 0.73862141, 0.74225263, 0.74585799, + 0.74943730, 0.75299039, 0.75651711, 0.76001729, + 0.76349062, 0.76693670, 0.77035516, 0.77374564, + 0.77710790, 0.78044169, 0.78374678, 0.78702291, + 0.79026979, 0.79348715, 0.79667471, 0.79983215, + 0.80295914, 0.80605536, 0.80912047, 0.81215417, + 0.81515616, 0.81812616, 0.82106389, 0.82396915, + 0.82684176, 0.82968154, 0.83248830, 0.83526186, + 0.83800204, 0.84070866, 0.84338156, 0.84602058, + 0.84862556, 0.85119636, 0.85373292, 0.85623523, + 0.85870326, 0.86113701, 0.86353649, 0.86590173, + 0.86823275, 0.87052968, 0.87279275, 0.87502220, + 0.87721829, 0.87938130, 0.88151157, 0.88360940, + 0.88567517, 0.88770954, 0.88971328, 0.89168716, + 0.89363199, 0.89554856, 0.89743771, 0.89930025, + 0.90113740, 0.90295086, 0.90474240, 0.90651380, + 0.90826684, 0.91000335, 0.91172515, 0.91343416, + 0.91513276, 0.91682357, 0.91850924, 0.92019170, + 0.92187129, 0.92354778, 0.92522116, 0.92688597, + 0.92852960, 0.93013861, 0.93169897, 0.93319114, + 0.93458502, 0.93587626, 0.93694276, 0.93825562, + 0.93882222, 0.93910780, 0.93944183, 0.93981497, + 0.94021434, 0.94062629, 0.94103714, 0.94144084, + 0.94184042, 0.94223966, 0.94264206, 0.94304859, + 0.94345831, 0.94387033, 0.94428390, 0.94469895, + 0.94511572, 0.94553441, 0.94595520, 0.94637816, + 0.94680335, 0.94723080, 0.94766054, 0.94809253, + 0.94852674, 0.94896314, 0.94940178, 0.94984276, + 0.95028618, 0.95073213, 0.95118056, 0.95163139, + 0.95208451, 0.95253992, 0.95299770, 0.95345799, + 0.95392092, 0.95438653, 0.95485472, 0.95532539, + 0.95579847, 0.95627397, 0.95675201, 0.95723273, + 0.95771618, 0.95820232, 0.95869103, 0.95918218, + 0.95967573, 0.96017172, 0.96067026, 0.96117144, + 0.96167526, 0.96218157, 0.96269026, 0.96320119, + 0.96371437, 0.96422988, 0.96474782, 0.96526824, + 0.96579106, 0.96631614, 0.96684334, 0.96737257, + 0.96790390, 0.96843740, 0.96897315, 0.96951112, + 0.97005119, 0.97059318, 0.97113697, 0.97168253, + 0.97222994, 0.97277928, 0.97333058, 0.97388375, + 0.97443863, 0.97499505, 0.97555292, 0.97611230, + 0.97667326, 0.97723589, 0.97780016, 0.97836591, + 0.97893300, 0.97950127, 0.98007071, 0.98064139, + 0.98121342, 0.98178684, 0.98236156, 0.98293743, + 0.98351428, 0.98409205, 0.98467078, 0.98525056, + 0.98583146, 0.98641348, 0.98699650, 0.98758037, + 0.98816497, 0.98875030, 0.98933647, 0.98992356, + 0.99051163, 0.99110062, 0.99169038, 0.99228079, + 0.99287177, 0.99346341, 0.99405581, 0.99464907, + 0.99524320, 0.99583812, 0.99643375, 0.99702997, + 0.99762671, 0.99822386, 0.99882134, 0.99941903, + 1.00058131, 1.00118006, 1.00177930, 1.00237893, + 1.00297887, 1.00357902, 1.00417927, 1.00477954, + 1.00537972, 1.00597973, 1.00657959, 1.00717940, + 1.00777926, 1.00837925, 1.00897929, 1.00957926, + 1.01017901, 1.01077847, 1.01137769, 1.01197678, + 1.01257582, 1.01317482, 1.01377365, 1.01437217, + 1.01497025, 1.01556786, 1.01616510, 1.01676205, + 1.01735876, 1.01795514, 1.01855103, 1.01914627, + 1.01974076, 1.02033455, 1.02092772, 1.02152037, + 1.02211247, 1.02270387, 1.02329439, 1.02388387, + 1.02447229, 1.02505972, 1.02564624, 1.02623190, + 1.02681660, 1.02740017, 1.02798242, 1.02856326, + 1.02914272, 1.02972087, 1.03029778, 1.03087344, + 1.03144768, 1.03202035, 1.03259127, 1.03316042, + 1.03372788, 1.03429373, 1.03485801, 1.03542064, + 1.03598146, 1.03654030, 1.03709708, 1.03765185, + 1.03820470, 1.03875571, 1.03930488, 1.03985206, + 1.04039712, 1.04093989, 1.04148037, 1.04201865, + 1.04255481, 1.04308893, 1.04362093, 1.04415068, + 1.04467803, 1.04520292, 1.04572542, 1.04624566, + 1.04676376, 1.04727974, 1.04779350, 1.04830493, + 1.04881391, 1.04932048, 1.04982477, 1.05032693, + 1.05082705, 1.05132510, 1.05182098, 1.05231457, + 1.05280584, 1.05329485, 1.05378171, 1.05426654, + 1.05474937, 1.05523018, 1.05570892, 1.05618554, + 1.05666005, 1.05713251, 1.05760297, 1.05807149, + 1.05853828, 1.05900355, 1.05946756, 1.05993024, + 1.06039075, 1.06084806, 1.06130111, 1.06175099, + 1.06220164, 1.06265732, 1.06312146, 1.06358726, + 1.06403924, 1.06446186, 1.06484048, 1.06516440, + 1.06527864, 1.06498077, 1.06470196, 1.06425743, + 1.06372091, 1.06311464, 1.06246622, 1.06179277, + 1.06110808, 1.06042455, 1.05974495, 1.05906206, + 1.05836706, 1.05765243, 1.05691470, 1.05615178, + 1.05536069, 1.05454152, 1.05370030, 1.05284445, + 1.05198094, 1.05111433, 1.05024634, 1.04937859, + 1.04851245, 1.04764614, 1.04677586, 1.04589855, + 1.04501046, 1.04410500, 1.04317417, 1.04221010, + 1.04120649, 1.04016012, 1.03906851, 1.03792894, + 1.03674090, 1.03550649, 1.03422800, 1.03290769, + 1.03154944, 1.03015834, 1.02873938, 1.02729712, + 1.02583470, 1.02435463, 1.02285952, 1.02135114, + 1.01982974, 1.01829520, 1.01674752, 1.01518534, + 1.01360559, 1.01200510, 1.01038076, 1.00872996, + 1.00705045, 1.00533999, 1.00359618, 1.00181613, + 0.99999673, 0.99813477, 0.99622793, 0.99427571, + 0.99227814, 0.99023501, 0.98815128, 0.98603857, + 0.98390898, 0.98177413, 0.97964151, 0.97751528, + 0.97539999, 0.97329751, 0.97119933, 0.96909179, + 0.96696152, 0.96479824, 0.96259840, 0.96036028, + 0.95808180, 0.95576295, 0.95340622, 0.95101436, + 0.94859030, 0.94614009, 0.94367232, 0.94119555, + 0.93871796, 0.93624630, 0.93378636, 0.93134465, + 0.92892076, 0.92649974, 0.92406255, 0.92159041, + 0.91907411, 0.91651711, 0.91392425, 0.91130056, + 0.90865471, 0.90599838, 0.90334350, 0.90069934, + 0.89806435, 0.89543132, 0.89279335, 0.89014496, + 0.88748403, 0.88480945, 0.88211997, 0.87941558, + 0.87669794, 0.87396891, 0.87123030, 0.86848394, + 0.86573164, 0.86297523, 0.86021649, 0.85745725, + 0.85474342, 0.85193656, 0.84911455, 0.84627969, + 0.84343424, 0.84058046, 0.83772057, 0.83485680, + 0.83199134, 0.82912621, 0.82626143, 0.82339529, + 0.82052619, 0.81765147, 0.81476433, 0.81185593, + 0.80891701, 0.80594452, 0.80294885, 0.79994431, + 0.79694485, 0.79396166, 0.79100220, 0.78807349, + 0.78518123, 0.78231422, 0.77944709, 0.77655407, + 0.77361369, 0.77062281, 0.76758806, 0.76451506, + 0.76141145, 0.75828860, 0.75515892, 0.75203479, + 0.74892561, 0.74583682, 0.74277342, 0.73974008, + 0.73673754, 0.73376310, 0.73081444, 0.72788616, + 0.72496070, 0.72201426, 0.71902283, 0.71596990, + 0.71285541, 0.70968427, 0.70646064, 0.70319589, + 0.69991077, 0.69662714, 0.69336592, 0.69013742, + 0.68694302, 0.68378420, 0.68066143, 0.67757157, + 0.67450951, 0.67147030, 0.66844879, 0.66543949, + 0.66243677, 0.65943505, 0.65642754, 0.65340591, + 0.65036160, 0.64728630, 0.64417440, 0.64102268, + 0.63782771, 0.63458757, 0.63130628, 0.62799109, + 0.62464879, 0.62128816, 0.61792203, 0.61456438, + 0.61122915, 0.60792802, 0.60466971, 0.60146257, + 0.59831460, 0.59522876, 0.59220375, 0.58923859, + 0.58632936, 0.58346064, 0.58061078, 0.57775874, + 0.57488246, 0.57195790, 0.56896078, 0.56586637, + 0.56266594, 0.55937186, 0.55599898, 0.55256299, + 0.54909184, 0.54562376, 0.54219742, 0.53884728, + 0.53559047, 0.53243453, 0.52938894, 0.52645052, + 0.52358958, 0.52076862, 0.51795080, 0.51510761, + 0.51222179, 0.50927733, 0.50625944, 0.50317073, + 0.50002767, 0.49685021, 0.49364116, 0.49048690, + 0.48726128, 0.48404889, 0.48090875, 0.47783482, + 0.47481564, 0.47184024, 0.46889391, 0.46595836, + 0.46301611, 0.46005089, 0.45705924, 0.45404822, + 0.45102447, 0.44799543, 0.44497138, 0.44196397, + 0.43898547, 0.43604105, 0.43312057, 0.43020942, + 0.42729337, 0.42436272, 0.42141388, 0.41844400, + 0.41545081, 0.41244014, 0.40942464, 0.40641716, + 0.40342874, 0.40046292, 0.39751923, 0.39459758, + 0.39169692, 0.38881435, 0.38594643, 0.38308980, + 0.38024146, 0.37739896, 0.37455986, 0.37172187, + 0.36888463, 0.36604937, 0.36321735, 0.36038967, + 0.35756668, 0.35474832, 0.35193455, 0.34912542, + 0.34632129, 0.34352258, 0.34072974, 0.33794323, + 0.33516354, 0.33239114, 0.32962648, 0.32686967, + 0.32412042, 0.32137919, 0.31864044, 0.31588373, + 0.31309909, 0.31028631, 0.30745528, 0.30462678, + 0.30180656, 0.29899424, 0.29619082, 0.29339717, + 0.29061333, 0.28783935, 0.28507563, 0.28232266, + 0.27958067, 0.27684984, 0.27413017, 0.27142157, + 0.26872396, 0.26603737, 0.26336211, 0.26069855, + 0.25804700, 0.25540830, 0.25278329, 0.25017211, + 0.24757451, 0.24498713, 0.24240740, 0.23983550, + 0.23727200, 0.23471866, 0.23217624, 0.22964458, + 0.22712346, 0.22461258, 0.22211202, 0.21962197, + 0.21714290, 0.21467522, 0.21221877, 0.20977323, + 0.20733693, 0.20490860, 0.20248823, 0.20007615, + 0.19767358, 0.19528091, 0.19289781, 0.19052347, + 0.18815661, 0.18579693, 0.18344441, 0.18110010, + 0.17876595, 0.17644344, 0.17413400, 0.17183905, + 0.16956003, 0.16729836, 0.16505547, 0.16283278, + 0.15990780, 0.15776021, 0.15563325, 0.15352557, + 0.15143584, 0.14936270, 0.14730481, 0.14526081, + 0.14322937, 0.14120918, 0.13919977, 0.13720138, + 0.13521422, 0.13323852, 0.13127445, 0.12932216, + 0.12738181, 0.12545358, 0.12353773, 0.12163457, + 0.11974436, 0.11786730, 0.11600347, 0.11415293, + 0.11231573, 0.11049201, 0.10868196, 0.10688578, + 0.10510362, 0.10333551, 0.10158143, 0.09984133, + 0.09811524, 0.09640327, 0.09470556, 0.09302228, + 0.09135347, 0.08969907, 0.08805903, 0.08643326, + 0.08482183, 0.08322486, 0.08164249, 0.08007481, + 0.07852179, 0.07698335, 0.07545938, 0.07394984, + 0.07245482, 0.07097444, 0.06950883, 0.06805800, + 0.06662187, 0.06520031, 0.06379324, 0.06240065, + 0.06102266, 0.05965936, 0.05831084, 0.05697701, + 0.05565775, 0.05435290, 0.05306239, 0.05178628, + 0.05052464, 0.04927758, 0.04804510, 0.04682709, + 0.04562344, 0.04443405, 0.04325893, 0.04209822, + 0.04095208, 0.03982059, 0.03870371, 0.03760131, + 0.03651325, 0.03543944, 0.03437987, 0.03333454, + 0.03230348, 0.03128653, 0.03028332, 0.02929346, + 0.02831658, 0.02735252, 0.02640127, 0.02546283, + 0.02453725, 0.02362471, 0.02272547, 0.02183980, + 0.02096810, 0.02011108, 0.01926957, 0.01844439, + 0.01763565, 0.01684248, 0.01606394, 0.01529909, + 0.01454726, 0.01380802, 0.01308092, 0.01236569, + 0.01166273, 0.01097281, 0.01029671, 0.00963479, + 0.00898646, 0.00835089, 0.00772725, 0.00711521, + 0.00651513, 0.00592741, 0.00535249, 0.00479089, + 0.00424328, 0.00371041, 0.00319271, 0.00268947, + 0.00219928, 0.00172084, 0.00125271, 0.00079311, + 0.00034023, -0.00010786, -0.00055144, -0.00098865, + -0.00141741, -0.00183557, -0.00224010, -0.00262725, + -0.00299314, -0.00333475, -0.00365250, -0.00394867, + -0.00422533, -0.00448528, -0.00473278, -0.00497252, + -0.00520916, -0.00544584, -0.00568360, -0.00592326, + -0.00616547, -0.00640861, -0.00664914, -0.00688354, + -0.00710845, -0.00732136, -0.00752022, -0.00770289, + -0.00786789, -0.00801521, -0.00814526, -0.00825839, + -0.00835563, -0.00843882, -0.00850996, -0.00857097, + -0.00862360, -0.00866943, -0.00871004, -0.00874688, + -0.00878091, -0.00881277, -0.00884320, -0.00887248, + -0.00890002, -0.00892494, -0.00894641, -0.00896355, + -0.00897541, -0.00898104, -0.00897948, -0.00896990, + -0.00895149, -0.00892346, -0.00888519, -0.00883670, + -0.00877839, -0.00871058, -0.00863388, -0.00854936, + -0.00845826, -0.00836179, -0.00826124, -0.00815807, + -0.00805372, -0.00794953, -0.00784572, -0.00774156, + -0.00763634, -0.00752929, -0.00741941, -0.00730556, + -0.00718664, -0.00706184, -0.00693107, -0.00679443, + -0.00665200, -0.00650428, -0.00635230, -0.00619718, + -0.00603995, -0.00588133, -0.00572169, -0.00556143, + -0.00540085, -0.00523988, -0.00507828, -0.00491582, + -0.00475220, -0.00458693, -0.00441953, -0.00424950, + -0.00407681, -0.00390204, -0.00372581, -0.00354874, + -0.00337115, -0.00319318, -0.00301494, -0.00283652, + -0.00265797, -0.00247934, -0.00230066, -0.00212197, + -0.00194331, -0.00176471, -0.00158620, -0.00140787, + -0.00122989, -0.00105244, -0.00087567, -0.00069976, + -0.00052487, -0.00035115, -0.00017875, -0.00000782, + 0.00000779, 0.00017701, 0.00034552, 0.00051313, + 0.00067966, 0.00084492, 0.00100873, 0.00117093, + 0.00133133, 0.00148978, 0.00164611, 0.00180023, + 0.00195211, 0.00210172, 0.00224898, 0.00239383, + 0.00253618, 0.00267593, 0.00281306, 0.00294756, + 0.00307942, 0.00320864, 0.00333502, 0.00345816, + 0.00357762, 0.00369297, 0.00380414, 0.00391140, + 0.00401499, 0.00411524, 0.00421242, 0.00430678, + 0.00439859, 0.00448799, 0.00457487, 0.00465908, + 0.00474045, 0.00481857, 0.00489277, 0.00496235, + 0.00502666, 0.00508546, 0.00513877, 0.00518662, + 0.00522904, 0.00526648, 0.00529956, 0.00532895, + 0.00535532, 0.00537929, 0.00540141, 0.00542228, + 0.00544196, 0.00545981, 0.00547515, 0.00548726, + 0.00549542, 0.00549899, 0.00549732, 0.00548986, + 0.00547633, 0.00545664, 0.00543067, 0.00539849, + 0.00536061, 0.00531757, 0.00526993, 0.00521822, + 0.00516300, 0.00510485, 0.00504432, 0.00498194, + 0.00491822, 0.00485364, 0.00478862, 0.00472309, + 0.00465675, 0.00458939, 0.00452067, 0.00445003, + 0.00437688, 0.00430063, 0.00422062, 0.00413609, + 0.00404632, 0.00395060, 0.00384863, 0.00374044, + 0.00362600, 0.00350540, 0.00337934, 0.00324885, + 0.00311486, 0.00297849, 0.00284122, 0.00270458, + 0.00257013, 0.00243867, 0.00231005, 0.00218399, + 0.00206023, 0.00193766, 0.00181460, 0.00168938, + 0.00156050, 0.00142701, 0.00128830, 0.00114365, + 0.00099297, 0.00083752, 0.00067884, 0.00051845, + 0.00035760, 0.00019720, 0.00003813, -0.00011885, + -0.00027375, -0.00042718, -0.00057975, -0.00073204, + -0.00088453, -0.00103767, -0.00119192, -0.00134747, + -0.00150411, -0.00166151, -0.00181932, -0.00197723, + -0.00213493, -0.00229210, -0.00244849, -0.00260415, + -0.00275928, -0.00291410, -0.00306879, -0.00322332, + -0.00337759, -0.00353145, -0.00368470, -0.00383722, + -0.00398892, -0.00413972, -0.00428967, -0.00443889, + -0.00458749, -0.00473571, -0.00488366, -0.00503137, + -0.00517887, -0.00532610, -0.00547302, -0.00561965, + -0.00576598, -0.00591199, -0.00605766, -0.00620300, + -0.00634801, -0.00649273, -0.00663727, -0.00678170, + -0.00692617, -0.00707084, -0.00721583, -0.00736129, + -0.00750735, -0.00765415, -0.00780184, -0.00795059, + -0.00810058, -0.00825195, -0.00840487, -0.00855950, + -0.00871607, -0.00887480, -0.00903596, -0.00919978, + -0.00936650, -0.00953635, -0.00970931, -0.00988421, + -0.01005916, -0.01023208, -0.01040130, -0.01056627, + -0.01072678, -0.01088259, -0.01103348, -0.01117933, + -0.01132004, -0.01145552, -0.01158573, -0.01171065, + -0.01183025, -0.01194454, -0.01205352, -0.01215722, + -0.01225572, -0.01234911, -0.01243749, -0.01252102, + -0.01259985, -0.01267419, -0.01274437, -0.01281078, + -0.01287379, -0.01293350, -0.01298972, -0.01304224, + -0.01309086, -0.01313556, -0.01317644, -0.01321357, + -0.01324707, -0.01327697, -0.01330334, -0.01332622, + -0.01334570, -0.01336194, -0.01337510, -0.01338538, + -0.01339276, -0.01339708, -0.01339816, -0.01339584, + -0.01339014, -0.01338116, -0.01336903, -0.01335382, + -0.01333545, -0.01331381, -0.01328876, -0.01326033, + -0.01322880, -0.01319457, -0.01315806, -0.01311968, + -0.01307987, -0.01303906, -0.01299769, -0.01295623, + -0.01308207, -0.01304153, -0.01299802, -0.01295155, + -0.01290215, -0.01284980, -0.01279450, -0.01273625, + -0.01267501, -0.01261077, -0.01254347, -0.01247306, + -0.01239950, -0.01232277, -0.01224304, -0.01216055, + -0.01207554, -0.01198813, -0.01189829, -0.01180590, + -0.01171090, -0.01161335, -0.01151352, -0.01141167, + -0.01130807, -0.01120289, -0.01109626, -0.01098830, + -0.01087916, -0.01076898, -0.01065793, -0.01054618, + -0.01043380, -0.01032068, -0.01020670, -0.01009171, + -0.00997585, -0.00985959, -0.00974338, -0.00962765, + -0.00951273, -0.00939888, -0.00928634, -0.00917534, + -0.00906604, -0.00895860, -0.00885313, -0.00874977, + -0.00864862, -0.00854979, -0.00845337, -0.00835939, + -0.00826785, -0.00817872, -0.00809195, -0.00800745, + -0.00792506, -0.00784469, -0.00776588, -0.00768695, + -0.00760568, -0.00752004, -0.00742875, -0.00733186, + -0.00722976, -0.00712279, -0.00701130, -0.00689559, + -0.00677595, -0.00665269, -0.00652610, -0.00639649, + -0.00626417, -0.00612943, -0.00599252, -0.00585368, + -0.00571315, -0.00557115, -0.00542792, -0.00528367, + -0.00513864, -0.00499301, -0.00484693, -0.00470054, + -0.00455395, -0.00440733, -0.00426086, -0.00411471, + -0.00396904, -0.00382404, -0.00367991, -0.00353684, + -0.00339502, -0.00325472, -0.00311618, -0.00297967, + -0.00284531, -0.00271307, -0.00258290, -0.00245475, + -0.00232860, -0.00220447, -0.00208236, -0.00196233, + -0.00184450, -0.00172906, -0.00161620, -0.00150603, + -0.00139852, -0.00129358, -0.00119112, -0.00109115, + -0.00099375, -0.00089902, -0.00080705, -0.00071796, + -0.00063185, -0.00054886, -0.00046904, -0.00039231, + -0.00031845, -0.00024728, -0.00017860, -0.00011216, + -0.00004771, 0.00001500, 0.00007600, 0.00013501, + 0.00019176, 0.00024595, 0.00029720, 0.00034504, + 0.00038902, 0.00042881, 0.00046456, 0.00049662, + 0.00052534, 0.00055114, 0.00057459, 0.00059629, + 0.00061684, 0.00063660, 0.00065568, 0.00067417, + 0.00069213, 0.00070935, 0.00072545, 0.00074005, + 0.00075283, 0.00076356, 0.00077209, 0.00077828, + 0.00078205, 0.00078350, 0.00078275, 0.00077992, + 0.00077520, 0.00076884, 0.00076108, 0.00075218, + 0.00074232, 0.00073170, 0.00072048, 0.00070881, + 0.00069680, 0.00068450, 0.00067201, 0.00065934, + 0.00064647, 0.00063335, 0.00061994, 0.00060621, + 0.00059211, 0.00057763, 0.00056274, 0.00054743, + 0.00053169, 0.00051553, 0.00049897, 0.00048206, + 0.00046487, 0.00044748, 0.00042996, 0.00041241, + 0.00039492, 0.00037759, 0.00036049, 0.00034371, + 0.00032732, 0.00031137, 0.00029587, 0.00028079, + 0.00026612, 0.00025183, 0.00023789, 0.00022428, + 0.00021097, 0.00019797, 0.00018530, 0.00017297, + 0.00016100, 0.00014942, 0.00013827, 0.00012757, + 0.00011736, 0.00010764, 0.00009841, 0.00008969, + 0.00008145, 0.00007369, 0.00006641, 0.00005958, + 0.00005320, 0.00004725, 0.00004171, 0.00003659, + 0.00003186, 0.00002752, 0.00002357, 0.00001999, + 0.00001679, 0.00001392, 0.00001140, 0.00000918, + 0.00000726, 0.00000562, 0.00000424, 0.00000309, + 0.00000217, 0.00000143, 0.00000088, 0.00000048, + 0.00000020, 0.00000004, -0.00000004, -0.00000006, + -0.00000004, -0.00000000, 0.00000002, 0.00000000, + 0.00000000, 0.00000002, -0.00000000, -0.00000004, + -0.00000005, -0.00000004, 0.00000004, 0.00000019, + 0.00000045, 0.00000083, 0.00000134, 0.00000201, + 0.00000285, 0.00000387, 0.00000510, 0.00000654, + 0.00000821, 0.00001011, 0.00001227, 0.00001468, + 0.00001735, 0.00002030, 0.00002352, 0.00002702, + 0.00003080, 0.00003486, 0.00003918, 0.00004379, + 0.00004866, 0.00005382, 0.00005924, 0.00006495, + 0.00007093, 0.00007719, 0.00008373, 0.00009053, + 0.00009758, 0.00010488, 0.00011240, 0.00012010, + 0.00012796, 0.00013596, 0.00014406, 0.00015226, + 0.00016053, 0.00016886, 0.00017725, 0.00018571, + 0.00019424, 0.00020286, 0.00021156, 0.00022037, + 0.00022928, 0.00023825, 0.00024724, 0.00025621, + 0.00026509, 0.00027385, 0.00028241, 0.00029072, + 0.00029874, 0.00030643, 0.00031374, 0.00032065, + 0.00032715, 0.00033325, 0.00033895, 0.00034425, + 0.00034917, 0.00035374, 0.00035796, 0.00036187, + 0.00036549, 0.00036883, 0.00037194, 0.00037479, + 0.00037736, 0.00037963, 0.00038154, 0.00038306, + 0.00038411, 0.00038462, 0.00038453, 0.00038373, + 0.00038213, 0.00037965, 0.00037621, 0.00037179, + 0.00036636, 0.00035989, 0.00035244, 0.00034407, + 0.00033488, 0.00032497, 0.00031449, 0.00030361, + 0.00029252, 0.00028133, 0.00027003, 0.00025862, + 0.00024706, 0.00023524, 0.00022297, 0.00021004, + 0.00019626, 0.00018150, 0.00016566, 0.00014864, + 0.00013041, 0.00011112, 0.00009096, 0.00007014, + 0.00004884, 0.00002718, 0.00000530, -0.00001667, + -0.00003871, -0.00006090, -0.00008331, -0.00010600, + -0.00012902, -0.00015244, -0.00017631, -0.00020065, + -0.00022541, -0.00025052, -0.00027594, -0.00030159, + -0.00032740, -0.00035332, -0.00037928, -0.00040527, + -0.00043131, -0.00045741, -0.00048357, -0.00050978, + -0.00053599, -0.00056217, -0.00058827, -0.00061423, + -0.00064002, -0.00066562, -0.00069100, -0.00071616, + -0.00074110, -0.00076584, -0.00079036, -0.00081465, + -0.00083869, -0.00086245, -0.00088590, -0.00090901, + -0.00093176, -0.00095413, -0.00097608, -0.00099758, + -0.00101862, -0.00103918, -0.00105924, -0.00107879, + -0.00109783, -0.00111635, -0.00113434, -0.00115181, + -0.00116873, -0.00118510, -0.00120091, -0.00121615, + -0.00123082, -0.00124490, -0.00125838, -0.00127125, + -0.00128350, -0.00129511, -0.00130610, -0.00131643, + -0.00132610, -0.00133509, -0.00134334, -0.00135069, + -0.00135711, -0.00136272, -0.00136768, -0.00137225, + -0.00137649, -0.00138042, -0.00138404, -0.00138737, + -0.00139041, -0.00139317, -0.00139565, -0.00139785, + -0.00139976, -0.00140137, -0.00140267, -0.00140366, + -0.00140432, -0.00140464, -0.00140461, -0.00140423, + -0.00140347, -0.00140235, -0.00140084, -0.00139894, + -0.00139664, -0.00139388, -0.00139065, -0.00138694, + -0.00138278, -0.00137818, -0.00137317, -0.00136772, + -0.00136185, -0.00135556, -0.00134884, -0.00134170, + -0.00133415, -0.00132619, -0.00131784, -0.00130908, + -0.00129991, -0.00129031, -0.00128031, -0.00126990, + -0.00125912, -0.00124797, -0.00123645, -0.00122458, + -0.00121233, -0.00119972, -0.00118676, -0.00117347, + -0.00115988, -0.00114605, -0.00113200, -0.00111778, + -0.00110343, -0.00108898, -0.00107448, -0.00105995, +}; + +const DECLARE_ALIGNED(32, int, ff_aac_eld_window_480_fixed)[1800] = { + 0x00109442, 0x00482797, 0x0075bf2a, 0x00afa864, + 0x00ef2aa5, 0x01335b36, 0x017a4df0, 0x01c2cffe, + 0x020bfb4c, 0x0254fd74, 0x029d557c, 0x02e50574, + 0x032c41a8, 0x03732c08, 0x03b9cb88, 0x040032e8, + 0x044686f0, 0x048cd578, 0x04d30738, 0x05190500, + 0x055ec210, 0x05a44750, 0x05e9aeb8, 0x062f0c80, + 0x067477a0, 0x06ba1ac0, 0x07001998, 0x074680e0, + 0x078d5ec0, 0x07d4d038, 0x081cf8f0, 0x0865f8b0, + 0x08afe0e0, 0x08fab150, 0x09466cd0, 0x09931910, + 0x09e0adb0, 0x0a2f1640, 0x0a7e43f0, 0x0ace2960, + 0x0b1eb180, 0x0b6fc4b0, 0x0bc15050, 0x0c134710, + 0x0c65a420, 0x0cb86340, 0x0d0b7df0, 0x0d5ef450, + 0x0db2cb60, 0x0e070180, 0x0e5b91f0, 0x0eb07f20, + 0x0f05d0a0, 0x0f5b8920, 0x0fb1a950, 0x10082e40, + 0x105f1400, 0x10b65820, 0x110df780, 0x1165f120, + 0x11be43e0, 0x1216eea0, 0x126feac0, 0x12c92b00, + 0x1322a620, 0x137c55c0, 0x13d61ae0, 0x142fc940, + 0x148949e0, 0x14e28da0, 0x153b9a80, 0x15947640, + 0x15ed1840, 0x16458660, 0x169deb20, 0x16f663c0, + 0x174ef8c0, 0x17a7a120, 0x180041c0, 0x1858d000, + 0x18b14940, 0x1909a140, 0x1961c820, 0x19b9b620, + 0x1a116480, 0x1a68c1a0, 0x1abfbd00, 0x1b164f60, + 0x1b6c7580, 0x1bc23120, 0x1c1780e0, 0x1c6c5d00, + 0x1cc0dbe0, 0x1d1532a0, 0x1d697660, 0x1dbdac20, + 0x1e11b280, 0x1e655b80, 0x1eb89e80, 0x1f0b7720, + 0x1f5dd680, 0x1fafaec0, 0x2000fb00, 0x2051c340, + 0x20a22ac0, 0x20f24580, 0x214213c0, 0x21919140, + 0x21e0b300, 0x222f7580, 0x227dd900, 0x22cbd880, + 0x23196ec0, 0x23669b00, 0x23b35d80, 0x23ffb6c0, + 0x244ba7c0, 0x249731c0, 0x24e25700, 0x252d1940, + 0x2594ae40, 0x25deea40, 0x2628bd00, 0x26722680, + 0x26bb2740, 0x2703bf40, 0x274beec0, 0x2793b600, + 0x27db1500, 0x28220c00, 0x28689b80, 0x28aec4c0, + 0x28f48800, 0x2939e680, 0x297ee080, 0x29c37600, + 0x2a07a740, 0x2a4b74c0, 0x2a8ede80, 0x2ad1e500, + 0x2b148880, 0x2b56c940, 0x2b98a740, 0x2bda2240, + 0x2c1b3a80, 0x2c5bef80, 0x2c9c4100, 0x2cdc2e80, + 0x2d1bb800, 0x2d5adc80, 0x2d999b80, 0x2dd7f500, + 0x2e15e800, 0x2e537400, 0x2e9098c0, 0x2ecd5540, + 0x2f09a900, 0x2f4592c0, 0x2f811140, 0x2fbc2340, + 0x2ff6c7c0, 0x3030fe80, 0x306ac6c0, 0x30a41f80, + 0x30dd07c0, 0x31157dc0, 0x314d7fc0, 0x31850c80, + 0x31bc22c0, 0x31f2c1c0, 0x3228e840, 0x325e9540, + 0x3293c7c0, 0x32c87e40, 0x32fcb800, 0x33307340, + 0x3363aec0, 0x33966940, 0x33c8a140, 0x33fa5580, + 0x342b84c0, 0x345c2dc0, 0x348c4f80, 0x34bbe900, + 0x34eaf9c0, 0x35198080, 0x35477d00, 0x3574ee40, + 0x35a1d340, 0x35ce2bc0, 0x35f9f6c0, 0x36253380, + 0x364fe180, 0x367a0040, 0x36a38f80, 0x36cc8ec0, + 0x36f4fe80, 0x371cde80, 0x37442e80, 0x376aef00, + 0x37912000, 0x37b6c200, 0x37dbd600, 0x38005d00, + 0x38245840, 0x3847c880, 0x386aaf80, 0x388d0e80, + 0x38aee700, 0x38d03bc0, 0x38f11000, 0x39116700, + 0x39314440, 0x3950ab00, 0x396f9e80, 0x398e22c0, + 0x39ac3c40, 0x39c9f280, 0x39e74cc0, 0x3a045280, + 0x3a210b40, 0x3a3d7ec0, 0x3a59b480, 0x3a75b480, + 0x3a918900, 0x3aad3cc0, 0x3ac8db00, 0x3ae46bc0, + 0x3afff080, 0x3b1b6840, 0x3b36d2c0, 0x3b521980, + 0x3b6d0780, 0x3b876400, 0x3ba0f4c0, 0x3bb96740, + 0x3bd03dc0, 0x3be56580, 0x3bf6dec0, 0x3c0c6140, + 0x3c15a9c0, 0x3c1a5780, 0x3c1fd0c0, 0x3c25edc0, + 0x3c2c78c0, 0x3c333880, 0x3c39f3c0, 0x3c409100, + 0x3c471d00, 0x3c4da780, 0x3c543f40, 0x3c5ae880, + 0x3c619f00, 0x3c685f00, 0x3c6f25c0, 0x3c75f280, + 0x3c7cc6c0, 0x3c83a2c0, 0x3c8a87c0, 0x3c9175c0, + 0x3c986d00, 0x3c9f6e00, 0x3ca67880, 0x3cad8c40, + 0x3cb4a980, 0x3cbbd000, 0x3cc2ffc0, 0x3cca3940, + 0x3cd17d40, 0x3cd8cb80, 0x3ce02480, 0x3ce78740, + 0x3ceef3c0, 0x3cf66a00, 0x3cfdea00, 0x3d0574c0, + 0x3d0d0a40, 0x3d14ab40, 0x3d1c5700, 0x3d240d00, + 0x3d2bcd40, 0x3d3397c0, 0x3d3b6cc0, 0x3d434d00, + 0x3d4b38c0, 0x3d532fc0, 0x3d5b3180, 0x3d633dc0, + 0x3d6b53c0, 0x3d737400, 0x3d7b9f00, 0x3d83d540, + 0x3d8c1680, 0x3d946200, 0x3d9cb780, 0x3da51680, + 0x3dad7f00, 0x3db5f140, 0x3dbe6dc0, 0x3dc6f480, + 0x3dcf8540, 0x3dd81fc0, 0x3de0c300, 0x3de96ec0, + 0x3df22340, 0x3dfae0c0, 0x3e03a800, 0x3e0c7840, + 0x3e155180, 0x3e1e32c0, 0x3e271bc0, 0x3e300c00, + 0x3e390400, 0x3e420400, 0x3e4b0c40, 0x3e541c80, + 0x3e5d33c0, 0x3e6651c0, 0x3e6f7580, 0x3e789fc0, + 0x3e81d080, 0x3e8b0880, 0x3e944700, 0x3e9d8c00, + 0x3ea6d680, 0x3eb02600, 0x3eb97a80, 0x3ec2d400, + 0x3ecc3340, 0x3ed59880, 0x3edf0300, 0x3ee87280, + 0x3ef1e600, 0x3efb5d40, 0x3f04d880, 0x3f0e5840, + 0x3f17dcc0, 0x3f216600, 0x3f2af340, 0x3f348440, + 0x3f3e1840, 0x3f47af40, 0x3f514a00, 0x3f5ae840, + 0x3f648b00, 0x3f6e3140, 0x3f77db00, 0x3f818740, + 0x3f8b3600, 0x3f94e780, 0x3f9e9c40, 0x3fa85480, + 0x3fb21080, 0x3fbbcfc0, 0x3fc59200, 0x3fcf56c0, + 0x3fd91dc0, 0x3fe2e640, 0x3fecb040, 0x3ff67b40, + 0x40098600, 0x40135580, 0x401d2700, 0x4026fa00, + 0x4030ce80, 0x403aa380, 0x40447900, 0x404e4f00, + 0x40582400, 0x4061f900, 0x406bcd00, 0x4075a080, + 0x407f7480, 0x40894900, 0x40931e00, 0x409cf280, + 0x40a6c600, 0x40b09800, 0x40ba6980, 0x40c43a80, + 0x40ce0b00, 0x40d7db00, 0x40e1ab00, 0x40eb7980, + 0x40f54600, 0x40ff1080, 0x4108d980, 0x4112a100, + 0x411c6800, 0x41262d80, 0x412ff080, 0x4139b180, + 0x41436e80, 0x414d2980, 0x4156e100, 0x41609700, + 0x416a4a80, 0x4173fb00, 0x417da800, 0x41875000, + 0x4190f400, 0x419a9400, 0x41a43000, 0x41adc880, + 0x41b75d00, 0x41c0ec80, 0x41ca7700, 0x41d3fb00, + 0x41dd7980, 0x41e6f280, 0x41f06600, 0x41f9d480, + 0x42033d00, 0x420c9f00, 0x4215f980, 0x421f4d00, + 0x42289900, 0x4231de80, 0x423b1d00, 0x42445500, + 0x424d8500, 0x4256ad00, 0x425fcc80, 0x4268e380, + 0x4271f200, 0x427af900, 0x4283f880, 0x428cef80, + 0x4295de00, 0x429ec280, 0x42a79d80, 0x42b06f00, + 0x42b93800, 0x42c1f800, 0x42caaf80, 0x42d35d80, + 0x42dc0100, 0x42e49b00, 0x42ed2a80, 0x42f5b080, + 0x42fe2d80, 0x4306a180, 0x430f0c80, 0x43176d80, + 0x431fc480, 0x43281100, 0x43305400, 0x43388e80, + 0x4340c000, 0x4348e900, 0x43510900, 0x43591f00, + 0x43612b80, 0x43692f00, 0x43712900, 0x43791a80, + 0x43810380, 0x4388e400, 0x4390bc00, 0x43988b00, + 0x43a05180, 0x43a80f00, 0x43afc480, 0x43b77180, + 0x43bf1780, 0x43c6b700, 0x43ce5100, 0x43d5e580, + 0x43dd7100, 0x43e4ef80, 0x43ec5b80, 0x43f3ba80, + 0x43fb1c80, 0x44029400, 0x440a2e80, 0x4411d080, + 0x44193800, 0x44202480, 0x44265880, 0x442ba780, + 0x442d8680, 0x4428a500, 0x44241380, 0x441ccb00, + 0x44140100, 0x440a1200, 0x43ff7280, 0x43f46980, + 0x43e93200, 0x43ddff00, 0x43d2dc80, 0x43c7ac00, + 0x43bc4900, 0x43b09400, 0x43a47d80, 0x4397fd80, + 0x438b0780, 0x437d9b80, 0x436fd380, 0x4361cd80, + 0x4353a800, 0x43457500, 0x43373c80, 0x43290500, + 0x431ad400, 0x430ca280, 0x42fe6000, 0x42f00080, + 0x42e17380, 0x42d29e00, 0x42c35d80, 0x42b39200, + 0x42a32080, 0x4291fc00, 0x42801900, 0x426d6d80, + 0x4259f680, 0x4245bd00, 0x4230ca80, 0x421b2900, + 0x4204e800, 0x41ee1d00, 0x41d6dd80, 0x41bf3c80, + 0x41a74680, 0x418f0680, 0x41768800, 0x415dd100, + 0x4144e400, 0x412bbf80, 0x41126400, 0x40f8cc00, + 0x40deea00, 0x40c4b100, 0x40aa1400, 0x408f0800, + 0x40738380, 0x40577d80, 0x403aeb80, 0x401dc180, + 0x3ffff240, 0x3fe170c0, 0x3fc232c0, 0x3fa23680, + 0x3f817c40, 0x3f6002c0, 0x3f3ddec0, 0x3f1b4180, + 0x3ef85d40, 0x3ed56340, 0x3eb27240, 0x3e8f9c40, + 0x3e6cf400, 0x3e4a81c0, 0x3e282140, 0x3e059980, + 0x3de2b280, 0x3dbf4100, 0x3d9b3640, 0x3d768b00, + 0x3d513640, 0x3d2b3840, 0x3d049b80, 0x3cdd6b40, + 0x3cb5b400, 0x3c8d8f40, 0x3c652080, 0x3c3c8c40, + 0x3c13f480, 0x3beb7580, 0x3bc327c0, 0x3b9b2680, + 0x3b737000, 0x3b4bc580, 0x3b23d740, 0x3afb5640, + 0x3ad21c40, 0x3aa83780, 0x3a7dbc40, 0x3a52bf80, + 0x3a276600, 0x39fbe0c0, 0x39d06140, 0x39a50ec0, + 0x3979e300, 0x394ebf40, 0x392386c0, 0x38f82280, + 0x38cc89c0, 0x38a0b7c0, 0x3874a740, 0x38485840, + 0x381bd1c0, 0x37ef1b40, 0x37c23cc0, 0x37953dc0, + 0x376825c0, 0x373afc80, 0x370dc980, 0x36e09440, + 0x36b41dc0, 0x36862100, 0x3657e480, 0x36297240, + 0x35fad380, 0x35cc1200, 0x359d36c0, 0x356e4b40, + 0x353f5880, 0x35106780, 0x34e17780, 0x34b28240, + 0x34838040, 0x345466c0, 0x34251940, 0x33f57280, + 0x33c54bc0, 0x33949840, 0x33638380, 0x33324980, + 0x33012500, 0x32d04480, 0x329fc7c0, 0x326fcbc0, + 0x324068c0, 0x32116fc0, 0x31e27600, 0x31b30fc0, + 0x3182e300, 0x3151e240, 0x312029c0, 0x30edd080, + 0x30baf700, 0x3087cd00, 0x30548600, 0x30215680, + 0x2fee65c0, 0x2fbbca40, 0x2f899980, 0x2f57e6c0, + 0x2f26b540, 0x2ef5f980, 0x2ec5aa00, 0x2e95afc0, + 0x2e65c180, 0x2e357b40, 0x2e047840, 0x2dd27380, + 0x2d9f6c40, 0x2d6b7780, 0x2d36a6c0, 0x2d012940, + 0x2ccb5680, 0x2c958a00, 0x2c601b80, 0x2c2b3640, + 0x2bf6dfc0, 0x2bc31ec0, 0x2b8ff500, 0x2b5d5540, + 0x2b2b2a00, 0x2af95e80, 0x2ac7dd80, 0x2a968f80, + 0x2a655d40, 0x2a342f00, 0x2a02e8c0, 0x29d16700, + 0x299f8640, 0x296d2380, 0x293a2740, 0x29068400, + 0x28d22b40, 0x289d1540, 0x28675280, 0x28310180, + 0x27fa3f00, 0x27c32f80, 0x278c08c0, 0x275505c0, + 0x271e60c0, 0x26e84b00, 0x26b2e880, 0x267e5cc0, + 0x264ac940, 0x26183a40, 0x25e6aa80, 0x25b615c0, + 0x25866b80, 0x25576b40, 0x2528ba00, 0x24f9ffc0, + 0x24cadfc0, 0x249af540, 0x2469da80, 0x24372780, + 0x2402b800, 0x23ccbfc0, 0x23957cc0, 0x235d3140, + 0x23245200, 0x22eb8000, 0x22b35cc0, 0x227c7940, + 0x22471d40, 0x22136840, 0x21e18240, 0x21b15d80, + 0x21827dc0, 0x21544600, 0x21261b00, 0x20f78600, + 0x20c83e00, 0x20980000, 0x20668e00, 0x2033f300, + 0x20007400, 0x1fcc64e0, 0x1f97d120, 0x1f642320, + 0x1f2f49e0, 0x1efaa840, 0x1ec73580, 0x1e94d880, + 0x1e636120, 0x1e32a160, 0x1e025ba0, 0x1dd24300, + 0x1da20e60, 0x1d717940, 0x1d407560, 0x1d0f2040, + 0x1cdd95c0, 0x1cabf500, 0x1c7a6940, 0x1c492340, + 0x1c185680, 0x1be818c0, 0x1bb83f60, 0x1b888d20, + 0x1b58c640, 0x1b28c240, 0x1af871e0, 0x1ac7c960, + 0x1a96bf00, 0x1a656b60, 0x1a340360, 0x1a02bd20, + 0x19d1c6c0, 0x19a12f40, 0x1970f480, 0x19411640, + 0x19119000, 0x18e255a0, 0x18b358a0, 0x18848b20, + 0x1855e040, 0x18274e00, 0x17f8c9e0, 0x17ca4a80, + 0x179bce40, 0x176d5a60, 0x173ef400, 0x17109fe0, + 0x16e25f60, 0x16b43240, 0x16861880, 0x16581220, + 0x162a20c0, 0x15fc4620, 0x15ce8420, 0x15a0dca0, + 0x157351c0, 0x1545e580, 0x151899a0, 0x14eb6ec0, + 0x14be63a0, 0x14917a00, 0x14649ae0, 0x14377060, + 0x1409d0c0, 0x13dbbb20, 0x13ad58e0, 0x137f0160, + 0x1350cc80, 0x1322b8c0, 0x12f4ca60, 0x12c704e0, + 0x129968a0, 0x126bf5c0, 0x123eade0, 0x12119300, + 0x11e4a660, 0x11b7e860, 0x118b5940, 0x115ef8a0, + 0x1132c600, 0x1106c1a0, 0x10daecc0, 0x10af4900, + 0x1083d7a0, 0x10589c00, 0x102d9a00, 0x1002d1e0, + 0x0fd842c0, 0x0fadde80, 0x0f839a50, 0x0f597700, + 0x0f2f76e0, 0x0f05a170, 0x0edbf9c0, 0x0eb27f30, + 0x0e8930d0, 0x0e600d70, 0x0e371550, 0x0e0e4950, + 0x0de5ab50, 0x0dbd3d20, 0x0d94fe10, 0x0d6cecb0, + 0x0d450220, 0x0d1d38f0, 0x0cf59130, 0x0cce0c30, + 0x0ca6af10, 0x0c7f7b80, 0x0c587010, 0x0c318960, + 0x0c0ac200, 0x0be418d0, 0x0bbd8da0, 0x0b9724e0, + 0x0b70e6c0, 0x0b4ad970, 0x0b2502f0, 0x0aff6930, + 0x0ada1250, 0x0ab50430, 0x0a9044d0, 0x0a6bda30, + 0x0a3bedf0, 0x0a18be40, 0x09f5e530, 0x09d35cf0, + 0x09b11ff0, 0x098f2890, 0x096d7120, 0x094bf400, + 0x092aab80, 0x09099240, 0x08e8a620, 0x08c7e850, + 0x08a75990, 0x0886fae0, 0x0866ccf0, 0x0846d070, + 0x08270610, 0x08076e70, 0x07e80ac8, 0x07c8dc60, + 0x07a9e440, 0x078b2348, 0x076c99d0, 0x074e4818, + 0x07302e50, 0x07124d18, 0x06f4a530, 0x06d73778, + 0x06ba0488, 0x069d0c88, 0x06804f68, 0x0663cce0, + 0x06478528, 0x062b78a0, 0x060fa7e8, 0x05f413b8, + 0x05d8bc38, 0x05bda128, 0x05a2c258, 0x05881f60, + 0x056db888, 0x05538e60, 0x0539a170, 0x051ff218, + 0x05068040, 0x04ed4b90, 0x04d45398, 0x04bb9820, + 0x04a31988, 0x048ad860, 0x0472d528, 0x045b0ff0, + 0x04438860, 0x042c3de8, 0x04153040, 0x03fe5f4c, + 0x03e7cb98, 0x03d17580, 0x03bb5d64, 0x03a582e8, + 0x038fe588, 0x037a8494, 0x03655fcc, 0x03507768, + 0x033bcbb4, 0x03275d28, 0x03132bc0, 0x02ff370c, + 0x02eb7e94, 0x02d801e8, 0x02c4c11c, 0x02b1bcbc, + 0x029ef578, 0x028c6ba8, 0x027a1f20, 0x02680f54, + 0x02563bac, 0x0244a3c8, 0x023347a0, 0x02222730, + 0x0211429c, 0x02009938, 0x01f02974, 0x01dff1ae, + 0x01cff058, 0x01c024c8, 0x01b08ef4, 0x01a12eda, + 0x019204b0, 0x01831138, 0x01745588, 0x0165d2c2, + 0x01578a96, 0x01497ffc, 0x013bb670, 0x012e3160, + 0x0120f146, 0x0113f27c, 0x0107310c, 0x00faa909, + 0x00ee57a1, 0x00e23b09, 0x00d6515b, 0x00ca9977, + 0x00bf1509, 0x00b3c74d, 0x00a8b388, 0x009ddb3d, + 0x00933bf2, 0x0088d22c, 0x007e9a70, 0x0074935a, + 0x006abe70, 0x00611d5c, 0x0057b1f8, 0x004e7e73, + 0x0045859b, 0x003cca96, 0x00344f32, 0x002c1074, + 0x00240873, 0x001c31ba, 0x0014863f, 0x000cfe8b, + 0x00059307, 0xfffe3b9a, 0xfff6f718, 0xffefcd4d, + 0xffe8c6f4, 0xffe1ed10, 0xffdb4c57, 0xffd4f484, + 0xffcef5dc, 0xffc95d0c, 0xffc4284e, 0xffbf4e14, + 0xffbac5ae, 0xffb68360, 0xffb27548, 0xffae87be, + 0xffaaa733, 0xffa6c67e, 0xffa2e141, 0xff9ef40c, + 0xff9afc25, 0xff970058, 0xff930f7c, 0xff8f3857, + 0xff8b8900, 0xff880bfe, 0xff84c9ea, 0xff81cbbd, + 0xff7f17ad, 0xff7cadc6, 0xff7a8c4e, 0xff78b1cd, + 0xff7719f3, 0xff75bd06, 0xff7492a4, 0xff7392bf, + 0xff72b600, 0xff71f5c6, 0xff714b72, 0xff70b0ed, + 0xff702232, 0xff6f9c90, 0xff6f1cee, 0xff6ea21f, + 0xff6e2e9c, 0xff6dc617, 0xff6d6c09, 0xff6d2425, + 0xff6cf267, 0xff6cdaca, 0xff6ce155, 0xff6d0983, + 0xff6d56bb, 0xff6dcc4c, 0xff6e6cd0, 0xff6f3832, + 0xff702cc4, 0xff71492e, 0xff728ae2, 0xff73ed63, + 0xff756b7c, 0xff77001c, 0xff78a5d9, 0xff7a5693, + 0xff7c0c40, 0xff7dc141, 0xff7f74aa, 0xff81298b, + 0xff82e2de, 0xff84a3de, 0xff8670bd, 0xff884e42, + 0xff8a410c, 0xff8c4c7f, 0xff8e70fc, 0xff90ae18, + 0xff93037e, 0xff956f12, 0xff97ec86, 0xff9a7724, + 0xff9d0a9d, 0xff9fa3ea, 0xffa2417e, 0xffa4e1ac, + 0xffa78332, 0xffaa265a, 0xffaccc26, 0xffaf758e, + 0xffb223d4, 0xffb4d906, 0xffb79726, 0xffba604e, + 0xffbd349e, 0xffc011a8, 0xffc2f4d2, 0xffc5db82, + 0xffc8c45f, 0xffcbaed5, 0xffce9a6d, 0xffd186c6, + 0xffd473aa, 0xffd760e5, 0xffda4e55, 0xffdd3bd0, + 0xffe0292b, 0xffe31645, 0xffe602ff, 0xffe8eef7, + 0xffebd978, 0xffeec1bf, 0xfff1a72c, 0xfff488fe, + 0xfff76689, 0xfffa3f2c, 0xfffd1245, 0xffffdf33, + 0x000020ac, 0x0002e66f, 0x0005a937, 0x00086839, + 0x000b22b3, 0x000dd7da, 0x001086ec, 0x00132f3c, + 0x0015d001, 0x00186897, 0x001af849, 0x001d7eb6, + 0x001ffbbe, 0x00226f41, 0x0024d8e8, 0x00273874, + 0x00298d82, 0x002bd7aa, 0x002e16d4, 0x00304af6, + 0x00327406, 0x00349203, 0x0036a416, 0x0038a893, + 0x003a9da0, 0x003c8170, 0x003e53b8, 0x0040159a, + 0x0041c816, 0x00436c92, 0x0045042c, 0x00468ff2, + 0x00481106, 0x004987fe, 0x004af466, 0x004c5599, + 0x004daae4, 0x004ef28c, 0x005029c4, 0x00514d9a, + 0x00525b57, 0x005351f7, 0x00543190, 0x0054fa43, + 0x0055ac2f, 0x00564938, 0x0056d3f7, 0x00574f3c, + 0x0057bdd7, 0x00582260, 0x00587f28, 0x0058d6b1, + 0x0059293c, 0x0059741a, 0x0059b472, 0x0059e73c, + 0x005a0976, 0x005a1870, 0x005a116e, 0x0059f224, + 0x0059b964, 0x005966ce, 0x0058f9e2, 0x005872e8, + 0x0057d407, 0x00571f82, 0x005657b0, 0x00557ecd, + 0x00549731, 0x0053a34b, 0x0052a56a, 0x00519fc6, + 0x00509482, 0x004f85a4, 0x004e74ee, 0x004d6214, + 0x004c4bd3, 0x004b314c, 0x004a1110, 0x0048e8c8, + 0x0047b5f7, 0x00467626, 0x00452690, 0x0043c405, + 0x00424b7f, 0x0040ba04, 0x003f0e53, 0x003d488b, + 0x003b688c, 0x00396eb6, 0x00375dfb, 0x00353aaa, + 0x003308ac, 0x0030ccb1, 0x002e8cf1, 0x002c4fd5, + 0x002a1be8, 0x0027f486, 0x0025d90d, 0x0023c852, + 0x0021c13b, 0x001fbf23, 0x001dbafc, 0x001badc6, + 0x00199136, 0x00176150, 0x00151b86, 0x0012bcd1, + 0x001044d1, 0x000db8d0, 0x000b1f43, 0x00087e89, + 0x0005dbe2, 0x00033b1e, 0x00009fee, 0xfffe0d82, + 0xfffb83cf, 0xfff90047, 0xfff6805a, 0xfff4019a, + 0xfff18203, 0xffeeffb2, 0xffec78ba, 0xffe9ec4d, + 0xffe75b4e, 0xffe4c71f, 0xffe23138, 0xffdf9ae6, + 0xffdd0574, 0xffda723c, 0xffd7e24a, 0xffd55567, + 0xffd2cabe, 0xffd04161, 0xffcdb890, 0xffcb306a, + 0xffc8a95c, 0xffc62406, 0xffc3a140, 0xffc12188, + 0xffbea542, 0xffbc2cc2, 0xffb9b7d2, 0xffb745f2, + 0xffb4d6ac, 0xffb268fe, 0xffaffc72, 0xffad90e8, + 0xffab263e, 0xffa8bcb8, 0xffa6547e, 0xffa3ed7b, + 0xffa187ba, 0xff9f2351, 0xff9cc055, 0xff9a5ebc, + 0xff97fe84, 0xff959f84, 0xff934146, 0xff90e37d, + 0xff8e858a, 0xff8c26c0, 0xff89c69e, 0xff876483, + 0xff84ffe4, 0xff82982b, 0xff802cb6, 0xff7dbccf, + 0xff7b47b4, 0xff78ccd0, 0xff764b6c, 0xff73c2db, + 0xff713227, 0xff6e9864, 0xff6bf470, 0xff694553, + 0xff668a0d, 0xff63c1a6, 0xff60ec34, 0xff5e0e9e, + 0xff5b30d3, 0xff585b8c, 0xff5595c9, 0xff52e1da, + 0xff5040a0, 0xff4db31c, 0xff4b3a3b, 0xff48d67e, + 0xff468850, 0xff445011, 0xff422ded, 0xff4021f9, + 0xff3e2c56, 0xff3c4cf8, 0xff3a83df, 0xff38d0ec, + 0xff3733c9, 0xff35ac14, 0xff343963, 0xff32db09, + 0xff319066, 0xff305898, 0xff2f323d, 0xff2e1bb2, + 0xff2d1369, 0xff2c18f8, 0xff2b2d2a, 0xff2a50e1, + 0xff2984f4, 0xff28c978, 0xff281e01, 0xff278245, + 0xff26f5c3, 0xff26785a, 0xff2609bf, 0xff25a9c8, + 0xff255814, 0xff2513f6, 0xff24dcc4, 0xff24b1a6, + 0xff2492b1, 0xff248093, 0xff247c0b, 0xff2485c6, + 0xff249daf, 0xff24c359, 0xff24f639, 0xff253605, + 0xff258312, 0xff25ddd5, 0xff2646e7, 0xff26be25, + 0xff274264, 0xff27d1f6, 0xff286b19, 0xff290c13, + 0xff29b30d, 0xff2a5e38, 0xff2b0bbd, 0xff2bb9a2, + 0xff29a9d2, 0xff2a53dc, 0xff2b0a5a, 0xff2bcd43, + 0xff2c9c76, 0xff2d7808, 0xff2e5ffa, 0xff2f544c, + 0xff305528, 0xff316299, 0xff327ce0, 0xff33a432, + 0xff34d8ba, 0xff361a8e, 0xff3768f8, 0xff38c2f5, + 0xff3a2784, 0xff3b9623, 0xff3d0ef4, 0xff3e9277, + 0xff4020ed, 0xff41ba14, 0xff435ccc, 0xff4507fd, + 0xff46ba84, 0xff4873ac, 0xff4a32ea, 0xff4bf7bb, + 0xff4dc17f, 0xff4f8fa0, 0xff516167, 0xff53361d, + 0xff550d79, 0xff56e7ee, 0xff58c5ff, 0xff5aa84d, + 0xff5c8e41, 0xff5e75e2, 0xff605d4d, 0xff6242b6, + 0xff6424b8, 0xff66023d, 0xff67da44, 0xff69abd6, + 0xff6b7646, 0xff6d38e8, 0xff6ef348, 0xff70a4ce, + 0xff724d0f, 0xff73eb95, 0xff757fff, 0xff770a2d, + 0xff788a20, 0xff79fff6, 0xff7b6be7, 0xff7cce52, + 0xff7e27e4, 0xff7f78fc, 0xff80c38a, 0xff820e98, + 0xff836378, 0xff84caaa, 0xff864990, 0xff87dff4, + 0xff898c30, 0xff8b4cda, 0xff8d207a, 0xff8f05cc, + 0xff90fb9b, 0xff930098, 0xff95138e, 0xff97332d, + 0xff995e2a, 0xff9b934e, 0xff9dd18c, 0xffa017e3, + 0xffa26550, 0xffa4b8e7, 0xffa711a8, 0xffa96eae, + 0xffabcefc, 0xffae31cc, 0xffb09680, 0xffb2fc82, + 0xffb5635a, 0xffb7ca52, 0xffba30a8, 0xffbc95a8, + 0xffbef8a4, 0xffc158d0, 0xffc3b557, 0xffc60d6b, + 0xffc86041, 0xffcaacb7, 0xffccf1cb, 0xffcf2e5c, + 0xffd161e8, 0xffd38c8f, 0xffd5ae88, 0xffd7c808, + 0xffd9d925, 0xffdbe1c8, 0xffdde1f3, 0xffdfd964, + 0xffe1c79b, 0xffe3abcc, 0xffe5852a, 0xffe75341, + 0xffe9162f, 0xffeace55, 0xffec7c15, 0xffee1f63, + 0xffefb7e9, 0xfff1453d, 0xfff2c6fd, 0xfff43ca8, + 0xfff5a5d4, 0xfff701ea, 0xfff850b4, 0xfff99288, + 0xfffac853, 0xfffbf2d5, 0xfffd12e6, 0xfffe2991, + 0xffff37e4, 0x00003eea, 0x00013ec4, 0x00023646, + 0x0003244d, 0x00040797, 0x0004de8c, 0x0005a734, + 0x00065fab, 0x0007068f, 0x00079c82, 0x000822fa, + 0x00089b70, 0x000907a6, 0x00096a01, 0x0009c506, + 0x000a1b37, 0x000a6e18, 0x000abe1f, 0x000b0bac, + 0x000b5701, 0x000b9f3b, 0x000be2c2, 0x000c1fff, + 0x000c5599, 0x000c829a, 0x000ca661, 0x000cc058, + 0x000cd028, 0x000cd63d, 0x000cd317, 0x000cc739, + 0x000cb36d, 0x000c98c0, 0x000c7833, 0x000c52df, + 0x000c2984, 0x000bfcf9, 0x000bcdea, 0x000b9cf7, + 0x000b6a97, 0x000b3700, 0x000b029d, 0x000acd79, + 0x000a977e, 0x000a6076, 0x000a2838, 0x0009eea1, + 0x0009b37d, 0x000976c2, 0x0009384e, 0x0008f816, + 0x0008b612, 0x0008724a, 0x00082cd5, 0x0007e5e8, + 0x00079dce, 0x000754de, 0x00070b62, 0x0006c1c6, + 0x0006786a, 0x00062fba, 0x0005e801, 0x0005a1a0, + 0x00055ce1, 0x000519fb, 0x0004d8f8, 0x000499b8, + 0x00045c30, 0x00042040, 0x0003e5c8, 0x0003acb3, + 0x000374df, 0x00033e59, 0x00030934, 0x0002d57d, + 0x0002a348, 0x000272b6, 0x000243f2, 0x00021711, + 0x0001ec3e, 0x0001c37a, 0x00019cc3, 0x00017830, + 0x000155a0, 0x00013514, 0x0001168b, 0x0000f9e6, + 0x0000df23, 0x0000c62e, 0x0000aef2, 0x00009978, + 0x000085a1, 0x0000736d, 0x000062dc, 0x000053d8, + 0x0000466c, 0x00003a62, 0x00002fd1, 0x00002681, + 0x00001e73, 0x00001792, 0x000011c9, 0x00000cf6, + 0x0000091a, 0x000005ff, 0x000003b1, 0x00000203, + 0x000000d7, 0x0000002b, 0xffffffd5, 0xffffffc0, + 0xffffffd5, 0x00000000, 0x00000015, 0x00000000, + 0x00000000, 0x00000015, 0x00000000, 0xffffffd5, + 0xffffffca, 0xffffffd5, 0x0000002b, 0x000000cc, + 0x000001e3, 0x0000037b, 0x0000059f, 0x0000086e, + 0x00000bf4, 0x0000103b, 0x00001564, 0x00001b6e, + 0x0000226f, 0x00002a68, 0x00003377, 0x00003d93, + 0x000048c5, 0x00005525, 0x000062a6, 0x00007155, + 0x0000812f, 0x00009237, 0x0000a455, 0x0000b7ab, + 0x0000cc18, 0x0000e1bd, 0x0000f878, 0x0001106c, + 0x00012981, 0x000143c2, 0x00015f30, 0x00017bb6, + 0x00019948, 0x0001b7e6, 0x0001d771, 0x0001f7bc, + 0x000218b4, 0x00023a42, 0x00025c3b, 0x00027ea0, + 0x0002a150, 0x0002c440, 0x0002e771, 0x00030aed, + 0x00032eb4, 0x000352db, 0x00037759, 0x00039c4c, + 0x0003c1ac, 0x0003e74b, 0x00040d00, 0x0004329f, + 0x000457de, 0x00047c9c, 0x0004a083, 0x0004c35e, + 0x0004e502, 0x00050543, 0x000523ec, 0x000540e7, + 0x00055c2b, 0x000575c0, 0x00058da9, 0x0005a3e4, + 0x0005b886, 0x0005cbb1, 0x0005dd65, 0x0005edcb, + 0x0005fcfa, 0x00060afc, 0x00061808, 0x000623fc, + 0x00062ec3, 0x00063849, 0x0006404b, 0x000646ac, + 0x00064b13, 0x00064d37, 0x00064cd6, 0x0006497b, + 0x000642c5, 0x0006385e, 0x000629f0, 0x00061766, + 0x000600a0, 0x0005e57d, 0x0005c63e, 0x0005a322, + 0x00057c97, 0x00055306, 0x00052711, 0x0004f96f, + 0x0004caeb, 0x00049bfc, 0x00046c96, 0x00043cbb, + 0x00040c3f, 0x0003daab, 0x0003a734, 0x000370f9, + 0x0003372d, 0x0002f944, 0x0002b6d4, 0x00026f71, + 0x000222fb, 0x0001d212, 0x00017d84, 0x00012630, + 0x0000ccda, 0x00007200, 0x0000163b, 0xffffba15, + 0xffff5da3, 0xffff0091, 0xfffea293, 0xfffe4367, + 0xfffde2da, 0xfffd809f, 0xfffd1c81, 0xfffcb66a, + 0xfffc4e90, 0xfffbe53e, 0xfffb7aa0, 0xfffb0f0a, + 0xfffaa2c9, 0xfffa3612, 0xfff9c92f, 0xfff95c2d, + 0xfff8eef4, 0xfff8817c, 0xfff813c3, 0xfff7a5d4, + 0xfff737e5, 0xfff6ca17, 0xfff65c9e, 0xfff5efbc, + 0xfff58390, 0xfff51830, 0xfff4adbc, 0xfff44435, + 0xfff3db9a, 0xfff373d6, 0xfff30cfd, 0xfff2a71c, + 0xfff24248, 0xfff1de9f, 0xfff17c44, 0xfff11b56, + 0xfff0bbea, 0xfff05e17, 0xfff00206, 0xffefa7d9, + 0xffef4f99, 0xffeef95d, 0xffeea53a, 0xffee533a, + 0xffee035e, 0xffedb5b0, 0xffed6a3c, 0xffed20f5, + 0xffecd9fe, 0xffec9555, 0xffec5305, 0xffec1319, + 0xffebd591, 0xffeb9a83, 0xffeb61f9, 0xffeb2bfe, + 0xffeaf89c, 0xffeac7ea, 0xffea99d2, 0xffea6e7e, + 0xffea45ef, 0xffea203a, 0xffe9fda0, 0xffe9decc, + 0xffe9c3de, 0xffe9ac56, 0xffe99789, 0xffe9845e, + 0xffe97295, 0xffe96219, 0xffe952ea, 0xffe944f3, + 0xffe93833, 0xffe92c9f, 0xffe92238, 0xffe918fe, + 0xffe910fb, 0xffe90a3a, 0xffe904c6, 0xffe900a0, + 0xffe8fddb, 0xffe8fc83, 0xffe8fca4, 0xffe8fe3c, + 0xffe9016c, 0xffe9061e, 0xffe90c74, 0xffe9146c, + 0xffe91e11, 0xffe929a5, 0xffe93731, 0xffe946c0, + 0xffe95833, 0xffe96b7e, 0xffe98082, 0xffe9975e, + 0xffe9affd, 0xffe9ca5e, 0xffe9e68e, 0xffea0481, + 0xffea242b, 0xffea458e, 0xffea6894, 0xffea8d52, + 0xffeab3c8, 0xffeadc0c, 0xffeb05fe, 0xffeb31a7, + 0xffeb5ede, 0xffeb8da2, 0xffebbdf4, 0xffebefbd, + 0xffec231f, 0xffec5802, 0xffec8e5e, 0xffecc61c, + 0xffecff1c, 0xffed391e, 0xffed740c, 0xffedafb1, + 0xffedebe1, 0xffee287d, 0xffee654e, 0xffeea23f, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aactab.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aactab.h new file mode 100644 index 000000000..7cd812823 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aactab.h @@ -0,0 +1,186 @@ +/* + * AAC data declarations + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC data declarations + * @author Oded Shimon ( ods15 ods15 dyndns org ) + * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) + */ + +#ifndef AVCODEC_AACTAB_H +#define AVCODEC_AACTAB_H + +#include "libavutil/mem.h" +#include "aac.h" + +#include + +/* NOTE: + * Tables in this file are shared by the AAC decoders and encoder + */ + +extern float ff_aac_pow2sf_tab[428]; +extern float ff_aac_pow34sf_tab[428]; + +static inline void ff_aac_tableinit(void) +{ + int i; + + /* 2^(i/16) for 0 <= i <= 15 */ + static const float exp2_lut[] = { + 1.00000000000000000000, + 1.04427378242741384032, + 1.09050773266525765921, + 1.13878863475669165370, + 1.18920711500272106672, + 1.24185781207348404859, + 1.29683955465100966593, + 1.35425554693689272830, + 1.41421356237309504880, + 1.47682614593949931139, + 1.54221082540794082361, + 1.61049033194925430818, + 1.68179283050742908606, + 1.75625216037329948311, + 1.83400808640934246349, + 1.91520656139714729387, + }; + float t1 = 8.8817841970012523233890533447265625e-16; // 2^(-50) + float t2 = 3.63797880709171295166015625e-12; // 2^(-38) + int t1_inc_cur, t2_inc_cur; + int t1_inc_prev = 0; + int t2_inc_prev = 8; + + for (i = 0; i < 428; i++) { + t1_inc_cur = 4 * (i % 4); + t2_inc_cur = (8 + 3*i) % 16; + if (t1_inc_cur < t1_inc_prev) + t1 *= 2; + if (t2_inc_cur < t2_inc_prev) + t2 *= 2; + // A much more efficient and accurate way of doing: + // ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0); + // ff_aac_pow34sf_tab[i] = pow(ff_aac_pow2sf_tab[i], 3.0/4.0); + ff_aac_pow2sf_tab[i] = t1 * exp2_lut[t1_inc_cur]; + ff_aac_pow34sf_tab[i] = t2 * exp2_lut[t2_inc_cur]; + t1_inc_prev = t1_inc_cur; + t2_inc_prev = t2_inc_cur; + } +} + +/* @name ltp_coef + * Table of the LTP coefficients + */ +static const INTFLOAT ltp_coef[8] = { + Q30(0.570829), Q30(0.696616), Q30(0.813004), Q30(0.911304), + Q30(0.984900), Q30(1.067894), Q30(1.194601), Q30(1.369533), +}; + +/* @name tns_tmp2_map + * Tables of the tmp2[] arrays of LPC coefficients used for TNS. + * The suffix _M_N[] indicate the values of coef_compress and coef_res + * respectively. + * @{ + */ +static const INTFLOAT tns_tmp2_map_1_3[4] = { + Q31(0.00000000), Q31(-0.43388373), Q31(0.64278758), Q31(0.34202015), +}; + +static const INTFLOAT tns_tmp2_map_0_3[8] = { + Q31(0.00000000), Q31(-0.43388373), Q31(-0.78183150), Q31(-0.97492790), + Q31(0.98480773), Q31( 0.86602539), Q31( 0.64278758), Q31( 0.34202015), +}; + +static const INTFLOAT tns_tmp2_map_1_4[8] = { + Q31(0.00000000), Q31(-0.20791170), Q31(-0.40673664), Q31(-0.58778524), + Q31(0.67369562), Q31( 0.52643216), Q31( 0.36124167), Q31( 0.18374951), +}; + +static const INTFLOAT tns_tmp2_map_0_4[16] = { + Q31( 0.00000000), Q31(-0.20791170), Q31(-0.40673664), Q31(-0.58778524), + Q31(-0.74314481), Q31(-0.86602539), Q31(-0.95105654), Q31(-0.99452192), + Q31( 0.99573416), Q31( 0.96182561), Q31( 0.89516330), Q31( 0.79801720), + Q31( 0.67369562), Q31( 0.52643216), Q31( 0.36124167), Q31( 0.18374951), +}; + +static const INTFLOAT * const tns_tmp2_map[4] = { + tns_tmp2_map_0_3, + tns_tmp2_map_0_4, + tns_tmp2_map_1_3, + tns_tmp2_map_1_4 +}; +// @} + +/* @name window coefficients + * @{ + */ +DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024]; +DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128]; +DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_960)[960]; +DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_120)[120]; +DECLARE_ALIGNED(32, extern int, ff_aac_kbd_long_1024_fixed)[1024]; +DECLARE_ALIGNED(32, extern int, ff_aac_kbd_long_512_fixed)[512]; +DECLARE_ALIGNED(32, extern int, ff_aac_kbd_short_128_fixed)[128]; +DECLARE_ALIGNED(32, extern const float, ff_aac_eld_window_512)[1920]; +DECLARE_ALIGNED(32, extern const int, ff_aac_eld_window_512_fixed)[1920]; +DECLARE_ALIGNED(32, extern const float, ff_aac_eld_window_480)[1800]; +DECLARE_ALIGNED(32, extern const int, ff_aac_eld_window_480_fixed)[1800]; +// @} + +/* @name number of scalefactor window bands for long and short transform windows respectively + * @{ + */ +extern const uint8_t ff_aac_num_swb_1024[]; +extern const uint8_t ff_aac_num_swb_960 []; +extern const uint8_t ff_aac_num_swb_512 []; +extern const uint8_t ff_aac_num_swb_480 []; +extern const uint8_t ff_aac_num_swb_128 []; +extern const uint8_t ff_aac_num_swb_120 []; +// @} + +extern const uint8_t ff_aac_pred_sfb_max []; + +extern const uint32_t ff_aac_scalefactor_code[121]; +extern const uint8_t ff_aac_scalefactor_bits[121]; + +extern const uint16_t * const ff_aac_spectral_codes[11]; +extern const uint8_t * const ff_aac_spectral_bits [11]; +extern const uint16_t ff_aac_spectral_sizes[11]; + +extern const float *ff_aac_codebook_vectors[]; +extern const float *ff_aac_codebook_vector_vals[]; +extern const uint16_t *ff_aac_codebook_vector_idx[]; + +extern const uint16_t * const ff_swb_offset_1024[13]; +extern const uint16_t * const ff_swb_offset_960 [13]; +extern const uint16_t * const ff_swb_offset_512 [13]; +extern const uint16_t * const ff_swb_offset_480 [13]; +extern const uint16_t * const ff_swb_offset_128 [13]; +extern const uint16_t * const ff_swb_offset_120 [13]; + +extern const uint8_t ff_tns_max_bands_1024[13]; +extern const uint8_t ff_tns_max_bands_512 [13]; +extern const uint8_t ff_tns_max_bands_480 [13]; +extern const uint8_t ff_tns_max_bands_128 [13]; + +#endif /* AVCODEC_AACTAB_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/aacpsdsp_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/aacpsdsp_init_aarch64.c new file mode 100644 index 000000000..5e7e19bba --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/aacpsdsp_init_aarch64.c @@ -0,0 +1,48 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/aacpsdsp.h" + +void ff_ps_add_squares_neon(float *dst, const float (*src)[2], int n); +void ff_ps_mul_pair_single_neon(float (*dst)[2], float (*src0)[2], + float *src1, int n); +void ff_ps_hybrid_analysis_neon(float (*out)[2], float (*in)[2], + const float (*filter)[8][2], + ptrdiff_t stride, int n); +void ff_ps_stereo_interpolate_neon(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len); +void ff_ps_stereo_interpolate_ipdopd_neon(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len); + +av_cold void ff_psdsp_init_aarch64(PSDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + s->add_squares = ff_ps_add_squares_neon; + s->mul_pair_single = ff_ps_mul_pair_single_neon; + s->hybrid_analysis = ff_ps_hybrid_analysis_neon; + s->stereo_interpolate[0] = ff_ps_stereo_interpolate_neon; + s->stereo_interpolate[1] = ff_ps_stereo_interpolate_ipdopd_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/asm-offsets.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/asm-offsets.h new file mode 100644 index 000000000..fc38eed29 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/asm-offsets.h @@ -0,0 +1,25 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AARCH64_ASM_OFFSETS_H +#define AVCODEC_AARCH64_ASM_OFFSETS_H + +/* FFTContext */ +#define IMDCT_HALF 0x48 + +#endif /* AVCODEC_AARCH64_ASM_OFFSETS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/cabac.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/cabac.h new file mode 100644 index 000000000..6b9b77eb3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/cabac.h @@ -0,0 +1,104 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AARCH64_CABAC_H +#define AVCODEC_AARCH64_CABAC_H + +#include "config.h" +#if HAVE_INLINE_ASM + +#include "libavutil/attributes.h" +#include "libavutil/internal.h" +#include "libavcodec/cabac.h" + +#define get_cabac_inline get_cabac_inline_aarch64 +static av_always_inline int get_cabac_inline_aarch64(CABACContext *c, + uint8_t *const state) +{ + int bit; + void *reg_a, *reg_b, *reg_c, *tmp; + + __asm__ volatile( + "ldrb %w[bit] , [%[state]] \n\t" + "add %[r_b] , %[tables] , %[lps_off] \n\t" + "mov %w[tmp] , %w[range] \n\t" + "and %w[range] , %w[range] , #0xC0 \n\t" + "lsl %w[r_c] , %w[range] , #1 \n\t" + "add %[r_b] , %[r_b] , %w[bit], UXTW \n\t" + "ldrb %w[range] , [%[r_b], %w[r_c], SXTW] \n\t" + "sub %w[r_c] , %w[tmp] , %w[range] \n\t" + "lsl %w[tmp] , %w[r_c] , #17 \n\t" + "cmp %w[tmp] , %w[low] \n\t" + "csel %w[tmp] , %w[tmp] , wzr , cc \n\t" + "csel %w[range] , %w[r_c] , %w[range], gt \n\t" + "cinv %w[bit] , %w[bit] , cc \n\t" + "sub %w[low] , %w[low] , %w[tmp] \n\t" + "add %[r_b] , %[tables] , %[norm_off] \n\t" + "add %[r_a] , %[tables] , %[mlps_off] \n\t" + "ldrb %w[tmp] , [%[r_b], %w[range], SXTW] \n\t" + "ldrb %w[r_a] , [%[r_a], %w[bit], SXTW] \n\t" + "lsl %w[low] , %w[low] , %w[tmp] \n\t" + "lsl %w[range] , %w[range] , %w[tmp] \n\t" + "uxth %w[r_c] , %w[low] \n\t" + "strb %w[r_a] , [%[state]] \n\t" + "cbnz %w[r_c] , 2f \n\t" + "ldr %[r_c] , [%[c], %[byte]] \n\t" + "ldr %[r_a] , [%[c], %[end]] \n\t" + "ldrh %w[tmp] , [%[r_c]] \n\t" + "cmp %[r_c] , %[r_a] \n\t" + "b.ge 1f \n\t" + "add %[r_a] , %[r_c] , #2 \n\t" + "str %[r_a] , [%[c], %[byte]] \n\t" + "1: \n\t" + "sub %w[r_c] , %w[low] , #1 \n\t" + "eor %w[r_c] , %w[r_c] , %w[low] \n\t" + "rev %w[tmp] , %w[tmp] \n\t" + "lsr %w[r_c] , %w[r_c] , #15 \n\t" + "lsr %w[tmp] , %w[tmp] , #15 \n\t" + "ldrb %w[r_c] , [%[r_b], %w[r_c], SXTW] \n\t" + "mov %w[r_b] , #0xFFFF \n\t" + "mov %w[r_a] , #7 \n\t" + "sub %w[tmp] , %w[tmp] , %w[r_b] \n\t" + "sub %w[r_c] , %w[r_a] , %w[r_c] \n\t" + "lsl %w[tmp] , %w[tmp] , %w[r_c] \n\t" + "add %w[low] , %w[low] , %w[tmp] \n\t" + "2: \n\t" + : [bit]"=&r"(bit), + [low]"+&r"(c->low), + [range]"+&r"(c->range), + [r_a]"=&r"(reg_a), + [r_b]"=&r"(reg_b), + [r_c]"=&r"(reg_c), + [tmp]"=&r"(tmp) + : [c]"r"(c), + [state]"r"(state), + [tables]"r"(ff_h264_cabac_tables), + [byte]"i"(offsetof(CABACContext, bytestream)), + [end]"i"(offsetof(CABACContext, bytestream_end)), + [norm_off]"I"(H264_NORM_SHIFT_OFFSET), + [lps_off]"I"(H264_LPS_RANGE_OFFSET), + [mlps_off]"I"(H264_MLPS_STATE_OFFSET + 128) + : "memory", "cc" + ); + + return bit & 1; +} + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVCODEC_AARCH64_CABAC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/fft_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/fft_init_aarch64.c new file mode 100644 index 000000000..db285205a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/fft_init_aarch64.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" + +#include "libavcodec/fft.h" + +void ff_fft_permute_neon(FFTContext *s, FFTComplex *z); +void ff_fft_calc_neon(FFTContext *s, FFTComplex *z); + +void ff_imdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_neon(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_mdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input); + +av_cold void ff_fft_init_aarch64(FFTContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + s->fft_permute = ff_fft_permute_neon; + s->fft_calc = ff_fft_calc_neon; +#if CONFIG_MDCT + s->imdct_calc = ff_imdct_calc_neon; + s->imdct_half = ff_imdct_half_neon; + s->mdct_calc = ff_mdct_calc_neon; + s->mdct_permutation = FF_MDCT_PERM_INTERLEAVE; +#endif + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/fmtconvert_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/fmtconvert_init.c new file mode 100644 index 000000000..210e74b65 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/fmtconvert_init.c @@ -0,0 +1,43 @@ +/* + * ARM optimized Format Conversion Utils + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/fmtconvert.h" + +void ff_int32_to_float_fmul_array8_neon(FmtConvertContext *c, float *dst, + const int32_t *src, const float *mul, + int len); +void ff_int32_to_float_fmul_scalar_neon(float *dst, const int32_t *src, + float mul, int len); + +av_cold void ff_fmt_convert_init_aarch64(FmtConvertContext *c, + AVCodecContext *avctx) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_neon; + c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264chroma_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264chroma_init_aarch64.c new file mode 100644 index 000000000..fa6e0eaf1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264chroma_init_aarch64.c @@ -0,0 +1,59 @@ +/* + * ARM NEON optimised H.264 chroma functions + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/h264chroma.h" + +#include "config.h" + +void ff_put_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); + +void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); + +av_cold void ff_h264chroma_init_aarch64(H264ChromaContext *c, int bit_depth) +{ + const int high_bit_depth = bit_depth > 8; + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags) && !high_bit_depth) { + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_neon; + c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_neon; + c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_neon; + + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_neon; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_neon; + c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264dsp_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264dsp_init_aarch64.c new file mode 100644 index 000000000..d5baccf23 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264dsp_init_aarch64.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2010 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/h264dsp.h" + +void ff_h264_v_loop_filter_luma_neon(uint8_t *pix, ptrdiff_t stride, int alpha, + int beta, int8_t *tc0); +void ff_h264_h_loop_filter_luma_neon(uint8_t *pix, ptrdiff_t stride, int alpha, + int beta, int8_t *tc0); +void ff_h264_v_loop_filter_luma_intra_neon(uint8_t *pix, ptrdiff_t stride, int alpha, + int beta); +void ff_h264_h_loop_filter_luma_intra_neon(uint8_t *pix, ptrdiff_t stride, int alpha, + int beta); +void ff_h264_v_loop_filter_chroma_neon(uint8_t *pix, ptrdiff_t stride, int alpha, + int beta, int8_t *tc0); +void ff_h264_h_loop_filter_chroma_neon(uint8_t *pix, ptrdiff_t stride, int alpha, + int beta, int8_t *tc0); +void ff_h264_h_loop_filter_chroma422_neon(uint8_t *pix, ptrdiff_t stride, int alpha, + int beta, int8_t *tc0); +void ff_h264_v_loop_filter_chroma_intra_neon(uint8_t *pix, ptrdiff_t stride, + int alpha, int beta); +void ff_h264_h_loop_filter_chroma_intra_neon(uint8_t *pix, ptrdiff_t stride, + int alpha, int beta); +void ff_h264_h_loop_filter_chroma422_intra_neon(uint8_t *pix, ptrdiff_t stride, + int alpha, int beta); +void ff_h264_h_loop_filter_chroma_mbaff_intra_neon(uint8_t *pix, ptrdiff_t stride, + int alpha, int beta); + +void ff_weight_h264_pixels_16_neon(uint8_t *dst, ptrdiff_t stride, int height, + int log2_den, int weight, int offset); +void ff_weight_h264_pixels_8_neon(uint8_t *dst, ptrdiff_t stride, int height, + int log2_den, int weight, int offset); +void ff_weight_h264_pixels_4_neon(uint8_t *dst, ptrdiff_t stride, int height, + int log2_den, int weight, int offset); + +void ff_biweight_h264_pixels_16_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int height, int log2_den, int weightd, + int weights, int offset); +void ff_biweight_h264_pixels_8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int height, int log2_den, int weightd, + int weights, int offset); +void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int height, int log2_den, int weightd, + int weights, int offset); + +void ff_h264_idct_add_neon(uint8_t *dst, int16_t *block, int stride); +void ff_h264_idct_dc_add_neon(uint8_t *dst, int16_t *block, int stride); +void ff_h264_idct_add16_neon(uint8_t *dst, const int *block_offset, + int16_t *block, int stride, + const uint8_t nnzc[6*8]); +void ff_h264_idct_add16intra_neon(uint8_t *dst, const int *block_offset, + int16_t *block, int stride, + const uint8_t nnzc[6*8]); +void ff_h264_idct_add8_neon(uint8_t **dest, const int *block_offset, + int16_t *block, int stride, + const uint8_t nnzc[6*8]); + +void ff_h264_idct8_add_neon(uint8_t *dst, int16_t *block, int stride); +void ff_h264_idct8_dc_add_neon(uint8_t *dst, int16_t *block, int stride); +void ff_h264_idct8_add4_neon(uint8_t *dst, const int *block_offset, + int16_t *block, int stride, + const uint8_t nnzc[6*8]); + +av_cold void ff_h264dsp_init_aarch64(H264DSPContext *c, const int bit_depth, + const int chroma_format_idc) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags) && bit_depth == 8) { + c->h264_v_loop_filter_luma = ff_h264_v_loop_filter_luma_neon; + c->h264_h_loop_filter_luma = ff_h264_h_loop_filter_luma_neon; + c->h264_v_loop_filter_luma_intra= ff_h264_v_loop_filter_luma_intra_neon; + c->h264_h_loop_filter_luma_intra= ff_h264_h_loop_filter_luma_intra_neon; + + c->h264_v_loop_filter_chroma = ff_h264_v_loop_filter_chroma_neon; + c->h264_v_loop_filter_chroma_intra = ff_h264_v_loop_filter_chroma_intra_neon; + + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_h264_h_loop_filter_chroma_neon; + c->h264_h_loop_filter_chroma_intra = ff_h264_h_loop_filter_chroma_intra_neon; + c->h264_h_loop_filter_chroma_mbaff_intra = ff_h264_h_loop_filter_chroma_mbaff_intra_neon; + } else { + c->h264_h_loop_filter_chroma = ff_h264_h_loop_filter_chroma422_neon; + c->h264_h_loop_filter_chroma_mbaff = ff_h264_h_loop_filter_chroma_neon; + c->h264_h_loop_filter_chroma_intra = ff_h264_h_loop_filter_chroma422_intra_neon; + c->h264_h_loop_filter_chroma_mbaff_intra = ff_h264_h_loop_filter_chroma_intra_neon; + } + + c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels_16_neon; + c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels_8_neon; + c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels_4_neon; + + c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels_16_neon; + c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels_8_neon; + c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels_4_neon; + + c->h264_idct_add = ff_h264_idct_add_neon; + c->h264_idct_dc_add = ff_h264_idct_dc_add_neon; + c->h264_idct_add16 = ff_h264_idct_add16_neon; + c->h264_idct_add16intra = ff_h264_idct_add16intra_neon; + if (chroma_format_idc <= 1) + c->h264_idct_add8 = ff_h264_idct_add8_neon; + c->h264_idct8_add = ff_h264_idct8_add_neon; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_neon; + c->h264_idct8_add4 = ff_h264_idct8_add4_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264pred_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264pred_init.c new file mode 100644 index 000000000..b144376f9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264pred_init.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/h264pred.h" + +void ff_pred16x16_vert_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred16x16_hor_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred16x16_plane_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred16x16_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred16x16_128_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred16x16_left_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred16x16_top_dc_neon(uint8_t *src, ptrdiff_t stride); + +void ff_pred8x8_vert_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_hor_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_plane_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_128_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_left_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_top_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_l0t_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_0lt_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_l00_dc_neon(uint8_t *src, ptrdiff_t stride); +void ff_pred8x8_0l0_dc_neon(uint8_t *src, ptrdiff_t stride); + +static av_cold void h264_pred_init_neon(H264PredContext *h, int codec_id, + const int bit_depth, + const int chroma_format_idc) +{ + const int high_depth = bit_depth > 8; + + if (high_depth) + return; + + if (chroma_format_idc <= 1) { + h->pred8x8[VERT_PRED8x8 ] = ff_pred8x8_vert_neon; + h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_hor_neon; + if (codec_id != AV_CODEC_ID_VP7 && codec_id != AV_CODEC_ID_VP8) + h->pred8x8[PLANE_PRED8x8] = ff_pred8x8_plane_neon; + h->pred8x8[DC_128_PRED8x8 ] = ff_pred8x8_128_dc_neon; + if (codec_id != AV_CODEC_ID_RV40 && codec_id != AV_CODEC_ID_VP7 && + codec_id != AV_CODEC_ID_VP8) { + h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_neon; + h->pred8x8[LEFT_DC_PRED8x8] = ff_pred8x8_left_dc_neon; + h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_neon; + h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8] = ff_pred8x8_l0t_dc_neon; + h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8] = ff_pred8x8_0lt_dc_neon; + h->pred8x8[ALZHEIMER_DC_L00_PRED8x8] = ff_pred8x8_l00_dc_neon; + h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8] = ff_pred8x8_0l0_dc_neon; + } + } + + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_neon; + h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vert_neon; + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_hor_neon; + h->pred16x16[LEFT_DC_PRED8x8] = ff_pred16x16_left_dc_neon; + h->pred16x16[TOP_DC_PRED8x8 ] = ff_pred16x16_top_dc_neon; + h->pred16x16[DC_128_PRED8x8 ] = ff_pred16x16_128_dc_neon; + if (codec_id != AV_CODEC_ID_SVQ3 && codec_id != AV_CODEC_ID_RV40 && + codec_id != AV_CODEC_ID_VP7 && codec_id != AV_CODEC_ID_VP8) + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_neon; +} + +av_cold void ff_h264_pred_init_aarch64(H264PredContext *h, int codec_id, + int bit_depth, const int chroma_format_idc) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) + h264_pred_init_neon(h, codec_id, bit_depth, chroma_format_idc); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264qpel_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264qpel_init_aarch64.c new file mode 100644 index 000000000..77f41d9a2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/h264qpel_init_aarch64.c @@ -0,0 +1,172 @@ +/* + * ARM NEON optimised DSP functions + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/h264qpel.h" + +void ff_put_h264_qpel16_mc00_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc10_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc20_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc30_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc01_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc11_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc21_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc31_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc02_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc12_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc22_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc32_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc03_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc13_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc23_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel16_mc33_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + +void ff_put_h264_qpel8_mc00_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc10_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc20_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc30_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc01_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc11_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc21_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc31_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc02_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc12_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc22_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc32_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc03_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc13_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc23_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_h264_qpel8_mc33_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + +void ff_avg_h264_qpel16_mc00_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc10_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc20_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc30_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc01_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc11_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc21_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc31_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc02_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc12_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc22_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc32_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc03_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc13_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc23_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel16_mc33_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + +void ff_avg_h264_qpel8_mc00_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc10_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc20_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc30_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc01_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc11_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc21_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc31_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc02_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc12_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc22_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc32_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc03_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc13_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc23_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_h264_qpel8_mc33_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + +av_cold void ff_h264qpel_init_aarch64(H264QpelContext *c, int bit_depth) +{ + const int high_bit_depth = bit_depth > 8; + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags) && !high_bit_depth) { + c->put_h264_qpel_pixels_tab[0][ 0] = ff_put_h264_qpel16_mc00_neon; + c->put_h264_qpel_pixels_tab[0][ 1] = ff_put_h264_qpel16_mc10_neon; + c->put_h264_qpel_pixels_tab[0][ 2] = ff_put_h264_qpel16_mc20_neon; + c->put_h264_qpel_pixels_tab[0][ 3] = ff_put_h264_qpel16_mc30_neon; + c->put_h264_qpel_pixels_tab[0][ 4] = ff_put_h264_qpel16_mc01_neon; + c->put_h264_qpel_pixels_tab[0][ 5] = ff_put_h264_qpel16_mc11_neon; + c->put_h264_qpel_pixels_tab[0][ 6] = ff_put_h264_qpel16_mc21_neon; + c->put_h264_qpel_pixels_tab[0][ 7] = ff_put_h264_qpel16_mc31_neon; + c->put_h264_qpel_pixels_tab[0][ 8] = ff_put_h264_qpel16_mc02_neon; + c->put_h264_qpel_pixels_tab[0][ 9] = ff_put_h264_qpel16_mc12_neon; + c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_neon; + c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_neon; + c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_neon; + c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_neon; + c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_neon; + c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_neon; + + c->put_h264_qpel_pixels_tab[1][ 0] = ff_put_h264_qpel8_mc00_neon; + c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_neon; + c->put_h264_qpel_pixels_tab[1][ 2] = ff_put_h264_qpel8_mc20_neon; + c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_neon; + c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_neon; + c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_neon; + c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_neon; + c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_neon; + c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_neon; + c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_neon; + c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_neon; + c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_neon; + c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_neon; + c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_neon; + c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_neon; + c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_neon; + + c->avg_h264_qpel_pixels_tab[0][ 0] = ff_avg_h264_qpel16_mc00_neon; + c->avg_h264_qpel_pixels_tab[0][ 1] = ff_avg_h264_qpel16_mc10_neon; + c->avg_h264_qpel_pixels_tab[0][ 2] = ff_avg_h264_qpel16_mc20_neon; + c->avg_h264_qpel_pixels_tab[0][ 3] = ff_avg_h264_qpel16_mc30_neon; + c->avg_h264_qpel_pixels_tab[0][ 4] = ff_avg_h264_qpel16_mc01_neon; + c->avg_h264_qpel_pixels_tab[0][ 5] = ff_avg_h264_qpel16_mc11_neon; + c->avg_h264_qpel_pixels_tab[0][ 6] = ff_avg_h264_qpel16_mc21_neon; + c->avg_h264_qpel_pixels_tab[0][ 7] = ff_avg_h264_qpel16_mc31_neon; + c->avg_h264_qpel_pixels_tab[0][ 8] = ff_avg_h264_qpel16_mc02_neon; + c->avg_h264_qpel_pixels_tab[0][ 9] = ff_avg_h264_qpel16_mc12_neon; + c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_neon; + c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_neon; + c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_neon; + c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_neon; + c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_neon; + c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_neon; + + c->avg_h264_qpel_pixels_tab[1][ 0] = ff_avg_h264_qpel8_mc00_neon; + c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_neon; + c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_neon; + c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_neon; + c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_neon; + c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_neon; + c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_neon; + c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_neon; + c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_neon; + c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_neon; + c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_neon; + c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_neon; + c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_neon; + c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_neon; + c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_neon; + c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/hpeldsp_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/hpeldsp_init_aarch64.c new file mode 100644 index 000000000..144ae2bcc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/hpeldsp_init_aarch64.c @@ -0,0 +1,123 @@ +/* + * ARM NEON optimised DSP functions + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/hpeldsp.h" + +void ff_put_pixels16_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_x2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_y2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_xy2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_x2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_y2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_xy2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_put_pixels16_x2_no_rnd_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_y2_no_rnd_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_xy2_no_rnd_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_x2_no_rnd_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_y2_no_rnd_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_xy2_no_rnd_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_avg_pixels16_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_x2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_y2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_xy2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_x2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_y2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_xy2_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_avg_pixels16_x2_no_rnd_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_y2_no_rnd_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_xy2_no_rnd_neon(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +av_cold void ff_hpeldsp_init_aarch64(HpelDSPContext *c, int flags) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + c->put_pixels_tab[0][0] = ff_put_pixels16_neon; + c->put_pixels_tab[0][1] = ff_put_pixels16_x2_neon; + c->put_pixels_tab[0][2] = ff_put_pixels16_y2_neon; + c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_neon; + c->put_pixels_tab[1][0] = ff_put_pixels8_neon; + c->put_pixels_tab[1][1] = ff_put_pixels8_x2_neon; + c->put_pixels_tab[1][2] = ff_put_pixels8_y2_neon; + c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_neon; + + c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_neon; + c->put_no_rnd_pixels_tab[0][1] = ff_put_pixels16_x2_no_rnd_neon; + c->put_no_rnd_pixels_tab[0][2] = ff_put_pixels16_y2_no_rnd_neon; + c->put_no_rnd_pixels_tab[0][3] = ff_put_pixels16_xy2_no_rnd_neon; + c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_neon; + c->put_no_rnd_pixels_tab[1][1] = ff_put_pixels8_x2_no_rnd_neon; + c->put_no_rnd_pixels_tab[1][2] = ff_put_pixels8_y2_no_rnd_neon; + c->put_no_rnd_pixels_tab[1][3] = ff_put_pixels8_xy2_no_rnd_neon; + + c->avg_pixels_tab[0][0] = ff_avg_pixels16_neon; + c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_neon; + c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_neon; + c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_neon; + c->avg_pixels_tab[1][0] = ff_avg_pixels8_neon; + c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_neon; + c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_neon; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_neon; + + c->avg_no_rnd_pixels_tab[0] = ff_avg_pixels16_neon; + c->avg_no_rnd_pixels_tab[1] = ff_avg_pixels16_x2_no_rnd_neon; + c->avg_no_rnd_pixels_tab[2] = ff_avg_pixels16_y2_no_rnd_neon; + c->avg_no_rnd_pixels_tab[3] = ff_avg_pixels16_xy2_no_rnd_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/idct.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/idct.h new file mode 100644 index 000000000..5c4904614 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/idct.h @@ -0,0 +1,28 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AARCH64_IDCT_H +#define AVCODEC_AARCH64_IDCT_H + +#include + +void ff_simple_idct_neon(int16_t *data); +void ff_simple_idct_put_neon(uint8_t *dest, ptrdiff_t line_size, int16_t *data); +void ff_simple_idct_add_neon(uint8_t *dest, ptrdiff_t line_size, int16_t *data); + +#endif /* AVCODEC_AARCH64_IDCT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/idctdsp_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/idctdsp_init_aarch64.c new file mode 100644 index 000000000..0406e6083 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/idctdsp_init_aarch64.c @@ -0,0 +1,41 @@ +/* + * ARM-NEON-optimized IDCT functions + * Copyright (c) 2008 Mans Rullgard + * Copyright (c) 2017 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/idctdsp.h" +#include "idct.h" + +av_cold void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth) +{ + if (!avctx->lowres && !high_bit_depth) { + if (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLENEON) { + c->idct_put = ff_simple_idct_put_neon; + c->idct_add = ff_simple_idct_add_neon; + c->idct = ff_simple_idct_neon; + c->perm_type = FF_IDCT_PERM_PARTTRANS; + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/mpegaudiodsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/mpegaudiodsp_init.c new file mode 100644 index 000000000..5d966af5f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/mpegaudiodsp_init.c @@ -0,0 +1,40 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/attributes.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/mpegaudiodsp.h" +#include "config.h" + +void ff_mpadsp_apply_window_fixed_neon(int32_t *synth_buf, int32_t *window, + int *dither, int16_t *samples, ptrdiff_t incr); +void ff_mpadsp_apply_window_float_neon(float *synth_buf, float *window, + int *dither, float *samples, ptrdiff_t incr); + +av_cold void ff_mpadsp_init_aarch64(MPADSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + s->apply_window_fixed = ff_mpadsp_apply_window_fixed_neon; + s->apply_window_float = ff_mpadsp_apply_window_float_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/opusdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/opusdsp_init.c new file mode 100644 index 000000000..cc6a1b672 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/opusdsp_init.c @@ -0,0 +1,35 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/opusdsp.h" + +void ff_opus_postfilter_neon(float *data, int period, float *gains, int len); +float ff_opus_deemphasis_neon(float *out, float *in, float coeff, int len); + +av_cold void ff_opus_dsp_init_aarch64(OpusDSP *ctx) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + ctx->postfilter = ff_opus_postfilter_neon; + ctx->deemphasis = ff_opus_deemphasis_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/rv40dsp_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/rv40dsp_init_aarch64.c new file mode 100644 index 000000000..142705db9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/rv40dsp_init_aarch64.c @@ -0,0 +1,48 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/rv34dsp.h" + +#include "config.h" + +void ff_put_rv40_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_rv40_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); + +void ff_avg_rv40_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_rv40_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); + +av_cold void ff_rv40dsp_init_aarch64(RV34DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_neon; + c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_neon; + c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_neon; + c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/sbrdsp_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/sbrdsp_init_aarch64.c new file mode 100644 index 000000000..9c967990d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/sbrdsp_init_aarch64.c @@ -0,0 +1,70 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/aarch64/cpu.h" +#include "libavutil/attributes.h" +#include "libavcodec/sbrdsp.h" + +void ff_sbr_sum64x5_neon(float *z); +float ff_sbr_sum_square_neon(float (*x)[2], int n); +void ff_sbr_neg_odd_64_neon(float *x); +void ff_sbr_qmf_pre_shuffle_neon(float *z); +void ff_sbr_qmf_post_shuffle_neon(float W[32][2], const float *z); +void ff_sbr_qmf_deint_neg_neon(float *v, const float *src); +void ff_sbr_qmf_deint_bfly_neon(float *v, const float *src0, const float *src1); +void ff_sbr_hf_g_filt_neon(float (*Y)[2], const float (*X_high)[40][2], + const float *g_filt, int m_max, intptr_t ixh); +void ff_sbr_hf_gen_neon(float (*X_high)[2], const float (*X_low)[2], + const float alpha0[2], const float alpha1[2], + float bw, int start, int end); +void ff_sbr_autocorrelate_neon(const float x[40][2], float phi[3][2][2]); +void ff_sbr_hf_apply_noise_0_neon(float Y[64][2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_1_neon(float Y[64][2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_2_neon(float Y[64][2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_3_neon(float Y[64][2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); + +av_cold void ff_sbrdsp_init_aarch64(SBRDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + s->sum64x5 = ff_sbr_sum64x5_neon; + s->sum_square = ff_sbr_sum_square_neon; + s->neg_odd_64 = ff_sbr_neg_odd_64_neon; + s->qmf_pre_shuffle = ff_sbr_qmf_pre_shuffle_neon; + s->qmf_post_shuffle = ff_sbr_qmf_post_shuffle_neon; + s->qmf_deint_neg = ff_sbr_qmf_deint_neg_neon; + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_neon; + s->hf_g_filt = ff_sbr_hf_g_filt_neon; + s->hf_gen = ff_sbr_hf_gen_neon; + s->autocorrelate = ff_sbr_autocorrelate_neon; + s->hf_apply_noise[0] = ff_sbr_hf_apply_noise_0_neon; + s->hf_apply_noise[1] = ff_sbr_hf_apply_noise_1_neon; + s->hf_apply_noise[2] = ff_sbr_hf_apply_noise_2_neon; + s->hf_apply_noise[3] = ff_sbr_hf_apply_noise_3_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/synth_filter_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/synth_filter_init.c new file mode 100644 index 000000000..767b01112 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/synth_filter_init.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/aarch64/cpu.h" +#include "libavutil/attributes.h" +#include "libavutil/internal.h" +#include "libavcodec/fft.h" +#include "libavcodec/synth_filter.h" + +#include "asm-offsets.h" + +#if HAVE_NEON || HAVE_VFP +AV_CHECK_OFFSET(FFTContext, imdct_half, IMDCT_HALF); +#endif + +void ff_synth_filter_float_neon(FFTContext *imdct, + float *synth_buf_ptr, int *synth_buf_offset, + float synth_buf2[32], const float window[512], + float out[32], const float in[32], + float scale); + +av_cold void ff_synth_filter_init_aarch64(SynthFilterContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) + s->synth_filter_float = ff_synth_filter_float_neon; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vc1dsp_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vc1dsp_init_aarch64.c new file mode 100644 index 000000000..13dfd7494 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vc1dsp_init_aarch64.c @@ -0,0 +1,47 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/vc1dsp.h" + +#include "config.h" + +void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); + +av_cold void ff_vc1dsp_init_aarch64(VC1DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_neon; + dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_neon; + dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = ff_put_vc1_chroma_mc4_neon; + dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = ff_avg_vc1_chroma_mc4_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/videodsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/videodsp_init.c new file mode 100644 index 000000000..6f667a6d3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/videodsp_init.c @@ -0,0 +1,32 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/videodsp.h" + +void ff_prefetch_aarch64(uint8_t *mem, ptrdiff_t stride, int h); + +av_cold void ff_videodsp_init_aarch64(VideoDSPContext *ctx, int bpc) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_armv8(cpu_flags)) + ctx->prefetch = ff_prefetch_aarch64; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vorbisdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vorbisdsp_init.c new file mode 100644 index 000000000..c796f95e6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vorbisdsp_init.c @@ -0,0 +1,34 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/vorbisdsp.h" + +void ff_vorbis_inverse_coupling_neon(float *mag, float *ang, + intptr_t blocksize); + +av_cold void ff_vorbisdsp_init_aarch64(VorbisDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp8dsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp8dsp.h new file mode 100644 index 000000000..871fed7a9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp8dsp.h @@ -0,0 +1,75 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AARCH64_VP8DSP_H +#define AVCODEC_AARCH64_VP8DSP_H + +#include "libavcodec/vp8dsp.h" + +#define VP8_LF_Y(hv, inner, opt) \ + void ff_vp8_##hv##_loop_filter16##inner##_##opt(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim_E, int flim_I, \ + int hev_thresh) + +#define VP8_LF_UV(hv, inner, opt) \ + void ff_vp8_##hv##_loop_filter8uv##inner##_##opt(uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t stride, \ + int flim_E, int flim_I, \ + int hev_thresh) + +#define VP8_LF_SIMPLE(hv, opt) \ + void ff_vp8_##hv##_loop_filter16_simple_##opt(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim) + +#define VP8_LF_HV(inner, opt) \ + VP8_LF_Y(h, inner, opt); \ + VP8_LF_Y(v, inner, opt); \ + VP8_LF_UV(h, inner, opt); \ + VP8_LF_UV(v, inner, opt) + +#define VP8_LF(opt) \ + VP8_LF_HV(, opt); \ + VP8_LF_HV(_inner, opt); \ + VP8_LF_SIMPLE(h, opt); \ + VP8_LF_SIMPLE(v, opt) + +#define VP8_MC(n, opt) \ + void ff_put_vp8_##n##_##opt(uint8_t *dst, ptrdiff_t dststride, \ + uint8_t *src, ptrdiff_t srcstride, \ + int h, int x, int y) + +#define VP8_EPEL(w, opt) \ + VP8_MC(pixels ## w, opt); \ + VP8_MC(epel ## w ## _h4, opt); \ + VP8_MC(epel ## w ## _h6, opt); \ + VP8_MC(epel ## w ## _v4, opt); \ + VP8_MC(epel ## w ## _h4v4, opt); \ + VP8_MC(epel ## w ## _h6v4, opt); \ + VP8_MC(epel ## w ## _v6, opt); \ + VP8_MC(epel ## w ## _h4v6, opt); \ + VP8_MC(epel ## w ## _h6v6, opt) + +#define VP8_BILIN(w, opt) \ + VP8_MC(bilin ## w ## _h, opt); \ + VP8_MC(bilin ## w ## _v, opt); \ + VP8_MC(bilin ## w ## _hv, opt) + +#endif /* AVCODEC_AARCH64_VP8DSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp8dsp_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp8dsp_init_aarch64.c new file mode 100644 index 000000000..fc7e831d1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp8dsp_init_aarch64.c @@ -0,0 +1,124 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/vp8dsp.h" +#include "vp8dsp.h" + +void ff_vp8_luma_dc_wht_neon(int16_t block[4][4][16], int16_t dc[16]); + +void ff_vp8_idct_add_neon(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +void ff_vp8_idct_dc_add_neon(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); +void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); + +VP8_LF(neon); + +VP8_EPEL(16, neon); +VP8_EPEL(8, neon); +VP8_EPEL(4, neon); + +VP8_BILIN(16, neon); +VP8_BILIN(8, neon); +VP8_BILIN(4, neon); + +av_cold void ff_vp78dsp_init_aarch64(VP8DSPContext *dsp) +{ + if (!have_neon(av_get_cpu_flags())) + return; + dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon; + dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_neon; + dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_neon; + dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_neon; + + dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon; + dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_neon; + dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_neon; + dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_neon; + dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_neon; + dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_neon; + dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_neon; + dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_neon; + dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_neon; + + dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_neon; + dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_neon; + dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_neon; + dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_neon; + dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_neon; + dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_neon; + dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_neon; + dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_neon; + + dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon; + dsp->put_vp8_bilinear_pixels_tab[0][0][1] = ff_put_vp8_bilin16_h_neon; + dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilin16_h_neon; + dsp->put_vp8_bilinear_pixels_tab[0][1][0] = ff_put_vp8_bilin16_v_neon; + dsp->put_vp8_bilinear_pixels_tab[0][1][1] = ff_put_vp8_bilin16_hv_neon; + dsp->put_vp8_bilinear_pixels_tab[0][1][2] = ff_put_vp8_bilin16_hv_neon; + dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilin16_v_neon; + dsp->put_vp8_bilinear_pixels_tab[0][2][1] = ff_put_vp8_bilin16_hv_neon; + dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilin16_hv_neon; + + dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon; + dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilin8_h_neon; + dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilin8_h_neon; + dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilin8_v_neon; + dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilin8_hv_neon; + dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilin8_hv_neon; + dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilin8_v_neon; + dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilin8_hv_neon; + dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilin8_hv_neon; + + dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilin4_h_neon; + dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilin4_h_neon; + dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilin4_v_neon; + dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilin4_hv_neon; + dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilin4_hv_neon; + dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilin4_v_neon; + dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilin4_hv_neon; + dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilin4_hv_neon; +} + +av_cold void ff_vp8dsp_init_aarch64(VP8DSPContext *dsp) +{ + if (!have_neon(av_get_cpu_flags())) + return; + dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_neon; + + dsp->vp8_idct_add = ff_vp8_idct_add_neon; + dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_neon; + dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_neon; + dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_neon; + + dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_neon; + dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_neon; + dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_neon; + dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_neon; + + dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_neon; + dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_neon; + dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_neon; + dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_neon; + + dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter16_simple_neon; + dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter16_simple_neon; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init.h new file mode 100644 index 000000000..9df1752c6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 Google Inc. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AARCH64_VP9DSP_INIT_H +#define AVCODEC_AARCH64_VP9DSP_INIT_H + +#include "libavcodec/vp9dsp.h" + +void ff_vp9dsp_init_10bpp_aarch64(VP9DSPContext *dsp); +void ff_vp9dsp_init_12bpp_aarch64(VP9DSPContext *dsp); + +#endif /* AVCODEC_AARCH64_VP9DSP_INIT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_10bpp_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_10bpp_aarch64.c new file mode 100644 index 000000000..0fa0d7f8c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_10bpp_aarch64.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 Google Inc. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define BPP 10 +#define INIT_FUNC ff_vp9dsp_init_10bpp_aarch64 +#include "vp9dsp_init_16bpp_aarch64_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_12bpp_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_12bpp_aarch64.c new file mode 100644 index 000000000..dae223240 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_12bpp_aarch64.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 Google Inc. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define BPP 12 +#define INIT_FUNC ff_vp9dsp_init_12bpp_aarch64 +#include "vp9dsp_init_16bpp_aarch64_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c new file mode 100644 index 000000000..8dcfdeaaf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_16bpp_aarch64_template.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2017 Google Inc. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/internal.h" +#include "libavutil/aarch64/cpu.h" +#include "vp9dsp_init.h" + +#define declare_fpel(type, sz, suffix) \ +void ff_vp9_##type##sz##suffix##_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define decl_mc_func(op, filter, dir, sz, bpp) \ +void ff_vp9_##op##_##filter##sz##_##dir##_##bpp##_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define define_8tap_2d_fn(op, filter, sz, bpp) \ +static void op##_##filter##sz##_hv_##bpp##_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, \ + ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + LOCAL_ALIGNED_16(uint8_t, temp, [((1 + (sz < 64)) * sz + 8) * sz * 2]); \ + /* We only need h + 7 lines, but the horizontal filter assumes an \ + * even number of rows, so filter h + 8 lines here. */ \ + ff_vp9_put_##filter##sz##_h_##bpp##_neon(temp, 2 * sz, \ + src - 3 * src_stride, src_stride, \ + h + 8, mx, 0); \ + ff_vp9_##op##_##filter##sz##_v_##bpp##_neon(dst, dst_stride, \ + temp + 3 * 2 * sz, 2 * sz, \ + h, 0, my); \ +} + +#define decl_filter_funcs(op, dir, sz, bpp) \ + decl_mc_func(op, regular, dir, sz, bpp); \ + decl_mc_func(op, sharp, dir, sz, bpp); \ + decl_mc_func(op, smooth, dir, sz, bpp) + +#define decl_mc_funcs(sz, bpp) \ + decl_filter_funcs(put, h, sz, bpp); \ + decl_filter_funcs(avg, h, sz, bpp); \ + decl_filter_funcs(put, v, sz, bpp); \ + decl_filter_funcs(avg, v, sz, bpp); \ + decl_filter_funcs(put, hv, sz, bpp); \ + decl_filter_funcs(avg, hv, sz, bpp) + +#define ff_vp9_copy32_neon ff_vp9_copy32_aarch64 +#define ff_vp9_copy64_neon ff_vp9_copy64_aarch64 +#define ff_vp9_copy128_neon ff_vp9_copy128_aarch64 + +declare_fpel(copy, 128, ); +declare_fpel(copy, 64, ); +declare_fpel(copy, 32, ); +declare_fpel(copy, 16, ); +declare_fpel(copy, 8, ); +declare_fpel(avg, 64, _16); +declare_fpel(avg, 32, _16); +declare_fpel(avg, 16, _16); +declare_fpel(avg, 8, _16); +declare_fpel(avg, 4, _16); + +decl_mc_funcs(64, BPP); +decl_mc_funcs(32, BPP); +decl_mc_funcs(16, BPP); +decl_mc_funcs(8, BPP); +decl_mc_funcs(4, BPP); + +#define define_8tap_2d_funcs(sz, bpp) \ + define_8tap_2d_fn(put, regular, sz, bpp) \ + define_8tap_2d_fn(put, sharp, sz, bpp) \ + define_8tap_2d_fn(put, smooth, sz, bpp) \ + define_8tap_2d_fn(avg, regular, sz, bpp) \ + define_8tap_2d_fn(avg, sharp, sz, bpp) \ + define_8tap_2d_fn(avg, smooth, sz, bpp) + +define_8tap_2d_funcs(64, BPP) +define_8tap_2d_funcs(32, BPP) +define_8tap_2d_funcs(16, BPP) +define_8tap_2d_funcs(8, BPP) +define_8tap_2d_funcs(4, BPP) + +static av_cold void vp9dsp_mc_init_aarch64(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + +#define init_fpel(idx1, idx2, sz, type, suffix) \ + dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_BILINEAR ][idx2][0][0] = ff_vp9_##type##sz##suffix + +#define init_copy(idx, sz, suffix) \ + init_fpel(idx, 0, sz, copy, suffix) + +#define init_avg(idx, sz, suffix) \ + init_fpel(idx, 1, sz, avg, suffix) + +#define init_copy_avg(idx, sz1, sz2) \ + init_copy(idx, sz2, _neon); \ + init_avg (idx, sz1, _16_neon) + + if (have_armv8(cpu_flags)) { + init_copy(0, 128, _aarch64); + init_copy(1, 64, _aarch64); + init_copy(2, 32, _aarch64); + } + + if (have_neon(cpu_flags)) { +#define init_mc_func(idx1, idx2, op, filter, fname, dir, mx, my, sz, pfx, bpp) \ + dsp->mc[idx1][filter][idx2][mx][my] = pfx##op##_##fname##sz##_##dir##_##bpp##_neon + +#define init_mc_funcs(idx, dir, mx, my, sz, pfx, bpp) \ + init_mc_func(idx, 0, put, FILTER_8TAP_REGULAR, regular, dir, mx, my, sz, pfx, bpp); \ + init_mc_func(idx, 0, put, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx, bpp); \ + init_mc_func(idx, 0, put, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx, bpp); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_REGULAR, regular, dir, mx, my, sz, pfx, bpp); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx, bpp); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx, bpp) + +#define init_mc_funcs_dirs(idx, sz, bpp) \ + init_mc_funcs(idx, v, 0, 1, sz, ff_vp9_, bpp); \ + init_mc_funcs(idx, h, 1, 0, sz, ff_vp9_, bpp); \ + init_mc_funcs(idx, hv, 1, 1, sz, , bpp) + + + init_avg(0, 64, _16_neon); + init_avg(1, 32, _16_neon); + init_avg(2, 16, _16_neon); + init_copy_avg(3, 8, 16); + init_copy_avg(4, 4, 8); + + init_mc_funcs_dirs(0, 64, BPP); + init_mc_funcs_dirs(1, 32, BPP); + init_mc_funcs_dirs(2, 16, BPP); + init_mc_funcs_dirs(3, 8, BPP); + init_mc_funcs_dirs(4, 4, BPP); + } +} + +#define define_itxfm2(type_a, type_b, sz, bpp) \ +void ff_vp9_##type_a##_##type_b##_##sz##x##sz##_add_##bpp##_neon(uint8_t *_dst, \ + ptrdiff_t stride, \ + int16_t *_block, int eob) +#define define_itxfm(type_a, type_b, sz, bpp) define_itxfm2(type_a, type_b, sz, bpp) + +#define define_itxfm_funcs(sz, bpp) \ + define_itxfm(idct, idct, sz, bpp); \ + define_itxfm(iadst, idct, sz, bpp); \ + define_itxfm(idct, iadst, sz, bpp); \ + define_itxfm(iadst, iadst, sz, bpp) + +define_itxfm_funcs(4, BPP); +define_itxfm_funcs(8, BPP); +define_itxfm_funcs(16, BPP); +define_itxfm(idct, idct, 32, BPP); +define_itxfm(iwht, iwht, 4, BPP); + + +static av_cold void vp9dsp_itxfm_init_aarch64(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { +#define init_itxfm2(tx, sz, bpp) \ + dsp->itxfm_add[tx][DCT_DCT] = ff_vp9_idct_idct_##sz##_add_##bpp##_neon; \ + dsp->itxfm_add[tx][DCT_ADST] = ff_vp9_iadst_idct_##sz##_add_##bpp##_neon; \ + dsp->itxfm_add[tx][ADST_DCT] = ff_vp9_idct_iadst_##sz##_add_##bpp##_neon; \ + dsp->itxfm_add[tx][ADST_ADST] = ff_vp9_iadst_iadst_##sz##_add_##bpp##_neon +#define init_itxfm(tx, sz, bpp) init_itxfm2(tx, sz, bpp) + +#define init_idct2(tx, nm, bpp) \ + dsp->itxfm_add[tx][DCT_DCT] = \ + dsp->itxfm_add[tx][ADST_DCT] = \ + dsp->itxfm_add[tx][DCT_ADST] = \ + dsp->itxfm_add[tx][ADST_ADST] = ff_vp9_##nm##_add_##bpp##_neon +#define init_idct(tx, nm, bpp) init_idct2(tx, nm, bpp) + + init_itxfm(TX_4X4, 4x4, BPP); + init_itxfm(TX_8X8, 8x8, BPP); + init_itxfm(TX_16X16, 16x16, BPP); + init_idct(TX_32X32, idct_idct_32x32, BPP); + init_idct(4, iwht_iwht_4x4, BPP); + } +} + +#define define_loop_filter(dir, wd, size, bpp) \ +void ff_vp9_loop_filter_##dir##_##wd##_##size##_##bpp##_neon(uint8_t *dst, ptrdiff_t stride, int E, int I, int H) + +#define define_loop_filters(wd, size, bpp) \ + define_loop_filter(h, wd, size, bpp); \ + define_loop_filter(v, wd, size, bpp) + +define_loop_filters(4, 8, BPP); +define_loop_filters(8, 8, BPP); +define_loop_filters(16, 8, BPP); + +define_loop_filters(16, 16, BPP); + +define_loop_filters(44, 16, BPP); +define_loop_filters(48, 16, BPP); +define_loop_filters(84, 16, BPP); +define_loop_filters(88, 16, BPP); + +static av_cold void vp9dsp_loopfilter_init_aarch64(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { +#define init_lpf_func_8(idx1, idx2, dir, wd, bpp) \ + dsp->loop_filter_8[idx1][idx2] = ff_vp9_loop_filter_##dir##_##wd##_8_##bpp##_neon + +#define init_lpf_func_16(idx, dir, bpp) \ + dsp->loop_filter_16[idx] = ff_vp9_loop_filter_##dir##_16_16_##bpp##_neon + +#define init_lpf_func_mix2(idx1, idx2, idx3, dir, wd, bpp) \ + dsp->loop_filter_mix2[idx1][idx2][idx3] = ff_vp9_loop_filter_##dir##_##wd##_16_##bpp##_neon + +#define init_lpf_funcs_8_wd(idx, wd, bpp) \ + init_lpf_func_8(idx, 0, h, wd, bpp); \ + init_lpf_func_8(idx, 1, v, wd, bpp) + +#define init_lpf_funcs_16(bpp) \ + init_lpf_func_16(0, h, bpp); \ + init_lpf_func_16(1, v, bpp) + +#define init_lpf_funcs_mix2_wd(idx1, idx2, wd, bpp) \ + init_lpf_func_mix2(idx1, idx2, 0, h, wd, bpp); \ + init_lpf_func_mix2(idx1, idx2, 1, v, wd, bpp) + +#define init_lpf_funcs_8(bpp) \ + init_lpf_funcs_8_wd(0, 4, bpp); \ + init_lpf_funcs_8_wd(1, 8, bpp); \ + init_lpf_funcs_8_wd(2, 16, bpp) + +#define init_lpf_funcs_mix2(bpp) \ + init_lpf_funcs_mix2_wd(0, 0, 44, bpp); \ + init_lpf_funcs_mix2_wd(0, 1, 48, bpp); \ + init_lpf_funcs_mix2_wd(1, 0, 84, bpp); \ + init_lpf_funcs_mix2_wd(1, 1, 88, bpp) + + init_lpf_funcs_8(BPP); + init_lpf_funcs_16(BPP); + init_lpf_funcs_mix2(BPP); + } +} + +av_cold void INIT_FUNC(VP9DSPContext *dsp) +{ + vp9dsp_mc_init_aarch64(dsp); + vp9dsp_loopfilter_init_aarch64(dsp); + vp9dsp_itxfm_init_aarch64(dsp); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_aarch64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_aarch64.c new file mode 100644 index 000000000..4c699759f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/vp9dsp_init_aarch64.c @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2016 Google Inc. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/internal.h" +#include "libavutil/aarch64/cpu.h" +#include "libavcodec/vp9dsp.h" +#include "vp9dsp_init.h" + +#define declare_fpel(type, sz) \ +void ff_vp9_##type##sz##_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define declare_copy_avg(sz) \ + declare_fpel(copy, sz); \ + declare_fpel(avg , sz) + +#define decl_mc_func(op, filter, dir, sz) \ +void ff_vp9_##op##_##filter##sz##_##dir##_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define define_8tap_2d_fn(op, filter, sz) \ +static void op##_##filter##sz##_hv_neon(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + LOCAL_ALIGNED_16(uint8_t, temp, [((1 + (sz < 64)) * sz + 8) * sz]); \ + /* We only need h + 7 lines, but the horizontal filter assumes an \ + * even number of rows, so filter h + 8 lines here. */ \ + ff_vp9_put_##filter##sz##_h_neon(temp, sz, \ + src - 3 * src_stride, src_stride, \ + h + 8, mx, 0); \ + ff_vp9_##op##_##filter##sz##_v_neon(dst, dst_stride, \ + temp + 3 * sz, sz, \ + h, 0, my); \ +} + +#define decl_filter_funcs(op, dir, sz) \ + decl_mc_func(op, regular, dir, sz); \ + decl_mc_func(op, sharp, dir, sz); \ + decl_mc_func(op, smooth, dir, sz) + +#define decl_mc_funcs(sz) \ + decl_filter_funcs(put, h, sz); \ + decl_filter_funcs(avg, h, sz); \ + decl_filter_funcs(put, v, sz); \ + decl_filter_funcs(avg, v, sz); \ + decl_filter_funcs(put, hv, sz); \ + decl_filter_funcs(avg, hv, sz) + +#define ff_vp9_copy32_neon ff_vp9_copy32_aarch64 +#define ff_vp9_copy64_neon ff_vp9_copy64_aarch64 + +declare_copy_avg(64); +declare_copy_avg(32); +declare_copy_avg(16); +declare_copy_avg(8); +declare_copy_avg(4); + +decl_mc_funcs(64); +decl_mc_funcs(32); +decl_mc_funcs(16); +decl_mc_funcs(8); +decl_mc_funcs(4); + +#define define_8tap_2d_funcs(sz) \ + define_8tap_2d_fn(put, regular, sz) \ + define_8tap_2d_fn(put, sharp, sz) \ + define_8tap_2d_fn(put, smooth, sz) \ + define_8tap_2d_fn(avg, regular, sz) \ + define_8tap_2d_fn(avg, sharp, sz) \ + define_8tap_2d_fn(avg, smooth, sz) + +define_8tap_2d_funcs(64) +define_8tap_2d_funcs(32) +define_8tap_2d_funcs(16) +define_8tap_2d_funcs(8) +define_8tap_2d_funcs(4) + +static av_cold void vp9dsp_mc_init_aarch64(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + +#define init_fpel(idx1, idx2, sz, type, suffix) \ + dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_BILINEAR ][idx2][0][0] = ff_vp9_##type##sz##suffix + +#define init_copy(idx, sz, suffix) \ + init_fpel(idx, 0, sz, copy, suffix) + +#define init_avg(idx, sz, suffix) \ + init_fpel(idx, 1, sz, avg, suffix) + +#define init_copy_avg(idx, sz) \ + init_copy(idx, sz, _neon); \ + init_avg (idx, sz, _neon) + + if (have_armv8(cpu_flags)) { + init_copy(0, 64, _aarch64); + init_copy(1, 32, _aarch64); + } + + if (have_neon(cpu_flags)) { +#define init_mc_func(idx1, idx2, op, filter, fname, dir, mx, my, sz, pfx) \ + dsp->mc[idx1][filter][idx2][mx][my] = pfx##op##_##fname##sz##_##dir##_neon + +#define init_mc_funcs(idx, dir, mx, my, sz, pfx) \ + init_mc_func(idx, 0, put, FILTER_8TAP_REGULAR, regular, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 0, put, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 0, put, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_REGULAR, regular, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_SHARP, sharp, dir, mx, my, sz, pfx); \ + init_mc_func(idx, 1, avg, FILTER_8TAP_SMOOTH, smooth, dir, mx, my, sz, pfx) + +#define init_mc_funcs_dirs(idx, sz) \ + init_mc_funcs(idx, h, 1, 0, sz, ff_vp9_); \ + init_mc_funcs(idx, v, 0, 1, sz, ff_vp9_); \ + init_mc_funcs(idx, hv, 1, 1, sz,) + + init_avg(0, 64, _neon); + init_avg(1, 32, _neon); + init_copy_avg(2, 16); + init_copy_avg(3, 8); + init_copy_avg(4, 4); + + init_mc_funcs_dirs(0, 64); + init_mc_funcs_dirs(1, 32); + init_mc_funcs_dirs(2, 16); + init_mc_funcs_dirs(3, 8); + init_mc_funcs_dirs(4, 4); + } +} + +#define define_itxfm(type_a, type_b, sz) \ +void ff_vp9_##type_a##_##type_b##_##sz##x##sz##_add_neon(uint8_t *_dst, \ + ptrdiff_t stride, \ + int16_t *_block, int eob) + +#define define_itxfm_funcs(sz) \ + define_itxfm(idct, idct, sz); \ + define_itxfm(iadst, idct, sz); \ + define_itxfm(idct, iadst, sz); \ + define_itxfm(iadst, iadst, sz) + +define_itxfm_funcs(4); +define_itxfm_funcs(8); +define_itxfm_funcs(16); +define_itxfm(idct, idct, 32); +define_itxfm(iwht, iwht, 4); + + +static av_cold void vp9dsp_itxfm_init_aarch64(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { +#define init_itxfm(tx, sz) \ + dsp->itxfm_add[tx][DCT_DCT] = ff_vp9_idct_idct_##sz##_add_neon; \ + dsp->itxfm_add[tx][DCT_ADST] = ff_vp9_iadst_idct_##sz##_add_neon; \ + dsp->itxfm_add[tx][ADST_DCT] = ff_vp9_idct_iadst_##sz##_add_neon; \ + dsp->itxfm_add[tx][ADST_ADST] = ff_vp9_iadst_iadst_##sz##_add_neon + +#define init_idct(tx, nm) \ + dsp->itxfm_add[tx][DCT_DCT] = \ + dsp->itxfm_add[tx][ADST_DCT] = \ + dsp->itxfm_add[tx][DCT_ADST] = \ + dsp->itxfm_add[tx][ADST_ADST] = ff_vp9_##nm##_add_neon + + init_itxfm(TX_4X4, 4x4); + init_itxfm(TX_8X8, 8x8); + init_itxfm(TX_16X16, 16x16); + init_idct(TX_32X32, idct_idct_32x32); + init_idct(4, iwht_iwht_4x4); + } +} + +#define define_loop_filter(dir, wd, len) \ +void ff_vp9_loop_filter_##dir##_##wd##_##len##_neon(uint8_t *dst, ptrdiff_t stride, int E, int I, int H) + +#define define_loop_filters(wd, len) \ + define_loop_filter(h, wd, len); \ + define_loop_filter(v, wd, len) + +define_loop_filters(4, 8); +define_loop_filters(8, 8); +define_loop_filters(16, 8); + +define_loop_filters(16, 16); + +define_loop_filters(44, 16); +define_loop_filters(48, 16); +define_loop_filters(84, 16); +define_loop_filters(88, 16); + +static av_cold void vp9dsp_loopfilter_init_aarch64(VP9DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + dsp->loop_filter_8[0][1] = ff_vp9_loop_filter_v_4_8_neon; + dsp->loop_filter_8[0][0] = ff_vp9_loop_filter_h_4_8_neon; + dsp->loop_filter_8[1][1] = ff_vp9_loop_filter_v_8_8_neon; + dsp->loop_filter_8[1][0] = ff_vp9_loop_filter_h_8_8_neon; + dsp->loop_filter_8[2][1] = ff_vp9_loop_filter_v_16_8_neon; + dsp->loop_filter_8[2][0] = ff_vp9_loop_filter_h_16_8_neon; + + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_neon; + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_neon; + + dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_neon; + dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_neon; + dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_neon; + dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_neon; + dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_neon; + dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_neon; + dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_neon; + dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_neon; + } +} + +av_cold void ff_vp9dsp_init_aarch64(VP9DSPContext *dsp, int bpp) +{ + if (bpp == 10) { + ff_vp9dsp_init_10bpp_aarch64(dsp); + return; + } else if (bpp == 12) { + ff_vp9dsp_init_12bpp_aarch64(dsp); + return; + } else if (bpp != 8) + return; + + vp9dsp_mc_init_aarch64(dsp); + vp9dsp_loopfilter_init_aarch64(dsp); + vp9dsp_itxfm_init_aarch64(dsp); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.c new file mode 100644 index 000000000..6d09288ee --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.c @@ -0,0 +1,211 @@ +/* + * Common code between the AC-3 encoder and decoder + * Copyright (c) 2000 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Common code between the AC-3 encoder and decoder. + */ + +#include "libavutil/common.h" + +#include "avcodec.h" +#include "ac3.h" + +/** + * Starting frequency coefficient bin for each critical band. + */ +const uint8_t ff_ac3_band_start_tab[AC3_CRITICAL_BANDS+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, + 34, 37, 40, 43, 46, 49, 55, 61, 67, 73, + 79, 85, 97, 109, 121, 133, 157, 181, 205, 229, 253 +}; + +/** + * Map each frequency coefficient bin to the critical band that contains it. + */ +const uint8_t ff_ac3_bin_to_band_tab[253] = { + 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, + 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, + 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, + 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, + 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49 +}; + +static inline int calc_lowcomp1(int a, int b0, int b1, int c) +{ + if ((b0 + 256) == b1) { + a = c; + } else if (b0 > b1) { + a = FFMAX(a - 64, 0); + } + return a; +} + +static inline int calc_lowcomp(int a, int b0, int b1, int bin) +{ + if (bin < 7) { + return calc_lowcomp1(a, b0, b1, 384); + } else if (bin < 20) { + return calc_lowcomp1(a, b0, b1, 320); + } else { + return FFMAX(a - 128, 0); + } +} + +void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd, + int16_t *band_psd) +{ + int bin, band; + + /* exponent mapping to PSD */ + for (bin = start; bin < end; bin++) { + psd[bin]=(3072 - (exp[bin] << 7)); + } + + /* PSD integration */ + bin = start; + band = ff_ac3_bin_to_band_tab[start]; + do { + int v = psd[bin++]; + int band_end = FFMIN(ff_ac3_band_start_tab[band+1], end); + for (; bin < band_end; bin++) { + int max = FFMAX(v, psd[bin]); + /* logadd */ + int adr = FFMIN(max - ((v + psd[bin] + 1) >> 1), 255); + v = max + ff_ac3_log_add_tab[adr]; + } + band_psd[band++] = v; + } while (end > ff_ac3_band_start_tab[band]); +} + +int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd, + int start, int end, int fast_gain, int is_lfe, + int dba_mode, int dba_nsegs, uint8_t *dba_offsets, + uint8_t *dba_lengths, uint8_t *dba_values, + int16_t *mask) +{ + int16_t excite[AC3_CRITICAL_BANDS]; /* excitation */ + int band; + int band_start, band_end, begin, end1; + int lowcomp, fastleak, slowleak; + + if (end <= 0) + return AVERROR_INVALIDDATA; + + /* excitation function */ + band_start = ff_ac3_bin_to_band_tab[start]; + band_end = ff_ac3_bin_to_band_tab[end-1] + 1; + + if (band_start == 0) { + lowcomp = 0; + lowcomp = calc_lowcomp1(lowcomp, band_psd[0], band_psd[1], 384); + excite[0] = band_psd[0] - fast_gain - lowcomp; + lowcomp = calc_lowcomp1(lowcomp, band_psd[1], band_psd[2], 384); + excite[1] = band_psd[1] - fast_gain - lowcomp; + begin = 7; + for (band = 2; band < 7; band++) { + if (!(is_lfe && band == 6)) + lowcomp = calc_lowcomp1(lowcomp, band_psd[band], band_psd[band+1], 384); + fastleak = band_psd[band] - fast_gain; + slowleak = band_psd[band] - s->slow_gain; + excite[band] = fastleak - lowcomp; + if (!(is_lfe && band == 6)) { + if (band_psd[band] <= band_psd[band+1]) { + begin = band + 1; + break; + } + } + } + + end1 = FFMIN(band_end, 22); + for (band = begin; band < end1; band++) { + if (!(is_lfe && band == 6)) + lowcomp = calc_lowcomp(lowcomp, band_psd[band], band_psd[band+1], band); + fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain); + slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain); + excite[band] = FFMAX(fastleak - lowcomp, slowleak); + } + begin = 22; + } else { + /* coupling channel */ + begin = band_start; + fastleak = (s->cpl_fast_leak << 8) + 768; + slowleak = (s->cpl_slow_leak << 8) + 768; + } + + for (band = begin; band < band_end; band++) { + fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain); + slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain); + excite[band] = FFMAX(fastleak, slowleak); + } + + /* compute masking curve */ + + for (band = band_start; band < band_end; band++) { + int tmp = s->db_per_bit - band_psd[band]; + if (tmp > 0) { + excite[band] += tmp >> 2; + } + mask[band] = FFMAX(ff_ac3_hearing_threshold_tab[band >> s->sr_shift][s->sr_code], excite[band]); + } + + /* delta bit allocation */ + + if (dba_mode == DBA_REUSE || dba_mode == DBA_NEW) { + int i, seg, delta; + if (dba_nsegs > 8) + return -1; + band = band_start; + for (seg = 0; seg < dba_nsegs; seg++) { + band += dba_offsets[seg]; + if (band >= AC3_CRITICAL_BANDS || dba_lengths[seg] > AC3_CRITICAL_BANDS-band) + return -1; + if (dba_values[seg] >= 4) { + delta = (dba_values[seg] - 3) * 128; + } else { + delta = (dba_values[seg] - 4) * 128; + } + for (i = 0; i < dba_lengths[seg]; i++) { + mask[band++] += delta; + } + } + } + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.h new file mode 100644 index 000000000..f8f6a81f4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3.h @@ -0,0 +1,263 @@ +/* + * Common code between the AC-3 encoder and decoder + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Common code between the AC-3 encoder and decoder. + */ + +#ifndef AVCODEC_AC3_H +#define AVCODEC_AC3_H + +#define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ +#define EAC3_MAX_CHANNELS 16 /**< maximum number of channels in EAC3 */ +#define AC3_MAX_CHANNELS 7 /**< maximum number of channels, including coupling channel */ +#define CPL_CH 0 /**< coupling channel index */ + +#define AC3_MAX_COEFS 256 +#define AC3_BLOCK_SIZE 256 +#define AC3_MAX_BLOCKS 6 +#define AC3_FRAME_SIZE (AC3_MAX_BLOCKS * 256) +#define AC3_WINDOW_SIZE (AC3_BLOCK_SIZE * 2) +#define AC3_CRITICAL_BANDS 50 +#define AC3_MAX_CPL_BANDS 18 + +#include "libavutil/opt.h" +#include "avcodec.h" +#include "ac3tab.h" + +/* exponent encoding strategy */ +#define EXP_REUSE 0 +#define EXP_NEW 1 + +#define EXP_D15 1 +#define EXP_D25 2 +#define EXP_D45 3 + +#ifndef USE_FIXED +#define USE_FIXED 0 +#endif + +#if USE_FIXED + +#define FFT_FLOAT 0 + +#define FIXR(a) ((int)((a) * 0 + 0.5)) +#define FIXR12(a) ((int)((a) * 4096 + 0.5)) +#define FIXR15(a) ((int)((a) * 32768 + 0.5)) +#define ROUND15(x) ((x) + 16384) >> 15 + +#define AC3_RENAME(x) x ## _fixed +#define AC3_NORM(norm) (1<<24)/(norm) +#define AC3_MUL(a,b) ((((int64_t) (a)) * (b))>>12) +#define AC3_RANGE(x) ((x)|(((x)&128)<<1)) +#define AC3_HEAVY_RANGE(x) ((x)<<1) +#define AC3_DYNAMIC_RANGE(x) (x) +#define AC3_SPX_BLEND(x) (x) +#define AC3_DYNAMIC_RANGE1 0 + +typedef int INTFLOAT; +typedef int16_t SHORTFLOAT; + +#else /* USE_FIXED */ + +#define FIXR(x) ((float)(x)) +#define FIXR12(x) ((float)(x)) +#define FIXR15(x) ((float)(x)) +#define ROUND15(x) (x) + +#define AC3_RENAME(x) x +#define AC3_NORM(norm) (1.0f/(norm)) +#define AC3_MUL(a,b) ((a) * (b)) +#define AC3_RANGE(x) (dynamic_range_tab[(x)]) +#define AC3_HEAVY_RANGE(x) (ff_ac3_heavy_dynamic_range_tab[(x)]) +#define AC3_DYNAMIC_RANGE(x) (powf(x, s->drc_scale)) +#define AC3_SPX_BLEND(x) (x)* (1.0f/32) +#define AC3_DYNAMIC_RANGE1 1.0f + +typedef float INTFLOAT; +typedef float SHORTFLOAT; + +#endif /* USE_FIXED */ + +#define AC3_LEVEL(x) ROUND15((x) * FIXR15(M_SQRT1_2)) + +/* pre-defined gain values */ +#define LEVEL_PLUS_3DB M_SQRT2 +#define LEVEL_PLUS_1POINT5DB 1.1892071150027209 +#define LEVEL_MINUS_1POINT5DB 0.8408964152537145 +#define LEVEL_MINUS_3DB M_SQRT1_2 +#define LEVEL_MINUS_4POINT5DB 0.5946035575013605 +#define LEVEL_MINUS_6DB 0.5000000000000000 +#define LEVEL_MINUS_9DB 0.3535533905932738 +#define LEVEL_ZERO 0.0000000000000000 +#define LEVEL_ONE 1.0000000000000000 + +/** Delta bit allocation strategy */ +typedef enum { + DBA_REUSE = 0, + DBA_NEW, + DBA_NONE, + DBA_RESERVED +} AC3DeltaStrategy; + +/** Channel mode (audio coding mode) */ +typedef enum { + AC3_CHMODE_DUALMONO = 0, + AC3_CHMODE_MONO, + AC3_CHMODE_STEREO, + AC3_CHMODE_3F, + AC3_CHMODE_2F1R, + AC3_CHMODE_3F1R, + AC3_CHMODE_2F2R, + AC3_CHMODE_3F2R +} AC3ChannelMode; + +/** Dolby Surround mode */ +typedef enum AC3DolbySurroundMode { + AC3_DSURMOD_NOTINDICATED = 0, + AC3_DSURMOD_OFF, + AC3_DSURMOD_ON, + AC3_DSURMOD_RESERVED +} AC3DolbySurroundMode; + +/** Dolby Surround EX mode */ +typedef enum AC3DolbySurroundEXMode { + AC3_DSUREXMOD_NOTINDICATED = 0, + AC3_DSUREXMOD_OFF, + AC3_DSUREXMOD_ON, + AC3_DSUREXMOD_PLIIZ +} AC3DolbySurroundEXMode; + +/** Dolby Headphone mode */ +typedef enum AC3DolbyHeadphoneMode { + AC3_DHEADPHONMOD_NOTINDICATED = 0, + AC3_DHEADPHONMOD_OFF, + AC3_DHEADPHONMOD_ON, + AC3_DHEADPHONMOD_RESERVED +} AC3DolbyHeadphoneMode; + +/** Preferred Stereo Downmix mode */ +typedef enum AC3PreferredStereoDownmixMode { + AC3_DMIXMOD_NOTINDICATED = 0, + AC3_DMIXMOD_LTRT, + AC3_DMIXMOD_LORO, + AC3_DMIXMOD_DPLII // reserved value in A/52, but used by encoders to indicate DPL2 +} AC3PreferredStereoDownmixMode; + +typedef struct AC3BitAllocParameters { + int sr_code; + int sr_shift; + int slow_gain, slow_decay, fast_decay, db_per_bit, floor; + int cpl_fast_leak, cpl_slow_leak; +} AC3BitAllocParameters; + +/** + * @struct AC3HeaderInfo + * Coded AC-3 header values up to the lfeon element, plus derived values. + */ +typedef struct AC3HeaderInfo { + /** @name Coded elements + * @{ + */ + uint16_t sync_word; + uint16_t crc1; + uint8_t sr_code; + uint8_t bitstream_id; + uint8_t bitstream_mode; + uint8_t channel_mode; + uint8_t lfe_on; + uint8_t frame_type; + int substreamid; ///< substream identification + int center_mix_level; ///< Center mix level index + int surround_mix_level; ///< Surround mix level index + uint16_t channel_map; + int num_blocks; ///< number of audio blocks + int dolby_surround_mode; + /** @} */ + + /** @name Derived values + * @{ + */ + uint8_t sr_shift; + uint16_t sample_rate; + uint32_t bit_rate; + uint8_t channels; + uint16_t frame_size; + uint64_t channel_layout; + /** @} */ +} AC3HeaderInfo; + +typedef enum { + EAC3_FRAME_TYPE_INDEPENDENT = 0, + EAC3_FRAME_TYPE_DEPENDENT, + EAC3_FRAME_TYPE_AC3_CONVERT, + EAC3_FRAME_TYPE_RESERVED +} EAC3FrameType; + +void ff_ac3_common_init(void); + +/** + * Calculate the log power-spectral density of the input signal. + * This gives a rough estimate of signal power in the frequency domain by using + * the spectral envelope (exponents). The psd is also separately grouped + * into critical bands for use in the calculating the masking curve. + * 128 units in psd = -6 dB. The dbknee parameter in AC3BitAllocParameters + * determines the reference level. + * + * @param[in] exp frequency coefficient exponents + * @param[in] start starting bin location + * @param[in] end ending bin location + * @param[out] psd signal power for each frequency bin + * @param[out] band_psd signal power for each critical band + */ +void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd, + int16_t *band_psd); + +/** + * Calculate the masking curve. + * First, the excitation is calculated using parameters in s and the signal + * power in each critical band. The excitation is compared with a predefined + * hearing threshold table to produce the masking curve. If delta bit + * allocation information is provided, it is used for adjusting the masking + * curve, usually to give a closer match to a better psychoacoustic model. + * + * @param[in] s adjustable bit allocation parameters + * @param[in] band_psd signal power for each critical band + * @param[in] start starting bin location + * @param[in] end ending bin location + * @param[in] fast_gain fast gain (estimated signal-to-mask ratio) + * @param[in] is_lfe whether or not the channel being processed is the LFE + * @param[in] dba_mode delta bit allocation mode (none, reuse, or new) + * @param[in] dba_nsegs number of delta segments + * @param[in] dba_offsets location offsets for each segment + * @param[in] dba_lengths length of each segment + * @param[in] dba_values delta bit allocation for each segment + * @param[out] mask calculated masking curve + * @return returns 0 for success, non-zero for error + */ +int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd, + int start, int end, int fast_gain, int is_lfe, + int dba_mode, int dba_nsegs, uint8_t *dba_offsets, + uint8_t *dba_lengths, uint8_t *dba_values, + int16_t *mask); + +#endif /* AVCODEC_AC3_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser.c new file mode 100644 index 000000000..1e203ae6a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser.c @@ -0,0 +1,258 @@ +/* + * AC-3 parser + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/channel_layout.h" +#include "parser.h" +#include "ac3_parser.h" +#include "ac3_parser_internal.h" +#include "aac_ac3_parser.h" +#include "get_bits.h" + + +#define AC3_HEADER_SIZE 7 + +#if CONFIG_AC3_PARSER + +static const uint8_t eac3_blocks[4] = { + 1, 2, 3, 6 +}; + +/** + * Table for center mix levels + * reference: Section 5.4.2.4 cmixlev + */ +static const uint8_t center_levels[4] = { 4, 5, 6, 5 }; + +/** + * Table for surround mix levels + * reference: Section 5.4.2.5 surmixlev + */ +static const uint8_t surround_levels[4] = { 4, 6, 7, 6 }; + + +int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) +{ + int frame_size_code; + + memset(hdr, 0, sizeof(*hdr)); + + hdr->sync_word = get_bits(gbc, 16); + if(hdr->sync_word != 0x0B77) + return AAC_AC3_PARSE_ERROR_SYNC; + + /* read ahead to bsid to distinguish between AC-3 and E-AC-3 */ + hdr->bitstream_id = show_bits_long(gbc, 29) & 0x1F; + if(hdr->bitstream_id > 16) + return AAC_AC3_PARSE_ERROR_BSID; + + hdr->num_blocks = 6; + + /* set default mix levels */ + hdr->center_mix_level = 5; // -4.5dB + hdr->surround_mix_level = 6; // -6.0dB + + /* set default dolby surround mode */ + hdr->dolby_surround_mode = AC3_DSURMOD_NOTINDICATED; + + if(hdr->bitstream_id <= 10) { + /* Normal AC-3 */ + hdr->crc1 = get_bits(gbc, 16); + hdr->sr_code = get_bits(gbc, 2); + if(hdr->sr_code == 3) + return AAC_AC3_PARSE_ERROR_SAMPLE_RATE; + + frame_size_code = get_bits(gbc, 6); + if(frame_size_code > 37) + return AAC_AC3_PARSE_ERROR_FRAME_SIZE; + + skip_bits(gbc, 5); // skip bsid, already got it + + hdr->bitstream_mode = get_bits(gbc, 3); + hdr->channel_mode = get_bits(gbc, 3); + + if(hdr->channel_mode == AC3_CHMODE_STEREO) { + hdr->dolby_surround_mode = get_bits(gbc, 2); + } else { + if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO) + hdr-> center_mix_level = center_levels[get_bits(gbc, 2)]; + if(hdr->channel_mode & 4) + hdr->surround_mix_level = surround_levels[get_bits(gbc, 2)]; + } + hdr->lfe_on = get_bits1(gbc); + + hdr->sr_shift = FFMAX(hdr->bitstream_id, 8) - 8; + hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift; + hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift; + hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; + hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2; + hdr->frame_type = EAC3_FRAME_TYPE_AC3_CONVERT; //EAC3_FRAME_TYPE_INDEPENDENT; + hdr->substreamid = 0; + } else { + /* Enhanced AC-3 */ + hdr->crc1 = 0; + hdr->frame_type = get_bits(gbc, 2); + if(hdr->frame_type == EAC3_FRAME_TYPE_RESERVED) + return AAC_AC3_PARSE_ERROR_FRAME_TYPE; + + hdr->substreamid = get_bits(gbc, 3); + + hdr->frame_size = (get_bits(gbc, 11) + 1) << 1; + if(hdr->frame_size < AC3_HEADER_SIZE) + return AAC_AC3_PARSE_ERROR_FRAME_SIZE; + + hdr->sr_code = get_bits(gbc, 2); + if (hdr->sr_code == 3) { + int sr_code2 = get_bits(gbc, 2); + if(sr_code2 == 3) + return AAC_AC3_PARSE_ERROR_SAMPLE_RATE; + hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2; + hdr->sr_shift = 1; + } else { + hdr->num_blocks = eac3_blocks[get_bits(gbc, 2)]; + hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code]; + hdr->sr_shift = 0; + } + + hdr->channel_mode = get_bits(gbc, 3); + hdr->lfe_on = get_bits1(gbc); + + hdr->bit_rate = 8LL * hdr->frame_size * hdr->sample_rate / + (hdr->num_blocks * 256); + hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; + } + hdr->channel_layout = avpriv_ac3_channel_layout_tab[hdr->channel_mode]; + if (hdr->lfe_on) + hdr->channel_layout |= AV_CH_LOW_FREQUENCY; + + return 0; +} + +// TODO: Better way to pass AC3HeaderInfo fields to mov muxer. +int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const uint8_t *buf, + size_t size) +{ + GetBitContext gb; + AC3HeaderInfo *hdr; + int err; + + if (!*phdr) + *phdr = av_mallocz(sizeof(AC3HeaderInfo)); + if (!*phdr) + return AVERROR(ENOMEM); + hdr = *phdr; + + err = init_get_bits8(&gb, buf, size); + if (err < 0) + return AVERROR_INVALIDDATA; + err = ff_ac3_parse_header(&gb, hdr); + if (err < 0) + return AVERROR_INVALIDDATA; + + return get_bits_count(&gb); +} + +int av_ac3_parse_header(const uint8_t *buf, size_t size, + uint8_t *bitstream_id, uint16_t *frame_size) +{ + GetBitContext gb; + AC3HeaderInfo hdr; + int err; + + init_get_bits8(&gb, buf, size); + err = ff_ac3_parse_header(&gb, &hdr); + if (err < 0) + return AVERROR_INVALIDDATA; + + *bitstream_id = hdr.bitstream_id; + *frame_size = hdr.frame_size; + + return 0; +} + +static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, + int *need_next_header, int *new_frame_start) +{ + int err; + union { + uint64_t u64; + uint8_t u8[8 + AV_INPUT_BUFFER_PADDING_SIZE]; + } tmp = { av_be2ne64(state) }; + AC3HeaderInfo hdr; + GetBitContext gbc; + + init_get_bits(&gbc, tmp.u8+8-AC3_HEADER_SIZE, 54); + err = ff_ac3_parse_header(&gbc, &hdr); + + if(err < 0) + return 0; + + hdr_info->sample_rate = hdr.sample_rate; + hdr_info->bit_rate = hdr.bit_rate; + hdr_info->channels = hdr.channels; + hdr_info->channel_layout = hdr.channel_layout; + hdr_info->samples = hdr.num_blocks * 256; + hdr_info->service_type = hdr.bitstream_mode; + if (hdr.bitstream_mode == 0x7 && hdr.channels > 1) + hdr_info->service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; + if(hdr.bitstream_id>10) + hdr_info->codec_id = AV_CODEC_ID_EAC3; + else if (hdr_info->codec_id == AV_CODEC_ID_NONE) + hdr_info->codec_id = AV_CODEC_ID_AC3; + + *new_frame_start = (hdr.frame_type != EAC3_FRAME_TYPE_DEPENDENT); + *need_next_header = *new_frame_start || (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT); + return hdr.frame_size; +} + +static av_cold int ac3_parse_init(AVCodecParserContext *s1) +{ + AACAC3ParseContext *s = s1->priv_data; + s->header_size = AC3_HEADER_SIZE; + s->sync = ac3_sync; + return 0; +} + + +AVCodecParser ff_ac3_parser = { + .codec_ids = { AV_CODEC_ID_AC3, AV_CODEC_ID_EAC3 }, + .priv_data_size = sizeof(AACAC3ParseContext), + .parser_init = ac3_parse_init, + .parser_parse = ff_aac_ac3_parse, + .parser_close = ff_parse_close, +}; + +#else + +int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const uint8_t *buf, + size_t size) +{ + return AVERROR(ENOSYS); +} + +int av_ac3_parse_header(const uint8_t *buf, size_t size, + uint8_t *bitstream_id, uint16_t *frame_size) +{ + return AVERROR(ENOSYS); +} +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser.h new file mode 100644 index 000000000..ff8cc4cf0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser.h @@ -0,0 +1,36 @@ +/* + * AC-3 parser prototypes + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AC3_PARSER_H +#define AVCODEC_AC3_PARSER_H + +#include +#include + +/** + * Extract the bitstream ID and the frame size from AC-3 data. + */ +int av_ac3_parse_header(const uint8_t *buf, size_t size, + uint8_t *bitstream_id, uint16_t *frame_size); + + +#endif /* AVCODEC_AC3_PARSER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser_internal.h new file mode 100644 index 000000000..3648802a7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3_parser_internal.h @@ -0,0 +1,42 @@ +/* + * AC-3 parser internal code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AC3_PARSER_INTERNAL_H +#define AVCODEC_AC3_PARSER_INTERNAL_H + +#include "ac3.h" +#include "get_bits.h" + +/** + * Parse AC-3 frame header. + * Parse the header up to the lfeon element, which is the first 52 or 54 bits + * depending on the audio coding mode. + * @param[in] gbc BitContext containing the first 54 bits of the frame. + * @param[out] hdr Pointer to struct where header info is written. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the bsid (version) element is invalid, -3 if the fscod (sample rate) + * element is invalid, or -4 if the frmsizecod (bit rate) element is invalid. + */ +int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr); + +int avpriv_ac3_parse_header(AC3HeaderInfo **hdr, const uint8_t *buf, + size_t size); + +#endif /* AVCODEC_AC3_PARSER_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec.c new file mode 100644 index 000000000..eaa327a3e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec.c @@ -0,0 +1,1843 @@ +/* + * AC-3 Audio Decoder + * This code was developed as part of Google Summer of Code 2006. + * E-AC-3 support was added as part of Google Summer of Code 2007. + * + * Copyright (c) 2006 Kartikey Mahendra BHATT (bhattkm at gmail dot com) + * Copyright (c) 2007-2008 Bartlomiej Wolowiec + * Copyright (c) 2007 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include "libavutil/channel_layout.h" +#include "libavutil/crc.h" +#include "libavutil/downmix_info.h" +#include "libavutil/opt.h" +#include "bswapdsp.h" +#include "internal.h" +#include "aac_ac3_parser.h" +#include "ac3_parser_internal.h" +#include "ac3dec.h" +#include "ac3dec_data.h" +#include "kbdwin.h" + +/** + * table for ungrouping 3 values in 7 bits. + * used for exponents and bap=2 mantissas + */ +static uint8_t ungroup_3_in_7_bits_tab[128][3]; + +/** tables for ungrouping mantissas */ +static int b1_mantissas[32][3]; +static int b2_mantissas[128][3]; +static int b3_mantissas[8]; +static int b4_mantissas[128][2]; +static int b5_mantissas[16]; + +/** + * Quantization table: levels for symmetric. bits for asymmetric. + * reference: Table 7.18 Mapping of bap to Quantizer + */ +static const uint8_t quantization_tab[16] = { + 0, 3, 5, 7, 11, 15, + 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 +}; + +#if (!USE_FIXED) +/** dynamic range table. converts codes to scale factors. */ +static float dynamic_range_tab[256]; +float ff_ac3_heavy_dynamic_range_tab[256]; +#endif + +/** Adjustments in dB gain */ +static const float gain_levels[9] = { + LEVEL_PLUS_3DB, + LEVEL_PLUS_1POINT5DB, + LEVEL_ONE, + LEVEL_MINUS_1POINT5DB, + LEVEL_MINUS_3DB, + LEVEL_MINUS_4POINT5DB, + LEVEL_MINUS_6DB, + LEVEL_ZERO, + LEVEL_MINUS_9DB +}; + +/** Adjustments in dB gain (LFE, +10 to -21 dB) */ +static const float gain_levels_lfe[32] = { + 3.162275, 2.818382, 2.511886, 2.238719, 1.995261, 1.778278, 1.584893, + 1.412536, 1.258924, 1.122018, 1.000000, 0.891251, 0.794328, 0.707946, + 0.630957, 0.562341, 0.501187, 0.446683, 0.398107, 0.354813, 0.316227, + 0.281838, 0.251188, 0.223872, 0.199526, 0.177828, 0.158489, 0.141253, + 0.125892, 0.112201, 0.100000, 0.089125 +}; + +/** + * Table for default stereo downmixing coefficients + * reference: Section 7.8.2 Downmixing Into Two Channels + */ +static const uint8_t ac3_default_coeffs[8][5][2] = { + { { 2, 7 }, { 7, 2 }, }, + { { 4, 4 }, }, + { { 2, 7 }, { 7, 2 }, }, + { { 2, 7 }, { 5, 5 }, { 7, 2 }, }, + { { 2, 7 }, { 7, 2 }, { 6, 6 }, }, + { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 8, 8 }, }, + { { 2, 7 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, }, + { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, }, +}; + +/** + * Symmetrical Dequantization + * reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization + * Tables 7.19 to 7.23 + */ +static inline int +symmetric_dequant(int code, int levels) +{ + return ((code - (levels >> 1)) * (1 << 24)) / levels; +} + +/* + * Initialize tables at runtime. + */ +static av_cold void ac3_tables_init(void) +{ + int i; + + /* generate table for ungrouping 3 values in 7 bits + reference: Section 7.1.3 Exponent Decoding */ + for (i = 0; i < 128; i++) { + ungroup_3_in_7_bits_tab[i][0] = i / 25; + ungroup_3_in_7_bits_tab[i][1] = (i % 25) / 5; + ungroup_3_in_7_bits_tab[i][2] = (i % 25) % 5; + } + + /* generate grouped mantissa tables + reference: Section 7.3.5 Ungrouping of Mantissas */ + for (i = 0; i < 32; i++) { + /* bap=1 mantissas */ + b1_mantissas[i][0] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][0], 3); + b1_mantissas[i][1] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][1], 3); + b1_mantissas[i][2] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][2], 3); + } + for (i = 0; i < 128; i++) { + /* bap=2 mantissas */ + b2_mantissas[i][0] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][0], 5); + b2_mantissas[i][1] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][1], 5); + b2_mantissas[i][2] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][2], 5); + + /* bap=4 mantissas */ + b4_mantissas[i][0] = symmetric_dequant(i / 11, 11); + b4_mantissas[i][1] = symmetric_dequant(i % 11, 11); + } + /* generate ungrouped mantissa tables + reference: Tables 7.21 and 7.23 */ + for (i = 0; i < 7; i++) { + /* bap=3 mantissas */ + b3_mantissas[i] = symmetric_dequant(i, 7); + } + for (i = 0; i < 15; i++) { + /* bap=5 mantissas */ + b5_mantissas[i] = symmetric_dequant(i, 15); + } + +#if (!USE_FIXED) + /* generate dynamic range table + reference: Section 7.7.1 Dynamic Range Control */ + for (i = 0; i < 256; i++) { + int v = (i >> 5) - ((i >> 7) << 3) - 5; + dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20); + } + + /* generate compr dynamic range table + reference: Section 7.7.2 Heavy Compression */ + for (i = 0; i < 256; i++) { + int v = (i >> 4) - ((i >> 7) << 4) - 4; + ff_ac3_heavy_dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0xF) | 0x10); + } +#endif +} + +/** + * AVCodec initialization + */ +static av_cold int ac3_decode_init(AVCodecContext *avctx) +{ + AC3DecodeContext *s = avctx->priv_data; + int i; + + s->avctx = avctx; + + ac3_tables_init(); + ff_mdct_init(&s->imdct_256, 8, 1, 1.0); + ff_mdct_init(&s->imdct_512, 9, 1, 1.0); + AC3_RENAME(ff_kbd_window_init)(s->window, 5.0, 256); + ff_bswapdsp_init(&s->bdsp); + +#if (USE_FIXED) + s->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & AV_CODEC_FLAG_BITEXACT); +#else + s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + ff_fmt_convert_init(&s->fmt_conv, avctx); +#endif + + ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT); + av_lfg_init(&s->dith_state, 0); + + if (USE_FIXED) + avctx->sample_fmt = AV_SAMPLE_FMT_S16P; + else + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + + /* allow downmixing to stereo or mono */ + if (avctx->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) + avctx->channels = 1; + else if (avctx->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) + avctx->channels = 2; + s->downmixed = 1; + + for (i = 0; i < AC3_MAX_CHANNELS; i++) { + s->xcfptr[i] = s->transform_coeffs[i]; + s->dlyptr[i] = s->delay[i]; + } + + return 0; +} + +/** + * Parse the 'sync info' and 'bit stream info' from the AC-3 bitstream. + * GetBitContext within AC3DecodeContext must point to + * the start of the synchronized AC-3 bitstream. + */ +static int ac3_parse_header(AC3DecodeContext *s) +{ + GetBitContext *gbc = &s->gbc; + int i; + + /* read the rest of the bsi. read twice for dual mono mode. */ + i = !s->channel_mode; + do { + s->dialog_normalization[(!s->channel_mode)-i] = -get_bits(gbc, 5); + if (s->dialog_normalization[(!s->channel_mode)-i] == 0) { + s->dialog_normalization[(!s->channel_mode)-i] = -31; + } + if (s->target_level != 0) { + s->level_gain[(!s->channel_mode)-i] = powf(2.0f, + (float)(s->target_level - + s->dialog_normalization[(!s->channel_mode)-i])/6.0f); + } + if (s->compression_exists[(!s->channel_mode)-i] = get_bits1(gbc)) { + s->heavy_dynamic_range[(!s->channel_mode)-i] = + AC3_HEAVY_RANGE(get_bits(gbc, 8)); + } + if (get_bits1(gbc)) + skip_bits(gbc, 8); //skip language code + if (get_bits1(gbc)) + skip_bits(gbc, 7); //skip audio production information + } while (i--); + + skip_bits(gbc, 2); //skip copyright bit and original bitstream bit + + /* skip the timecodes or parse the Alternate Bit Stream Syntax */ + if (s->bitstream_id != 6) { + if (get_bits1(gbc)) + skip_bits(gbc, 14); //skip timecode1 + if (get_bits1(gbc)) + skip_bits(gbc, 14); //skip timecode2 + } else { + if (get_bits1(gbc)) { + s->preferred_downmix = get_bits(gbc, 2); + s->center_mix_level_ltrt = get_bits(gbc, 3); + s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7); + s->center_mix_level = get_bits(gbc, 3); + s->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7); + } + if (get_bits1(gbc)) { + s->dolby_surround_ex_mode = get_bits(gbc, 2); + s->dolby_headphone_mode = get_bits(gbc, 2); + skip_bits(gbc, 10); // skip adconvtyp (1), xbsi2 (8), encinfo (1) + } + } + + /* skip additional bitstream info */ + if (get_bits1(gbc)) { + i = get_bits(gbc, 6); + do { + skip_bits(gbc, 8); + } while (i--); + } + + return 0; +} + +/** + * Common function to parse AC-3 or E-AC-3 frame header + */ +static int parse_frame_header(AC3DecodeContext *s) +{ + AC3HeaderInfo hdr; + int err; + + err = ff_ac3_parse_header(&s->gbc, &hdr); + if (err) + return err; + + /* get decoding parameters from header info */ + s->bit_alloc_params.sr_code = hdr.sr_code; + s->bitstream_id = hdr.bitstream_id; + s->bitstream_mode = hdr.bitstream_mode; + s->channel_mode = hdr.channel_mode; + s->lfe_on = hdr.lfe_on; + s->bit_alloc_params.sr_shift = hdr.sr_shift; + s->sample_rate = hdr.sample_rate; + s->bit_rate = hdr.bit_rate; + s->channels = hdr.channels; + s->fbw_channels = s->channels - s->lfe_on; + s->lfe_ch = s->fbw_channels + 1; + s->frame_size = hdr.frame_size; + s->superframe_size += hdr.frame_size; + s->preferred_downmix = AC3_DMIXMOD_NOTINDICATED; + s->center_mix_level = hdr.center_mix_level; + s->center_mix_level_ltrt = 4; // -3.0dB + s->surround_mix_level = hdr.surround_mix_level; + s->surround_mix_level_ltrt = 4; // -3.0dB + s->lfe_mix_level_exists = 0; + s->num_blocks = hdr.num_blocks; + s->frame_type = hdr.frame_type; + s->substreamid = hdr.substreamid; + s->dolby_surround_mode = hdr.dolby_surround_mode; + s->dolby_surround_ex_mode = AC3_DSUREXMOD_NOTINDICATED; + s->dolby_headphone_mode = AC3_DHEADPHONMOD_NOTINDICATED; + + if (s->lfe_on) { + s->start_freq[s->lfe_ch] = 0; + s->end_freq[s->lfe_ch] = 7; + s->num_exp_groups[s->lfe_ch] = 2; + s->channel_in_cpl[s->lfe_ch] = 0; + } + + if (s->bitstream_id <= 10) { + s->eac3 = 0; + s->snr_offset_strategy = 2; + s->block_switch_syntax = 1; + s->dither_flag_syntax = 1; + s->bit_allocation_syntax = 1; + s->fast_gain_syntax = 0; + s->first_cpl_leak = 0; + s->dba_syntax = 1; + s->skip_syntax = 1; + memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht)); + return ac3_parse_header(s); + } else if (CONFIG_EAC3_DECODER) { + s->eac3 = 1; + return ff_eac3_parse_header(s); + } else { + av_log(s->avctx, AV_LOG_ERROR, "E-AC-3 support not compiled in\n"); + return AVERROR(ENOSYS); + } +} + +/** + * Set stereo downmixing coefficients based on frame header info. + * reference: Section 7.8.2 Downmixing Into Two Channels + */ +static int set_downmix_coeffs(AC3DecodeContext *s) +{ + int i; + float cmix = gain_levels[s-> center_mix_level]; + float smix = gain_levels[s->surround_mix_level]; + float norm0, norm1; + float downmix_coeffs[2][AC3_MAX_CHANNELS]; + + if (!s->downmix_coeffs[0]) { + s->downmix_coeffs[0] = av_malloc_array(2 * AC3_MAX_CHANNELS, + sizeof(**s->downmix_coeffs)); + if (!s->downmix_coeffs[0]) + return AVERROR(ENOMEM); + s->downmix_coeffs[1] = s->downmix_coeffs[0] + AC3_MAX_CHANNELS; + } + + for (i = 0; i < s->fbw_channels; i++) { + downmix_coeffs[0][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; + downmix_coeffs[1][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; + } + if (s->channel_mode > 1 && s->channel_mode & 1) { + downmix_coeffs[0][1] = downmix_coeffs[1][1] = cmix; + } + if (s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) { + int nf = s->channel_mode - 2; + downmix_coeffs[0][nf] = downmix_coeffs[1][nf] = smix * LEVEL_MINUS_3DB; + } + if (s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) { + int nf = s->channel_mode - 4; + downmix_coeffs[0][nf] = downmix_coeffs[1][nf+1] = smix; + } + + /* renormalize */ + norm0 = norm1 = 0.0; + for (i = 0; i < s->fbw_channels; i++) { + norm0 += downmix_coeffs[0][i]; + norm1 += downmix_coeffs[1][i]; + } + norm0 = 1.0f / norm0; + norm1 = 1.0f / norm1; + for (i = 0; i < s->fbw_channels; i++) { + downmix_coeffs[0][i] *= norm0; + downmix_coeffs[1][i] *= norm1; + } + + if (s->output_mode == AC3_CHMODE_MONO) { + for (i = 0; i < s->fbw_channels; i++) + downmix_coeffs[0][i] = (downmix_coeffs[0][i] + + downmix_coeffs[1][i]) * LEVEL_MINUS_3DB; + } + for (i = 0; i < s->fbw_channels; i++) { + s->downmix_coeffs[0][i] = FIXR12(downmix_coeffs[0][i]); + s->downmix_coeffs[1][i] = FIXR12(downmix_coeffs[1][i]); + } + + return 0; +} + +/** + * Decode the grouped exponents according to exponent strategy. + * reference: Section 7.1.3 Exponent Decoding + */ +static int decode_exponents(AC3DecodeContext *s, + GetBitContext *gbc, int exp_strategy, int ngrps, + uint8_t absexp, int8_t *dexps) +{ + int i, j, grp, group_size; + int dexp[256]; + int expacc, prevexp; + + /* unpack groups */ + group_size = exp_strategy + (exp_strategy == EXP_D45); + for (grp = 0, i = 0; grp < ngrps; grp++) { + expacc = get_bits(gbc, 7); + if (expacc >= 125) { + av_log(s->avctx, AV_LOG_ERROR, "expacc %d is out-of-range\n", expacc); + return AVERROR_INVALIDDATA; + } + dexp[i++] = ungroup_3_in_7_bits_tab[expacc][0]; + dexp[i++] = ungroup_3_in_7_bits_tab[expacc][1]; + dexp[i++] = ungroup_3_in_7_bits_tab[expacc][2]; + } + + /* convert to absolute exps and expand groups */ + prevexp = absexp; + for (i = 0, j = 0; i < ngrps * 3; i++) { + prevexp += dexp[i] - 2; + if (prevexp > 24U) { + av_log(s->avctx, AV_LOG_ERROR, "exponent %d is out-of-range\n", prevexp); + return AVERROR_INVALIDDATA; + } + switch (group_size) { + case 4: dexps[j++] = prevexp; + dexps[j++] = prevexp; + case 2: dexps[j++] = prevexp; + case 1: dexps[j++] = prevexp; + } + } + return 0; +} + +/** + * Generate transform coefficients for each coupled channel in the coupling + * range using the coupling coefficients and coupling coordinates. + * reference: Section 7.4.3 Coupling Coordinate Format + */ +static void calc_transform_coeffs_cpl(AC3DecodeContext *s) +{ + int bin, band, ch; + + bin = s->start_freq[CPL_CH]; + for (band = 0; band < s->num_cpl_bands; band++) { + int band_start = bin; + int band_end = bin + s->cpl_band_sizes[band]; + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (s->channel_in_cpl[ch]) { + int cpl_coord = s->cpl_coords[ch][band] << 5; + for (bin = band_start; bin < band_end; bin++) { + s->fixed_coeffs[ch][bin] = + MULH(s->fixed_coeffs[CPL_CH][bin] * (1 << 4), cpl_coord); + } + if (ch == 2 && s->phase_flags[band]) { + for (bin = band_start; bin < band_end; bin++) + s->fixed_coeffs[2][bin] = -s->fixed_coeffs[2][bin]; + } + } + } + bin = band_end; + } +} + +/** + * Grouped mantissas for 3-level 5-level and 11-level quantization + */ +typedef struct mant_groups { + int b1_mant[2]; + int b2_mant[2]; + int b4_mant; + int b1; + int b2; + int b4; +} mant_groups; + +/** + * Decode the transform coefficients for a particular channel + * reference: Section 7.3 Quantization and Decoding of Mantissas + */ +static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, mant_groups *m) +{ + int start_freq = s->start_freq[ch_index]; + int end_freq = s->end_freq[ch_index]; + uint8_t *baps = s->bap[ch_index]; + int8_t *exps = s->dexps[ch_index]; + int32_t *coeffs = s->fixed_coeffs[ch_index]; + int dither = (ch_index == CPL_CH) || s->dither_flag[ch_index]; + GetBitContext *gbc = &s->gbc; + int freq; + + for (freq = start_freq; freq < end_freq; freq++) { + int bap = baps[freq]; + int mantissa; + switch (bap) { + case 0: + /* random noise with approximate range of -0.707 to 0.707 */ + if (dither) + mantissa = (((av_lfg_get(&s->dith_state)>>8)*181)>>8) - 5931008; + else + mantissa = 0; + break; + case 1: + if (m->b1) { + m->b1--; + mantissa = m->b1_mant[m->b1]; + } else { + int bits = get_bits(gbc, 5); + mantissa = b1_mantissas[bits][0]; + m->b1_mant[1] = b1_mantissas[bits][1]; + m->b1_mant[0] = b1_mantissas[bits][2]; + m->b1 = 2; + } + break; + case 2: + if (m->b2) { + m->b2--; + mantissa = m->b2_mant[m->b2]; + } else { + int bits = get_bits(gbc, 7); + mantissa = b2_mantissas[bits][0]; + m->b2_mant[1] = b2_mantissas[bits][1]; + m->b2_mant[0] = b2_mantissas[bits][2]; + m->b2 = 2; + } + break; + case 3: + mantissa = b3_mantissas[get_bits(gbc, 3)]; + break; + case 4: + if (m->b4) { + m->b4 = 0; + mantissa = m->b4_mant; + } else { + int bits = get_bits(gbc, 7); + mantissa = b4_mantissas[bits][0]; + m->b4_mant = b4_mantissas[bits][1]; + m->b4 = 1; + } + break; + case 5: + mantissa = b5_mantissas[get_bits(gbc, 4)]; + break; + default: /* 6 to 15 */ + /* Shift mantissa and sign-extend it. */ + if (bap > 15) { + av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap); + bap = 15; + } + mantissa = (unsigned)get_sbits(gbc, quantization_tab[bap]) << (24 - quantization_tab[bap]); + break; + } + coeffs[freq] = mantissa >> exps[freq]; + } +} + +/** + * Remove random dithering from coupling range coefficients with zero-bit + * mantissas for coupled channels which do not use dithering. + * reference: Section 7.3.4 Dither for Zero Bit Mantissas (bap=0) + */ +static void remove_dithering(AC3DecodeContext *s) { + int ch, i; + + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (!s->dither_flag[ch] && s->channel_in_cpl[ch]) { + for (i = s->start_freq[CPL_CH]; i < s->end_freq[CPL_CH]; i++) { + if (!s->bap[CPL_CH][i]) + s->fixed_coeffs[ch][i] = 0; + } + } + } +} + +static inline void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, + int ch, mant_groups *m) +{ + if (!s->channel_uses_aht[ch]) { + ac3_decode_transform_coeffs_ch(s, ch, m); + } else { + /* if AHT is used, mantissas for all blocks are encoded in the first + block of the frame. */ + int bin; + if (CONFIG_EAC3_DECODER && !blk) + ff_eac3_decode_transform_coeffs_aht_ch(s, ch); + for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) { + s->fixed_coeffs[ch][bin] = s->pre_mantissa[ch][bin][blk] >> s->dexps[ch][bin]; + } + } +} + +/** + * Decode the transform coefficients. + */ +static inline void decode_transform_coeffs(AC3DecodeContext *s, int blk) +{ + int ch, end; + int got_cplchan = 0; + mant_groups m; + + m.b1 = m.b2 = m.b4 = 0; + + for (ch = 1; ch <= s->channels; ch++) { + /* transform coefficients for full-bandwidth channel */ + decode_transform_coeffs_ch(s, blk, ch, &m); + /* transform coefficients for coupling channel come right after the + coefficients for the first coupled channel*/ + if (s->channel_in_cpl[ch]) { + if (!got_cplchan) { + decode_transform_coeffs_ch(s, blk, CPL_CH, &m); + calc_transform_coeffs_cpl(s); + got_cplchan = 1; + } + end = s->end_freq[CPL_CH]; + } else { + end = s->end_freq[ch]; + } + do + s->fixed_coeffs[ch][end] = 0; + while (++end < 256); + } + + /* zero the dithered coefficients for appropriate channels */ + remove_dithering(s); +} + +/** + * Stereo rematrixing. + * reference: Section 7.5.4 Rematrixing : Decoding Technique + */ +static void do_rematrixing(AC3DecodeContext *s) +{ + int bnd, i; + int end, bndend; + + end = FFMIN(s->end_freq[1], s->end_freq[2]); + + for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) { + if (s->rematrixing_flags[bnd]) { + bndend = FFMIN(end, ff_ac3_rematrix_band_tab[bnd + 1]); + for (i = ff_ac3_rematrix_band_tab[bnd]; i < bndend; i++) { + int tmp0 = s->fixed_coeffs[1][i]; + s->fixed_coeffs[1][i] += s->fixed_coeffs[2][i]; + s->fixed_coeffs[2][i] = tmp0 - s->fixed_coeffs[2][i]; + } + } + } +} + +/** + * Inverse MDCT Transform. + * Convert frequency domain coefficients to time-domain audio samples. + * reference: Section 7.9.4 Transformation Equations + */ +static inline void do_imdct(AC3DecodeContext *s, int channels, int offset) +{ + int ch; + + for (ch = 1; ch <= channels; ch++) { + if (s->block_switch[ch]) { + int i; + FFTSample *x = s->tmp_output + 128; + for (i = 0; i < 128; i++) + x[i] = s->transform_coeffs[ch][2 * i]; + s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x); +#if USE_FIXED + s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1 + offset], + s->tmp_output, s->window, 128, 8); +#else + s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1 + offset], + s->tmp_output, s->window, 128); +#endif + for (i = 0; i < 128; i++) + x[i] = s->transform_coeffs[ch][2 * i + 1]; + s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1 + offset], x); + } else { + s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]); +#if USE_FIXED + s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1 + offset], + s->tmp_output, s->window, 128, 8); +#else + s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1 + offset], + s->tmp_output, s->window, 128); +#endif + memcpy(s->delay[ch - 1 + offset], s->tmp_output + 128, 128 * sizeof(FFTSample)); + } + } +} + +/** + * Upmix delay samples from stereo to original channel layout. + */ +static void ac3_upmix_delay(AC3DecodeContext *s) +{ + int channel_data_size = sizeof(s->delay[0]); + switch (s->channel_mode) { + case AC3_CHMODE_DUALMONO: + case AC3_CHMODE_STEREO: + /* upmix mono to stereo */ + memcpy(s->delay[1], s->delay[0], channel_data_size); + break; + case AC3_CHMODE_2F2R: + memset(s->delay[3], 0, channel_data_size); + case AC3_CHMODE_2F1R: + memset(s->delay[2], 0, channel_data_size); + break; + case AC3_CHMODE_3F2R: + memset(s->delay[4], 0, channel_data_size); + case AC3_CHMODE_3F1R: + memset(s->delay[3], 0, channel_data_size); + case AC3_CHMODE_3F: + memcpy(s->delay[2], s->delay[1], channel_data_size); + memset(s->delay[1], 0, channel_data_size); + break; + } +} + +/** + * Decode band structure for coupling, spectral extension, or enhanced coupling. + * The band structure defines how many subbands are in each band. For each + * subband in the range, 1 means it is combined with the previous band, and 0 + * means that it starts a new band. + * + * @param[in] gbc bit reader context + * @param[in] blk block number + * @param[in] eac3 flag to indicate E-AC-3 + * @param[in] ecpl flag to indicate enhanced coupling + * @param[in] start_subband subband number for start of range + * @param[in] end_subband subband number for end of range + * @param[in] default_band_struct default band structure table + * @param[out] num_bands number of bands (optionally NULL) + * @param[out] band_sizes array containing the number of bins in each band (optionally NULL) + * @param[in,out] band_struct current band structure + */ +static void decode_band_structure(GetBitContext *gbc, int blk, int eac3, + int ecpl, int start_subband, int end_subband, + const uint8_t *default_band_struct, + int *num_bands, uint8_t *band_sizes, + uint8_t *band_struct, int band_struct_size) +{ + int subbnd, bnd, n_subbands, n_bands=0; + uint8_t bnd_sz[22]; + + n_subbands = end_subband - start_subband; + + if (!blk) + memcpy(band_struct, default_band_struct, band_struct_size); + + av_assert0(band_struct_size >= start_subband + n_subbands); + + band_struct += start_subband + 1; + + /* decode band structure from bitstream or use default */ + if (!eac3 || get_bits1(gbc)) { + for (subbnd = 0; subbnd < n_subbands - 1; subbnd++) { + band_struct[subbnd] = get_bits1(gbc); + } + } + + /* calculate number of bands and band sizes based on band structure. + note that the first 4 subbands in enhanced coupling span only 6 bins + instead of 12. */ + if (num_bands || band_sizes ) { + n_bands = n_subbands; + bnd_sz[0] = ecpl ? 6 : 12; + for (bnd = 0, subbnd = 1; subbnd < n_subbands; subbnd++) { + int subbnd_size = (ecpl && subbnd < 4) ? 6 : 12; + if (band_struct[subbnd - 1]) { + n_bands--; + bnd_sz[bnd] += subbnd_size; + } else { + bnd_sz[++bnd] = subbnd_size; + } + } + } + + /* set optional output params */ + if (num_bands) + *num_bands = n_bands; + if (band_sizes) + memcpy(band_sizes, bnd_sz, n_bands); +} + +static inline int spx_strategy(AC3DecodeContext *s, int blk) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int dst_start_freq, dst_end_freq, src_start_freq, + start_subband, end_subband, ch; + + /* determine which channels use spx */ + if (s->channel_mode == AC3_CHMODE_MONO) { + s->channel_uses_spx[1] = 1; + } else { + for (ch = 1; ch <= fbw_channels; ch++) + s->channel_uses_spx[ch] = get_bits1(bc); + } + + /* get the frequency bins of the spx copy region and the spx start + and end subbands */ + dst_start_freq = get_bits(bc, 2); + start_subband = get_bits(bc, 3) + 2; + if (start_subband > 7) + start_subband += start_subband - 7; + end_subband = get_bits(bc, 3) + 5; +#if USE_FIXED + s->spx_dst_end_freq = end_freq_inv_tab[end_subband-5]; +#endif + if (end_subband > 7) + end_subband += end_subband - 7; + dst_start_freq = dst_start_freq * 12 + 25; + src_start_freq = start_subband * 12 + 25; + dst_end_freq = end_subband * 12 + 25; + + /* check validity of spx ranges */ + if (start_subband >= end_subband) { + av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " + "range (%d >= %d)\n", start_subband, end_subband); + return AVERROR_INVALIDDATA; + } + if (dst_start_freq >= src_start_freq) { + av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " + "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq); + return AVERROR_INVALIDDATA; + } + + s->spx_dst_start_freq = dst_start_freq; + s->spx_src_start_freq = src_start_freq; + if (!USE_FIXED) + s->spx_dst_end_freq = dst_end_freq; + + decode_band_structure(bc, blk, s->eac3, 0, + start_subband, end_subband, + ff_eac3_default_spx_band_struct, + &s->num_spx_bands, + s->spx_band_sizes, + s->spx_band_struct, sizeof(s->spx_band_struct)); + return 0; +} + +static inline void spx_coordinates(AC3DecodeContext *s) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int ch, bnd; + + for (ch = 1; ch <= fbw_channels; ch++) { + if (s->channel_uses_spx[ch]) { + if (s->first_spx_coords[ch] || get_bits1(bc)) { + INTFLOAT spx_blend; + int bin, master_spx_coord; + + s->first_spx_coords[ch] = 0; + spx_blend = AC3_SPX_BLEND(get_bits(bc, 5)); + master_spx_coord = get_bits(bc, 2) * 3; + + bin = s->spx_src_start_freq; + for (bnd = 0; bnd < s->num_spx_bands; bnd++) { + int bandsize = s->spx_band_sizes[bnd]; + int spx_coord_exp, spx_coord_mant; + INTFLOAT nratio, sblend, nblend; +#if USE_FIXED + /* calculate blending factors */ + int64_t accu = ((bin << 23) + (bandsize << 22)) + * (int64_t)s->spx_dst_end_freq; + nratio = (int)(accu >> 32); + nratio -= spx_blend << 18; + + if (nratio < 0) { + nblend = 0; + sblend = 0x800000; + } else if (nratio > 0x7fffff) { + nblend = 14529495; // sqrt(3) in FP.23 + sblend = 0; + } else { + nblend = fixed_sqrt(nratio, 23); + accu = (int64_t)nblend * 1859775393; + nblend = (int)((accu + (1<<29)) >> 30); + sblend = fixed_sqrt(0x800000 - nratio, 23); + } +#else + float spx_coord; + + /* calculate blending factors */ + nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend; + nratio = av_clipf(nratio, 0.0f, 1.0f); + nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3) + // to give unity variance + sblend = sqrtf(1.0f - nratio); +#endif + bin += bandsize; + + /* decode spx coordinates */ + spx_coord_exp = get_bits(bc, 4); + spx_coord_mant = get_bits(bc, 2); + if (spx_coord_exp == 15) spx_coord_mant <<= 1; + else spx_coord_mant += 4; + spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord); + + /* multiply noise and signal blending factors by spx coordinate */ +#if USE_FIXED + accu = (int64_t)nblend * spx_coord_mant; + s->spx_noise_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); + accu = (int64_t)sblend * spx_coord_mant; + s->spx_signal_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); +#else + spx_coord = spx_coord_mant * (1.0f / (1 << 23)); + s->spx_noise_blend [ch][bnd] = nblend * spx_coord; + s->spx_signal_blend[ch][bnd] = sblend * spx_coord; +#endif + } + } + } else { + s->first_spx_coords[ch] = 1; + } + } +} + +static inline int coupling_strategy(AC3DecodeContext *s, int blk, + uint8_t *bit_alloc_stages) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int channel_mode = s->channel_mode; + int ch; + + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); + if (!s->eac3) + s->cpl_in_use[blk] = get_bits1(bc); + if (s->cpl_in_use[blk]) { + /* coupling in use */ + int cpl_start_subband, cpl_end_subband; + + if (channel_mode < AC3_CHMODE_STEREO) { + av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); + return AVERROR_INVALIDDATA; + } + + /* check for enhanced coupling */ + if (s->eac3 && get_bits1(bc)) { + /* TODO: parse enhanced coupling strategy info */ + avpriv_request_sample(s->avctx, "Enhanced coupling"); + return AVERROR_PATCHWELCOME; + } + + /* determine which channels are coupled */ + if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) { + s->channel_in_cpl[1] = 1; + s->channel_in_cpl[2] = 1; + } else { + for (ch = 1; ch <= fbw_channels; ch++) + s->channel_in_cpl[ch] = get_bits1(bc); + } + + /* phase flags in use */ + if (channel_mode == AC3_CHMODE_STEREO) + s->phase_flags_in_use = get_bits1(bc); + + /* coupling frequency range */ + cpl_start_subband = get_bits(bc, 4); + cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 : + get_bits(bc, 4) + 3; + if (cpl_start_subband >= cpl_end_subband) { + av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n", + cpl_start_subband, cpl_end_subband); + return AVERROR_INVALIDDATA; + } + s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; + s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; + + decode_band_structure(bc, blk, s->eac3, 0, cpl_start_subband, + cpl_end_subband, + ff_eac3_default_cpl_band_struct, + &s->num_cpl_bands, s->cpl_band_sizes, + s->cpl_band_struct, sizeof(s->cpl_band_struct)); + } else { + /* coupling not in use */ + for (ch = 1; ch <= fbw_channels; ch++) { + s->channel_in_cpl[ch] = 0; + s->first_cpl_coords[ch] = 1; + } + s->first_cpl_leak = s->eac3; + s->phase_flags_in_use = 0; + } + + return 0; +} + +static inline int coupling_coordinates(AC3DecodeContext *s, int blk) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int ch, bnd; + int cpl_coords_exist = 0; + + for (ch = 1; ch <= fbw_channels; ch++) { + if (s->channel_in_cpl[ch]) { + if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(bc)) { + int master_cpl_coord, cpl_coord_exp, cpl_coord_mant; + s->first_cpl_coords[ch] = 0; + cpl_coords_exist = 1; + master_cpl_coord = 3 * get_bits(bc, 2); + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + cpl_coord_exp = get_bits(bc, 4); + cpl_coord_mant = get_bits(bc, 4); + if (cpl_coord_exp == 15) + s->cpl_coords[ch][bnd] = cpl_coord_mant << 22; + else + s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21; + s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord); + } + } else if (!blk) { + av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must " + "be present in block 0\n"); + return AVERROR_INVALIDDATA; + } + } else { + /* channel not in coupling */ + s->first_cpl_coords[ch] = 1; + } + } + /* phase flags */ + if (s->channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) { + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + s->phase_flags[bnd] = s->phase_flags_in_use ? get_bits1(bc) : 0; + } + } + + return 0; +} + +/** + * Decode a single audio block from the AC-3 bitstream. + */ +static int decode_audio_block(AC3DecodeContext *s, int blk, int offset) +{ + int fbw_channels = s->fbw_channels; + int channel_mode = s->channel_mode; + int i, bnd, seg, ch, ret; + int different_transforms; + int downmix_output; + int cpl_in_use; + GetBitContext *gbc = &s->gbc; + uint8_t bit_alloc_stages[AC3_MAX_CHANNELS] = { 0 }; + + /* block switch flags */ + different_transforms = 0; + if (s->block_switch_syntax) { + for (ch = 1; ch <= fbw_channels; ch++) { + s->block_switch[ch] = get_bits1(gbc); + if (ch > 1 && s->block_switch[ch] != s->block_switch[1]) + different_transforms = 1; + } + } + + /* dithering flags */ + if (s->dither_flag_syntax) { + for (ch = 1; ch <= fbw_channels; ch++) { + s->dither_flag[ch] = get_bits1(gbc); + } + } + + /* dynamic range */ + i = !s->channel_mode; + do { + if (get_bits1(gbc)) { + /* Allow asymmetric application of DRC when drc_scale > 1. + Amplification of quiet sounds is enhanced */ + int range_bits = get_bits(gbc, 8); + INTFLOAT range = AC3_RANGE(range_bits); + if (range_bits <= 127 || s->drc_scale <= 1.0) + s->dynamic_range[i] = AC3_DYNAMIC_RANGE(range); + else + s->dynamic_range[i] = range; + } else if (blk == 0) { + s->dynamic_range[i] = AC3_DYNAMIC_RANGE1; + } + } while (i--); + + /* spectral extension strategy */ + if (s->eac3 && (!blk || get_bits1(gbc))) { + s->spx_in_use = get_bits1(gbc); + if (s->spx_in_use) { + if ((ret = spx_strategy(s, blk)) < 0) + return ret; + } + } + if (!s->eac3 || !s->spx_in_use) { + s->spx_in_use = 0; + for (ch = 1; ch <= fbw_channels; ch++) { + s->channel_uses_spx[ch] = 0; + s->first_spx_coords[ch] = 1; + } + } + + /* spectral extension coordinates */ + if (s->spx_in_use) + spx_coordinates(s); + + /* coupling strategy */ + if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) { + if ((ret = coupling_strategy(s, blk, bit_alloc_stages)) < 0) + return ret; + } else if (!s->eac3) { + if (!blk) { + av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must " + "be present in block 0\n"); + return AVERROR_INVALIDDATA; + } else { + s->cpl_in_use[blk] = s->cpl_in_use[blk-1]; + } + } + cpl_in_use = s->cpl_in_use[blk]; + + /* coupling coordinates */ + if (cpl_in_use) { + if ((ret = coupling_coordinates(s, blk)) < 0) + return ret; + } + + /* stereo rematrixing strategy and band structure */ + if (channel_mode == AC3_CHMODE_STEREO) { + if ((s->eac3 && !blk) || get_bits1(gbc)) { + s->num_rematrixing_bands = 4; + if (cpl_in_use && s->start_freq[CPL_CH] <= 61) { + s->num_rematrixing_bands -= 1 + (s->start_freq[CPL_CH] == 37); + } else if (s->spx_in_use && s->spx_src_start_freq <= 61) { + s->num_rematrixing_bands--; + } + for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) + s->rematrixing_flags[bnd] = get_bits1(gbc); + } else if (!blk) { + av_log(s->avctx, AV_LOG_WARNING, "Warning: " + "new rematrixing strategy not present in block 0\n"); + s->num_rematrixing_bands = 0; + } + } + + /* exponent strategies for each channel */ + for (ch = !cpl_in_use; ch <= s->channels; ch++) { + if (!s->eac3) + s->exp_strategy[blk][ch] = get_bits(gbc, 2 - (ch == s->lfe_ch)); + if (s->exp_strategy[blk][ch] != EXP_REUSE) + bit_alloc_stages[ch] = 3; + } + + /* channel bandwidth */ + for (ch = 1; ch <= fbw_channels; ch++) { + s->start_freq[ch] = 0; + if (s->exp_strategy[blk][ch] != EXP_REUSE) { + int group_size; + int prev = s->end_freq[ch]; + if (s->channel_in_cpl[ch]) + s->end_freq[ch] = s->start_freq[CPL_CH]; + else if (s->channel_uses_spx[ch]) + s->end_freq[ch] = s->spx_src_start_freq; + else { + int bandwidth_code = get_bits(gbc, 6); + if (bandwidth_code > 60) { + av_log(s->avctx, AV_LOG_ERROR, "bandwidth code = %d > 60\n", bandwidth_code); + return AVERROR_INVALIDDATA; + } + s->end_freq[ch] = bandwidth_code * 3 + 73; + } + group_size = 3 << (s->exp_strategy[blk][ch] - 1); + s->num_exp_groups[ch] = (s->end_freq[ch] + group_size-4) / group_size; + if (blk > 0 && s->end_freq[ch] != prev) + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); + } + } + if (cpl_in_use && s->exp_strategy[blk][CPL_CH] != EXP_REUSE) { + s->num_exp_groups[CPL_CH] = (s->end_freq[CPL_CH] - s->start_freq[CPL_CH]) / + (3 << (s->exp_strategy[blk][CPL_CH] - 1)); + } + + /* decode exponents for each channel */ + for (ch = !cpl_in_use; ch <= s->channels; ch++) { + if (s->exp_strategy[blk][ch] != EXP_REUSE) { + s->dexps[ch][0] = get_bits(gbc, 4) << !ch; + if (decode_exponents(s, gbc, s->exp_strategy[blk][ch], + s->num_exp_groups[ch], s->dexps[ch][0], + &s->dexps[ch][s->start_freq[ch]+!!ch])) { + return AVERROR_INVALIDDATA; + } + if (ch != CPL_CH && ch != s->lfe_ch) + skip_bits(gbc, 2); /* skip gainrng */ + } + } + + /* bit allocation information */ + if (s->bit_allocation_syntax) { + if (get_bits1(gbc)) { + s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift; + s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift; + s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab[get_bits(gbc, 2)]; + s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[get_bits(gbc, 2)]; + s->bit_alloc_params.floor = ff_ac3_floor_tab[get_bits(gbc, 3)]; + for (ch = !cpl_in_use; ch <= s->channels; ch++) + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); + } else if (!blk) { + av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must " + "be present in block 0\n"); + return AVERROR_INVALIDDATA; + } + } + + /* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */ + if (!s->eac3 || !blk) { + if (s->snr_offset_strategy && get_bits1(gbc)) { + int snr = 0; + int csnr; + csnr = (get_bits(gbc, 6) - 15) << 4; + for (i = ch = !cpl_in_use; ch <= s->channels; ch++) { + /* snr offset */ + if (ch == i || s->snr_offset_strategy == 2) + snr = (csnr + get_bits(gbc, 4)) << 2; + /* run at least last bit allocation stage if snr offset changes */ + if (blk && s->snr_offset[ch] != snr) { + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 1); + } + s->snr_offset[ch] = snr; + + /* fast gain (normal AC-3 only) */ + if (!s->eac3) { + int prev = s->fast_gain[ch]; + s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)]; + /* run last 2 bit allocation stages if fast gain changes */ + if (blk && prev != s->fast_gain[ch]) + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); + } + } + } else if (!s->eac3 && !blk) { + av_log(s->avctx, AV_LOG_ERROR, "new snr offsets must be present in block 0\n"); + return AVERROR_INVALIDDATA; + } + } + + /* fast gain (E-AC-3 only) */ + if (s->fast_gain_syntax && get_bits1(gbc)) { + for (ch = !cpl_in_use; ch <= s->channels; ch++) { + int prev = s->fast_gain[ch]; + s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)]; + /* run last 2 bit allocation stages if fast gain changes */ + if (blk && prev != s->fast_gain[ch]) + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); + } + } else if (s->eac3 && !blk) { + for (ch = !cpl_in_use; ch <= s->channels; ch++) + s->fast_gain[ch] = ff_ac3_fast_gain_tab[4]; + } + + /* E-AC-3 to AC-3 converter SNR offset */ + if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && get_bits1(gbc)) { + skip_bits(gbc, 10); // skip converter snr offset + } + + /* coupling leak information */ + if (cpl_in_use) { + if (s->first_cpl_leak || get_bits1(gbc)) { + int fl = get_bits(gbc, 3); + int sl = get_bits(gbc, 3); + /* run last 2 bit allocation stages for coupling channel if + coupling leak changes */ + if (blk && (fl != s->bit_alloc_params.cpl_fast_leak || + sl != s->bit_alloc_params.cpl_slow_leak)) { + bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2); + } + s->bit_alloc_params.cpl_fast_leak = fl; + s->bit_alloc_params.cpl_slow_leak = sl; + } else if (!s->eac3 && !blk) { + av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must " + "be present in block 0\n"); + return AVERROR_INVALIDDATA; + } + s->first_cpl_leak = 0; + } + + /* delta bit allocation information */ + if (s->dba_syntax && get_bits1(gbc)) { + /* delta bit allocation exists (strategy) */ + for (ch = !cpl_in_use; ch <= fbw_channels; ch++) { + s->dba_mode[ch] = get_bits(gbc, 2); + if (s->dba_mode[ch] == DBA_RESERVED) { + av_log(s->avctx, AV_LOG_ERROR, "delta bit allocation strategy reserved\n"); + return AVERROR_INVALIDDATA; + } + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); + } + /* channel delta offset, len and bit allocation */ + for (ch = !cpl_in_use; ch <= fbw_channels; ch++) { + if (s->dba_mode[ch] == DBA_NEW) { + s->dba_nsegs[ch] = get_bits(gbc, 3) + 1; + for (seg = 0; seg < s->dba_nsegs[ch]; seg++) { + s->dba_offsets[ch][seg] = get_bits(gbc, 5); + s->dba_lengths[ch][seg] = get_bits(gbc, 4); + s->dba_values[ch][seg] = get_bits(gbc, 3); + } + /* run last 2 bit allocation stages if new dba values */ + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); + } + } + } else if (blk == 0) { + for (ch = 0; ch <= s->channels; ch++) { + s->dba_mode[ch] = DBA_NONE; + } + } + + /* Bit allocation */ + for (ch = !cpl_in_use; ch <= s->channels; ch++) { + if (bit_alloc_stages[ch] > 2) { + /* Exponent mapping into PSD and PSD integration */ + ff_ac3_bit_alloc_calc_psd(s->dexps[ch], + s->start_freq[ch], s->end_freq[ch], + s->psd[ch], s->band_psd[ch]); + } + if (bit_alloc_stages[ch] > 1) { + /* Compute excitation function, Compute masking curve, and + Apply delta bit allocation */ + if (ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params, s->band_psd[ch], + s->start_freq[ch], s->end_freq[ch], + s->fast_gain[ch], (ch == s->lfe_ch), + s->dba_mode[ch], s->dba_nsegs[ch], + s->dba_offsets[ch], s->dba_lengths[ch], + s->dba_values[ch], s->mask[ch])) { + av_log(s->avctx, AV_LOG_ERROR, "error in bit allocation\n"); + return AVERROR_INVALIDDATA; + } + } + if (bit_alloc_stages[ch] > 0) { + /* Compute bit allocation */ + const uint8_t *bap_tab = s->channel_uses_aht[ch] ? + ff_eac3_hebap_tab : ff_ac3_bap_tab; + s->ac3dsp.bit_alloc_calc_bap(s->mask[ch], s->psd[ch], + s->start_freq[ch], s->end_freq[ch], + s->snr_offset[ch], + s->bit_alloc_params.floor, + bap_tab, s->bap[ch]); + } + } + + /* unused dummy data */ + if (s->skip_syntax && get_bits1(gbc)) { + int skipl = get_bits(gbc, 9); + skip_bits_long(gbc, 8 * skipl); + } + + /* unpack the transform coefficients + this also uncouples channels if coupling is in use. */ + decode_transform_coeffs(s, blk); + + /* TODO: generate enhanced coupling coordinates and uncouple */ + + /* recover coefficients if rematrixing is in use */ + if (s->channel_mode == AC3_CHMODE_STEREO) + do_rematrixing(s); + + /* apply scaling to coefficients (headroom, dynrng) */ + for (ch = 1; ch <= s->channels; ch++) { + int audio_channel = 0; + INTFLOAT gain; + if (s->channel_mode == AC3_CHMODE_DUALMONO && ch <= 2) + audio_channel = 2-ch; + if (s->heavy_compression && s->compression_exists[audio_channel]) + gain = s->heavy_dynamic_range[audio_channel]; + else + gain = s->dynamic_range[audio_channel]; + +#if USE_FIXED + scale_coefs(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256); +#else + if (s->target_level != 0) + gain = gain * s->level_gain[audio_channel]; + gain *= 1.0 / 4194304.0f; + s->fmt_conv.int32_to_float_fmul_scalar(s->transform_coeffs[ch], + s->fixed_coeffs[ch], gain, 256); +#endif + } + + /* apply spectral extension to high frequency bins */ + if (CONFIG_EAC3_DECODER && s->spx_in_use) { + ff_eac3_apply_spectral_extension(s); + } + + /* downmix and MDCT. order depends on whether block switching is used for + any channel in this block. this is because coefficients for the long + and short transforms cannot be mixed. */ + downmix_output = s->channels != s->out_channels && + !((s->output_mode & AC3_OUTPUT_LFEON) && + s->fbw_channels == s->out_channels); + if (different_transforms) { + /* the delay samples have already been downmixed, so we upmix the delay + samples in order to reconstruct all channels before downmixing. */ + if (s->downmixed) { + s->downmixed = 0; + ac3_upmix_delay(s); + } + + do_imdct(s, s->channels, offset); + + if (downmix_output) { +#if USE_FIXED + ac3_downmix_c_fixed16(s->outptr, s->downmix_coeffs, + s->out_channels, s->fbw_channels, 256); +#else + ff_ac3dsp_downmix(&s->ac3dsp, s->outptr, s->downmix_coeffs, + s->out_channels, s->fbw_channels, 256); +#endif + } + } else { + if (downmix_output) { + AC3_RENAME(ff_ac3dsp_downmix)(&s->ac3dsp, s->xcfptr + 1, s->downmix_coeffs, + s->out_channels, s->fbw_channels, 256); + } + + if (downmix_output && !s->downmixed) { + s->downmixed = 1; + AC3_RENAME(ff_ac3dsp_downmix)(&s->ac3dsp, s->dlyptr, s->downmix_coeffs, + s->out_channels, s->fbw_channels, 128); + } + + do_imdct(s, s->out_channels, offset); + } + + return 0; +} + +/** + * Decode a single AC-3 frame. + */ +static int ac3_decode_frame(AVCodecContext * avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + AVFrame *frame = data; + const uint8_t *buf = avpkt->data; + int buf_size, full_buf_size = avpkt->size; + AC3DecodeContext *s = avctx->priv_data; + int blk, ch, err, offset, ret; + int i; + int skip = 0, got_independent_frame = 0; + const uint8_t *channel_map; + uint8_t extended_channel_map[EAC3_MAX_CHANNELS]; + const SHORTFLOAT *output[AC3_MAX_CHANNELS]; + enum AVMatrixEncoding matrix_encoding; + AVDownmixInfo *downmix_info; + + s->superframe_size = 0; + + buf_size = full_buf_size; + for (i = 1; i < buf_size; i += 2) { + if (buf[i] == 0x77 || buf[i] == 0x0B) { + if ((buf[i] ^ buf[i-1]) == (0x77 ^ 0x0B)) { + i--; + break; + } else if ((buf[i] ^ buf[i+1]) == (0x77 ^ 0x0B)) { + break; + } + } + } + if (i >= buf_size) + return AVERROR_INVALIDDATA; + if (i > 10) + return i; + buf += i; + buf_size -= i; + + /* copy input buffer to decoder context to avoid reading past the end + of the buffer, which can be caused by a damaged input stream. */ + if (buf_size >= 2 && AV_RB16(buf) == 0x770B) { + // seems to be byte-swapped AC-3 + int cnt = FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE) >> 1; + s->bdsp.bswap16_buf((uint16_t *) s->input_buffer, + (const uint16_t *) buf, cnt); + } else + memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE)); + + /* if consistent noise generation is enabled, seed the linear feedback generator + * with the contents of the AC-3 frame so that the noise is identical across + * decodes given the same AC-3 frame data, for use with non-linear edititing software. */ + if (s->consistent_noise_generation) + av_lfg_init_from_data(&s->dith_state, s->input_buffer, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE)); + + buf = s->input_buffer; +dependent_frame: + /* initialize the GetBitContext with the start of valid AC-3 Frame */ + if ((ret = init_get_bits8(&s->gbc, buf, buf_size)) < 0) + return ret; + + /* parse the syncinfo */ + err = parse_frame_header(s); + + if (err) { + switch (err) { + case AAC_AC3_PARSE_ERROR_SYNC: + av_log(avctx, AV_LOG_ERROR, "frame sync error\n"); + return AVERROR_INVALIDDATA; + case AAC_AC3_PARSE_ERROR_BSID: + av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n"); + break; + case AAC_AC3_PARSE_ERROR_SAMPLE_RATE: + av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n"); + break; + case AAC_AC3_PARSE_ERROR_FRAME_SIZE: + av_log(avctx, AV_LOG_ERROR, "invalid frame size\n"); + break; + case AAC_AC3_PARSE_ERROR_FRAME_TYPE: + /* skip frame if CRC is ok. otherwise use error concealment. */ + /* TODO: add support for substreams */ + if (s->substreamid) { + av_log(avctx, AV_LOG_DEBUG, + "unsupported substream %d: skipping frame\n", + s->substreamid); + *got_frame_ptr = 0; + return buf_size; + } else { + av_log(avctx, AV_LOG_ERROR, "invalid frame type\n"); + } + break; + case AAC_AC3_PARSE_ERROR_CRC: + case AAC_AC3_PARSE_ERROR_CHANNEL_CFG: + break; + default: // Normal AVERROR do not try to recover. + *got_frame_ptr = 0; + return err; + } + } else { + /* check that reported frame size fits in input buffer */ + if (s->frame_size > buf_size) { + av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); + err = AAC_AC3_PARSE_ERROR_FRAME_SIZE; + } else if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) { + /* check for crc mismatch */ + if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], + s->frame_size - 2)) { + av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + err = AAC_AC3_PARSE_ERROR_CRC; + } + } + } + + if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT && !got_independent_frame) { + av_log(avctx, AV_LOG_WARNING, "Ignoring dependent frame without independent frame.\n"); + *got_frame_ptr = 0; + return FFMIN(full_buf_size, s->frame_size); + } + + /* channel config */ + if (!err || (s->channels && s->out_channels != s->channels)) { + s->out_channels = s->channels; + s->output_mode = s->channel_mode; + if (s->lfe_on) + s->output_mode |= AC3_OUTPUT_LFEON; + if (s->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) { + s->out_channels = 1; + s->output_mode = AC3_CHMODE_MONO; + } else if (s->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + s->out_channels = 2; + s->output_mode = AC3_CHMODE_STEREO; + } + + s->loro_center_mix_level = gain_levels[s-> center_mix_level]; + s->loro_surround_mix_level = gain_levels[s->surround_mix_level]; + s->ltrt_center_mix_level = LEVEL_MINUS_3DB; + s->ltrt_surround_mix_level = LEVEL_MINUS_3DB; + /* set downmixing coefficients if needed */ + if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) && + s->fbw_channels == s->out_channels)) { + if ((ret = set_downmix_coeffs(s)) < 0) { + av_log(avctx, AV_LOG_ERROR, "error setting downmix coeffs\n"); + return ret; + } + } + } else if (!s->channels) { + av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n"); + return AVERROR_INVALIDDATA; + } + avctx->channels = s->out_channels; + avctx->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON]; + if (s->output_mode & AC3_OUTPUT_LFEON) + avctx->channel_layout |= AV_CH_LOW_FREQUENCY; + + /* set audio service type based on bitstream mode for AC-3 */ + avctx->audio_service_type = s->bitstream_mode; + if (s->bitstream_mode == 0x7 && s->channels > 1) + avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; + + /* decode the audio blocks */ + channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on]; + offset = s->frame_type == EAC3_FRAME_TYPE_DEPENDENT ? AC3_MAX_CHANNELS : 0; + for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) { + output[ch] = s->output[ch + offset]; + s->outptr[ch] = s->output[ch + offset]; + } + for (ch = 0; ch < s->channels; ch++) { + if (ch < s->out_channels) + s->outptr[channel_map[ch]] = s->output_buffer[ch + offset]; + } + for (blk = 0; blk < s->num_blocks; blk++) { + if (!err && decode_audio_block(s, blk, offset)) { + av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n"); + err = 1; + } + if (err) + for (ch = 0; ch < s->out_channels; ch++) + memcpy(s->output_buffer[ch + offset] + AC3_BLOCK_SIZE*blk, output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT)); + for (ch = 0; ch < s->out_channels; ch++) + output[ch] = s->outptr[channel_map[ch]]; + for (ch = 0; ch < s->out_channels; ch++) { + if (!ch || channel_map[ch]) + s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE; + } + } + + /* keep last block for error concealment in next frame */ + for (ch = 0; ch < s->out_channels; ch++) + memcpy(s->output[ch + offset], output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT)); + + /* check if there is dependent frame */ + if (buf_size > s->frame_size) { + AC3HeaderInfo hdr; + int err; + + if (buf_size - s->frame_size <= 16) { + skip = buf_size - s->frame_size; + goto skip; + } + + if ((ret = init_get_bits8(&s->gbc, buf + s->frame_size, buf_size - s->frame_size)) < 0) + return ret; + + err = ff_ac3_parse_header(&s->gbc, &hdr); + if (err) + return err; + + if (hdr.frame_type == EAC3_FRAME_TYPE_DEPENDENT) { + if (hdr.num_blocks != s->num_blocks || s->sample_rate != hdr.sample_rate) { + av_log(avctx, AV_LOG_WARNING, "Ignoring non-compatible dependent frame.\n"); + } else { + buf += s->frame_size; + buf_size -= s->frame_size; + s->prev_output_mode = s->output_mode; + s->prev_bit_rate = s->bit_rate; + got_independent_frame = 1; + goto dependent_frame; + } + } + } +skip: + + frame->decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0; + + /* if frame is ok, set audio parameters */ + if (!err) { + avctx->sample_rate = s->sample_rate; + avctx->bit_rate = s->bit_rate + s->prev_bit_rate; + } + + for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++) + extended_channel_map[ch] = ch; + + if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { + uint64_t ich_layout = avpriv_ac3_channel_layout_tab[s->prev_output_mode & ~AC3_OUTPUT_LFEON]; + int channel_map_size = ff_ac3_channels_tab[s->output_mode & ~AC3_OUTPUT_LFEON] + s->lfe_on; + uint64_t channel_layout; + int extend = 0; + + if (s->prev_output_mode & AC3_OUTPUT_LFEON) + ich_layout |= AV_CH_LOW_FREQUENCY; + + channel_layout = ich_layout; + for (ch = 0; ch < 16; ch++) { + if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) { + channel_layout |= ff_eac3_custom_channel_map_locations[ch][1]; + } + } + if (av_get_channel_layout_nb_channels(channel_layout) > EAC3_MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Too many channels (%d) coded\n", + av_get_channel_layout_nb_channels(channel_layout)); + return AVERROR_INVALIDDATA; + } + + avctx->channel_layout = channel_layout; + avctx->channels = av_get_channel_layout_nb_channels(channel_layout); + + for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++) { + if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) { + if (ff_eac3_custom_channel_map_locations[ch][0]) { + int index = av_get_channel_layout_channel_index(channel_layout, + ff_eac3_custom_channel_map_locations[ch][1]); + if (index < 0) + return AVERROR_INVALIDDATA; + if (extend >= channel_map_size) + return AVERROR_INVALIDDATA; + + extended_channel_map[index] = offset + channel_map[extend++]; + } else { + int i; + + for (i = 0; i < 64; i++) { + if ((1ULL << i) & ff_eac3_custom_channel_map_locations[ch][1]) { + int index = av_get_channel_layout_channel_index(channel_layout, + 1ULL << i); + if (index < 0) + return AVERROR_INVALIDDATA; + if (extend >= channel_map_size) + return AVERROR_INVALIDDATA; + + extended_channel_map[index] = offset + channel_map[extend++]; + } + } + } + } + } + } + + /* get output buffer */ + frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + for (ch = 0; ch < avctx->channels; ch++) { + int map = extended_channel_map[ch]; + av_assert0(ch>=AV_NUM_DATA_POINTERS || frame->extended_data[ch] == frame->data[ch]); + memcpy((SHORTFLOAT *)frame->extended_data[ch], + s->output_buffer[map], + s->num_blocks * AC3_BLOCK_SIZE * sizeof(SHORTFLOAT)); + } + + /* + * AVMatrixEncoding + * + * Check whether the input layout is compatible, and make sure we're not + * downmixing (else the matrix encoding is no longer applicable). + */ + matrix_encoding = AV_MATRIX_ENCODING_NONE; + if (s->channel_mode == AC3_CHMODE_STEREO && + s->channel_mode == (s->output_mode & ~AC3_OUTPUT_LFEON)) { + if (s->dolby_surround_mode == AC3_DSURMOD_ON) + matrix_encoding = AV_MATRIX_ENCODING_DOLBY; + else if (s->dolby_headphone_mode == AC3_DHEADPHONMOD_ON) + matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE; + } else if (s->channel_mode >= AC3_CHMODE_2F2R && + s->channel_mode == (s->output_mode & ~AC3_OUTPUT_LFEON)) { + switch (s->dolby_surround_ex_mode) { + case AC3_DSUREXMOD_ON: // EX or PLIIx + matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX; + break; + case AC3_DSUREXMOD_PLIIZ: + matrix_encoding = AV_MATRIX_ENCODING_DPLIIZ; + break; + default: // not indicated or off + break; + } + } + if ((ret = ff_side_data_update_matrix_encoding(frame, matrix_encoding)) < 0) + return ret; + + /* AVDownmixInfo */ + if ((downmix_info = av_downmix_info_update_side_data(frame))) { + switch (s->preferred_downmix) { + case AC3_DMIXMOD_LTRT: + downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_LTRT; + break; + case AC3_DMIXMOD_LORO: + downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_LORO; + break; + case AC3_DMIXMOD_DPLII: + downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_DPLII; + break; + default: + downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_UNKNOWN; + break; + } + downmix_info->center_mix_level = gain_levels[s-> center_mix_level]; + downmix_info->center_mix_level_ltrt = gain_levels[s-> center_mix_level_ltrt]; + downmix_info->surround_mix_level = gain_levels[s-> surround_mix_level]; + downmix_info->surround_mix_level_ltrt = gain_levels[s->surround_mix_level_ltrt]; + if (s->lfe_mix_level_exists) + downmix_info->lfe_mix_level = gain_levels_lfe[s->lfe_mix_level]; + else + downmix_info->lfe_mix_level = 0.0; // -inf dB + } else + return AVERROR(ENOMEM); + + *got_frame_ptr = 1; + + if (!s->superframe_size) + return FFMIN(full_buf_size, s->frame_size + skip); + + return FFMIN(full_buf_size, s->superframe_size + skip); +} + +/** + * Uninitialize the AC-3 decoder. + */ +static av_cold int ac3_decode_end(AVCodecContext *avctx) +{ + AC3DecodeContext *s = avctx->priv_data; + ff_mdct_end(&s->imdct_512); + ff_mdct_end(&s->imdct_256); + av_freep(&s->fdsp); + av_freep(&s->downmix_coeffs[0]); + + return 0; +} + +#define OFFSET(x) offsetof(AC3DecodeContext, x) +#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM) diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec.h new file mode 100644 index 000000000..ce1434b55 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec.h @@ -0,0 +1,277 @@ +/* + * Common code between the AC-3 and E-AC-3 decoders + * Copyright (c) 2007 Bartlomiej Wolowiec + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Common code between the AC-3 and E-AC-3 decoders. + * + * Summary of MDCT Coefficient Grouping: + * The individual MDCT coefficient indices are often referred to in the + * (E-)AC-3 specification as frequency bins. These bins are grouped together + * into subbands of 12 coefficients each. The subbands are grouped together + * into bands as defined in the bitstream by the band structures, which + * determine the number of bands and the size of each band. The full spectrum + * of 256 frequency bins is divided into 1 DC bin + 21 subbands = 253 bins. + * This system of grouping coefficients is used for channel bandwidth, stereo + * rematrixing, channel coupling, enhanced coupling, and spectral extension. + * + * +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+ + * |1| |12| | [12|12|12|12] | | | | | | | | | | | | |3| + * +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+ + * ~~~ ~~~~ ~~~~~~~~~~~~~ ~~~ + * | | | | + * | | | 3 unused frequency bins--+ + * | | | + * | | +--1 band containing 4 subbands + * | | + * | +--1 subband of 12 frequency bins + * | + * +--DC frequency bin + */ + +#ifndef AVCODEC_AC3DEC_H +#define AVCODEC_AC3DEC_H + +#include "libavutil/float_dsp.h" +#include "libavutil/fixed_dsp.h" +#include "libavutil/lfg.h" +#include "ac3.h" +#include "ac3dsp.h" +#include "bswapdsp.h" +#include "get_bits.h" +#include "fft.h" +#include "fmtconvert.h" + +#define AC3_OUTPUT_LFEON 8 + +#define SPX_MAX_BANDS 17 + +/** Large enough for maximum possible frame size when the specification limit is ignored */ +#define AC3_FRAME_BUFFER_SIZE 32768 + +typedef struct AC3DecodeContext { + AVClass *class; ///< class for AVOptions + AVCodecContext *avctx; ///< parent context + GetBitContext gbc; ///< bitstream reader + +///@name Bit stream information +///@{ + int frame_type; ///< frame type (strmtyp) + int substreamid; ///< substream identification + int superframe_size; ///< current superframe size, in bytes + int frame_size; ///< current frame size, in bytes + int bit_rate; ///< stream bit rate, in bits-per-second + int sample_rate; ///< sample frequency, in Hz + int num_blocks; ///< number of audio blocks + int bitstream_id; ///< bitstream id (bsid) + int bitstream_mode; ///< bitstream mode (bsmod) + int channel_mode; ///< channel mode (acmod) + int lfe_on; ///< lfe channel in use + int dialog_normalization[2]; ///< dialog level in dBFS (dialnorm) + int compression_exists[2]; ///< compression field is valid for frame (compre) + int compression_gain[2]; ///< gain to apply for heavy compression (compr) + int channel_map; ///< custom channel map (chanmap) + int preferred_downmix; ///< Preferred 2-channel downmix mode (dmixmod) + int center_mix_level; ///< Center mix level index + int center_mix_level_ltrt; ///< Center mix level index for Lt/Rt (ltrtcmixlev) + int surround_mix_level; ///< Surround mix level index + int surround_mix_level_ltrt; ///< Surround mix level index for Lt/Rt (ltrtsurmixlev) + int lfe_mix_level_exists; ///< indicates if lfemixlevcod is specified (lfemixlevcode) + int lfe_mix_level; ///< LFE mix level index (lfemixlevcod) + int eac3; ///< indicates if current frame is E-AC-3 + int eac3_frame_dependent_found; ///< bitstream has E-AC-3 dependent frame(s) + int eac3_subsbtreamid_found; ///< bitstream has E-AC-3 additional substream(s) + int dolby_surround_mode; ///< dolby surround mode (dsurmod) + int dolby_surround_ex_mode; ///< dolby surround ex mode (dsurexmod) + int dolby_headphone_mode; ///< dolby headphone mode (dheadphonmod) +///@} + + int preferred_stereo_downmix; + float ltrt_center_mix_level; + float ltrt_surround_mix_level; + float loro_center_mix_level; + float loro_surround_mix_level; + int target_level; ///< target level in dBFS + float level_gain[2]; + +///@name Frame syntax parameters + int snr_offset_strategy; ///< SNR offset strategy (snroffststr) + int block_switch_syntax; ///< block switch syntax enabled (blkswe) + int dither_flag_syntax; ///< dither flag syntax enabled (dithflage) + int bit_allocation_syntax; ///< bit allocation model syntax enabled (bamode) + int fast_gain_syntax; ///< fast gain codes enabled (frmfgaincode) + int dba_syntax; ///< delta bit allocation syntax enabled (dbaflde) + int skip_syntax; ///< skip field syntax enabled (skipflde) + ///@} + +///@name Standard coupling + int cpl_in_use[AC3_MAX_BLOCKS]; ///< coupling in use (cplinu) + int cpl_strategy_exists[AC3_MAX_BLOCKS];///< coupling strategy exists (cplstre) + int channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl) + int phase_flags_in_use; ///< phase flags in use (phsflginu) + int phase_flags[AC3_MAX_CPL_BANDS]; ///< phase flags (phsflg) + int num_cpl_bands; ///< number of coupling bands (ncplbnd) + uint8_t cpl_band_struct[AC3_MAX_CPL_BANDS]; + uint8_t cpl_band_sizes[AC3_MAX_CPL_BANDS]; ///< number of coeffs in each coupling band + int firstchincpl; ///< first channel in coupling + int first_cpl_coords[AC3_MAX_CHANNELS]; ///< first coupling coordinates states (firstcplcos) + int cpl_coords[AC3_MAX_CHANNELS][AC3_MAX_CPL_BANDS]; ///< coupling coordinates (cplco) +///@} + +///@name Spectral extension +///@{ + int spx_in_use; ///< spectral extension in use (spxinu) + uint8_t channel_uses_spx[AC3_MAX_CHANNELS]; ///< channel uses spectral extension (chinspx) + int8_t spx_atten_code[AC3_MAX_CHANNELS]; ///< spx attenuation code (spxattencod) + int spx_src_start_freq; ///< spx start frequency bin + int spx_dst_end_freq; ///< spx end frequency bin + int spx_dst_start_freq; ///< spx starting frequency bin for copying (copystartmant) + ///< the copy region ends at the start of the spx region. + int num_spx_bands; ///< number of spx bands (nspxbnds) + uint8_t spx_band_struct[SPX_MAX_BANDS]; + uint8_t spx_band_sizes[SPX_MAX_BANDS]; ///< number of bins in each spx band + uint8_t first_spx_coords[AC3_MAX_CHANNELS]; ///< first spx coordinates states (firstspxcos) + INTFLOAT spx_noise_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS]; ///< spx noise blending factor (nblendfact) + INTFLOAT spx_signal_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS];///< spx signal blending factor (sblendfact) +///@} + +///@name Adaptive hybrid transform + int channel_uses_aht[AC3_MAX_CHANNELS]; ///< channel AHT in use (chahtinu) + int pre_mantissa[AC3_MAX_CHANNELS][AC3_MAX_COEFS][AC3_MAX_BLOCKS]; ///< pre-IDCT mantissas +///@} + +///@name Channel + int fbw_channels; ///< number of full-bandwidth channels + int channels; ///< number of total channels + int lfe_ch; ///< index of LFE channel + SHORTFLOAT *downmix_coeffs[2]; ///< stereo downmix coefficients + int downmixed; ///< indicates if coeffs are currently downmixed + int output_mode; ///< output channel configuration + int prev_output_mode; ///< output channel configuration for previous frame + int out_channels; ///< number of output channels + int prev_bit_rate; ///< stream bit rate, in bits-per-second for previous frame +///@} + +///@name Dynamic range + INTFLOAT dynamic_range[2]; ///< dynamic range + INTFLOAT drc_scale; ///< percentage of dynamic range compression to be applied + int heavy_compression; ///< apply heavy compression + INTFLOAT heavy_dynamic_range[2]; ///< heavy dynamic range compression +///@} + +///@name Bandwidth + int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin (strtmant) + int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin (endmant) +///@} + +///@name Consistent noise generation + int consistent_noise_generation; ///< seed noise generation with AC-3 frame on decode +///@} + +///@name Rematrixing + int num_rematrixing_bands; ///< number of rematrixing bands (nrematbnd) + int rematrixing_flags[4]; ///< rematrixing flags (rematflg) +///@} + +///@name Exponents + int num_exp_groups[AC3_MAX_CHANNELS]; ///< Number of exponent groups (nexpgrp) + int8_t dexps[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< decoded exponents + int exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS]; ///< exponent strategies (expstr) +///@} + +///@name Bit allocation + AC3BitAllocParameters bit_alloc_params; ///< bit allocation parameters + int first_cpl_leak; ///< first coupling leak state (firstcplleak) + int snr_offset[AC3_MAX_CHANNELS]; ///< signal-to-noise ratio offsets (snroffst) + int fast_gain[AC3_MAX_CHANNELS]; ///< fast gain values/SMR's (fgain) + uint8_t bap[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< bit allocation pointers + int16_t psd[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< scaled exponents + int16_t band_psd[AC3_MAX_CHANNELS][AC3_CRITICAL_BANDS]; ///< interpolated exponents + int16_t mask[AC3_MAX_CHANNELS][AC3_CRITICAL_BANDS]; ///< masking curve values + int dba_mode[AC3_MAX_CHANNELS]; ///< delta bit allocation mode + int dba_nsegs[AC3_MAX_CHANNELS]; ///< number of delta segments + uint8_t dba_offsets[AC3_MAX_CHANNELS][8]; ///< delta segment offsets + uint8_t dba_lengths[AC3_MAX_CHANNELS][8]; ///< delta segment lengths + uint8_t dba_values[AC3_MAX_CHANNELS][8]; ///< delta values for each segment +///@} + +///@name Zero-mantissa dithering + int dither_flag[AC3_MAX_CHANNELS]; ///< dither flags (dithflg) + AVLFG dith_state; ///< for dither generation +///@} + +///@name IMDCT + int block_switch[AC3_MAX_CHANNELS]; ///< block switch flags (blksw) + FFTContext imdct_512; ///< for 512 sample IMDCT + FFTContext imdct_256; ///< for 256 sample IMDCT +///@} + +///@name Optimization + BswapDSPContext bdsp; +#if USE_FIXED + AVFixedDSPContext *fdsp; +#else + AVFloatDSPContext *fdsp; +#endif + AC3DSPContext ac3dsp; + FmtConvertContext fmt_conv; ///< optimized conversion functions +///@} + + SHORTFLOAT *outptr[AC3_MAX_CHANNELS]; + INTFLOAT *xcfptr[AC3_MAX_CHANNELS]; + INTFLOAT *dlyptr[AC3_MAX_CHANNELS]; + +///@name Aligned arrays + DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients + DECLARE_ALIGNED(32, INTFLOAT, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients + DECLARE_ALIGNED(32, INTFLOAT, delay)[EAC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block + DECLARE_ALIGNED(32, INTFLOAT, window)[AC3_BLOCK_SIZE]; ///< window coefficients + DECLARE_ALIGNED(32, INTFLOAT, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing + DECLARE_ALIGNED(32, SHORTFLOAT, output)[EAC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing + DECLARE_ALIGNED(32, uint8_t, input_buffer)[AC3_FRAME_BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; ///< temp buffer to prevent overread + DECLARE_ALIGNED(32, SHORTFLOAT, output_buffer)[EAC3_MAX_CHANNELS][AC3_BLOCK_SIZE * 6]; ///< final output buffer +///@} +} AC3DecodeContext; + +/** + * Parse the E-AC-3 frame header. + * This parses both the bit stream info and audio frame header. + */ +static int ff_eac3_parse_header(AC3DecodeContext *s); + +/** + * Decode mantissas in a single channel for the entire frame. + * This is used when AHT mode is enabled. + */ +static void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch); + +/** + * Apply spectral extension to each channel by copying lower frequency + * coefficients to higher frequency bins and applying side information to + * approximate the original high frequency signal. + */ +static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s); + +#if (!USE_FIXED) +extern float ff_ac3_heavy_dynamic_range_tab[256]; +#endif + +#endif /* AVCODEC_AC3DEC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_data.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_data.c new file mode 100644 index 000000000..d0a9b1ec4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_data.c @@ -0,0 +1,60 @@ +/* + * AC-3 and E-AC-3 decoder tables + * Copyright (c) 2007 Bartlomiej Wolowiec + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Tables taken directly from the AC-3 spec. + */ + +#include "ac3dec_data.h" +#include "ac3.h" + +/** + * Table used to ungroup 3 values stored in 5 bits. + * Used by bap=1 mantissas and GAQ. + * ff_ac3_ungroup_3_in_5_bits_tab[i] = { i/9, (i%9)/3, (i%9)%3 } + */ +const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3] = { + { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 2 }, { 0, 1, 0 }, + { 0, 1, 1 }, { 0, 1, 2 }, { 0, 2, 0 }, { 0, 2, 1 }, + { 0, 2, 2 }, { 1, 0, 0 }, { 1, 0, 1 }, { 1, 0, 2 }, + { 1, 1, 0 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 2, 0 }, + { 1, 2, 1 }, { 1, 2, 2 }, { 2, 0, 0 }, { 2, 0, 1 }, + { 2, 0, 2 }, { 2, 1, 0 }, { 2, 1, 1 }, { 2, 1, 2 }, + { 2, 2, 0 }, { 2, 2, 1 }, { 2, 2, 2 }, { 3, 0, 0 }, + { 3, 0, 1 }, { 3, 0, 2 }, { 3, 1, 0 }, { 3, 1, 1 } +}; + +const uint8_t ff_eac3_hebap_tab[64] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, + 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, + 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, + 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, + 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, + 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, + 19, 19, 19, 19, +}; + +/** + * Table E2.15 Default Spectral Extension Banding Structure + */ +const uint8_t ff_eac3_default_spx_band_struct[17] = +{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_data.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_data.h new file mode 100644 index 000000000..975b52ef2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_data.h @@ -0,0 +1,32 @@ +/* + * AC-3 and E-AC-3 decoder tables + * Copyright (c) 2007 Bartlomiej Wolowiec + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AC3DEC_DATA_H +#define AVCODEC_AC3DEC_DATA_H + +#include + +extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3]; + +extern const uint8_t ff_eac3_hebap_tab[64]; +extern const uint8_t ff_eac3_default_spx_band_struct[17]; + +#endif /* AVCODEC_AC3DEC_DATA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_fixed.c new file mode 100644 index 000000000..bd66175d5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_fixed.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Stanislav Ocovaj (socovaj@mips.com) + * + * AC3 fixed-point decoder for MIPS platforms + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define FFT_FLOAT 0 +#define USE_FIXED 1 +#define FFT_FIXED_32 1 +#include "ac3dec.h" + + +static const int end_freq_inv_tab[8] = +{ + 50529027, 44278013, 39403370, 32292987, 27356480, 23729101, 20951060, 18755316 +}; + +static void scale_coefs ( + int32_t *dst, + const int32_t *src, + int dynrng, + int len) +{ + int i, shift; + unsigned mul, round; + int temp, temp1, temp2, temp3, temp4, temp5, temp6, temp7; + + mul = (dynrng & 0x1f) + 0x20; + shift = 4 - (sign_extend(dynrng, 9) >> 5); + if (shift > 0 ) { + round = 1 << (shift-1); + for (i=0; i> shift; + temp3 = src[i+3] * mul; + temp2 = temp2 + round; + + dst[i+1] = temp1 >> shift; + temp4 = src[i + 4] * mul; + temp3 = temp3 + round; + dst[i+2] = temp2 >> shift; + + temp5 = src[i+5] * mul; + temp4 = temp4 + round; + dst[i+3] = temp3 >> shift; + temp6 = src[i+6] * mul; + + dst[i+4] = temp4 >> shift; + temp5 = temp5 + round; + temp7 = src[i+7] * mul; + temp6 = temp6 + round; + + dst[i+5] = temp5 >> shift; + temp7 = temp7 + round; + dst[i+6] = temp6 >> shift; + dst[i+7] = temp7 >> shift; + + } + } else { + shift = -shift; + for (i=0; i>12; + samples[1][i] = (v1+2048)>>12; + } + } else if (out_ch == 1) { + for (i = 0; i < len; i++) { + v0 = 0; + for (j = 0; j < in_ch; j++) + v0 += samples[j][i] * matrix[0][j]; + samples[0][i] = (v0+2048)>>12; + } + } +} + +#include "eac3dec.c" +#include "ac3dec.c" + +static const AVOption options[] = { + { "cons_noisegen", "enable consistent noise generation", OFFSET(consistent_noise_generation), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR }, + { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR }, + { "heavy_compr", "enable heavy dynamic range compression", OFFSET(heavy_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR }, + { NULL}, +}; + +static const AVClass ac3_decoder_class = { + .class_name = "Fixed-Point AC-3 Decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_ac3_fixed_decoder = { + .name = "ac3_fixed", + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AC3, + .priv_data_size = sizeof (AC3DecodeContext), + .init = ac3_decode_init, + .close = ac3_decode_end, + .decode = ac3_decode_frame, + .capabilities = AV_CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_NONE }, + .priv_class = &ac3_decoder_class, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_float.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_float.c new file mode 100644 index 000000000..b85a4ce33 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dec_float.c @@ -0,0 +1,93 @@ +/* + * AC-3 Audio Decoder + * This code was developed as part of Google Summer of Code 2006. + * E-AC-3 support was added as part of Google Summer of Code 2007. + * + * Copyright (c) 2006 Kartikey Mahendra BHATT (bhattkm at gmail dot com) + * Copyright (c) 2007-2008 Bartlomiej Wolowiec + * Copyright (c) 2007 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * Upmix delay samples from stereo to original channel layout. + */ +#include "ac3dec.h" +#include "eac3dec.c" +#include "ac3dec.c" + +static const AVOption options[] = { + { "cons_noisegen", "enable consistent noise generation", OFFSET(consistent_noise_generation), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR }, + { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR }, + { "heavy_compr", "enable heavy dynamic range compression", OFFSET(heavy_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR }, + { "target_level", "target level in -dBFS (0 not applied)", OFFSET(target_level), AV_OPT_TYPE_INT, {.i64 = 0 }, -31, 0, PAR }, + +{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, 0, "dmix_mode"}, +{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, + + { NULL}, +}; + +static const AVClass ac3_decoder_class = { + .class_name = "AC3 decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_ac3_decoder = { + .name = "ac3", + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AC3, + .priv_data_size = sizeof (AC3DecodeContext), + .init = ac3_decode_init, + .close = ac3_decode_end, + .decode = ac3_decode_frame, + .capabilities = AV_CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, + .priv_class = &ac3_decoder_class, +}; + +#if CONFIG_EAC3_DECODER +static const AVClass eac3_decoder_class = { + .class_name = "E-AC3 decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_eac3_decoder = { + .name = "eac3", + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_EAC3, + .priv_data_size = sizeof (AC3DecodeContext), + .init = ac3_decode_init, + .close = ac3_decode_end, + .decode = ac3_decode_frame, + .capabilities = AV_CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, + .priv_class = &eac3_decoder_class, +}; +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dsp.c new file mode 100644 index 000000000..43438da13 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dsp.c @@ -0,0 +1,447 @@ +/* + * AC-3 DSP functions + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "ac3.h" +#include "ac3dsp.h" +#include "mathops.h" + +static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs) +{ + int blk, i; + + if (!num_reuse_blocks) + return; + + for (i = 0; i < nb_coefs; i++) { + uint8_t min_exp = *exp; + uint8_t *exp1 = exp + 256; + for (blk = 0; blk < num_reuse_blocks; blk++) { + uint8_t next_exp = *exp1; + if (next_exp < min_exp) + min_exp = next_exp; + exp1 += 256; + } + *exp++ = min_exp; + } +} + +static int ac3_max_msb_abs_int16_c(const int16_t *src, int len) +{ + int i, v = 0; + for (i = 0; i < len; i++) + v |= abs(src[i]); + return v; +} + +static void ac3_lshift_int16_c(int16_t *src, unsigned int len, + unsigned int shift) +{ + uint32_t *src32 = (uint32_t *)src; + const uint32_t mask = ~(((1 << shift) - 1) << 16); + int i; + len >>= 1; + for (i = 0; i < len; i += 8) { + src32[i ] = (src32[i ] << shift) & mask; + src32[i+1] = (src32[i+1] << shift) & mask; + src32[i+2] = (src32[i+2] << shift) & mask; + src32[i+3] = (src32[i+3] << shift) & mask; + src32[i+4] = (src32[i+4] << shift) & mask; + src32[i+5] = (src32[i+5] << shift) & mask; + src32[i+6] = (src32[i+6] << shift) & mask; + src32[i+7] = (src32[i+7] << shift) & mask; + } +} + +static void ac3_rshift_int32_c(int32_t *src, unsigned int len, + unsigned int shift) +{ + do { + *src++ >>= shift; + *src++ >>= shift; + *src++ >>= shift; + *src++ >>= shift; + *src++ >>= shift; + *src++ >>= shift; + *src++ >>= shift; + *src++ >>= shift; + len -= 8; + } while (len > 0); +} + +static void float_to_fixed24_c(int32_t *dst, const float *src, unsigned int len) +{ + const float scale = 1 << 24; + do { + *dst++ = lrintf(*src++ * scale); + *dst++ = lrintf(*src++ * scale); + *dst++ = lrintf(*src++ * scale); + *dst++ = lrintf(*src++ * scale); + *dst++ = lrintf(*src++ * scale); + *dst++ = lrintf(*src++ * scale); + *dst++ = lrintf(*src++ * scale); + *dst++ = lrintf(*src++ * scale); + len -= 8; + } while (len > 0); +} + +static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd, + int start, int end, + int snr_offset, int floor, + const uint8_t *bap_tab, uint8_t *bap) +{ + int bin, band, band_end; + + /* special case, if snr offset is -960, set all bap's to zero */ + if (snr_offset == -960) { + memset(bap, 0, AC3_MAX_COEFS); + return; + } + + bin = start; + band = ff_ac3_bin_to_band_tab[start]; + do { + int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor; + band_end = ff_ac3_band_start_tab[++band]; + band_end = FFMIN(band_end, end); + + for (; bin < band_end; bin++) { + int address = av_clip_uintp2((psd[bin] - m) >> 5, 6); + bap[bin] = bap_tab[address]; + } + } while (end > band_end); +} + +static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap, + int len) +{ + while (len-- > 0) + mant_cnt[bap[len]]++; +} + +DECLARE_ALIGNED(16, const uint16_t, ff_ac3_bap_bits)[16] = { + 0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 +}; + +static int ac3_compute_mantissa_size_c(uint16_t mant_cnt[6][16]) +{ + int blk, bap; + int bits = 0; + + for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + // bap=1 : 3 mantissas in 5 bits + bits += (mant_cnt[blk][1] / 3) * 5; + // bap=2 : 3 mantissas in 7 bits + // bap=4 : 2 mantissas in 7 bits + bits += ((mant_cnt[blk][2] / 3) + (mant_cnt[blk][4] >> 1)) * 7; + // bap=3 : 1 mantissa in 3 bits + bits += mant_cnt[blk][3] * 3; + // bap=5 to 15 : get bits per mantissa from table + for (bap = 5; bap < 16; bap++) + bits += mant_cnt[blk][bap] * ff_ac3_bap_bits[bap]; + } + return bits; +} + +static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs) +{ + int i; + + for (i = 0; i < nb_coefs; i++) { + int v = abs(coef[i]); + exp[i] = v ? 23 - av_log2(v) : 24; + } +} + +static void ac3_sum_square_butterfly_int32_c(int64_t sum[4], + const int32_t *coef0, + const int32_t *coef1, + int len) +{ + int i; + + sum[0] = sum[1] = sum[2] = sum[3] = 0; + + for (i = 0; i < len; i++) { + int lt = coef0[i]; + int rt = coef1[i]; + int md = lt + rt; + int sd = lt - rt; + MAC64(sum[0], lt, lt); + MAC64(sum[1], rt, rt); + MAC64(sum[2], md, md); + MAC64(sum[3], sd, sd); + } +} + +static void ac3_sum_square_butterfly_float_c(float sum[4], + const float *coef0, + const float *coef1, + int len) +{ + int i; + + sum[0] = sum[1] = sum[2] = sum[3] = 0; + + for (i = 0; i < len; i++) { + float lt = coef0[i]; + float rt = coef1[i]; + float md = lt + rt; + float sd = lt - rt; + sum[0] += lt * lt; + sum[1] += rt * rt; + sum[2] += md * md; + sum[3] += sd * sd; + } +} + +static void ac3_downmix_5_to_2_symmetric_c(float **samples, float **matrix, + int len) +{ + int i; + float v0, v1; + float front_mix = matrix[0][0]; + float center_mix = matrix[0][1]; + float surround_mix = matrix[0][3]; + + for (i = 0; i < len; i++) { + v0 = samples[0][i] * front_mix + + samples[1][i] * center_mix + + samples[3][i] * surround_mix; + + v1 = samples[1][i] * center_mix + + samples[2][i] * front_mix + + samples[4][i] * surround_mix; + + samples[0][i] = v0; + samples[1][i] = v1; + } +} + +static void ac3_downmix_5_to_1_symmetric_c(float **samples, float **matrix, + int len) +{ + int i; + float front_mix = matrix[0][0]; + float center_mix = matrix[0][1]; + float surround_mix = matrix[0][3]; + + for (i = 0; i < len; i++) { + samples[0][i] = samples[0][i] * front_mix + + samples[1][i] * center_mix + + samples[2][i] * front_mix + + samples[3][i] * surround_mix + + samples[4][i] * surround_mix; + } +} + +static void ac3_downmix_c(float **samples, float **matrix, + int out_ch, int in_ch, int len) +{ + int i, j; + float v0, v1; + + if (out_ch == 2) { + for (i = 0; i < len; i++) { + v0 = v1 = 0.0f; + for (j = 0; j < in_ch; j++) { + v0 += samples[j][i] * matrix[0][j]; + v1 += samples[j][i] * matrix[1][j]; + } + samples[0][i] = v0; + samples[1][i] = v1; + } + } else if (out_ch == 1) { + for (i = 0; i < len; i++) { + v0 = 0.0f; + for (j = 0; j < in_ch; j++) + v0 += samples[j][i] * matrix[0][j]; + samples[0][i] = v0; + } + } +} + +static void ac3_downmix_5_to_2_symmetric_c_fixed(int32_t **samples, int16_t **matrix, + int len) +{ + int i; + int64_t v0, v1; + int16_t front_mix = matrix[0][0]; + int16_t center_mix = matrix[0][1]; + int16_t surround_mix = matrix[0][3]; + + for (i = 0; i < len; i++) { + v0 = (int64_t)samples[0][i] * front_mix + + (int64_t)samples[1][i] * center_mix + + (int64_t)samples[3][i] * surround_mix; + + v1 = (int64_t)samples[1][i] * center_mix + + (int64_t)samples[2][i] * front_mix + + (int64_t)samples[4][i] * surround_mix; + + samples[0][i] = (v0+2048)>>12; + samples[1][i] = (v1+2048)>>12; + } +} + +static void ac3_downmix_5_to_1_symmetric_c_fixed(int32_t **samples, int16_t **matrix, + int len) +{ + int i; + int64_t v0; + int16_t front_mix = matrix[0][0]; + int16_t center_mix = matrix[0][1]; + int16_t surround_mix = matrix[0][3]; + + for (i = 0; i < len; i++) { + v0 = (int64_t)samples[0][i] * front_mix + + (int64_t)samples[1][i] * center_mix + + (int64_t)samples[2][i] * front_mix + + (int64_t)samples[3][i] * surround_mix + + (int64_t)samples[4][i] * surround_mix; + + samples[0][i] = (v0+2048)>>12; + } +} + +static void ac3_downmix_c_fixed(int32_t **samples, int16_t **matrix, + int out_ch, int in_ch, int len) +{ + int i, j; + int64_t v0, v1; + if (out_ch == 2) { + for (i = 0; i < len; i++) { + v0 = v1 = 0; + for (j = 0; j < in_ch; j++) { + v0 += (int64_t)samples[j][i] * matrix[0][j]; + v1 += (int64_t)samples[j][i] * matrix[1][j]; + } + samples[0][i] = (v0+2048)>>12; + samples[1][i] = (v1+2048)>>12; + } + } else if (out_ch == 1) { + for (i = 0; i < len; i++) { + v0 = 0; + for (j = 0; j < in_ch; j++) + v0 += (int64_t)samples[j][i] * matrix[0][j]; + samples[0][i] = (v0+2048)>>12; + } + } +} + +void ff_ac3dsp_downmix_fixed(AC3DSPContext *c, int32_t **samples, int16_t **matrix, + int out_ch, int in_ch, int len) +{ + if (c->in_channels != in_ch || c->out_channels != out_ch) { + c->in_channels = in_ch; + c->out_channels = out_ch; + c->downmix_fixed = NULL; + + if (in_ch == 5 && out_ch == 2 && + !(matrix[1][0] | matrix[0][2] | + matrix[1][3] | matrix[0][4] | + (matrix[0][1] ^ matrix[1][1]) | + (matrix[0][0] ^ matrix[1][2]))) { + c->downmix_fixed = ac3_downmix_5_to_2_symmetric_c_fixed; + } else if (in_ch == 5 && out_ch == 1 && + matrix[0][0] == matrix[0][2] && + matrix[0][3] == matrix[0][4]) { + c->downmix_fixed = ac3_downmix_5_to_1_symmetric_c_fixed; + } + } + + if (c->downmix_fixed) + c->downmix_fixed(samples, matrix, len); + else + ac3_downmix_c_fixed(samples, matrix, out_ch, in_ch, len); +} + +static void apply_window_int16_c(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len) +{ + int i; + int len2 = len >> 1; + + for (i = 0; i < len2; i++) { + int16_t w = window[i]; + output[i] = (MUL16(input[i], w) + (1 << 14)) >> 15; + output[len-i-1] = (MUL16(input[len-i-1], w) + (1 << 14)) >> 15; + } +} + +void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix, + int out_ch, int in_ch, int len) +{ + if (c->in_channels != in_ch || c->out_channels != out_ch) { + int **matrix_cmp = (int **)matrix; + + c->in_channels = in_ch; + c->out_channels = out_ch; + c->downmix = NULL; + + if (in_ch == 5 && out_ch == 2 && + !(matrix_cmp[1][0] | matrix_cmp[0][2] | + matrix_cmp[1][3] | matrix_cmp[0][4] | + (matrix_cmp[0][1] ^ matrix_cmp[1][1]) | + (matrix_cmp[0][0] ^ matrix_cmp[1][2]))) { + c->downmix = ac3_downmix_5_to_2_symmetric_c; + } else if (in_ch == 5 && out_ch == 1 && + matrix_cmp[0][0] == matrix_cmp[0][2] && + matrix_cmp[0][3] == matrix_cmp[0][4]) { + c->downmix = ac3_downmix_5_to_1_symmetric_c; + } + + if (ARCH_X86) + ff_ac3dsp_set_downmix_x86(c); + } + + if (c->downmix) + c->downmix(samples, matrix, len); + else + ac3_downmix_c(samples, matrix, out_ch, in_ch, len); +} + +av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) +{ + c->ac3_exponent_min = ac3_exponent_min_c; + c->ac3_max_msb_abs_int16 = ac3_max_msb_abs_int16_c; + c->ac3_lshift_int16 = ac3_lshift_int16_c; + c->ac3_rshift_int32 = ac3_rshift_int32_c; + c->float_to_fixed24 = float_to_fixed24_c; + c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_c; + c->update_bap_counts = ac3_update_bap_counts_c; + c->compute_mantissa_size = ac3_compute_mantissa_size_c; + c->extract_exponents = ac3_extract_exponents_c; + c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c; + c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c; + c->in_channels = 0; + c->out_channels = 0; + c->downmix = NULL; + c->downmix_fixed = NULL; + c->apply_window_int16 = apply_window_int16_c; + + if (ARCH_ARM) + ff_ac3dsp_init_arm(c, bit_exact); + if (ARCH_X86) + ff_ac3dsp_init_x86(c, bit_exact); + if (ARCH_MIPS) + ff_ac3dsp_init_mips(c, bit_exact); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dsp.h new file mode 100644 index 000000000..161de4cb8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3dsp.h @@ -0,0 +1,167 @@ +/* + * AC-3 DSP functions + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AC3DSP_H +#define AVCODEC_AC3DSP_H + +#include + +/** + * Number of mantissa bits written for each bap value. + * bap values with fractional bits are set to 0 and are calculated separately. + */ +extern const uint16_t ff_ac3_bap_bits[16]; + +typedef struct AC3DSPContext { + /** + * Set each encoded exponent in a block to the minimum of itself and the + * exponents in the same frequency bin of up to 5 following blocks. + * @param exp pointer to the start of the current block of exponents. + * constraints: align 16 + * @param num_reuse_blocks number of blocks that will reuse exponents from the current block. + * constraints: range 0 to 5 + * @param nb_coefs number of frequency coefficients. + */ + void (*ac3_exponent_min)(uint8_t *exp, int num_reuse_blocks, int nb_coefs); + + /** + * Calculate the maximum MSB of the absolute value of each element in an + * array of int16_t. + * @param src input array + * constraints: align 16. values must be in range [-32767,32767] + * @param len number of values in the array + * constraints: multiple of 16 greater than 0 + * @return a value with the same MSB as max(abs(src[])) + */ + int (*ac3_max_msb_abs_int16)(const int16_t *src, int len); + + /** + * Left-shift each value in an array of int16_t by a specified amount. + * @param src input array + * constraints: align 16 + * @param len number of values in the array + * constraints: multiple of 32 greater than 0 + * @param shift left shift amount + * constraints: range [0,15] + */ + void (*ac3_lshift_int16)(int16_t *src, unsigned int len, unsigned int shift); + + /** + * Right-shift each value in an array of int32_t by a specified amount. + * @param src input array + * constraints: align 16 + * @param len number of values in the array + * constraints: multiple of 16 greater than 0 + * @param shift right shift amount + * constraints: range [0,31] + */ + void (*ac3_rshift_int32)(int32_t *src, unsigned int len, unsigned int shift); + + /** + * Convert an array of float in range [-1.0,1.0] to int32_t with range + * [-(1<<24),(1<<24)] + * + * @param dst destination array of int32_t. + * constraints: 16-byte aligned + * @param src source array of float. + * constraints: 16-byte aligned + * @param len number of elements to convert. + * constraints: multiple of 32 greater than zero + */ + void (*float_to_fixed24)(int32_t *dst, const float *src, unsigned int len); + + /** + * Calculate bit allocation pointers. + * The SNR is the difference between the masking curve and the signal. AC-3 + * uses this value for each frequency bin to allocate bits. The snroffset + * parameter is a global adjustment to the SNR for all bins. + * + * @param[in] mask masking curve + * @param[in] psd signal power for each frequency bin + * @param[in] start starting bin location + * @param[in] end ending bin location + * @param[in] snr_offset SNR adjustment + * @param[in] floor noise floor + * @param[in] bap_tab look-up table for bit allocation pointers + * @param[out] bap bit allocation pointers + */ + void (*bit_alloc_calc_bap)(int16_t *mask, int16_t *psd, int start, int end, + int snr_offset, int floor, + const uint8_t *bap_tab, uint8_t *bap); + + /** + * Update bap counts using the supplied array of bap. + * + * @param[out] mant_cnt bap counts for 1 block + * @param[in] bap array of bap, pointing to start coef bin + * @param[in] len number of elements to process + */ + void (*update_bap_counts)(uint16_t mant_cnt[16], uint8_t *bap, int len); + + /** + * Calculate the number of bits needed to encode a set of mantissas. + * + * @param[in] mant_cnt bap counts for all blocks + * @return mantissa bit count + */ + int (*compute_mantissa_size)(uint16_t mant_cnt[6][16]); + + void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs); + + void (*sum_square_butterfly_int32)(int64_t sum[4], const int32_t *coef0, + const int32_t *coef1, int len); + + void (*sum_square_butterfly_float)(float sum[4], const float *coef0, + const float *coef1, int len); + + int out_channels; + int in_channels; + void (*downmix)(float **samples, float **matrix, int len); + void (*downmix_fixed)(int32_t **samples, int16_t **matrix, int len); + + /** + * Apply symmetric window in 16-bit fixed-point. + * @param output destination array + * constraints: 16-byte aligned + * @param input source array + * constraints: 16-byte aligned + * @param window window array + * constraints: 16-byte aligned, at least len/2 elements + * @param len full window length + * constraints: multiple of ? greater than zero + */ + void (*apply_window_int16)(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +} AC3DSPContext; + +void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact); +void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact); +void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact); +void ff_ac3dsp_init_mips(AC3DSPContext *c, int bit_exact); + +void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix, + int out_ch, int in_ch, int len); +void ff_ac3dsp_downmix_fixed(AC3DSPContext *c, int32_t **samples, int16_t **matrix, + int out_ch, int in_ch, int len); + +void ff_ac3dsp_set_downmix_x86(AC3DSPContext *c); + +#endif /* AVCODEC_AC3DSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc.c new file mode 100644 index 000000000..f1c95ce87 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc.c @@ -0,0 +1,2495 @@ +/* + * The simplest AC-3 encoder + * Copyright (c) 2000 Fabrice Bellard + * Copyright (c) 2006-2010 Justin Ruggles + * Copyright (c) 2006-2010 Prakash Punnoor + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * The simplest AC-3 encoder. + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/channel_layout.h" +#include "libavutil/crc.h" +#include "libavutil/internal.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "internal.h" +#include "me_cmp.h" +#include "put_bits.h" +#include "audiodsp.h" +#include "ac3dsp.h" +#include "ac3.h" +#include "fft.h" +#include "ac3enc.h" +#include "eac3enc.h" + +typedef struct AC3Mant { + int16_t *qmant1_ptr, *qmant2_ptr, *qmant4_ptr; ///< mantissa pointers for bap=1,2,4 + int mant1_cnt, mant2_cnt, mant4_cnt; ///< mantissa counts for bap=1,2,4 +} AC3Mant; + +#define CMIXLEV_NUM_OPTIONS 3 +static const float cmixlev_options[CMIXLEV_NUM_OPTIONS] = { + LEVEL_MINUS_3DB, LEVEL_MINUS_4POINT5DB, LEVEL_MINUS_6DB +}; + +#define SURMIXLEV_NUM_OPTIONS 3 +static const float surmixlev_options[SURMIXLEV_NUM_OPTIONS] = { + LEVEL_MINUS_3DB, LEVEL_MINUS_6DB, LEVEL_ZERO +}; + +#define EXTMIXLEV_NUM_OPTIONS 8 +static const float extmixlev_options[EXTMIXLEV_NUM_OPTIONS] = { + LEVEL_PLUS_3DB, LEVEL_PLUS_1POINT5DB, LEVEL_ONE, LEVEL_MINUS_4POINT5DB, + LEVEL_MINUS_3DB, LEVEL_MINUS_4POINT5DB, LEVEL_MINUS_6DB, LEVEL_ZERO +}; + + +/** + * LUT for number of exponent groups. + * exponent_group_tab[coupling][exponent strategy-1][number of coefficients] + */ +static uint8_t exponent_group_tab[2][3][256]; + + +/** + * List of supported channel layouts. + */ +const uint64_t ff_ac3_channel_layouts[19] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_2_1, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_2_2, + AV_CH_LAYOUT_QUAD, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_5POINT0, + AV_CH_LAYOUT_5POINT0_BACK, + (AV_CH_LAYOUT_MONO | AV_CH_LOW_FREQUENCY), + (AV_CH_LAYOUT_STEREO | AV_CH_LOW_FREQUENCY), + (AV_CH_LAYOUT_2_1 | AV_CH_LOW_FREQUENCY), + (AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY), + (AV_CH_LAYOUT_2_2 | AV_CH_LOW_FREQUENCY), + (AV_CH_LAYOUT_QUAD | AV_CH_LOW_FREQUENCY), + (AV_CH_LAYOUT_4POINT0 | AV_CH_LOW_FREQUENCY), + AV_CH_LAYOUT_5POINT1, + AV_CH_LAYOUT_5POINT1_BACK, + 0 +}; + + +/** + * LUT to select the bandwidth code based on the bit rate, sample rate, and + * number of full-bandwidth channels. + * bandwidth_tab[fbw_channels-1][sample rate code][bit rate code] + */ +static const uint8_t ac3_bandwidth_tab[5][3][19] = { +// 32 40 48 56 64 80 96 112 128 160 192 224 256 320 384 448 512 576 640 + + { { 0, 0, 0, 12, 16, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 }, + { 0, 0, 0, 16, 20, 36, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 }, + { 0, 0, 0, 32, 40, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 } }, + + { { 0, 0, 0, 0, 0, 0, 0, 20, 24, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48 }, + { 0, 0, 0, 0, 0, 0, 4, 24, 28, 36, 56, 56, 56, 56, 56, 56, 56, 56, 56 }, + { 0, 0, 0, 0, 0, 0, 20, 44, 52, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 } }, + + { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 24, 32, 40, 48, 48, 48, 48, 48, 48 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 4, 20, 28, 36, 44, 56, 56, 56, 56, 56, 56 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 20, 40, 48, 60, 60, 60, 60, 60, 60, 60, 60 } }, + + { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 24, 32, 48, 48, 48, 48, 48, 48 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 36, 56, 56, 56, 56, 56, 56 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 48, 60, 60, 60, 60, 60, 60, 60 } }, + + { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 20, 32, 40, 48, 48, 48, 48 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 24, 36, 44, 56, 56, 56, 56 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 44, 60, 60, 60, 60, 60, 60 } } +}; + + +/** + * LUT to select the coupling start band based on the bit rate, sample rate, and + * number of full-bandwidth channels. -1 = coupling off + * ac3_coupling_start_tab[channel_mode-2][sample rate code][bit rate code] + * + * TODO: more testing for optimal parameters. + * multi-channel tests at 44.1kHz and 32kHz. + */ +static const int8_t ac3_coupling_start_tab[6][3][19] = { +// 32 40 48 56 64 80 96 112 128 160 192 224 256 320 384 448 512 576 640 + + // 2/0 + { { 0, 0, 0, 0, 0, 0, 0, 1, 1, 7, 8, 11, 12, -1, -1, -1, -1, -1, -1 }, + { 0, 0, 0, 0, 0, 0, 1, 3, 5, 7, 10, 12, 13, -1, -1, -1, -1, -1, -1 }, + { 0, 0, 0, 0, 1, 2, 2, 9, 13, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, + + // 3/0 + { { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 }, + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, + + // 2/1 - untested + { { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 }, + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, + + // 3/1 + { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 }, + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, + + // 2/2 - untested + { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 }, + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, + + // 3/2 + { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 8, 11, 12, 12, -1, -1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 8, 11, 12, 12, -1, -1 }, + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, +}; + + +/** + * Adjust the frame size to make the average bit rate match the target bit rate. + * This is only needed for 11025, 22050, and 44100 sample rates or any E-AC-3. + * + * @param s AC-3 encoder private context + */ +void ff_ac3_adjust_frame_size(AC3EncodeContext *s) +{ + while (s->bits_written >= s->bit_rate && s->samples_written >= s->sample_rate) { + s->bits_written -= s->bit_rate; + s->samples_written -= s->sample_rate; + } + s->frame_size = s->frame_size_min + + 2 * (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate); + s->bits_written += s->frame_size * 8; + s->samples_written += AC3_BLOCK_SIZE * s->num_blocks; +} + + +/** + * Set the initial coupling strategy parameters prior to coupling analysis. + * + * @param s AC-3 encoder private context + */ +void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s) +{ + int blk, ch; + int got_cpl_snr; + int num_cpl_blocks; + + /* set coupling use flags for each block/channel */ + /* TODO: turn coupling on/off and adjust start band based on bit usage */ + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + for (ch = 1; ch <= s->fbw_channels; ch++) + block->channel_in_cpl[ch] = s->cpl_on; + } + + /* enable coupling for each block if at least 2 channels have coupling + enabled for that block */ + got_cpl_snr = 0; + num_cpl_blocks = 0; + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + block->num_cpl_channels = 0; + for (ch = 1; ch <= s->fbw_channels; ch++) + block->num_cpl_channels += block->channel_in_cpl[ch]; + block->cpl_in_use = block->num_cpl_channels > 1; + num_cpl_blocks += block->cpl_in_use; + if (!block->cpl_in_use) { + block->num_cpl_channels = 0; + for (ch = 1; ch <= s->fbw_channels; ch++) + block->channel_in_cpl[ch] = 0; + } + + block->new_cpl_strategy = !blk; + if (blk) { + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (block->channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]) { + block->new_cpl_strategy = 1; + break; + } + } + } + block->new_cpl_leak = block->new_cpl_strategy; + + if (!blk || (block->cpl_in_use && !got_cpl_snr)) { + block->new_snr_offsets = 1; + if (block->cpl_in_use) + got_cpl_snr = 1; + } else { + block->new_snr_offsets = 0; + } + } + if (!num_cpl_blocks) + s->cpl_on = 0; + + /* set bandwidth for each channel */ + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (block->channel_in_cpl[ch]) + block->end_freq[ch] = s->start_freq[CPL_CH]; + else + block->end_freq[ch] = s->bandwidth_code * 3 + 73; + } + } +} + + +/** + * Apply stereo rematrixing to coefficients based on rematrixing flags. + * + * @param s AC-3 encoder private context + */ +void ff_ac3_apply_rematrixing(AC3EncodeContext *s) +{ + int nb_coefs; + int blk, bnd, i; + int start, end; + uint8_t *flags = NULL; + + if (!s->rematrixing_enabled) + return; + + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + if (block->new_rematrixing_strategy) + flags = block->rematrixing_flags; + nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]); + for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) { + if (flags[bnd]) { + start = ff_ac3_rematrix_band_tab[bnd]; + end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); + for (i = start; i < end; i++) { + int32_t lt = block->fixed_coef[1][i]; + int32_t rt = block->fixed_coef[2][i]; + block->fixed_coef[1][i] = (lt + rt) >> 1; + block->fixed_coef[2][i] = (lt - rt) >> 1; + } + } + } + } +} + + +/* + * Initialize exponent tables. + */ +static av_cold void exponent_init(AC3EncodeContext *s) +{ + int expstr, i, grpsize; + + for (expstr = EXP_D15-1; expstr <= EXP_D45-1; expstr++) { + grpsize = 3 << expstr; + for (i = 12; i < 256; i++) { + exponent_group_tab[0][expstr][i] = (i + grpsize - 4) / grpsize; + exponent_group_tab[1][expstr][i] = (i ) / grpsize; + } + } + /* LFE */ + exponent_group_tab[0][0][7] = 2; + + if (CONFIG_EAC3_ENCODER && s->eac3) + ff_eac3_exponent_init(); +} + + +/* + * Extract exponents from the MDCT coefficients. + */ +static void extract_exponents(AC3EncodeContext *s) +{ + int ch = !s->cpl_on; + int chan_size = AC3_MAX_COEFS * s->num_blocks * (s->channels - ch + 1); + AC3Block *block = &s->blocks[0]; + + s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch], chan_size); +} + + +/** + * Exponent Difference Threshold. + * New exponents are sent if their SAD exceed this number. + */ +#define EXP_DIFF_THRESHOLD 500 + +/** + * Table used to select exponent strategy based on exponent reuse block interval. + */ +static const uint8_t exp_strategy_reuse_tab[4][6] = { + { EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15 }, + { EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15 }, + { EXP_D25, EXP_D25, EXP_D15, EXP_D15, EXP_D15, EXP_D15 }, + { EXP_D45, EXP_D25, EXP_D25, EXP_D15, EXP_D15, EXP_D15 } +}; + +/* + * Calculate exponent strategies for all channels. + * Array arrangement is reversed to simplify the per-channel calculation. + */ +static void compute_exp_strategy(AC3EncodeContext *s) +{ + int ch, blk, blk1; + + for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) { + uint8_t *exp_strategy = s->exp_strategy[ch]; + uint8_t *exp = s->blocks[0].exp[ch]; + int exp_diff; + + /* estimate if the exponent variation & decide if they should be + reused in the next frame */ + exp_strategy[0] = EXP_NEW; + exp += AC3_MAX_COEFS; + for (blk = 1; blk < s->num_blocks; blk++, exp += AC3_MAX_COEFS) { + if (ch == CPL_CH) { + if (!s->blocks[blk-1].cpl_in_use) { + exp_strategy[blk] = EXP_NEW; + continue; + } else if (!s->blocks[blk].cpl_in_use) { + exp_strategy[blk] = EXP_REUSE; + continue; + } + } else if (s->blocks[blk].channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]) { + exp_strategy[blk] = EXP_NEW; + continue; + } + exp_diff = s->mecc.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16); + exp_strategy[blk] = EXP_REUSE; + if (ch == CPL_CH && exp_diff > (EXP_DIFF_THRESHOLD * (s->blocks[blk].end_freq[ch] - s->start_freq[ch]) / AC3_MAX_COEFS)) + exp_strategy[blk] = EXP_NEW; + else if (ch > CPL_CH && exp_diff > EXP_DIFF_THRESHOLD) + exp_strategy[blk] = EXP_NEW; + } + + /* now select the encoding strategy type : if exponents are often + recoded, we use a coarse encoding */ + blk = 0; + while (blk < s->num_blocks) { + blk1 = blk + 1; + while (blk1 < s->num_blocks && exp_strategy[blk1] == EXP_REUSE) + blk1++; + exp_strategy[blk] = exp_strategy_reuse_tab[s->num_blks_code][blk1-blk-1]; + blk = blk1; + } + } + if (s->lfe_on) { + ch = s->lfe_channel; + s->exp_strategy[ch][0] = EXP_D15; + for (blk = 1; blk < s->num_blocks; blk++) + s->exp_strategy[ch][blk] = EXP_REUSE; + } + + /* for E-AC-3, determine frame exponent strategy */ + if (CONFIG_EAC3_ENCODER && s->eac3) + ff_eac3_get_frame_exp_strategy(s); +} + + +/** + * Update the exponents so that they are the ones the decoder will decode. + * + * @param[in,out] exp array of exponents for 1 block in 1 channel + * @param nb_exps number of exponents in active bandwidth + * @param exp_strategy exponent strategy for the block + * @param cpl indicates if the block is in the coupling channel + */ +static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy, + int cpl) +{ + int nb_groups, i, k; + + nb_groups = exponent_group_tab[cpl][exp_strategy-1][nb_exps] * 3; + + /* for each group, compute the minimum exponent */ + switch(exp_strategy) { + case EXP_D25: + for (i = 1, k = 1-cpl; i <= nb_groups; i++) { + uint8_t exp_min = exp[k]; + if (exp[k+1] < exp_min) + exp_min = exp[k+1]; + exp[i-cpl] = exp_min; + k += 2; + } + break; + case EXP_D45: + for (i = 1, k = 1-cpl; i <= nb_groups; i++) { + uint8_t exp_min = exp[k]; + if (exp[k+1] < exp_min) + exp_min = exp[k+1]; + if (exp[k+2] < exp_min) + exp_min = exp[k+2]; + if (exp[k+3] < exp_min) + exp_min = exp[k+3]; + exp[i-cpl] = exp_min; + k += 4; + } + break; + } + + /* constraint for DC exponent */ + if (!cpl && exp[0] > 15) + exp[0] = 15; + + /* decrease the delta between each groups to within 2 so that they can be + differentially encoded */ + for (i = 1; i <= nb_groups; i++) + exp[i] = FFMIN(exp[i], exp[i-1] + 2); + i--; + while (--i >= 0) + exp[i] = FFMIN(exp[i], exp[i+1] + 2); + + if (cpl) + exp[-1] = exp[0] & ~1; + + /* now we have the exponent values the decoder will see */ + switch (exp_strategy) { + case EXP_D25: + for (i = nb_groups, k = (nb_groups * 2)-cpl; i > 0; i--) { + uint8_t exp1 = exp[i-cpl]; + exp[k--] = exp1; + exp[k--] = exp1; + } + break; + case EXP_D45: + for (i = nb_groups, k = (nb_groups * 4)-cpl; i > 0; i--) { + exp[k] = exp[k-1] = exp[k-2] = exp[k-3] = exp[i-cpl]; + k -= 4; + } + break; + } +} + + +/* + * Encode exponents from original extracted form to what the decoder will see. + * This copies and groups exponents based on exponent strategy and reduces + * deltas between adjacent exponent groups so that they can be differentially + * encoded. + */ +static void encode_exponents(AC3EncodeContext *s) +{ + int blk, blk1, ch, cpl; + uint8_t *exp, *exp_strategy; + int nb_coefs, num_reuse_blocks; + + for (ch = !s->cpl_on; ch <= s->channels; ch++) { + exp = s->blocks[0].exp[ch] + s->start_freq[ch]; + exp_strategy = s->exp_strategy[ch]; + + cpl = (ch == CPL_CH); + blk = 0; + while (blk < s->num_blocks) { + AC3Block *block = &s->blocks[blk]; + if (cpl && !block->cpl_in_use) { + exp += AC3_MAX_COEFS; + blk++; + continue; + } + nb_coefs = block->end_freq[ch] - s->start_freq[ch]; + blk1 = blk + 1; + + /* count the number of EXP_REUSE blocks after the current block + and set exponent reference block numbers */ + s->exp_ref_block[ch][blk] = blk; + while (blk1 < s->num_blocks && exp_strategy[blk1] == EXP_REUSE) { + s->exp_ref_block[ch][blk1] = blk; + blk1++; + } + num_reuse_blocks = blk1 - blk - 1; + + /* for the EXP_REUSE case we select the min of the exponents */ + s->ac3dsp.ac3_exponent_min(exp-s->start_freq[ch], num_reuse_blocks, + AC3_MAX_COEFS); + + encode_exponents_blk_ch(exp, nb_coefs, exp_strategy[blk], cpl); + + exp += AC3_MAX_COEFS * (num_reuse_blocks + 1); + blk = blk1; + } + } + + /* reference block numbers have been changed, so reset ref_bap_set */ + s->ref_bap_set = 0; +} + + +/* + * Count exponent bits based on bandwidth, coupling, and exponent strategies. + */ +static int count_exponent_bits(AC3EncodeContext *s) +{ + int blk, ch; + int nb_groups, bit_count; + + bit_count = 0; + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { + int exp_strategy = s->exp_strategy[ch][blk]; + int cpl = (ch == CPL_CH); + int nb_coefs = block->end_freq[ch] - s->start_freq[ch]; + + if (exp_strategy == EXP_REUSE) + continue; + + nb_groups = exponent_group_tab[cpl][exp_strategy-1][nb_coefs]; + bit_count += 4 + (nb_groups * 7); + } + } + + return bit_count; +} + + +/** + * Group exponents. + * 3 delta-encoded exponents are in each 7-bit group. The number of groups + * varies depending on exponent strategy and bandwidth. + * + * @param s AC-3 encoder private context + */ +void ff_ac3_group_exponents(AC3EncodeContext *s) +{ + int blk, ch, i, cpl; + int group_size, nb_groups; + uint8_t *p; + int delta0, delta1, delta2; + int exp0, exp1; + + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { + int exp_strategy = s->exp_strategy[ch][blk]; + if (exp_strategy == EXP_REUSE) + continue; + cpl = (ch == CPL_CH); + group_size = exp_strategy + (exp_strategy == EXP_D45); + nb_groups = exponent_group_tab[cpl][exp_strategy-1][block->end_freq[ch]-s->start_freq[ch]]; + p = block->exp[ch] + s->start_freq[ch] - cpl; + + /* DC exponent */ + exp1 = *p++; + block->grouped_exp[ch][0] = exp1; + + /* remaining exponents are delta encoded */ + for (i = 1; i <= nb_groups; i++) { + /* merge three delta in one code */ + exp0 = exp1; + exp1 = p[0]; + p += group_size; + delta0 = exp1 - exp0 + 2; + av_assert2(delta0 >= 0 && delta0 <= 4); + + exp0 = exp1; + exp1 = p[0]; + p += group_size; + delta1 = exp1 - exp0 + 2; + av_assert2(delta1 >= 0 && delta1 <= 4); + + exp0 = exp1; + exp1 = p[0]; + p += group_size; + delta2 = exp1 - exp0 + 2; + av_assert2(delta2 >= 0 && delta2 <= 4); + + block->grouped_exp[ch][i] = ((delta0 * 5 + delta1) * 5) + delta2; + } + } + } +} + + +/** + * Calculate final exponents from the supplied MDCT coefficients and exponent shift. + * Extract exponents from MDCT coefficients, calculate exponent strategies, + * and encode final exponents. + * + * @param s AC-3 encoder private context + */ +void ff_ac3_process_exponents(AC3EncodeContext *s) +{ + extract_exponents(s); + + compute_exp_strategy(s); + + encode_exponents(s); + + emms_c(); +} + + +/* + * Count frame bits that are based solely on fixed parameters. + * This only has to be run once when the encoder is initialized. + */ +static void count_frame_bits_fixed(AC3EncodeContext *s) +{ + static const uint8_t frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 }; + int blk; + int frame_bits; + + /* assumptions: + * no dynamic range codes + * bit allocation parameters do not change between blocks + * no delta bit allocation + * no skipped data + * no auxiliary data + * no E-AC-3 metadata + */ + + /* header */ + frame_bits = 16; /* sync info */ + if (s->eac3) { + /* bitstream info header */ + frame_bits += 35; + frame_bits += 1 + 1; + if (s->num_blocks != 0x6) + frame_bits++; + frame_bits++; + /* audio frame header */ + if (s->num_blocks == 6) + frame_bits += 2; + frame_bits += 10; + /* exponent strategy */ + if (s->use_frame_exp_strategy) + frame_bits += 5 * s->fbw_channels; + else + frame_bits += s->num_blocks * 2 * s->fbw_channels; + if (s->lfe_on) + frame_bits += s->num_blocks; + /* converter exponent strategy */ + if (s->num_blks_code != 0x3) + frame_bits++; + else + frame_bits += s->fbw_channels * 5; + /* snr offsets */ + frame_bits += 10; + /* block start info */ + if (s->num_blocks != 1) + frame_bits++; + } else { + frame_bits += 49; + frame_bits += frame_bits_inc[s->channel_mode]; + } + + /* audio blocks */ + for (blk = 0; blk < s->num_blocks; blk++) { + if (!s->eac3) { + /* block switch flags */ + frame_bits += s->fbw_channels; + + /* dither flags */ + frame_bits += s->fbw_channels; + } + + /* dynamic range */ + frame_bits++; + + /* spectral extension */ + if (s->eac3) + frame_bits++; + + if (!s->eac3) { + /* exponent strategy */ + frame_bits += 2 * s->fbw_channels; + if (s->lfe_on) + frame_bits++; + + /* bit allocation params */ + frame_bits++; + if (!blk) + frame_bits += 2 + 2 + 2 + 2 + 3; + } + + /* converter snr offset */ + if (s->eac3) + frame_bits++; + + if (!s->eac3) { + /* delta bit allocation */ + frame_bits++; + + /* skipped data */ + frame_bits++; + } + } + + /* auxiliary data */ + frame_bits++; + + /* CRC */ + frame_bits += 1 + 16; + + s->frame_bits_fixed = frame_bits; +} + + +/* + * Initialize bit allocation. + * Set default parameter codes and calculate parameter values. + */ +static av_cold void bit_alloc_init(AC3EncodeContext *s) +{ + int ch; + + /* init default parameters */ + s->slow_decay_code = 2; + s->fast_decay_code = 1; + s->slow_gain_code = 1; + s->db_per_bit_code = s->eac3 ? 2 : 3; + s->floor_code = 7; + for (ch = 0; ch <= s->channels; ch++) + s->fast_gain_code[ch] = 4; + + /* initial snr offset */ + s->coarse_snr_offset = 40; + + /* compute real values */ + /* currently none of these values change during encoding, so we can just + set them once at initialization */ + s->bit_alloc.slow_decay = ff_ac3_slow_decay_tab[s->slow_decay_code] >> s->bit_alloc.sr_shift; + s->bit_alloc.fast_decay = ff_ac3_fast_decay_tab[s->fast_decay_code] >> s->bit_alloc.sr_shift; + s->bit_alloc.slow_gain = ff_ac3_slow_gain_tab[s->slow_gain_code]; + s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code]; + s->bit_alloc.floor = ff_ac3_floor_tab[s->floor_code]; + s->bit_alloc.cpl_fast_leak = 0; + s->bit_alloc.cpl_slow_leak = 0; + + count_frame_bits_fixed(s); +} + + +/* + * Count the bits used to encode the frame, minus exponents and mantissas. + * Bits based on fixed parameters have already been counted, so now we just + * have to add the bits based on parameters that change during encoding. + */ +static void count_frame_bits(AC3EncodeContext *s) +{ + AC3EncOptions *opt = &s->options; + int blk, ch; + int frame_bits = 0; + + /* header */ + if (s->eac3) { + if (opt->eac3_mixing_metadata) { + if (s->channel_mode > AC3_CHMODE_STEREO) + frame_bits += 2; + if (s->has_center) + frame_bits += 6; + if (s->has_surround) + frame_bits += 6; + frame_bits += s->lfe_on; + frame_bits += 1 + 1 + 2; + if (s->channel_mode < AC3_CHMODE_STEREO) + frame_bits++; + frame_bits++; + } + if (opt->eac3_info_metadata) { + frame_bits += 3 + 1 + 1; + if (s->channel_mode == AC3_CHMODE_STEREO) + frame_bits += 2 + 2; + if (s->channel_mode >= AC3_CHMODE_2F2R) + frame_bits += 2; + frame_bits++; + if (opt->audio_production_info) + frame_bits += 5 + 2 + 1; + frame_bits++; + } + /* coupling */ + if (s->channel_mode > AC3_CHMODE_MONO) { + frame_bits++; + for (blk = 1; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + frame_bits++; + if (block->new_cpl_strategy) + frame_bits++; + } + } + /* coupling exponent strategy */ + if (s->cpl_on) { + if (s->use_frame_exp_strategy) { + frame_bits += 5 * s->cpl_on; + } else { + for (blk = 0; blk < s->num_blocks; blk++) + frame_bits += 2 * s->blocks[blk].cpl_in_use; + } + } + } else { + if (opt->audio_production_info) + frame_bits += 7; + if (s->bitstream_id == 6) { + if (opt->extended_bsi_1) + frame_bits += 14; + if (opt->extended_bsi_2) + frame_bits += 14; + } + } + + /* audio blocks */ + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + + /* coupling strategy */ + if (!s->eac3) + frame_bits++; + if (block->new_cpl_strategy) { + if (!s->eac3) + frame_bits++; + if (block->cpl_in_use) { + if (s->eac3) + frame_bits++; + if (!s->eac3 || s->channel_mode != AC3_CHMODE_STEREO) + frame_bits += s->fbw_channels; + if (s->channel_mode == AC3_CHMODE_STEREO) + frame_bits++; + frame_bits += 4 + 4; + if (s->eac3) + frame_bits++; + else + frame_bits += s->num_cpl_subbands - 1; + } + } + + /* coupling coordinates */ + if (block->cpl_in_use) { + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (block->channel_in_cpl[ch]) { + if (!s->eac3 || block->new_cpl_coords[ch] != 2) + frame_bits++; + if (block->new_cpl_coords[ch]) { + frame_bits += 2; + frame_bits += (4 + 4) * s->num_cpl_bands; + } + } + } + } + + /* stereo rematrixing */ + if (s->channel_mode == AC3_CHMODE_STEREO) { + if (!s->eac3 || blk > 0) + frame_bits++; + if (s->blocks[blk].new_rematrixing_strategy) + frame_bits += block->num_rematrixing_bands; + } + + /* bandwidth codes & gain range */ + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (s->exp_strategy[ch][blk] != EXP_REUSE) { + if (!block->channel_in_cpl[ch]) + frame_bits += 6; + frame_bits += 2; + } + } + + /* coupling exponent strategy */ + if (!s->eac3 && block->cpl_in_use) + frame_bits += 2; + + /* snr offsets and fast gain codes */ + if (!s->eac3) { + frame_bits++; + if (block->new_snr_offsets) + frame_bits += 6 + (s->channels + block->cpl_in_use) * (4 + 3); + } + + /* coupling leak info */ + if (block->cpl_in_use) { + if (!s->eac3 || block->new_cpl_leak != 2) + frame_bits++; + if (block->new_cpl_leak) + frame_bits += 3 + 3; + } + } + + s->frame_bits = s->frame_bits_fixed + frame_bits; +} + + +/* + * Calculate masking curve based on the final exponents. + * Also calculate the power spectral densities to use in future calculations. + */ +static void bit_alloc_masking(AC3EncodeContext *s) +{ + int blk, ch; + + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { + /* We only need psd and mask for calculating bap. + Since we currently do not calculate bap when exponent + strategy is EXP_REUSE we do not need to calculate psd or mask. */ + if (s->exp_strategy[ch][blk] != EXP_REUSE) { + ff_ac3_bit_alloc_calc_psd(block->exp[ch], s->start_freq[ch], + block->end_freq[ch], block->psd[ch], + block->band_psd[ch]); + ff_ac3_bit_alloc_calc_mask(&s->bit_alloc, block->band_psd[ch], + s->start_freq[ch], block->end_freq[ch], + ff_ac3_fast_gain_tab[s->fast_gain_code[ch]], + ch == s->lfe_channel, + DBA_NONE, 0, NULL, NULL, NULL, + block->mask[ch]); + } + } + } +} + + +/* + * Ensure that bap for each block and channel point to the current bap_buffer. + * They may have been switched during the bit allocation search. + */ +static void reset_block_bap(AC3EncodeContext *s) +{ + int blk, ch; + uint8_t *ref_bap; + + if (s->ref_bap[0][0] == s->bap_buffer && s->ref_bap_set) + return; + + ref_bap = s->bap_buffer; + for (ch = 0; ch <= s->channels; ch++) { + for (blk = 0; blk < s->num_blocks; blk++) + s->ref_bap[ch][blk] = ref_bap + AC3_MAX_COEFS * s->exp_ref_block[ch][blk]; + ref_bap += AC3_MAX_COEFS * s->num_blocks; + } + s->ref_bap_set = 1; +} + + +/** + * Initialize mantissa counts. + * These are set so that they are padded to the next whole group size when bits + * are counted in compute_mantissa_size. + * + * @param[in,out] mant_cnt running counts for each bap value for each block + */ +static void count_mantissa_bits_init(uint16_t mant_cnt[AC3_MAX_BLOCKS][16]) +{ + int blk; + + for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + memset(mant_cnt[blk], 0, sizeof(mant_cnt[blk])); + mant_cnt[blk][1] = mant_cnt[blk][2] = 2; + mant_cnt[blk][4] = 1; + } +} + + +/** + * Update mantissa bit counts for all blocks in 1 channel in a given bandwidth + * range. + * + * @param s AC-3 encoder private context + * @param ch channel index + * @param[in,out] mant_cnt running counts for each bap value for each block + * @param start starting coefficient bin + * @param end ending coefficient bin + */ +static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch, + uint16_t mant_cnt[AC3_MAX_BLOCKS][16], + int start, int end) +{ + int blk; + + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + if (ch == CPL_CH && !block->cpl_in_use) + continue; + s->ac3dsp.update_bap_counts(mant_cnt[blk], + s->ref_bap[ch][blk] + start, + FFMIN(end, block->end_freq[ch]) - start); + } +} + + +/* + * Count the number of mantissa bits in the frame based on the bap values. + */ +static int count_mantissa_bits(AC3EncodeContext *s) +{ + int ch, max_end_freq; + LOCAL_ALIGNED_16(uint16_t, mant_cnt, [AC3_MAX_BLOCKS], [16]); + + count_mantissa_bits_init(mant_cnt); + + max_end_freq = s->bandwidth_code * 3 + 73; + for (ch = !s->cpl_enabled; ch <= s->channels; ch++) + count_mantissa_bits_update_ch(s, ch, mant_cnt, s->start_freq[ch], + max_end_freq); + + return s->ac3dsp.compute_mantissa_size(mant_cnt); +} + + +/** + * Run the bit allocation with a given SNR offset. + * This calculates the bit allocation pointers that will be used to determine + * the quantization of each mantissa. + * + * @param s AC-3 encoder private context + * @param snr_offset SNR offset, 0 to 1023 + * @return the number of bits needed for mantissas if the given SNR offset is + * is used. + */ +static int bit_alloc(AC3EncodeContext *s, int snr_offset) +{ + int blk, ch; + + snr_offset = (snr_offset - 240) << 2; + + reset_block_bap(s); + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + + for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { + /* Currently the only bit allocation parameters which vary across + blocks within a frame are the exponent values. We can take + advantage of that by reusing the bit allocation pointers + whenever we reuse exponents. */ + if (s->exp_strategy[ch][blk] != EXP_REUSE) { + s->ac3dsp.bit_alloc_calc_bap(block->mask[ch], block->psd[ch], + s->start_freq[ch], block->end_freq[ch], + snr_offset, s->bit_alloc.floor, + ff_ac3_bap_tab, s->ref_bap[ch][blk]); + } + } + } + return count_mantissa_bits(s); +} + + +/* + * Constant bitrate bit allocation search. + * Find the largest SNR offset that will allow data to fit in the frame. + */ +static int cbr_bit_allocation(AC3EncodeContext *s) +{ + int ch; + int bits_left; + int snr_offset, snr_incr; + + bits_left = 8 * s->frame_size - (s->frame_bits + s->exponent_bits); + if (bits_left < 0) + return AVERROR(EINVAL); + + snr_offset = s->coarse_snr_offset << 4; + + /* if previous frame SNR offset was 1023, check if current frame can also + use SNR offset of 1023. if so, skip the search. */ + if ((snr_offset | s->fine_snr_offset[1]) == 1023) { + if (bit_alloc(s, 1023) <= bits_left) + return 0; + } + + while (snr_offset >= 0 && + bit_alloc(s, snr_offset) > bits_left) { + snr_offset -= 64; + } + if (snr_offset < 0) + return AVERROR(EINVAL); + + FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer); + for (snr_incr = 64; snr_incr > 0; snr_incr >>= 2) { + while (snr_offset + snr_incr <= 1023 && + bit_alloc(s, snr_offset + snr_incr) <= bits_left) { + snr_offset += snr_incr; + FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer); + } + } + FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer); + reset_block_bap(s); + + s->coarse_snr_offset = snr_offset >> 4; + for (ch = !s->cpl_on; ch <= s->channels; ch++) + s->fine_snr_offset[ch] = snr_offset & 0xF; + + return 0; +} + + +/* + * Perform bit allocation search. + * Finds the SNR offset value that maximizes quality and fits in the specified + * frame size. Output is the SNR offset and a set of bit allocation pointers + * used to quantize the mantissas. + */ +int ff_ac3_compute_bit_allocation(AC3EncodeContext *s) +{ + count_frame_bits(s); + + s->exponent_bits = count_exponent_bits(s); + + bit_alloc_masking(s); + + return cbr_bit_allocation(s); +} + + +/** + * Symmetric quantization on 'levels' levels. + * + * @param c unquantized coefficient + * @param e exponent + * @param levels number of quantization levels + * @return quantized coefficient + */ +static inline int sym_quant(int c, int e, int levels) +{ + int v = (((levels * c) >> (24 - e)) + levels) >> 1; + av_assert2(v >= 0 && v < levels); + return v; +} + + +/** + * Asymmetric quantization on 2^qbits levels. + * + * @param c unquantized coefficient + * @param e exponent + * @param qbits number of quantization bits + * @return quantized coefficient + */ +static inline int asym_quant(int c, int e, int qbits) +{ + int m; + + c = (((c * (1<> (24 - qbits)) + 1) >> 1; + m = (1 << (qbits-1)); + if (c >= m) + c = m - 1; + av_assert2(c >= -m); + return c; +} + + +/** + * Quantize a set of mantissas for a single channel in a single block. + * + * @param s Mantissa count context + * @param fixed_coef unquantized fixed-point coefficients + * @param exp exponents + * @param bap bit allocation pointer indices + * @param[out] qmant quantized coefficients + * @param start_freq starting coefficient bin + * @param end_freq ending coefficient bin + */ +static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, + uint8_t *exp, uint8_t *bap, + int16_t *qmant, int start_freq, + int end_freq) +{ + int i; + + for (i = start_freq; i < end_freq; i++) { + int c = fixed_coef[i]; + int e = exp[i]; + int v = bap[i]; + if (v) + switch (v) { + case 1: + v = sym_quant(c, e, 3); + switch (s->mant1_cnt) { + case 0: + s->qmant1_ptr = &qmant[i]; + v = 9 * v; + s->mant1_cnt = 1; + break; + case 1: + *s->qmant1_ptr += 3 * v; + s->mant1_cnt = 2; + v = 128; + break; + default: + *s->qmant1_ptr += v; + s->mant1_cnt = 0; + v = 128; + break; + } + break; + case 2: + v = sym_quant(c, e, 5); + switch (s->mant2_cnt) { + case 0: + s->qmant2_ptr = &qmant[i]; + v = 25 * v; + s->mant2_cnt = 1; + break; + case 1: + *s->qmant2_ptr += 5 * v; + s->mant2_cnt = 2; + v = 128; + break; + default: + *s->qmant2_ptr += v; + s->mant2_cnt = 0; + v = 128; + break; + } + break; + case 3: + v = sym_quant(c, e, 7); + break; + case 4: + v = sym_quant(c, e, 11); + switch (s->mant4_cnt) { + case 0: + s->qmant4_ptr = &qmant[i]; + v = 11 * v; + s->mant4_cnt = 1; + break; + default: + *s->qmant4_ptr += v; + s->mant4_cnt = 0; + v = 128; + break; + } + break; + case 5: + v = sym_quant(c, e, 15); + break; + case 14: + v = asym_quant(c, e, 14); + break; + case 15: + v = asym_quant(c, e, 16); + break; + default: + v = asym_quant(c, e, v - 1); + break; + } + qmant[i] = v; + } +} + + +/** + * Quantize mantissas using coefficients, exponents, and bit allocation pointers. + * + * @param s AC-3 encoder private context + */ +void ff_ac3_quantize_mantissas(AC3EncodeContext *s) +{ + int blk, ch, ch0=0, got_cpl; + + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + AC3Mant m = { 0 }; + + got_cpl = !block->cpl_in_use; + for (ch = 1; ch <= s->channels; ch++) { + if (!got_cpl && ch > 1 && block->channel_in_cpl[ch-1]) { + ch0 = ch - 1; + ch = CPL_CH; + got_cpl = 1; + } + quantize_mantissas_blk_ch(&m, block->fixed_coef[ch], + s->blocks[s->exp_ref_block[ch][blk]].exp[ch], + s->ref_bap[ch][blk], block->qmant[ch], + s->start_freq[ch], block->end_freq[ch]); + if (ch == CPL_CH) + ch = ch0; + } + } +} + + +/* + * Write the AC-3 frame header to the output bitstream. + */ +static void ac3_output_frame_header(AC3EncodeContext *s) +{ + AC3EncOptions *opt = &s->options; + + put_bits(&s->pb, 16, 0x0b77); /* frame header */ + put_bits(&s->pb, 16, 0); /* crc1: will be filled later */ + put_bits(&s->pb, 2, s->bit_alloc.sr_code); + put_bits(&s->pb, 6, s->frame_size_code + (s->frame_size - s->frame_size_min) / 2); + put_bits(&s->pb, 5, s->bitstream_id); + put_bits(&s->pb, 3, s->bitstream_mode); + put_bits(&s->pb, 3, s->channel_mode); + if ((s->channel_mode & 0x01) && s->channel_mode != AC3_CHMODE_MONO) + put_bits(&s->pb, 2, s->center_mix_level); + if (s->channel_mode & 0x04) + put_bits(&s->pb, 2, s->surround_mix_level); + if (s->channel_mode == AC3_CHMODE_STEREO) + put_bits(&s->pb, 2, opt->dolby_surround_mode); + put_bits(&s->pb, 1, s->lfe_on); /* LFE */ + put_bits(&s->pb, 5, -opt->dialogue_level); + put_bits(&s->pb, 1, 0); /* no compression control word */ + put_bits(&s->pb, 1, 0); /* no lang code */ + put_bits(&s->pb, 1, opt->audio_production_info); + if (opt->audio_production_info) { + put_bits(&s->pb, 5, opt->mixing_level - 80); + put_bits(&s->pb, 2, opt->room_type); + } + put_bits(&s->pb, 1, opt->copyright); + put_bits(&s->pb, 1, opt->original); + if (s->bitstream_id == 6) { + /* alternate bit stream syntax */ + put_bits(&s->pb, 1, opt->extended_bsi_1); + if (opt->extended_bsi_1) { + put_bits(&s->pb, 2, opt->preferred_stereo_downmix); + put_bits(&s->pb, 3, s->ltrt_center_mix_level); + put_bits(&s->pb, 3, s->ltrt_surround_mix_level); + put_bits(&s->pb, 3, s->loro_center_mix_level); + put_bits(&s->pb, 3, s->loro_surround_mix_level); + } + put_bits(&s->pb, 1, opt->extended_bsi_2); + if (opt->extended_bsi_2) { + put_bits(&s->pb, 2, opt->dolby_surround_ex_mode); + put_bits(&s->pb, 2, opt->dolby_headphone_mode); + put_bits(&s->pb, 1, opt->ad_converter_type); + put_bits(&s->pb, 9, 0); /* xbsi2 and encinfo : reserved */ + } + } else { + put_bits(&s->pb, 1, 0); /* no time code 1 */ + put_bits(&s->pb, 1, 0); /* no time code 2 */ + } + put_bits(&s->pb, 1, 0); /* no additional bit stream info */ +} + + +/* + * Write one audio block to the output bitstream. + */ +static void output_audio_block(AC3EncodeContext *s, int blk) +{ + int ch, i, baie, bnd, got_cpl, av_uninit(ch0); + AC3Block *block = &s->blocks[blk]; + + /* block switching */ + if (!s->eac3) { + for (ch = 0; ch < s->fbw_channels; ch++) + put_bits(&s->pb, 1, 0); + } + + /* dither flags */ + if (!s->eac3) { + for (ch = 0; ch < s->fbw_channels; ch++) + put_bits(&s->pb, 1, 1); + } + + /* dynamic range codes */ + put_bits(&s->pb, 1, 0); + + /* spectral extension */ + if (s->eac3) + put_bits(&s->pb, 1, 0); + + /* channel coupling */ + if (!s->eac3) + put_bits(&s->pb, 1, block->new_cpl_strategy); + if (block->new_cpl_strategy) { + if (!s->eac3) + put_bits(&s->pb, 1, block->cpl_in_use); + if (block->cpl_in_use) { + int start_sub, end_sub; + if (s->eac3) + put_bits(&s->pb, 1, 0); /* enhanced coupling */ + if (!s->eac3 || s->channel_mode != AC3_CHMODE_STEREO) { + for (ch = 1; ch <= s->fbw_channels; ch++) + put_bits(&s->pb, 1, block->channel_in_cpl[ch]); + } + if (s->channel_mode == AC3_CHMODE_STEREO) + put_bits(&s->pb, 1, 0); /* phase flags in use */ + start_sub = (s->start_freq[CPL_CH] - 37) / 12; + end_sub = (s->cpl_end_freq - 37) / 12; + put_bits(&s->pb, 4, start_sub); + put_bits(&s->pb, 4, end_sub - 3); + /* coupling band structure */ + if (s->eac3) { + put_bits(&s->pb, 1, 0); /* use default */ + } else { + for (bnd = start_sub+1; bnd < end_sub; bnd++) + put_bits(&s->pb, 1, ff_eac3_default_cpl_band_struct[bnd]); + } + } + } + + /* coupling coordinates */ + if (block->cpl_in_use) { + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (block->channel_in_cpl[ch]) { + if (!s->eac3 || block->new_cpl_coords[ch] != 2) + put_bits(&s->pb, 1, block->new_cpl_coords[ch]); + if (block->new_cpl_coords[ch]) { + put_bits(&s->pb, 2, block->cpl_master_exp[ch]); + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]); + put_bits(&s->pb, 4, block->cpl_coord_mant[ch][bnd]); + } + } + } + } + } + + /* stereo rematrixing */ + if (s->channel_mode == AC3_CHMODE_STEREO) { + if (!s->eac3 || blk > 0) + put_bits(&s->pb, 1, block->new_rematrixing_strategy); + if (block->new_rematrixing_strategy) { + /* rematrixing flags */ + for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) + put_bits(&s->pb, 1, block->rematrixing_flags[bnd]); + } + } + + /* exponent strategy */ + if (!s->eac3) { + for (ch = !block->cpl_in_use; ch <= s->fbw_channels; ch++) + put_bits(&s->pb, 2, s->exp_strategy[ch][blk]); + if (s->lfe_on) + put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]); + } + + /* bandwidth */ + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (s->exp_strategy[ch][blk] != EXP_REUSE && !block->channel_in_cpl[ch]) + put_bits(&s->pb, 6, s->bandwidth_code); + } + + /* exponents */ + for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { + int nb_groups; + int cpl = (ch == CPL_CH); + + if (s->exp_strategy[ch][blk] == EXP_REUSE) + continue; + + /* DC exponent */ + put_bits(&s->pb, 4, block->grouped_exp[ch][0] >> cpl); + + /* exponent groups */ + nb_groups = exponent_group_tab[cpl][s->exp_strategy[ch][blk]-1][block->end_freq[ch]-s->start_freq[ch]]; + for (i = 1; i <= nb_groups; i++) + put_bits(&s->pb, 7, block->grouped_exp[ch][i]); + + /* gain range info */ + if (ch != s->lfe_channel && !cpl) + put_bits(&s->pb, 2, 0); + } + + /* bit allocation info */ + if (!s->eac3) { + baie = (blk == 0); + put_bits(&s->pb, 1, baie); + if (baie) { + put_bits(&s->pb, 2, s->slow_decay_code); + put_bits(&s->pb, 2, s->fast_decay_code); + put_bits(&s->pb, 2, s->slow_gain_code); + put_bits(&s->pb, 2, s->db_per_bit_code); + put_bits(&s->pb, 3, s->floor_code); + } + } + + /* snr offset */ + if (!s->eac3) { + put_bits(&s->pb, 1, block->new_snr_offsets); + if (block->new_snr_offsets) { + put_bits(&s->pb, 6, s->coarse_snr_offset); + for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { + put_bits(&s->pb, 4, s->fine_snr_offset[ch]); + put_bits(&s->pb, 3, s->fast_gain_code[ch]); + } + } + } else { + put_bits(&s->pb, 1, 0); /* no converter snr offset */ + } + + /* coupling leak */ + if (block->cpl_in_use) { + if (!s->eac3 || block->new_cpl_leak != 2) + put_bits(&s->pb, 1, block->new_cpl_leak); + if (block->new_cpl_leak) { + put_bits(&s->pb, 3, s->bit_alloc.cpl_fast_leak); + put_bits(&s->pb, 3, s->bit_alloc.cpl_slow_leak); + } + } + + if (!s->eac3) { + put_bits(&s->pb, 1, 0); /* no delta bit allocation */ + put_bits(&s->pb, 1, 0); /* no data to skip */ + } + + /* mantissas */ + got_cpl = !block->cpl_in_use; + for (ch = 1; ch <= s->channels; ch++) { + int b, q; + + if (!got_cpl && ch > 1 && block->channel_in_cpl[ch-1]) { + ch0 = ch - 1; + ch = CPL_CH; + got_cpl = 1; + } + for (i = s->start_freq[ch]; i < block->end_freq[ch]; i++) { + q = block->qmant[ch][i]; + b = s->ref_bap[ch][blk][i]; + switch (b) { + case 0: break; + case 1: if (q != 128) put_bits (&s->pb, 5, q); break; + case 2: if (q != 128) put_bits (&s->pb, 7, q); break; + case 3: put_sbits(&s->pb, 3, q); break; + case 4: if (q != 128) put_bits (&s->pb, 7, q); break; + case 14: put_sbits(&s->pb, 14, q); break; + case 15: put_sbits(&s->pb, 16, q); break; + default: put_sbits(&s->pb, b-1, q); break; + } + } + if (ch == CPL_CH) + ch = ch0; + } +} + + +/** CRC-16 Polynomial */ +#define CRC16_POLY ((1 << 0) | (1 << 2) | (1 << 15) | (1 << 16)) + + +static unsigned int mul_poly(unsigned int a, unsigned int b, unsigned int poly) +{ + unsigned int c; + + c = 0; + while (a) { + if (a & 1) + c ^= b; + a = a >> 1; + b = b << 1; + if (b & (1 << 16)) + b ^= poly; + } + return c; +} + + +static unsigned int pow_poly(unsigned int a, unsigned int n, unsigned int poly) +{ + unsigned int r; + r = 1; + while (n) { + if (n & 1) + r = mul_poly(r, a, poly); + a = mul_poly(a, a, poly); + n >>= 1; + } + return r; +} + + +/* + * Fill the end of the frame with 0's and compute the two CRCs. + */ +static void output_frame_end(AC3EncodeContext *s) +{ + const AVCRC *crc_ctx = av_crc_get_table(AV_CRC_16_ANSI); + int frame_size_58, pad_bytes, crc1, crc2_partial, crc2, crc_inv; + uint8_t *frame; + + frame_size_58 = ((s->frame_size >> 2) + (s->frame_size >> 4)) << 1; + + /* pad the remainder of the frame with zeros */ + av_assert2(s->frame_size * 8 - put_bits_count(&s->pb) >= 18); + flush_put_bits(&s->pb); + frame = s->pb.buf; + pad_bytes = s->frame_size - (put_bits_ptr(&s->pb) - frame) - 2; + av_assert2(pad_bytes >= 0); + if (pad_bytes > 0) + memset(put_bits_ptr(&s->pb), 0, pad_bytes); + + if (s->eac3) { + /* compute crc2 */ + crc2_partial = av_crc(crc_ctx, 0, frame + 2, s->frame_size - 5); + } else { + /* compute crc1 */ + /* this is not so easy because it is at the beginning of the data... */ + crc1 = av_bswap16(av_crc(crc_ctx, 0, frame + 4, frame_size_58 - 4)); + crc_inv = s->crc_inv[s->frame_size > s->frame_size_min]; + crc1 = mul_poly(crc_inv, crc1, CRC16_POLY); + AV_WB16(frame + 2, crc1); + + /* compute crc2 */ + crc2_partial = av_crc(crc_ctx, 0, frame + frame_size_58, + s->frame_size - frame_size_58 - 3); + } + crc2 = av_crc(crc_ctx, crc2_partial, frame + s->frame_size - 3, 1); + /* ensure crc2 does not match sync word by flipping crcrsv bit if needed */ + if (crc2 == 0x770B) { + frame[s->frame_size - 3] ^= 0x1; + crc2 = av_crc(crc_ctx, crc2_partial, frame + s->frame_size - 3, 1); + } + crc2 = av_bswap16(crc2); + AV_WB16(frame + s->frame_size - 2, crc2); +} + + +/** + * Write the frame to the output bitstream. + * + * @param s AC-3 encoder private context + * @param frame output data buffer + */ +void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame) +{ + int blk; + + init_put_bits(&s->pb, frame, AC3_MAX_CODED_FRAME_SIZE); + + s->output_frame_header(s); + + for (blk = 0; blk < s->num_blocks; blk++) + output_audio_block(s, blk); + + output_frame_end(s); +} + + +static void dprint_options(AC3EncodeContext *s) +{ +#ifdef DEBUG + AVCodecContext *avctx = s->avctx; + AC3EncOptions *opt = &s->options; + char strbuf[32]; + + switch (s->bitstream_id) { + case 6: av_strlcpy(strbuf, "AC-3 (alt syntax)", 32); break; + case 8: av_strlcpy(strbuf, "AC-3 (standard)", 32); break; + case 9: av_strlcpy(strbuf, "AC-3 (dnet half-rate)", 32); break; + case 10: av_strlcpy(strbuf, "AC-3 (dnet quater-rate)", 32); break; + case 16: av_strlcpy(strbuf, "E-AC-3 (enhanced)", 32); break; + default: snprintf(strbuf, 32, "ERROR"); + } + ff_dlog(avctx, "bitstream_id: %s (%d)\n", strbuf, s->bitstream_id); + ff_dlog(avctx, "sample_fmt: %s\n", av_get_sample_fmt_name(avctx->sample_fmt)); + av_get_channel_layout_string(strbuf, 32, s->channels, avctx->channel_layout); + ff_dlog(avctx, "channel_layout: %s\n", strbuf); + ff_dlog(avctx, "sample_rate: %d\n", s->sample_rate); + ff_dlog(avctx, "bit_rate: %d\n", s->bit_rate); + ff_dlog(avctx, "blocks/frame: %d (code=%d)\n", s->num_blocks, s->num_blks_code); + if (s->cutoff) + ff_dlog(avctx, "cutoff: %d\n", s->cutoff); + + ff_dlog(avctx, "per_frame_metadata: %s\n", + opt->allow_per_frame_metadata?"on":"off"); + if (s->has_center) + ff_dlog(avctx, "center_mixlev: %0.3f (%d)\n", opt->center_mix_level, + s->center_mix_level); + else + ff_dlog(avctx, "center_mixlev: {not written}\n"); + if (s->has_surround) + ff_dlog(avctx, "surround_mixlev: %0.3f (%d)\n", opt->surround_mix_level, + s->surround_mix_level); + else + ff_dlog(avctx, "surround_mixlev: {not written}\n"); + if (opt->audio_production_info) { + ff_dlog(avctx, "mixing_level: %ddB\n", opt->mixing_level); + switch (opt->room_type) { + case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break; + case AC3ENC_OPT_LARGE_ROOM: av_strlcpy(strbuf, "large", 32); break; + case AC3ENC_OPT_SMALL_ROOM: av_strlcpy(strbuf, "small", 32); break; + default: snprintf(strbuf, 32, "ERROR (%d)", opt->room_type); + } + ff_dlog(avctx, "room_type: %s\n", strbuf); + } else { + ff_dlog(avctx, "mixing_level: {not written}\n"); + ff_dlog(avctx, "room_type: {not written}\n"); + } + ff_dlog(avctx, "copyright: %s\n", opt->copyright?"on":"off"); + ff_dlog(avctx, "dialnorm: %ddB\n", opt->dialogue_level); + if (s->channel_mode == AC3_CHMODE_STEREO) { + switch (opt->dolby_surround_mode) { + case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break; + case AC3ENC_OPT_MODE_ON: av_strlcpy(strbuf, "on", 32); break; + case AC3ENC_OPT_MODE_OFF: av_strlcpy(strbuf, "off", 32); break; + default: snprintf(strbuf, 32, "ERROR (%d)", opt->dolby_surround_mode); + } + ff_dlog(avctx, "dsur_mode: %s\n", strbuf); + } else { + ff_dlog(avctx, "dsur_mode: {not written}\n"); + } + ff_dlog(avctx, "original: %s\n", opt->original?"on":"off"); + + if (s->bitstream_id == 6) { + if (opt->extended_bsi_1) { + switch (opt->preferred_stereo_downmix) { + case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break; + case AC3ENC_OPT_DOWNMIX_LTRT: av_strlcpy(strbuf, "ltrt", 32); break; + case AC3ENC_OPT_DOWNMIX_LORO: av_strlcpy(strbuf, "loro", 32); break; + default: snprintf(strbuf, 32, "ERROR (%d)", opt->preferred_stereo_downmix); + } + ff_dlog(avctx, "dmix_mode: %s\n", strbuf); + ff_dlog(avctx, "ltrt_cmixlev: %0.3f (%d)\n", + opt->ltrt_center_mix_level, s->ltrt_center_mix_level); + ff_dlog(avctx, "ltrt_surmixlev: %0.3f (%d)\n", + opt->ltrt_surround_mix_level, s->ltrt_surround_mix_level); + ff_dlog(avctx, "loro_cmixlev: %0.3f (%d)\n", + opt->loro_center_mix_level, s->loro_center_mix_level); + ff_dlog(avctx, "loro_surmixlev: %0.3f (%d)\n", + opt->loro_surround_mix_level, s->loro_surround_mix_level); + } else { + ff_dlog(avctx, "extended bitstream info 1: {not written}\n"); + } + if (opt->extended_bsi_2) { + switch (opt->dolby_surround_ex_mode) { + case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break; + case AC3ENC_OPT_MODE_ON: av_strlcpy(strbuf, "on", 32); break; + case AC3ENC_OPT_MODE_OFF: av_strlcpy(strbuf, "off", 32); break; + default: snprintf(strbuf, 32, "ERROR (%d)", opt->dolby_surround_ex_mode); + } + ff_dlog(avctx, "dsurex_mode: %s\n", strbuf); + switch (opt->dolby_headphone_mode) { + case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break; + case AC3ENC_OPT_MODE_ON: av_strlcpy(strbuf, "on", 32); break; + case AC3ENC_OPT_MODE_OFF: av_strlcpy(strbuf, "off", 32); break; + default: snprintf(strbuf, 32, "ERROR (%d)", opt->dolby_headphone_mode); + } + ff_dlog(avctx, "dheadphone_mode: %s\n", strbuf); + + switch (opt->ad_converter_type) { + case AC3ENC_OPT_ADCONV_STANDARD: av_strlcpy(strbuf, "standard", 32); break; + case AC3ENC_OPT_ADCONV_HDCD: av_strlcpy(strbuf, "hdcd", 32); break; + default: snprintf(strbuf, 32, "ERROR (%d)", opt->ad_converter_type); + } + ff_dlog(avctx, "ad_conv_type: %s\n", strbuf); + } else { + ff_dlog(avctx, "extended bitstream info 2: {not written}\n"); + } + } +#endif +} + + +#define FLT_OPTION_THRESHOLD 0.01 + +static int validate_float_option(float v, const float *v_list, int v_list_size) +{ + int i; + + for (i = 0; i < v_list_size; i++) { + if (v < (v_list[i] + FLT_OPTION_THRESHOLD) && + v > (v_list[i] - FLT_OPTION_THRESHOLD)) + break; + } + if (i == v_list_size) + return AVERROR(EINVAL); + + return i; +} + + +static void validate_mix_level(void *log_ctx, const char *opt_name, + float *opt_param, const float *list, + int list_size, int default_value, int min_value, + int *ctx_param) +{ + int mixlev = validate_float_option(*opt_param, list, list_size); + if (mixlev < min_value) { + mixlev = default_value; + if (*opt_param >= 0.0) { + av_log(log_ctx, AV_LOG_WARNING, "requested %s is not valid. using " + "default value: %0.3f\n", opt_name, list[mixlev]); + } + } + *opt_param = list[mixlev]; + *ctx_param = mixlev; +} + + +/** + * Validate metadata options as set by AVOption system. + * These values can optionally be changed per-frame. + * + * @param s AC-3 encoder private context + */ +int ff_ac3_validate_metadata(AC3EncodeContext *s) +{ + AVCodecContext *avctx = s->avctx; + AC3EncOptions *opt = &s->options; + + opt->audio_production_info = 0; + opt->extended_bsi_1 = 0; + opt->extended_bsi_2 = 0; + opt->eac3_mixing_metadata = 0; + opt->eac3_info_metadata = 0; + + /* determine mixing metadata / xbsi1 use */ + if (s->channel_mode > AC3_CHMODE_STEREO && opt->preferred_stereo_downmix != AC3ENC_OPT_NONE) { + opt->extended_bsi_1 = 1; + opt->eac3_mixing_metadata = 1; + } + if (s->has_center && + (opt->ltrt_center_mix_level >= 0 || opt->loro_center_mix_level >= 0)) { + opt->extended_bsi_1 = 1; + opt->eac3_mixing_metadata = 1; + } + if (s->has_surround && + (opt->ltrt_surround_mix_level >= 0 || opt->loro_surround_mix_level >= 0)) { + opt->extended_bsi_1 = 1; + opt->eac3_mixing_metadata = 1; + } + + if (s->eac3) { + /* determine info metadata use */ + if (avctx->audio_service_type != AV_AUDIO_SERVICE_TYPE_MAIN) + opt->eac3_info_metadata = 1; + if (opt->copyright != AC3ENC_OPT_NONE || opt->original != AC3ENC_OPT_NONE) + opt->eac3_info_metadata = 1; + if (s->channel_mode == AC3_CHMODE_STEREO && + (opt->dolby_headphone_mode != AC3ENC_OPT_NONE || opt->dolby_surround_mode != AC3ENC_OPT_NONE)) + opt->eac3_info_metadata = 1; + if (s->channel_mode >= AC3_CHMODE_2F2R && opt->dolby_surround_ex_mode != AC3ENC_OPT_NONE) + opt->eac3_info_metadata = 1; + if (opt->mixing_level != AC3ENC_OPT_NONE || opt->room_type != AC3ENC_OPT_NONE || + opt->ad_converter_type != AC3ENC_OPT_NONE) { + opt->audio_production_info = 1; + opt->eac3_info_metadata = 1; + } + } else { + /* determine audio production info use */ + if (opt->mixing_level != AC3ENC_OPT_NONE || opt->room_type != AC3ENC_OPT_NONE) + opt->audio_production_info = 1; + + /* determine xbsi2 use */ + if (s->channel_mode >= AC3_CHMODE_2F2R && opt->dolby_surround_ex_mode != AC3ENC_OPT_NONE) + opt->extended_bsi_2 = 1; + if (s->channel_mode == AC3_CHMODE_STEREO && opt->dolby_headphone_mode != AC3ENC_OPT_NONE) + opt->extended_bsi_2 = 1; + if (opt->ad_converter_type != AC3ENC_OPT_NONE) + opt->extended_bsi_2 = 1; + } + + /* validate AC-3 mixing levels */ + if (!s->eac3) { + if (s->has_center) { + validate_mix_level(avctx, "center_mix_level", &opt->center_mix_level, + cmixlev_options, CMIXLEV_NUM_OPTIONS, 1, 0, + &s->center_mix_level); + } + if (s->has_surround) { + validate_mix_level(avctx, "surround_mix_level", &opt->surround_mix_level, + surmixlev_options, SURMIXLEV_NUM_OPTIONS, 1, 0, + &s->surround_mix_level); + } + } + + /* validate extended bsi 1 / mixing metadata */ + if (opt->extended_bsi_1 || opt->eac3_mixing_metadata) { + /* default preferred stereo downmix */ + if (opt->preferred_stereo_downmix == AC3ENC_OPT_NONE) + opt->preferred_stereo_downmix = AC3ENC_OPT_NOT_INDICATED; + if (!s->eac3 || s->has_center) { + /* validate Lt/Rt center mix level */ + validate_mix_level(avctx, "ltrt_center_mix_level", + &opt->ltrt_center_mix_level, extmixlev_options, + EXTMIXLEV_NUM_OPTIONS, 5, 0, + &s->ltrt_center_mix_level); + /* validate Lo/Ro center mix level */ + validate_mix_level(avctx, "loro_center_mix_level", + &opt->loro_center_mix_level, extmixlev_options, + EXTMIXLEV_NUM_OPTIONS, 5, 0, + &s->loro_center_mix_level); + } + if (!s->eac3 || s->has_surround) { + /* validate Lt/Rt surround mix level */ + validate_mix_level(avctx, "ltrt_surround_mix_level", + &opt->ltrt_surround_mix_level, extmixlev_options, + EXTMIXLEV_NUM_OPTIONS, 6, 3, + &s->ltrt_surround_mix_level); + /* validate Lo/Ro surround mix level */ + validate_mix_level(avctx, "loro_surround_mix_level", + &opt->loro_surround_mix_level, extmixlev_options, + EXTMIXLEV_NUM_OPTIONS, 6, 3, + &s->loro_surround_mix_level); + } + } + + /* validate audio service type / channels combination */ + if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE && + avctx->channels == 1) || + ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY || + avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY || + avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER) + && avctx->channels > 1)) { + av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the " + "specified number of channels\n"); + return AVERROR(EINVAL); + } + + /* validate extended bsi 2 / info metadata */ + if (opt->extended_bsi_2 || opt->eac3_info_metadata) { + /* default dolby headphone mode */ + if (opt->dolby_headphone_mode == AC3ENC_OPT_NONE) + opt->dolby_headphone_mode = AC3ENC_OPT_NOT_INDICATED; + /* default dolby surround ex mode */ + if (opt->dolby_surround_ex_mode == AC3ENC_OPT_NONE) + opt->dolby_surround_ex_mode = AC3ENC_OPT_NOT_INDICATED; + /* default A/D converter type */ + if (opt->ad_converter_type == AC3ENC_OPT_NONE) + opt->ad_converter_type = AC3ENC_OPT_ADCONV_STANDARD; + } + + /* copyright & original defaults */ + if (!s->eac3 || opt->eac3_info_metadata) { + /* default copyright */ + if (opt->copyright == AC3ENC_OPT_NONE) + opt->copyright = AC3ENC_OPT_OFF; + /* default original */ + if (opt->original == AC3ENC_OPT_NONE) + opt->original = AC3ENC_OPT_ON; + } + + /* dolby surround mode default */ + if (!s->eac3 || opt->eac3_info_metadata) { + if (opt->dolby_surround_mode == AC3ENC_OPT_NONE) + opt->dolby_surround_mode = AC3ENC_OPT_NOT_INDICATED; + } + + /* validate audio production info */ + if (opt->audio_production_info) { + if (opt->mixing_level == AC3ENC_OPT_NONE) { + av_log(avctx, AV_LOG_ERROR, "mixing_level must be set if " + "room_type is set\n"); + return AVERROR(EINVAL); + } + if (opt->mixing_level < 80) { + av_log(avctx, AV_LOG_ERROR, "invalid mixing level. must be between " + "80dB and 111dB\n"); + return AVERROR(EINVAL); + } + /* default room type */ + if (opt->room_type == AC3ENC_OPT_NONE) + opt->room_type = AC3ENC_OPT_NOT_INDICATED; + } + + /* set bitstream id for alternate bitstream syntax */ + if (!s->eac3 && (opt->extended_bsi_1 || opt->extended_bsi_2)) { + if (s->bitstream_id > 8 && s->bitstream_id < 11) { + static int warn_once = 1; + if (warn_once) { + av_log(avctx, AV_LOG_WARNING, "alternate bitstream syntax is " + "not compatible with reduced samplerates. writing of " + "extended bitstream information will be disabled.\n"); + warn_once = 0; + } + } else { + s->bitstream_id = 6; + } + } + + return 0; +} + + +/** + * Finalize encoding and free any memory allocated by the encoder. + * + * @param avctx Codec context + */ +av_cold int ff_ac3_encode_close(AVCodecContext *avctx) +{ + int blk, ch; + AC3EncodeContext *s = avctx->priv_data; + + av_freep(&s->windowed_samples); + if (s->planar_samples) + for (ch = 0; ch < s->channels; ch++) + av_freep(&s->planar_samples[ch]); + av_freep(&s->planar_samples); + av_freep(&s->bap_buffer); + av_freep(&s->bap1_buffer); + av_freep(&s->mdct_coef_buffer); + av_freep(&s->fixed_coef_buffer); + av_freep(&s->exp_buffer); + av_freep(&s->grouped_exp_buffer); + av_freep(&s->psd_buffer); + av_freep(&s->band_psd_buffer); + av_freep(&s->mask_buffer); + av_freep(&s->qmant_buffer); + av_freep(&s->cpl_coord_exp_buffer); + av_freep(&s->cpl_coord_mant_buffer); + av_freep(&s->fdsp); + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + av_freep(&block->mdct_coef); + av_freep(&block->fixed_coef); + av_freep(&block->exp); + av_freep(&block->grouped_exp); + av_freep(&block->psd); + av_freep(&block->band_psd); + av_freep(&block->mask); + av_freep(&block->qmant); + av_freep(&block->cpl_coord_exp); + av_freep(&block->cpl_coord_mant); + } + + s->mdct_end(s); + + return 0; +} + + +/* + * Set channel information during initialization. + */ +static av_cold int set_channel_info(AC3EncodeContext *s, int channels, + uint64_t *channel_layout) +{ + int ch_layout; + + if (channels < 1 || channels > AC3_MAX_CHANNELS) + return AVERROR(EINVAL); + if (*channel_layout > 0x7FF) + return AVERROR(EINVAL); + ch_layout = *channel_layout; + if (!ch_layout) + ch_layout = av_get_default_channel_layout(channels); + + s->lfe_on = !!(ch_layout & AV_CH_LOW_FREQUENCY); + s->channels = channels; + s->fbw_channels = channels - s->lfe_on; + s->lfe_channel = s->lfe_on ? s->fbw_channels + 1 : -1; + if (s->lfe_on) + ch_layout -= AV_CH_LOW_FREQUENCY; + + switch (ch_layout) { + case AV_CH_LAYOUT_MONO: s->channel_mode = AC3_CHMODE_MONO; break; + case AV_CH_LAYOUT_STEREO: s->channel_mode = AC3_CHMODE_STEREO; break; + case AV_CH_LAYOUT_SURROUND: s->channel_mode = AC3_CHMODE_3F; break; + case AV_CH_LAYOUT_2_1: s->channel_mode = AC3_CHMODE_2F1R; break; + case AV_CH_LAYOUT_4POINT0: s->channel_mode = AC3_CHMODE_3F1R; break; + case AV_CH_LAYOUT_QUAD: + case AV_CH_LAYOUT_2_2: s->channel_mode = AC3_CHMODE_2F2R; break; + case AV_CH_LAYOUT_5POINT0: + case AV_CH_LAYOUT_5POINT0_BACK: s->channel_mode = AC3_CHMODE_3F2R; break; + default: + return AVERROR(EINVAL); + } + s->has_center = (s->channel_mode & 0x01) && s->channel_mode != AC3_CHMODE_MONO; + s->has_surround = s->channel_mode & 0x04; + + s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe_on]; + *channel_layout = ch_layout; + if (s->lfe_on) + *channel_layout |= AV_CH_LOW_FREQUENCY; + + return 0; +} + + +static av_cold int validate_options(AC3EncodeContext *s) +{ + AVCodecContext *avctx = s->avctx; + int i, ret, max_sr; + + /* validate channel layout */ + if (!avctx->channel_layout) { + av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The " + "encoder will guess the layout, but it " + "might be incorrect.\n"); + } + ret = set_channel_info(s, avctx->channels, &avctx->channel_layout); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "invalid channel layout\n"); + return ret; + } + + /* validate sample rate */ + /* note: max_sr could be changed from 2 to 5 for E-AC-3 once we find a + decoder that supports half sample rate so we can validate that + the generated files are correct. */ + max_sr = s->eac3 ? 2 : 8; + for (i = 0; i <= max_sr; i++) { + if ((ff_ac3_sample_rate_tab[i % 3] >> (i / 3)) == avctx->sample_rate) + break; + } + if (i > max_sr) { + av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n"); + return AVERROR(EINVAL); + } + s->sample_rate = avctx->sample_rate; + s->bit_alloc.sr_shift = i / 3; + s->bit_alloc.sr_code = i % 3; + s->bitstream_id = s->eac3 ? 16 : 8 + s->bit_alloc.sr_shift; + + /* select a default bit rate if not set by the user */ + if (!avctx->bit_rate) { + switch (s->fbw_channels) { + case 1: avctx->bit_rate = 96000; break; + case 2: avctx->bit_rate = 192000; break; + case 3: avctx->bit_rate = 320000; break; + case 4: avctx->bit_rate = 384000; break; + case 5: avctx->bit_rate = 448000; break; + } + } + + /* validate bit rate */ + if (s->eac3) { + int max_br, min_br, wpf, min_br_code; + int num_blks_code, num_blocks, frame_samples; + long long min_br_dist; + + /* calculate min/max bitrate */ + /* TODO: More testing with 3 and 2 blocks. All E-AC-3 samples I've + found use either 6 blocks or 1 block, even though 2 or 3 blocks + would work as far as the bit rate is concerned. */ + for (num_blks_code = 3; num_blks_code >= 0; num_blks_code--) { + num_blocks = ((int[]){ 1, 2, 3, 6 })[num_blks_code]; + frame_samples = AC3_BLOCK_SIZE * num_blocks; + max_br = 2048 * s->sample_rate / frame_samples * 16; + min_br = ((s->sample_rate + (frame_samples-1)) / frame_samples) * 16; + if (avctx->bit_rate <= max_br) + break; + } + if (avctx->bit_rate < min_br || avctx->bit_rate > max_br) { + av_log(avctx, AV_LOG_ERROR, "invalid bit rate. must be %d to %d " + "for this sample rate\n", min_br, max_br); + return AVERROR(EINVAL); + } + s->num_blks_code = num_blks_code; + s->num_blocks = num_blocks; + + /* calculate words-per-frame for the selected bitrate */ + wpf = (avctx->bit_rate / 16) * frame_samples / s->sample_rate; + av_assert1(wpf > 0 && wpf <= 2048); + + /* find the closest AC-3 bitrate code to the selected bitrate. + this is needed for lookup tables for bandwidth and coupling + parameter selection */ + min_br_code = -1; + min_br_dist = INT64_MAX; + for (i = 0; i < 19; i++) { + long long br_dist = llabs(ff_ac3_bitrate_tab[i] * 1000 - avctx->bit_rate); + if (br_dist < min_br_dist) { + min_br_dist = br_dist; + min_br_code = i; + } + } + + /* make sure the minimum frame size is below the average frame size */ + s->frame_size_code = min_br_code << 1; + while (wpf > 1 && wpf * s->sample_rate / AC3_FRAME_SIZE * 16 > avctx->bit_rate) + wpf--; + s->frame_size_min = 2 * wpf; + } else { + int best_br = 0, best_code = 0; + long long best_diff = INT64_MAX; + for (i = 0; i < 19; i++) { + int br = (ff_ac3_bitrate_tab[i] >> s->bit_alloc.sr_shift) * 1000; + long long diff = llabs(br - avctx->bit_rate); + if (diff < best_diff) { + best_br = br; + best_code = i; + best_diff = diff; + } + if (!best_diff) + break; + } + avctx->bit_rate = best_br; + s->frame_size_code = best_code << 1; + s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code]; + s->num_blks_code = 0x3; + s->num_blocks = 6; + } + s->bit_rate = avctx->bit_rate; + s->frame_size = s->frame_size_min; + + /* validate cutoff */ + if (avctx->cutoff < 0) { + av_log(avctx, AV_LOG_ERROR, "invalid cutoff frequency\n"); + return AVERROR(EINVAL); + } + s->cutoff = avctx->cutoff; + if (s->cutoff > (s->sample_rate >> 1)) + s->cutoff = s->sample_rate >> 1; + + ret = ff_ac3_validate_metadata(s); + if (ret) + return ret; + + s->rematrixing_enabled = s->options.stereo_rematrixing && + (s->channel_mode == AC3_CHMODE_STEREO); + + s->cpl_enabled = s->options.channel_coupling && + s->channel_mode >= AC3_CHMODE_STEREO; + + return 0; +} + + +/* + * Set bandwidth for all channels. + * The user can optionally supply a cutoff frequency. Otherwise an appropriate + * default value will be used. + */ +static av_cold void set_bandwidth(AC3EncodeContext *s) +{ + int blk, ch, av_uninit(cpl_start); + + if (s->cutoff) { + /* calculate bandwidth based on user-specified cutoff frequency */ + int fbw_coeffs; + fbw_coeffs = s->cutoff * 2 * AC3_MAX_COEFS / s->sample_rate; + s->bandwidth_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); + } else { + /* use default bandwidth setting */ + s->bandwidth_code = ac3_bandwidth_tab[s->fbw_channels-1][s->bit_alloc.sr_code][s->frame_size_code/2]; + } + + /* set number of coefficients for each channel */ + for (ch = 1; ch <= s->fbw_channels; ch++) { + s->start_freq[ch] = 0; + for (blk = 0; blk < s->num_blocks; blk++) + s->blocks[blk].end_freq[ch] = s->bandwidth_code * 3 + 73; + } + /* LFE channel always has 7 coefs */ + if (s->lfe_on) { + s->start_freq[s->lfe_channel] = 0; + for (blk = 0; blk < s->num_blocks; blk++) + s->blocks[blk].end_freq[ch] = 7; + } + + /* initialize coupling strategy */ + if (s->cpl_enabled) { + if (s->options.cpl_start != AC3ENC_OPT_AUTO) { + cpl_start = s->options.cpl_start; + } else { + cpl_start = ac3_coupling_start_tab[s->channel_mode-2][s->bit_alloc.sr_code][s->frame_size_code/2]; + if (cpl_start < 0) { + if (s->options.channel_coupling == AC3ENC_OPT_AUTO) + s->cpl_enabled = 0; + else + cpl_start = 15; + } + } + } + if (s->cpl_enabled) { + int i, cpl_start_band, cpl_end_band; + uint8_t *cpl_band_sizes = s->cpl_band_sizes; + + cpl_end_band = s->bandwidth_code / 4 + 3; + cpl_start_band = av_clip(cpl_start, 0, FFMIN(cpl_end_band-1, 15)); + + s->num_cpl_subbands = cpl_end_band - cpl_start_band; + + s->num_cpl_bands = 1; + *cpl_band_sizes = 12; + for (i = cpl_start_band + 1; i < cpl_end_band; i++) { + if (ff_eac3_default_cpl_band_struct[i]) { + *cpl_band_sizes += 12; + } else { + s->num_cpl_bands++; + cpl_band_sizes++; + *cpl_band_sizes = 12; + } + } + + s->start_freq[CPL_CH] = cpl_start_band * 12 + 37; + s->cpl_end_freq = cpl_end_band * 12 + 37; + for (blk = 0; blk < s->num_blocks; blk++) + s->blocks[blk].end_freq[CPL_CH] = s->cpl_end_freq; + } +} + + +static av_cold int allocate_buffers(AC3EncodeContext *s) +{ + AVCodecContext *avctx = s->avctx; + int blk, ch; + int channels = s->channels + 1; /* includes coupling channel */ + int channel_blocks = channels * s->num_blocks; + int total_coefs = AC3_MAX_COEFS * channel_blocks; + + if (s->allocate_sample_buffers(s)) + goto alloc_fail; + + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->bap_buffer, total_coefs, + sizeof(*s->bap_buffer), alloc_fail); + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->bap1_buffer, total_coefs, + sizeof(*s->bap1_buffer), alloc_fail); + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->mdct_coef_buffer, total_coefs, + sizeof(*s->mdct_coef_buffer), alloc_fail); + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->exp_buffer, total_coefs, + sizeof(*s->exp_buffer), alloc_fail); + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->grouped_exp_buffer, channel_blocks, 128 * + sizeof(*s->grouped_exp_buffer), alloc_fail); + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->psd_buffer, total_coefs, + sizeof(*s->psd_buffer), alloc_fail); + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->band_psd_buffer, channel_blocks, 64 * + sizeof(*s->band_psd_buffer), alloc_fail); + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->mask_buffer, channel_blocks, 64 * + sizeof(*s->mask_buffer), alloc_fail); + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->qmant_buffer, total_coefs, + sizeof(*s->qmant_buffer), alloc_fail); + if (s->cpl_enabled) { + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->cpl_coord_exp_buffer, channel_blocks, 16 * + sizeof(*s->cpl_coord_exp_buffer), alloc_fail); + FF_ALLOC_ARRAY_OR_GOTO(avctx, s->cpl_coord_mant_buffer, channel_blocks, 16 * + sizeof(*s->cpl_coord_mant_buffer), alloc_fail); + } + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->mdct_coef, channels, sizeof(*block->mdct_coef), + alloc_fail); + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->exp, channels, sizeof(*block->exp), + alloc_fail); + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->grouped_exp, channels, sizeof(*block->grouped_exp), + alloc_fail); + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->psd, channels, sizeof(*block->psd), + alloc_fail); + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->band_psd, channels, sizeof(*block->band_psd), + alloc_fail); + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->mask, channels, sizeof(*block->mask), + alloc_fail); + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->qmant, channels, sizeof(*block->qmant), + alloc_fail); + if (s->cpl_enabled) { + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->cpl_coord_exp, channels, sizeof(*block->cpl_coord_exp), + alloc_fail); + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->cpl_coord_mant, channels, sizeof(*block->cpl_coord_mant), + alloc_fail); + } + + for (ch = 0; ch < channels; ch++) { + /* arrangement: block, channel, coeff */ + block->grouped_exp[ch] = &s->grouped_exp_buffer[128 * (blk * channels + ch)]; + block->psd[ch] = &s->psd_buffer [AC3_MAX_COEFS * (blk * channels + ch)]; + block->band_psd[ch] = &s->band_psd_buffer [64 * (blk * channels + ch)]; + block->mask[ch] = &s->mask_buffer [64 * (blk * channels + ch)]; + block->qmant[ch] = &s->qmant_buffer [AC3_MAX_COEFS * (blk * channels + ch)]; + if (s->cpl_enabled) { + block->cpl_coord_exp[ch] = &s->cpl_coord_exp_buffer [16 * (blk * channels + ch)]; + block->cpl_coord_mant[ch] = &s->cpl_coord_mant_buffer[16 * (blk * channels + ch)]; + } + + /* arrangement: channel, block, coeff */ + block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (s->num_blocks * ch + blk)]; + block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (s->num_blocks * ch + blk)]; + } + } + + if (!s->fixed_point) { + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->fixed_coef_buffer, total_coefs, + sizeof(*s->fixed_coef_buffer), alloc_fail); + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->fixed_coef, channels, + sizeof(*block->fixed_coef), alloc_fail); + for (ch = 0; ch < channels; ch++) + block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (s->num_blocks * ch + blk)]; + } + } else { + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->fixed_coef, channels, + sizeof(*block->fixed_coef), alloc_fail); + for (ch = 0; ch < channels; ch++) + block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch]; + } + } + + return 0; +alloc_fail: + return AVERROR(ENOMEM); +} + + +av_cold int ff_ac3_encode_init(AVCodecContext *avctx) +{ + AC3EncodeContext *s = avctx->priv_data; + int ret, frame_size_58; + + s->avctx = avctx; + + s->eac3 = avctx->codec_id == AV_CODEC_ID_EAC3; + + ret = validate_options(s); + if (ret) + return ret; + + avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks; + avctx->initial_padding = AC3_BLOCK_SIZE; + + s->bitstream_mode = avctx->audio_service_type; + if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE) + s->bitstream_mode = 0x7; + + s->bits_written = 0; + s->samples_written = 0; + + /* calculate crc_inv for both possible frame sizes */ + frame_size_58 = (( s->frame_size >> 2) + ( s->frame_size >> 4)) << 1; + s->crc_inv[0] = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY); + if (s->bit_alloc.sr_code == 1) { + frame_size_58 = (((s->frame_size+2) >> 2) + ((s->frame_size+2) >> 4)) << 1; + s->crc_inv[1] = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY); + } + + /* set function pointers */ + if (CONFIG_AC3_FIXED_ENCODER && s->fixed_point) { + s->mdct_end = ff_ac3_fixed_mdct_end; + s->mdct_init = ff_ac3_fixed_mdct_init; + s->allocate_sample_buffers = ff_ac3_fixed_allocate_sample_buffers; + } else if (CONFIG_AC3_ENCODER || CONFIG_EAC3_ENCODER) { + s->mdct_end = ff_ac3_float_mdct_end; + s->mdct_init = ff_ac3_float_mdct_init; + s->allocate_sample_buffers = ff_ac3_float_allocate_sample_buffers; + } + if (CONFIG_EAC3_ENCODER && s->eac3) + s->output_frame_header = ff_eac3_output_frame_header; + else + s->output_frame_header = ac3_output_frame_header; + + set_bandwidth(s); + + exponent_init(s); + + bit_alloc_init(s); + + ret = s->mdct_init(s); + if (ret) + goto init_fail; + + ret = allocate_buffers(s); + if (ret) + goto init_fail; + + ff_audiodsp_init(&s->adsp); + ff_me_cmp_init(&s->mecc, avctx); + ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT); + + dprint_options(s); + + return 0; +init_fail: + ff_ac3_encode_close(avctx); + return ret; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc.h new file mode 100644 index 000000000..a2442d0e5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc.h @@ -0,0 +1,315 @@ +/* + * AC-3 encoder & E-AC-3 encoder common header + * Copyright (c) 2000 Fabrice Bellard + * Copyright (c) 2006-2010 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AC-3 encoder & E-AC-3 encoder common header + */ + +#ifndef AVCODEC_AC3ENC_H +#define AVCODEC_AC3ENC_H + +#include + +#include "libavutil/float_dsp.h" + +#include "ac3.h" +#include "ac3dsp.h" +#include "avcodec.h" +#include "fft.h" +#include "mathops.h" +#include "me_cmp.h" +#include "put_bits.h" +#include "audiodsp.h" + +#ifndef CONFIG_AC3ENC_FLOAT +#define CONFIG_AC3ENC_FLOAT 0 +#endif + +#define OFFSET(param) offsetof(AC3EncodeContext, options.param) +#define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) + +#define AC3ENC_TYPE_AC3_FIXED 0 +#define AC3ENC_TYPE_AC3 1 +#define AC3ENC_TYPE_EAC3 2 + +#if CONFIG_AC3ENC_FLOAT +#define AC3_NAME(x) ff_ac3_float_ ## x +#define MAC_COEF(d,a,b) ((d)+=(a)*(b)) +#define COEF_MIN (-16777215.0/16777216.0) +#define COEF_MAX ( 16777215.0/16777216.0) +#define NEW_CPL_COORD_THRESHOLD 0.03 +typedef float SampleType; +typedef float CoefType; +typedef float CoefSumType; +#else +#define AC3_NAME(x) ff_ac3_fixed_ ## x +#define MAC_COEF(d,a,b) MAC64(d,a,b) +#define COEF_MIN -16777215 +#define COEF_MAX 16777215 +#define NEW_CPL_COORD_THRESHOLD 503317 +typedef int16_t SampleType; +typedef int32_t CoefType; +typedef int64_t CoefSumType; +#endif + +/* common option values */ +#define AC3ENC_OPT_NONE -1 +#define AC3ENC_OPT_AUTO -1 +#define AC3ENC_OPT_OFF 0 +#define AC3ENC_OPT_ON 1 +#define AC3ENC_OPT_NOT_INDICATED 0 +#define AC3ENC_OPT_MODE_ON 2 +#define AC3ENC_OPT_MODE_OFF 1 +#define AC3ENC_OPT_DSUREX_DPLIIZ 3 + +/* specific option values */ +#define AC3ENC_OPT_LARGE_ROOM 1 +#define AC3ENC_OPT_SMALL_ROOM 2 +#define AC3ENC_OPT_DOWNMIX_LTRT 1 +#define AC3ENC_OPT_DOWNMIX_LORO 2 +#define AC3ENC_OPT_DOWNMIX_DPLII 3 // reserved value in A/52, but used by encoders to indicate DPL2 +#define AC3ENC_OPT_ADCONV_STANDARD 0 +#define AC3ENC_OPT_ADCONV_HDCD 1 + + +/** + * Encoding Options used by AVOption. + */ +typedef struct AC3EncOptions { + /* AC-3 metadata options*/ + int dialogue_level; + int bitstream_mode; + float center_mix_level; + float surround_mix_level; + int dolby_surround_mode; + int audio_production_info; + int mixing_level; + int room_type; + int copyright; + int original; + int extended_bsi_1; + int preferred_stereo_downmix; + float ltrt_center_mix_level; + float ltrt_surround_mix_level; + float loro_center_mix_level; + float loro_surround_mix_level; + int extended_bsi_2; + int dolby_surround_ex_mode; + int dolby_headphone_mode; + int ad_converter_type; + int eac3_mixing_metadata; + int eac3_info_metadata; + + /* other encoding options */ + int allow_per_frame_metadata; + int stereo_rematrixing; + int channel_coupling; + int cpl_start; +} AC3EncOptions; + +/** + * Data for a single audio block. + */ +typedef struct AC3Block { + CoefType **mdct_coef; ///< MDCT coefficients + int32_t **fixed_coef; ///< fixed-point MDCT coefficients + uint8_t **exp; ///< original exponents + uint8_t **grouped_exp; ///< grouped exponents + int16_t **psd; ///< psd per frequency bin + int16_t **band_psd; ///< psd per critical band + int16_t **mask; ///< masking curve + uint16_t **qmant; ///< quantized mantissas + uint8_t **cpl_coord_exp; ///< coupling coord exponents (cplcoexp) + uint8_t **cpl_coord_mant; ///< coupling coord mantissas (cplcomant) + uint8_t coeff_shift[AC3_MAX_CHANNELS]; ///< fixed-point coefficient shift values + uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block + int num_rematrixing_bands; ///< number of rematrixing bands + uint8_t rematrixing_flags[4]; ///< rematrixing flags + int new_cpl_strategy; ///< send new coupling strategy + int cpl_in_use; ///< coupling in use for this block (cplinu) + uint8_t channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl) + int num_cpl_channels; ///< number of channels in coupling + uint8_t new_cpl_coords[AC3_MAX_CHANNELS]; ///< send new coupling coordinates (cplcoe) + uint8_t cpl_master_exp[AC3_MAX_CHANNELS]; ///< coupling coord master exponents (mstrcplco) + int new_snr_offsets; ///< send new SNR offsets + int new_cpl_leak; ///< send new coupling leak info + int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin (endmant) +} AC3Block; + +/** + * AC-3 encoder private context. + */ +typedef struct AC3EncodeContext { + AVClass *av_class; ///< AVClass used for AVOption + AC3EncOptions options; ///< encoding options + AVCodecContext *avctx; ///< parent AVCodecContext + PutBitContext pb; ///< bitstream writer context + AudioDSPContext adsp; + AVFloatDSPContext *fdsp; + MECmpContext mecc; + AC3DSPContext ac3dsp; ///< AC-3 optimized functions + FFTContext mdct; ///< FFT context for MDCT calculation + const SampleType *mdct_window; ///< MDCT window function array + + AC3Block blocks[AC3_MAX_BLOCKS]; ///< per-block info + + int fixed_point; ///< indicates if fixed-point encoder is being used + int eac3; ///< indicates if this is E-AC-3 vs. AC-3 + int bitstream_id; ///< bitstream id (bsid) + int bitstream_mode; ///< bitstream mode (bsmod) + + int bit_rate; ///< target bit rate, in bits-per-second + int sample_rate; ///< sampling frequency, in Hz + + int num_blks_code; ///< number of blocks code (numblkscod) + int num_blocks; ///< number of blocks per frame + int frame_size_min; ///< minimum frame size in case rounding is necessary + int frame_size; ///< current frame size in bytes + int frame_size_code; ///< frame size code (frmsizecod) + uint16_t crc_inv[2]; + int64_t bits_written; ///< bit count (used to avg. bitrate) + int64_t samples_written; ///< sample count (used to avg. bitrate) + + int fbw_channels; ///< number of full-bandwidth channels (nfchans) + int channels; ///< total number of channels (nchans) + int lfe_on; ///< indicates if there is an LFE channel (lfeon) + int lfe_channel; ///< channel index of the LFE channel + int has_center; ///< indicates if there is a center channel + int has_surround; ///< indicates if there are one or more surround channels + int channel_mode; ///< channel mode (acmod) + const uint8_t *channel_map; ///< channel map used to reorder channels + + int center_mix_level; ///< center mix level code + int surround_mix_level; ///< surround mix level code + int ltrt_center_mix_level; ///< Lt/Rt center mix level code + int ltrt_surround_mix_level; ///< Lt/Rt surround mix level code + int loro_center_mix_level; ///< Lo/Ro center mix level code + int loro_surround_mix_level; ///< Lo/Ro surround mix level code + + int cutoff; ///< user-specified cutoff frequency, in Hz + int bandwidth_code; ///< bandwidth code (0 to 60) (chbwcod) + int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin (strtmant) + int cpl_end_freq; ///< coupling channel end frequency bin + + int cpl_on; ///< coupling turned on for this frame + int cpl_enabled; ///< coupling enabled for all frames + int num_cpl_subbands; ///< number of coupling subbands (ncplsubnd) + int num_cpl_bands; ///< number of coupling bands (ncplbnd) + uint8_t cpl_band_sizes[AC3_MAX_CPL_BANDS]; ///< number of coeffs in each coupling band + + int rematrixing_enabled; ///< stereo rematrixing enabled + + /* bitrate allocation control */ + int slow_gain_code; ///< slow gain code (sgaincod) + int slow_decay_code; ///< slow decay code (sdcycod) + int fast_decay_code; ///< fast decay code (fdcycod) + int db_per_bit_code; ///< dB/bit code (dbpbcod) + int floor_code; ///< floor code (floorcod) + AC3BitAllocParameters bit_alloc; ///< bit allocation parameters + int coarse_snr_offset; ///< coarse SNR offsets (csnroffst) + int fast_gain_code[AC3_MAX_CHANNELS]; ///< fast gain codes (signal-to-mask ratio) (fgaincod) + int fine_snr_offset[AC3_MAX_CHANNELS]; ///< fine SNR offsets (fsnroffst) + int frame_bits_fixed; ///< number of non-coefficient bits for fixed parameters + int frame_bits; ///< all frame bits except exponents and mantissas + int exponent_bits; ///< number of bits used for exponents + + SampleType *windowed_samples; + SampleType **planar_samples; + uint8_t *bap_buffer; + uint8_t *bap1_buffer; + CoefType *mdct_coef_buffer; + int32_t *fixed_coef_buffer; + uint8_t *exp_buffer; + uint8_t *grouped_exp_buffer; + int16_t *psd_buffer; + int16_t *band_psd_buffer; + int16_t *mask_buffer; + int16_t *qmant_buffer; + uint8_t *cpl_coord_exp_buffer; + uint8_t *cpl_coord_mant_buffer; + + uint8_t exp_strategy[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< exponent strategies + uint8_t frame_exp_strategy[AC3_MAX_CHANNELS]; ///< frame exp strategy index + int use_frame_exp_strategy; ///< indicates use of frame exp strategy + uint8_t exp_ref_block[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< reference blocks for EXP_REUSE + uint8_t *ref_bap [AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< bit allocation pointers (bap) + int ref_bap_set; ///< indicates if ref_bap pointers have been set + + /* fixed vs. float function pointers */ + void (*mdct_end)(struct AC3EncodeContext *s); + int (*mdct_init)(struct AC3EncodeContext *s); + + /* fixed vs. float templated function pointers */ + int (*allocate_sample_buffers)(struct AC3EncodeContext *s); + + /* AC-3 vs. E-AC-3 function pointers */ + void (*output_frame_header)(struct AC3EncodeContext *s); +} AC3EncodeContext; + + +extern const uint64_t ff_ac3_channel_layouts[19]; + +int ff_ac3_encode_init(AVCodecContext *avctx); +int ff_ac3_float_encode_init(AVCodecContext *avctx); + +int ff_ac3_encode_close(AVCodecContext *avctx); + +int ff_ac3_validate_metadata(AC3EncodeContext *s); + +void ff_ac3_adjust_frame_size(AC3EncodeContext *s); + +void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s); + +void ff_ac3_apply_rematrixing(AC3EncodeContext *s); + +void ff_ac3_process_exponents(AC3EncodeContext *s); + +int ff_ac3_compute_bit_allocation(AC3EncodeContext *s); + +void ff_ac3_group_exponents(AC3EncodeContext *s); + +void ff_ac3_quantize_mantissas(AC3EncodeContext *s); + +void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame); + + +/* prototypes for functions in ac3enc_fixed.c and ac3enc_float.c */ + +void ff_ac3_fixed_mdct_end(AC3EncodeContext *s); +void ff_ac3_float_mdct_end(AC3EncodeContext *s); + +int ff_ac3_fixed_mdct_init(AC3EncodeContext *s); +int ff_ac3_float_mdct_init(AC3EncodeContext *s); + + +/* prototypes for functions in ac3enc_template.c */ + +int ff_ac3_fixed_allocate_sample_buffers(AC3EncodeContext *s); +int ff_ac3_float_allocate_sample_buffers(AC3EncodeContext *s); + +int ff_ac3_fixed_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr); +int ff_ac3_float_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr); + +#endif /* AVCODEC_AC3ENC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_fixed.c new file mode 100644 index 000000000..b23fc6477 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_fixed.c @@ -0,0 +1,160 @@ +/* + * The simplest AC-3 encoder + * Copyright (c) 2000 Fabrice Bellard + * Copyright (c) 2006-2010 Justin Ruggles + * Copyright (c) 2006-2010 Prakash Punnoor + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * fixed-point AC-3 encoder. + */ + +#define FFT_FLOAT 0 +#undef CONFIG_AC3ENC_FLOAT +#include "internal.h" +#include "audiodsp.h" +#include "ac3enc.h" +#include "eac3enc.h" + +#define AC3ENC_TYPE AC3ENC_TYPE_AC3_FIXED +#include "ac3enc_opts_template.c" + +static const AVClass ac3enc_class = { + .class_name = "Fixed-Point AC-3 Encoder", + .item_name = av_default_item_name, + .option = ac3_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +/* + * Normalize the input samples to use the maximum available precision. + * This assumes signed 16-bit input samples. + */ +static int normalize_samples(AC3EncodeContext *s) +{ + int v = s->ac3dsp.ac3_max_msb_abs_int16(s->windowed_samples, AC3_WINDOW_SIZE); + v = 14 - av_log2(v); + if (v > 0) + s->ac3dsp.ac3_lshift_int16(s->windowed_samples, AC3_WINDOW_SIZE, v); + /* +6 to right-shift from 31-bit to 25-bit */ + return v + 6; +} + + +/* + * Scale MDCT coefficients to 25-bit signed fixed-point. + */ +static void scale_coefficients(AC3EncodeContext *s) +{ + int blk, ch; + + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + for (ch = 1; ch <= s->channels; ch++) { + s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS, + block->coeff_shift[ch]); + } + } +} + +static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4], + const int32_t *coef0, const int32_t *coef1, + int len) +{ + s->ac3dsp.sum_square_butterfly_int32(sum, coef0, coef1, len); +} + +/* + * Clip MDCT coefficients to allowable range. + */ +static void clip_coefficients(AudioDSPContext *adsp, int32_t *coef, + unsigned int len) +{ + adsp->vector_clip_int32(coef, coef, COEF_MIN, COEF_MAX, len); +} + + +/* + * Calculate a single coupling coordinate. + */ +static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) +{ + if (energy_cpl <= COEF_MAX) { + return 1048576; + } else { + uint64_t coord = energy_ch / (energy_cpl >> 24); + uint32_t coord32 = FFMIN(coord, 1073741824); + coord32 = ff_sqrt(coord32) << 9; + return FFMIN(coord32, COEF_MAX); + } +} + + +#include "ac3enc_template.c" + + +/** + * Finalize MDCT and free allocated memory. + * + * @param s AC-3 encoder private context + */ +av_cold void ff_ac3_fixed_mdct_end(AC3EncodeContext *s) +{ + ff_mdct_end(&s->mdct); +} + + +/** + * Initialize MDCT tables. + * + * @param s AC-3 encoder private context + * @return 0 on success, negative error code on failure + */ +av_cold int ff_ac3_fixed_mdct_init(AC3EncodeContext *s) +{ + int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0); + s->mdct_window = ff_ac3_window; + return ret; +} + + +static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx) +{ + AC3EncodeContext *s = avctx->priv_data; + s->fixed_point = 1; + return ff_ac3_encode_init(avctx); +} + + +AVCodec ff_ac3_fixed_encoder = { + .name = "ac3_fixed", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AC3, + .priv_data_size = sizeof(AC3EncodeContext), + .init = ac3_fixed_encode_init, + .encode2 = ff_ac3_fixed_encode_frame, + .close = ff_ac3_encode_close, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_NONE }, + .priv_class = &ac3enc_class, + .channel_layouts = ff_ac3_channel_layouts, + .defaults = ac3_defaults, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_float.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_float.c new file mode 100644 index 000000000..d6e658b2b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_float.c @@ -0,0 +1,155 @@ +/* + * The simplest AC-3 encoder + * Copyright (c) 2000 Fabrice Bellard + * Copyright (c) 2006-2010 Justin Ruggles + * Copyright (c) 2006-2010 Prakash Punnoor + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * floating-point AC-3 encoder. + */ + +#define CONFIG_AC3ENC_FLOAT 1 +#include "internal.h" +#include "audiodsp.h" +#include "ac3enc.h" +#include "eac3enc.h" +#include "kbdwin.h" + + +#define AC3ENC_TYPE AC3ENC_TYPE_AC3 +#include "ac3enc_opts_template.c" +static const AVClass ac3enc_class = { + .class_name = "AC-3 Encoder", + .item_name = av_default_item_name, + .option = ac3_options, + .version = LIBAVUTIL_VERSION_INT, +}; + + +/* + * Scale MDCT coefficients from float to 24-bit fixed-point. + */ +static void scale_coefficients(AC3EncodeContext *s) +{ + int chan_size = AC3_MAX_COEFS * s->num_blocks; + int cpl = s->cpl_on; + s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + (chan_size * !cpl), + s->mdct_coef_buffer + (chan_size * !cpl), + chan_size * (s->channels + cpl)); +} + + +/* + * Clip MDCT coefficients to allowable range. + */ +static void clip_coefficients(AudioDSPContext *adsp, float *coef, + unsigned int len) +{ + adsp->vector_clipf(coef, coef, len, COEF_MIN, COEF_MAX); +} + + +/* + * Calculate a single coupling coordinate. + */ +static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) +{ + float coord = 0.125; + if (energy_cpl > 0) + coord *= sqrtf(energy_ch / energy_cpl); + return FFMIN(coord, COEF_MAX); +} + +static void sum_square_butterfly(AC3EncodeContext *s, float sum[4], + const float *coef0, const float *coef1, + int len) +{ + s->ac3dsp.sum_square_butterfly_float(sum, coef0, coef1, len); +} + + +#include "ac3enc_template.c" + + +/** + * Finalize MDCT and free allocated memory. + * + * @param s AC-3 encoder private context + */ +av_cold void ff_ac3_float_mdct_end(AC3EncodeContext *s) +{ + ff_mdct_end(&s->mdct); + av_freep(&s->mdct_window); +} + + +/** + * Initialize MDCT tables. + * + * @param s AC-3 encoder private context + * @return 0 on success, negative error code on failure + */ +av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s) +{ + float *window; + int i, n, n2; + + n = 1 << 9; + n2 = n >> 1; + + window = av_malloc_array(n, sizeof(*window)); + if (!window) { + av_log(s->avctx, AV_LOG_ERROR, "Cannot allocate memory.\n"); + return AVERROR(ENOMEM); + } + ff_kbd_window_init(window, 5.0, n2); + for (i = 0; i < n2; i++) + window[n-1-i] = window[i]; + s->mdct_window = window; + + return ff_mdct_init(&s->mdct, 9, 0, -2.0 / n); +} + + +av_cold int ff_ac3_float_encode_init(AVCodecContext *avctx) +{ + AC3EncodeContext *s = avctx->priv_data; + s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!s->fdsp) + return AVERROR(ENOMEM); + return ff_ac3_encode_init(avctx); +} + +AVCodec ff_ac3_encoder = { + .name = "ac3", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AC3, + .priv_data_size = sizeof(AC3EncodeContext), + .init = ff_ac3_float_encode_init, + .encode2 = ff_ac3_float_encode_frame, + .close = ff_ac3_encode_close, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, + .priv_class = &ac3enc_class, + .channel_layouts = ff_ac3_channel_layouts, + .defaults = ac3_defaults, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_opts_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_opts_template.c new file mode 100644 index 000000000..57b65a7a9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_opts_template.c @@ -0,0 +1,82 @@ +/* + * AC-3 encoder options + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/opt.h" +#include "internal.h" +#include "ac3.h" + +static const AVOption ac3_options[] = { +/* Metadata Options */ +{"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, AC3ENC_PARAM}, +#if AC3ENC_TYPE != AC3ENC_TYPE_EAC3 +/* AC-3 downmix levels */ +{"center_mixlev", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_4POINT5DB }, 0.0, 1.0, AC3ENC_PARAM}, +{"surround_mixlev", "Surround Mix Level", OFFSET(surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_6DB }, 0.0, 1.0, AC3ENC_PARAM}, +#endif +/* audio production information */ +{"mixing_level", "Mixing Level", OFFSET(mixing_level), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 111, AC3ENC_PARAM}, +{"room_type", "Room Type", OFFSET(room_type), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_SMALL_ROOM, AC3ENC_PARAM, "room_type"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"}, + {"large", "Large Room", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_LARGE_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"}, + {"small", "Small Room", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_SMALL_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"}, +/* other metadata options */ +{"copyright", "Copyright Bit", OFFSET(copyright), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM}, +{"dialnorm", "Dialogue Level (dB)", OFFSET(dialogue_level), AV_OPT_TYPE_INT, {.i64 = -31 }, -31, -1, AC3ENC_PARAM}, +{"dsur_mode", "Dolby Surround Mode", OFFSET(dolby_surround_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dsur_mode"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"}, + {"on", "Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"}, + {"off", "Not Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"}, +{"original", "Original Bit Stream", OFFSET(original), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM}, +/* extended bitstream information */ +{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DOWNMIX_DPLII, AC3ENC_PARAM, "dmix_mode"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"}, + {"ltrt", "Lt/Rt Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LTRT }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"}, + {"loro", "Lo/Ro Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LORO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"}, + {"dplii", "Dolby Pro Logic II Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_DPLII }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"}, +{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM}, +{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM}, +{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM}, +{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM}, +{"dsurex_mode", "Dolby Surround EX Mode", OFFSET(dolby_surround_ex_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DSUREX_DPLIIZ, AC3ENC_PARAM, "dsurex_mode"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"}, + {"on", "Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"}, + {"off", "Not Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"}, + {"dpliiz", "Dolby Pro Logic IIz-encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DSUREX_DPLIIZ }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"}, +{"dheadphone_mode", "Dolby Headphone Mode", OFFSET(dolby_headphone_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dheadphone_mode"}, + {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"}, + {"on", "Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"}, + {"off", "Not Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"}, +{"ad_conv_type", "A/D Converter Type", OFFSET(ad_converter_type), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_ADCONV_HDCD, AC3ENC_PARAM, "ad_conv_type"}, + {"standard", "Standard (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_ADCONV_STANDARD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, + {"hdcd", "HDCD", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_ADCONV_HDCD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, +/* Other Encoding Options */ +{"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, AC3ENC_PARAM}, +{"channel_coupling", "Channel Coupling", OFFSET(channel_coupling), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, AC3ENC_OPT_ON, AC3ENC_PARAM, "channel_coupling"}, + {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "channel_coupling"}, +{"cpl_start_band", "Coupling Start Band", OFFSET(cpl_start), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, 15, AC3ENC_PARAM, "cpl_start_band"}, + {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "cpl_start_band"}, +{NULL} +}; + +static const AVCodecDefault ac3_defaults[] = { + { "b", "0" }, + { NULL } +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_template.c new file mode 100644 index 000000000..be659872f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3enc_template.c @@ -0,0 +1,436 @@ +/* + * AC-3 encoder float/fixed template + * Copyright (c) 2000 Fabrice Bellard + * Copyright (c) 2006-2011 Justin Ruggles + * Copyright (c) 2006-2010 Prakash Punnoor + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AC-3 encoder float/fixed template + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/internal.h" + +#include "audiodsp.h" +#include "internal.h" +#include "ac3enc.h" +#include "eac3enc.h" + + +int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s) +{ + int ch; + + FF_ALLOC_OR_GOTO(s->avctx, s->windowed_samples, AC3_WINDOW_SIZE * + sizeof(*s->windowed_samples), alloc_fail); + FF_ALLOC_ARRAY_OR_GOTO(s->avctx, s->planar_samples, s->channels, sizeof(*s->planar_samples), + alloc_fail); + for (ch = 0; ch < s->channels; ch++) { + FF_ALLOCZ_OR_GOTO(s->avctx, s->planar_samples[ch], + (AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples), + alloc_fail); + } + + return 0; +alloc_fail: + return AVERROR(ENOMEM); +} + + +/* + * Copy input samples. + * Channels are reordered from FFmpeg's default order to AC-3 order. + */ +static void copy_input_samples(AC3EncodeContext *s, SampleType **samples) +{ + int ch; + + /* copy and remap input samples */ + for (ch = 0; ch < s->channels; ch++) { + /* copy last 256 samples of previous frame to the start of the current frame */ + memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_BLOCK_SIZE * s->num_blocks], + AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0])); + + /* copy new samples for current frame */ + memcpy(&s->planar_samples[ch][AC3_BLOCK_SIZE], + samples[s->channel_map[ch]], + AC3_BLOCK_SIZE * s->num_blocks * sizeof(s->planar_samples[0][0])); + } +} + + +/* + * Apply the MDCT to input samples to generate frequency coefficients. + * This applies the KBD window and normalizes the input to reduce precision + * loss due to fixed-point calculations. + */ +static void apply_mdct(AC3EncodeContext *s) +{ + int blk, ch; + + for (ch = 0; ch < s->channels; ch++) { + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE]; + +#if CONFIG_AC3ENC_FLOAT + s->fdsp->vector_fmul(s->windowed_samples, input_samples, + s->mdct_window, AC3_WINDOW_SIZE); +#else + s->ac3dsp.apply_window_int16(s->windowed_samples, input_samples, + s->mdct_window, AC3_WINDOW_SIZE); + + if (s->fixed_point) + block->coeff_shift[ch+1] = normalize_samples(s); +#endif + + s->mdct.mdct_calcw(&s->mdct, block->mdct_coef[ch+1], + s->windowed_samples); + } + } +} + + +/* + * Calculate coupling channel and coupling coordinates. + */ +static void apply_channel_coupling(AC3EncodeContext *s) +{ + LOCAL_ALIGNED_16(CoefType, cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); +#if CONFIG_AC3ENC_FLOAT + LOCAL_ALIGNED_16(int32_t, fixed_cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); +#else + int32_t (*fixed_cpl_coords)[AC3_MAX_CHANNELS][16] = cpl_coords; +#endif + int av_uninit(blk), ch, bnd, i, j; + CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}}; + int cpl_start, num_cpl_coefs; + + memset(cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords)); +#if CONFIG_AC3ENC_FLOAT + memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords)); +#endif + + /* align start to 16-byte boundary. align length to multiple of 32. + note: coupling start bin % 4 will always be 1 */ + cpl_start = s->start_freq[CPL_CH] - 1; + num_cpl_coefs = FFALIGN(s->num_cpl_subbands * 12 + 1, 32); + cpl_start = FFMIN(256, cpl_start + num_cpl_coefs) - num_cpl_coefs; + + /* calculate coupling channel from fbw channels */ + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + CoefType *cpl_coef = &block->mdct_coef[CPL_CH][cpl_start]; + if (!block->cpl_in_use) + continue; + memset(cpl_coef, 0, num_cpl_coefs * sizeof(*cpl_coef)); + for (ch = 1; ch <= s->fbw_channels; ch++) { + CoefType *ch_coef = &block->mdct_coef[ch][cpl_start]; + if (!block->channel_in_cpl[ch]) + continue; + for (i = 0; i < num_cpl_coefs; i++) + cpl_coef[i] += ch_coef[i]; + } + + /* coefficients must be clipped in order to be encoded */ + clip_coefficients(&s->adsp, cpl_coef, num_cpl_coefs); + } + + /* calculate energy in each band in coupling channel and each fbw channel */ + /* TODO: possibly use SIMD to speed up energy calculation */ + bnd = 0; + i = s->start_freq[CPL_CH]; + while (i < s->cpl_end_freq) { + int band_size = s->cpl_band_sizes[bnd]; + for (ch = CPL_CH; ch <= s->fbw_channels; ch++) { + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch])) + continue; + for (j = 0; j < band_size; j++) { + CoefType v = block->mdct_coef[ch][i+j]; + MAC_COEF(energy[blk][ch][bnd], v, v); + } + } + } + i += band_size; + bnd++; + } + + /* calculate coupling coordinates for all blocks for all channels */ + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + if (!block->cpl_in_use) + continue; + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (!block->channel_in_cpl[ch]) + continue; + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd], + energy[blk][CPL_CH][bnd]); + } + } + } + + /* determine which blocks to send new coupling coordinates for */ + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL; + + memset(block->new_cpl_coords, 0, sizeof(block->new_cpl_coords)); + + if (block->cpl_in_use) { + /* send new coordinates if this is the first block, if previous + * block did not use coupling but this block does, the channels + * using coupling has changed from the previous block, or the + * coordinate difference from the last block for any channel is + * greater than a threshold value. */ + if (blk == 0 || !block0->cpl_in_use) { + for (ch = 1; ch <= s->fbw_channels; ch++) + block->new_cpl_coords[ch] = 1; + } else { + for (ch = 1; ch <= s->fbw_channels; ch++) { + if (!block->channel_in_cpl[ch]) + continue; + if (!block0->channel_in_cpl[ch]) { + block->new_cpl_coords[ch] = 1; + } else { + CoefSumType coord_diff = 0; + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + coord_diff += FFABS(cpl_coords[blk-1][ch][bnd] - + cpl_coords[blk ][ch][bnd]); + } + coord_diff /= s->num_cpl_bands; + if (coord_diff > NEW_CPL_COORD_THRESHOLD) + block->new_cpl_coords[ch] = 1; + } + } + } + } + } + + /* calculate final coupling coordinates, taking into account reusing of + coordinates in successive blocks */ + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + blk = 0; + while (blk < s->num_blocks) { + int av_uninit(blk1); + AC3Block *block = &s->blocks[blk]; + + if (!block->cpl_in_use) { + blk++; + continue; + } + + for (ch = 1; ch <= s->fbw_channels; ch++) { + CoefSumType energy_ch, energy_cpl; + if (!block->channel_in_cpl[ch]) + continue; + energy_cpl = energy[blk][CPL_CH][bnd]; + energy_ch = energy[blk][ch][bnd]; + blk1 = blk+1; + while (blk1 < s->num_blocks && !s->blocks[blk1].new_cpl_coords[ch]) { + if (s->blocks[blk1].cpl_in_use) { + energy_cpl += energy[blk1][CPL_CH][bnd]; + energy_ch += energy[blk1][ch][bnd]; + } + blk1++; + } + cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl); + } + blk = blk1; + } + } + + /* calculate exponents/mantissas for coupling coordinates */ + for (blk = 0; blk < s->num_blocks; blk++) { + AC3Block *block = &s->blocks[blk]; + if (!block->cpl_in_use) + continue; + +#if CONFIG_AC3ENC_FLOAT + s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1], + cpl_coords[blk][1], + s->fbw_channels * 16); +#endif + s->ac3dsp.extract_exponents(block->cpl_coord_exp[1], + fixed_cpl_coords[blk][1], + s->fbw_channels * 16); + + for (ch = 1; ch <= s->fbw_channels; ch++) { + int bnd, min_exp, max_exp, master_exp; + + if (!block->new_cpl_coords[ch]) + continue; + + /* determine master exponent */ + min_exp = max_exp = block->cpl_coord_exp[ch][0]; + for (bnd = 1; bnd < s->num_cpl_bands; bnd++) { + int exp = block->cpl_coord_exp[ch][bnd]; + min_exp = FFMIN(exp, min_exp); + max_exp = FFMAX(exp, max_exp); + } + master_exp = ((max_exp - 15) + 2) / 3; + master_exp = FFMAX(master_exp, 0); + while (min_exp < master_exp * 3) + master_exp--; + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + block->cpl_coord_exp[ch][bnd] = av_clip(block->cpl_coord_exp[ch][bnd] - + master_exp * 3, 0, 15); + } + block->cpl_master_exp[ch] = master_exp; + + /* quantize mantissas */ + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + int cpl_exp = block->cpl_coord_exp[ch][bnd]; + int cpl_mant = (fixed_cpl_coords[blk][ch][bnd] << (5 + cpl_exp + master_exp * 3)) >> 24; + if (cpl_exp == 15) + cpl_mant >>= 1; + else + cpl_mant -= 16; + + block->cpl_coord_mant[ch][bnd] = cpl_mant; + } + } + } + + if (CONFIG_EAC3_ENCODER && s->eac3) + ff_eac3_set_cpl_states(s); +} + + +/* + * Determine rematrixing flags for each block and band. + */ +static void compute_rematrixing_strategy(AC3EncodeContext *s) +{ + int nb_coefs; + int blk, bnd; + AC3Block *block, *block0 = NULL; + + if (s->channel_mode != AC3_CHMODE_STEREO) + return; + + for (blk = 0; blk < s->num_blocks; blk++) { + block = &s->blocks[blk]; + block->new_rematrixing_strategy = !blk; + + block->num_rematrixing_bands = 4; + if (block->cpl_in_use) { + block->num_rematrixing_bands -= (s->start_freq[CPL_CH] <= 61); + block->num_rematrixing_bands -= (s->start_freq[CPL_CH] == 37); + if (blk && block->num_rematrixing_bands != block0->num_rematrixing_bands) + block->new_rematrixing_strategy = 1; + } + nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]); + + if (!s->rematrixing_enabled) { + block0 = block; + continue; + } + + for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) { + /* calculate sum of squared coeffs for one band in one block */ + int start = ff_ac3_rematrix_band_tab[bnd]; + int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); + CoefSumType sum[4]; + sum_square_butterfly(s, sum, block->mdct_coef[1] + start, + block->mdct_coef[2] + start, end - start); + + /* compare sums to determine if rematrixing will be used for this band */ + if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1])) + block->rematrixing_flags[bnd] = 1; + else + block->rematrixing_flags[bnd] = 0; + + /* determine if new rematrixing flags will be sent */ + if (blk && + block->rematrixing_flags[bnd] != block0->rematrixing_flags[bnd]) { + block->new_rematrixing_strategy = 1; + } + } + block0 = block; + } +} + + +int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + AC3EncodeContext *s = avctx->priv_data; + int ret; + + if (s->options.allow_per_frame_metadata) { + ret = ff_ac3_validate_metadata(s); + if (ret) + return ret; + } + + if (s->bit_alloc.sr_code == 1 || s->eac3) + ff_ac3_adjust_frame_size(s); + + copy_input_samples(s, (SampleType **)frame->extended_data); + + apply_mdct(s); + + if (s->fixed_point) + scale_coefficients(s); + + clip_coefficients(&s->adsp, s->blocks[0].mdct_coef[1], + AC3_MAX_COEFS * s->num_blocks * s->channels); + + s->cpl_on = s->cpl_enabled; + ff_ac3_compute_coupling_strategy(s); + + if (s->cpl_on) + apply_channel_coupling(s); + + compute_rematrixing_strategy(s); + + if (!s->fixed_point) + scale_coefficients(s); + + ff_ac3_apply_rematrixing(s); + + ff_ac3_process_exponents(s); + + ret = ff_ac3_compute_bit_allocation(s); + if (ret) { + av_log(avctx, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n"); + return ret; + } + + ff_ac3_group_exponents(s); + + ff_ac3_quantize_mantissas(s); + + if ((ret = ff_alloc_packet2(avctx, avpkt, s->frame_size, 0)) < 0) + return ret; + ff_ac3_output_frame(s, avpkt->data); + + if (frame->pts != AV_NOPTS_VALUE) + avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding); + + *got_packet_ptr = 1; + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3tab.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3tab.c new file mode 100644 index 000000000..bd88f32d9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3tab.c @@ -0,0 +1,334 @@ +/* + * AC-3 tables + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * tables taken directly from the AC-3 spec. + */ + +#include "libavutil/channel_layout.h" +#include "libavutil/mem.h" + +#include "avcodec.h" +#include "ac3tab.h" + +/** + * Possible frame sizes. + * from ATSC A/52 Table 5.18 Frame Size Code Table. + */ +const uint16_t ff_ac3_frame_size_tab[38][3] = { + { 64, 69, 96 }, + { 64, 70, 96 }, + { 80, 87, 120 }, + { 80, 88, 120 }, + { 96, 104, 144 }, + { 96, 105, 144 }, + { 112, 121, 168 }, + { 112, 122, 168 }, + { 128, 139, 192 }, + { 128, 140, 192 }, + { 160, 174, 240 }, + { 160, 175, 240 }, + { 192, 208, 288 }, + { 192, 209, 288 }, + { 224, 243, 336 }, + { 224, 244, 336 }, + { 256, 278, 384 }, + { 256, 279, 384 }, + { 320, 348, 480 }, + { 320, 349, 480 }, + { 384, 417, 576 }, + { 384, 418, 576 }, + { 448, 487, 672 }, + { 448, 488, 672 }, + { 512, 557, 768 }, + { 512, 558, 768 }, + { 640, 696, 960 }, + { 640, 697, 960 }, + { 768, 835, 1152 }, + { 768, 836, 1152 }, + { 896, 975, 1344 }, + { 896, 976, 1344 }, + { 1024, 1114, 1536 }, + { 1024, 1115, 1536 }, + { 1152, 1253, 1728 }, + { 1152, 1254, 1728 }, + { 1280, 1393, 1920 }, + { 1280, 1394, 1920 }, +}; + +/** + * Map audio coding mode (acmod) to number of full-bandwidth channels. + * from ATSC A/52 Table 5.8 Audio Coding Mode + */ +const uint8_t ff_ac3_channels_tab[8] = { + 2, 1, 2, 3, 3, 4, 4, 5 +}; + +/** + * Map audio coding mode (acmod) to channel layout mask. + */ +const uint16_t avpriv_ac3_channel_layout_tab[8] = { + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_2_1, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_2_2, + AV_CH_LAYOUT_5POINT0 +}; + +#define COMMON_CHANNEL_MAP \ + { { 0, 1, }, { 0, 1, 2, } },\ + { { 0, }, { 0, 1, } },\ + { { 0, 1, }, { 0, 1, 2, } },\ + { { 0, 2, 1, }, { 0, 2, 1, 3, } },\ + { { 0, 1, 2, }, { 0, 1, 3, 2, } },\ + { { 0, 2, 1, 3, }, { 0, 2, 1, 4, 3, } }, + +/** + * Table to remap channels from SMPTE order to AC-3 order. + * [channel_mode][lfe][ch] + */ +const uint8_t ff_ac3_enc_channel_map[8][2][6] = { + COMMON_CHANNEL_MAP + { { 0, 1, 2, 3, }, { 0, 1, 3, 4, 2, } }, + { { 0, 2, 1, 3, 4, }, { 0, 2, 1, 4, 5, 3 } }, +}; + +/** + * Table to remap channels from AC-3 order to SMPTE order. + * [channel_mode][lfe][ch] + */ +const uint8_t ff_ac3_dec_channel_map[8][2][6] = { + COMMON_CHANNEL_MAP + { { 0, 1, 2, 3, }, { 0, 1, 4, 2, 3, } }, + { { 0, 2, 1, 3, 4, }, { 0, 2, 1, 5, 3, 4 } }, +}; + +/* possible frequencies */ +const uint16_t ff_ac3_sample_rate_tab[3] = { 48000, 44100, 32000 }; + +/* possible bitrates */ +const uint16_t ff_ac3_bitrate_tab[19] = { + 32, 40, 48, 56, 64, 80, 96, 112, 128, + 160, 192, 224, 256, 320, 384, 448, 512, 576, 640 +}; + +/** + * Table of bin locations for rematrixing bands + * reference: Section 7.5.2 Rematrixing : Frequency Band Definitions + */ +const uint8_t ff_ac3_rematrix_band_tab[5] = { 13, 25, 37, 61, 253 }; + +/** + * Table E2.16 Default Coupling Banding Structure + */ +const uint8_t ff_eac3_default_cpl_band_struct[18] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 +}; + +/* AC-3 MDCT window */ + +/* MDCT window */ +DECLARE_ALIGNED(16, const int16_t, ff_ac3_window)[AC3_WINDOW_SIZE/2] = { + 4, 7, 12, 16, 21, 28, 34, 42, + 51, 61, 72, 84, 97, 111, 127, 145, + 164, 184, 207, 231, 257, 285, 315, 347, + 382, 419, 458, 500, 544, 591, 641, 694, + 750, 810, 872, 937, 1007, 1079, 1155, 1235, + 1318, 1406, 1497, 1593, 1692, 1796, 1903, 2016, + 2132, 2253, 2379, 2509, 2644, 2783, 2927, 3076, + 3230, 3389, 3552, 3721, 3894, 4072, 4255, 4444, + 4637, 4835, 5038, 5246, 5459, 5677, 5899, 6127, + 6359, 6596, 6837, 7083, 7334, 7589, 7848, 8112, + 8380, 8652, 8927, 9207, 9491, 9778,10069,10363, +10660,10960,11264,11570,11879,12190,12504,12820, +13138,13458,13780,14103,14427,14753,15079,15407, +15735,16063,16392,16720,17049,17377,17705,18032, +18358,18683,19007,19330,19651,19970,20287,20602, +20914,21225,21532,21837,22139,22438,22733,23025, +23314,23599,23880,24157,24430,24699,24964,25225, +25481,25732,25979,26221,26459,26691,26919,27142, +27359,27572,27780,27983,28180,28373,28560,28742, +28919,29091,29258,29420,29577,29729,29876,30018, +30155,30288,30415,30538,30657,30771,30880,30985, +31086,31182,31274,31363,31447,31528,31605,31678, +31747,31814,31877,31936,31993,32046,32097,32145, +32190,32232,32272,32310,32345,32378,32409,32438, +32465,32490,32513,32535,32556,32574,32592,32608, +32623,32636,32649,32661,32671,32681,32690,32698, +32705,32712,32718,32724,32729,32733,32737,32741, +32744,32747,32750,32752,32754,32756,32757,32759, +32760,32761,32762,32763,32764,32764,32765,32765, +32766,32766,32766,32766,32767,32767,32767,32767, +32767,32767,32767,32767,32767,32767,32767,32767, +32767,32767,32767,32767,32767,32767,32767,32767, +}; + +const uint8_t ff_ac3_log_add_tab[260]= { +0x40,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37, +0x36,0x35,0x34,0x34,0x33,0x32,0x31,0x30,0x2f,0x2f, +0x2e,0x2d,0x2c,0x2c,0x2b,0x2a,0x29,0x29,0x28,0x27, +0x26,0x26,0x25,0x24,0x24,0x23,0x23,0x22,0x21,0x21, +0x20,0x20,0x1f,0x1e,0x1e,0x1d,0x1d,0x1c,0x1c,0x1b, +0x1b,0x1a,0x1a,0x19,0x19,0x18,0x18,0x17,0x17,0x16, +0x16,0x15,0x15,0x15,0x14,0x14,0x13,0x13,0x13,0x12, +0x12,0x12,0x11,0x11,0x11,0x10,0x10,0x10,0x0f,0x0f, +0x0f,0x0e,0x0e,0x0e,0x0d,0x0d,0x0d,0x0d,0x0c,0x0c, +0x0c,0x0c,0x0b,0x0b,0x0b,0x0b,0x0a,0x0a,0x0a,0x0a, +0x0a,0x09,0x09,0x09,0x09,0x09,0x08,0x08,0x08,0x08, +0x08,0x08,0x07,0x07,0x07,0x07,0x07,0x07,0x06,0x06, +0x06,0x06,0x06,0x06,0x06,0x06,0x05,0x05,0x05,0x05, +0x05,0x05,0x05,0x05,0x04,0x04,0x04,0x04,0x04,0x04, +0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03, +0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x02, +0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, +0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +const uint16_t ff_ac3_hearing_threshold_tab[AC3_CRITICAL_BANDS][3]= { +{ 0x04d0,0x04f0,0x0580 }, +{ 0x04d0,0x04f0,0x0580 }, +{ 0x0440,0x0460,0x04b0 }, +{ 0x0400,0x0410,0x0450 }, +{ 0x03e0,0x03e0,0x0420 }, +{ 0x03c0,0x03d0,0x03f0 }, +{ 0x03b0,0x03c0,0x03e0 }, +{ 0x03b0,0x03b0,0x03d0 }, +{ 0x03a0,0x03b0,0x03c0 }, +{ 0x03a0,0x03a0,0x03b0 }, +{ 0x03a0,0x03a0,0x03b0 }, +{ 0x03a0,0x03a0,0x03b0 }, +{ 0x03a0,0x03a0,0x03a0 }, +{ 0x0390,0x03a0,0x03a0 }, +{ 0x0390,0x0390,0x03a0 }, +{ 0x0390,0x0390,0x03a0 }, +{ 0x0380,0x0390,0x03a0 }, +{ 0x0380,0x0380,0x03a0 }, +{ 0x0370,0x0380,0x03a0 }, +{ 0x0370,0x0380,0x03a0 }, +{ 0x0360,0x0370,0x0390 }, +{ 0x0360,0x0370,0x0390 }, +{ 0x0350,0x0360,0x0390 }, +{ 0x0350,0x0360,0x0390 }, +{ 0x0340,0x0350,0x0380 }, +{ 0x0340,0x0350,0x0380 }, +{ 0x0330,0x0340,0x0380 }, +{ 0x0320,0x0340,0x0370 }, +{ 0x0310,0x0320,0x0360 }, +{ 0x0300,0x0310,0x0350 }, +{ 0x02f0,0x0300,0x0340 }, +{ 0x02f0,0x02f0,0x0330 }, +{ 0x02f0,0x02f0,0x0320 }, +{ 0x02f0,0x02f0,0x0310 }, +{ 0x0300,0x02f0,0x0300 }, +{ 0x0310,0x0300,0x02f0 }, +{ 0x0340,0x0320,0x02f0 }, +{ 0x0390,0x0350,0x02f0 }, +{ 0x03e0,0x0390,0x0300 }, +{ 0x0420,0x03e0,0x0310 }, +{ 0x0460,0x0420,0x0330 }, +{ 0x0490,0x0450,0x0350 }, +{ 0x04a0,0x04a0,0x03c0 }, +{ 0x0460,0x0490,0x0410 }, +{ 0x0440,0x0460,0x0470 }, +{ 0x0440,0x0440,0x04a0 }, +{ 0x0520,0x0480,0x0460 }, +{ 0x0800,0x0630,0x0440 }, +{ 0x0840,0x0840,0x0450 }, +{ 0x0840,0x0840,0x04e0 }, +}; + +const uint8_t ff_ac3_bap_tab[64]= { + 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, + 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, + 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, + 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, + 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, + 15, 15, 15, 15, +}; + +const uint8_t ff_ac3_slow_decay_tab[4]={ + 0x0f, 0x11, 0x13, 0x15, +}; + +const uint8_t ff_ac3_fast_decay_tab[4]={ + 0x3f, 0x53, 0x67, 0x7b, +}; + +const uint16_t ff_ac3_slow_gain_tab[4]= { + 0x540, 0x4d8, 0x478, 0x410, +}; + +const uint16_t ff_ac3_db_per_bit_tab[4]= { + 0x000, 0x700, 0x900, 0xb00, +}; + +const int16_t ff_ac3_floor_tab[8]= { + 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800, +}; + +const uint16_t ff_ac3_fast_gain_tab[8]= { + 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400, +}; + +/** + * Default channel map for a dependent substream defined by acmod + */ +const uint16_t ff_eac3_default_chmap[8] = { + AC3_CHMAP_L | AC3_CHMAP_R, // FIXME Ch1+Ch2 + AC3_CHMAP_C, + AC3_CHMAP_L | AC3_CHMAP_R, + AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R, + AC3_CHMAP_L | AC3_CHMAP_R | AC3_CHMAP_C_SUR, + AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R | AC3_CHMAP_C_SUR, + AC3_CHMAP_L | AC3_CHMAP_R | AC3_CHMAP_L_SUR | AC3_CHMAP_R_SUR, + AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R | AC3_CHMAP_L_SUR | AC3_CHMAP_R_SUR +}; +const uint64_t ff_eac3_custom_channel_map_locations[16][2] = { + { 1, AV_CH_FRONT_LEFT }, + { 1, AV_CH_FRONT_CENTER }, + { 1, AV_CH_FRONT_RIGHT }, + { 1, AV_CH_SIDE_LEFT }, + { 1, AV_CH_SIDE_RIGHT }, + { 0, AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER }, + { 0, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT }, + { 0, AV_CH_BACK_CENTER }, + { 0, AV_CH_TOP_CENTER }, + { 0, AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT }, + { 0, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT }, + { 0, AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT}, + { 0, AV_CH_TOP_FRONT_CENTER }, + { 0, AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT }, + { 0, AV_CH_LOW_FREQUENCY_2 }, + { 1, AV_CH_LOW_FREQUENCY }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3tab.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3tab.h new file mode 100644 index 000000000..aa71acbce --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ac3tab.h @@ -0,0 +1,71 @@ +/* + * AC-3 tables + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AC3TAB_H +#define AVCODEC_AC3TAB_H + +#include + +#include "libavutil/internal.h" +#include "ac3.h" +#include "internal.h" + +extern const uint16_t ff_ac3_frame_size_tab[38][3]; +extern const uint8_t ff_ac3_channels_tab[8]; +extern av_export_avcodec const uint16_t avpriv_ac3_channel_layout_tab[8]; +extern const uint8_t ff_ac3_enc_channel_map[8][2][6]; +extern const uint8_t ff_ac3_dec_channel_map[8][2][6]; +extern const uint16_t ff_ac3_sample_rate_tab[3]; +extern const uint16_t ff_ac3_bitrate_tab[19]; +extern const uint8_t ff_ac3_rematrix_band_tab[5]; +extern const uint8_t ff_eac3_default_cpl_band_struct[18]; +extern const int16_t ff_ac3_window[AC3_WINDOW_SIZE/2]; +extern const uint8_t ff_ac3_log_add_tab[260]; +extern const uint16_t ff_ac3_hearing_threshold_tab[AC3_CRITICAL_BANDS][3]; +extern const uint8_t ff_ac3_bap_tab[64]; +extern const uint8_t ff_ac3_slow_decay_tab[4]; +extern const uint8_t ff_ac3_fast_decay_tab[4]; +extern const uint16_t ff_ac3_slow_gain_tab[4]; +extern const uint16_t ff_ac3_db_per_bit_tab[4]; +extern const int16_t ff_ac3_floor_tab[8]; +extern const uint16_t ff_ac3_fast_gain_tab[8]; +extern const uint16_t ff_eac3_default_chmap[8]; +extern const uint8_t ff_ac3_band_start_tab[AC3_CRITICAL_BANDS+1]; +extern const uint8_t ff_ac3_bin_to_band_tab[253]; +extern const uint64_t ff_eac3_custom_channel_map_locations[16][2]; + + +/** Custom channel map locations bitmask + * Other channels described in documentation: + * Lc/Rc pair, Lrs/Rrs pair, Ts, Lsd/Rsd pair, + * Lw/Rw pair, Lvh/Rvh pair, Cvh, Reserved, LFE2 + */ +enum CustomChannelMapLocation{ + AC3_CHMAP_L= 1<<(15-0), + AC3_CHMAP_C= 1<<(15-1), + AC3_CHMAP_R= 1<<(15-2), + AC3_CHMAP_L_SUR= 1<<(15-3), + AC3_CHMAP_R_SUR = 1<<(15-4), + AC3_CHMAP_C_SUR= 1<<(15-7), + AC3_CHMAP_LFE = 1<<(15-15) +}; + +#endif /* AVCODEC_AC3TAB_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_header.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_header.c new file mode 100644 index 000000000..0889820f8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_header.c @@ -0,0 +1,71 @@ +/* + * Audio and Video frame extraction + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2009 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "aac_ac3_parser.h" +#include "adts_header.h" +#include "adts_parser.h" +#include "get_bits.h" +#include "mpeg4audio.h" + +int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr) +{ + int size, rdb, ch, sr; + int aot, crc_abs; + + if (get_bits(gbc, 12) != 0xfff) + return AAC_AC3_PARSE_ERROR_SYNC; + + skip_bits1(gbc); /* id */ + skip_bits(gbc, 2); /* layer */ + crc_abs = get_bits1(gbc); /* protection_absent */ + aot = get_bits(gbc, 2); /* profile_objecttype */ + sr = get_bits(gbc, 4); /* sample_frequency_index */ + if (!avpriv_mpeg4audio_sample_rates[sr]) + return AAC_AC3_PARSE_ERROR_SAMPLE_RATE; + skip_bits1(gbc); /* private_bit */ + ch = get_bits(gbc, 3); /* channel_configuration */ + + skip_bits1(gbc); /* original/copy */ + skip_bits1(gbc); /* home */ + + /* adts_variable_header */ + skip_bits1(gbc); /* copyright_identification_bit */ + skip_bits1(gbc); /* copyright_identification_start */ + size = get_bits(gbc, 13); /* aac_frame_length */ + if (size < AV_AAC_ADTS_HEADER_SIZE) + return AAC_AC3_PARSE_ERROR_FRAME_SIZE; + + skip_bits(gbc, 11); /* adts_buffer_fullness */ + rdb = get_bits(gbc, 2); /* number_of_raw_data_blocks_in_frame */ + + hdr->object_type = aot + 1; + hdr->chan_config = ch; + hdr->crc_absent = crc_abs; + hdr->num_aac_frames = rdb + 1; + hdr->sampling_index = sr; + hdr->sample_rate = avpriv_mpeg4audio_sample_rates[sr]; + hdr->samples = (rdb + 1) * 1024; + hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; + + return size; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_header.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_header.h new file mode 100644 index 000000000..f615f6a9f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_header.h @@ -0,0 +1,50 @@ +/* + * AAC ADTS header decoding prototypes and structures + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_ADTS_HEADER_H +#define AVCODEC_ADTS_HEADER_H + +#include "get_bits.h" + +typedef struct AACADTSHeaderInfo { + uint32_t sample_rate; + uint32_t samples; + uint32_t bit_rate; + uint8_t crc_absent; + uint8_t object_type; + uint8_t sampling_index; + uint8_t chan_config; + uint8_t num_aac_frames; +} AACADTSHeaderInfo; + +/** + * Parse the ADTS frame header to the end of the variable header, which is + * the first 54 bits. + * @param[in] gbc BitContext containing the first 54 bits of the frame. + * @param[out] hdr Pointer to struct where header info is written. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr); + +#endif /* AVCODEC_ADTS_HEADER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_parser.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_parser.c new file mode 100644 index 000000000..5c9f8ff6f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_parser.c @@ -0,0 +1,44 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include + +#include "adts_header.h" +#include "adts_parser.h" + +int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, uint8_t *frames) +{ +#if CONFIG_ADTS_HEADER + GetBitContext gb; + AACADTSHeaderInfo hdr; + int err = init_get_bits8(&gb, buf, AV_AAC_ADTS_HEADER_SIZE); + if (err < 0) + return err; + err = ff_adts_header_parse(&gb, &hdr); + if (err < 0) + return err; + *samples = hdr.samples; + *frames = hdr.num_aac_frames; + return 0; +#else + return AVERROR(ENOSYS); +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_parser.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_parser.h new file mode 100644 index 000000000..f85becd13 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/adts_parser.h @@ -0,0 +1,37 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_ADTS_PARSER_H +#define AVCODEC_ADTS_PARSER_H + +#include +#include + +#define AV_AAC_ADTS_HEADER_SIZE 7 + +/** + * Extract the number of samples and frames from AAC data. + * @param[in] buf pointer to AAC data buffer + * @param[out] samples Pointer to where number of samples is written + * @param[out] frames Pointer to where number of frames is written + * @return Returns 0 on success, error code on failure. + */ +int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, + uint8_t *frames); + +#endif /* AVCODEC_ADTS_PARSER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/allcodecs.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/allcodecs.c new file mode 100644 index 000000000..d2f9a39ce --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/allcodecs.c @@ -0,0 +1,921 @@ +/* + * Provide registration of all codecs, parsers and bitstream filters for libavcodec. + * Copyright (c) 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Provide registration of all codecs, parsers and bitstream filters for libavcodec. + */ + +#include "config.h" +#include "libavutil/thread.h" +#include "avcodec.h" +#include "version.h" + +extern AVCodec ff_a64multi_encoder; +extern AVCodec ff_a64multi5_encoder; +extern AVCodec ff_aasc_decoder; +extern AVCodec ff_aic_decoder; +extern AVCodec ff_alias_pix_encoder; +extern AVCodec ff_alias_pix_decoder; +extern AVCodec ff_agm_decoder; +extern AVCodec ff_amv_encoder; +extern AVCodec ff_amv_decoder; +extern AVCodec ff_anm_decoder; +extern AVCodec ff_ansi_decoder; +extern AVCodec ff_apng_encoder; +extern AVCodec ff_apng_decoder; +extern AVCodec ff_arbc_decoder; +extern AVCodec ff_asv1_encoder; +extern AVCodec ff_asv1_decoder; +extern AVCodec ff_asv2_encoder; +extern AVCodec ff_asv2_decoder; +extern AVCodec ff_aura_decoder; +extern AVCodec ff_aura2_decoder; +extern AVCodec ff_avrp_encoder; +extern AVCodec ff_avrp_decoder; +extern AVCodec ff_avrn_decoder; +extern AVCodec ff_avs_decoder; +extern AVCodec ff_avui_encoder; +extern AVCodec ff_avui_decoder; +extern AVCodec ff_ayuv_encoder; +extern AVCodec ff_ayuv_decoder; +extern AVCodec ff_bethsoftvid_decoder; +extern AVCodec ff_bfi_decoder; +extern AVCodec ff_bink_decoder; +extern AVCodec ff_bitpacked_decoder; +extern AVCodec ff_bmp_encoder; +extern AVCodec ff_bmp_decoder; +extern AVCodec ff_bmv_video_decoder; +extern AVCodec ff_brender_pix_decoder; +extern AVCodec ff_c93_decoder; +extern AVCodec ff_cavs_decoder; +extern AVCodec ff_cdgraphics_decoder; +extern AVCodec ff_cdxl_decoder; +extern AVCodec ff_cfhd_decoder; +extern AVCodec ff_cinepak_encoder; +extern AVCodec ff_cinepak_decoder; +extern AVCodec ff_clearvideo_decoder; +extern AVCodec ff_cljr_encoder; +extern AVCodec ff_cljr_decoder; +extern AVCodec ff_cllc_decoder; +extern AVCodec ff_comfortnoise_encoder; +extern AVCodec ff_comfortnoise_decoder; +extern AVCodec ff_cpia_decoder; +extern AVCodec ff_cscd_decoder; +extern AVCodec ff_cyuv_decoder; +extern AVCodec ff_dds_decoder; +extern AVCodec ff_dfa_decoder; +extern AVCodec ff_dirac_decoder; +extern AVCodec ff_dnxhd_encoder; +extern AVCodec ff_dnxhd_decoder; +extern AVCodec ff_dpx_encoder; +extern AVCodec ff_dpx_decoder; +extern AVCodec ff_dsicinvideo_decoder; +extern AVCodec ff_dvaudio_decoder; +extern AVCodec ff_dvvideo_encoder; +extern AVCodec ff_dvvideo_decoder; +extern AVCodec ff_dxa_decoder; +extern AVCodec ff_dxtory_decoder; +extern AVCodec ff_dxv_decoder; +extern AVCodec ff_eacmv_decoder; +extern AVCodec ff_eamad_decoder; +extern AVCodec ff_eatgq_decoder; +extern AVCodec ff_eatgv_decoder; +extern AVCodec ff_eatqi_decoder; +extern AVCodec ff_eightbps_decoder; +extern AVCodec ff_eightsvx_exp_decoder; +extern AVCodec ff_eightsvx_fib_decoder; +extern AVCodec ff_escape124_decoder; +extern AVCodec ff_escape130_decoder; +extern AVCodec ff_exr_decoder; +extern AVCodec ff_ffv1_encoder; +extern AVCodec ff_ffv1_decoder; +extern AVCodec ff_ffvhuff_encoder; +extern AVCodec ff_ffvhuff_decoder; +extern AVCodec ff_fic_decoder; +extern AVCodec ff_fits_encoder; +extern AVCodec ff_fits_decoder; +extern AVCodec ff_flashsv_encoder; +extern AVCodec ff_flashsv_decoder; +extern AVCodec ff_flashsv2_encoder; +extern AVCodec ff_flashsv2_decoder; +extern AVCodec ff_flic_decoder; +extern AVCodec ff_flv_encoder; +extern AVCodec ff_flv_decoder; +extern AVCodec ff_fmvc_decoder; +extern AVCodec ff_fourxm_decoder; +extern AVCodec ff_fraps_decoder; +extern AVCodec ff_frwu_decoder; +extern AVCodec ff_g2m_decoder; +extern AVCodec ff_gdv_decoder; +extern AVCodec ff_gif_encoder; +extern AVCodec ff_gif_decoder; +extern AVCodec ff_h261_encoder; +extern AVCodec ff_h261_decoder; +extern AVCodec ff_h263_encoder; +extern AVCodec ff_h263_decoder; +extern AVCodec ff_h263i_decoder; +extern AVCodec ff_h263p_encoder; +extern AVCodec ff_h263p_decoder; +extern AVCodec ff_h263_v4l2m2m_decoder; +extern AVCodec ff_h264_decoder; +extern AVCodec ff_h264_crystalhd_decoder; +extern AVCodec ff_h264_v4l2m2m_decoder; +extern AVCodec ff_h264_mediacodec_decoder; +extern AVCodec ff_h264_mmal_decoder; +extern AVCodec ff_h264_qsv_decoder; +extern AVCodec ff_h264_rkmpp_decoder; +extern AVCodec ff_hap_encoder; +extern AVCodec ff_hap_decoder; +extern AVCodec ff_hevc_decoder; +extern AVCodec ff_hevc_qsv_decoder; +extern AVCodec ff_hevc_rkmpp_decoder; +extern AVCodec ff_hevc_v4l2m2m_decoder; +extern AVCodec ff_hnm4_video_decoder; +extern AVCodec ff_hq_hqa_decoder; +extern AVCodec ff_hqx_decoder; +extern AVCodec ff_huffyuv_encoder; +extern AVCodec ff_huffyuv_decoder; +extern AVCodec ff_hymt_decoder; +extern AVCodec ff_idcin_decoder; +extern AVCodec ff_iff_ilbm_decoder; +extern AVCodec ff_imm4_decoder; +extern AVCodec ff_indeo2_decoder; +extern AVCodec ff_indeo3_decoder; +extern AVCodec ff_indeo4_decoder; +extern AVCodec ff_indeo5_decoder; +extern AVCodec ff_interplay_video_decoder; +extern AVCodec ff_jpeg2000_encoder; +extern AVCodec ff_jpeg2000_decoder; +extern AVCodec ff_jpegls_encoder; +extern AVCodec ff_jpegls_decoder; +extern AVCodec ff_jv_decoder; +extern AVCodec ff_kgv1_decoder; +extern AVCodec ff_kmvc_decoder; +extern AVCodec ff_lagarith_decoder; +extern AVCodec ff_ljpeg_encoder; +extern AVCodec ff_loco_decoder; +extern AVCodec ff_lscr_decoder; +extern AVCodec ff_m101_decoder; +extern AVCodec ff_magicyuv_encoder; +extern AVCodec ff_magicyuv_decoder; +extern AVCodec ff_mdec_decoder; +extern AVCodec ff_mimic_decoder; +extern AVCodec ff_mjpeg_encoder; +extern AVCodec ff_mjpeg_decoder; +extern AVCodec ff_mjpegb_decoder; +extern AVCodec ff_mmvideo_decoder; +extern AVCodec ff_motionpixels_decoder; +extern AVCodec ff_mpeg1video_encoder; +extern AVCodec ff_mpeg1video_decoder; +extern AVCodec ff_mpeg2video_encoder; +extern AVCodec ff_mpeg2video_decoder; +extern AVCodec ff_mpeg4_encoder; +extern AVCodec ff_mpeg4_decoder; +extern AVCodec ff_mpeg4_crystalhd_decoder; +extern AVCodec ff_mpeg4_v4l2m2m_decoder; +extern AVCodec ff_mpeg4_mmal_decoder; +extern AVCodec ff_mpegvideo_decoder; +extern AVCodec ff_mpeg1_v4l2m2m_decoder; +extern AVCodec ff_mpeg2_mmal_decoder; +extern AVCodec ff_mpeg2_crystalhd_decoder; +extern AVCodec ff_mpeg2_v4l2m2m_decoder; +extern AVCodec ff_mpeg2_qsv_decoder; +extern AVCodec ff_mpeg2_mediacodec_decoder; +extern AVCodec ff_msa1_decoder; +extern AVCodec ff_mscc_decoder; +extern AVCodec ff_msmpeg4v1_decoder; +extern AVCodec ff_msmpeg4v2_encoder; +extern AVCodec ff_msmpeg4v2_decoder; +extern AVCodec ff_msmpeg4v3_encoder; +extern AVCodec ff_msmpeg4v3_decoder; +extern AVCodec ff_msmpeg4_crystalhd_decoder; +extern AVCodec ff_msrle_decoder; +extern AVCodec ff_mss1_decoder; +extern AVCodec ff_mss2_decoder; +extern AVCodec ff_msvideo1_encoder; +extern AVCodec ff_msvideo1_decoder; +extern AVCodec ff_mszh_decoder; +extern AVCodec ff_mts2_decoder; +extern AVCodec ff_mvc1_decoder; +extern AVCodec ff_mvc2_decoder; +extern AVCodec ff_mwsc_decoder; +extern AVCodec ff_mxpeg_decoder; +extern AVCodec ff_nuv_decoder; +extern AVCodec ff_paf_video_decoder; +extern AVCodec ff_pam_encoder; +extern AVCodec ff_pam_decoder; +extern AVCodec ff_pbm_encoder; +extern AVCodec ff_pbm_decoder; +extern AVCodec ff_pcx_encoder; +extern AVCodec ff_pcx_decoder; +extern AVCodec ff_pgm_encoder; +extern AVCodec ff_pgm_decoder; +extern AVCodec ff_pgmyuv_encoder; +extern AVCodec ff_pgmyuv_decoder; +extern AVCodec ff_pictor_decoder; +extern AVCodec ff_pixlet_decoder; +extern AVCodec ff_png_encoder; +extern AVCodec ff_png_decoder; +extern AVCodec ff_ppm_encoder; +extern AVCodec ff_ppm_decoder; +extern AVCodec ff_prores_encoder; +extern AVCodec ff_prores_decoder; +extern AVCodec ff_prores_aw_encoder; +extern AVCodec ff_prores_ks_encoder; +extern AVCodec ff_prosumer_decoder; +extern AVCodec ff_psd_decoder; +extern AVCodec ff_ptx_decoder; +extern AVCodec ff_qdraw_decoder; +extern AVCodec ff_qpeg_decoder; +extern AVCodec ff_qtrle_encoder; +extern AVCodec ff_qtrle_decoder; +extern AVCodec ff_r10k_encoder; +extern AVCodec ff_r10k_decoder; +extern AVCodec ff_r210_encoder; +extern AVCodec ff_r210_decoder; +extern AVCodec ff_rasc_decoder; +extern AVCodec ff_rawvideo_encoder; +extern AVCodec ff_rawvideo_decoder; +extern AVCodec ff_rl2_decoder; +extern AVCodec ff_roq_encoder; +extern AVCodec ff_roq_decoder; +extern AVCodec ff_rpza_decoder; +extern AVCodec ff_rscc_decoder; +extern AVCodec ff_rv10_encoder; +extern AVCodec ff_rv10_decoder; +extern AVCodec ff_rv20_encoder; +extern AVCodec ff_rv20_decoder; +extern AVCodec ff_rv30_decoder; +extern AVCodec ff_rv40_decoder; +extern AVCodec ff_s302m_encoder; +extern AVCodec ff_s302m_decoder; +extern AVCodec ff_sanm_decoder; +extern AVCodec ff_scpr_decoder; +extern AVCodec ff_screenpresso_decoder; +extern AVCodec ff_sdx2_dpcm_decoder; +extern AVCodec ff_sgi_encoder; +extern AVCodec ff_sgi_decoder; +extern AVCodec ff_sgirle_decoder; +extern AVCodec ff_sheervideo_decoder; +extern AVCodec ff_smacker_decoder; +extern AVCodec ff_smc_decoder; +extern AVCodec ff_smvjpeg_decoder; +extern AVCodec ff_snow_encoder; +extern AVCodec ff_snow_decoder; +extern AVCodec ff_sp5x_decoder; +extern AVCodec ff_speedhq_decoder; +extern AVCodec ff_srgc_decoder; +extern AVCodec ff_sunrast_encoder; +extern AVCodec ff_sunrast_decoder; +extern AVCodec ff_svq1_encoder; +extern AVCodec ff_svq1_decoder; +extern AVCodec ff_svq3_decoder; +extern AVCodec ff_targa_encoder; +extern AVCodec ff_targa_decoder; +extern AVCodec ff_targa_y216_decoder; +extern AVCodec ff_tdsc_decoder; +extern AVCodec ff_theora_decoder; +extern AVCodec ff_thp_decoder; +extern AVCodec ff_tiertexseqvideo_decoder; +extern AVCodec ff_tiff_encoder; +extern AVCodec ff_tiff_decoder; +extern AVCodec ff_tmv_decoder; +extern AVCodec ff_truemotion1_decoder; +extern AVCodec ff_truemotion2_decoder; +extern AVCodec ff_truemotion2rt_decoder; +extern AVCodec ff_tscc_decoder; +extern AVCodec ff_tscc2_decoder; +extern AVCodec ff_txd_decoder; +extern AVCodec ff_ulti_decoder; +extern AVCodec ff_utvideo_encoder; +extern AVCodec ff_utvideo_decoder; +extern AVCodec ff_v210_encoder; +extern AVCodec ff_v210_decoder; +extern AVCodec ff_v210x_decoder; +extern AVCodec ff_v308_encoder; +extern AVCodec ff_v308_decoder; +extern AVCodec ff_v408_encoder; +extern AVCodec ff_v408_decoder; +extern AVCodec ff_v410_encoder; +extern AVCodec ff_v410_decoder; +extern AVCodec ff_vb_decoder; +extern AVCodec ff_vble_decoder; +extern AVCodec ff_vc1_decoder; +extern AVCodec ff_vc1_crystalhd_decoder; +extern AVCodec ff_vc1image_decoder; +extern AVCodec ff_vc1_mmal_decoder; +extern AVCodec ff_vc1_qsv_decoder; +extern AVCodec ff_vc1_v4l2m2m_decoder; +extern AVCodec ff_vc2_encoder; +extern AVCodec ff_vcr1_decoder; +extern AVCodec ff_vmdvideo_decoder; +extern AVCodec ff_vmnc_decoder; +extern AVCodec ff_vp3_decoder; +extern AVCodec ff_vp4_decoder; +extern AVCodec ff_vp5_decoder; +extern AVCodec ff_vp6_decoder; +extern AVCodec ff_vp6a_decoder; +extern AVCodec ff_vp6f_decoder; +extern AVCodec ff_vp7_decoder; +extern AVCodec ff_vp8_decoder; +extern AVCodec ff_vp8_rkmpp_decoder; +extern AVCodec ff_vp8_v4l2m2m_decoder; +extern AVCodec ff_vp9_decoder; +extern AVCodec ff_vp9_rkmpp_decoder; +extern AVCodec ff_vp9_v4l2m2m_decoder; +extern AVCodec ff_vqa_decoder; +extern AVCodec ff_webp_decoder; +extern AVCodec ff_wcmv_decoder; +extern AVCodec ff_wrapped_avframe_encoder; +extern AVCodec ff_wrapped_avframe_decoder; +extern AVCodec ff_wmv1_encoder; +extern AVCodec ff_wmv1_decoder; +extern AVCodec ff_wmv2_encoder; +extern AVCodec ff_wmv2_decoder; +extern AVCodec ff_wmv3_decoder; +extern AVCodec ff_wmv3_crystalhd_decoder; +extern AVCodec ff_wmv3image_decoder; +extern AVCodec ff_wnv1_decoder; +extern AVCodec ff_xan_wc3_decoder; +extern AVCodec ff_xan_wc4_decoder; +extern AVCodec ff_xbm_encoder; +extern AVCodec ff_xbm_decoder; +extern AVCodec ff_xface_encoder; +extern AVCodec ff_xface_decoder; +extern AVCodec ff_xl_decoder; +extern AVCodec ff_xpm_decoder; +extern AVCodec ff_xwd_encoder; +extern AVCodec ff_xwd_decoder; +extern AVCodec ff_y41p_encoder; +extern AVCodec ff_y41p_decoder; +extern AVCodec ff_ylc_decoder; +extern AVCodec ff_yop_decoder; +extern AVCodec ff_yuv4_encoder; +extern AVCodec ff_yuv4_decoder; +extern AVCodec ff_zero12v_decoder; +extern AVCodec ff_zerocodec_decoder; +extern AVCodec ff_zlib_encoder; +extern AVCodec ff_zlib_decoder; +extern AVCodec ff_zmbv_encoder; +extern AVCodec ff_zmbv_decoder; + +/* audio codecs */ +extern AVCodec ff_aac_encoder; +extern AVCodec ff_aac_decoder; +extern AVCodec ff_aac_fixed_decoder; +extern AVCodec ff_aac_latm_decoder; +extern AVCodec ff_ac3_encoder; +extern AVCodec ff_ac3_decoder; +extern AVCodec ff_ac3_fixed_encoder; +extern AVCodec ff_ac3_fixed_decoder; +extern AVCodec ff_alac_encoder; +extern AVCodec ff_alac_decoder; +extern AVCodec ff_als_decoder; +extern AVCodec ff_amrnb_decoder; +extern AVCodec ff_amrwb_decoder; +extern AVCodec ff_ape_decoder; +extern AVCodec ff_aptx_encoder; +extern AVCodec ff_aptx_decoder; +extern AVCodec ff_aptx_hd_encoder; +extern AVCodec ff_aptx_hd_decoder; +extern AVCodec ff_atrac1_decoder; +extern AVCodec ff_atrac3_decoder; +extern AVCodec ff_atrac3al_decoder; +extern AVCodec ff_atrac3p_decoder; +extern AVCodec ff_atrac3pal_decoder; +extern AVCodec ff_atrac9_decoder; +extern AVCodec ff_binkaudio_dct_decoder; +extern AVCodec ff_binkaudio_rdft_decoder; +extern AVCodec ff_bmv_audio_decoder; +extern AVCodec ff_cook_decoder; +extern AVCodec ff_dca_encoder; +extern AVCodec ff_dca_decoder; +extern AVCodec ff_dolby_e_decoder; +extern AVCodec ff_dsd_lsbf_decoder; +extern AVCodec ff_dsd_msbf_decoder; +extern AVCodec ff_dsd_lsbf_planar_decoder; +extern AVCodec ff_dsd_msbf_planar_decoder; +extern AVCodec ff_dsicinaudio_decoder; +extern AVCodec ff_dss_sp_decoder; +extern AVCodec ff_dst_decoder; +extern AVCodec ff_eac3_encoder; +extern AVCodec ff_eac3_decoder; +extern AVCodec ff_evrc_decoder; +extern AVCodec ff_ffwavesynth_decoder; +extern AVCodec ff_flac_encoder; +extern AVCodec ff_flac_decoder; +extern AVCodec ff_g723_1_encoder; +extern AVCodec ff_g723_1_decoder; +extern AVCodec ff_g729_decoder; +extern AVCodec ff_gsm_decoder; +extern AVCodec ff_gsm_ms_decoder; +extern AVCodec ff_hcom_decoder; +extern AVCodec ff_iac_decoder; +extern AVCodec ff_ilbc_decoder; +extern AVCodec ff_imc_decoder; +extern AVCodec ff_interplay_acm_decoder; +extern AVCodec ff_mace3_decoder; +extern AVCodec ff_mace6_decoder; +extern AVCodec ff_metasound_decoder; +extern AVCodec ff_mlp_encoder; +extern AVCodec ff_mlp_decoder; +extern AVCodec ff_mp1_decoder; +extern AVCodec ff_mp1float_decoder; +extern AVCodec ff_mp2_encoder; +extern AVCodec ff_mp2_decoder; +extern AVCodec ff_mp2float_decoder; +extern AVCodec ff_mp2fixed_encoder; +extern AVCodec ff_mp3float_decoder; +extern AVCodec ff_mp3_decoder; +extern AVCodec ff_mp3adufloat_decoder; +extern AVCodec ff_mp3adu_decoder; +extern AVCodec ff_mp3on4float_decoder; +extern AVCodec ff_mp3on4_decoder; +extern AVCodec ff_mpc7_decoder; +extern AVCodec ff_mpc8_decoder; +extern AVCodec ff_nellymoser_encoder; +extern AVCodec ff_nellymoser_decoder; +extern AVCodec ff_on2avc_decoder; +extern AVCodec ff_opus_encoder; +extern AVCodec ff_opus_decoder; +extern AVCodec ff_paf_audio_decoder; +extern AVCodec ff_qcelp_decoder; +extern AVCodec ff_qdm2_decoder; +extern AVCodec ff_qdmc_decoder; +extern AVCodec ff_ra_144_encoder; +extern AVCodec ff_ra_144_decoder; +extern AVCodec ff_ra_288_decoder; +extern AVCodec ff_ralf_decoder; +extern AVCodec ff_sbc_encoder; +extern AVCodec ff_sbc_decoder; +extern AVCodec ff_shorten_decoder; +extern AVCodec ff_sipr_decoder; +extern AVCodec ff_smackaud_decoder; +extern AVCodec ff_sonic_encoder; +extern AVCodec ff_sonic_decoder; +extern AVCodec ff_sonic_ls_encoder; +extern AVCodec ff_tak_decoder; +extern AVCodec ff_truehd_encoder; +extern AVCodec ff_truehd_decoder; +extern AVCodec ff_truespeech_decoder; +extern AVCodec ff_tta_encoder; +extern AVCodec ff_tta_decoder; +extern AVCodec ff_twinvq_decoder; +extern AVCodec ff_vmdaudio_decoder; +extern AVCodec ff_vorbis_encoder; +extern AVCodec ff_vorbis_decoder; +extern AVCodec ff_wavpack_encoder; +extern AVCodec ff_wavpack_decoder; +extern AVCodec ff_wmalossless_decoder; +extern AVCodec ff_wmapro_decoder; +extern AVCodec ff_wmav1_encoder; +extern AVCodec ff_wmav1_decoder; +extern AVCodec ff_wmav2_encoder; +extern AVCodec ff_wmav2_decoder; +extern AVCodec ff_wmavoice_decoder; +extern AVCodec ff_ws_snd1_decoder; +extern AVCodec ff_xma1_decoder; +extern AVCodec ff_xma2_decoder; + +/* PCM codecs */ +extern AVCodec ff_pcm_alaw_encoder; +extern AVCodec ff_pcm_alaw_decoder; +extern AVCodec ff_pcm_bluray_decoder; +extern AVCodec ff_pcm_dvd_encoder; +extern AVCodec ff_pcm_dvd_decoder; +extern AVCodec ff_pcm_f16le_decoder; +extern AVCodec ff_pcm_f24le_decoder; +extern AVCodec ff_pcm_f32be_encoder; +extern AVCodec ff_pcm_f32be_decoder; +extern AVCodec ff_pcm_f32le_encoder; +extern AVCodec ff_pcm_f32le_decoder; +extern AVCodec ff_pcm_f64be_encoder; +extern AVCodec ff_pcm_f64be_decoder; +extern AVCodec ff_pcm_f64le_encoder; +extern AVCodec ff_pcm_f64le_decoder; +extern AVCodec ff_pcm_lxf_decoder; +extern AVCodec ff_pcm_mulaw_encoder; +extern AVCodec ff_pcm_mulaw_decoder; +extern AVCodec ff_pcm_s8_encoder; +extern AVCodec ff_pcm_s8_decoder; +extern AVCodec ff_pcm_s8_planar_encoder; +extern AVCodec ff_pcm_s8_planar_decoder; +extern AVCodec ff_pcm_s16be_encoder; +extern AVCodec ff_pcm_s16be_decoder; +extern AVCodec ff_pcm_s16be_planar_encoder; +extern AVCodec ff_pcm_s16be_planar_decoder; +extern AVCodec ff_pcm_s16le_encoder; +extern AVCodec ff_pcm_s16le_decoder; +extern AVCodec ff_pcm_s16le_planar_encoder; +extern AVCodec ff_pcm_s16le_planar_decoder; +extern AVCodec ff_pcm_s24be_encoder; +extern AVCodec ff_pcm_s24be_decoder; +extern AVCodec ff_pcm_s24daud_encoder; +extern AVCodec ff_pcm_s24daud_decoder; +extern AVCodec ff_pcm_s24le_encoder; +extern AVCodec ff_pcm_s24le_decoder; +extern AVCodec ff_pcm_s24le_planar_encoder; +extern AVCodec ff_pcm_s24le_planar_decoder; +extern AVCodec ff_pcm_s32be_encoder; +extern AVCodec ff_pcm_s32be_decoder; +extern AVCodec ff_pcm_s32le_encoder; +extern AVCodec ff_pcm_s32le_decoder; +extern AVCodec ff_pcm_s32le_planar_encoder; +extern AVCodec ff_pcm_s32le_planar_decoder; +extern AVCodec ff_pcm_s64be_encoder; +extern AVCodec ff_pcm_s64be_decoder; +extern AVCodec ff_pcm_s64le_encoder; +extern AVCodec ff_pcm_s64le_decoder; +extern AVCodec ff_pcm_u8_encoder; +extern AVCodec ff_pcm_u8_decoder; +extern AVCodec ff_pcm_u16be_encoder; +extern AVCodec ff_pcm_u16be_decoder; +extern AVCodec ff_pcm_u16le_encoder; +extern AVCodec ff_pcm_u16le_decoder; +extern AVCodec ff_pcm_u24be_encoder; +extern AVCodec ff_pcm_u24be_decoder; +extern AVCodec ff_pcm_u24le_encoder; +extern AVCodec ff_pcm_u24le_decoder; +extern AVCodec ff_pcm_u32be_encoder; +extern AVCodec ff_pcm_u32be_decoder; +extern AVCodec ff_pcm_u32le_encoder; +extern AVCodec ff_pcm_u32le_decoder; +extern AVCodec ff_pcm_vidc_encoder; +extern AVCodec ff_pcm_vidc_decoder; +extern AVCodec ff_pcm_zork_decoder; + +/* DPCM codecs */ +extern AVCodec ff_gremlin_dpcm_decoder; +extern AVCodec ff_interplay_dpcm_decoder; +extern AVCodec ff_roq_dpcm_encoder; +extern AVCodec ff_roq_dpcm_decoder; +extern AVCodec ff_sol_dpcm_decoder; +extern AVCodec ff_xan_dpcm_decoder; + +/* ADPCM codecs */ +extern AVCodec ff_adpcm_4xm_decoder; +extern AVCodec ff_adpcm_adx_encoder; +extern AVCodec ff_adpcm_adx_decoder; +extern AVCodec ff_adpcm_afc_decoder; +extern AVCodec ff_adpcm_agm_decoder; +extern AVCodec ff_adpcm_aica_decoder; +extern AVCodec ff_adpcm_ct_decoder; +extern AVCodec ff_adpcm_dtk_decoder; +extern AVCodec ff_adpcm_ea_decoder; +extern AVCodec ff_adpcm_ea_maxis_xa_decoder; +extern AVCodec ff_adpcm_ea_r1_decoder; +extern AVCodec ff_adpcm_ea_r2_decoder; +extern AVCodec ff_adpcm_ea_r3_decoder; +extern AVCodec ff_adpcm_ea_xas_decoder; +extern AVCodec ff_adpcm_g722_encoder; +extern AVCodec ff_adpcm_g722_decoder; +extern AVCodec ff_adpcm_g726_encoder; +extern AVCodec ff_adpcm_g726_decoder; +extern AVCodec ff_adpcm_g726le_encoder; +extern AVCodec ff_adpcm_g726le_decoder; +extern AVCodec ff_adpcm_ima_amv_decoder; +extern AVCodec ff_adpcm_ima_apc_decoder; +extern AVCodec ff_adpcm_ima_dat4_decoder; +extern AVCodec ff_adpcm_ima_dk3_decoder; +extern AVCodec ff_adpcm_ima_dk4_decoder; +extern AVCodec ff_adpcm_ima_ea_eacs_decoder; +extern AVCodec ff_adpcm_ima_ea_sead_decoder; +extern AVCodec ff_adpcm_ima_iss_decoder; +extern AVCodec ff_adpcm_ima_oki_decoder; +extern AVCodec ff_adpcm_ima_qt_encoder; +extern AVCodec ff_adpcm_ima_qt_decoder; +extern AVCodec ff_adpcm_ima_rad_decoder; +extern AVCodec ff_adpcm_ima_smjpeg_decoder; +extern AVCodec ff_adpcm_ima_wav_encoder; +extern AVCodec ff_adpcm_ima_wav_decoder; +extern AVCodec ff_adpcm_ima_ws_decoder; +extern AVCodec ff_adpcm_ms_encoder; +extern AVCodec ff_adpcm_ms_decoder; +extern AVCodec ff_adpcm_mtaf_decoder; +extern AVCodec ff_adpcm_psx_decoder; +extern AVCodec ff_adpcm_sbpro_2_decoder; +extern AVCodec ff_adpcm_sbpro_3_decoder; +extern AVCodec ff_adpcm_sbpro_4_decoder; +extern AVCodec ff_adpcm_swf_encoder; +extern AVCodec ff_adpcm_swf_decoder; +extern AVCodec ff_adpcm_thp_decoder; +extern AVCodec ff_adpcm_thp_le_decoder; +extern AVCodec ff_adpcm_vima_decoder; +extern AVCodec ff_adpcm_xa_decoder; +extern AVCodec ff_adpcm_yamaha_encoder; +extern AVCodec ff_adpcm_yamaha_decoder; + +/* subtitles */ +extern AVCodec ff_ssa_encoder; +extern AVCodec ff_ssa_decoder; +extern AVCodec ff_ass_encoder; +extern AVCodec ff_ass_decoder; +extern AVCodec ff_ccaption_decoder; +extern AVCodec ff_dvbsub_encoder; +extern AVCodec ff_dvbsub_decoder; +extern AVCodec ff_dvdsub_encoder; +extern AVCodec ff_dvdsub_decoder; +extern AVCodec ff_jacosub_decoder; +extern AVCodec ff_microdvd_decoder; +extern AVCodec ff_movtext_encoder; +extern AVCodec ff_movtext_decoder; +extern AVCodec ff_mpl2_decoder; +extern AVCodec ff_pgssub_decoder; +extern AVCodec ff_pjs_decoder; +extern AVCodec ff_realtext_decoder; +extern AVCodec ff_sami_decoder; +extern AVCodec ff_srt_encoder; +extern AVCodec ff_srt_decoder; +extern AVCodec ff_stl_decoder; +extern AVCodec ff_subrip_encoder; +extern AVCodec ff_subrip_decoder; +extern AVCodec ff_subviewer_decoder; +extern AVCodec ff_subviewer1_decoder; +extern AVCodec ff_text_encoder; +extern AVCodec ff_text_decoder; +extern AVCodec ff_vplayer_decoder; +extern AVCodec ff_webvtt_encoder; +extern AVCodec ff_webvtt_decoder; +extern AVCodec ff_xsub_encoder; +extern AVCodec ff_xsub_decoder; + +/* external libraries */ +extern AVCodec ff_aac_at_encoder; +extern AVCodec ff_aac_at_decoder; +extern AVCodec ff_ac3_at_decoder; +extern AVCodec ff_adpcm_ima_qt_at_decoder; +extern AVCodec ff_alac_at_encoder; +extern AVCodec ff_alac_at_decoder; +extern AVCodec ff_amr_nb_at_decoder; +extern AVCodec ff_eac3_at_decoder; +extern AVCodec ff_gsm_ms_at_decoder; +extern AVCodec ff_ilbc_at_encoder; +extern AVCodec ff_ilbc_at_decoder; +extern AVCodec ff_mp1_at_decoder; +extern AVCodec ff_mp2_at_decoder; +extern AVCodec ff_mp3_at_decoder; +extern AVCodec ff_pcm_alaw_at_encoder; +extern AVCodec ff_pcm_alaw_at_decoder; +extern AVCodec ff_pcm_mulaw_at_encoder; +extern AVCodec ff_pcm_mulaw_at_decoder; +extern AVCodec ff_qdmc_at_decoder; +extern AVCodec ff_qdm2_at_decoder; +extern AVCodec ff_libaom_av1_decoder; +extern AVCodec ff_libaom_av1_encoder; +extern AVCodec ff_libaribb24_decoder; +extern AVCodec ff_libcelt_decoder; +extern AVCodec ff_libcodec2_encoder; +extern AVCodec ff_libcodec2_decoder; +extern AVCodec ff_libdav1d_decoder; +extern AVCodec ff_libdavs2_decoder; +extern AVCodec ff_libfdk_aac_encoder; +extern AVCodec ff_libfdk_aac_decoder; +extern AVCodec ff_libgsm_encoder; +extern AVCodec ff_libgsm_decoder; +extern AVCodec ff_libgsm_ms_encoder; +extern AVCodec ff_libgsm_ms_decoder; +extern AVCodec ff_libilbc_encoder; +extern AVCodec ff_libilbc_decoder; +extern AVCodec ff_libmp3lame_encoder; +extern AVCodec ff_libopencore_amrnb_encoder; +extern AVCodec ff_libopencore_amrnb_decoder; +extern AVCodec ff_libopencore_amrwb_decoder; +extern AVCodec ff_libopenjpeg_encoder; +extern AVCodec ff_libopenjpeg_decoder; +extern AVCodec ff_libopus_encoder; +extern AVCodec ff_libopus_decoder; +extern AVCodec ff_librsvg_decoder; +extern AVCodec ff_libshine_encoder; +extern AVCodec ff_libspeex_encoder; +extern AVCodec ff_libspeex_decoder; +extern AVCodec ff_libtheora_encoder; +extern AVCodec ff_libtwolame_encoder; +extern AVCodec ff_libvo_amrwbenc_encoder; +extern AVCodec ff_libvorbis_encoder; +extern AVCodec ff_libvorbis_decoder; +extern AVCodec ff_libvpx_vp8_encoder; +extern AVCodec ff_libvpx_vp8_decoder; +extern AVCodec ff_libvpx_vp9_encoder; +extern AVCodec ff_libvpx_vp9_decoder; +extern AVCodec ff_libwavpack_encoder; +/* preferred over libwebp */ +extern AVCodec ff_libwebp_anim_encoder; +extern AVCodec ff_libwebp_encoder; +extern AVCodec ff_libx262_encoder; +extern AVCodec ff_libx264_encoder; +extern AVCodec ff_libx264rgb_encoder; +extern AVCodec ff_libx265_encoder; +extern AVCodec ff_libxavs_encoder; +extern AVCodec ff_libxavs2_encoder; +extern AVCodec ff_libxvid_encoder; +extern AVCodec ff_libzvbi_teletext_decoder; + +/* text */ +extern AVCodec ff_bintext_decoder; +extern AVCodec ff_xbin_decoder; +extern AVCodec ff_idf_decoder; + +/* external libraries, that shouldn't be used by default if one of the + * above is available */ +extern AVCodec ff_h263_v4l2m2m_encoder; +extern AVCodec ff_libopenh264_encoder; +extern AVCodec ff_libopenh264_decoder; +extern AVCodec ff_h264_amf_encoder; +extern AVCodec ff_h264_cuvid_decoder; +extern AVCodec ff_h264_nvenc_encoder; +extern AVCodec ff_h264_omx_encoder; +extern AVCodec ff_h264_qsv_encoder; +extern AVCodec ff_h264_v4l2m2m_encoder; +extern AVCodec ff_h264_vaapi_encoder; +extern AVCodec ff_h264_videotoolbox_encoder; +#if FF_API_NVENC_OLD_NAME +extern AVCodec ff_nvenc_encoder; +extern AVCodec ff_nvenc_h264_encoder; +extern AVCodec ff_nvenc_hevc_encoder; +#endif +extern AVCodec ff_hevc_amf_encoder; +extern AVCodec ff_hevc_cuvid_decoder; +extern AVCodec ff_hevc_mediacodec_decoder; +extern AVCodec ff_hevc_nvenc_encoder; +extern AVCodec ff_hevc_qsv_encoder; +extern AVCodec ff_hevc_v4l2m2m_encoder; +extern AVCodec ff_hevc_vaapi_encoder; +extern AVCodec ff_hevc_videotoolbox_encoder; +extern AVCodec ff_libkvazaar_encoder; +extern AVCodec ff_mjpeg_cuvid_decoder; +extern AVCodec ff_mjpeg_qsv_encoder; +extern AVCodec ff_mjpeg_vaapi_encoder; +extern AVCodec ff_mpeg1_cuvid_decoder; +extern AVCodec ff_mpeg2_cuvid_decoder; +extern AVCodec ff_mpeg2_qsv_encoder; +extern AVCodec ff_mpeg2_vaapi_encoder; +extern AVCodec ff_mpeg4_cuvid_decoder; +extern AVCodec ff_mpeg4_mediacodec_decoder; +extern AVCodec ff_mpeg4_v4l2m2m_encoder; +extern AVCodec ff_vc1_cuvid_decoder; +extern AVCodec ff_vp8_cuvid_decoder; +extern AVCodec ff_vp8_mediacodec_decoder; +extern AVCodec ff_vp8_qsv_decoder; +extern AVCodec ff_vp8_v4l2m2m_encoder; +extern AVCodec ff_vp8_vaapi_encoder; +extern AVCodec ff_vp9_cuvid_decoder; +extern AVCodec ff_vp9_mediacodec_decoder; +extern AVCodec ff_vp9_vaapi_encoder; + +// The iterate API is not usable with ossfuzz due to the excessive size of binaries created +#if CONFIG_OSSFUZZ +AVCodec * codec_list[] = { + NULL, + NULL +}; +#else +#include "libavcodec/codec_list.c" +#endif + +static AVOnce av_codec_static_init = AV_ONCE_INIT; +static void av_codec_init_static(void) +{ + for (int i = 0; codec_list[i]; i++) { + if (codec_list[i]->init_static_data) + codec_list[i]->init_static_data((AVCodec*)codec_list[i]); + } +} + +const AVCodec *av_codec_iterate(void **opaque) +{ + uintptr_t i = (uintptr_t)*opaque; + const AVCodec *c = codec_list[i]; + + ff_thread_once(&av_codec_static_init, av_codec_init_static); + + if (c) + *opaque = (void*)(i + 1); + + return c; +} + +#if FF_API_NEXT +FF_DISABLE_DEPRECATION_WARNINGS +static AVOnce av_codec_next_init = AV_ONCE_INIT; + +static void av_codec_init_next(void) +{ + AVCodec *prev = NULL, *p; + void *i = 0; + while ((p = (AVCodec*)av_codec_iterate(&i))) { + if (prev) + prev->next = p; + prev = p; + } +} + + + +av_cold void avcodec_register(AVCodec *codec) +{ + ff_thread_once(&av_codec_next_init, av_codec_init_next); +} + +AVCodec *av_codec_next(const AVCodec *c) +{ + ff_thread_once(&av_codec_next_init, av_codec_init_next); + + if (c) + return c->next; + else + return (AVCodec*)codec_list[0]; +} + +void avcodec_register_all(void) +{ + ff_thread_once(&av_codec_next_init, av_codec_init_next); +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +static enum AVCodecID remap_deprecated_codec_id(enum AVCodecID id) +{ + switch(id){ + //This is for future deprecatec codec ids, its empty since + //last major bump but will fill up again over time, please don't remove it + default : return id; + } +} + +static AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *)) +{ + const AVCodec *p, *experimental = NULL; + void *i = 0; + + id = remap_deprecated_codec_id(id); + + while ((p = av_codec_iterate(&i))) { + if (!x(p)) + continue; + if (p->id == id) { + if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) { + experimental = p; + } else + return (AVCodec*)p; + } + } + + return (AVCodec*)experimental; +} + +AVCodec *avcodec_find_encoder(enum AVCodecID id) +{ + return find_codec(id, av_codec_is_encoder); +} + +AVCodec *avcodec_find_decoder(enum AVCodecID id) +{ + return find_codec(id, av_codec_is_decoder); +} + +static AVCodec *find_codec_by_name(const char *name, int (*x)(const AVCodec *)) +{ + void *i = 0; + const AVCodec *p; + + if (!name) + return NULL; + + while ((p = av_codec_iterate(&i))) { + if (!x(p)) + continue; + if (strcmp(name, p->name) == 0) + return (AVCodec*)p; + } + + return NULL; +} + +AVCodec *avcodec_find_encoder_by_name(const char *name) +{ + return find_codec_by_name(name, av_codec_is_encoder); +} + +AVCodec *avcodec_find_decoder_by_name(const char *name) +{ + return find_codec_by_name(name, av_codec_is_decoder); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/audio_frame_queue.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/audio_frame_queue.c new file mode 100644 index 000000000..f2ccd6928 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/audio_frame_queue.c @@ -0,0 +1,113 @@ +/* + * Audio Frame Queue + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/common.h" +#include "audio_frame_queue.h" +#include "internal.h" +#include "libavutil/avassert.h" + +av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq) +{ + afq->avctx = avctx; + afq->remaining_delay = avctx->initial_padding; + afq->remaining_samples = avctx->initial_padding; + afq->frame_count = 0; +} + +void ff_af_queue_close(AudioFrameQueue *afq) +{ + if(afq->frame_count) + av_log(afq->avctx, AV_LOG_WARNING, "%d frames left in the queue on closing\n", afq->frame_count); + av_freep(&afq->frames); + memset(afq, 0, sizeof(*afq)); +} + +int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f) +{ + AudioFrame *new = av_fast_realloc(afq->frames, &afq->frame_alloc, sizeof(*afq->frames)*(afq->frame_count+1)); + if(!new) + return AVERROR(ENOMEM); + afq->frames = new; + new += afq->frame_count; + + /* get frame parameters */ + new->duration = f->nb_samples; + new->duration += afq->remaining_delay; + if (f->pts != AV_NOPTS_VALUE) { + new->pts = av_rescale_q(f->pts, + afq->avctx->time_base, + (AVRational){ 1, afq->avctx->sample_rate }); + new->pts -= afq->remaining_delay; + if(afq->frame_count && new[-1].pts >= new->pts) + av_log(afq->avctx, AV_LOG_WARNING, "Queue input is backward in time\n"); + } else { + new->pts = AV_NOPTS_VALUE; + } + afq->remaining_delay = 0; + + /* add frame sample count */ + afq->remaining_samples += f->nb_samples; + + afq->frame_count++; + + return 0; +} + +void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts, + int64_t *duration) +{ + int64_t out_pts = AV_NOPTS_VALUE; + int removed_samples = 0; + int i; + + if (afq->frame_count || afq->frame_alloc) { + if (afq->frames->pts != AV_NOPTS_VALUE) + out_pts = afq->frames->pts; + } + if(!afq->frame_count) + av_log(afq->avctx, AV_LOG_WARNING, "Trying to remove %d samples, but the queue is empty\n", nb_samples); + if (pts) + *pts = ff_samples_to_time_base(afq->avctx, out_pts); + + for(i=0; nb_samples && iframe_count; i++){ + int n= FFMIN(afq->frames[i].duration, nb_samples); + afq->frames[i].duration -= n; + nb_samples -= n; + removed_samples += n; + if(afq->frames[i].pts != AV_NOPTS_VALUE) + afq->frames[i].pts += n; + } + afq->remaining_samples -= removed_samples; + i -= i && afq->frames[i-1].duration; + memmove(afq->frames, afq->frames + i, sizeof(*afq->frames) * (afq->frame_count - i)); + afq->frame_count -= i; + + if(nb_samples){ + av_assert0(!afq->frame_count); + av_assert0(afq->remaining_samples == afq->remaining_delay); + if(afq->frames && afq->frames[0].pts != AV_NOPTS_VALUE) + afq->frames[0].pts += nb_samples; + av_log(afq->avctx, AV_LOG_DEBUG, "Trying to remove %d more samples than there are in the queue\n", nb_samples); + } + if (duration) + *duration = ff_samples_to_time_base(afq->avctx, removed_samples); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/audio_frame_queue.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/audio_frame_queue.h new file mode 100644 index 000000000..d8076eae5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/audio_frame_queue.h @@ -0,0 +1,83 @@ +/* + * Audio Frame Queue + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AUDIO_FRAME_QUEUE_H +#define AVCODEC_AUDIO_FRAME_QUEUE_H + +#include "avcodec.h" + +typedef struct AudioFrame { + int64_t pts; + int duration; +} AudioFrame; + +typedef struct AudioFrameQueue { + AVCodecContext *avctx; + int remaining_delay; + int remaining_samples; + AudioFrame *frames; + unsigned frame_count; + unsigned frame_alloc; +} AudioFrameQueue; + +/** + * Initialize AudioFrameQueue. + * + * @param avctx context to use for time_base and av_log + * @param afq queue context + */ +void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq); + +/** + * Close AudioFrameQueue. + * + * Frees memory if needed. + * + * @param afq queue context + */ +void ff_af_queue_close(AudioFrameQueue *afq); + +/** + * Add a frame to the queue. + * + * @param afq queue context + * @param f frame to add to the queue + */ +int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f); + +/** + * Remove frame(s) from the queue. + * + * Retrieves the pts of the next available frame, or a generated pts based on + * the last frame duration if there are no frames left in the queue. The number + * of requested samples should be the full number of samples represented by the + * packet that will be output by the encoder. If fewer samples are available + * in the queue, a smaller value will be used for the output duration. + * + * @param afq queue context + * @param nb_samples number of samples to remove from the queue + * @param[out] pts output packet pts + * @param[out] duration output packet duration + */ +void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts, + int64_t *duration); + +#endif /* AVCODEC_AUDIO_FRAME_QUEUE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avcodec.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avcodec.h new file mode 100644 index 000000000..d234271c5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avcodec.h @@ -0,0 +1,6228 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVCODEC_H +#define AVCODEC_AVCODEC_H + +/** + * @file + * @ingroup libavc + * Libavcodec external API header + */ + +#include +#include "libavutil/samplefmt.h" +#include "libavutil/attributes.h" +#include "libavutil/avutil.h" +#include "libavutil/buffer.h" +#include "libavutil/cpu.h" +#include "libavutil/channel_layout.h" +#include "libavutil/dict.h" +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/log.h" +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" + +#include "version.h" + +/** + * @defgroup libavc libavcodec + * Encoding/Decoding Library + * + * @{ + * + * @defgroup lavc_decoding Decoding + * @{ + * @} + * + * @defgroup lavc_encoding Encoding + * @{ + * @} + * + * @defgroup lavc_codec Codecs + * @{ + * @defgroup lavc_codec_native Native Codecs + * @{ + * @} + * @defgroup lavc_codec_wrappers External library wrappers + * @{ + * @} + * @defgroup lavc_codec_hwaccel Hardware Accelerators bridge + * @{ + * @} + * @} + * @defgroup lavc_internal Internal + * @{ + * @} + * @} + */ + +/** + * @ingroup libavc + * @defgroup lavc_encdec send/receive encoding and decoding API overview + * @{ + * + * The avcodec_send_packet()/avcodec_receive_frame()/avcodec_send_frame()/ + * avcodec_receive_packet() functions provide an encode/decode API, which + * decouples input and output. + * + * The API is very similar for encoding/decoding and audio/video, and works as + * follows: + * - Set up and open the AVCodecContext as usual. + * - Send valid input: + * - For decoding, call avcodec_send_packet() to give the decoder raw + * compressed data in an AVPacket. + * - For encoding, call avcodec_send_frame() to give the encoder an AVFrame + * containing uncompressed audio or video. + * In both cases, it is recommended that AVPackets and AVFrames are + * refcounted, or libavcodec might have to copy the input data. (libavformat + * always returns refcounted AVPackets, and av_frame_get_buffer() allocates + * refcounted AVFrames.) + * - Receive output in a loop. Periodically call one of the avcodec_receive_*() + * functions and process their output: + * - For decoding, call avcodec_receive_frame(). On success, it will return + * an AVFrame containing uncompressed audio or video data. + * - For encoding, call avcodec_receive_packet(). On success, it will return + * an AVPacket with a compressed frame. + * Repeat this call until it returns AVERROR(EAGAIN) or an error. The + * AVERROR(EAGAIN) return value means that new input data is required to + * return new output. In this case, continue with sending input. For each + * input frame/packet, the codec will typically return 1 output frame/packet, + * but it can also be 0 or more than 1. + * + * At the beginning of decoding or encoding, the codec might accept multiple + * input frames/packets without returning a frame, until its internal buffers + * are filled. This situation is handled transparently if you follow the steps + * outlined above. + * + * In theory, sending input can result in EAGAIN - this should happen only if + * not all output was received. You can use this to structure alternative decode + * or encode loops other than the one suggested above. For example, you could + * try sending new input on each iteration, and try to receive output if that + * returns EAGAIN. + * + * End of stream situations. These require "flushing" (aka draining) the codec, + * as the codec might buffer multiple frames or packets internally for + * performance or out of necessity (consider B-frames). + * This is handled as follows: + * - Instead of valid input, send NULL to the avcodec_send_packet() (decoding) + * or avcodec_send_frame() (encoding) functions. This will enter draining + * mode. + * - Call avcodec_receive_frame() (decoding) or avcodec_receive_packet() + * (encoding) in a loop until AVERROR_EOF is returned. The functions will + * not return AVERROR(EAGAIN), unless you forgot to enter draining mode. + * - Before decoding can be resumed again, the codec has to be reset with + * avcodec_flush_buffers(). + * + * Using the API as outlined above is highly recommended. But it is also + * possible to call functions outside of this rigid schema. For example, you can + * call avcodec_send_packet() repeatedly without calling + * avcodec_receive_frame(). In this case, avcodec_send_packet() will succeed + * until the codec's internal buffer has been filled up (which is typically of + * size 1 per output frame, after initial input), and then reject input with + * AVERROR(EAGAIN). Once it starts rejecting input, you have no choice but to + * read at least some output. + * + * Not all codecs will follow a rigid and predictable dataflow; the only + * guarantee is that an AVERROR(EAGAIN) return value on a send/receive call on + * one end implies that a receive/send call on the other end will succeed, or + * at least will not fail with AVERROR(EAGAIN). In general, no codec will + * permit unlimited buffering of input or output. + * + * This API replaces the following legacy functions: + * - avcodec_decode_video2() and avcodec_decode_audio4(): + * Use avcodec_send_packet() to feed input to the decoder, then use + * avcodec_receive_frame() to receive decoded frames after each packet. + * Unlike with the old video decoding API, multiple frames might result from + * a packet. For audio, splitting the input packet into frames by partially + * decoding packets becomes transparent to the API user. You never need to + * feed an AVPacket to the API twice (unless it is rejected with AVERROR(EAGAIN) - then + * no data was read from the packet). + * Additionally, sending a flush/draining packet is required only once. + * - avcodec_encode_video2()/avcodec_encode_audio2(): + * Use avcodec_send_frame() to feed input to the encoder, then use + * avcodec_receive_packet() to receive encoded packets. + * Providing user-allocated buffers for avcodec_receive_packet() is not + * possible. + * - The new API does not handle subtitles yet. + * + * Mixing new and old function calls on the same AVCodecContext is not allowed, + * and will result in undefined behavior. + * + * Some codecs might require using the new API; using the old API will return + * an error when calling it. All codecs support the new API. + * + * A codec is not allowed to return AVERROR(EAGAIN) for both sending and receiving. This + * would be an invalid state, which could put the codec user into an endless + * loop. The API has no concept of time either: it cannot happen that trying to + * do avcodec_send_packet() results in AVERROR(EAGAIN), but a repeated call 1 second + * later accepts the packet (with no other receive/flush API calls involved). + * The API is a strict state machine, and the passage of time is not supposed + * to influence it. Some timing-dependent behavior might still be deemed + * acceptable in certain cases. But it must never result in both send/receive + * returning EAGAIN at the same time at any point. It must also absolutely be + * avoided that the current state is "unstable" and can "flip-flop" between + * the send/receive APIs allowing progress. For example, it's not allowed that + * the codec randomly decides that it actually wants to consume a packet now + * instead of returning a frame, after it just returned AVERROR(EAGAIN) on an + * avcodec_send_packet() call. + * @} + */ + +/** + * @defgroup lavc_core Core functions/structures. + * @ingroup libavc + * + * Basic definitions, functions for querying libavcodec capabilities, + * allocating core structures, etc. + * @{ + */ + + +/** + * Identify the syntax and semantics of the bitstream. + * The principle is roughly: + * Two decoders with the same ID can decode the same streams. + * Two encoders with the same ID can encode compatible streams. + * There may be slight deviations from the principle due to implementation + * details. + * + * If you add a codec ID to this list, add it so that + * 1. no value of an existing codec ID changes (that would break ABI), + * 2. it is as close as possible to similar codecs + * + * After adding new codec IDs, do not forget to add an entry to the codec + * descriptor list and bump libavcodec minor version. + */ +enum AVCodecID { + AV_CODEC_ID_NONE, + + /* video codecs */ + AV_CODEC_ID_MPEG1VIDEO, + AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding + AV_CODEC_ID_H261, + AV_CODEC_ID_H263, + AV_CODEC_ID_RV10, + AV_CODEC_ID_RV20, + AV_CODEC_ID_MJPEG, + AV_CODEC_ID_MJPEGB, + AV_CODEC_ID_LJPEG, + AV_CODEC_ID_SP5X, + AV_CODEC_ID_JPEGLS, + AV_CODEC_ID_MPEG4, + AV_CODEC_ID_RAWVIDEO, + AV_CODEC_ID_MSMPEG4V1, + AV_CODEC_ID_MSMPEG4V2, + AV_CODEC_ID_MSMPEG4V3, + AV_CODEC_ID_WMV1, + AV_CODEC_ID_WMV2, + AV_CODEC_ID_H263P, + AV_CODEC_ID_H263I, + AV_CODEC_ID_FLV1, + AV_CODEC_ID_SVQ1, + AV_CODEC_ID_SVQ3, + AV_CODEC_ID_DVVIDEO, + AV_CODEC_ID_HUFFYUV, + AV_CODEC_ID_CYUV, + AV_CODEC_ID_H264, + AV_CODEC_ID_INDEO3, + AV_CODEC_ID_VP3, + AV_CODEC_ID_THEORA, + AV_CODEC_ID_ASV1, + AV_CODEC_ID_ASV2, + AV_CODEC_ID_FFV1, + AV_CODEC_ID_4XM, + AV_CODEC_ID_VCR1, + AV_CODEC_ID_CLJR, + AV_CODEC_ID_MDEC, + AV_CODEC_ID_ROQ, + AV_CODEC_ID_INTERPLAY_VIDEO, + AV_CODEC_ID_XAN_WC3, + AV_CODEC_ID_XAN_WC4, + AV_CODEC_ID_RPZA, + AV_CODEC_ID_CINEPAK, + AV_CODEC_ID_WS_VQA, + AV_CODEC_ID_MSRLE, + AV_CODEC_ID_MSVIDEO1, + AV_CODEC_ID_IDCIN, + AV_CODEC_ID_8BPS, + AV_CODEC_ID_SMC, + AV_CODEC_ID_FLIC, + AV_CODEC_ID_TRUEMOTION1, + AV_CODEC_ID_VMDVIDEO, + AV_CODEC_ID_MSZH, + AV_CODEC_ID_ZLIB, + AV_CODEC_ID_QTRLE, + AV_CODEC_ID_TSCC, + AV_CODEC_ID_ULTI, + AV_CODEC_ID_QDRAW, + AV_CODEC_ID_VIXL, + AV_CODEC_ID_QPEG, + AV_CODEC_ID_PNG, + AV_CODEC_ID_PPM, + AV_CODEC_ID_PBM, + AV_CODEC_ID_PGM, + AV_CODEC_ID_PGMYUV, + AV_CODEC_ID_PAM, + AV_CODEC_ID_FFVHUFF, + AV_CODEC_ID_RV30, + AV_CODEC_ID_RV40, + AV_CODEC_ID_VC1, + AV_CODEC_ID_WMV3, + AV_CODEC_ID_LOCO, + AV_CODEC_ID_WNV1, + AV_CODEC_ID_AASC, + AV_CODEC_ID_INDEO2, + AV_CODEC_ID_FRAPS, + AV_CODEC_ID_TRUEMOTION2, + AV_CODEC_ID_BMP, + AV_CODEC_ID_CSCD, + AV_CODEC_ID_MMVIDEO, + AV_CODEC_ID_ZMBV, + AV_CODEC_ID_AVS, + AV_CODEC_ID_SMACKVIDEO, + AV_CODEC_ID_NUV, + AV_CODEC_ID_KMVC, + AV_CODEC_ID_FLASHSV, + AV_CODEC_ID_CAVS, + AV_CODEC_ID_JPEG2000, + AV_CODEC_ID_VMNC, + AV_CODEC_ID_VP5, + AV_CODEC_ID_VP6, + AV_CODEC_ID_VP6F, + AV_CODEC_ID_TARGA, + AV_CODEC_ID_DSICINVIDEO, + AV_CODEC_ID_TIERTEXSEQVIDEO, + AV_CODEC_ID_TIFF, + AV_CODEC_ID_GIF, + AV_CODEC_ID_DXA, + AV_CODEC_ID_DNXHD, + AV_CODEC_ID_THP, + AV_CODEC_ID_SGI, + AV_CODEC_ID_C93, + AV_CODEC_ID_BETHSOFTVID, + AV_CODEC_ID_PTX, + AV_CODEC_ID_TXD, + AV_CODEC_ID_VP6A, + AV_CODEC_ID_AMV, + AV_CODEC_ID_VB, + AV_CODEC_ID_PCX, + AV_CODEC_ID_SUNRAST, + AV_CODEC_ID_INDEO4, + AV_CODEC_ID_INDEO5, + AV_CODEC_ID_MIMIC, + AV_CODEC_ID_RL2, + AV_CODEC_ID_ESCAPE124, + AV_CODEC_ID_DIRAC, + AV_CODEC_ID_BFI, + AV_CODEC_ID_CMV, + AV_CODEC_ID_MOTIONPIXELS, + AV_CODEC_ID_TGV, + AV_CODEC_ID_TGQ, + AV_CODEC_ID_TQI, + AV_CODEC_ID_AURA, + AV_CODEC_ID_AURA2, + AV_CODEC_ID_V210X, + AV_CODEC_ID_TMV, + AV_CODEC_ID_V210, + AV_CODEC_ID_DPX, + AV_CODEC_ID_MAD, + AV_CODEC_ID_FRWU, + AV_CODEC_ID_FLASHSV2, + AV_CODEC_ID_CDGRAPHICS, + AV_CODEC_ID_R210, + AV_CODEC_ID_ANM, + AV_CODEC_ID_BINKVIDEO, + AV_CODEC_ID_IFF_ILBM, +#define AV_CODEC_ID_IFF_BYTERUN1 AV_CODEC_ID_IFF_ILBM + AV_CODEC_ID_KGV1, + AV_CODEC_ID_YOP, + AV_CODEC_ID_VP8, + AV_CODEC_ID_PICTOR, + AV_CODEC_ID_ANSI, + AV_CODEC_ID_A64_MULTI, + AV_CODEC_ID_A64_MULTI5, + AV_CODEC_ID_R10K, + AV_CODEC_ID_MXPEG, + AV_CODEC_ID_LAGARITH, + AV_CODEC_ID_PRORES, + AV_CODEC_ID_JV, + AV_CODEC_ID_DFA, + AV_CODEC_ID_WMV3IMAGE, + AV_CODEC_ID_VC1IMAGE, + AV_CODEC_ID_UTVIDEO, + AV_CODEC_ID_BMV_VIDEO, + AV_CODEC_ID_VBLE, + AV_CODEC_ID_DXTORY, + AV_CODEC_ID_V410, + AV_CODEC_ID_XWD, + AV_CODEC_ID_CDXL, + AV_CODEC_ID_XBM, + AV_CODEC_ID_ZEROCODEC, + AV_CODEC_ID_MSS1, + AV_CODEC_ID_MSA1, + AV_CODEC_ID_TSCC2, + AV_CODEC_ID_MTS2, + AV_CODEC_ID_CLLC, + AV_CODEC_ID_MSS2, + AV_CODEC_ID_VP9, + AV_CODEC_ID_AIC, + AV_CODEC_ID_ESCAPE130, + AV_CODEC_ID_G2M, + AV_CODEC_ID_WEBP, + AV_CODEC_ID_HNM4_VIDEO, + AV_CODEC_ID_HEVC, +#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC + AV_CODEC_ID_FIC, + AV_CODEC_ID_ALIAS_PIX, + AV_CODEC_ID_BRENDER_PIX, + AV_CODEC_ID_PAF_VIDEO, + AV_CODEC_ID_EXR, + AV_CODEC_ID_VP7, + AV_CODEC_ID_SANM, + AV_CODEC_ID_SGIRLE, + AV_CODEC_ID_MVC1, + AV_CODEC_ID_MVC2, + AV_CODEC_ID_HQX, + AV_CODEC_ID_TDSC, + AV_CODEC_ID_HQ_HQA, + AV_CODEC_ID_HAP, + AV_CODEC_ID_DDS, + AV_CODEC_ID_DXV, + AV_CODEC_ID_SCREENPRESSO, + AV_CODEC_ID_RSCC, + AV_CODEC_ID_AVS2, + + AV_CODEC_ID_Y41P = 0x8000, + AV_CODEC_ID_AVRP, + AV_CODEC_ID_012V, + AV_CODEC_ID_AVUI, + AV_CODEC_ID_AYUV, + AV_CODEC_ID_TARGA_Y216, + AV_CODEC_ID_V308, + AV_CODEC_ID_V408, + AV_CODEC_ID_YUV4, + AV_CODEC_ID_AVRN, + AV_CODEC_ID_CPIA, + AV_CODEC_ID_XFACE, + AV_CODEC_ID_SNOW, + AV_CODEC_ID_SMVJPEG, + AV_CODEC_ID_APNG, + AV_CODEC_ID_DAALA, + AV_CODEC_ID_CFHD, + AV_CODEC_ID_TRUEMOTION2RT, + AV_CODEC_ID_M101, + AV_CODEC_ID_MAGICYUV, + AV_CODEC_ID_SHEERVIDEO, + AV_CODEC_ID_YLC, + AV_CODEC_ID_PSD, + AV_CODEC_ID_PIXLET, + AV_CODEC_ID_SPEEDHQ, + AV_CODEC_ID_FMVC, + AV_CODEC_ID_SCPR, + AV_CODEC_ID_CLEARVIDEO, + AV_CODEC_ID_XPM, + AV_CODEC_ID_AV1, + AV_CODEC_ID_BITPACKED, + AV_CODEC_ID_MSCC, + AV_CODEC_ID_SRGC, + AV_CODEC_ID_SVG, + AV_CODEC_ID_GDV, + AV_CODEC_ID_FITS, + AV_CODEC_ID_IMM4, + AV_CODEC_ID_PROSUMER, + AV_CODEC_ID_MWSC, + AV_CODEC_ID_WCMV, + AV_CODEC_ID_RASC, + AV_CODEC_ID_HYMT, + AV_CODEC_ID_ARBC, + AV_CODEC_ID_AGM, + AV_CODEC_ID_LSCR, + AV_CODEC_ID_VP4, + + /* various PCM "codecs" */ + AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs + AV_CODEC_ID_PCM_S16LE = 0x10000, + AV_CODEC_ID_PCM_S16BE, + AV_CODEC_ID_PCM_U16LE, + AV_CODEC_ID_PCM_U16BE, + AV_CODEC_ID_PCM_S8, + AV_CODEC_ID_PCM_U8, + AV_CODEC_ID_PCM_MULAW, + AV_CODEC_ID_PCM_ALAW, + AV_CODEC_ID_PCM_S32LE, + AV_CODEC_ID_PCM_S32BE, + AV_CODEC_ID_PCM_U32LE, + AV_CODEC_ID_PCM_U32BE, + AV_CODEC_ID_PCM_S24LE, + AV_CODEC_ID_PCM_S24BE, + AV_CODEC_ID_PCM_U24LE, + AV_CODEC_ID_PCM_U24BE, + AV_CODEC_ID_PCM_S24DAUD, + AV_CODEC_ID_PCM_ZORK, + AV_CODEC_ID_PCM_S16LE_PLANAR, + AV_CODEC_ID_PCM_DVD, + AV_CODEC_ID_PCM_F32BE, + AV_CODEC_ID_PCM_F32LE, + AV_CODEC_ID_PCM_F64BE, + AV_CODEC_ID_PCM_F64LE, + AV_CODEC_ID_PCM_BLURAY, + AV_CODEC_ID_PCM_LXF, + AV_CODEC_ID_S302M, + AV_CODEC_ID_PCM_S8_PLANAR, + AV_CODEC_ID_PCM_S24LE_PLANAR, + AV_CODEC_ID_PCM_S32LE_PLANAR, + AV_CODEC_ID_PCM_S16BE_PLANAR, + + AV_CODEC_ID_PCM_S64LE = 0x10800, + AV_CODEC_ID_PCM_S64BE, + AV_CODEC_ID_PCM_F16LE, + AV_CODEC_ID_PCM_F24LE, + AV_CODEC_ID_PCM_VIDC, + + /* various ADPCM codecs */ + AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, + AV_CODEC_ID_ADPCM_IMA_WAV, + AV_CODEC_ID_ADPCM_IMA_DK3, + AV_CODEC_ID_ADPCM_IMA_DK4, + AV_CODEC_ID_ADPCM_IMA_WS, + AV_CODEC_ID_ADPCM_IMA_SMJPEG, + AV_CODEC_ID_ADPCM_MS, + AV_CODEC_ID_ADPCM_4XM, + AV_CODEC_ID_ADPCM_XA, + AV_CODEC_ID_ADPCM_ADX, + AV_CODEC_ID_ADPCM_EA, + AV_CODEC_ID_ADPCM_G726, + AV_CODEC_ID_ADPCM_CT, + AV_CODEC_ID_ADPCM_SWF, + AV_CODEC_ID_ADPCM_YAMAHA, + AV_CODEC_ID_ADPCM_SBPRO_4, + AV_CODEC_ID_ADPCM_SBPRO_3, + AV_CODEC_ID_ADPCM_SBPRO_2, + AV_CODEC_ID_ADPCM_THP, + AV_CODEC_ID_ADPCM_IMA_AMV, + AV_CODEC_ID_ADPCM_EA_R1, + AV_CODEC_ID_ADPCM_EA_R3, + AV_CODEC_ID_ADPCM_EA_R2, + AV_CODEC_ID_ADPCM_IMA_EA_SEAD, + AV_CODEC_ID_ADPCM_IMA_EA_EACS, + AV_CODEC_ID_ADPCM_EA_XAS, + AV_CODEC_ID_ADPCM_EA_MAXIS_XA, + AV_CODEC_ID_ADPCM_IMA_ISS, + AV_CODEC_ID_ADPCM_G722, + AV_CODEC_ID_ADPCM_IMA_APC, + AV_CODEC_ID_ADPCM_VIMA, + + AV_CODEC_ID_ADPCM_AFC = 0x11800, + AV_CODEC_ID_ADPCM_IMA_OKI, + AV_CODEC_ID_ADPCM_DTK, + AV_CODEC_ID_ADPCM_IMA_RAD, + AV_CODEC_ID_ADPCM_G726LE, + AV_CODEC_ID_ADPCM_THP_LE, + AV_CODEC_ID_ADPCM_PSX, + AV_CODEC_ID_ADPCM_AICA, + AV_CODEC_ID_ADPCM_IMA_DAT4, + AV_CODEC_ID_ADPCM_MTAF, + AV_CODEC_ID_ADPCM_AGM, + + /* AMR */ + AV_CODEC_ID_AMR_NB = 0x12000, + AV_CODEC_ID_AMR_WB, + + /* RealAudio codecs*/ + AV_CODEC_ID_RA_144 = 0x13000, + AV_CODEC_ID_RA_288, + + /* various DPCM codecs */ + AV_CODEC_ID_ROQ_DPCM = 0x14000, + AV_CODEC_ID_INTERPLAY_DPCM, + AV_CODEC_ID_XAN_DPCM, + AV_CODEC_ID_SOL_DPCM, + + AV_CODEC_ID_SDX2_DPCM = 0x14800, + AV_CODEC_ID_GREMLIN_DPCM, + + /* audio codecs */ + AV_CODEC_ID_MP2 = 0x15000, + AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 + AV_CODEC_ID_AAC, + AV_CODEC_ID_AC3, + AV_CODEC_ID_DTS, + AV_CODEC_ID_VORBIS, + AV_CODEC_ID_DVAUDIO, + AV_CODEC_ID_WMAV1, + AV_CODEC_ID_WMAV2, + AV_CODEC_ID_MACE3, + AV_CODEC_ID_MACE6, + AV_CODEC_ID_VMDAUDIO, + AV_CODEC_ID_FLAC, + AV_CODEC_ID_MP3ADU, + AV_CODEC_ID_MP3ON4, + AV_CODEC_ID_SHORTEN, + AV_CODEC_ID_ALAC, + AV_CODEC_ID_WESTWOOD_SND1, + AV_CODEC_ID_GSM, ///< as in Berlin toast format + AV_CODEC_ID_QDM2, + AV_CODEC_ID_COOK, + AV_CODEC_ID_TRUESPEECH, + AV_CODEC_ID_TTA, + AV_CODEC_ID_SMACKAUDIO, + AV_CODEC_ID_QCELP, + AV_CODEC_ID_WAVPACK, + AV_CODEC_ID_DSICINAUDIO, + AV_CODEC_ID_IMC, + AV_CODEC_ID_MUSEPACK7, + AV_CODEC_ID_MLP, + AV_CODEC_ID_GSM_MS, /* as found in WAV */ + AV_CODEC_ID_ATRAC3, + AV_CODEC_ID_APE, + AV_CODEC_ID_NELLYMOSER, + AV_CODEC_ID_MUSEPACK8, + AV_CODEC_ID_SPEEX, + AV_CODEC_ID_WMAVOICE, + AV_CODEC_ID_WMAPRO, + AV_CODEC_ID_WMALOSSLESS, + AV_CODEC_ID_ATRAC3P, + AV_CODEC_ID_EAC3, + AV_CODEC_ID_SIPR, + AV_CODEC_ID_MP1, + AV_CODEC_ID_TWINVQ, + AV_CODEC_ID_TRUEHD, + AV_CODEC_ID_MP4ALS, + AV_CODEC_ID_ATRAC1, + AV_CODEC_ID_BINKAUDIO_RDFT, + AV_CODEC_ID_BINKAUDIO_DCT, + AV_CODEC_ID_AAC_LATM, + AV_CODEC_ID_QDMC, + AV_CODEC_ID_CELT, + AV_CODEC_ID_G723_1, + AV_CODEC_ID_G729, + AV_CODEC_ID_8SVX_EXP, + AV_CODEC_ID_8SVX_FIB, + AV_CODEC_ID_BMV_AUDIO, + AV_CODEC_ID_RALF, + AV_CODEC_ID_IAC, + AV_CODEC_ID_ILBC, + AV_CODEC_ID_OPUS, + AV_CODEC_ID_COMFORT_NOISE, + AV_CODEC_ID_TAK, + AV_CODEC_ID_METASOUND, + AV_CODEC_ID_PAF_AUDIO, + AV_CODEC_ID_ON2AVC, + AV_CODEC_ID_DSS_SP, + AV_CODEC_ID_CODEC2, + + AV_CODEC_ID_FFWAVESYNTH = 0x15800, + AV_CODEC_ID_SONIC, + AV_CODEC_ID_SONIC_LS, + AV_CODEC_ID_EVRC, + AV_CODEC_ID_SMV, + AV_CODEC_ID_DSD_LSBF, + AV_CODEC_ID_DSD_MSBF, + AV_CODEC_ID_DSD_LSBF_PLANAR, + AV_CODEC_ID_DSD_MSBF_PLANAR, + AV_CODEC_ID_4GV, + AV_CODEC_ID_INTERPLAY_ACM, + AV_CODEC_ID_XMA1, + AV_CODEC_ID_XMA2, + AV_CODEC_ID_DST, + AV_CODEC_ID_ATRAC3AL, + AV_CODEC_ID_ATRAC3PAL, + AV_CODEC_ID_DOLBY_E, + AV_CODEC_ID_APTX, + AV_CODEC_ID_APTX_HD, + AV_CODEC_ID_SBC, + AV_CODEC_ID_ATRAC9, + AV_CODEC_ID_HCOM, + + /* subtitle codecs */ + AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. + AV_CODEC_ID_DVD_SUBTITLE = 0x17000, + AV_CODEC_ID_DVB_SUBTITLE, + AV_CODEC_ID_TEXT, ///< raw UTF-8 text + AV_CODEC_ID_XSUB, + AV_CODEC_ID_SSA, + AV_CODEC_ID_MOV_TEXT, + AV_CODEC_ID_HDMV_PGS_SUBTITLE, + AV_CODEC_ID_DVB_TELETEXT, + AV_CODEC_ID_SRT, + + AV_CODEC_ID_MICRODVD = 0x17800, + AV_CODEC_ID_EIA_608, + AV_CODEC_ID_JACOSUB, + AV_CODEC_ID_SAMI, + AV_CODEC_ID_REALTEXT, + AV_CODEC_ID_STL, + AV_CODEC_ID_SUBVIEWER1, + AV_CODEC_ID_SUBVIEWER, + AV_CODEC_ID_SUBRIP, + AV_CODEC_ID_WEBVTT, + AV_CODEC_ID_MPL2, + AV_CODEC_ID_VPLAYER, + AV_CODEC_ID_PJS, + AV_CODEC_ID_ASS, + AV_CODEC_ID_HDMV_TEXT_SUBTITLE, + AV_CODEC_ID_TTML, + AV_CODEC_ID_ARIB_CAPTION, + + /* other specific kind of codecs (generally used for attachments) */ + AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. + AV_CODEC_ID_TTF = 0x18000, + + AV_CODEC_ID_SCTE_35, ///< Contain timestamp estimated through PCR of program stream. + AV_CODEC_ID_BINTEXT = 0x18800, + AV_CODEC_ID_XBIN, + AV_CODEC_ID_IDF, + AV_CODEC_ID_OTF, + AV_CODEC_ID_SMPTE_KLV, + AV_CODEC_ID_DVD_NAV, + AV_CODEC_ID_TIMED_ID3, + AV_CODEC_ID_BIN_DATA, + + + AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it + + AV_CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS + * stream (only used by libavformat) */ + AV_CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems + * stream (only used by libavformat) */ + AV_CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information. + AV_CODEC_ID_WRAPPED_AVFRAME = 0x21001, ///< Passthrough codec, AVFrames wrapped in AVPacket +}; + +/** + * This struct describes the properties of a single codec described by an + * AVCodecID. + * @see avcodec_descriptor_get() + */ +typedef struct AVCodecDescriptor { + enum AVCodecID id; + enum AVMediaType type; + /** + * Name of the codec described by this descriptor. It is non-empty and + * unique for each codec descriptor. It should contain alphanumeric + * characters and '_' only. + */ + const char *name; + /** + * A more descriptive name for this codec. May be NULL. + */ + const char *long_name; + /** + * Codec properties, a combination of AV_CODEC_PROP_* flags. + */ + int props; + /** + * MIME type(s) associated with the codec. + * May be NULL; if not, a NULL-terminated array of MIME types. + * The first item is always non-NULL and is the preferred MIME type. + */ + const char *const *mime_types; + /** + * If non-NULL, an array of profiles recognized for this codec. + * Terminated with FF_PROFILE_UNKNOWN. + */ + const struct AVProfile *profiles; +} AVCodecDescriptor; + +/** + * Codec uses only intra compression. + * Video and audio codecs only. + */ +#define AV_CODEC_PROP_INTRA_ONLY (1 << 0) +/** + * Codec supports lossy compression. Audio and video codecs only. + * @note a codec may support both lossy and lossless + * compression modes + */ +#define AV_CODEC_PROP_LOSSY (1 << 1) +/** + * Codec supports lossless compression. Audio and video codecs only. + */ +#define AV_CODEC_PROP_LOSSLESS (1 << 2) +/** + * Codec supports frame reordering. That is, the coded order (the order in which + * the encoded packets are output by the encoders / stored / input to the + * decoders) may be different from the presentation order of the corresponding + * frames. + * + * For codecs that do not have this property set, PTS and DTS should always be + * equal. + */ +#define AV_CODEC_PROP_REORDER (1 << 3) +/** + * Subtitle codec is bitmap based + * Decoded AVSubtitle data can be read from the AVSubtitleRect->pict field. + */ +#define AV_CODEC_PROP_BITMAP_SUB (1 << 16) +/** + * Subtitle codec is text based. + * Decoded AVSubtitle data can be read from the AVSubtitleRect->ass field. + */ +#define AV_CODEC_PROP_TEXT_SUB (1 << 17) + +/** + * @ingroup lavc_decoding + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * This is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end.
      + * Note: If the first 23 bits of the additional bytes are not 0, then damaged + * MPEG bitstreams could cause overread and segfault. + */ +#define AV_INPUT_BUFFER_PADDING_SIZE 64 + +/** + * @ingroup lavc_encoding + * minimum encoding buffer size + * Used to avoid some checks during header writing. + */ +#define AV_INPUT_BUFFER_MIN_SIZE 16384 + +/** + * @ingroup lavc_decoding + */ +enum AVDiscard{ + /* We leave some space between them for extensions (drop some + * keyframes for intra-only or drop just some bidir frames). */ + AVDISCARD_NONE =-16, ///< discard nothing + AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi + AVDISCARD_NONREF = 8, ///< discard all non reference + AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames + AVDISCARD_NONINTRA= 24, ///< discard all non intra frames + AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes + AVDISCARD_ALL = 48, ///< discard all +}; + +enum AVAudioServiceType { + AV_AUDIO_SERVICE_TYPE_MAIN = 0, + AV_AUDIO_SERVICE_TYPE_EFFECTS = 1, + AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2, + AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3, + AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4, + AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5, + AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6, + AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7, + AV_AUDIO_SERVICE_TYPE_KARAOKE = 8, + AV_AUDIO_SERVICE_TYPE_NB , ///< Not part of ABI +}; + +/** + * @ingroup lavc_encoding + */ +typedef struct RcOverride{ + int start_frame; + int end_frame; + int qscale; // If this is 0 then quality_factor will be used instead. + float quality_factor; +} RcOverride; + +/* encoding support + These flags can be passed in AVCodecContext.flags before initialization. + Note: Not everything is supported yet. +*/ + +/** + * Allow decoders to produce frames with data planes that are not aligned + * to CPU requirements (e.g. due to cropping). + */ +#define AV_CODEC_FLAG_UNALIGNED (1 << 0) +/** + * Use fixed qscale. + */ +#define AV_CODEC_FLAG_QSCALE (1 << 1) +/** + * 4 MV per MB allowed / advanced prediction for H.263. + */ +#define AV_CODEC_FLAG_4MV (1 << 2) +/** + * Output even those frames that might be corrupted. + */ +#define AV_CODEC_FLAG_OUTPUT_CORRUPT (1 << 3) +/** + * Use qpel MC. + */ +#define AV_CODEC_FLAG_QPEL (1 << 4) +/** + * Don't output frames whose parameters differ from first + * decoded frame in stream. + */ +#define AV_CODEC_FLAG_DROPCHANGED (1 << 5) +/** + * Use internal 2pass ratecontrol in first pass mode. + */ +#define AV_CODEC_FLAG_PASS1 (1 << 9) +/** + * Use internal 2pass ratecontrol in second pass mode. + */ +#define AV_CODEC_FLAG_PASS2 (1 << 10) +/** + * loop filter. + */ +#define AV_CODEC_FLAG_LOOP_FILTER (1 << 11) +/** + * Only decode/encode grayscale. + */ +#define AV_CODEC_FLAG_GRAY (1 << 13) +/** + * error[?] variables will be set during encoding. + */ +#define AV_CODEC_FLAG_PSNR (1 << 15) +/** + * Input bitstream might be truncated at a random location + * instead of only at frame boundaries. + */ +#define AV_CODEC_FLAG_TRUNCATED (1 << 16) +/** + * Use interlaced DCT. + */ +#define AV_CODEC_FLAG_INTERLACED_DCT (1 << 18) +/** + * Force low delay. + */ +#define AV_CODEC_FLAG_LOW_DELAY (1 << 19) +/** + * Place global headers in extradata instead of every keyframe. + */ +#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22) +/** + * Use only bitexact stuff (except (I)DCT). + */ +#define AV_CODEC_FLAG_BITEXACT (1 << 23) +/* Fx : Flag for H.263+ extra options */ +/** + * H.263 advanced intra coding / MPEG-4 AC prediction + */ +#define AV_CODEC_FLAG_AC_PRED (1 << 24) +/** + * interlaced motion estimation + */ +#define AV_CODEC_FLAG_INTERLACED_ME (1 << 29) +#define AV_CODEC_FLAG_CLOSED_GOP (1U << 31) + +/** + * Allow non spec compliant speedup tricks. + */ +#define AV_CODEC_FLAG2_FAST (1 << 0) +/** + * Skip bitstream encoding. + */ +#define AV_CODEC_FLAG2_NO_OUTPUT (1 << 2) +/** + * Place global headers at every keyframe instead of in extradata. + */ +#define AV_CODEC_FLAG2_LOCAL_HEADER (1 << 3) + +/** + * timecode is in drop frame format. DEPRECATED!!!! + */ +#define AV_CODEC_FLAG2_DROP_FRAME_TIMECODE (1 << 13) + +/** + * Input bitstream might be truncated at a packet boundaries + * instead of only at frame boundaries. + */ +#define AV_CODEC_FLAG2_CHUNKS (1 << 15) +/** + * Discard cropping information from SPS. + */ +#define AV_CODEC_FLAG2_IGNORE_CROP (1 << 16) + +/** + * Show all frames before the first keyframe + */ +#define AV_CODEC_FLAG2_SHOW_ALL (1 << 22) +/** + * Export motion vectors through frame side data + */ +#define AV_CODEC_FLAG2_EXPORT_MVS (1 << 28) +/** + * Do not skip samples and export skip information as frame side data + */ +#define AV_CODEC_FLAG2_SKIP_MANUAL (1 << 29) +/** + * Do not reset ASS ReadOrder field on flush (subtitles decoding) + */ +#define AV_CODEC_FLAG2_RO_FLUSH_NOOP (1 << 30) + +/* Unsupported options : + * Syntax Arithmetic coding (SAC) + * Reference Picture Selection + * Independent Segment Decoding */ +/* /Fx */ +/* codec capabilities */ + +/** + * Decoder can use draw_horiz_band callback. + */ +#define AV_CODEC_CAP_DRAW_HORIZ_BAND (1 << 0) +/** + * Codec uses get_buffer() for allocating buffers and supports custom allocators. + * If not set, it might not use get_buffer() at all or use operations that + * assume the buffer was allocated by avcodec_default_get_buffer. + */ +#define AV_CODEC_CAP_DR1 (1 << 1) +#define AV_CODEC_CAP_TRUNCATED (1 << 3) +/** + * Encoder or decoder requires flushing with NULL input at the end in order to + * give the complete and correct output. + * + * NOTE: If this flag is not set, the codec is guaranteed to never be fed with + * with NULL data. The user can still send NULL data to the public encode + * or decode function, but libavcodec will not pass it along to the codec + * unless this flag is set. + * + * Decoders: + * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL, + * avpkt->size=0 at the end to get the delayed data until the decoder no longer + * returns frames. + * + * Encoders: + * The encoder needs to be fed with NULL data at the end of encoding until the + * encoder no longer returns data. + * + * NOTE: For encoders implementing the AVCodec.encode2() function, setting this + * flag also means that the encoder must set the pts and duration for + * each output packet. If this flag is not set, the pts and duration will + * be determined by libavcodec from the input frame. + */ +#define AV_CODEC_CAP_DELAY (1 << 5) +/** + * Codec can be fed a final frame with a smaller size. + * This can be used to prevent truncation of the last audio samples. + */ +#define AV_CODEC_CAP_SMALL_LAST_FRAME (1 << 6) + +/** + * Codec can output multiple frames per AVPacket + * Normally demuxers return one frame at a time, demuxers which do not do + * are connected to a parser to split what they return into proper frames. + * This flag is reserved to the very rare category of codecs which have a + * bitstream that cannot be split into frames without timeconsuming + * operations like full decoding. Demuxers carrying such bitstreams thus + * may return multiple frames in a packet. This has many disadvantages like + * prohibiting stream copy in many cases thus it should only be considered + * as a last resort. + */ +#define AV_CODEC_CAP_SUBFRAMES (1 << 8) +/** + * Codec is experimental and is thus avoided in favor of non experimental + * encoders + */ +#define AV_CODEC_CAP_EXPERIMENTAL (1 << 9) +/** + * Codec should fill in channel configuration and samplerate instead of container + */ +#define AV_CODEC_CAP_CHANNEL_CONF (1 << 10) +/** + * Codec supports frame-level multithreading. + */ +#define AV_CODEC_CAP_FRAME_THREADS (1 << 12) +/** + * Codec supports slice-based (or partition-based) multithreading. + */ +#define AV_CODEC_CAP_SLICE_THREADS (1 << 13) +/** + * Codec supports changed parameters at any point. + */ +#define AV_CODEC_CAP_PARAM_CHANGE (1 << 14) +/** + * Codec supports avctx->thread_count == 0 (auto). + */ +#define AV_CODEC_CAP_AUTO_THREADS (1 << 15) +/** + * Audio encoder supports receiving a different number of samples in each call. + */ +#define AV_CODEC_CAP_VARIABLE_FRAME_SIZE (1 << 16) +/** + * Decoder is not a preferred choice for probing. + * This indicates that the decoder is not a good choice for probing. + * It could for example be an expensive to spin up hardware decoder, + * or it could simply not provide a lot of useful information about + * the stream. + * A decoder marked with this flag should only be used as last resort + * choice for probing. + */ +#define AV_CODEC_CAP_AVOID_PROBING (1 << 17) +/** + * Codec is intra only. + */ +#define AV_CODEC_CAP_INTRA_ONLY 0x40000000 +/** + * Codec is lossless. + */ +#define AV_CODEC_CAP_LOSSLESS 0x80000000 + +/** + * Codec is backed by a hardware implementation. Typically used to + * identify a non-hwaccel hardware decoder. For information about hwaccels, use + * avcodec_get_hw_config() instead. + */ +#define AV_CODEC_CAP_HARDWARE (1 << 18) + +/** + * Codec is potentially backed by a hardware implementation, but not + * necessarily. This is used instead of AV_CODEC_CAP_HARDWARE, if the + * implementation provides some sort of internal fallback. + */ +#define AV_CODEC_CAP_HYBRID (1 << 19) + +/** + * This codec takes the reordered_opaque field from input AVFrames + * and returns it in the corresponding field in AVCodecContext after + * encoding. + */ +#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 20) + +/** + * Pan Scan area. + * This specifies the area which should be displayed. + * Note there may be multiple such areas for one frame. + */ +typedef struct AVPanScan { + /** + * id + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int id; + + /** + * width and height in 1/16 pel + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int width; + int height; + + /** + * position of the top left corner in 1/16 pel for up to 3 fields/frames + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int16_t position[3][2]; +} AVPanScan; + +/** + * This structure describes the bitrate properties of an encoded bitstream. It + * roughly corresponds to a subset the VBV parameters for MPEG-2 or HRD + * parameters for H.264/HEVC. + */ +typedef struct AVCPBProperties { + /** + * Maximum bitrate of the stream, in bits per second. + * Zero if unknown or unspecified. + */ +#if FF_API_UNSANITIZED_BITRATES + int max_bitrate; +#else + int64_t max_bitrate; +#endif + /** + * Minimum bitrate of the stream, in bits per second. + * Zero if unknown or unspecified. + */ +#if FF_API_UNSANITIZED_BITRATES + int min_bitrate; +#else + int64_t min_bitrate; +#endif + /** + * Average bitrate of the stream, in bits per second. + * Zero if unknown or unspecified. + */ +#if FF_API_UNSANITIZED_BITRATES + int avg_bitrate; +#else + int64_t avg_bitrate; +#endif + + /** + * The size of the buffer to which the ratecontrol is applied, in bits. + * Zero if unknown or unspecified. + */ + int buffer_size; + + /** + * The delay between the time the packet this structure is associated with + * is received and the time when it should be decoded, in periods of a 27MHz + * clock. + * + * UINT64_MAX when unknown or unspecified. + */ + uint64_t vbv_delay; +} AVCPBProperties; + +/** + * The decoder will keep a reference to the frame and may reuse it later. + */ +#define AV_GET_BUFFER_FLAG_REF (1 << 0) + +/** + * @defgroup lavc_packet AVPacket + * + * Types and functions for working with AVPacket. + * @{ + */ +enum AVPacketSideDataType { + /** + * An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE + * bytes worth of palette. This side data signals that a new palette is + * present. + */ + AV_PKT_DATA_PALETTE, + + /** + * The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format + * that the extradata buffer was changed and the receiving side should + * act upon it appropriately. The new extradata is embedded in the side + * data buffer and should be immediately used for processing the current + * frame or packet. + */ + AV_PKT_DATA_NEW_EXTRADATA, + + /** + * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows: + * @code + * u32le param_flags + * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) + * s32le channel_count + * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) + * u64le channel_layout + * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) + * s32le sample_rate + * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) + * s32le width + * s32le height + * @endcode + */ + AV_PKT_DATA_PARAM_CHANGE, + + /** + * An AV_PKT_DATA_H263_MB_INFO side data packet contains a number of + * structures with info about macroblocks relevant to splitting the + * packet into smaller packets on macroblock edges (e.g. as for RFC 2190). + * That is, it does not necessarily contain info about all macroblocks, + * as long as the distance between macroblocks in the info is smaller + * than the target payload size. + * Each MB info structure is 12 bytes, and is laid out as follows: + * @code + * u32le bit offset from the start of the packet + * u8 current quantizer at the start of the macroblock + * u8 GOB number + * u16le macroblock address within the GOB + * u8 horizontal MV predictor + * u8 vertical MV predictor + * u8 horizontal MV predictor for block number 3 + * u8 vertical MV predictor for block number 3 + * @endcode + */ + AV_PKT_DATA_H263_MB_INFO, + + /** + * This side data should be associated with an audio stream and contains + * ReplayGain information in form of the AVReplayGain struct. + */ + AV_PKT_DATA_REPLAYGAIN, + + /** + * This side data contains a 3x3 transformation matrix describing an affine + * transformation that needs to be applied to the decoded video frames for + * correct presentation. + * + * See libavutil/display.h for a detailed description of the data. + */ + AV_PKT_DATA_DISPLAYMATRIX, + + /** + * This side data should be associated with a video stream and contains + * Stereoscopic 3D information in form of the AVStereo3D struct. + */ + AV_PKT_DATA_STEREO3D, + + /** + * This side data should be associated with an audio stream and corresponds + * to enum AVAudioServiceType. + */ + AV_PKT_DATA_AUDIO_SERVICE_TYPE, + + /** + * This side data contains quality related information from the encoder. + * @code + * u32le quality factor of the compressed frame. Allowed range is between 1 (good) and FF_LAMBDA_MAX (bad). + * u8 picture type + * u8 error count + * u16 reserved + * u64le[error count] sum of squared differences between encoder in and output + * @endcode + */ + AV_PKT_DATA_QUALITY_STATS, + + /** + * This side data contains an integer value representing the stream index + * of a "fallback" track. A fallback track indicates an alternate + * track to use when the current track can not be decoded for some reason. + * e.g. no decoder available for codec. + */ + AV_PKT_DATA_FALLBACK_TRACK, + + /** + * This side data corresponds to the AVCPBProperties struct. + */ + AV_PKT_DATA_CPB_PROPERTIES, + + /** + * Recommmends skipping the specified number of samples + * @code + * u32le number of samples to skip from start of this packet + * u32le number of samples to skip from end of this packet + * u8 reason for start skip + * u8 reason for end skip (0=padding silence, 1=convergence) + * @endcode + */ + AV_PKT_DATA_SKIP_SAMPLES, + + /** + * An AV_PKT_DATA_JP_DUALMONO side data packet indicates that + * the packet may contain "dual mono" audio specific to Japanese DTV + * and if it is true, recommends only the selected channel to be used. + * @code + * u8 selected channels (0=mail/left, 1=sub/right, 2=both) + * @endcode + */ + AV_PKT_DATA_JP_DUALMONO, + + /** + * A list of zero terminated key/value strings. There is no end marker for + * the list, so it is required to rely on the side data size to stop. + */ + AV_PKT_DATA_STRINGS_METADATA, + + /** + * Subtitle event position + * @code + * u32le x1 + * u32le y1 + * u32le x2 + * u32le y2 + * @endcode + */ + AV_PKT_DATA_SUBTITLE_POSITION, + + /** + * Data found in BlockAdditional element of matroska container. There is + * no end marker for the data, so it is required to rely on the side data + * size to recognize the end. 8 byte id (as found in BlockAddId) followed + * by data. + */ + AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, + + /** + * The optional first identifier line of a WebVTT cue. + */ + AV_PKT_DATA_WEBVTT_IDENTIFIER, + + /** + * The optional settings (rendering instructions) that immediately + * follow the timestamp specifier of a WebVTT cue. + */ + AV_PKT_DATA_WEBVTT_SETTINGS, + + /** + * A list of zero terminated key/value strings. There is no end marker for + * the list, so it is required to rely on the side data size to stop. This + * side data includes updated metadata which appeared in the stream. + */ + AV_PKT_DATA_METADATA_UPDATE, + + /** + * MPEGTS stream ID as uint8_t, this is required to pass the stream ID + * information from the demuxer to the corresponding muxer. + */ + AV_PKT_DATA_MPEGTS_STREAM_ID, + + /** + * Mastering display metadata (based on SMPTE-2086:2014). This metadata + * should be associated with a video stream and contains data in the form + * of the AVMasteringDisplayMetadata struct. + */ + AV_PKT_DATA_MASTERING_DISPLAY_METADATA, + + /** + * This side data should be associated with a video stream and corresponds + * to the AVSphericalMapping structure. + */ + AV_PKT_DATA_SPHERICAL, + + /** + * Content light level (based on CTA-861.3). This metadata should be + * associated with a video stream and contains data in the form of the + * AVContentLightMetadata struct. + */ + AV_PKT_DATA_CONTENT_LIGHT_LEVEL, + + /** + * ATSC A53 Part 4 Closed Captions. This metadata should be associated with + * a video stream. A53 CC bitstream is stored as uint8_t in AVPacketSideData.data. + * The number of bytes of CC data is AVPacketSideData.size. + */ + AV_PKT_DATA_A53_CC, + + /** + * This side data is encryption initialization data. + * The format is not part of ABI, use av_encryption_init_info_* methods to + * access. + */ + AV_PKT_DATA_ENCRYPTION_INIT_INFO, + + /** + * This side data contains encryption info for how to decrypt the packet. + * The format is not part of ABI, use av_encryption_info_* methods to access. + */ + AV_PKT_DATA_ENCRYPTION_INFO, + + /** + * Active Format Description data consisting of a single byte as specified + * in ETSI TS 101 154 using AVActiveFormatDescription enum. + */ + AV_PKT_DATA_AFD, + + /** + * The number of side data types. + * This is not part of the public API/ABI in the sense that it may + * change when new side data types are added. + * This must stay the last enum value. + * If its value becomes huge, some code using it + * needs to be updated as it assumes it to be smaller than other limits. + */ + AV_PKT_DATA_NB +}; + +#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED + +typedef struct AVPacketSideData { + uint8_t *data; + int size; + enum AVPacketSideDataType type; +} AVPacketSideData; + +/** + * This structure stores compressed data. It is typically exported by demuxers + * and then passed as input to decoders, or received as output from encoders and + * then passed to muxers. + * + * For video, it should typically contain one compressed frame. For audio it may + * contain several compressed frames. Encoders are allowed to output empty + * packets, with no compressed data, containing only side data + * (e.g. to update some stream parameters at the end of encoding). + * + * AVPacket is one of the few structs in FFmpeg, whose size is a part of public + * ABI. Thus it may be allocated on stack and no new fields can be added to it + * without libavcodec and libavformat major bump. + * + * The semantics of data ownership depends on the buf field. + * If it is set, the packet data is dynamically allocated and is + * valid indefinitely until a call to av_packet_unref() reduces the + * reference count to 0. + * + * If the buf field is not set av_packet_ref() would make a copy instead + * of increasing the reference count. + * + * The side data is always allocated with av_malloc(), copied by + * av_packet_ref() and freed by av_packet_unref(). + * + * @see av_packet_ref + * @see av_packet_unref + */ +typedef struct AVPacket { + /** + * A reference to the reference-counted buffer where the packet data is + * stored. + * May be NULL, then the packet data is not reference-counted. + */ + AVBufferRef *buf; + /** + * Presentation timestamp in AVStream->time_base units; the time at which + * the decompressed packet will be presented to the user. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + * pts MUST be larger or equal to dts as presentation cannot happen before + * decompression, unless one wants to view hex dumps. Some formats misuse + * the terms dts and pts/cts to mean something different. Such timestamps + * must be converted to true pts/dts before they are stored in AVPacket. + */ + int64_t pts; + /** + * Decompression timestamp in AVStream->time_base units; the time at which + * the packet is decompressed. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + */ + int64_t dts; + uint8_t *data; + int size; + int stream_index; + /** + * A combination of AV_PKT_FLAG values + */ + int flags; + /** + * Additional packet data that can be provided by the container. + * Packet can contain several types of side information. + */ + AVPacketSideData *side_data; + int side_data_elems; + + /** + * Duration of this packet in AVStream->time_base units, 0 if unknown. + * Equals next_pts - this_pts in presentation order. + */ + int64_t duration; + + int64_t pos; ///< byte position in stream, -1 if unknown + +#if FF_API_CONVERGENCE_DURATION + /** + * @deprecated Same as the duration field, but as int64_t. This was required + * for Matroska subtitles, whose duration values could overflow when the + * duration field was still an int. + */ + attribute_deprecated + int64_t convergence_duration; +#endif +} AVPacket; +#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe +#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted +/** + * Flag is used to discard packets which are required to maintain valid + * decoder state but are not required for output and should be dropped + * after decoding. + **/ +#define AV_PKT_FLAG_DISCARD 0x0004 +/** + * The packet comes from a trusted source. + * + * Otherwise-unsafe constructs such as arbitrary pointers to data + * outside the packet may be followed. + */ +#define AV_PKT_FLAG_TRUSTED 0x0008 +/** + * Flag is used to indicate packets that contain frames that can + * be discarded by the decoder. I.e. Non-reference frames. + */ +#define AV_PKT_FLAG_DISPOSABLE 0x0010 + + +enum AVSideDataParamChangeFlags { + AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, + AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002, + AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004, + AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008, +}; +/** + * @} + */ + +struct AVCodecInternal; + +enum AVFieldOrder { + AV_FIELD_UNKNOWN, + AV_FIELD_PROGRESSIVE, + AV_FIELD_TT, //< Top coded_first, top displayed first + AV_FIELD_BB, //< Bottom coded first, bottom displayed first + AV_FIELD_TB, //< Top coded first, bottom displayed first + AV_FIELD_BT, //< Bottom coded first, top displayed first +}; + +/** + * main external API structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user + * applications. + * The name string for AVOptions options matches the associated command line + * parameter name and can be found in libavcodec/options_table.h + * The AVOption/command line parameter names differ in some cases from the C + * structure field names for historic reasons or brevity. + * sizeof(AVCodecContext) must not be used outside libav*. + */ +typedef struct AVCodecContext { + /** + * information on struct for av_log + * - set by avcodec_alloc_context3 + */ + const AVClass *av_class; + int log_level_offset; + + enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */ + const struct AVCodec *codec; + enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */ + + /** + * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * A demuxer should set this to what is stored in the field used to identify the codec. + * If there are multiple such fields in a container then the demuxer should choose the one + * which maximizes the information about the used codec. + * If the codec tag field in a container is larger than 32 bits then the demuxer should + * remap the longer ID to 32 bits with a table or other structure. Alternatively a new + * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated + * first. + * - encoding: Set by user, if not then the default based on codec_id will be used. + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ + unsigned int codec_tag; + + void *priv_data; + + /** + * Private context used for internal data. + * + * Unlike priv_data, this is not codec-specific. It is used in general + * libavcodec functions. + */ + struct AVCodecInternal *internal; + + /** + * Private data of the user, can be used to carry app specific stuff. + * - encoding: Set by user. + * - decoding: Set by user. + */ + void *opaque; + + /** + * the average bitrate + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: Set by user, may be overwritten by libavcodec + * if this info is available in the stream + */ + int64_t bit_rate; + + /** + * number of bits the bitstream is allowed to diverge from the reference. + * the reference can be CBR (for CBR pass1) or VBR (for pass2) + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: unused + */ + int bit_rate_tolerance; + + /** + * Global quality for codecs which cannot change it per frame. + * This should be proportional to MPEG-1/2/4 qscale. + * - encoding: Set by user. + * - decoding: unused + */ + int global_quality; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int compression_level; +#define FF_COMPRESSION_DEFAULT -1 + + /** + * AV_CODEC_FLAG_*. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags; + + /** + * AV_CODEC_FLAG2_* + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags2; + + /** + * some codecs need / can use extradata like Huffman tables. + * MJPEG: Huffman tables + * rv10: additional flags + * MPEG-4: global headers (they can be in the bitstream or here) + * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger + * than extradata_size to avoid problems if it is read with the bitstream reader. + * The bytewise contents of extradata must not depend on the architecture or CPU endianness. + * Must be allocated with the av_malloc() family of functions. + * - encoding: Set/allocated/freed by libavcodec. + * - decoding: Set/allocated/freed by user. + */ + uint8_t *extradata; + int extradata_size; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, + * timebase should be 1/framerate and timestamp increments should be + * identically 1. + * This often, but not always is the inverse of the frame rate or field rate + * for video. 1/time_base is not the average frame rate if the frame rate is not + * constant. + * + * Like containers, elementary streams also can store timestamps, 1/time_base + * is the unit in which these timestamps are specified. + * As example of such codec time base see ISO/IEC 14496-2:2001(E) + * vop_time_increment_resolution and fixed_vop_rate + * (fixed_vop_rate == 0 implies that it is different from the framerate) + * + * - encoding: MUST be set by user. + * - decoding: the use of this field for decoding is deprecated. + * Use framerate instead. + */ + AVRational time_base; + + /** + * For some codecs, the time base is closer to the field rate than the frame rate. + * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration + * if no telecine is used ... + * + * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. + */ + int ticks_per_frame; + + /** + * Codec delay. + * + * Encoding: Number of frames delay there will be from the encoder input to + * the decoder output. (we assume the decoder matches the spec) + * Decoding: Number of frames delay in addition to what a standard decoder + * as specified in the spec would produce. + * + * Video: + * Number of frames the decoded output will be delayed relative to the + * encoded input. + * + * Audio: + * For encoding, this field is unused (see initial_padding). + * + * For decoding, this is the number of samples the decoder needs to + * output before the decoder's output is valid. When seeking, you should + * start decoding this many samples prior to your desired seek point. + * + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + int delay; + + + /* video only */ + /** + * picture width / height. + * + * @note Those fields may not match the values of the last + * AVFrame output by avcodec_decode_video2 due frame + * reordering. + * + * - encoding: MUST be set by user. + * - decoding: May be set by the user before opening the decoder if known e.g. + * from the container. Some decoders will require the dimensions + * to be set by the caller. During decoding, the decoder may + * overwrite those values as required while parsing the data. + */ + int width, height; + + /** + * Bitstream width / height, may be different from width/height e.g. when + * the decoded frame is cropped before being output or lowres is enabled. + * + * @note Those field may not match the value of the last + * AVFrame output by avcodec_receive_frame() due frame + * reordering. + * + * - encoding: unused + * - decoding: May be set by the user before opening the decoder if known + * e.g. from the container. During decoding, the decoder may + * overwrite those values as required while parsing the data. + */ + int coded_width, coded_height; + + /** + * the number of pictures in a group of pictures, or 0 for intra_only + * - encoding: Set by user. + * - decoding: unused + */ + int gop_size; + + /** + * Pixel format, see AV_PIX_FMT_xxx. + * May be set by the demuxer if known from headers. + * May be overridden by the decoder if it knows better. + * + * @note This field may not match the value of the last + * AVFrame output by avcodec_receive_frame() due frame + * reordering. + * + * - encoding: Set by user. + * - decoding: Set by user if known, overridden by libavcodec while + * parsing the data. + */ + enum AVPixelFormat pix_fmt; + + /** + * If non NULL, 'draw_horiz_band' is called by the libavcodec + * decoder to draw a horizontal band. It improves cache usage. Not + * all codecs can do that. You must check the codec capabilities + * beforehand. + * When multithreading is used, it may be called from multiple threads + * at the same time; threads might draw different parts of the same AVFrame, + * or multiple AVFrames, and there is no guarantee that slices will be drawn + * in order. + * The function is also used by hardware acceleration APIs. + * It is called at least once during frame decoding to pass + * the data needed for hardware render. + * In that mode instead of pixel data, AVFrame points to + * a structure specific to the acceleration API. The application + * reads the structure and can change some fields to indicate progress + * or mark state. + * - encoding: unused + * - decoding: Set by user. + * @param height the height of the slice + * @param y the y position of the slice + * @param type 1->top field, 2->bottom field, 3->frame + * @param offset offset into the AVFrame.data from which the slice should be read + */ + void (*draw_horiz_band)(struct AVCodecContext *s, + const AVFrame *src, int offset[AV_NUM_DATA_POINTERS], + int y, int type, int height); + + /** + * callback to negotiate the pixelFormat + * @param fmt is the list of formats which are supported by the codec, + * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. + * The first is always the native one. + * @note The callback may be called again immediately if initialization for + * the selected (hardware-accelerated) pixel format failed. + * @warning Behavior is undefined if the callback returns a value not + * in the fmt list of formats. + * @return the chosen format + * - encoding: unused + * - decoding: Set by user, if not set the native format will be chosen. + */ + enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt); + + /** + * maximum number of B-frames between non-B-frames + * Note: The output will be delayed by max_b_frames+1 relative to the input. + * - encoding: Set by user. + * - decoding: unused + */ + int max_b_frames; + + /** + * qscale factor between IP and B-frames + * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_factor; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int b_frame_strategy; +#endif + + /** + * qscale offset between IP and B-frames + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_offset; + + /** + * Size of the frame reordering buffer in the decoder. + * For MPEG-2 it is 1 IPB or 0 low delay IP. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + int has_b_frames; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int mpeg_quant; +#endif + + /** + * qscale factor between P- and I-frames + * If > 0 then the last P-frame quantizer will be used (q = lastp_q * factor + offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_factor; + + /** + * qscale offset between P and I-frames + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_offset; + + /** + * luminance masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float lumi_masking; + + /** + * temporary complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float temporal_cplx_masking; + + /** + * spatial complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float spatial_cplx_masking; + + /** + * p block masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float p_masking; + + /** + * darkness masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float dark_masking; + + /** + * slice count + * - encoding: Set by libavcodec. + * - decoding: Set by user (or 0). + */ + int slice_count; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int prediction_method; +#define FF_PRED_LEFT 0 +#define FF_PRED_PLANE 1 +#define FF_PRED_MEDIAN 2 +#endif + + /** + * slice offsets in the frame in bytes + * - encoding: Set/allocated by libavcodec. + * - decoding: Set/allocated by user (or NULL). + */ + int *slice_offset; + + /** + * sample aspect ratio (0 if unknown) + * That is the width of a pixel divided by the height of the pixel. + * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + AVRational sample_aspect_ratio; + + /** + * motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_cmp; + /** + * subpixel motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_sub_cmp; + /** + * macroblock comparison function (not supported yet) + * - encoding: Set by user. + * - decoding: unused + */ + int mb_cmp; + /** + * interlaced DCT comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int ildct_cmp; +#define FF_CMP_SAD 0 +#define FF_CMP_SSE 1 +#define FF_CMP_SATD 2 +#define FF_CMP_DCT 3 +#define FF_CMP_PSNR 4 +#define FF_CMP_BIT 5 +#define FF_CMP_RD 6 +#define FF_CMP_ZERO 7 +#define FF_CMP_VSAD 8 +#define FF_CMP_VSSE 9 +#define FF_CMP_NSSE 10 +#define FF_CMP_W53 11 +#define FF_CMP_W97 12 +#define FF_CMP_DCTMAX 13 +#define FF_CMP_DCT264 14 +#define FF_CMP_MEDIAN_SAD 15 +#define FF_CMP_CHROMA 256 + + /** + * ME diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int dia_size; + + /** + * amount of previous MV predictors (2a+1 x 2a+1 square) + * - encoding: Set by user. + * - decoding: unused + */ + int last_predictor_count; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int pre_me; +#endif + + /** + * motion estimation prepass comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_pre_cmp; + + /** + * ME prepass diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int pre_dia_size; + + /** + * subpel ME quality + * - encoding: Set by user. + * - decoding: unused + */ + int me_subpel_quality; + + /** + * maximum motion estimation search range in subpel units + * If 0 then no limit. + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_range; + + /** + * slice flags + * - encoding: unused + * - decoding: Set by user. + */ + int slice_flags; +#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display +#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG-2 field pics) +#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1) + + /** + * macroblock decision mode + * - encoding: Set by user. + * - decoding: unused + */ + int mb_decision; +#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp +#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits +#define FF_MB_DECISION_RD 2 ///< rate distortion + + /** + * custom intra quantization matrix + * Must be allocated with the av_malloc() family of functions, and will be freed in + * avcodec_free_context(). + * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL. + * - decoding: Set/allocated/freed by libavcodec. + */ + uint16_t *intra_matrix; + + /** + * custom inter quantization matrix + * Must be allocated with the av_malloc() family of functions, and will be freed in + * avcodec_free_context(). + * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL. + * - decoding: Set/allocated/freed by libavcodec. + */ + uint16_t *inter_matrix; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int scenechange_threshold; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int noise_reduction; +#endif + + /** + * precision of the intra DC coefficient - 8 + * - encoding: Set by user. + * - decoding: Set by libavcodec + */ + int intra_dc_precision; + + /** + * Number of macroblock rows at the top which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_top; + + /** + * Number of macroblock rows at the bottom which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_bottom; + + /** + * minimum MB Lagrange multiplier + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmin; + + /** + * maximum MB Lagrange multiplier + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmax; + +#if FF_API_PRIVATE_OPT + /** + * @deprecated use encoder private options instead + */ + attribute_deprecated + int me_penalty_compensation; +#endif + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int bidir_refine; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int brd_scale; +#endif + + /** + * minimum GOP size + * - encoding: Set by user. + * - decoding: unused + */ + int keyint_min; + + /** + * number of reference frames + * - encoding: Set by user. + * - decoding: Set by lavc. + */ + int refs; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int chromaoffset; +#endif + + /** + * Note: Value depends upon the compare function used for fullpel ME. + * - encoding: Set by user. + * - decoding: unused + */ + int mv0_threshold; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int b_sensitivity; +#endif + + /** + * Chromaticity coordinates of the source primaries. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorPrimaries color_primaries; + + /** + * Color Transfer Characteristic. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorSpace colorspace; + + /** + * MPEG vs JPEG YUV range. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorRange color_range; + + /** + * This defines the location of chroma samples. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVChromaLocation chroma_sample_location; + + /** + * Number of slices. + * Indicates number of picture subdivisions. Used for parallelized + * decoding. + * - encoding: Set by user + * - decoding: unused + */ + int slices; + + /** Field order + * - encoding: set by libavcodec + * - decoding: Set by user. + */ + enum AVFieldOrder field_order; + + /* audio only */ + int sample_rate; ///< samples per second + int channels; ///< number of audio channels + + /** + * audio sample format + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum AVSampleFormat sample_fmt; ///< sample format + + /* The following data should not be initialized. */ + /** + * Number of samples per channel in an audio frame. + * + * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame + * except the last must contain exactly frame_size samples per channel. + * May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then the + * frame size is not restricted. + * - decoding: may be set by some decoders to indicate constant frame size + */ + int frame_size; + + /** + * Frame counter, set by libavcodec. + * + * - decoding: total number of frames returned from the decoder so far. + * - encoding: total number of frames passed to the encoder so far. + * + * @note the counter is not incremented if encoding/decoding resulted in + * an error. + */ + int frame_number; + + /** + * number of bytes per packet if constant and known or 0 + * Used by some WAV based audio codecs. + */ + int block_align; + + /** + * Audio cutoff bandwidth (0 means "automatic") + * - encoding: Set by user. + * - decoding: unused + */ + int cutoff; + + /** + * Audio channel layout. + * - encoding: set by user. + * - decoding: set by user, may be overwritten by libavcodec. + */ + uint64_t channel_layout; + + /** + * Request decoder to use this channel layout if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + */ + uint64_t request_channel_layout; + + /** + * Type of service that the audio stream conveys. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum AVAudioServiceType audio_service_type; + + /** + * desired sample format + * - encoding: Not used. + * - decoding: Set by user. + * Decoder will decode to this format if it can. + */ + enum AVSampleFormat request_sample_fmt; + + /** + * This callback is called at the beginning of each frame to get data + * buffer(s) for it. There may be one contiguous buffer for all the data or + * there may be a buffer per each data plane or anything in between. What + * this means is, you may set however many entries in buf[] you feel necessary. + * Each buffer must be reference-counted using the AVBuffer API (see description + * of buf[] below). + * + * The following fields will be set in the frame before this callback is + * called: + * - format + * - width, height (video only) + * - sample_rate, channel_layout, nb_samples (audio only) + * Their values may differ from the corresponding values in + * AVCodecContext. This callback must use the frame values, not the codec + * context values, to calculate the required buffer size. + * + * This callback must fill the following fields in the frame: + * - data[] + * - linesize[] + * - extended_data: + * * if the data is planar audio with more than 8 channels, then this + * callback must allocate and fill extended_data to contain all pointers + * to all data planes. data[] must hold as many pointers as it can. + * extended_data must be allocated with av_malloc() and will be freed in + * av_frame_unref(). + * * otherwise extended_data must point to data + * - buf[] must contain one or more pointers to AVBufferRef structures. Each of + * the frame's data and extended_data pointers must be contained in these. That + * is, one AVBufferRef for each allocated chunk of memory, not necessarily one + * AVBufferRef per data[] entry. See: av_buffer_create(), av_buffer_alloc(), + * and av_buffer_ref(). + * - extended_buf and nb_extended_buf must be allocated with av_malloc() by + * this callback and filled with the extra buffers if there are more + * buffers than buf[] can hold. extended_buf will be freed in + * av_frame_unref(). + * + * If AV_CODEC_CAP_DR1 is not set then get_buffer2() must call + * avcodec_default_get_buffer2() instead of providing buffers allocated by + * some other means. + * + * Each data plane must be aligned to the maximum required by the target + * CPU. + * + * @see avcodec_default_get_buffer2() + * + * Video: + * + * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused + * (read and/or written to if it is writable) later by libavcodec. + * + * avcodec_align_dimensions2() should be used to find the required width and + * height, as they normally need to be rounded up to the next multiple of 16. + * + * Some decoders do not support linesizes changing between frames. + * + * If frame multithreading is used and thread_safe_callbacks is set, + * this callback may be called from a different thread, but not from more + * than one at once. Does not need to be reentrant. + * + * @see avcodec_align_dimensions2() + * + * Audio: + * + * Decoders request a buffer of a particular size by setting + * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may, + * however, utilize only part of the buffer by setting AVFrame.nb_samples + * to a smaller value in the output frame. + * + * As a convenience, av_samples_get_buffer_size() and + * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2() + * functions to find the required data size and to fill data pointers and + * linesize. In AVFrame.linesize, only linesize[0] may be set for audio + * since all planes must be the same size. + * + * @see av_samples_get_buffer_size(), av_samples_fill_arrays() + * + * - encoding: unused + * - decoding: Set by libavcodec, user can override. + */ + int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); + + /** + * If non-zero, the decoded audio and video frames returned from + * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted + * and are valid indefinitely. The caller must free them with + * av_frame_unref() when they are not needed anymore. + * Otherwise, the decoded frames must not be freed by the caller and are + * only valid until the next decode call. + * + * This is always automatically enabled if avcodec_receive_frame() is used. + * + * - encoding: unused + * - decoding: set by the caller before avcodec_open2(). + */ + attribute_deprecated + int refcounted_frames; + + /* - encoding parameters */ + float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) + float qblur; ///< amount of qscale smoothing over time (0.0-1.0) + + /** + * minimum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmin; + + /** + * maximum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmax; + + /** + * maximum quantizer difference between frames + * - encoding: Set by user. + * - decoding: unused + */ + int max_qdiff; + + /** + * decoder bitstream buffer size + * - encoding: Set by user. + * - decoding: unused + */ + int rc_buffer_size; + + /** + * ratecontrol override, see RcOverride + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + int rc_override_count; + RcOverride *rc_override; + + /** + * maximum bitrate + * - encoding: Set by user. + * - decoding: Set by user, may be overwritten by libavcodec. + */ + int64_t rc_max_rate; + + /** + * minimum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int64_t rc_min_rate; + + /** + * Ratecontrol attempt to use, at maximum, of what can be used without an underflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_max_available_vbv_use; + + /** + * Ratecontrol attempt to use, at least, times the amount needed to prevent a vbv overflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_min_vbv_overflow_use; + + /** + * Number of bits which should be loaded into the rc buffer before decoding starts. + * - encoding: Set by user. + * - decoding: unused + */ + int rc_initial_buffer_occupancy; + +#if FF_API_CODER_TYPE +#define FF_CODER_TYPE_VLC 0 +#define FF_CODER_TYPE_AC 1 +#define FF_CODER_TYPE_RAW 2 +#define FF_CODER_TYPE_RLE 3 + /** + * @deprecated use encoder private options instead + */ + attribute_deprecated + int coder_type; +#endif /* FF_API_CODER_TYPE */ + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int context_model; +#endif + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int frame_skip_threshold; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int frame_skip_factor; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int frame_skip_exp; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int frame_skip_cmp; +#endif /* FF_API_PRIVATE_OPT */ + + /** + * trellis RD quantization + * - encoding: Set by user. + * - decoding: unused + */ + int trellis; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int min_prediction_order; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int max_prediction_order; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int64_t timecode_frame_start; +#endif + +#if FF_API_RTP_CALLBACK + /** + * @deprecated unused + */ + /* The RTP callback: This function is called */ + /* every time the encoder has a packet to send. */ + /* It depends on the encoder if the data starts */ + /* with a Start Code (it should). H.263 does. */ + /* mb_nb contains the number of macroblocks */ + /* encoded in the RTP payload. */ + attribute_deprecated + void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb); +#endif + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int rtp_payload_size; /* The size of the RTP payload: the coder will */ + /* do its best to deliver a chunk with size */ + /* below rtp_payload_size, the chunk will start */ + /* with a start code on some codecs like H.263. */ + /* This doesn't take account of any particular */ + /* headers inside the transmitted RTP payload. */ +#endif + +#if FF_API_STAT_BITS + /* statistics, used for 2-pass encoding */ + attribute_deprecated + int mv_bits; + attribute_deprecated + int header_bits; + attribute_deprecated + int i_tex_bits; + attribute_deprecated + int p_tex_bits; + attribute_deprecated + int i_count; + attribute_deprecated + int p_count; + attribute_deprecated + int skip_count; + attribute_deprecated + int misc_bits; + + /** @deprecated this field is unused */ + attribute_deprecated + int frame_bits; +#endif + + /** + * pass1 encoding statistics output buffer + * - encoding: Set by libavcodec. + * - decoding: unused + */ + char *stats_out; + + /** + * pass2 encoding statistics input buffer + * Concatenated stuff from stats_out of pass1 should be placed here. + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + char *stats_in; + + /** + * Work around bugs in encoders which sometimes cannot be detected automatically. + * - encoding: Set by user + * - decoding: Set by user + */ + int workaround_bugs; +#define FF_BUG_AUTODETECT 1 ///< autodetection +#define FF_BUG_XVID_ILACE 4 +#define FF_BUG_UMP4 8 +#define FF_BUG_NO_PADDING 16 +#define FF_BUG_AMV 32 +#define FF_BUG_QPEL_CHROMA 64 +#define FF_BUG_STD_QPEL 128 +#define FF_BUG_QPEL_CHROMA2 256 +#define FF_BUG_DIRECT_BLOCKSIZE 512 +#define FF_BUG_EDGE 1024 +#define FF_BUG_HPEL_CHROMA 2048 +#define FF_BUG_DC_CLIP 4096 +#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders. +#define FF_BUG_TRUNCATED 16384 +#define FF_BUG_IEDGE 32768 + + /** + * strictly follow the standard (MPEG-4, ...). + * - encoding: Set by user. + * - decoding: Set by user. + * Setting this to STRICT or higher means the encoder and decoder will + * generally do stupid things, whereas setting it to unofficial or lower + * will mean the encoder might produce output that is not supported by all + * spec-compliant decoders. Decoders don't differentiate between normal, + * unofficial and experimental (that is, they always try to decode things + * when they can) unless they are explicitly asked to behave stupidly + * (=strictly conform to the specs) + */ + int strict_std_compliance; +#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software. +#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences. +#define FF_COMPLIANCE_NORMAL 0 +#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions +#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things. + + /** + * error concealment flags + * - encoding: unused + * - decoding: Set by user. + */ + int error_concealment; +#define FF_EC_GUESS_MVS 1 +#define FF_EC_DEBLOCK 2 +#define FF_EC_FAVOR_INTER 256 + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug; +#define FF_DEBUG_PICT_INFO 1 +#define FF_DEBUG_RC 2 +#define FF_DEBUG_BITSTREAM 4 +#define FF_DEBUG_MB_TYPE 8 +#define FF_DEBUG_QP 16 +#if FF_API_DEBUG_MV +/** + * @deprecated this option does nothing + */ +#define FF_DEBUG_MV 32 +#endif +#define FF_DEBUG_DCT_COEFF 0x00000040 +#define FF_DEBUG_SKIP 0x00000080 +#define FF_DEBUG_STARTCODE 0x00000100 +#define FF_DEBUG_ER 0x00000400 +#define FF_DEBUG_MMCO 0x00000800 +#define FF_DEBUG_BUGS 0x00001000 +#if FF_API_DEBUG_MV +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 +#endif +#define FF_DEBUG_BUFFERS 0x00008000 +#define FF_DEBUG_THREADS 0x00010000 +#define FF_DEBUG_GREEN_MD 0x00800000 +#define FF_DEBUG_NOMC 0x01000000 + +#if FF_API_DEBUG_MV + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 // visualize forward predicted MVs of P-frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 // visualize forward predicted MVs of B-frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 // visualize backward predicted MVs of B-frames +#endif + + /** + * Error recognition; may misdetect some more or less valid parts as errors. + * - encoding: unused + * - decoding: Set by user. + */ + int err_recognition; + +/** + * Verify checksums embedded in the bitstream (could be of either encoded or + * decoded data, depending on the codec) and print an error message on mismatch. + * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the + * decoder returning an error. + */ +#define AV_EF_CRCCHECK (1<<0) +#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations +#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length +#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection + +#define AV_EF_IGNORE_ERR (1<<15) ///< ignore errors and continue +#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors +#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliances as errors +#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error + + + /** + * opaque 64-bit number (generally a PTS) that will be reordered and + * output in AVFrame.reordered_opaque + * - encoding: Set by libavcodec to the reordered_opaque of the input + * frame corresponding to the last returned packet. Only + * supported by encoders with the + * AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability. + * - decoding: Set by user. + */ + int64_t reordered_opaque; + + /** + * Hardware accelerator in use + * - encoding: unused. + * - decoding: Set by libavcodec + */ + const struct AVHWAccel *hwaccel; + + /** + * Hardware accelerator context. + * For some hardware accelerators, a global context needs to be + * provided by the user. In that case, this holds display-dependent + * data FFmpeg cannot instantiate itself. Please refer to the + * FFmpeg HW accelerator documentation to know how to fill this + * is. e.g. for VA API, this is a struct vaapi_context. + * - encoding: unused + * - decoding: Set by user + */ + void *hwaccel_context; + + /** + * error + * - encoding: Set by libavcodec if flags & AV_CODEC_FLAG_PSNR. + * - decoding: unused + */ + uint64_t error[AV_NUM_DATA_POINTERS]; + + /** + * DCT algorithm, see FF_DCT_* below + * - encoding: Set by user. + * - decoding: unused + */ + int dct_algo; +#define FF_DCT_AUTO 0 +#define FF_DCT_FASTINT 1 +#define FF_DCT_INT 2 +#define FF_DCT_MMX 3 +#define FF_DCT_ALTIVEC 5 +#define FF_DCT_FAAN 6 + + /** + * IDCT algorithm, see FF_IDCT_* below. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int idct_algo; +#define FF_IDCT_AUTO 0 +#define FF_IDCT_INT 1 +#define FF_IDCT_SIMPLE 2 +#define FF_IDCT_SIMPLEMMX 3 +#define FF_IDCT_ARM 7 +#define FF_IDCT_ALTIVEC 8 +#define FF_IDCT_SIMPLEARM 10 +#define FF_IDCT_XVID 14 +#define FF_IDCT_SIMPLEARMV5TE 16 +#define FF_IDCT_SIMPLEARMV6 17 +#define FF_IDCT_FAAN 20 +#define FF_IDCT_SIMPLENEON 22 +#define FF_IDCT_NONE 24 /* Used by XvMC to extract IDCT coefficients with FF_IDCT_PERM_NONE */ +#define FF_IDCT_SIMPLEAUTO 128 + + /** + * bits per sample/pixel from the demuxer (needed for huffyuv). + * - encoding: Set by libavcodec. + * - decoding: Set by user. + */ + int bits_per_coded_sample; + + /** + * Bits per sample/pixel of internal libavcodec pixel/sample format. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int bits_per_raw_sample; + +#if FF_API_LOWRES + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + */ + int lowres; +#endif + +#if FF_API_CODED_FRAME + /** + * the picture in the bitstream + * - encoding: Set by libavcodec. + * - decoding: unused + * + * @deprecated use the quality factor packet side data instead + */ + attribute_deprecated AVFrame *coded_frame; +#endif + + /** + * thread count + * is used to decide how many independent tasks should be passed to execute() + * - encoding: Set by user. + * - decoding: Set by user. + */ + int thread_count; + + /** + * Which multithreading methods to use. + * Use of FF_THREAD_FRAME will increase decoding delay by one frame per thread, + * so clients which cannot provide future frames should not use it. + * + * - encoding: Set by user, otherwise the default is used. + * - decoding: Set by user, otherwise the default is used. + */ + int thread_type; +#define FF_THREAD_FRAME 1 ///< Decode more than one frame at once +#define FF_THREAD_SLICE 2 ///< Decode more than one part of a single frame at once + + /** + * Which multithreading methods are in use by the codec. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + int active_thread_type; + + /** + * Set by the client if its custom get_buffer() callback can be called + * synchronously from another thread, which allows faster multithreaded decoding. + * draw_horiz_band() will be called from other threads regardless of this setting. + * Ignored if the default get_buffer() is used. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int thread_safe_callbacks; + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * @param count the number of things to execute + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size); + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * Also see avcodec_thread_init and e.g. the --enable-pthread configure option. + * @param c context passed also to func + * @param count the number of things to execute + * @param arg2 argument passed unchanged to func + * @param ret return values of executed functions, must have space for "count" values. May be NULL. + * @param func function that will be called count times, with jobnr from 0 to count-1. + * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no + * two instances of func executing at the same time will have the same threadnr. + * @return always 0 currently, but code should handle a future improvement where when any call to func + * returns < 0 no further calls to func may be done and < 0 is returned. + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); + + /** + * noise vs. sse weight for the nsse comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int nsse_weight; + + /** + * profile + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int profile; +#define FF_PROFILE_UNKNOWN -99 +#define FF_PROFILE_RESERVED -100 + +#define FF_PROFILE_AAC_MAIN 0 +#define FF_PROFILE_AAC_LOW 1 +#define FF_PROFILE_AAC_SSR 2 +#define FF_PROFILE_AAC_LTP 3 +#define FF_PROFILE_AAC_HE 4 +#define FF_PROFILE_AAC_HE_V2 28 +#define FF_PROFILE_AAC_LD 22 +#define FF_PROFILE_AAC_ELD 38 +#define FF_PROFILE_MPEG2_AAC_LOW 128 +#define FF_PROFILE_MPEG2_AAC_HE 131 + +#define FF_PROFILE_DNXHD 0 +#define FF_PROFILE_DNXHR_LB 1 +#define FF_PROFILE_DNXHR_SQ 2 +#define FF_PROFILE_DNXHR_HQ 3 +#define FF_PROFILE_DNXHR_HQX 4 +#define FF_PROFILE_DNXHR_444 5 + +#define FF_PROFILE_DTS 20 +#define FF_PROFILE_DTS_ES 30 +#define FF_PROFILE_DTS_96_24 40 +#define FF_PROFILE_DTS_HD_HRA 50 +#define FF_PROFILE_DTS_HD_MA 60 +#define FF_PROFILE_DTS_EXPRESS 70 + +#define FF_PROFILE_MPEG2_422 0 +#define FF_PROFILE_MPEG2_HIGH 1 +#define FF_PROFILE_MPEG2_SS 2 +#define FF_PROFILE_MPEG2_SNR_SCALABLE 3 +#define FF_PROFILE_MPEG2_MAIN 4 +#define FF_PROFILE_MPEG2_SIMPLE 5 + +#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag +#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag + +#define FF_PROFILE_H264_BASELINE 66 +#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED) +#define FF_PROFILE_H264_MAIN 77 +#define FF_PROFILE_H264_EXTENDED 88 +#define FF_PROFILE_H264_HIGH 100 +#define FF_PROFILE_H264_HIGH_10 110 +#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA) +#define FF_PROFILE_H264_MULTIVIEW_HIGH 118 +#define FF_PROFILE_H264_HIGH_422 122 +#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA) +#define FF_PROFILE_H264_STEREO_HIGH 128 +#define FF_PROFILE_H264_HIGH_444 144 +#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244 +#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA) +#define FF_PROFILE_H264_CAVLC_444 44 + +#define FF_PROFILE_VC1_SIMPLE 0 +#define FF_PROFILE_VC1_MAIN 1 +#define FF_PROFILE_VC1_COMPLEX 2 +#define FF_PROFILE_VC1_ADVANCED 3 + +#define FF_PROFILE_MPEG4_SIMPLE 0 +#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1 +#define FF_PROFILE_MPEG4_CORE 2 +#define FF_PROFILE_MPEG4_MAIN 3 +#define FF_PROFILE_MPEG4_N_BIT 4 +#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5 +#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6 +#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7 +#define FF_PROFILE_MPEG4_HYBRID 8 +#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9 +#define FF_PROFILE_MPEG4_CORE_SCALABLE 10 +#define FF_PROFILE_MPEG4_ADVANCED_CODING 11 +#define FF_PROFILE_MPEG4_ADVANCED_CORE 12 +#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13 +#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14 +#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15 + +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 1 +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 2 +#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 32768 +#define FF_PROFILE_JPEG2000_DCINEMA_2K 3 +#define FF_PROFILE_JPEG2000_DCINEMA_4K 4 + +#define FF_PROFILE_VP9_0 0 +#define FF_PROFILE_VP9_1 1 +#define FF_PROFILE_VP9_2 2 +#define FF_PROFILE_VP9_3 3 + +#define FF_PROFILE_HEVC_MAIN 1 +#define FF_PROFILE_HEVC_MAIN_10 2 +#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 +#define FF_PROFILE_HEVC_REXT 4 + +#define FF_PROFILE_AV1_MAIN 0 +#define FF_PROFILE_AV1_HIGH 1 +#define FF_PROFILE_AV1_PROFESSIONAL 2 + +#define FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT 0xc0 +#define FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT 0xc1 +#define FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT 0xc2 +#define FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS 0xc3 +#define FF_PROFILE_MJPEG_JPEG_LS 0xf7 + +#define FF_PROFILE_SBC_MSBC 1 + +#define FF_PROFILE_PRORES_PROXY 0 +#define FF_PROFILE_PRORES_LT 1 +#define FF_PROFILE_PRORES_STANDARD 2 +#define FF_PROFILE_PRORES_HQ 3 +#define FF_PROFILE_PRORES_4444 4 +#define FF_PROFILE_PRORES_XQ 5 + +#define FF_PROFILE_ARIB_PROFILE_A 0 +#define FF_PROFILE_ARIB_PROFILE_C 1 + + /** + * level + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int level; +#define FF_LEVEL_UNKNOWN -99 + + /** + * Skip loop filtering for selected frames. + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_loop_filter; + + /** + * Skip IDCT/dequantization for selected frames. + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_idct; + + /** + * Skip decoding for selected frames. + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_frame; + + /** + * Header containing style information for text subtitles. + * For SUBTITLE_ASS subtitle type, it should contain the whole ASS + * [Script Info] and [V4+ Styles] section, plus the [Events] line and + * the Format line following. It shouldn't include any Dialogue line. + * - encoding: Set/allocated/freed by user (before avcodec_open2()) + * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2()) + */ + uint8_t *subtitle_header; + int subtitle_header_size; + +#if FF_API_VBV_DELAY + /** + * VBV delay coded in the last frame (in periods of a 27 MHz clock). + * Used for compliant TS muxing. + * - encoding: Set by libavcodec. + * - decoding: unused. + * @deprecated this value is now exported as a part of + * AV_PKT_DATA_CPB_PROPERTIES packet side data + */ + attribute_deprecated + uint64_t vbv_delay; +#endif + +#if FF_API_SIDEDATA_ONLY_PKT + /** + * Encoding only and set by default. Allow encoders to output packets + * that do not contain any encoded data, only side data. + * + * Some encoders need to output such packets, e.g. to update some stream + * parameters at the end of encoding. + * + * @deprecated this field disables the default behaviour and + * it is kept only for compatibility. + */ + attribute_deprecated + int side_data_only_packets; +#endif + + /** + * Audio only. The number of "priming" samples (padding) inserted by the + * encoder at the beginning of the audio. I.e. this number of leading + * decoded samples must be discarded by the caller to get the original audio + * without leading padding. + * + * - decoding: unused + * - encoding: Set by libavcodec. The timestamps on the output packets are + * adjusted by the encoder so that they always refer to the + * first sample of the data actually contained in the packet, + * including any added padding. E.g. if the timebase is + * 1/samplerate and the timestamp of the first input sample is + * 0, the timestamp of the first output packet will be + * -initial_padding. + */ + int initial_padding; + + /** + * - decoding: For codecs that store a framerate value in the compressed + * bitstream, the decoder may export it here. { 0, 1} when + * unknown. + * - encoding: May be used to signal the framerate of CFR content to an + * encoder. + */ + AVRational framerate; + + /** + * Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx. + * - encoding: unused. + * - decoding: Set by libavcodec before calling get_format() + */ + enum AVPixelFormat sw_pix_fmt; + + /** + * Timebase in which pkt_dts/pts and AVPacket.dts/pts are. + * - encoding unused. + * - decoding set by user. + */ + AVRational pkt_timebase; + + /** + * AVCodecDescriptor + * - encoding: unused. + * - decoding: set by libavcodec. + */ + const AVCodecDescriptor *codec_descriptor; + +#if !FF_API_LOWRES + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + */ + int lowres; +#endif + + /** + * Current statistics for PTS correction. + * - decoding: maintained and used by libavcodec, not intended to be used by user apps + * - encoding: unused + */ + int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far + int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far + int64_t pts_correction_last_pts; /// PTS of the last frame + int64_t pts_correction_last_dts; /// DTS of the last frame + + /** + * Character encoding of the input subtitles file. + * - decoding: set by user + * - encoding: unused + */ + char *sub_charenc; + + /** + * Subtitles character encoding mode. Formats or codecs might be adjusting + * this setting (if they are doing the conversion themselves for instance). + * - decoding: set by libavcodec + * - encoding: unused + */ + int sub_charenc_mode; +#define FF_SUB_CHARENC_MODE_DO_NOTHING -1 ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance) +#define FF_SUB_CHARENC_MODE_AUTOMATIC 0 ///< libavcodec will select the mode itself +#define FF_SUB_CHARENC_MODE_PRE_DECODER 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv +#define FF_SUB_CHARENC_MODE_IGNORE 2 ///< neither convert the subtitles, nor check them for valid UTF-8 + + /** + * Skip processing alpha if supported by codec. + * Note that if the format uses pre-multiplied alpha (common with VP6, + * and recommended due to better video quality/compression) + * the image will look as if alpha-blended onto a black background. + * However for formats that do not use pre-multiplied alpha + * there might be serious artefacts (though e.g. libswscale currently + * assumes pre-multiplied alpha anyway). + * + * - decoding: set by user + * - encoding: unused + */ + int skip_alpha; + + /** + * Number of samples to skip after a discontinuity + * - decoding: unused + * - encoding: set by libavcodec + */ + int seek_preroll; + +#if !FF_API_DEBUG_MV + /** + * debug motion vectors + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames +#endif + + /** + * custom intra quantization matrix + * - encoding: Set by user, can be NULL. + * - decoding: unused. + */ + uint16_t *chroma_intra_matrix; + + /** + * dump format separator. + * can be ", " or "\n " or anything else + * - encoding: Set by user. + * - decoding: Set by user. + */ + uint8_t *dump_separator; + + /** + * ',' separated list of allowed decoders. + * If NULL then all are allowed + * - encoding: unused + * - decoding: set by user + */ + char *codec_whitelist; + + /** + * Properties of the stream that gets decoded + * - encoding: unused + * - decoding: set by libavcodec + */ + unsigned properties; +#define FF_CODEC_PROPERTY_LOSSLESS 0x00000001 +#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002 + + /** + * Additional data associated with the entire coded stream. + * + * - decoding: unused + * - encoding: may be set by libavcodec after avcodec_open2(). + */ + AVPacketSideData *coded_side_data; + int nb_coded_side_data; + + /** + * A reference to the AVHWFramesContext describing the input (for encoding) + * or output (decoding) frames. The reference is set by the caller and + * afterwards owned (and freed) by libavcodec - it should never be read by + * the caller after being set. + * + * - decoding: This field should be set by the caller from the get_format() + * callback. The previous reference (if any) will always be + * unreffed by libavcodec before the get_format() call. + * + * If the default get_buffer2() is used with a hwaccel pixel + * format, then this AVHWFramesContext will be used for + * allocating the frame buffers. + * + * - encoding: For hardware encoders configured to use a hwaccel pixel + * format, this field should be set by the caller to a reference + * to the AVHWFramesContext describing input frames. + * AVHWFramesContext.format must be equal to + * AVCodecContext.pix_fmt. + * + * This field should be set before avcodec_open2() is called. + */ + AVBufferRef *hw_frames_ctx; + + /** + * Control the form of AVSubtitle.rects[N]->ass + * - decoding: set by user + * - encoding: unused + */ + int sub_text_format; +#define FF_SUB_TEXT_FMT_ASS 0 +#if FF_API_ASS_TIMING +#define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1 +#endif + + /** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + * + * - decoding: unused + * - encoding: unused + */ + int trailing_padding; + + /** + * The number of pixels per image to maximally accept. + * + * - decoding: set by user + * - encoding: set by user + */ + int64_t max_pixels; + + /** + * A reference to the AVHWDeviceContext describing the device which will + * be used by a hardware encoder/decoder. The reference is set by the + * caller and afterwards owned (and freed) by libavcodec. + * + * This should be used if either the codec device does not require + * hardware frames or any that are used are to be allocated internally by + * libavcodec. If the user wishes to supply any of the frames used as + * encoder input or decoder output then hw_frames_ctx should be used + * instead. When hw_frames_ctx is set in get_format() for a decoder, this + * field will be ignored while decoding the associated stream segment, but + * may again be used on a following one after another get_format() call. + * + * For both encoders and decoders this field should be set before + * avcodec_open2() is called and must not be written to thereafter. + * + * Note that some decoders may require this field to be set initially in + * order to support hw_frames_ctx at all - in that case, all frames + * contexts used must be created on the same device. + */ + AVBufferRef *hw_device_ctx; + + /** + * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated + * decoding (if active). + * - encoding: unused + * - decoding: Set by user (either before avcodec_open2(), or in the + * AVCodecContext.get_format callback) + */ + int hwaccel_flags; + + /** + * Video decoding only. Certain video codecs support cropping, meaning that + * only a sub-rectangle of the decoded frame is intended for display. This + * option controls how cropping is handled by libavcodec. + * + * When set to 1 (the default), libavcodec will apply cropping internally. + * I.e. it will modify the output frame width/height fields and offset the + * data pointers (only by as much as possible while preserving alignment, or + * by the full amount if the AV_CODEC_FLAG_UNALIGNED flag is set) so that + * the frames output by the decoder refer only to the cropped area. The + * crop_* fields of the output frames will be zero. + * + * When set to 0, the width/height fields of the output frames will be set + * to the coded dimensions and the crop_* fields will describe the cropping + * rectangle. Applying the cropping is left to the caller. + * + * @warning When hardware acceleration with opaque output frames is used, + * libavcodec is unable to apply cropping from the top/left border. + * + * @note when this option is set to zero, the width/height fields of the + * AVCodecContext and output AVFrames have different meanings. The codec + * context fields store display dimensions (with the coded dimensions in + * coded_width/height), while the frame fields store the coded dimensions + * (with the display dimensions being determined by the crop_* fields). + */ + int apply_cropping; + + /* + * Video decoding only. Sets the number of extra hardware frames which + * the decoder will allocate for use by the caller. This must be set + * before avcodec_open2() is called. + * + * Some hardware decoders require all frames that they will use for + * output to be defined in advance before decoding starts. For such + * decoders, the hardware frame pool must therefore be of a fixed size. + * The extra frames set here are on top of any number that the decoder + * needs internally in order to operate normally (for example, frames + * used as reference pictures). + */ + int extra_hw_frames; + + /** + * The percentage of damaged samples to discard a frame. + * + * - decoding: set by user + * - encoding: unused + */ + int discard_damaged_percentage; +} AVCodecContext; + +#if FF_API_CODEC_GET_SET +/** + * Accessors for some AVCodecContext fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. + */ +attribute_deprecated +AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_pkt_timebase (AVCodecContext *avctx, AVRational val); + +attribute_deprecated +const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc); + +attribute_deprecated +unsigned av_codec_get_codec_properties(const AVCodecContext *avctx); + +#if FF_API_LOWRES +attribute_deprecated +int av_codec_get_lowres(const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_lowres(AVCodecContext *avctx, int val); +#endif + +attribute_deprecated +int av_codec_get_seek_preroll(const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_seek_preroll(AVCodecContext *avctx, int val); + +attribute_deprecated +uint16_t *av_codec_get_chroma_intra_matrix(const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_chroma_intra_matrix(AVCodecContext *avctx, uint16_t *val); +#endif + +/** + * AVProfile. + */ +typedef struct AVProfile { + int profile; + const char *name; ///< short name for the profile +} AVProfile; + +enum { + /** + * The codec supports this format via the hw_device_ctx interface. + * + * When selecting this format, AVCodecContext.hw_device_ctx should + * have been set to a device of the specified type before calling + * avcodec_open2(). + */ + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 0x01, + /** + * The codec supports this format via the hw_frames_ctx interface. + * + * When selecting this format for a decoder, + * AVCodecContext.hw_frames_ctx should be set to a suitable frames + * context inside the get_format() callback. The frames context + * must have been created on a device of the specified type. + */ + AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX = 0x02, + /** + * The codec supports this format by some internal method. + * + * This format can be selected without any additional configuration - + * no device or frames context is required. + */ + AV_CODEC_HW_CONFIG_METHOD_INTERNAL = 0x04, + /** + * The codec supports this format by some ad-hoc method. + * + * Additional settings and/or function calls are required. See the + * codec-specific documentation for details. (Methods requiring + * this sort of configuration are deprecated and others should be + * used in preference.) + */ + AV_CODEC_HW_CONFIG_METHOD_AD_HOC = 0x08, +}; + +typedef struct AVCodecHWConfig { + /** + * A hardware pixel format which the codec can use. + */ + enum AVPixelFormat pix_fmt; + /** + * Bit set of AV_CODEC_HW_CONFIG_METHOD_* flags, describing the possible + * setup methods which can be used with this configuration. + */ + int methods; + /** + * The device type associated with the configuration. + * + * Must be set for AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX and + * AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, otherwise unused. + */ + enum AVHWDeviceType device_type; +} AVCodecHWConfig; + +typedef struct AVCodecDefault AVCodecDefault; + +struct AVSubtitle; + +/** + * AVCodec. + */ +typedef struct AVCodec { + /** + * Name of the codec implementation. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + * This is the primary way to find a codec from the user perspective. + */ + const char *name; + /** + * Descriptive name for the codec, meant to be more human readable than name. + * You should use the NULL_IF_CONFIG_SMALL() macro to define it. + */ + const char *long_name; + enum AVMediaType type; + enum AVCodecID id; + /** + * Codec capabilities. + * see AV_CODEC_CAP_* + */ + int capabilities; + const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} + const enum AVPixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 + const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 + const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 + const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 + uint8_t max_lowres; ///< maximum value for lowres supported by the decoder + const AVClass *priv_class; ///< AVClass for the private context + const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} + + /** + * Group name of the codec implementation. + * This is a short symbolic name of the wrapper backing this codec. A + * wrapper uses some kind of external implementation for the codec, such + * as an external library, or a codec implementation provided by the OS or + * the hardware. + * If this field is NULL, this is a builtin, libavcodec native codec. + * If non-NULL, this will be the suffix in AVCodec.name in most cases + * (usually AVCodec.name will be of the form "_"). + */ + const char *wrapper_name; + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavcodec and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + int priv_data_size; + struct AVCodec *next; + /** + * @name Frame-level threading support functions + * @{ + */ + /** + * If defined, called on thread contexts when they are created. + * If the codec allocates writable tables in init(), re-allocate them here. + * priv_data will be set to a copy of the original. + */ + int (*init_thread_copy)(AVCodecContext *); + /** + * Copy necessary context variables from a previous thread context to the current one. + * If not defined, the next thread will start automatically; otherwise, the codec + * must call ff_thread_finish_setup(). + * + * dst and src will (rarely) point to the same context, in which case memcpy should be skipped. + */ + int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src); + /** @} */ + + /** + * Private codec-specific defaults. + */ + const AVCodecDefault *defaults; + + /** + * Initialize codec static data, called from avcodec_register(). + * + * This is not intended for time consuming operations as it is + * run for every codec regardless of that codec being used. + */ + void (*init_static_data)(struct AVCodec *codec); + + int (*init)(AVCodecContext *); + int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size, + const struct AVSubtitle *sub); + /** + * Encode data to an AVPacket. + * + * @param avctx codec context + * @param avpkt output AVPacket (may contain a user-provided buffer) + * @param[in] frame AVFrame containing the raw data to be encoded + * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a + * non-empty packet was returned in avpkt. + * @return 0 on success, negative error code on failure + */ + int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, + int *got_packet_ptr); + int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); + int (*close)(AVCodecContext *); + /** + * Encode API with decoupled packet/frame dataflow. The API is the + * same as the avcodec_ prefixed APIs (avcodec_send_frame() etc.), except + * that: + * - never called if the codec is closed or the wrong type, + * - if AV_CODEC_CAP_DELAY is not set, drain frames are never sent, + * - only one drain frame is ever passed down, + */ + int (*send_frame)(AVCodecContext *avctx, const AVFrame *frame); + int (*receive_packet)(AVCodecContext *avctx, AVPacket *avpkt); + + /** + * Decode API with decoupled packet/frame dataflow. This function is called + * to get one output frame. It should call ff_decode_get_packet() to obtain + * input data. + */ + int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame); + /** + * Flush buffers. + * Will be called when seeking + */ + void (*flush)(AVCodecContext *); + /** + * Internal codec capabilities. + * See FF_CODEC_CAP_* in internal.h + */ + int caps_internal; + + /** + * Decoding only, a comma-separated list of bitstream filters to apply to + * packets before decoding. + */ + const char *bsfs; + + /** + * Array of pointers to hardware configurations supported by the codec, + * or NULL if no hardware supported. The array is terminated by a NULL + * pointer. + * + * The user can only access this field via avcodec_get_hw_config(). + */ + const struct AVCodecHWConfigInternal **hw_configs; +} AVCodec; + +#if FF_API_CODEC_GET_SET +attribute_deprecated +int av_codec_get_max_lowres(const AVCodec *codec); +#endif + +struct MpegEncContext; + +/** + * Retrieve supported hardware configurations for a codec. + * + * Values of index from zero to some maximum return the indexed configuration + * descriptor; all other values return NULL. If the codec does not support + * any hardware configurations then it will always return NULL. + */ +const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index); + +/** + * @defgroup lavc_hwaccel AVHWAccel + * + * @note Nothing in this structure should be accessed by the user. At some + * point in future it will not be externally visible at all. + * + * @{ + */ +typedef struct AVHWAccel { + /** + * Name of the hardware accelerated codec. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + */ + const char *name; + + /** + * Type of codec implemented by the hardware accelerator. + * + * See AVMEDIA_TYPE_xxx + */ + enum AVMediaType type; + + /** + * Codec implemented by the hardware accelerator. + * + * See AV_CODEC_ID_xxx + */ + enum AVCodecID id; + + /** + * Supported pixel format. + * + * Only hardware accelerated formats are supported here. + */ + enum AVPixelFormat pix_fmt; + + /** + * Hardware accelerated codec capabilities. + * see AV_HWACCEL_CODEC_CAP_* + */ + int capabilities; + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavcodec and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + + /** + * Allocate a custom buffer + */ + int (*alloc_frame)(AVCodecContext *avctx, AVFrame *frame); + + /** + * Called at the beginning of each frame or field picture. + * + * Meaningful frame information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * + * Note that buf can be NULL along with buf_size set to 0. + * Otherwise, this means the whole frame is available at this point. + * + * @param avctx the codec context + * @param buf the frame data buffer base + * @param buf_size the size of the frame in bytes + * @return zero if successful, a negative value otherwise + */ + int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Callback for parameter data (SPS/PPS/VPS etc). + * + * Useful for hardware decoders which keep persistent state about the + * video parameters, and need to receive any changes to update that state. + * + * @param avctx the codec context + * @param type the nal unit type + * @param buf the nal unit data buffer + * @param buf_size the size of the nal unit in bytes + * @return zero if successful, a negative value otherwise + */ + int (*decode_params)(AVCodecContext *avctx, int type, const uint8_t *buf, uint32_t buf_size); + + /** + * Callback for each slice. + * + * Meaningful slice information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * The only exception is XvMC, that works on MB level. + * + * @param avctx the codec context + * @param buf the slice data buffer base + * @param buf_size the size of the slice in bytes + * @return zero if successful, a negative value otherwise + */ + int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Called at the end of each frame or field picture. + * + * The whole picture is parsed at this point and can now be sent + * to the hardware accelerator. This function is mandatory. + * + * @param avctx the codec context + * @return zero if successful, a negative value otherwise + */ + int (*end_frame)(AVCodecContext *avctx); + + /** + * Size of per-frame hardware accelerator private data. + * + * Private data is allocated with av_mallocz() before + * AVCodecContext.get_buffer() and deallocated after + * AVCodecContext.release_buffer(). + */ + int frame_priv_data_size; + + /** + * Called for every Macroblock in a slice. + * + * XvMC uses it to replace the ff_mpv_reconstruct_mb(). + * Instead of decoding to raw picture, MB parameters are + * stored in an array provided by the video driver. + * + * @param s the mpeg context + */ + void (*decode_mb)(struct MpegEncContext *s); + + /** + * Initialize the hwaccel private data. + * + * This will be called from ff_get_format(), after hwaccel and + * hwaccel_context are set and the hwaccel private data in AVCodecInternal + * is allocated. + */ + int (*init)(AVCodecContext *avctx); + + /** + * Uninitialize the hwaccel private data. + * + * This will be called from get_format() or avcodec_close(), after hwaccel + * and hwaccel_context are already uninitialized. + */ + int (*uninit)(AVCodecContext *avctx); + + /** + * Size of the private data to allocate in + * AVCodecInternal.hwaccel_priv_data. + */ + int priv_data_size; + + /** + * Internal hwaccel capabilities. + */ + int caps_internal; + + /** + * Fill the given hw_frames context with current codec parameters. Called + * from get_format. Refer to avcodec_get_hw_frames_parameters() for + * details. + * + * This CAN be called before AVHWAccel.init is called, and you must assume + * that avctx->hwaccel_priv_data is invalid. + */ + int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); +} AVHWAccel; + +/** + * HWAccel is experimental and is thus avoided in favor of non experimental + * codecs + */ +#define AV_HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200 + +/** + * Hardware acceleration should be used for decoding even if the codec level + * used is unknown or higher than the maximum supported level reported by the + * hardware driver. + * + * It's generally a good idea to pass this flag unless you have a specific + * reason not to, as hardware tends to under-report supported levels. + */ +#define AV_HWACCEL_FLAG_IGNORE_LEVEL (1 << 0) + +/** + * Hardware acceleration can output YUV pixel formats with a different chroma + * sampling than 4:2:0 and/or other than 8 bits per component. + */ +#define AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH (1 << 1) + +/** + * Hardware acceleration should still be attempted for decoding when the + * codec profile does not match the reported capabilities of the hardware. + * + * For example, this can be used to try to decode baseline profile H.264 + * streams in hardware - it will often succeed, because many streams marked + * as baseline profile actually conform to constrained baseline profile. + * + * @warning If the stream is actually not supported then the behaviour is + * undefined, and may include returning entirely incorrect output + * while indicating success. + */ +#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH (1 << 2) + +/** + * @} + */ + +#if FF_API_AVPICTURE +/** + * @defgroup lavc_picture AVPicture + * + * Functions for working with AVPicture + * @{ + */ + +/** + * Picture data structure. + * + * Up to four components can be stored into it, the last component is + * alpha. + * @deprecated use AVFrame or imgutils functions instead + */ +typedef struct AVPicture { + attribute_deprecated + uint8_t *data[AV_NUM_DATA_POINTERS]; ///< pointers to the image data planes + attribute_deprecated + int linesize[AV_NUM_DATA_POINTERS]; ///< number of bytes per line +} AVPicture; + +/** + * @} + */ +#endif + +enum AVSubtitleType { + SUBTITLE_NONE, + + SUBTITLE_BITMAP, ///< A bitmap, pict will be set + + /** + * Plain text, the text field must be set by the decoder and is + * authoritative. ass and pict fields may contain approximations. + */ + SUBTITLE_TEXT, + + /** + * Formatted text, the ass field must be set by the decoder and is + * authoritative. pict and text fields may contain approximations. + */ + SUBTITLE_ASS, +}; + +#define AV_SUBTITLE_FLAG_FORCED 0x00000001 + +typedef struct AVSubtitleRect { + int x; ///< top left corner of pict, undefined when pict is not set + int y; ///< top left corner of pict, undefined when pict is not set + int w; ///< width of pict, undefined when pict is not set + int h; ///< height of pict, undefined when pict is not set + int nb_colors; ///< number of colors in pict, undefined when pict is not set + +#if FF_API_AVPICTURE + /** + * @deprecated unused + */ + attribute_deprecated + AVPicture pict; +#endif + /** + * data+linesize for the bitmap of this subtitle. + * Can be set for text/ass as well once they are rendered. + */ + uint8_t *data[4]; + int linesize[4]; + + enum AVSubtitleType type; + + char *text; ///< 0 terminated plain UTF-8 text + + /** + * 0 terminated ASS/SSA compatible event line. + * The presentation of this is unaffected by the other values in this + * struct. + */ + char *ass; + + int flags; +} AVSubtitleRect; + +typedef struct AVSubtitle { + uint16_t format; /* 0 = graphics */ + uint32_t start_display_time; /* relative to packet pts, in ms */ + uint32_t end_display_time; /* relative to packet pts, in ms */ + unsigned num_rects; + AVSubtitleRect **rects; + int64_t pts; ///< Same as packet pts, in AV_TIME_BASE +} AVSubtitle; + +/** + * This struct describes the properties of an encoded stream. + * + * sizeof(AVCodecParameters) is not a part of the public ABI, this struct must + * be allocated with avcodec_parameters_alloc() and freed with + * avcodec_parameters_free(). + */ +typedef struct AVCodecParameters { + /** + * General type of the encoded data. + */ + enum AVMediaType codec_type; + /** + * Specific type of the encoded data (the codec used). + */ + enum AVCodecID codec_id; + /** + * Additional information about the codec (corresponds to the AVI FOURCC). + */ + uint32_t codec_tag; + + /** + * Extra binary data needed for initializing the decoder, codec-dependent. + * + * Must be allocated with av_malloc() and will be freed by + * avcodec_parameters_free(). The allocated size of extradata must be at + * least extradata_size + AV_INPUT_BUFFER_PADDING_SIZE, with the padding + * bytes zeroed. + */ + uint8_t *extradata; + /** + * Size of the extradata content in bytes. + */ + int extradata_size; + + /** + * - video: the pixel format, the value corresponds to enum AVPixelFormat. + * - audio: the sample format, the value corresponds to enum AVSampleFormat. + */ + int format; + + /** + * The average bitrate of the encoded data (in bits per second). + */ + int64_t bit_rate; + + /** + * The number of bits per sample in the codedwords. + * + * This is basically the bitrate per sample. It is mandatory for a bunch of + * formats to actually decode them. It's the number of bits for one sample in + * the actual coded bitstream. + * + * This could be for example 4 for ADPCM + * For PCM formats this matches bits_per_raw_sample + * Can be 0 + */ + int bits_per_coded_sample; + + /** + * This is the number of valid bits in each output sample. If the + * sample format has more bits, the least significant bits are additional + * padding bits, which are always 0. Use right shifts to reduce the sample + * to its actual size. For example, audio formats with 24 bit samples will + * have bits_per_raw_sample set to 24, and format set to AV_SAMPLE_FMT_S32. + * To get the original sample use "(int32_t)sample >> 8"." + * + * For ADPCM this might be 12 or 16 or similar + * Can be 0 + */ + int bits_per_raw_sample; + + /** + * Codec-specific bitstream restrictions that the stream conforms to. + */ + int profile; + int level; + + /** + * Video only. The dimensions of the video frame in pixels. + */ + int width; + int height; + + /** + * Video only. The aspect ratio (width / height) which a single pixel + * should have when displayed. + * + * When the aspect ratio is unknown / undefined, the numerator should be + * set to 0 (the denominator may have any value). + */ + AVRational sample_aspect_ratio; + + /** + * Video only. The order of the fields in interlaced video. + */ + enum AVFieldOrder field_order; + + /** + * Video only. Additional colorspace characteristics. + */ + enum AVColorRange color_range; + enum AVColorPrimaries color_primaries; + enum AVColorTransferCharacteristic color_trc; + enum AVColorSpace color_space; + enum AVChromaLocation chroma_location; + + /** + * Video only. Number of delayed frames. + */ + int video_delay; + + /** + * Audio only. The channel layout bitmask. May be 0 if the channel layout is + * unknown or unspecified, otherwise the number of bits set must be equal to + * the channels field. + */ + uint64_t channel_layout; + /** + * Audio only. The number of audio channels. + */ + int channels; + /** + * Audio only. The number of audio samples per second. + */ + int sample_rate; + /** + * Audio only. The number of bytes per coded audio frame, required by some + * formats. + * + * Corresponds to nBlockAlign in WAVEFORMATEX. + */ + int block_align; + /** + * Audio only. Audio frame size, if known. Required by some formats to be static. + */ + int frame_size; + + /** + * Audio only. The amount of padding (in samples) inserted by the encoder at + * the beginning of the audio. I.e. this number of leading decoded samples + * must be discarded by the caller to get the original audio without leading + * padding. + */ + int initial_padding; + /** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + */ + int trailing_padding; + /** + * Audio only. Number of samples to skip after a discontinuity. + */ + int seek_preroll; +} AVCodecParameters; + +/** + * Iterate over all registered codecs. + * + * @param opaque a pointer where libavcodec will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered codec or NULL when the iteration is + * finished + */ +const AVCodec *av_codec_iterate(void **opaque); + +#if FF_API_NEXT +/** + * If c is NULL, returns the first registered codec, + * if c is non-NULL, returns the next registered codec after c, + * or NULL if c is the last one. + */ +attribute_deprecated +AVCodec *av_codec_next(const AVCodec *c); +#endif + +/** + * Return the LIBAVCODEC_VERSION_INT constant. + */ +unsigned avcodec_version(void); + +/** + * Return the libavcodec build-time configuration. + */ +const char *avcodec_configuration(void); + +/** + * Return the libavcodec license. + */ +const char *avcodec_license(void); + +#if FF_API_NEXT +/** + * Register the codec codec and initialize libavcodec. + * + * @warning either this function or avcodec_register_all() must be called + * before any other libavcodec functions. + * + * @see avcodec_register_all() + */ +attribute_deprecated +void avcodec_register(AVCodec *codec); + +/** + * Register all the codecs, parsers and bitstream filters which were enabled at + * configuration time. If you do not call this function you can select exactly + * which formats you want to support, by using the individual registration + * functions. + * + * @see avcodec_register + * @see av_register_codec_parser + * @see av_register_bitstream_filter + */ +attribute_deprecated +void avcodec_register_all(void); +#endif + +/** + * Allocate an AVCodecContext and set its fields to default values. The + * resulting struct should be freed with avcodec_free_context(). + * + * @param codec if non-NULL, allocate private data and initialize defaults + * for the given codec. It is illegal to then call avcodec_open2() + * with a different codec. + * If NULL, then the codec-specific defaults won't be initialized, + * which may result in suboptimal default settings (this is + * important mainly for encoders, e.g. libx264). + * + * @return An AVCodecContext filled with default values or NULL on failure. + */ +AVCodecContext *avcodec_alloc_context3(const AVCodec *codec); + +/** + * Free the codec context and everything associated with it and write NULL to + * the provided pointer. + */ +void avcodec_free_context(AVCodecContext **avctx); + +#if FF_API_GET_CONTEXT_DEFAULTS +/** + * @deprecated This function should not be used, as closing and opening a codec + * context multiple time is not supported. A new codec context should be + * allocated for each new use. + */ +int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec); +#endif + +/** + * Get the AVClass for AVCodecContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *avcodec_get_class(void); + +#if FF_API_COPY_CONTEXT +/** + * Get the AVClass for AVFrame. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *avcodec_get_frame_class(void); + +/** + * Get the AVClass for AVSubtitleRect. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *avcodec_get_subtitle_rect_class(void); + +/** + * Copy the settings of the source AVCodecContext into the destination + * AVCodecContext. The resulting destination codec context will be + * unopened, i.e. you are required to call avcodec_open2() before you + * can use this AVCodecContext to decode/encode video/audio data. + * + * @param dest target codec context, should be initialized with + * avcodec_alloc_context3(NULL), but otherwise uninitialized + * @param src source codec context + * @return AVERROR() on error (e.g. memory allocation error), 0 on success + * + * @deprecated The semantics of this function are ill-defined and it should not + * be used. If you need to transfer the stream parameters from one codec context + * to another, use an intermediate AVCodecParameters instance and the + * avcodec_parameters_from_context() / avcodec_parameters_to_context() + * functions. + */ +attribute_deprecated +int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); +#endif + +/** + * Allocate a new AVCodecParameters and set its fields to default values + * (unknown/invalid/0). The returned struct must be freed with + * avcodec_parameters_free(). + */ +AVCodecParameters *avcodec_parameters_alloc(void); + +/** + * Free an AVCodecParameters instance and everything associated with it and + * write NULL to the supplied pointer. + */ +void avcodec_parameters_free(AVCodecParameters **par); + +/** + * Copy the contents of src to dst. Any allocated fields in dst are freed and + * replaced with newly allocated duplicates of the corresponding fields in src. + * + * @return >= 0 on success, a negative AVERROR code on failure. + */ +int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src); + +/** + * Fill the parameters struct based on the values from the supplied codec + * context. Any allocated fields in par are freed and replaced with duplicates + * of the corresponding fields in codec. + * + * @return >= 0 on success, a negative AVERROR code on failure + */ +int avcodec_parameters_from_context(AVCodecParameters *par, + const AVCodecContext *codec); + +/** + * Fill the codec context based on the values from the supplied codec + * parameters. Any allocated fields in codec that have a corresponding field in + * par are freed and replaced with duplicates of the corresponding field in par. + * Fields in codec that do not have a counterpart in par are not touched. + * + * @return >= 0 on success, a negative AVERROR code on failure. + */ +int avcodec_parameters_to_context(AVCodecContext *codec, + const AVCodecParameters *par); + +/** + * Initialize the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated with avcodec_alloc_context3(). + * + * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), + * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for + * retrieving a codec. + * + * @warning This function is not thread safe! + * + * @note Always call this function before using decoding routines (such as + * @ref avcodec_receive_frame()). + * + * @code + * avcodec_register_all(); + * av_dict_set(&opts, "b", "2.5M", 0); + * codec = avcodec_find_decoder(AV_CODEC_ID_H264); + * if (!codec) + * exit(1); + * + * context = avcodec_alloc_context3(codec); + * + * if (avcodec_open2(context, codec, opts) < 0) + * exit(1); + * @endcode + * + * @param avctx The context to initialize. + * @param codec The codec to open this context for. If a non-NULL codec has been + * previously passed to avcodec_alloc_context3() or + * for this context, then this parameter MUST be either NULL or + * equal to the previously passed codec. + * @param options A dictionary filled with AVCodecContext and codec-private options. + * On return this object will be filled with options that were not found. + * + * @return zero on success, a negative value on error + * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(), + * av_dict_set(), av_opt_find(). + */ +int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); + +/** + * Close a given AVCodecContext and free all the data associated with it + * (but not the AVCodecContext itself). + * + * Calling this function on an AVCodecContext that hasn't been opened will free + * the codec-specific data allocated in avcodec_alloc_context3() with a non-NULL + * codec. Subsequent calls will do nothing. + * + * @note Do not use this function. Use avcodec_free_context() to destroy a + * codec context (either open or closed). Opening and closing a codec context + * multiple times is not supported anymore -- use multiple codec contexts + * instead. + */ +int avcodec_close(AVCodecContext *avctx); + +/** + * Free all allocated data in the given subtitle struct. + * + * @param sub AVSubtitle to free. + */ +void avsubtitle_free(AVSubtitle *sub); + +/** + * @} + */ + +/** + * @addtogroup lavc_packet + * @{ + */ + +/** + * Allocate an AVPacket and set its fields to default values. The resulting + * struct must be freed using av_packet_free(). + * + * @return An AVPacket filled with default values or NULL on failure. + * + * @note this only allocates the AVPacket itself, not the data buffers. Those + * must be allocated through other means such as av_new_packet. + * + * @see av_new_packet + */ +AVPacket *av_packet_alloc(void); + +/** + * Create a new packet that references the same data as src. + * + * This is a shortcut for av_packet_alloc()+av_packet_ref(). + * + * @return newly created AVPacket on success, NULL on error. + * + * @see av_packet_alloc + * @see av_packet_ref + */ +AVPacket *av_packet_clone(const AVPacket *src); + +/** + * Free the packet, if the packet is reference counted, it will be + * unreferenced first. + * + * @param pkt packet to be freed. The pointer will be set to NULL. + * @note passing NULL is a no-op. + */ +void av_packet_free(AVPacket **pkt); + +/** + * Initialize optional fields of a packet with default values. + * + * Note, this does not touch the data and size members, which have to be + * initialized separately. + * + * @param pkt packet + */ +void av_init_packet(AVPacket *pkt); + +/** + * Allocate the payload of a packet and initialize its fields with + * default values. + * + * @param pkt packet + * @param size wanted payload size + * @return 0 if OK, AVERROR_xxx otherwise + */ +int av_new_packet(AVPacket *pkt, int size); + +/** + * Reduce packet size, correctly zeroing padding + * + * @param pkt packet + * @param size new size + */ +void av_shrink_packet(AVPacket *pkt, int size); + +/** + * Increase packet size, correctly zeroing padding + * + * @param pkt packet + * @param grow_by number of bytes by which to increase the size of the packet + */ +int av_grow_packet(AVPacket *pkt, int grow_by); + +/** + * Initialize a reference-counted packet from av_malloc()ed data. + * + * @param pkt packet to be initialized. This function will set the data, size, + * and buf fields, all others are left untouched. + * @param data Data allocated by av_malloc() to be used as packet data. If this + * function returns successfully, the data is owned by the underlying AVBuffer. + * The caller may not access the data through other means. + * @param size size of data in bytes, without the padding. I.e. the full buffer + * size is assumed to be size + AV_INPUT_BUFFER_PADDING_SIZE. + * + * @return 0 on success, a negative AVERROR on error + */ +int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size); + +#if FF_API_AVPACKET_OLD_API +/** + * @warning This is a hack - the packet memory allocation stuff is broken. The + * packet is allocated if it was not really allocated. + * + * @deprecated Use av_packet_ref or av_packet_make_refcounted + */ +attribute_deprecated +int av_dup_packet(AVPacket *pkt); +/** + * Copy packet, including contents + * + * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_ref + */ +attribute_deprecated +int av_copy_packet(AVPacket *dst, const AVPacket *src); + +/** + * Copy packet side data + * + * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_copy_props + */ +attribute_deprecated +int av_copy_packet_side_data(AVPacket *dst, const AVPacket *src); + +/** + * Free a packet. + * + * @deprecated Use av_packet_unref + * + * @param pkt packet to free + */ +attribute_deprecated +void av_free_packet(AVPacket *pkt); +#endif +/** + * Allocate new information of a packet. + * + * @param pkt packet + * @param type side information type + * @param size side information size + * @return pointer to fresh allocated data or NULL otherwise + */ +uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, + int size); + +/** + * Wrap an existing array as a packet side data. + * + * @param pkt packet + * @param type side information type + * @param data the side data array. It must be allocated with the av_malloc() + * family of functions. The ownership of the data is transferred to + * pkt. + * @param size side information size + * @return a non-negative number on success, a negative AVERROR code on + * failure. On failure, the packet is unchanged and the data remains + * owned by the caller. + */ +int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, + uint8_t *data, size_t size); + +/** + * Shrink the already allocated side data buffer + * + * @param pkt packet + * @param type side information type + * @param size new side information size + * @return 0 on success, < 0 on failure + */ +int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, + int size); + +/** + * Get side information from packet. + * + * @param pkt packet + * @param type desired side information type + * @param size pointer for side information size to store (optional) + * @return pointer to data if present or NULL otherwise + */ +uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, + int *size); + +#if FF_API_MERGE_SD_API +attribute_deprecated +int av_packet_merge_side_data(AVPacket *pkt); + +attribute_deprecated +int av_packet_split_side_data(AVPacket *pkt); +#endif + +const char *av_packet_side_data_name(enum AVPacketSideDataType type); + +/** + * Pack a dictionary for use in side_data. + * + * @param dict The dictionary to pack. + * @param size pointer to store the size of the returned data + * @return pointer to data if successful, NULL otherwise + */ +uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size); +/** + * Unpack a dictionary from side_data. + * + * @param data data from side_data + * @param size size of the data + * @param dict the metadata storage dictionary + * @return 0 on success, < 0 on failure + */ +int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict); + + +/** + * Convenience function to free all the side data stored. + * All the other fields stay untouched. + * + * @param pkt packet + */ +void av_packet_free_side_data(AVPacket *pkt); + +/** + * Setup a new reference to the data described by a given packet + * + * If src is reference-counted, setup dst as a new reference to the + * buffer in src. Otherwise allocate a new buffer in dst and copy the + * data from src into it. + * + * All the other fields are copied from src. + * + * @see av_packet_unref + * + * @param dst Destination packet + * @param src Source packet + * + * @return 0 on success, a negative AVERROR on error. + */ +int av_packet_ref(AVPacket *dst, const AVPacket *src); + +/** + * Wipe the packet. + * + * Unreference the buffer referenced by the packet and reset the + * remaining packet fields to their default values. + * + * @param pkt The packet to be unreferenced. + */ +void av_packet_unref(AVPacket *pkt); + +/** + * Move every field in src to dst and reset src. + * + * @see av_packet_unref + * + * @param src Source packet, will be reset + * @param dst Destination packet + */ +void av_packet_move_ref(AVPacket *dst, AVPacket *src); + +/** + * Copy only "properties" fields from src to dst. + * + * Properties for the purpose of this function are all the fields + * beside those related to the packet data (buf, data, size) + * + * @param dst Destination packet + * @param src Source packet + * + * @return 0 on success AVERROR on failure. + */ +int av_packet_copy_props(AVPacket *dst, const AVPacket *src); + +/** + * Ensure the data described by a given packet is reference counted. + * + * @note This function does not ensure that the reference will be writable. + * Use av_packet_make_writable instead for that purpose. + * + * @see av_packet_ref + * @see av_packet_make_writable + * + * @param pkt packet whose data should be made reference counted. + * + * @return 0 on success, a negative AVERROR on error. On failure, the + * packet is unchanged. + */ +int av_packet_make_refcounted(AVPacket *pkt); + +/** + * Create a writable reference for the data described by a given packet, + * avoiding data copy if possible. + * + * @param pkt Packet whose data should be made writable. + * + * @return 0 on success, a negative AVERROR on failure. On failure, the + * packet is unchanged. + */ +int av_packet_make_writable(AVPacket *pkt); + +/** + * Convert valid timing fields (timestamps / durations) in a packet from one + * timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be + * ignored. + * + * @param pkt packet on which the conversion will be performed + * @param tb_src source timebase, in which the timing fields in pkt are + * expressed + * @param tb_dst destination timebase, to which the timing fields will be + * converted + */ +void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst); + +/** + * @} + */ + +/** + * @addtogroup lavc_decoding + * @{ + */ + +/** + * Find a registered decoder with a matching codec ID. + * + * @param id AVCodecID of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder(enum AVCodecID id); + +/** + * Find a registered decoder with the specified name. + * + * @param name name of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder_by_name(const char *name); + +/** + * The default callback for AVCodecContext.get_buffer2(). It is made public so + * it can be called by custom get_buffer2() implementations for decoders without + * AV_CODEC_CAP_DR1 set. + */ +int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags); + +/** + * Modify width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you do not use any horizontal + * padding. + * + * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened. + */ +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); + +/** + * Modify width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you also ensure that all + * line sizes are a multiple of the respective linesize_align[i]. + * + * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened. + */ +void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, + int linesize_align[AV_NUM_DATA_POINTERS]); + +/** + * Converts AVChromaLocation to swscale x/y chroma position. + * + * The positions represent the chroma (0,0) position in a coordinates system + * with luma (0,0) representing the origin and luma(1,1) representing 256,256 + * + * @param xpos horizontal chroma sample position + * @param ypos vertical chroma sample position + */ +int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos); + +/** + * Converts swscale x/y chroma position to AVChromaLocation. + * + * The positions represent the chroma (0,0) position in a coordinates system + * with luma (0,0) representing the origin and luma(1,1) representing 256,256 + * + * @param xpos horizontal chroma sample position + * @param ypos vertical chroma sample position + */ +enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos); + +/** + * Decode the audio frame of size avpkt->size from avpkt->data into frame. + * + * Some decoders may support multiple frames in a single AVPacket. Such + * decoders would then just decode the first frame and the return value would be + * less than the packet size. In this case, avcodec_decode_audio4 has to be + * called again with an AVPacket containing the remaining data in order to + * decode the second frame, etc... Even if no frames are returned, the packet + * needs to be fed to the decoder with remaining data until it is completely + * consumed or an error occurs. + * + * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input + * and output. This means that for some packets they will not immediately + * produce decoded output and need to be flushed at the end of decoding to get + * all the decoded data. Flushing is done by calling this function with packets + * with avpkt->data set to NULL and avpkt->size set to 0 until it stops + * returning samples. It is safe to flush even those decoders that are not + * marked with AV_CODEC_CAP_DELAY, then no samples will be returned. + * + * @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE + * larger than the actual read bytes because some optimized bitstream + * readers read 32 or 64 bits at once and could read over the end. + * + * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() + * before packets may be fed to the decoder. + * + * @param avctx the codec context + * @param[out] frame The AVFrame in which to store decoded audio samples. + * The decoder will allocate a buffer for the decoded frame by + * calling the AVCodecContext.get_buffer2() callback. + * When AVCodecContext.refcounted_frames is set to 1, the frame is + * reference counted and the returned reference belongs to the + * caller. The caller must release the frame using av_frame_unref() + * when the frame is no longer needed. The caller may safely write + * to the frame if av_frame_is_writable() returns 1. + * When AVCodecContext.refcounted_frames is set to 0, the returned + * reference belongs to the decoder and is valid only until the + * next call to this function or until closing or flushing the + * decoder. The caller may not write to it. + * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is + * non-zero. Note that this field being set to zero + * does not mean that an error has occurred. For + * decoders with AV_CODEC_CAP_DELAY set, no given decode + * call is guaranteed to produce a frame. + * @param[in] avpkt The input AVPacket containing the input buffer. + * At least avpkt->data and avpkt->size should be set. Some + * decoders might also require additional fields to be set. + * @return A negative error code is returned if an error occurred during + * decoding, otherwise the number of bytes consumed from the input + * AVPacket is returned. + * +* @deprecated Use avcodec_send_packet() and avcodec_receive_frame(). + */ +attribute_deprecated +int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, + int *got_frame_ptr, const AVPacket *avpkt); + +/** + * Decode the video frame of size avpkt->size from avpkt->data into picture. + * Some decoders may support multiple frames in a single AVPacket, such + * decoders would then just decode the first frame. + * + * @warning The input buffer must be AV_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer buf should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note Codecs which have the AV_CODEC_CAP_DELAY capability set have a delay + * between input and output, these need to be fed with avpkt->data=NULL, + * avpkt->size=0 at the end to return the remaining frames. + * + * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() + * before packets may be fed to the decoder. + * + * @param avctx the codec context + * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * Use av_frame_alloc() to get an AVFrame. The codec will + * allocate memory for the actual bitmap by calling the + * AVCodecContext.get_buffer2() callback. + * When AVCodecContext.refcounted_frames is set to 1, the frame is + * reference counted and the returned reference belongs to the + * caller. The caller must release the frame using av_frame_unref() + * when the frame is no longer needed. The caller may safely write + * to the frame if av_frame_is_writable() returns 1. + * When AVCodecContext.refcounted_frames is set to 0, the returned + * reference belongs to the decoder and is valid only until the + * next call to this function or until closing or flushing the + * decoder. The caller may not write to it. + * + * @param[in] avpkt The input AVPacket containing the input buffer. + * You can create such packet with av_init_packet() and by then setting + * data and size, some decoders might in addition need other fields like + * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least + * fields possible. + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + * + * @deprecated Use avcodec_send_packet() and avcodec_receive_frame(). + */ +attribute_deprecated +int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const AVPacket *avpkt); + +/** + * Decode a subtitle message. + * Return a negative value on error, otherwise return the number of bytes used. + * If no subtitle could be decompressed, got_sub_ptr is zero. + * Otherwise, the subtitle is stored in *sub. + * Note that AV_CODEC_CAP_DR1 is not available for subtitle codecs. This is for + * simplicity, because the performance difference is expect to be negligible + * and reusing a get_buffer written for video codecs would probably perform badly + * due to a potentially very different allocation pattern. + * + * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input + * and output. This means that for some packets they will not immediately + * produce decoded output and need to be flushed at the end of decoding to get + * all the decoded data. Flushing is done by calling this function with packets + * with avpkt->data set to NULL and avpkt->size set to 0 until it stops + * returning subtitles. It is safe to flush even those decoders that are not + * marked with AV_CODEC_CAP_DELAY, then no subtitles will be returned. + * + * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() + * before packets may be fed to the decoder. + * + * @param avctx the codec context + * @param[out] sub The Preallocated AVSubtitle in which the decoded subtitle will be stored, + * must be freed with avsubtitle_free if *got_sub_ptr is set. + * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero. + * @param[in] avpkt The input AVPacket containing the input buffer. + */ +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt); + +/** + * Supply raw packet data as input to a decoder. + * + * Internally, this call will copy relevant AVCodecContext fields, which can + * influence decoding per-packet, and apply them when the packet is actually + * decoded. (For example AVCodecContext.skip_frame, which might direct the + * decoder to drop the frame contained by the packet sent with this function.) + * + * @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE + * larger than the actual read bytes because some optimized bitstream + * readers read 32 or 64 bits at once and could read over the end. + * + * @warning Do not mix this API with the legacy API (like avcodec_decode_video2()) + * on the same AVCodecContext. It will return unexpected results now + * or in future libavcodec versions. + * + * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() + * before packets may be fed to the decoder. + * + * @param avctx codec context + * @param[in] avpkt The input AVPacket. Usually, this will be a single video + * frame, or several complete audio frames. + * Ownership of the packet remains with the caller, and the + * decoder will not write to the packet. The decoder may create + * a reference to the packet data (or copy it if the packet is + * not reference-counted). + * Unlike with older APIs, the packet is always fully consumed, + * and if it contains multiple frames (e.g. some audio codecs), + * will require you to call avcodec_receive_frame() multiple + * times afterwards before you can send a new packet. + * It can be NULL (or an AVPacket with data set to NULL and + * size set to 0); in this case, it is considered a flush + * packet, which signals the end of the stream. Sending the + * first flush packet will return success. Subsequent ones are + * unnecessary and will return AVERROR_EOF. If the decoder + * still has frames buffered, it will return them after sending + * a flush packet. + * + * @return 0 on success, otherwise negative error code: + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_frame() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). + * AVERROR_EOF: the decoder has been flushed, and no new packets can + * be sent to it (also returned if more than 1 flush + * packet is sent) + * AVERROR(EINVAL): codec not opened, it is an encoder, or requires flush + * AVERROR(ENOMEM): failed to add packet to internal queue, or similar + * other errors: legitimate decoding errors + */ +int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); + +/** + * Return decoded output data from a decoder. + * + * @param avctx codec context + * @param frame This will be set to a reference-counted video or audio + * frame (depending on the decoder type) allocated by the + * decoder. Note that the function will always call + * av_frame_unref(frame) before doing anything else. + * + * @return + * 0: success, a frame was returned + * AVERROR(EAGAIN): output is not available in this state - user must try + * to send new input + * AVERROR_EOF: the decoder has been fully flushed, and there will be + * no more output frames + * AVERROR(EINVAL): codec not opened, or it is an encoder + * AVERROR_INPUT_CHANGED: current decoded frame has changed parameters + * with respect to first decoded frame. Applicable + * when flag AV_CODEC_FLAG_DROPCHANGED is set. + * other negative values: legitimate decoding errors + */ +int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); + +/** + * Supply a raw video or audio frame to the encoder. Use avcodec_receive_packet() + * to retrieve buffered output packets. + * + * @param avctx codec context + * @param[in] frame AVFrame containing the raw audio or video frame to be encoded. + * Ownership of the frame remains with the caller, and the + * encoder will not write to the frame. The encoder may create + * a reference to the frame data (or copy it if the frame is + * not reference-counted). + * It can be NULL, in which case it is considered a flush + * packet. This signals the end of the stream. If the encoder + * still has packets buffered, it will return them after this + * call. Once flushing mode has been entered, additional flush + * packets are ignored, and sending frames will return + * AVERROR_EOF. + * + * For audio: + * If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame + * can have any number of samples. + * If it is not set, frame->nb_samples must be equal to + * avctx->frame_size for all frames except the last. + * The final frame may be smaller than avctx->frame_size. + * @return 0 on success, otherwise negative error code: + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_packet() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). + * AVERROR_EOF: the encoder has been flushed, and no new frames can + * be sent to it + * AVERROR(EINVAL): codec not opened, refcounted_frames not set, it is a + * decoder, or requires flush + * AVERROR(ENOMEM): failed to add packet to internal queue, or similar + * other errors: legitimate decoding errors + */ +int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); + +/** + * Read encoded data from the encoder. + * + * @param avctx codec context + * @param avpkt This will be set to a reference-counted packet allocated by the + * encoder. Note that the function will always call + * av_frame_unref(frame) before doing anything else. + * @return 0 on success, otherwise negative error code: + * AVERROR(EAGAIN): output is not available in the current state - user + * must try to send input + * AVERROR_EOF: the encoder has been fully flushed, and there will be + * no more output packets + * AVERROR(EINVAL): codec not opened, or it is an encoder + * other errors: legitimate decoding errors + */ +int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt); + +/** + * Create and return a AVHWFramesContext with values adequate for hardware + * decoding. This is meant to get called from the get_format callback, and is + * a helper for preparing a AVHWFramesContext for AVCodecContext.hw_frames_ctx. + * This API is for decoding with certain hardware acceleration modes/APIs only. + * + * The returned AVHWFramesContext is not initialized. The caller must do this + * with av_hwframe_ctx_init(). + * + * Calling this function is not a requirement, but makes it simpler to avoid + * codec or hardware API specific details when manually allocating frames. + * + * Alternatively to this, an API user can set AVCodecContext.hw_device_ctx, + * which sets up AVCodecContext.hw_frames_ctx fully automatically, and makes + * it unnecessary to call this function or having to care about + * AVHWFramesContext initialization at all. + * + * There are a number of requirements for calling this function: + * + * - It must be called from get_format with the same avctx parameter that was + * passed to get_format. Calling it outside of get_format is not allowed, and + * can trigger undefined behavior. + * - The function is not always supported (see description of return values). + * Even if this function returns successfully, hwaccel initialization could + * fail later. (The degree to which implementations check whether the stream + * is actually supported varies. Some do this check only after the user's + * get_format callback returns.) + * - The hw_pix_fmt must be one of the choices suggested by get_format. If the + * user decides to use a AVHWFramesContext prepared with this API function, + * the user must return the same hw_pix_fmt from get_format. + * - The device_ref passed to this function must support the given hw_pix_fmt. + * - After calling this API function, it is the user's responsibility to + * initialize the AVHWFramesContext (returned by the out_frames_ref parameter), + * and to set AVCodecContext.hw_frames_ctx to it. If done, this must be done + * before returning from get_format (this is implied by the normal + * AVCodecContext.hw_frames_ctx API rules). + * - The AVHWFramesContext parameters may change every time time get_format is + * called. Also, AVCodecContext.hw_frames_ctx is reset before get_format. So + * you are inherently required to go through this process again on every + * get_format call. + * - It is perfectly possible to call this function without actually using + * the resulting AVHWFramesContext. One use-case might be trying to reuse a + * previously initialized AVHWFramesContext, and calling this API function + * only to test whether the required frame parameters have changed. + * - Fields that use dynamically allocated values of any kind must not be set + * by the user unless setting them is explicitly allowed by the documentation. + * If the user sets AVHWFramesContext.free and AVHWFramesContext.user_opaque, + * the new free callback must call the potentially set previous free callback. + * This API call may set any dynamically allocated fields, including the free + * callback. + * + * The function will set at least the following fields on AVHWFramesContext + * (potentially more, depending on hwaccel API): + * + * - All fields set by av_hwframe_ctx_alloc(). + * - Set the format field to hw_pix_fmt. + * - Set the sw_format field to the most suited and most versatile format. (An + * implication is that this will prefer generic formats over opaque formats + * with arbitrary restrictions, if possible.) + * - Set the width/height fields to the coded frame size, rounded up to the + * API-specific minimum alignment. + * - Only _if_ the hwaccel requires a pre-allocated pool: set the initial_pool_size + * field to the number of maximum reference surfaces possible with the codec, + * plus 1 surface for the user to work (meaning the user can safely reference + * at most 1 decoded surface at a time), plus additional buffering introduced + * by frame threading. If the hwaccel does not require pre-allocation, the + * field is left to 0, and the decoder will allocate new surfaces on demand + * during decoding. + * - Possibly AVHWFramesContext.hwctx fields, depending on the underlying + * hardware API. + * + * Essentially, out_frames_ref returns the same as av_hwframe_ctx_alloc(), but + * with basic frame parameters set. + * + * The function is stateless, and does not change the AVCodecContext or the + * device_ref AVHWDeviceContext. + * + * @param avctx The context which is currently calling get_format, and which + * implicitly contains all state needed for filling the returned + * AVHWFramesContext properly. + * @param device_ref A reference to the AVHWDeviceContext describing the device + * which will be used by the hardware decoder. + * @param hw_pix_fmt The hwaccel format you are going to return from get_format. + * @param out_frames_ref On success, set to a reference to an _uninitialized_ + * AVHWFramesContext, created from the given device_ref. + * Fields will be set to values required for decoding. + * Not changed if an error is returned. + * @return zero on success, a negative value on error. The following error codes + * have special semantics: + * AVERROR(ENOENT): the decoder does not support this functionality. Setup + * is always manual, or it is a decoder which does not + * support setting AVCodecContext.hw_frames_ctx at all, + * or it is a software format. + * AVERROR(EINVAL): it is known that hardware decoding is not supported for + * this configuration, or the device_ref is not supported + * for the hwaccel referenced by hw_pix_fmt. + */ +int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, + AVBufferRef *device_ref, + enum AVPixelFormat hw_pix_fmt, + AVBufferRef **out_frames_ref); + + + +/** + * @defgroup lavc_parsing Frame parsing + * @{ + */ + +enum AVPictureStructure { + AV_PICTURE_STRUCTURE_UNKNOWN, //< unknown + AV_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field + AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field + AV_PICTURE_STRUCTURE_FRAME, //< coded as frame +}; + +typedef struct AVCodecParserContext { + void *priv_data; + struct AVCodecParser *parser; + int64_t frame_offset; /* offset of the current frame */ + int64_t cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + int64_t next_frame_offset; /* offset of the next frame */ + /* video info */ + int pict_type; /* XXX: Put it back in AVCodecContext. */ + /** + * This field is used for proper frame duration computation in lavf. + * It signals, how much longer the frame duration of the current frame + * is compared to normal frame duration. + * + * frame_duration = (1 + repeat_pict) * time_base + * + * It is used by codecs like H.264 to display telecined material. + */ + int repeat_pict; /* XXX: Put it back in AVCodecContext. */ + int64_t pts; /* pts of the current frame */ + int64_t dts; /* dts of the current frame */ + + /* private data */ + int64_t last_pts; + int64_t last_dts; + int fetch_timestamp; + +#define AV_PARSER_PTS_NB 4 + int cur_frame_start_index; + int64_t cur_frame_offset[AV_PARSER_PTS_NB]; + int64_t cur_frame_pts[AV_PARSER_PTS_NB]; + int64_t cur_frame_dts[AV_PARSER_PTS_NB]; + + int flags; +#define PARSER_FLAG_COMPLETE_FRAMES 0x0001 +#define PARSER_FLAG_ONCE 0x0002 +/// Set if the parser has a valid file offset +#define PARSER_FLAG_FETCHED_OFFSET 0x0004 +#define PARSER_FLAG_USE_CODEC_TS 0x1000 + + int64_t offset; ///< byte offset from starting packet start + int64_t cur_frame_end[AV_PARSER_PTS_NB]; + + /** + * Set by parser to 1 for key frames and 0 for non-key frames. + * It is initialized to -1, so if the parser doesn't set this flag, + * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames + * will be used. + */ + int key_frame; + +#if FF_API_CONVERGENCE_DURATION + /** + * @deprecated unused + */ + attribute_deprecated + int64_t convergence_duration; +#endif + + // Timestamp generation support: + /** + * Synchronization point for start of timestamp generation. + * + * Set to >0 for sync point, 0 for no sync point and <0 for undefined + * (default). + * + * For example, this corresponds to presence of H.264 buffering period + * SEI message. + */ + int dts_sync_point; + + /** + * Offset of the current timestamp against last timestamp sync point in + * units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain a valid timestamp offset. + * + * Note that the timestamp of sync point has usually a nonzero + * dts_ref_dts_delta, which refers to the previous sync point. Offset of + * the next frame after timestamp sync point will be usually 1. + * + * For example, this corresponds to H.264 cpb_removal_delay. + */ + int dts_ref_dts_delta; + + /** + * Presentation delay of current frame in units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain valid non-negative timestamp delta (presentation time of a frame + * must not lie in the past). + * + * This delay represents the difference between decoding and presentation + * time of the frame. + * + * For example, this corresponds to H.264 dpb_output_delay. + */ + int pts_dts_delta; + + /** + * Position of the packet in file. + * + * Analogous to cur_frame_pts/dts + */ + int64_t cur_frame_pos[AV_PARSER_PTS_NB]; + + /** + * Byte position of currently parsed frame in stream. + */ + int64_t pos; + + /** + * Previous frame byte position. + */ + int64_t last_pos; + + /** + * Duration of the current frame. + * For audio, this is in units of 1 / AVCodecContext.sample_rate. + * For all other types, this is in units of AVCodecContext.time_base. + */ + int duration; + + enum AVFieldOrder field_order; + + /** + * Indicate whether a picture is coded as a frame, top field or bottom field. + * + * For example, H.264 field_pic_flag equal to 0 corresponds to + * AV_PICTURE_STRUCTURE_FRAME. An H.264 picture with field_pic_flag + * equal to 1 and bottom_field_flag equal to 0 corresponds to + * AV_PICTURE_STRUCTURE_TOP_FIELD. + */ + enum AVPictureStructure picture_structure; + + /** + * Picture number incremented in presentation or output order. + * This field may be reinitialized at the first picture of a new sequence. + * + * For example, this corresponds to H.264 PicOrderCnt. + */ + int output_picture_number; + + /** + * Dimensions of the decoded video intended for presentation. + */ + int width; + int height; + + /** + * Dimensions of the coded video. + */ + int coded_width; + int coded_height; + + /** + * The format of the coded data, corresponds to enum AVPixelFormat for video + * and for enum AVSampleFormat for audio. + * + * Note that a decoder can have considerable freedom in how exactly it + * decodes the data, so the format reported here might be different from the + * one returned by a decoder. + */ + int format; +} AVCodecParserContext; + +typedef struct AVCodecParser { + int codec_ids[5]; /* several codec IDs are permitted */ + int priv_data_size; + int (*parser_init)(AVCodecParserContext *s); + /* This callback never returns an error, a negative value means that + * the frame start was in a previous packet. */ + int (*parser_parse)(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + void (*parser_close)(AVCodecParserContext *s); + int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); + struct AVCodecParser *next; +} AVCodecParser; + +/** + * Iterate over all registered codec parsers. + * + * @param opaque a pointer where libavcodec will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered codec parser or NULL when the iteration is + * finished + */ +const AVCodecParser *av_parser_iterate(void **opaque); + +attribute_deprecated +AVCodecParser *av_parser_next(const AVCodecParser *c); + +attribute_deprecated +void av_register_codec_parser(AVCodecParser *parser); +AVCodecParserContext *av_parser_init(int codec_id); + +/** + * Parse a packet. + * + * @param s parser context. + * @param avctx codec context. + * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished. + * @param poutbuf_size set to size of parsed buffer or zero if not yet finished. + * @param buf input buffer. + * @param buf_size buffer size in bytes without the padding. I.e. the full buffer + size is assumed to be buf_size + AV_INPUT_BUFFER_PADDING_SIZE. + To signal EOF, this should be 0 (so that the last frame + can be output). + * @param pts input presentation timestamp. + * @param dts input decoding timestamp. + * @param pos input byte position in stream. + * @return the number of bytes of the input bitstream used. + * + * Example: + * @code + * while(in_len){ + * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, + * in_data, in_len, + * pts, dts, pos); + * in_data += len; + * in_len -= len; + * + * if(size) + * decode_frame(data, size); + * } + * @endcode + */ +int av_parser_parse2(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts, + int64_t pos); + +/** + * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed + * @deprecated use AVBitStreamFilter + */ +int av_parser_change(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_parser_close(AVCodecParserContext *s); + +/** + * @} + * @} + */ + +/** + * @addtogroup lavc_encoding + * @{ + */ + +/** + * Find a registered encoder with a matching codec ID. + * + * @param id AVCodecID of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder(enum AVCodecID id); + +/** + * Find a registered encoder with the specified name. + * + * @param name name of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder_by_name(const char *name); + +/** + * Encode a frame of audio. + * + * Takes input samples from frame and writes the next output packet, if + * available, to avpkt. The output packet does not necessarily contain data for + * the most recent frame, as encoders can delay, split, and combine input frames + * internally as needed. + * + * @param avctx codec context + * @param avpkt output AVPacket. + * The user can supply an output buffer by setting + * avpkt->data and avpkt->size prior to calling the + * function, but if the size of the user-provided data is not + * large enough, encoding will fail. If avpkt->data and + * avpkt->size are set, avpkt->destruct must also be set. All + * other AVPacket fields will be reset by the encoder using + * av_init_packet(). If avpkt->data is NULL, the encoder will + * allocate it. The encoder will set avpkt->size to the size + * of the output packet. + * + * If this function fails or produces no output, avpkt will be + * freed using av_packet_unref(). + * @param[in] frame AVFrame containing the raw audio data to be encoded. + * May be NULL when flushing an encoder that has the + * AV_CODEC_CAP_DELAY capability set. + * If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame + * can have any number of samples. + * If it is not set, frame->nb_samples must be equal to + * avctx->frame_size for all frames except the last. + * The final frame may be smaller than avctx->frame_size. + * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the + * output packet is non-empty, and to 0 if it is + * empty. If the function returns an error, the + * packet can be assumed to be invalid, and the + * value of got_packet_ptr is undefined and should + * not be used. + * @return 0 on success, negative error code on failure + * + * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead + */ +attribute_deprecated +int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr); + +/** + * Encode a frame of video. + * + * Takes input raw video data from frame and writes the next output packet, if + * available, to avpkt. The output packet does not necessarily contain data for + * the most recent frame, as encoders can delay and reorder input frames + * internally as needed. + * + * @param avctx codec context + * @param avpkt output AVPacket. + * The user can supply an output buffer by setting + * avpkt->data and avpkt->size prior to calling the + * function, but if the size of the user-provided data is not + * large enough, encoding will fail. All other AVPacket fields + * will be reset by the encoder using av_init_packet(). If + * avpkt->data is NULL, the encoder will allocate it. + * The encoder will set avpkt->size to the size of the + * output packet. The returned data (if any) belongs to the + * caller, he is responsible for freeing it. + * + * If this function fails or produces no output, avpkt will be + * freed using av_packet_unref(). + * @param[in] frame AVFrame containing the raw video data to be encoded. + * May be NULL when flushing an encoder that has the + * AV_CODEC_CAP_DELAY capability set. + * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the + * output packet is non-empty, and to 0 if it is + * empty. If the function returns an error, the + * packet can be assumed to be invalid, and the + * value of got_packet_ptr is undefined and should + * not be used. + * @return 0 on success, negative error code on failure + * + * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead + */ +attribute_deprecated +int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr); + +int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVSubtitle *sub); + + +/** + * @} + */ + +#if FF_API_AVPICTURE +/** + * @addtogroup lavc_picture + * @{ + */ + +/** + * @deprecated unused + */ +attribute_deprecated +int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, int height); + +/** + * @deprecated unused + */ +attribute_deprecated +void avpicture_free(AVPicture *picture); + +/** + * @deprecated use av_image_fill_arrays() instead. + */ +attribute_deprecated +int avpicture_fill(AVPicture *picture, const uint8_t *ptr, + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * @deprecated use av_image_copy_to_buffer() instead. + */ +attribute_deprecated +int avpicture_layout(const AVPicture *src, enum AVPixelFormat pix_fmt, + int width, int height, + unsigned char *dest, int dest_size); + +/** + * @deprecated use av_image_get_buffer_size() instead. + */ +attribute_deprecated +int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height); + +/** + * @deprecated av_image_copy() instead. + */ +attribute_deprecated +void av_picture_copy(AVPicture *dst, const AVPicture *src, + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * @deprecated unused + */ +attribute_deprecated +int av_picture_crop(AVPicture *dst, const AVPicture *src, + enum AVPixelFormat pix_fmt, int top_band, int left_band); + +/** + * @deprecated unused + */ +attribute_deprecated +int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum AVPixelFormat pix_fmt, + int padtop, int padbottom, int padleft, int padright, int *color); + +/** + * @} + */ +#endif + +/** + * @defgroup lavc_misc Utility functions + * @ingroup libavc + * + * Miscellaneous utility functions related to both encoding and decoding + * (or neither). + * @{ + */ + +/** + * @defgroup lavc_misc_pixfmt Pixel formats + * + * Functions for working with pixel formats. + * @{ + */ + +#if FF_API_GETCHROMA +/** + * @deprecated Use av_pix_fmt_get_chroma_sub_sample + */ + +attribute_deprecated +void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift); +#endif + +/** + * Return a value representing the fourCC code associated to the + * pixel format pix_fmt, or 0 if no associated fourCC code can be + * found. + */ +unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat pix_fmt); + +/** + * @deprecated see av_get_pix_fmt_loss() + */ +int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, + int has_alpha); + +/** + * Find the best pixel format to convert to given a certain source pixel + * format. When converting from one pixel format to another, information loss + * may occur. For example, when converting from RGB24 to GRAY, the color + * information will be lost. Similarly, other losses occur when converting from + * some formats to other formats. avcodec_find_best_pix_fmt_of_2() searches which of + * the given pixel formats should be used to suffer the least amount of loss. + * The pixel formats from which it chooses one, are determined by the + * pix_fmt_list parameter. + * + * + * @param[in] pix_fmt_list AV_PIX_FMT_NONE terminated array of pixel formats to choose from + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. + * @return The best pixel format to convert to or -1 if none was found. + */ +enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list, + enum AVPixelFormat src_pix_fmt, + int has_alpha, int *loss_ptr); + +/** + * @deprecated see av_find_best_pix_fmt_of_2() + */ +enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); + +attribute_deprecated +enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); + +enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat * fmt); + +/** + * @} + */ + +#if FF_API_TAG_STRING +/** + * Put a string representing the codec tag codec_tag in buf. + * + * @param buf buffer to place codec tag in + * @param buf_size size in bytes of buf + * @param codec_tag codec tag to assign + * @return the length of the string that would have been generated if + * enough space had been available, excluding the trailing null + * + * @deprecated see av_fourcc_make_string() and av_fourcc2str(). + */ +attribute_deprecated +size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag); +#endif + +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); + +/** + * Return a name for the specified profile, if available. + * + * @param codec the codec that is searched for the given profile + * @param profile the profile value for which a name is requested + * @return A name for the profile if found, NULL otherwise. + */ +const char *av_get_profile_name(const AVCodec *codec, int profile); + +/** + * Return a name for the specified profile, if available. + * + * @param codec_id the ID of the codec to which the requested profile belongs + * @param profile the profile value for which a name is requested + * @return A name for the profile if found, NULL otherwise. + * + * @note unlike av_get_profile_name(), which searches a list of profiles + * supported by a specific decoder or encoder implementation, this + * function searches the list of profiles from the AVCodecDescriptor + */ +const char *avcodec_profile_name(enum AVCodecID codec_id, int profile); + +int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); +int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); +//FIXME func typedef + +/** + * Fill AVFrame audio data and linesize pointers. + * + * The buffer buf must be a preallocated buffer with a size big enough + * to contain the specified samples amount. The filled AVFrame data + * pointers will point to this buffer. + * + * AVFrame extended_data channel pointers are allocated if necessary for + * planar audio. + * + * @param frame the AVFrame + * frame->nb_samples must be set prior to calling the + * function. This function fills in frame->data, + * frame->extended_data, frame->linesize[0]. + * @param nb_channels channel count + * @param sample_fmt sample format + * @param buf buffer to use for frame data + * @param buf_size size of buffer + * @param align plane size sample alignment (0 = default) + * @return >=0 on success, negative error code on failure + * @todo return the size in bytes required to store the samples in + * case of success, at the next libavutil bump + */ +int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, + enum AVSampleFormat sample_fmt, const uint8_t *buf, + int buf_size, int align); + +/** + * Reset the internal decoder state / flush internal buffers. Should be called + * e.g. when seeking or when switching to a different stream. + * + * @note when refcounted frames are not used (i.e. avctx->refcounted_frames is 0), + * this invalidates the frames previously returned from the decoder. When + * refcounted frames are used, the decoder just releases any references it might + * keep internally, but the caller's reference remains valid. + */ +void avcodec_flush_buffers(AVCodecContext *avctx); + +/** + * Return codec bits per sample. + * + * @param[in] codec_id the codec + * @return Number of bits per sample or zero if unknown for the given codec. + */ +int av_get_bits_per_sample(enum AVCodecID codec_id); + +/** + * Return the PCM codec associated with a sample format. + * @param be endianness, 0 for little, 1 for big, + * -1 (or anything else) for native + * @return AV_CODEC_ID_PCM_* or AV_CODEC_ID_NONE + */ +enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be); + +/** + * Return codec bits per sample. + * Only return non-zero if the bits per sample is exactly correct, not an + * approximation. + * + * @param[in] codec_id the codec + * @return Number of bits per sample or zero if unknown for the given codec. + */ +int av_get_exact_bits_per_sample(enum AVCodecID codec_id); + +/** + * Return audio frame duration. + * + * @param avctx codec context + * @param frame_bytes size of the frame, or 0 if unknown + * @return frame duration, in samples, if known. 0 if not able to + * determine. + */ +int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes); + +/** + * This function is the same as av_get_audio_frame_duration(), except it works + * with AVCodecParameters instead of an AVCodecContext. + */ +int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes); + +#if FF_API_OLD_BSF +typedef struct AVBitStreamFilterContext { + void *priv_data; + const struct AVBitStreamFilter *filter; + AVCodecParserContext *parser; + struct AVBitStreamFilterContext *next; + /** + * Internal default arguments, used if NULL is passed to av_bitstream_filter_filter(). + * Not for access by library users. + */ + char *args; +} AVBitStreamFilterContext; +#endif + +typedef struct AVBSFInternal AVBSFInternal; + +/** + * The bitstream filter state. + * + * This struct must be allocated with av_bsf_alloc() and freed with + * av_bsf_free(). + * + * The fields in the struct will only be changed (by the caller or by the + * filter) as described in their documentation, and are to be considered + * immutable otherwise. + */ +typedef struct AVBSFContext { + /** + * A class for logging and AVOptions + */ + const AVClass *av_class; + + /** + * The bitstream filter this context is an instance of. + */ + const struct AVBitStreamFilter *filter; + + /** + * Opaque libavcodec internal data. Must not be touched by the caller in any + * way. + */ + AVBSFInternal *internal; + + /** + * Opaque filter-specific private data. If filter->priv_class is non-NULL, + * this is an AVOptions-enabled struct. + */ + void *priv_data; + + /** + * Parameters of the input stream. This field is allocated in + * av_bsf_alloc(), it needs to be filled by the caller before + * av_bsf_init(). + */ + AVCodecParameters *par_in; + + /** + * Parameters of the output stream. This field is allocated in + * av_bsf_alloc(), it is set by the filter in av_bsf_init(). + */ + AVCodecParameters *par_out; + + /** + * The timebase used for the timestamps of the input packets. Set by the + * caller before av_bsf_init(). + */ + AVRational time_base_in; + + /** + * The timebase used for the timestamps of the output packets. Set by the + * filter in av_bsf_init(). + */ + AVRational time_base_out; +} AVBSFContext; + +typedef struct AVBitStreamFilter { + const char *name; + + /** + * A list of codec ids supported by the filter, terminated by + * AV_CODEC_ID_NONE. + * May be NULL, in that case the bitstream filter works with any codec id. + */ + const enum AVCodecID *codec_ids; + + /** + * A class for the private data, used to declare bitstream filter private + * AVOptions. This field is NULL for bitstream filters that do not declare + * any options. + * + * If this field is non-NULL, the first member of the filter private data + * must be a pointer to AVClass, which will be set by libavcodec generic + * code to this class. + */ + const AVClass *priv_class; + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavcodec and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + + int priv_data_size; + int (*init)(AVBSFContext *ctx); + int (*filter)(AVBSFContext *ctx, AVPacket *pkt); + void (*close)(AVBSFContext *ctx); + void (*flush)(AVBSFContext *ctx); +} AVBitStreamFilter; + +#if FF_API_OLD_BSF +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use the new bitstream filtering API (using AVBSFContext). + */ +attribute_deprecated +void av_register_bitstream_filter(AVBitStreamFilter *bsf); +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_get_by_name(), av_bsf_alloc(), and av_bsf_init() + * from the new bitstream filtering API (using AVBSFContext). + */ +attribute_deprecated +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_send_packet() and av_bsf_receive_packet() from the + * new bitstream filtering API (using AVBSFContext). + */ +attribute_deprecated +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_free() from the new bitstream filtering API (using + * AVBSFContext). + */ +attribute_deprecated +void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_iterate() from the new bitstream filtering API (using + * AVBSFContext). + */ +attribute_deprecated +const AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f); +#endif + +/** + * @return a bitstream filter with the specified name or NULL if no such + * bitstream filter exists. + */ +const AVBitStreamFilter *av_bsf_get_by_name(const char *name); + +/** + * Iterate over all registered bitstream filters. + * + * @param opaque a pointer where libavcodec will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered bitstream filter or NULL when the iteration is + * finished + */ +const AVBitStreamFilter *av_bsf_iterate(void **opaque); +#if FF_API_NEXT +attribute_deprecated +const AVBitStreamFilter *av_bsf_next(void **opaque); +#endif + +/** + * Allocate a context for a given bitstream filter. The caller must fill in the + * context parameters as described in the documentation and then call + * av_bsf_init() before sending any data to the filter. + * + * @param filter the filter for which to allocate an instance. + * @param ctx a pointer into which the pointer to the newly-allocated context + * will be written. It must be freed with av_bsf_free() after the + * filtering is done. + * + * @return 0 on success, a negative AVERROR code on failure + */ +int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx); + +/** + * Prepare the filter for use, after all the parameters and options have been + * set. + */ +int av_bsf_init(AVBSFContext *ctx); + +/** + * Submit a packet for filtering. + * + * After sending each packet, the filter must be completely drained by calling + * av_bsf_receive_packet() repeatedly until it returns AVERROR(EAGAIN) or + * AVERROR_EOF. + * + * @param pkt the packet to filter. The bitstream filter will take ownership of + * the packet and reset the contents of pkt. pkt is not touched if an error occurs. + * This parameter may be NULL, which signals the end of the stream (i.e. no more + * packets will be sent). That will cause the filter to output any packets it + * may have buffered internally. + * + * @return 0 on success, a negative AVERROR on error. + */ +int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt); + +/** + * Retrieve a filtered packet. + * + * @param[out] pkt this struct will be filled with the contents of the filtered + * packet. It is owned by the caller and must be freed using + * av_packet_unref() when it is no longer needed. + * This parameter should be "clean" (i.e. freshly allocated + * with av_packet_alloc() or unreffed with av_packet_unref()) + * when this function is called. If this function returns + * successfully, the contents of pkt will be completely + * overwritten by the returned data. On failure, pkt is not + * touched. + * + * @return 0 on success. AVERROR(EAGAIN) if more packets need to be sent to the + * filter (using av_bsf_send_packet()) to get more output. AVERROR_EOF if there + * will be no further output from the filter. Another negative AVERROR value if + * an error occurs. + * + * @note one input packet may result in several output packets, so after sending + * a packet with av_bsf_send_packet(), this function needs to be called + * repeatedly until it stops returning 0. It is also possible for a filter to + * output fewer packets than were sent to it, so this function may return + * AVERROR(EAGAIN) immediately after a successful av_bsf_send_packet() call. + */ +int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt); + +/** + * Reset the internal bitstream filter state / flush internal buffers. + */ +void av_bsf_flush(AVBSFContext *ctx); + +/** + * Free a bitstream filter context and everything associated with it; write NULL + * into the supplied pointer. + */ +void av_bsf_free(AVBSFContext **ctx); + +/** + * Get the AVClass for AVBSFContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *av_bsf_get_class(void); + +/** + * Structure for chain/list of bitstream filters. + * Empty list can be allocated by av_bsf_list_alloc(). + */ +typedef struct AVBSFList AVBSFList; + +/** + * Allocate empty list of bitstream filters. + * The list must be later freed by av_bsf_list_free() + * or finalized by av_bsf_list_finalize(). + * + * @return Pointer to @ref AVBSFList on success, NULL in case of failure + */ +AVBSFList *av_bsf_list_alloc(void); + +/** + * Free list of bitstream filters. + * + * @param lst Pointer to pointer returned by av_bsf_list_alloc() + */ +void av_bsf_list_free(AVBSFList **lst); + +/** + * Append bitstream filter to the list of bitstream filters. + * + * @param lst List to append to + * @param bsf Filter context to be appended + * + * @return >=0 on success, negative AVERROR in case of failure + */ +int av_bsf_list_append(AVBSFList *lst, AVBSFContext *bsf); + +/** + * Construct new bitstream filter context given it's name and options + * and append it to the list of bitstream filters. + * + * @param lst List to append to + * @param bsf_name Name of the bitstream filter + * @param options Options for the bitstream filter, can be set to NULL + * + * @return >=0 on success, negative AVERROR in case of failure + */ +int av_bsf_list_append2(AVBSFList *lst, const char * bsf_name, AVDictionary **options); +/** + * Finalize list of bitstream filters. + * + * This function will transform @ref AVBSFList to single @ref AVBSFContext, + * so the whole chain of bitstream filters can be treated as single filter + * freshly allocated by av_bsf_alloc(). + * If the call is successful, @ref AVBSFList structure is freed and lst + * will be set to NULL. In case of failure, caller is responsible for + * freeing the structure by av_bsf_list_free() + * + * @param lst Filter list structure to be transformed + * @param[out] bsf Pointer to be set to newly created @ref AVBSFContext structure + * representing the chain of bitstream filters + * + * @return >=0 on success, negative AVERROR in case of failure + */ +int av_bsf_list_finalize(AVBSFList **lst, AVBSFContext **bsf); + +/** + * Parse string describing list of bitstream filters and create single + * @ref AVBSFContext describing the whole chain of bitstream filters. + * Resulting @ref AVBSFContext can be treated as any other @ref AVBSFContext freshly + * allocated by av_bsf_alloc(). + * + * @param str String describing chain of bitstream filters in format + * `bsf1[=opt1=val1:opt2=val2][,bsf2]` + * @param[out] bsf Pointer to be set to newly created @ref AVBSFContext structure + * representing the chain of bitstream filters + * + * @return >=0 on success, negative AVERROR in case of failure + */ +int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf); + +/** + * Get null/pass-through bitstream filter. + * + * @param[out] bsf Pointer to be set to new instance of pass-through bitstream filter + * + * @return + */ +int av_bsf_get_null_filter(AVBSFContext **bsf); + +/* memory */ + +/** + * Same behaviour av_fast_malloc but the buffer has additional + * AV_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0. + * + * In addition the whole buffer will initially and after resizes + * be 0-initialized so that no uninitialized data will ever appear. + */ +void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size); + +/** + * Same behaviour av_fast_padded_malloc except that buffer will always + * be 0-initialized after call. + */ +void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size); + +/** + * Encode extradata length to a buffer. Used by xiph codecs. + * + * @param s buffer to write to; must be at least (v/255+1) bytes long + * @param v size of extradata in bytes + * @return number of bytes written to the buffer. + */ +unsigned int av_xiphlacing(unsigned char *s, unsigned int v); + +#if FF_API_USER_VISIBLE_AVHWACCEL +/** + * Register the hardware accelerator hwaccel. + * + * @deprecated This function doesn't do anything. + */ +attribute_deprecated +void av_register_hwaccel(AVHWAccel *hwaccel); + +/** + * If hwaccel is NULL, returns the first registered hardware accelerator, + * if hwaccel is non-NULL, returns the next registered hardware accelerator + * after hwaccel, or NULL if hwaccel is the last one. + * + * @deprecated AVHWaccel structures contain no user-serviceable parts, so + * this function should not be used. + */ +attribute_deprecated +AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel); +#endif + +#if FF_API_LOCKMGR +/** + * Lock operation used by lockmgr + * + * @deprecated Deprecated together with av_lockmgr_register(). + */ +enum AVLockOp { + AV_LOCK_CREATE, ///< Create a mutex + AV_LOCK_OBTAIN, ///< Lock the mutex + AV_LOCK_RELEASE, ///< Unlock the mutex + AV_LOCK_DESTROY, ///< Free mutex resources +}; + +/** + * Register a user provided lock manager supporting the operations + * specified by AVLockOp. The "mutex" argument to the function points + * to a (void *) where the lockmgr should store/get a pointer to a user + * allocated mutex. It is NULL upon AV_LOCK_CREATE and equal to the + * value left by the last call for all other ops. If the lock manager is + * unable to perform the op then it should leave the mutex in the same + * state as when it was called and return a non-zero value. However, + * when called with AV_LOCK_DESTROY the mutex will always be assumed to + * have been successfully destroyed. If av_lockmgr_register succeeds + * it will return a non-negative value, if it fails it will return a + * negative value and destroy all mutex and unregister all callbacks. + * av_lockmgr_register is not thread-safe, it must be called from a + * single thread before any calls which make use of locking are used. + * + * @param cb User defined callback. av_lockmgr_register invokes calls + * to this callback and the previously registered callback. + * The callback will be used to create more than one mutex + * each of which must be backed by its own underlying locking + * mechanism (i.e. do not use a single static object to + * implement your lock manager). If cb is set to NULL the + * lockmgr will be unregistered. + * + * @deprecated This function does nothing, and always returns 0. Be sure to + * build with thread support to get basic thread safety. + */ +attribute_deprecated +int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)); +#endif + +/** + * Get the type of the given codec. + */ +enum AVMediaType avcodec_get_type(enum AVCodecID codec_id); + +/** + * Get the name of a codec. + * @return a static string identifying the codec; never NULL + */ +const char *avcodec_get_name(enum AVCodecID id); + +/** + * @return a positive value if s is open (i.e. avcodec_open2() was called on it + * with no corresponding avcodec_close()), 0 otherwise. + */ +int avcodec_is_open(AVCodecContext *s); + +/** + * @return a non-zero number if codec is an encoder, zero otherwise + */ +int av_codec_is_encoder(const AVCodec *codec); + +/** + * @return a non-zero number if codec is a decoder, zero otherwise + */ +int av_codec_is_decoder(const AVCodec *codec); + +/** + * @return descriptor for given codec ID or NULL if no descriptor exists. + */ +const AVCodecDescriptor *avcodec_descriptor_get(enum AVCodecID id); + +/** + * Iterate over all codec descriptors known to libavcodec. + * + * @param prev previous descriptor. NULL to get the first descriptor. + * + * @return next descriptor or NULL after the last descriptor + */ +const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev); + +/** + * @return codec descriptor with the given name or NULL if no such descriptor + * exists. + */ +const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name); + +/** + * Allocate a CPB properties structure and initialize its fields to default + * values. + * + * @param size if non-NULL, the size of the allocated struct will be written + * here. This is useful for embedding it in side data. + * + * @return the newly allocated struct or NULL on failure + */ +AVCPBProperties *av_cpb_properties_alloc(size_t *size); + +/** + * @} + */ + +#endif /* AVCODEC_AVCODEC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avdct.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avdct.c new file mode 100644 index 000000000..47e5f7134 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avdct.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "idctdsp.h" +#include "fdctdsp.h" +#include "pixblockdsp.h" +#include "avdct.h" + +#define OFFSET(x) offsetof(AVDCT,x) +#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C +//these names are too long to be readable +#define V AV_OPT_FLAG_VIDEO_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM +#define D AV_OPT_FLAG_DECODING_PARAM + +static const AVOption avdct_options[] = { +{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"}, +{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"}, +{"fastint", "fast integer (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"mmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"}, +{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"}, +{"faan", "floating point AAN DCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"}, + +{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"}, +{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"int", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simple", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplemmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"arm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv5te", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv6", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simpleneon", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"xvid", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"xvidmmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"faani", "floating point AAN IDCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"}, +{"simpleauto", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, + +{"bits_per_sample", "", OFFSET(bits_per_sample), AV_OPT_TYPE_INT, {.i64 = 8 }, 0, 14, 0,}, +{NULL}, +}; + +static const AVClass avdct_class = { + .class_name = "AVDCT", + .option = avdct_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVClass *avcodec_dct_get_class(void) +{ + return &avdct_class; +} + +AVDCT *avcodec_dct_alloc(void) +{ + AVDCT *dsp = av_mallocz(sizeof(AVDCT)); + + if (!dsp) + return NULL; + + dsp->av_class = &avdct_class; + av_opt_set_defaults(dsp); + + return dsp; +} + +int avcodec_dct_init(AVDCT *dsp) +{ + AVCodecContext *avctx = avcodec_alloc_context3(NULL); + + if (!avctx) + return AVERROR(ENOMEM); + + avctx->idct_algo = dsp->idct_algo; + avctx->dct_algo = dsp->dct_algo; + avctx->bits_per_raw_sample = dsp->bits_per_sample; + +#define COPY(src, name) memcpy(&dsp->name, &src.name, sizeof(dsp->name)) + +#if CONFIG_IDCTDSP + { + IDCTDSPContext idsp; + ff_idctdsp_init(&idsp, avctx); + COPY(idsp, idct); + COPY(idsp, idct_permutation); + } +#endif + +#if CONFIG_FDCTDSP + { + FDCTDSPContext fdsp; + ff_fdctdsp_init(&fdsp, avctx); + COPY(fdsp, fdct); + } +#endif + +#if CONFIG_PIXBLOCKDSP + { + PixblockDSPContext pdsp; + ff_pixblockdsp_init(&pdsp, avctx); + COPY(pdsp, get_pixels); + } +#endif + + avcodec_free_context(&avctx); + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avdct.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avdct.h new file mode 100644 index 000000000..272422e44 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avdct.h @@ -0,0 +1,84 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVDCT_H +#define AVCODEC_AVDCT_H + +#include "libavutil/opt.h" + +/** + * AVDCT context. + * @note function pointers can be NULL if the specific features have been + * disabled at build time. + */ +typedef struct AVDCT { + const AVClass *av_class; + + void (*idct)(int16_t *block /* align 16 */); + + /** + * IDCT input permutation. + * Several optimized IDCTs need a permutated input (relative to the + * normal order of the reference IDCT). + * This permutation must be performed before the idct_put/add. + * Note, normally this can be merged with the zigzag/alternate scan
      + * An example to avoid confusion: + * - (->decode coeffs -> zigzag reorder -> dequant -> reference IDCT -> ...) + * - (x -> reference DCT -> reference IDCT -> x) + * - (x -> reference DCT -> simple_mmx_perm = idct_permutation + * -> simple_idct_mmx -> x) + * - (-> decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant + * -> simple_idct_mmx -> ...) + */ + uint8_t idct_permutation[64]; + + void (*fdct)(int16_t *block /* align 16 */); + + + /** + * DCT algorithm. + * must use AVOptions to set this field. + */ + int dct_algo; + + /** + * IDCT algorithm. + * must use AVOptions to set this field. + */ + int idct_algo; + + void (*get_pixels)(int16_t *block /* align 16 */, + const uint8_t *pixels /* align 8 */, + ptrdiff_t line_size); + + int bits_per_sample; +} AVDCT; + +/** + * Allocates a AVDCT context. + * This needs to be initialized with avcodec_dct_init() after optionally + * configuring it with AVOptions. + * + * To free it use av_free() + */ +AVDCT *avcodec_dct_alloc(void); +int avcodec_dct_init(AVDCT *); + +const AVClass *avcodec_dct_get_class(void); + +#endif /* AVCODEC_AVDCT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avfft.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avfft.c new file mode 100644 index 000000000..2200f3770 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avfft.c @@ -0,0 +1,145 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/mem.h" +#include "avfft.h" +#include "fft.h" +#include "rdft.h" +#include "dct.h" + +/* FFT */ + +FFTContext *av_fft_init(int nbits, int inverse) +{ + FFTContext *s = av_mallocz(sizeof(*s)); + + if (s && ff_fft_init(s, nbits, inverse)) + av_freep(&s); + + return s; +} + +void av_fft_permute(FFTContext *s, FFTComplex *z) +{ + s->fft_permute(s, z); +} + +void av_fft_calc(FFTContext *s, FFTComplex *z) +{ + s->fft_calc(s, z); +} + +av_cold void av_fft_end(FFTContext *s) +{ + if (s) { + ff_fft_end(s); + av_free(s); + } +} + +#if CONFIG_MDCT + +FFTContext *av_mdct_init(int nbits, int inverse, double scale) +{ + FFTContext *s = av_malloc(sizeof(*s)); + + if (s && ff_mdct_init(s, nbits, inverse, scale)) + av_freep(&s); + + return s; +} + +void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input) +{ + s->imdct_calc(s, output, input); +} + +void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input) +{ + s->imdct_half(s, output, input); +} + +void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input) +{ + s->mdct_calc(s, output, input); +} + +av_cold void av_mdct_end(FFTContext *s) +{ + if (s) { + ff_mdct_end(s); + av_free(s); + } +} + +#endif /* CONFIG_MDCT */ + +#if CONFIG_RDFT + +RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans) +{ + RDFTContext *s = av_malloc(sizeof(*s)); + + if (s && ff_rdft_init(s, nbits, trans)) + av_freep(&s); + + return s; +} + +void av_rdft_calc(RDFTContext *s, FFTSample *data) +{ + s->rdft_calc(s, data); +} + +av_cold void av_rdft_end(RDFTContext *s) +{ + if (s) { + ff_rdft_end(s); + av_free(s); + } +} + +#endif /* CONFIG_RDFT */ + +#if CONFIG_DCT + +DCTContext *av_dct_init(int nbits, enum DCTTransformType inverse) +{ + DCTContext *s = av_malloc(sizeof(*s)); + + if (s && ff_dct_init(s, nbits, inverse)) + av_freep(&s); + + return s; +} + +void av_dct_calc(DCTContext *s, FFTSample *data) +{ + s->dct_calc(s, data); +} + +av_cold void av_dct_end(DCTContext *s) +{ + if (s) { + ff_dct_end(s); + av_free(s); + } +} + +#endif /* CONFIG_DCT */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avfft.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avfft.h new file mode 100644 index 000000000..0c0f9b8d8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avfft.h @@ -0,0 +1,118 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVFFT_H +#define AVCODEC_AVFFT_H + +/** + * @file + * @ingroup lavc_fft + * FFT functions + */ + +/** + * @defgroup lavc_fft FFT functions + * @ingroup lavc_misc + * + * @{ + */ + +typedef float FFTSample; + +typedef struct FFTComplex { + FFTSample re, im; +} FFTComplex; + +typedef struct FFTContext FFTContext; + +/** + * Set up a complex FFT. + * @param nbits log2 of the length of the input array + * @param inverse if 0 perform the forward transform, if 1 perform the inverse + */ +FFTContext *av_fft_init(int nbits, int inverse); + +/** + * Do the permutation needed BEFORE calling ff_fft_calc(). + */ +void av_fft_permute(FFTContext *s, FFTComplex *z); + +/** + * Do a complex FFT with the parameters defined in av_fft_init(). The + * input data must be permuted before. No 1.0/sqrt(n) normalization is done. + */ +void av_fft_calc(FFTContext *s, FFTComplex *z); + +void av_fft_end(FFTContext *s); + +FFTContext *av_mdct_init(int nbits, int inverse, double scale); +void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); +void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input); +void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); +void av_mdct_end(FFTContext *s); + +/* Real Discrete Fourier Transform */ + +enum RDFTransformType { + DFT_R2C, + IDFT_C2R, + IDFT_R2C, + DFT_C2R, +}; + +typedef struct RDFTContext RDFTContext; + +/** + * Set up a real FFT. + * @param nbits log2 of the length of the input array + * @param trans the type of transform + */ +RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans); +void av_rdft_calc(RDFTContext *s, FFTSample *data); +void av_rdft_end(RDFTContext *s); + +/* Discrete Cosine Transform */ + +typedef struct DCTContext DCTContext; + +enum DCTTransformType { + DCT_II = 0, + DCT_III, + DCT_I, + DST_I, +}; + +/** + * Set up DCT. + * + * @param nbits size of the input array: + * (1 << nbits) for DCT-II, DCT-III and DST-I + * (1 << nbits) + 1 for DCT-I + * @param type the type of transform + * + * @note the first element of the input of DST-I is ignored + */ +DCTContext *av_dct_init(int nbits, enum DCTTransformType type); +void av_dct_calc(DCTContext *s, FFTSample *data); +void av_dct_end (DCTContext *s); + +/** + * @} + */ + +#endif /* AVCODEC_AVFFT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avpacket.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avpacket.c new file mode 100644 index 000000000..2b2006721 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/avpacket.c @@ -0,0 +1,743 @@ +/* + * AVPacket functions for libavcodec + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/internal.h" +#include "libavutil/mathematics.h" +#include "libavutil/mem.h" +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" + +void av_init_packet(AVPacket *pkt) +{ + pkt->pts = AV_NOPTS_VALUE; + pkt->dts = AV_NOPTS_VALUE; + pkt->pos = -1; + pkt->duration = 0; +#if FF_API_CONVERGENCE_DURATION +FF_DISABLE_DEPRECATION_WARNINGS + pkt->convergence_duration = 0; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + pkt->flags = 0; + pkt->stream_index = 0; + pkt->buf = NULL; + pkt->side_data = NULL; + pkt->side_data_elems = 0; +} + +AVPacket *av_packet_alloc(void) +{ + AVPacket *pkt = av_mallocz(sizeof(AVPacket)); + if (!pkt) + return pkt; + + av_packet_unref(pkt); + + return pkt; +} + +void av_packet_free(AVPacket **pkt) +{ + if (!pkt || !*pkt) + return; + + av_packet_unref(*pkt); + av_freep(pkt); +} + +static int packet_alloc(AVBufferRef **buf, int size) +{ + int ret; + if (size < 0 || size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(buf, size + AV_INPUT_BUFFER_PADDING_SIZE); + if (ret < 0) + return ret; + + memset((*buf)->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + + return 0; +} + +int av_new_packet(AVPacket *pkt, int size) +{ + AVBufferRef *buf = NULL; + int ret = packet_alloc(&buf, size); + if (ret < 0) + return ret; + + av_init_packet(pkt); + pkt->buf = buf; + pkt->data = buf->data; + pkt->size = size; + + return 0; +} + +void av_shrink_packet(AVPacket *pkt, int size) +{ + if (pkt->size <= size) + return; + pkt->size = size; + memset(pkt->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); +} + +int av_grow_packet(AVPacket *pkt, int grow_by) +{ + int new_size; + av_assert0((unsigned)pkt->size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE); + if ((unsigned)grow_by > + INT_MAX - (pkt->size + AV_INPUT_BUFFER_PADDING_SIZE)) + return AVERROR(ENOMEM); + + new_size = pkt->size + grow_by + AV_INPUT_BUFFER_PADDING_SIZE; + if (pkt->buf) { + size_t data_offset; + uint8_t *old_data = pkt->data; + if (pkt->data == NULL) { + data_offset = 0; + pkt->data = pkt->buf->data; + } else { + data_offset = pkt->data - pkt->buf->data; + if (data_offset > INT_MAX - new_size) + return AVERROR(ENOMEM); + } + + if (new_size + data_offset > pkt->buf->size) { + int ret = av_buffer_realloc(&pkt->buf, new_size + data_offset); + if (ret < 0) { + pkt->data = old_data; + return ret; + } + pkt->data = pkt->buf->data + data_offset; + } + } else { + pkt->buf = av_buffer_alloc(new_size); + if (!pkt->buf) + return AVERROR(ENOMEM); + if (pkt->size > 0) + memcpy(pkt->buf->data, pkt->data, pkt->size); + pkt->data = pkt->buf->data; + } + pkt->size += grow_by; + memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + + return 0; +} + +int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size) +{ + if (size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + return AVERROR(EINVAL); + + pkt->buf = av_buffer_create(data, size + AV_INPUT_BUFFER_PADDING_SIZE, + av_buffer_default_free, NULL, 0); + if (!pkt->buf) + return AVERROR(ENOMEM); + + pkt->data = data; + pkt->size = size; + + return 0; +} + +#if FF_API_AVPACKET_OLD_API +FF_DISABLE_DEPRECATION_WARNINGS +#define ALLOC_MALLOC(data, size) data = av_malloc(size) +#define ALLOC_BUF(data, size) \ +do { \ + av_buffer_realloc(&pkt->buf, size); \ + data = pkt->buf ? pkt->buf->data : NULL; \ +} while (0) + +#define DUP_DATA(dst, src, size, padding, ALLOC) \ + do { \ + void *data; \ + if (padding) { \ + if ((unsigned)(size) > \ + (unsigned)(size) + AV_INPUT_BUFFER_PADDING_SIZE) \ + goto failed_alloc; \ + ALLOC(data, size + AV_INPUT_BUFFER_PADDING_SIZE); \ + } else { \ + ALLOC(data, size); \ + } \ + if (!data) \ + goto failed_alloc; \ + memcpy(data, src, size); \ + if (padding) \ + memset((uint8_t *)data + size, 0, \ + AV_INPUT_BUFFER_PADDING_SIZE); \ + dst = data; \ + } while (0) + +/* Makes duplicates of data, side_data, but does not copy any other fields */ +static int copy_packet_data(AVPacket *pkt, const AVPacket *src, int dup) +{ + pkt->data = NULL; + pkt->side_data = NULL; + pkt->side_data_elems = 0; + if (pkt->buf) { + AVBufferRef *ref = av_buffer_ref(src->buf); + if (!ref) + return AVERROR(ENOMEM); + pkt->buf = ref; + pkt->data = ref->data; + } else { + DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF); + } + if (src->side_data_elems && dup) { + pkt->side_data = src->side_data; + pkt->side_data_elems = src->side_data_elems; + } + if (src->side_data_elems && !dup) { + return av_copy_packet_side_data(pkt, src); + } + return 0; + +failed_alloc: + av_packet_unref(pkt); + return AVERROR(ENOMEM); +} + +int av_copy_packet_side_data(AVPacket *pkt, const AVPacket *src) +{ + if (src->side_data_elems) { + int i; + DUP_DATA(pkt->side_data, src->side_data, + src->side_data_elems * sizeof(*src->side_data), 0, ALLOC_MALLOC); + if (src != pkt) { + memset(pkt->side_data, 0, + src->side_data_elems * sizeof(*src->side_data)); + } + for (i = 0; i < src->side_data_elems; i++) { + DUP_DATA(pkt->side_data[i].data, src->side_data[i].data, + src->side_data[i].size, 1, ALLOC_MALLOC); + pkt->side_data[i].size = src->side_data[i].size; + pkt->side_data[i].type = src->side_data[i].type; + } + } + pkt->side_data_elems = src->side_data_elems; + return 0; + +failed_alloc: + av_packet_unref(pkt); + return AVERROR(ENOMEM); +} + +int av_dup_packet(AVPacket *pkt) +{ + AVPacket tmp_pkt; + + if (!pkt->buf && pkt->data) { + tmp_pkt = *pkt; + return copy_packet_data(pkt, &tmp_pkt, 1); + } + return 0; +} + +int av_copy_packet(AVPacket *dst, const AVPacket *src) +{ + *dst = *src; + return copy_packet_data(dst, src, 0); +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +void av_packet_free_side_data(AVPacket *pkt) +{ + int i; + for (i = 0; i < pkt->side_data_elems; i++) + av_freep(&pkt->side_data[i].data); + av_freep(&pkt->side_data); + pkt->side_data_elems = 0; +} + +#if FF_API_AVPACKET_OLD_API +FF_DISABLE_DEPRECATION_WARNINGS +void av_free_packet(AVPacket *pkt) +{ + if (pkt) { + if (pkt->buf) + av_buffer_unref(&pkt->buf); + pkt->data = NULL; + pkt->size = 0; + + av_packet_free_side_data(pkt); + } +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, + uint8_t *data, size_t size) +{ + AVPacketSideData *tmp; + int i, elems = pkt->side_data_elems; + + for (i = 0; i < elems; i++) { + AVPacketSideData *sd = &pkt->side_data[i]; + + if (sd->type == type) { + av_free(sd->data); + sd->data = data; + sd->size = size; + return 0; + } + } + + if ((unsigned)elems + 1 > AV_PKT_DATA_NB) + return AVERROR(ERANGE); + + tmp = av_realloc(pkt->side_data, (elems + 1) * sizeof(*tmp)); + if (!tmp) + return AVERROR(ENOMEM); + + pkt->side_data = tmp; + pkt->side_data[elems].data = data; + pkt->side_data[elems].size = size; + pkt->side_data[elems].type = type; + pkt->side_data_elems++; + + return 0; +} + + +uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, + int size) +{ + int ret; + uint8_t *data; + + if ((unsigned)size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + return NULL; + data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!data) + return NULL; + + ret = av_packet_add_side_data(pkt, type, data, size); + if (ret < 0) { + av_freep(&data); + return NULL; + } + + return data; +} + +uint8_t *av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, + int *size) +{ + int i; + + for (i = 0; i < pkt->side_data_elems; i++) { + if (pkt->side_data[i].type == type) { + if (size) + *size = pkt->side_data[i].size; + return pkt->side_data[i].data; + } + } + if (size) + *size = 0; + return NULL; +} + +const char *av_packet_side_data_name(enum AVPacketSideDataType type) +{ + switch(type) { + case AV_PKT_DATA_PALETTE: return "Palette"; + case AV_PKT_DATA_NEW_EXTRADATA: return "New Extradata"; + case AV_PKT_DATA_PARAM_CHANGE: return "Param Change"; + case AV_PKT_DATA_H263_MB_INFO: return "H263 MB Info"; + case AV_PKT_DATA_REPLAYGAIN: return "Replay Gain"; + case AV_PKT_DATA_DISPLAYMATRIX: return "Display Matrix"; + case AV_PKT_DATA_STEREO3D: return "Stereo 3D"; + case AV_PKT_DATA_AUDIO_SERVICE_TYPE: return "Audio Service Type"; + case AV_PKT_DATA_QUALITY_STATS: return "Quality stats"; + case AV_PKT_DATA_FALLBACK_TRACK: return "Fallback track"; + case AV_PKT_DATA_CPB_PROPERTIES: return "CPB properties"; + case AV_PKT_DATA_SKIP_SAMPLES: return "Skip Samples"; + case AV_PKT_DATA_JP_DUALMONO: return "JP Dual Mono"; + case AV_PKT_DATA_STRINGS_METADATA: return "Strings Metadata"; + case AV_PKT_DATA_SUBTITLE_POSITION: return "Subtitle Position"; + case AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL: return "Matroska BlockAdditional"; + case AV_PKT_DATA_WEBVTT_IDENTIFIER: return "WebVTT ID"; + case AV_PKT_DATA_WEBVTT_SETTINGS: return "WebVTT Settings"; + case AV_PKT_DATA_METADATA_UPDATE: return "Metadata Update"; + case AV_PKT_DATA_MPEGTS_STREAM_ID: return "MPEGTS Stream ID"; + case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata"; + case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; + case AV_PKT_DATA_SPHERICAL: return "Spherical Mapping"; + case AV_PKT_DATA_A53_CC: return "A53 Closed Captions"; + case AV_PKT_DATA_ENCRYPTION_INIT_INFO: return "Encryption initialization data"; + case AV_PKT_DATA_ENCRYPTION_INFO: return "Encryption info"; + case AV_PKT_DATA_AFD: return "Active Format Description data"; + } + return NULL; +} + +#if FF_API_MERGE_SD_API + +#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL + +int av_packet_merge_side_data(AVPacket *pkt){ + if(pkt->side_data_elems){ + AVBufferRef *buf; + int i; + uint8_t *p; + uint64_t size= pkt->size + 8LL + AV_INPUT_BUFFER_PADDING_SIZE; + AVPacket old= *pkt; + for (i=0; i INT_MAX) + return AVERROR(EINVAL); + buf = av_buffer_alloc(size); + if (!buf) + return AVERROR(ENOMEM); + pkt->buf = buf; + pkt->data = p = buf->data; + pkt->size = size - AV_INPUT_BUFFER_PADDING_SIZE; + bytestream_put_buffer(&p, old.data, old.size); + for (i=old.side_data_elems-1; i>=0; i--) { + bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size); + bytestream_put_be32(&p, old.side_data[i].size); + *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128); + } + bytestream_put_be64(&p, FF_MERGE_MARKER); + av_assert0(p-pkt->data == pkt->size); + memset(p, 0, AV_INPUT_BUFFER_PADDING_SIZE); + av_packet_unref(&old); + pkt->side_data_elems = 0; + pkt->side_data = NULL; + return 1; + } + return 0; +} + +int av_packet_split_side_data(AVPacket *pkt){ + if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){ + int i; + unsigned int size; + uint8_t *p; + + p = pkt->data + pkt->size - 8 - 5; + for (i=1; ; i++){ + size = AV_RB32(p); + if (size>INT_MAX - 5 || p - pkt->data < size) + return 0; + if (p[4]&128) + break; + if (p - pkt->data < size + 5) + return 0; + p-= size+5; + } + + if (i > AV_PKT_DATA_NB) + return AVERROR(ERANGE); + + pkt->side_data = av_malloc_array(i, sizeof(*pkt->side_data)); + if (!pkt->side_data) + return AVERROR(ENOMEM); + + p= pkt->data + pkt->size - 8 - 5; + for (i=0; ; i++){ + size= AV_RB32(p); + av_assert0(size<=INT_MAX - 5 && p - pkt->data >= size); + pkt->side_data[i].data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); + pkt->side_data[i].size = size; + pkt->side_data[i].type = p[4]&127; + if (!pkt->side_data[i].data) + return AVERROR(ENOMEM); + memcpy(pkt->side_data[i].data, p-size, size); + pkt->size -= size + 5; + if(p[4]&128) + break; + p-= size+5; + } + pkt->size -= 8; + pkt->side_data_elems = i+1; + return 1; + } + return 0; +} +#endif + +uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size) +{ + AVDictionaryEntry *t = NULL; + uint8_t *data = NULL; + *size = 0; + + if (!dict) + return NULL; + + while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) { + const size_t keylen = strlen(t->key); + const size_t valuelen = strlen(t->value); + const size_t new_size = *size + keylen + 1 + valuelen + 1; + uint8_t *const new_data = av_realloc(data, new_size); + + if (!new_data) + goto fail; + data = new_data; + if (new_size > INT_MAX) + goto fail; + + memcpy(data + *size, t->key, keylen + 1); + memcpy(data + *size + keylen + 1, t->value, valuelen + 1); + + *size = new_size; + } + + return data; + +fail: + av_freep(&data); + *size = 0; + return NULL; +} + +int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict) +{ + const uint8_t *end; + int ret = 0; + + if (!dict || !data || !size) + return ret; + end = data + size; + if (size && end[-1]) + return AVERROR_INVALIDDATA; + while (data < end) { + const uint8_t *key = data; + const uint8_t *val = data + strlen(key) + 1; + + if (val >= end || !*key) + return AVERROR_INVALIDDATA; + + ret = av_dict_set(dict, key, val, 0); + if (ret < 0) + break; + data = val + strlen(val) + 1; + } + + return ret; +} + +int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, + int size) +{ + int i; + + for (i = 0; i < pkt->side_data_elems; i++) { + if (pkt->side_data[i].type == type) { + if (size > pkt->side_data[i].size) + return AVERROR(ENOMEM); + pkt->side_data[i].size = size; + return 0; + } + } + return AVERROR(ENOENT); +} + +int av_packet_copy_props(AVPacket *dst, const AVPacket *src) +{ + int i; + + dst->pts = src->pts; + dst->dts = src->dts; + dst->pos = src->pos; + dst->duration = src->duration; +#if FF_API_CONVERGENCE_DURATION +FF_DISABLE_DEPRECATION_WARNINGS + dst->convergence_duration = src->convergence_duration; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + dst->flags = src->flags; + dst->stream_index = src->stream_index; + + dst->side_data = NULL; + dst->side_data_elems = 0; + for (i = 0; i < src->side_data_elems; i++) { + enum AVPacketSideDataType type = src->side_data[i].type; + int size = src->side_data[i].size; + uint8_t *src_data = src->side_data[i].data; + uint8_t *dst_data = av_packet_new_side_data(dst, type, size); + + if (!dst_data) { + av_packet_free_side_data(dst); + return AVERROR(ENOMEM); + } + memcpy(dst_data, src_data, size); + } + + return 0; +} + +void av_packet_unref(AVPacket *pkt) +{ + av_packet_free_side_data(pkt); + av_buffer_unref(&pkt->buf); + av_init_packet(pkt); + pkt->data = NULL; + pkt->size = 0; +} + +int av_packet_ref(AVPacket *dst, const AVPacket *src) +{ + int ret; + + ret = av_packet_copy_props(dst, src); + if (ret < 0) + return ret; + + if (!src->buf) { + ret = packet_alloc(&dst->buf, src->size); + if (ret < 0) + goto fail; + av_assert1(!src->size || src->data); + if (src->size) + memcpy(dst->buf->data, src->data, src->size); + + dst->data = dst->buf->data; + } else { + dst->buf = av_buffer_ref(src->buf); + if (!dst->buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst->data = src->data; + } + + dst->size = src->size; + + return 0; +fail: + av_packet_free_side_data(dst); + return ret; +} + +AVPacket *av_packet_clone(const AVPacket *src) +{ + AVPacket *ret = av_packet_alloc(); + + if (!ret) + return ret; + + if (av_packet_ref(ret, src)) + av_packet_free(&ret); + + return ret; +} + +void av_packet_move_ref(AVPacket *dst, AVPacket *src) +{ + *dst = *src; + av_init_packet(src); + src->data = NULL; + src->size = 0; +} + +int av_packet_make_refcounted(AVPacket *pkt) +{ + int ret; + + if (pkt->buf) + return 0; + + ret = packet_alloc(&pkt->buf, pkt->size); + if (ret < 0) + return ret; + av_assert1(!pkt->size || pkt->data); + if (pkt->size) + memcpy(pkt->buf->data, pkt->data, pkt->size); + + pkt->data = pkt->buf->data; + + return 0; +} + +int av_packet_make_writable(AVPacket *pkt) +{ + AVBufferRef *buf = NULL; + int ret; + + if (pkt->buf && av_buffer_is_writable(pkt->buf)) + return 0; + + ret = packet_alloc(&buf, pkt->size); + if (ret < 0) + return ret; + av_assert1(!pkt->size || pkt->data); + if (pkt->size) + memcpy(buf->data, pkt->data, pkt->size); + + av_buffer_unref(&pkt->buf); + pkt->buf = buf; + pkt->data = buf->data; + + return 0; +} + +void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb) +{ + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts = av_rescale_q(pkt->pts, src_tb, dst_tb); + if (pkt->dts != AV_NOPTS_VALUE) + pkt->dts = av_rescale_q(pkt->dts, src_tb, dst_tb); + if (pkt->duration > 0) + pkt->duration = av_rescale_q(pkt->duration, src_tb, dst_tb); +#if FF_API_CONVERGENCE_DURATION +FF_DISABLE_DEPRECATION_WARNINGS + if (pkt->convergence_duration > 0) + pkt->convergence_duration = av_rescale_q(pkt->convergence_duration, src_tb, dst_tb); +FF_ENABLE_DEPRECATION_WARNINGS +#endif +} + +int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type) +{ + uint8_t *side_data; + int side_data_size; + int i; + + side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, &side_data_size); + if (!side_data) { + side_data_size = 4+4+8*error_count; + side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, + side_data_size); + } + + if (!side_data || side_data_size < 4+4+8*error_count) + return AVERROR(ENOMEM); + + AV_WL32(side_data , quality ); + side_data[4] = pict_type; + side_data[5] = error_count; + for (i = 0; idata, picture->linesize, + ptr, pix_fmt, width, height, 1); +} + +int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt, int width, int height, + unsigned char *dest, int dest_size) +{ + return av_image_copy_to_buffer(dest, dest_size, + (const uint8_t * const*)src->data, src->linesize, + pix_fmt, width, height, 1); +} + +int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height) +{ + return av_image_get_buffer_size(pix_fmt, width, height, 1); +} + +int avpicture_alloc(AVPicture *picture, + enum AVPixelFormat pix_fmt, int width, int height) +{ + int ret = av_image_alloc(picture->data, picture->linesize, + width, height, pix_fmt, 1); + if (ret < 0) { + memset(picture, 0, sizeof(AVPicture)); + return ret; + } + + return 0; +} + +void avpicture_free(AVPicture *picture) +{ + av_freep(&picture->data[0]); +} + +void av_picture_copy(AVPicture *dst, const AVPicture *src, + enum AVPixelFormat pix_fmt, int width, int height) +{ + av_image_copy(dst->data, dst->linesize, (const uint8_t **)src->data, + src->linesize, pix_fmt, width, height); +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif /* FF_API_AVPICTURE */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream.c new file mode 100644 index 000000000..be8a0f634 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream.c @@ -0,0 +1,362 @@ +/* + * Common bit i/o utils + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * Copyright (c) 2010 Loren Merritt + * + * alternative bitstream reader & writer by Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * bitstream api. + */ + +#include "libavutil/avassert.h" +#include "libavutil/qsort.h" +#include "avcodec.h" +#include "internal.h" +#include "mathops.h" +#include "put_bits.h" +#include "vlc.h" + +const uint8_t ff_log2_run[41]={ + 0, 0, 0, 0, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9,10,11,12,13,14,15, +16,17,18,19,20,21,22,23, +24, +}; + +void avpriv_align_put_bits(PutBitContext *s) +{ + put_bits(s, s->bit_left & 7, 0); +} + +void avpriv_put_string(PutBitContext *pb, const char *string, + int terminate_string) +{ + while (*string) { + put_bits(pb, 8, *string); + string++; + } + if (terminate_string) + put_bits(pb, 8, 0); +} + +void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) +{ + int words = length >> 4; + int bits = length & 15; + int i; + + if (length == 0) + return; + + av_assert0(length <= put_bits_left(pb)); + + if (CONFIG_SMALL || words < 16 || put_bits_count(pb) & 7) { + for (i = 0; i < words; i++) + put_bits(pb, 16, AV_RB16(src + 2 * i)); + } else { + for (i = 0; put_bits_count(pb) & 31; i++) + put_bits(pb, 8, src[i]); + flush_put_bits(pb); + memcpy(put_bits_ptr(pb), src + i, 2 * words - i); + skip_put_bytes(pb, 2 * words - i); + } + + put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits)); +} + +/* VLC decoding */ + +#define GET_DATA(v, table, i, wrap, size) \ +{ \ + const uint8_t *ptr = (const uint8_t *)table + i * wrap; \ + switch(size) { \ + case 1: \ + v = *(const uint8_t *)ptr; \ + break; \ + case 2: \ + v = *(const uint16_t *)ptr; \ + break; \ + case 4: \ + v = *(const uint32_t *)ptr; \ + break; \ + default: \ + av_assert1(0); \ + } \ +} + + +static int alloc_table(VLC *vlc, int size, int use_static) +{ + int index = vlc->table_size; + + vlc->table_size += size; + if (vlc->table_size > vlc->table_allocated) { + if (use_static) + abort(); // cannot do anything, init_vlc() is used with too little memory + vlc->table_allocated += (1 << vlc->bits); + vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2); + if (!vlc->table) { + vlc->table_allocated = 0; + vlc->table_size = 0; + return AVERROR(ENOMEM); + } + memset(vlc->table + vlc->table_allocated - (1 << vlc->bits), 0, sizeof(VLC_TYPE) * 2 << vlc->bits); + } + return index; +} + +typedef struct VLCcode { + uint8_t bits; + uint16_t symbol; + /** codeword, with the first bit-to-be-read in the msb + * (even if intended for a little-endian bitstream reader) */ + uint32_t code; +} VLCcode; + +static int compare_vlcspec(const void *a, const void *b) +{ + const VLCcode *sa = a, *sb = b; + return (sa->code >> 1) - (sb->code >> 1); +} +/** + * Build VLC decoding tables suitable for use with get_vlc(). + * + * @param vlc the context to be initialized + * + * @param table_nb_bits max length of vlc codes to store directly in this table + * (Longer codes are delegated to subtables.) + * + * @param nb_codes number of elements in codes[] + * + * @param codes descriptions of the vlc codes + * These must be ordered such that codes going into the same subtable are contiguous. + * Sorting by VLCcode.code is sufficient, though not necessary. + */ +static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, + VLCcode *codes, int flags) +{ + int table_size, table_index, index, code_prefix, symbol, subtable_bits; + int i, j, k, n, nb, inc; + uint32_t code; + volatile VLC_TYPE (* volatile table)[2]; // the double volatile is needed to prevent an internal compiler error in gcc 4.2 + + table_size = 1 << table_nb_bits; + if (table_nb_bits > 30) + return AVERROR(EINVAL); + table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC); + ff_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size); + if (table_index < 0) + return table_index; + table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index]; + + /* first pass: map codes and compute auxiliary table sizes */ + for (i = 0; i < nb_codes; i++) { + n = codes[i].bits; + code = codes[i].code; + symbol = codes[i].symbol; + ff_dlog(NULL, "i=%d n=%d code=0x%"PRIx32"\n", i, n, code); + if (n <= table_nb_bits) { + /* no need to add another table */ + j = code >> (32 - table_nb_bits); + nb = 1 << (table_nb_bits - n); + inc = 1; + if (flags & INIT_VLC_LE) { + j = bitswap_32(code); + inc = 1 << n; + } + for (k = 0; k < nb; k++) { + int bits = table[j][1]; + int oldsym = table[j][0]; + ff_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n); + if ((bits || oldsym) && (bits != n || oldsym != symbol)) { + av_log(NULL, AV_LOG_ERROR, "incorrect codes\n"); + return AVERROR_INVALIDDATA; + } + table[j][1] = n; //bits + table[j][0] = symbol; + j += inc; + } + } else { + /* fill auxiliary table recursively */ + n -= table_nb_bits; + code_prefix = code >> (32 - table_nb_bits); + subtable_bits = n; + codes[i].bits = n; + codes[i].code = code << table_nb_bits; + for (k = i+1; k < nb_codes; k++) { + n = codes[k].bits - table_nb_bits; + if (n <= 0) + break; + code = codes[k].code; + if (code >> (32 - table_nb_bits) != code_prefix) + break; + codes[k].bits = n; + codes[k].code = code << table_nb_bits; + subtable_bits = FFMAX(subtable_bits, n); + } + subtable_bits = FFMIN(subtable_bits, table_nb_bits); + j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix; + table[j][1] = -subtable_bits; + ff_dlog(NULL, "%4x: n=%d (subtable)\n", + j, codes[i].bits + table_nb_bits); + index = build_table(vlc, subtable_bits, k-i, codes+i, flags); + if (index < 0) + return index; + /* note: realloc has been done, so reload tables */ + table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index]; + table[j][0] = index; //code + if (table[j][0] != index) { + avpriv_request_sample(NULL, "strange codes"); + return AVERROR_PATCHWELCOME; + } + i = k-1; + } + } + + for (i = 0; i < table_size; i++) { + if (table[i][1] == 0) //bits + table[i][0] = -1; //codes + } + + return table_index; +} + + +/* Build VLC decoding tables suitable for use with get_vlc(). + + 'nb_bits' sets the decoding table size (2^nb_bits) entries. The + bigger it is, the faster is the decoding. But it should not be too + big to save memory and L1 cache. '9' is a good compromise. + + 'nb_codes' : number of vlcs codes + + 'bits' : table which gives the size (in bits) of each vlc code. + + 'codes' : table which gives the bit pattern of of each vlc code. + + 'symbols' : table which gives the values to be returned from get_vlc(). + + 'xxx_wrap' : give the number of bytes between each entry of the + 'bits' or 'codes' tables. + + 'xxx_size' : gives the number of bytes of each entry of the 'bits' + or 'codes' tables. Currently 1,2 and 4 are supported. + + 'wrap' and 'size' make it possible to use any memory configuration and types + (byte/word/long) to store the 'bits', 'codes', and 'symbols' tables. + + 'use_static' should be set to 1 for tables, which should be freed + with av_free_static(), 0 if ff_free_vlc() will be used. +*/ +int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + const void *symbols, int symbols_wrap, int symbols_size, + int flags) +{ + VLCcode *buf; + int i, j, ret; + VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34 + VLC localvlc, *vlc; + + vlc = vlc_arg; + vlc->bits = nb_bits; + if (flags & INIT_VLC_USE_NEW_STATIC) { + av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf)); + buf = localbuf; + localvlc = *vlc_arg; + vlc = &localvlc; + vlc->table_size = 0; + } else { + vlc->table = NULL; + vlc->table_allocated = 0; + vlc->table_size = 0; + + buf = av_malloc_array((nb_codes + 1), sizeof(VLCcode)); + if (!buf) + return AVERROR(ENOMEM); + } + + + av_assert0(symbols_size <= 2 || !symbols); + j = 0; +#define COPY(condition)\ + for (i = 0; i < nb_codes; i++) { \ + GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size); \ + if (!(condition)) \ + continue; \ + if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \ + av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\ + if (!(flags & INIT_VLC_USE_NEW_STATIC)) \ + av_free(buf); \ + return AVERROR(EINVAL); \ + } \ + GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \ + if (buf[j].code >= (1LL< nb_bits); + // qsort is the slowest part of init_vlc, and could probably be improved or avoided + AV_QSORT(buf, j, struct VLCcode, compare_vlcspec); + COPY(buf[j].bits && buf[j].bits <= nb_bits); + nb_codes = j; + + ret = build_table(vlc, nb_bits, nb_codes, buf, flags); + + if (flags & INIT_VLC_USE_NEW_STATIC) { + if(vlc->table_size != vlc->table_allocated) + av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated); + + av_assert0(ret >= 0); + *vlc_arg = *vlc; + } else { + av_free(buf); + if (ret < 0) { + av_freep(&vlc->table); + return ret; + } + } + return 0; +} + + +void ff_free_vlc(VLC *vlc) +{ + av_freep(&vlc->table); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream_filter.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream_filter.c new file mode 100644 index 000000000..ca11ed371 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream_filter.c @@ -0,0 +1,185 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "avcodec.h" +#include "libavutil/internal.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" + +#if FF_API_OLD_BSF +FF_DISABLE_DEPRECATION_WARNINGS + +const AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f) +{ + const AVBitStreamFilter *filter = NULL; + void *opaque = NULL; + + while (filter != f) + filter = av_bsf_iterate(&opaque); + + return av_bsf_iterate(&opaque); +} + +void av_register_bitstream_filter(AVBitStreamFilter *bsf) +{ +} + +typedef struct BSFCompatContext { + AVBSFContext *ctx; + int extradata_updated; +} BSFCompatContext; + +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) +{ + AVBitStreamFilterContext *ctx = NULL; + BSFCompatContext *priv = NULL; + const AVBitStreamFilter *bsf; + + bsf = av_bsf_get_by_name(name); + if (!bsf) + return NULL; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + goto fail; + + + ctx->filter = bsf; + ctx->priv_data = priv; + + return ctx; + +fail: + if (priv) + av_bsf_free(&priv->ctx); + av_freep(&priv); + av_freep(&ctx); + return NULL; +} + +void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc) +{ + BSFCompatContext *priv; + + if (!bsfc) + return; + + priv = bsfc->priv_data; + + av_bsf_free(&priv->ctx); + av_freep(&bsfc->priv_data); + av_free(bsfc); +} + +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe) +{ + BSFCompatContext *priv = bsfc->priv_data; + AVPacket pkt = { 0 }; + int ret; + + if (!priv->ctx) { + ret = av_bsf_alloc(bsfc->filter, &priv->ctx); + if (ret < 0) + return ret; + + ret = avcodec_parameters_from_context(priv->ctx->par_in, avctx); + if (ret < 0) + return ret; + + priv->ctx->time_base_in = avctx->time_base; + + if (bsfc->args && bsfc->filter->priv_class) { + const AVOption *opt = av_opt_next(priv->ctx->priv_data, NULL); + const char * shorthand[2] = {NULL}; + + if (opt) + shorthand[0] = opt->name; + + ret = av_opt_set_from_string(priv->ctx->priv_data, bsfc->args, shorthand, "=", ":"); + if (ret < 0) + return ret; + } + + ret = av_bsf_init(priv->ctx); + if (ret < 0) + return ret; + } + + pkt.data = (uint8_t *)buf; + pkt.size = buf_size; + + ret = av_bsf_send_packet(priv->ctx, &pkt); + if (ret < 0) + return ret; + + *poutbuf = NULL; + *poutbuf_size = 0; + + ret = av_bsf_receive_packet(priv->ctx, &pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return 0; + else if (ret < 0) + return ret; + + *poutbuf = av_malloc(pkt.size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!*poutbuf) { + av_packet_unref(&pkt); + return AVERROR(ENOMEM); + } + + *poutbuf_size = pkt.size; + memcpy(*poutbuf, pkt.data, pkt.size); + + av_packet_unref(&pkt); + + /* drain all the remaining packets we cannot return */ + while (ret >= 0) { + ret = av_bsf_receive_packet(priv->ctx, &pkt); + av_packet_unref(&pkt); + } + + if (!priv->extradata_updated) { + /* update extradata in avctx from the output codec parameters */ + if (priv->ctx->par_out->extradata_size && (!args || !strstr(args, "private_spspps_buf"))) { + av_freep(&avctx->extradata); + avctx->extradata_size = 0; + avctx->extradata = av_mallocz(priv->ctx->par_out->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + memcpy(avctx->extradata, priv->ctx->par_out->extradata, priv->ctx->par_out->extradata_size); + avctx->extradata_size = priv->ctx->par_out->extradata_size; + } + + priv->extradata_updated = 1; + } + + return 1; +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream_filters.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream_filters.c new file mode 100644 index 000000000..463003966 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bitstream_filters.c @@ -0,0 +1,114 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/common.h" +#include "libavutil/log.h" + +#include "avcodec.h" +#include "bsf.h" + +extern const AVBitStreamFilter ff_aac_adtstoasc_bsf; +extern const AVBitStreamFilter ff_av1_frame_split_bsf; +extern const AVBitStreamFilter ff_av1_metadata_bsf; +extern const AVBitStreamFilter ff_chomp_bsf; +extern const AVBitStreamFilter ff_dump_extradata_bsf; +extern const AVBitStreamFilter ff_dca_core_bsf; +extern const AVBitStreamFilter ff_eac3_core_bsf; +extern const AVBitStreamFilter ff_extract_extradata_bsf; +extern const AVBitStreamFilter ff_filter_units_bsf; +extern const AVBitStreamFilter ff_h264_metadata_bsf; +extern const AVBitStreamFilter ff_h264_mp4toannexb_bsf; +extern const AVBitStreamFilter ff_h264_redundant_pps_bsf; +extern const AVBitStreamFilter ff_hapqa_extract_bsf; +extern const AVBitStreamFilter ff_hevc_metadata_bsf; +extern const AVBitStreamFilter ff_hevc_mp4toannexb_bsf; +extern const AVBitStreamFilter ff_imx_dump_header_bsf; +extern const AVBitStreamFilter ff_mjpeg2jpeg_bsf; +extern const AVBitStreamFilter ff_mjpega_dump_header_bsf; +extern const AVBitStreamFilter ff_mp3_header_decompress_bsf; +extern const AVBitStreamFilter ff_mpeg2_metadata_bsf; +extern const AVBitStreamFilter ff_mpeg4_unpack_bframes_bsf; +extern const AVBitStreamFilter ff_mov2textsub_bsf; +extern const AVBitStreamFilter ff_noise_bsf; +extern const AVBitStreamFilter ff_null_bsf; +extern const AVBitStreamFilter ff_prores_metadata_bsf; +extern const AVBitStreamFilter ff_remove_extradata_bsf; +extern const AVBitStreamFilter ff_text2movsub_bsf; +extern const AVBitStreamFilter ff_trace_headers_bsf; +extern const AVBitStreamFilter ff_truehd_core_bsf; +extern const AVBitStreamFilter ff_vp9_metadata_bsf; +extern const AVBitStreamFilter ff_vp9_raw_reorder_bsf; +extern const AVBitStreamFilter ff_vp9_superframe_bsf; +extern const AVBitStreamFilter ff_vp9_superframe_split_bsf; + +#include "libavcodec/bsf_list.c" + +const AVBitStreamFilter *av_bsf_iterate(void **opaque) +{ + uintptr_t i = (uintptr_t)*opaque; + const AVBitStreamFilter *f = bitstream_filters[i]; + + if (f) + *opaque = (void*)(i + 1); + + return f; +} + +#if FF_API_NEXT +const AVBitStreamFilter *av_bsf_next(void **opaque) { + return av_bsf_iterate(opaque); +} +#endif + +const AVBitStreamFilter *av_bsf_get_by_name(const char *name) +{ + const AVBitStreamFilter *f = NULL; + void *i = 0; + + if (!name) + return NULL; + + while ((f = av_bsf_iterate(&i))) { + if (!strcmp(f->name, name)) + return f; + } + + return NULL; +} + +const AVClass *ff_bsf_child_class_next(const AVClass *prev) +{ + const AVBitStreamFilter *f = NULL; + void *i = 0; + + /* find the filter that corresponds to prev */ + while (prev && (f = av_bsf_iterate(&i))) { + if (f->priv_class == prev) { + break; + } + } + + /* find next filter with priv options */ + while ((f = av_bsf_iterate(&i))) { + if (f->priv_class) + return f->priv_class; + } + return NULL; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/blockdsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/blockdsp.c new file mode 100644 index 000000000..c7efe7e77 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/blockdsp.c @@ -0,0 +1,78 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "avcodec.h" +#include "blockdsp.h" +#include "version.h" + +static void clear_block_c(int16_t *block) +{ + memset(block, 0, sizeof(int16_t) * 64); +} + +static void clear_blocks_c(int16_t *blocks) +{ + memset(blocks, 0, sizeof(int16_t) * 6 * 64); +} + +static void fill_block16_c(uint8_t *block, uint8_t value, ptrdiff_t line_size, + int h) +{ + int i; + + for (i = 0; i < h; i++) { + memset(block, value, 16); + block += line_size; + } +} + +static void fill_block8_c(uint8_t *block, uint8_t value, ptrdiff_t line_size, + int h) +{ + int i; + + for (i = 0; i < h; i++) { + memset(block, value, 8); + block += line_size; + } +} + +av_cold void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx) +{ + c->clear_block = clear_block_c; + c->clear_blocks = clear_blocks_c; + + c->fill_block_tab[0] = fill_block16_c; + c->fill_block_tab[1] = fill_block8_c; + + if (ARCH_ALPHA) + ff_blockdsp_init_alpha(c); + if (ARCH_ARM) + ff_blockdsp_init_arm(c); + if (ARCH_PPC) + ff_blockdsp_init_ppc(c); + if (ARCH_X86) + ff_blockdsp_init_x86(c, avctx); + if (ARCH_MIPS) + ff_blockdsp_init_mips(c); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/blockdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/blockdsp.h new file mode 100644 index 000000000..26fc2ea13 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/blockdsp.h @@ -0,0 +1,50 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_BLOCKDSP_H +#define AVCODEC_BLOCKDSP_H + +#include +#include + +#include "avcodec.h" +#include "version.h" + +/* add and put pixel (decoding) + * Block sizes for op_pixels_func are 8x4,8x8 16x8 16x16. + * h for op_pixels_func is limited to { width / 2, width }, + * but never larger than 16 and never smaller than 4. */ +typedef void (*op_fill_func)(uint8_t *block /* align width (8 or 16) */, + uint8_t value, ptrdiff_t line_size, int h); + +typedef struct BlockDSPContext { + void (*clear_block)(int16_t *block /* align 32 */); + void (*clear_blocks)(int16_t *blocks /* align 32 */); + + op_fill_func fill_block_tab[2]; +} BlockDSPContext; + +void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx); + +void ff_blockdsp_init_alpha(BlockDSPContext *c); +void ff_blockdsp_init_arm(BlockDSPContext *c); +void ff_blockdsp_init_ppc(BlockDSPContext *c); +void ff_blockdsp_init_x86(BlockDSPContext *c, AVCodecContext *avctx); +void ff_blockdsp_init_mips(BlockDSPContext *c); + +#endif /* AVCODEC_BLOCKDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.c new file mode 100644 index 000000000..508130760 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.c @@ -0,0 +1,567 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/log.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" + +#include "avcodec.h" +#include "bsf.h" + +struct AVBSFInternal { + AVPacket *buffer_pkt; + int eof; +}; + +void av_bsf_free(AVBSFContext **pctx) +{ + AVBSFContext *ctx; + + if (!pctx || !*pctx) + return; + ctx = *pctx; + + if (ctx->filter->close) + ctx->filter->close(ctx); + if (ctx->filter->priv_class && ctx->priv_data) + av_opt_free(ctx->priv_data); + + av_opt_free(ctx); + + av_packet_free(&ctx->internal->buffer_pkt); + av_freep(&ctx->internal); + av_freep(&ctx->priv_data); + + avcodec_parameters_free(&ctx->par_in); + avcodec_parameters_free(&ctx->par_out); + + av_freep(pctx); +} + +static void *bsf_child_next(void *obj, void *prev) +{ + AVBSFContext *ctx = obj; + if (!prev && ctx->filter->priv_class) + return ctx->priv_data; + return NULL; +} + +static const AVClass bsf_class = { + .class_name = "AVBSFContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, + .child_next = bsf_child_next, + .child_class_next = ff_bsf_child_class_next, +}; + +const AVClass *av_bsf_get_class(void) +{ + return &bsf_class; +} + +int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx) +{ + AVBSFContext *ctx; + int ret; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return AVERROR(ENOMEM); + + ctx->av_class = &bsf_class; + ctx->filter = filter; + + ctx->par_in = avcodec_parameters_alloc(); + ctx->par_out = avcodec_parameters_alloc(); + if (!ctx->par_in || !ctx->par_out) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ctx->internal = av_mallocz(sizeof(*ctx->internal)); + if (!ctx->internal) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ctx->internal->buffer_pkt = av_packet_alloc(); + if (!ctx->internal->buffer_pkt) { + ret = AVERROR(ENOMEM); + goto fail; + } + + av_opt_set_defaults(ctx); + + /* allocate priv data and init private options */ + if (filter->priv_data_size) { + ctx->priv_data = av_mallocz(filter->priv_data_size); + if (!ctx->priv_data) { + ret = AVERROR(ENOMEM); + goto fail; + } + if (filter->priv_class) { + *(const AVClass **)ctx->priv_data = filter->priv_class; + av_opt_set_defaults(ctx->priv_data); + } + } + + *pctx = ctx; + return 0; +fail: + av_bsf_free(&ctx); + return ret; +} + +int av_bsf_init(AVBSFContext *ctx) +{ + int ret, i; + + /* check that the codec is supported */ + if (ctx->filter->codec_ids) { + for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) + if (ctx->par_in->codec_id == ctx->filter->codec_ids[i]) + break; + if (ctx->filter->codec_ids[i] == AV_CODEC_ID_NONE) { + const AVCodecDescriptor *desc = avcodec_descriptor_get(ctx->par_in->codec_id); + av_log(ctx, AV_LOG_ERROR, "Codec '%s' (%d) is not supported by the " + "bitstream filter '%s'. Supported codecs are: ", + desc ? desc->name : "unknown", ctx->par_in->codec_id, ctx->filter->name); + for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) { + desc = avcodec_descriptor_get(ctx->filter->codec_ids[i]); + av_log(ctx, AV_LOG_ERROR, "%s (%d) ", + desc ? desc->name : "unknown", ctx->filter->codec_ids[i]); + } + av_log(ctx, AV_LOG_ERROR, "\n"); + return AVERROR(EINVAL); + } + } + + /* initialize output parameters to be the same as input + * init below might overwrite that */ + ret = avcodec_parameters_copy(ctx->par_out, ctx->par_in); + if (ret < 0) + return ret; + + ctx->time_base_out = ctx->time_base_in; + + if (ctx->filter->init) { + ret = ctx->filter->init(ctx); + if (ret < 0) + return ret; + } + + return 0; +} + +void av_bsf_flush(AVBSFContext *ctx) +{ + ctx->internal->eof = 0; + + av_packet_unref(ctx->internal->buffer_pkt); + + if (ctx->filter->flush) + ctx->filter->flush(ctx); +} + +int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt) +{ + int ret; + + if (!pkt || (!pkt->data && !pkt->side_data_elems)) { + ctx->internal->eof = 1; + return 0; + } + + if (ctx->internal->eof) { + av_log(ctx, AV_LOG_ERROR, "A non-NULL packet sent after an EOF.\n"); + return AVERROR(EINVAL); + } + + if (ctx->internal->buffer_pkt->data || + ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + ret = av_packet_make_refcounted(pkt); + if (ret < 0) + return ret; + av_packet_move_ref(ctx->internal->buffer_pkt, pkt); + + return 0; +} + +int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt) +{ + return ctx->filter->filter(ctx, pkt); +} + +int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt) +{ + AVBSFInternal *in = ctx->internal; + AVPacket *tmp_pkt; + + if (in->eof) + return AVERROR_EOF; + + if (!ctx->internal->buffer_pkt->data && + !ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + tmp_pkt = av_packet_alloc(); + if (!tmp_pkt) + return AVERROR(ENOMEM); + + *pkt = ctx->internal->buffer_pkt; + ctx->internal->buffer_pkt = tmp_pkt; + + return 0; +} + +int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt) +{ + AVBSFInternal *in = ctx->internal; + + if (in->eof) + return AVERROR_EOF; + + if (!ctx->internal->buffer_pkt->data && + !ctx->internal->buffer_pkt->side_data_elems) + return AVERROR(EAGAIN); + + av_packet_move_ref(pkt, ctx->internal->buffer_pkt); + + return 0; +} + +typedef struct BSFListContext { + const AVClass *class; + + AVBSFContext **bsfs; + int nb_bsfs; + + unsigned idx; // index of currently processed BSF + unsigned flushed_idx; // index of BSF being flushed + + char * item_name; +} BSFListContext; + + +static int bsf_list_init(AVBSFContext *bsf) +{ + BSFListContext *lst = bsf->priv_data; + int ret, i; + const AVCodecParameters *cod_par = bsf->par_in; + AVRational tb = bsf->time_base_in; + + for (i = 0; i < lst->nb_bsfs; ++i) { + ret = avcodec_parameters_copy(lst->bsfs[i]->par_in, cod_par); + if (ret < 0) + goto fail; + + lst->bsfs[i]->time_base_in = tb; + + ret = av_bsf_init(lst->bsfs[i]); + if (ret < 0) + goto fail; + + cod_par = lst->bsfs[i]->par_out; + tb = lst->bsfs[i]->time_base_out; + } + + bsf->time_base_out = tb; + ret = avcodec_parameters_copy(bsf->par_out, cod_par); + +fail: + return ret; +} + +static int bsf_list_filter(AVBSFContext *bsf, AVPacket *out) +{ + BSFListContext *lst = bsf->priv_data; + int ret; + + if (!lst->nb_bsfs) + return ff_bsf_get_packet_ref(bsf, out); + + while (1) { + if (lst->idx > lst->flushed_idx) { + ret = av_bsf_receive_packet(lst->bsfs[lst->idx-1], out); + if (ret == AVERROR(EAGAIN)) { + /* no more packets from idx-1, try with previous */ + ret = 0; + lst->idx--; + continue; + } else if (ret == AVERROR_EOF) { + /* filter idx-1 is done, continue with idx...nb_bsfs */ + lst->flushed_idx = lst->idx; + continue; + }else if (ret < 0) { + /* filtering error */ + break; + } + } else { + ret = ff_bsf_get_packet_ref(bsf, out); + if (ret == AVERROR_EOF) { + lst->idx = lst->flushed_idx; + } else if (ret < 0) + break; + } + + if (lst->idx < lst->nb_bsfs) { + AVPacket *pkt; + if (ret == AVERROR_EOF && lst->idx == lst->flushed_idx) { + /* ff_bsf_get_packet_ref returned EOF and idx is first + * filter of yet not flushed filter chain */ + pkt = NULL; + } else { + pkt = out; + } + ret = av_bsf_send_packet(lst->bsfs[lst->idx], pkt); + if (ret < 0) + break; + lst->idx++; + } else { + /* The end of filter chain, break to return result */ + break; + } + } + + if (ret < 0) + av_packet_unref(out); + + return ret; +} + +static void bsf_list_flush(AVBSFContext *bsf) +{ + BSFListContext *lst = bsf->priv_data; + + for (int i = 0; i < lst->nb_bsfs; i++) + av_bsf_flush(lst->bsfs[i]); + lst->idx = lst->flushed_idx = 0; +} + +static void bsf_list_close(AVBSFContext *bsf) +{ + BSFListContext *lst = bsf->priv_data; + int i; + + for (i = 0; i < lst->nb_bsfs; ++i) + av_bsf_free(&lst->bsfs[i]); + av_freep(&lst->bsfs); + av_freep(&lst->item_name); +} + +static const char *bsf_list_item_name(void *ctx) +{ + static const char *null_filter_name = "null"; + AVBSFContext *bsf_ctx = ctx; + BSFListContext *lst = bsf_ctx->priv_data; + + if (!lst->nb_bsfs) + return null_filter_name; + + if (!lst->item_name) { + int i; + AVBPrint bp; + av_bprint_init(&bp, 16, 128); + + av_bprintf(&bp, "bsf_list("); + for (i = 0; i < lst->nb_bsfs; i++) + av_bprintf(&bp, i ? ",%s" : "%s", lst->bsfs[i]->filter->name); + av_bprintf(&bp, ")"); + + av_bprint_finalize(&bp, &lst->item_name); + } + + return lst->item_name; +} + +static const AVClass bsf_list_class = { + .class_name = "bsf_list", + .item_name = bsf_list_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVBitStreamFilter ff_list_bsf = { + .name = "bsf_list", + .priv_data_size = sizeof(BSFListContext), + .priv_class = &bsf_list_class, + .init = bsf_list_init, + .filter = bsf_list_filter, + .flush = bsf_list_flush, + .close = bsf_list_close, +}; + +struct AVBSFList { + AVBSFContext **bsfs; + int nb_bsfs; +}; + +AVBSFList *av_bsf_list_alloc(void) +{ + return av_mallocz(sizeof(AVBSFList)); +} + +void av_bsf_list_free(AVBSFList **lst) +{ + int i; + + if (!*lst) + return; + + for (i = 0; i < (*lst)->nb_bsfs; ++i) + av_bsf_free(&(*lst)->bsfs[i]); + av_free((*lst)->bsfs); + av_freep(lst); +} + +int av_bsf_list_append(AVBSFList *lst, AVBSFContext *bsf) +{ + return av_dynarray_add_nofree(&lst->bsfs, &lst->nb_bsfs, bsf); +} + +int av_bsf_list_append2(AVBSFList *lst, const char *bsf_name, AVDictionary ** options) +{ + int ret; + const AVBitStreamFilter *filter; + AVBSFContext *bsf; + + filter = av_bsf_get_by_name(bsf_name); + if (!filter) + return AVERROR_BSF_NOT_FOUND; + + ret = av_bsf_alloc(filter, &bsf); + if (ret < 0) + return ret; + + if (options) { + ret = av_opt_set_dict2(bsf, options, AV_OPT_SEARCH_CHILDREN); + if (ret < 0) + goto end; + } + + ret = av_bsf_list_append(lst, bsf); + +end: + if (ret < 0) + av_bsf_free(&bsf); + + return ret; +} + +int av_bsf_list_finalize(AVBSFList **lst, AVBSFContext **bsf) +{ + int ret = 0; + BSFListContext *ctx; + + if ((*lst)->nb_bsfs == 1) { + *bsf = (*lst)->bsfs[0]; + av_freep(&(*lst)->bsfs); + (*lst)->nb_bsfs = 0; + goto end; + } + + ret = av_bsf_alloc(&ff_list_bsf, bsf); + if (ret < 0) + return ret; + + ctx = (*bsf)->priv_data; + + ctx->bsfs = (*lst)->bsfs; + ctx->nb_bsfs = (*lst)->nb_bsfs; + +end: + av_freep(lst); + return ret; +} + +static int bsf_parse_single(const char *str, AVBSFList *bsf_lst) +{ + char *bsf_name, *bsf_options_str, *buf; + AVDictionary *bsf_options = NULL; + int ret = 0; + + if (!(buf = av_strdup(str))) + return AVERROR(ENOMEM); + + bsf_name = av_strtok(buf, "=", &bsf_options_str); + if (!bsf_name) { + ret = AVERROR(EINVAL); + goto end; + } + + if (bsf_options_str) { + ret = av_dict_parse_string(&bsf_options, bsf_options_str, "=", ":", 0); + if (ret < 0) + goto end; + } + + ret = av_bsf_list_append2(bsf_lst, bsf_name, &bsf_options); + + av_dict_free(&bsf_options); +end: + av_free(buf); + return ret; +} + +int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf_lst) +{ + AVBSFList *lst; + char *bsf_str, *buf, *dup, *saveptr; + int ret; + + if (!str) + return av_bsf_get_null_filter(bsf_lst); + + lst = av_bsf_list_alloc(); + if (!lst) + return AVERROR(ENOMEM); + + if (!(dup = buf = av_strdup(str))) { + ret = AVERROR(ENOMEM); + goto end; + } + + while (1) { + bsf_str = av_strtok(buf, ",", &saveptr); + if (!bsf_str) + break; + + ret = bsf_parse_single(bsf_str, lst); + if (ret < 0) + goto end; + + buf = NULL; + } + + ret = av_bsf_list_finalize(&lst, bsf_lst); +end: + if (ret < 0) + av_bsf_list_free(&lst); + av_free(dup); + return ret; +} + +int av_bsf_get_null_filter(AVBSFContext **bsf) +{ + return av_bsf_alloc(&ff_list_bsf, bsf); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.h new file mode 100644 index 000000000..af035eee4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf.h @@ -0,0 +1,44 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_BSF_H +#define AVCODEC_BSF_H + +#include "avcodec.h" + +/** + * Called by the bitstream filters to get the next packet for filtering. + * The filter is responsible for either freeing the packet or passing it to the + * caller. + */ +int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt); + +/** + * Called by bitstream filters to get packet for filtering. + * The reference to packet is moved to provided packet structure. + * + * @param ctx pointer to AVBSFContext of filter + * @param pkt pointer to packet to move reference to + * + * @return 0>= on success, negative AVERROR in case of failure + */ +int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt); + +const AVClass *ff_bsf_child_class_next(const AVClass *prev); + +#endif /* AVCODEC_BSF_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf_list.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf_list.c new file mode 100644 index 000000000..d31ece942 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bsf_list.c @@ -0,0 +1,3 @@ +static const AVBitStreamFilter * const bitstream_filters[] = { + &ff_null_bsf, + NULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bytestream.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bytestream.h new file mode 100644 index 000000000..7be7fc22f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/bytestream.h @@ -0,0 +1,376 @@ +/* + * Bytestream functions + * copyright (c) 2006 Baptiste Coudurier + * Copyright (c) 2012 Aneesh Dogra (lionaneesh) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_BYTESTREAM_H +#define AVCODEC_BYTESTREAM_H + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" + +typedef struct GetByteContext { + const uint8_t *buffer, *buffer_end, *buffer_start; +} GetByteContext; + +typedef struct PutByteContext { + uint8_t *buffer, *buffer_end, *buffer_start; + int eof; +} PutByteContext; + +#define DEF(type, name, bytes, read, write) \ +static av_always_inline type bytestream_get_ ## name(const uint8_t **b) \ +{ \ + (*b) += bytes; \ + return read(*b - bytes); \ +} \ +static av_always_inline void bytestream_put_ ## name(uint8_t **b, \ + const type value) \ +{ \ + write(*b, value); \ + (*b) += bytes; \ +} \ +static av_always_inline void bytestream2_put_ ## name ## u(PutByteContext *p, \ + const type value) \ +{ \ + bytestream_put_ ## name(&p->buffer, value); \ +} \ +static av_always_inline void bytestream2_put_ ## name(PutByteContext *p, \ + const type value) \ +{ \ + if (!p->eof && (p->buffer_end - p->buffer >= bytes)) { \ + write(p->buffer, value); \ + p->buffer += bytes; \ + } else \ + p->eof = 1; \ +} \ +static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g) \ +{ \ + return bytestream_get_ ## name(&g->buffer); \ +} \ +static av_always_inline type bytestream2_get_ ## name(GetByteContext *g) \ +{ \ + if (g->buffer_end - g->buffer < bytes) { \ + g->buffer = g->buffer_end; \ + return 0; \ + } \ + return bytestream2_get_ ## name ## u(g); \ +} \ +static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g) \ +{ \ + if (g->buffer_end - g->buffer < bytes) \ + return 0; \ + return read(g->buffer); \ +} + +DEF(uint64_t, le64, 8, AV_RL64, AV_WL64) +DEF(unsigned int, le32, 4, AV_RL32, AV_WL32) +DEF(unsigned int, le24, 3, AV_RL24, AV_WL24) +DEF(unsigned int, le16, 2, AV_RL16, AV_WL16) +DEF(uint64_t, be64, 8, AV_RB64, AV_WB64) +DEF(unsigned int, be32, 4, AV_RB32, AV_WB32) +DEF(unsigned int, be24, 3, AV_RB24, AV_WB24) +DEF(unsigned int, be16, 2, AV_RB16, AV_WB16) +DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8) + +#if AV_HAVE_BIGENDIAN +# define bytestream2_get_ne16 bytestream2_get_be16 +# define bytestream2_get_ne24 bytestream2_get_be24 +# define bytestream2_get_ne32 bytestream2_get_be32 +# define bytestream2_get_ne64 bytestream2_get_be64 +# define bytestream2_get_ne16u bytestream2_get_be16u +# define bytestream2_get_ne24u bytestream2_get_be24u +# define bytestream2_get_ne32u bytestream2_get_be32u +# define bytestream2_get_ne64u bytestream2_get_be64u +# define bytestream2_put_ne16 bytestream2_put_be16 +# define bytestream2_put_ne24 bytestream2_put_be24 +# define bytestream2_put_ne32 bytestream2_put_be32 +# define bytestream2_put_ne64 bytestream2_put_be64 +# define bytestream2_peek_ne16 bytestream2_peek_be16 +# define bytestream2_peek_ne24 bytestream2_peek_be24 +# define bytestream2_peek_ne32 bytestream2_peek_be32 +# define bytestream2_peek_ne64 bytestream2_peek_be64 +#else +# define bytestream2_get_ne16 bytestream2_get_le16 +# define bytestream2_get_ne24 bytestream2_get_le24 +# define bytestream2_get_ne32 bytestream2_get_le32 +# define bytestream2_get_ne64 bytestream2_get_le64 +# define bytestream2_get_ne16u bytestream2_get_le16u +# define bytestream2_get_ne24u bytestream2_get_le24u +# define bytestream2_get_ne32u bytestream2_get_le32u +# define bytestream2_get_ne64u bytestream2_get_le64u +# define bytestream2_put_ne16 bytestream2_put_le16 +# define bytestream2_put_ne24 bytestream2_put_le24 +# define bytestream2_put_ne32 bytestream2_put_le32 +# define bytestream2_put_ne64 bytestream2_put_le64 +# define bytestream2_peek_ne16 bytestream2_peek_le16 +# define bytestream2_peek_ne24 bytestream2_peek_le24 +# define bytestream2_peek_ne32 bytestream2_peek_le32 +# define bytestream2_peek_ne64 bytestream2_peek_le64 +#endif + +static av_always_inline void bytestream2_init(GetByteContext *g, + const uint8_t *buf, + int buf_size) +{ + av_assert0(buf_size >= 0); + g->buffer = buf; + g->buffer_start = buf; + g->buffer_end = buf + buf_size; +} + +static av_always_inline void bytestream2_init_writer(PutByteContext *p, + uint8_t *buf, + int buf_size) +{ + av_assert0(buf_size >= 0); + p->buffer = buf; + p->buffer_start = buf; + p->buffer_end = buf + buf_size; + p->eof = 0; +} + +static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g) +{ + return g->buffer_end - g->buffer; +} + +static av_always_inline unsigned int bytestream2_get_bytes_left_p(PutByteContext *p) +{ + return p->buffer_end - p->buffer; +} + +static av_always_inline void bytestream2_skip(GetByteContext *g, + unsigned int size) +{ + g->buffer += FFMIN(g->buffer_end - g->buffer, size); +} + +static av_always_inline void bytestream2_skipu(GetByteContext *g, + unsigned int size) +{ + g->buffer += size; +} + +static av_always_inline void bytestream2_skip_p(PutByteContext *p, + unsigned int size) +{ + int size2; + if (p->eof) + return; + size2 = FFMIN(p->buffer_end - p->buffer, size); + if (size2 != size) + p->eof = 1; + p->buffer += size2; +} + +static av_always_inline int bytestream2_tell(GetByteContext *g) +{ + return (int)(g->buffer - g->buffer_start); +} + +static av_always_inline int bytestream2_tell_p(PutByteContext *p) +{ + return (int)(p->buffer - p->buffer_start); +} + +static av_always_inline int bytestream2_size(GetByteContext *g) +{ + return (int)(g->buffer_end - g->buffer_start); +} + +static av_always_inline int bytestream2_size_p(PutByteContext *p) +{ + return (int)(p->buffer_end - p->buffer_start); +} + +static av_always_inline int bytestream2_seek(GetByteContext *g, + int offset, + int whence) +{ + switch (whence) { + case SEEK_CUR: + offset = av_clip(offset, -(g->buffer - g->buffer_start), + g->buffer_end - g->buffer); + g->buffer += offset; + break; + case SEEK_END: + offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0); + g->buffer = g->buffer_end + offset; + break; + case SEEK_SET: + offset = av_clip(offset, 0, g->buffer_end - g->buffer_start); + g->buffer = g->buffer_start + offset; + break; + default: + return AVERROR(EINVAL); + } + return bytestream2_tell(g); +} + +static av_always_inline int bytestream2_seek_p(PutByteContext *p, + int offset, + int whence) +{ + p->eof = 0; + switch (whence) { + case SEEK_CUR: + if (p->buffer_end - p->buffer < offset) + p->eof = 1; + offset = av_clip(offset, -(p->buffer - p->buffer_start), + p->buffer_end - p->buffer); + p->buffer += offset; + break; + case SEEK_END: + if (offset > 0) + p->eof = 1; + offset = av_clip(offset, -(p->buffer_end - p->buffer_start), 0); + p->buffer = p->buffer_end + offset; + break; + case SEEK_SET: + if (p->buffer_end - p->buffer_start < offset) + p->eof = 1; + offset = av_clip(offset, 0, p->buffer_end - p->buffer_start); + p->buffer = p->buffer_start + offset; + break; + default: + return AVERROR(EINVAL); + } + return bytestream2_tell_p(p); +} + +static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, + uint8_t *dst, + unsigned int size) +{ + int size2 = FFMIN(g->buffer_end - g->buffer, size); + memcpy(dst, g->buffer, size2); + g->buffer += size2; + return size2; +} + +static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, + uint8_t *dst, + unsigned int size) +{ + memcpy(dst, g->buffer, size); + g->buffer += size; + return size; +} + +static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, + const uint8_t *src, + unsigned int size) +{ + int size2; + if (p->eof) + return 0; + size2 = FFMIN(p->buffer_end - p->buffer, size); + if (size2 != size) + p->eof = 1; + memcpy(p->buffer, src, size2); + p->buffer += size2; + return size2; +} + +static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p, + const uint8_t *src, + unsigned int size) +{ + memcpy(p->buffer, src, size); + p->buffer += size; + return size; +} + +static av_always_inline void bytestream2_set_buffer(PutByteContext *p, + const uint8_t c, + unsigned int size) +{ + int size2; + if (p->eof) + return; + size2 = FFMIN(p->buffer_end - p->buffer, size); + if (size2 != size) + p->eof = 1; + memset(p->buffer, c, size2); + p->buffer += size2; +} + +static av_always_inline void bytestream2_set_bufferu(PutByteContext *p, + const uint8_t c, + unsigned int size) +{ + memset(p->buffer, c, size); + p->buffer += size; +} + +static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p) +{ + return p->eof; +} + +static av_always_inline unsigned int bytestream2_copy_bufferu(PutByteContext *p, + GetByteContext *g, + unsigned int size) +{ + memcpy(p->buffer, g->buffer, size); + p->buffer += size; + g->buffer += size; + return size; +} + +static av_always_inline unsigned int bytestream2_copy_buffer(PutByteContext *p, + GetByteContext *g, + unsigned int size) +{ + int size2; + + if (p->eof) + return 0; + size = FFMIN(g->buffer_end - g->buffer, size); + size2 = FFMIN(p->buffer_end - p->buffer, size); + if (size2 != size) + p->eof = 1; + + return bytestream2_copy_bufferu(p, g, size2); +} + +static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, + uint8_t *dst, + unsigned int size) +{ + memcpy(dst, *b, size); + (*b) += size; + return size; +} + +static av_always_inline void bytestream_put_buffer(uint8_t **b, + const uint8_t *src, + unsigned int size) +{ + memcpy(*b, src, size); + (*b) += size; +} + +#endif /* AVCODEC_BYTESTREAM_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data.c new file mode 100644 index 000000000..d2e36cd6d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "cbrt_data.h" + +#include "libavutil/libm.h" + +#if CONFIG_HARDCODED_TABLES +#include "libavcodec/cbrt_tables.h" +#else +#include "cbrt_tablegen.h" +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data.h new file mode 100644 index 000000000..89117f85b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_CBRT_DATA_H +#define AVCODEC_CBRT_DATA_H + +#include + +#include "config.h" + +#if CONFIG_HARDCODED_TABLES +#define ff_cbrt_tableinit_fixed() +#define ff_cbrt_tableinit() +extern const uint32_t ff_cbrt_tab[1 << 13]; +extern const uint32_t ff_cbrt_tab_fixed[1 << 13]; +#else +void ff_cbrt_tableinit(void); +void ff_cbrt_tableinit_fixed(void); +extern uint32_t ff_cbrt_tab[1 << 13]; +extern uint32_t ff_cbrt_tab_fixed[1 << 13]; +#endif + +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data_fixed.c new file mode 100644 index 000000000..d661b25a6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_data_fixed.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "cbrt_data.h" + +#if CONFIG_HARDCODED_TABLES +#include "libavcodec/cbrt_fixed_tables.h" +#else +#define USE_FIXED 1 +#include "cbrt_tablegen.h" +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.c new file mode 100644 index 000000000..8c2235e98 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.c @@ -0,0 +1,24 @@ +/* + * Generate a header file for hardcoded AAC cube-root table + * + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 0 +#include "cbrt_tablegen_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.h new file mode 100644 index 000000000..9af18d8ab --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/cbrt_tablegen.h @@ -0,0 +1,73 @@ +/* + * Header file for hardcoded AAC cube-root table + * + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_CBRT_TABLEGEN_H +#define AVCODEC_CBRT_TABLEGEN_H + +#include +#include +#include "libavutil/attributes.h" +#include "libavutil/intfloat.h" +#include "libavcodec/aac_defines.h" + +#if USE_FIXED +#define CBRT(x) lrint((x) * 8192) +#else +#define CBRT(x) av_float2int((float)(x)) +#endif + +uint32_t AAC_RENAME(ff_cbrt_tab)[1 << 13]; + +av_cold void AAC_RENAME(ff_cbrt_tableinit)(void) +{ + static double cbrt_tab_dbl[1 << 13]; + if (!AAC_RENAME(ff_cbrt_tab)[(1<<13) - 1]) { + int i, j, k; + double cbrt_val; + + for (i = 1; i < 1<<13; i++) + cbrt_tab_dbl[i] = 1; + + /* have to take care of non-squarefree numbers */ + for (i = 2; i < 90; i++) { + if (cbrt_tab_dbl[i] == 1) { + cbrt_val = i * cbrt(i); + for (k = i; k < 1<<13; k *= i) + for (j = k; j < 1<<13; j += k) + cbrt_tab_dbl[j] *= cbrt_val; + } + } + + for (i = 91; i <= 8191; i+= 2) { + if (cbrt_tab_dbl[i] == 1) { + cbrt_val = i * cbrt(i); + for (j = i; j < 1<<13; j += i) + cbrt_tab_dbl[j] *= cbrt_val; + } + } + + for (i = 0; i < 1<<13; i++) + AAC_RENAME(ff_cbrt_tab)[i] = CBRT(cbrt_tab_dbl[i]); + } +} + +#endif /* AVCODEC_CBRT_TABLEGEN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/codec_desc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/codec_desc.c new file mode 100644 index 000000000..4d033c20f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/codec_desc.c @@ -0,0 +1,3286 @@ +/* + * This file is part of FFmpeg. + * + * This table was generated from the long and short names of AVCodecs + * please see the respective codec sources for authorship + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/internal.h" +#include "avcodec.h" +#include "profiles.h" +#include "version.h" + +#define MT(...) (const char *const[]){ __VA_ARGS__, NULL } + +static const AVCodecDescriptor codec_descriptors[] = { + /* video codecs */ + { + .id = AV_CODEC_ID_MPEG1VIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mpeg1video", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_MPEG2VIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mpeg2video", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + .profiles = NULL_IF_CONFIG_SMALL(ff_mpeg2_video_profiles), + }, + { + .id = AV_CODEC_ID_H261, + .type = AVMEDIA_TYPE_VIDEO, + .name = "h261", + .long_name = NULL_IF_CONFIG_SMALL("H.261"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_H263, + .type = AVMEDIA_TYPE_VIDEO, + .name = "h263", + .long_name = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_RV10, + .type = AVMEDIA_TYPE_VIDEO, + .name = "rv10", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_RV20, + .type = AVMEDIA_TYPE_VIDEO, + .name = "rv20", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_MJPEG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mjpeg", + .long_name = NULL_IF_CONFIG_SMALL("Motion JPEG"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + .mime_types= MT("image/jpeg"), + .profiles = NULL_IF_CONFIG_SMALL(ff_mjpeg_profiles), + }, + { + .id = AV_CODEC_ID_MJPEGB, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mjpegb", + .long_name = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_LJPEG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ljpeg", + .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SP5X, + .type = AVMEDIA_TYPE_VIDEO, + .name = "sp5x", + .long_name = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_JPEGLS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "jpegls", + .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | + AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MPEG4, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mpeg4", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + .profiles = NULL_IF_CONFIG_SMALL(ff_mpeg4_video_profiles), + }, + { + .id = AV_CODEC_ID_RAWVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "rawvideo", + .long_name = NULL_IF_CONFIG_SMALL("raw video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MSMPEG4V1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "msmpeg4v1", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MSMPEG4V2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "msmpeg4v2", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MSMPEG4V3, + .type = AVMEDIA_TYPE_VIDEO, + .name = "msmpeg4v3", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WMV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "wmv1", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 7"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WMV2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "wmv2", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_H263P, + .type = AVMEDIA_TYPE_VIDEO, + .name = "h263p", + .long_name = NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_H263I, + .type = AVMEDIA_TYPE_VIDEO, + .name = "h263i", + .long_name = NULL_IF_CONFIG_SMALL("Intel H.263"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_FLV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "flv1", + .long_name = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SVQ1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "svq1", + .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SVQ3, + .type = AVMEDIA_TYPE_VIDEO, + .name = "svq3", + .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_DVVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dvvideo", + .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_HUFFYUV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "huffyuv", + .long_name = NULL_IF_CONFIG_SMALL("HuffYUV"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_CYUV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cyuv", + .long_name = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_H264, + .type = AVMEDIA_TYPE_VIDEO, + .name = "h264", + .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS | AV_CODEC_PROP_REORDER, + .profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles), + }, + { + .id = AV_CODEC_ID_INDEO3, + .type = AVMEDIA_TYPE_VIDEO, + .name = "indeo3", + .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VP3, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vp3", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_THEORA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "theora", + .long_name = NULL_IF_CONFIG_SMALL("Theora"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ASV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "asv1", + .long_name = NULL_IF_CONFIG_SMALL("ASUS V1"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ASV2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "asv2", + .long_name = NULL_IF_CONFIG_SMALL("ASUS V2"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FFV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ffv1", + .long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_4XM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "4xm", + .long_name = NULL_IF_CONFIG_SMALL("4X Movie"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VCR1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vcr1", + .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CLJR, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cljr", + .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MDEC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mdec", + .long_name = NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ROQ, + .type = AVMEDIA_TYPE_VIDEO, + .name = "roq", + .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_INTERPLAY_VIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "interplayvideo", + .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_XAN_WC3, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xan_wc3", + .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_XAN_WC4, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xan_wc4", + .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_RPZA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "rpza", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime video (RPZA)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CINEPAK, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cinepak", + .long_name = NULL_IF_CONFIG_SMALL("Cinepak"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WS_VQA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ws_vqa", + .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA (Vector Quantized Animation) video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MSRLE, + .type = AVMEDIA_TYPE_VIDEO, + .name = "msrle", + .long_name = NULL_IF_CONFIG_SMALL("Microsoft RLE"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MSVIDEO1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "msvideo1", + .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video 1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_IDCIN, + .type = AVMEDIA_TYPE_VIDEO, + .name = "idcin", + .long_name = NULL_IF_CONFIG_SMALL("id Quake II CIN video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_8BPS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "8bps", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SMC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "smc", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FLIC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "flic", + .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_TRUEMOTION1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "truemotion1", + .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VMDVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vmdvideo", + .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MSZH, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mszh", + .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ZLIB, + .type = AVMEDIA_TYPE_VIDEO, + .name = "zlib", + .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_QTRLE, + .type = AVMEDIA_TYPE_VIDEO, + .name = "qtrle", + .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_TSCC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "tscc", + .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Capture Codec"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ULTI, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ulti", + .long_name = NULL_IF_CONFIG_SMALL("IBM UltiMotion"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_QDRAW, + .type = AVMEDIA_TYPE_VIDEO, + .name = "qdraw", + .long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_VIXL, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vixl", + .long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_QPEG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "qpeg", + .long_name = NULL_IF_CONFIG_SMALL("Q-team QPEG"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PNG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "png", + .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"), + .props = AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/png"), + }, + { + .id = AV_CODEC_ID_PPM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ppm", + .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PBM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pbm", + .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PGM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pgm", + .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PGMYUV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pgmyuv", + .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PAM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pam", + .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-portable-pixmap"), + }, + { + .id = AV_CODEC_ID_FFVHUFF, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ffvhuff", + .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_RV30, + .type = AVMEDIA_TYPE_VIDEO, + .name = "rv30", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 3.0"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_RV40, + .type = AVMEDIA_TYPE_VIDEO, + .name = "rv40", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_VC1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vc1", + .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + .profiles = NULL_IF_CONFIG_SMALL(ff_vc1_profiles), + }, + { + .id = AV_CODEC_ID_WMV3, + .type = AVMEDIA_TYPE_VIDEO, + .name = "wmv3", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + .profiles = NULL_IF_CONFIG_SMALL(ff_vc1_profiles), + }, + { + .id = AV_CODEC_ID_LOCO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "loco", + .long_name = NULL_IF_CONFIG_SMALL("LOCO"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_WNV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "wnv1", + .long_name = NULL_IF_CONFIG_SMALL("Winnov WNV1"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AASC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "aasc", + .long_name = NULL_IF_CONFIG_SMALL("Autodesk RLE"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_INDEO2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "indeo2", + .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FRAPS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fraps", + .long_name = NULL_IF_CONFIG_SMALL("Fraps"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_TRUEMOTION2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "truemotion2", + .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_BMP, + .type = AVMEDIA_TYPE_VIDEO, + .name = "bmp", + .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-ms-bmp"), + }, + { + .id = AV_CODEC_ID_CSCD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cscd", + .long_name = NULL_IF_CONFIG_SMALL("CamStudio"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MMVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mmvideo", + .long_name = NULL_IF_CONFIG_SMALL("American Laser Games MM Video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ZMBV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "zmbv", + .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_AVS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "avs", + .long_name = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SMACKVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "smackvideo", + .long_name = NULL_IF_CONFIG_SMALL("Smacker video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_NUV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "nuv", + .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo/RTJPEG"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_KMVC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "kmvc", + .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FLASHSV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "flashsv", + .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_CAVS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cavs", + .long_name = NULL_IF_CONFIG_SMALL("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_JPEG2000, + .type = AVMEDIA_TYPE_VIDEO, + .name = "jpeg2000", + .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | + AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/jp2"), + .profiles = NULL_IF_CONFIG_SMALL(ff_jpeg2000_profiles), + }, + { + .id = AV_CODEC_ID_VMNC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vmnc", + .long_name = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_VP5, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vp5", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP5"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VP6, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vp6", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VP6F, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vp6f", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TARGA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "targa", + .long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-targa", "image/x-tga"), + }, + { + .id = AV_CODEC_ID_DSICINVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dsicinvideo", + .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TIERTEXSEQVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "tiertexseqvideo", + .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TIFF, + .type = AVMEDIA_TYPE_VIDEO, + .name = "tiff", + .long_name = NULL_IF_CONFIG_SMALL("TIFF image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/tiff"), + }, + { + .id = AV_CODEC_ID_GIF, + .type = AVMEDIA_TYPE_VIDEO, + .name = "gif", + .long_name = NULL_IF_CONFIG_SMALL("CompuServe GIF (Graphics Interchange Format)"), + .props = AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/gif"), + }, + { + .id = AV_CODEC_ID_DXA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dxa", + .long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_DNXHD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dnxhd", + .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + .profiles = NULL_IF_CONFIG_SMALL(ff_dnxhd_profiles), + }, + { + .id = AV_CODEC_ID_THP, + .type = AVMEDIA_TYPE_VIDEO, + .name = "thp", + .long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SGI, + .type = AVMEDIA_TYPE_VIDEO, + .name = "sgi", + .long_name = NULL_IF_CONFIG_SMALL("SGI image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_C93, + .type = AVMEDIA_TYPE_VIDEO, + .name = "c93", + .long_name = NULL_IF_CONFIG_SMALL("Interplay C93"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_BETHSOFTVID, + .type = AVMEDIA_TYPE_VIDEO, + .name = "bethsoftvid", + .long_name = NULL_IF_CONFIG_SMALL("Bethesda VID video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PTX, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ptx", + .long_name = NULL_IF_CONFIG_SMALL("V.Flash PTX image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TXD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "txd", + .long_name = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VP6A, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vp6a", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AMV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "amv", + .long_name = NULL_IF_CONFIG_SMALL("AMV Video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VB, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vb", + .long_name = NULL_IF_CONFIG_SMALL("Beam Software VB"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PCX, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pcx", + .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-pcx"), + }, + { + .id = AV_CODEC_ID_SUNRAST, + .type = AVMEDIA_TYPE_VIDEO, + .name = "sunrast", + .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_INDEO4, + .type = AVMEDIA_TYPE_VIDEO, + .name = "indeo4", + .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_INDEO5, + .type = AVMEDIA_TYPE_VIDEO, + .name = "indeo5", + .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MIMIC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mimic", + .long_name = NULL_IF_CONFIG_SMALL("Mimic"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_RL2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "rl2", + .long_name = NULL_IF_CONFIG_SMALL("RL2 video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ESCAPE124, + .type = AVMEDIA_TYPE_VIDEO, + .name = "escape124", + .long_name = NULL_IF_CONFIG_SMALL("Escape 124"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DIRAC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dirac", + .long_name = NULL_IF_CONFIG_SMALL("Dirac"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS | AV_CODEC_PROP_REORDER, + }, + { + .id = AV_CODEC_ID_BFI, + .type = AVMEDIA_TYPE_VIDEO, + .name = "bfi", + .long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CMV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cmv", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts CMV video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MOTIONPIXELS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "motionpixels", + .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TGV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "tgv", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TGQ, + .type = AVMEDIA_TYPE_VIDEO, + .name = "tgq", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TQI, + .type = AVMEDIA_TYPE_VIDEO, + .name = "tqi", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AURA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "aura", + .long_name = NULL_IF_CONFIG_SMALL("Auravision AURA"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AURA2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "aura2", + .long_name = NULL_IF_CONFIG_SMALL("Auravision Aura 2"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_V210X, + .type = AVMEDIA_TYPE_VIDEO, + .name = "v210x", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_TMV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "tmv", + .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_V210, + .type = AVMEDIA_TYPE_VIDEO, + .name = "v210", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_DPX, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dpx", + .long_name = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MAD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mad", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FRWU, + .type = AVMEDIA_TYPE_VIDEO, + .name = "frwu", + .long_name = NULL_IF_CONFIG_SMALL("Forward Uncompressed"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_FLASHSV2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "flashsv2", + .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CDGRAPHICS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cdgraphics", + .long_name = NULL_IF_CONFIG_SMALL("CD Graphics video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_R210, + .type = AVMEDIA_TYPE_VIDEO, + .name = "r210", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ANM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "anm", + .long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_BINKVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "binkvideo", + .long_name = NULL_IF_CONFIG_SMALL("Bink video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_IFF_ILBM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "iff_ilbm", + .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_KGV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "kgv1", + .long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_YOP, + .type = AVMEDIA_TYPE_VIDEO, + .name = "yop", + .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VP8, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vp8", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PICTOR, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pictor", + .long_name = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ANSI, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ansi", + .long_name = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_A64_MULTI, + .type = AVMEDIA_TYPE_VIDEO, + .name = "a64_multi", + .long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_A64_MULTI5, + .type = AVMEDIA_TYPE_VIDEO, + .name = "a64_multi5", + .long_name = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_R10K, + .type = AVMEDIA_TYPE_VIDEO, + .name = "r10k", + .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MXPEG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mxpeg", + .long_name = NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_LAGARITH, + .type = AVMEDIA_TYPE_VIDEO, + .name = "lagarith", + .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PRORES, + .type = AVMEDIA_TYPE_VIDEO, + .name = "prores", + .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles), + }, + { + .id = AV_CODEC_ID_JV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "jv", + .long_name = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DFA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dfa", + .long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WMV3IMAGE, + .type = AVMEDIA_TYPE_VIDEO, + .name = "wmv3image", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VC1IMAGE, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vc1image", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_UTVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "utvideo", + .long_name = NULL_IF_CONFIG_SMALL("Ut Video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_BMV_VIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "bmv_video", + .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV video"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_VBLE, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vble", + .long_name = NULL_IF_CONFIG_SMALL("VBLE Lossless Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_DXTORY, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dxtory", + .long_name = NULL_IF_CONFIG_SMALL("Dxtory"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_V410, + .type = AVMEDIA_TYPE_VIDEO, + .name = "v410", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_XWD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xwd", + .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-xwindowdump"), + }, + { + .id = AV_CODEC_ID_CDXL, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cdxl", + .long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_XBM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xbm", + .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-xbitmap"), + }, + { + .id = AV_CODEC_ID_ZEROCODEC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "zerocodec", + .long_name = NULL_IF_CONFIG_SMALL("ZeroCodec Lossless Video"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MSS1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mss1", + .long_name = NULL_IF_CONFIG_SMALL("MS Screen 1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MSA1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "msa1", + .long_name = NULL_IF_CONFIG_SMALL("MS ATC Screen"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TSCC2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "tscc2", + .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MTS2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mts2", + .long_name = NULL_IF_CONFIG_SMALL("MS Expression Encoder Screen"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CLLC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cllc", + .long_name = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MSS2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mss2", + .long_name = NULL_IF_CONFIG_SMALL("MS Windows Media Video V9 Screen"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VP9, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vp9", + .long_name = NULL_IF_CONFIG_SMALL("Google VP9"), + .props = AV_CODEC_PROP_LOSSY, + .profiles = NULL_IF_CONFIG_SMALL(ff_vp9_profiles), + }, + { + .id = AV_CODEC_ID_AIC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "aic", + .long_name = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ESCAPE130, + .type = AVMEDIA_TYPE_VIDEO, + .name = "escape130", + .long_name = NULL_IF_CONFIG_SMALL("Escape 130"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_G2M, + .type = AVMEDIA_TYPE_VIDEO, + .name = "g2m", + .long_name = NULL_IF_CONFIG_SMALL("Go2Meeting"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WEBP, + .type = AVMEDIA_TYPE_VIDEO, + .name = "webp", + .long_name = NULL_IF_CONFIG_SMALL("WebP"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | + AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/webp"), + }, + { + .id = AV_CODEC_ID_HNM4_VIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hnm4video", + .long_name = NULL_IF_CONFIG_SMALL("HNM 4 video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_HEVC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hevc", + .long_name = NULL_IF_CONFIG_SMALL("H.265 / HEVC (High Efficiency Video Coding)"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_REORDER, + .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles), + }, + { + .id = AV_CODEC_ID_FIC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fic", + .long_name = NULL_IF_CONFIG_SMALL("Mirillis FIC"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ALIAS_PIX, + .type = AVMEDIA_TYPE_VIDEO, + .name = "alias_pix", + .long_name = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_BRENDER_PIX, + .type = AVMEDIA_TYPE_VIDEO, + .name = "brender_pix", + .long_name = NULL_IF_CONFIG_SMALL("BRender PIX image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PAF_VIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "paf_video", + .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_EXR, + .type = AVMEDIA_TYPE_VIDEO, + .name = "exr", + .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | + AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_VP7, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vp7", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP7"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SANM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "sanm", + .long_name = NULL_IF_CONFIG_SMALL("LucasArts SANM/SMUSH video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SGIRLE, + .type = AVMEDIA_TYPE_VIDEO, + .name = "sgirle", + .long_name = NULL_IF_CONFIG_SMALL("SGI RLE 8-bit"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MVC1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mvc1", + .long_name = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 1"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MVC2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mvc2", + .long_name = NULL_IF_CONFIG_SMALL("Silicon Graphics Motion Video Compressor 2"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_HQX, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hqx", + .long_name = NULL_IF_CONFIG_SMALL("Canopus HQX"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TDSC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "tdsc", + .long_name = NULL_IF_CONFIG_SMALL("TDSC"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_HQ_HQA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hq_hqa", + .long_name = NULL_IF_CONFIG_SMALL("Canopus HQ/HQA"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_HAP, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hap", + .long_name = NULL_IF_CONFIG_SMALL("Vidvox Hap"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DDS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dds", + .long_name = NULL_IF_CONFIG_SMALL("DirectDraw Surface image decoder"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | + AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_DXV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dxv", + .long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SCREENPRESSO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "screenpresso", + .long_name = NULL_IF_CONFIG_SMALL("Screenpresso"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_RSCC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "rscc", + .long_name = NULL_IF_CONFIG_SMALL("innoHeim/Rsupport Screen Capture Codec"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_AVS2, + .type = AVMEDIA_TYPE_VIDEO, + .name = "avs2", + .long_name = NULL_IF_CONFIG_SMALL("AVS2-P2/IEEE1857.4"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_Y41P, + .type = AVMEDIA_TYPE_VIDEO, + .name = "y41p", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_AVRP, + .type = AVMEDIA_TYPE_VIDEO, + .name = "avrp", + .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_012V, + .type = AVMEDIA_TYPE_VIDEO, + .name = "012v", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_AVUI, + .type = AVMEDIA_TYPE_VIDEO, + .name = "avui", + .long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_AYUV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ayuv", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_TARGA_Y216, + .type = AVMEDIA_TYPE_VIDEO, + .name = "targa_y216", + .long_name = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_V308, + .type = AVMEDIA_TYPE_VIDEO, + .name = "v308", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_V408, + .type = AVMEDIA_TYPE_VIDEO, + .name = "v408", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_YUV4, + .type = AVMEDIA_TYPE_VIDEO, + .name = "yuv4", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_AVRN, + .type = AVMEDIA_TYPE_VIDEO, + .name = "avrn", + .long_name = NULL_IF_CONFIG_SMALL("Avid AVI Codec"), + }, + { + .id = AV_CODEC_ID_CPIA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cpia", + .long_name = NULL_IF_CONFIG_SMALL("CPiA video format"), + }, + { + .id = AV_CODEC_ID_XFACE, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xface", + .long_name = NULL_IF_CONFIG_SMALL("X-face image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SNOW, + .type = AVMEDIA_TYPE_VIDEO, + .name = "snow", + .long_name = NULL_IF_CONFIG_SMALL("Snow"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SMVJPEG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "smvjpeg", + .long_name = NULL_IF_CONFIG_SMALL("Sigmatel Motion Video"), + }, + { + .id = AV_CODEC_ID_APNG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "apng", + .long_name = NULL_IF_CONFIG_SMALL("APNG (Animated Portable Network Graphics) image"), + .props = AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/png"), + }, + { + .id = AV_CODEC_ID_DAALA, + .type = AVMEDIA_TYPE_VIDEO, + .name = "daala", + .long_name = NULL_IF_CONFIG_SMALL("Daala"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_CFHD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "cfhd", + .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TRUEMOTION2RT, + .type = AVMEDIA_TYPE_VIDEO, + .name = "truemotion2rt", + .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_M101, + .type = AVMEDIA_TYPE_VIDEO, + .name = "m101", + .long_name = NULL_IF_CONFIG_SMALL("Matrox Uncompressed SD"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MAGICYUV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "magicyuv", + .long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SHEERVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "sheervideo", + .long_name = NULL_IF_CONFIG_SMALL("BitJazz SheerVideo"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_YLC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ylc", + .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PSD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "psd", + .long_name = NULL_IF_CONFIG_SMALL("Photoshop PSD file"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PIXLET, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pixlet", + .long_name = NULL_IF_CONFIG_SMALL("Apple Pixlet"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SPEEDHQ, + .type = AVMEDIA_TYPE_VIDEO, + .name = "speedhq", + .long_name = NULL_IF_CONFIG_SMALL("NewTek SpeedHQ"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FMVC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fmvc", + .long_name = NULL_IF_CONFIG_SMALL("FM Screen Capture Codec"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SCPR, + .type = AVMEDIA_TYPE_VIDEO, + .name = "scpr", + .long_name = NULL_IF_CONFIG_SMALL("ScreenPressor"), + .props = AV_CODEC_PROP_LOSSLESS | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CLEARVIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "clearvideo", + .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_XPM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xpm", + .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/x-xpixmap"), + }, + { + .id = AV_CODEC_ID_AV1, + .type = AVMEDIA_TYPE_VIDEO, + .name = "av1", + .long_name = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"), + .props = AV_CODEC_PROP_LOSSY, + .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), + }, + { + .id = AV_CODEC_ID_BITPACKED, + .type = AVMEDIA_TYPE_VIDEO, + .name = "bitpacked", + .long_name = NULL_IF_CONFIG_SMALL("Bitpacked"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MSCC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mscc", + .long_name = NULL_IF_CONFIG_SMALL("Mandsoft Screen Capture Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SRGC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "srgc", + .long_name = NULL_IF_CONFIG_SMALL("Screen Recorder Gold Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SVG, + .type = AVMEDIA_TYPE_VIDEO, + .name = "svg", + .long_name = NULL_IF_CONFIG_SMALL("Scalable Vector Graphics"), + .props = AV_CODEC_PROP_LOSSLESS, + .mime_types= MT("image/svg+xml"), + }, + { + .id = AV_CODEC_ID_GDV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "gdv", + .long_name = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FITS, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fits", + .long_name = NULL_IF_CONFIG_SMALL("FITS (Flexible Image Transport System)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_IMM4, + .type = AVMEDIA_TYPE_VIDEO, + .name = "imm4", + .long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PROSUMER, + .type = AVMEDIA_TYPE_VIDEO, + .name = "prosumer", + .long_name = NULL_IF_CONFIG_SMALL("Brooktree ProSumer Video"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MWSC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "mwsc", + .long_name = NULL_IF_CONFIG_SMALL("MatchWare Screen Capture Codec"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_WCMV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "wcmv", + .long_name = NULL_IF_CONFIG_SMALL("WinCAM Motion Video"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_RASC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "rasc", + .long_name = NULL_IF_CONFIG_SMALL("RemotelyAnywhere Screen Capture"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_HYMT, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hymt", + .long_name = NULL_IF_CONFIG_SMALL("HuffYUV MT"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ARBC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "arbc", + .long_name = NULL_IF_CONFIG_SMALL("Gryphon's Anim Compressor"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AGM, + .type = AVMEDIA_TYPE_VIDEO, + .name = "agm", + .long_name = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_LSCR, + .type = AVMEDIA_TYPE_VIDEO, + .name = "lscr", + .long_name = NULL_IF_CONFIG_SMALL("LEAD Screen Capture"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VP4, + .type = AVMEDIA_TYPE_VIDEO, + .name = "vp4", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP4"), + .props = AV_CODEC_PROP_LOSSY, + }, + + /* various PCM "codecs" */ + { + .id = AV_CODEC_ID_PCM_S16LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s16le", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16-bit little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S16BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s16be", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_U16LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_u16le", + .long_name = NULL_IF_CONFIG_SMALL("PCM unsigned 16-bit little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_U16BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_u16be", + .long_name = NULL_IF_CONFIG_SMALL("PCM unsigned 16-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S8, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s8", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 8-bit"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_U8, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_u8", + .long_name = NULL_IF_CONFIG_SMALL("PCM unsigned 8-bit"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_MULAW, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_mulaw", + .long_name = NULL_IF_CONFIG_SMALL("PCM mu-law / G.711 mu-law"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PCM_ALAW, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_alaw", + .long_name = NULL_IF_CONFIG_SMALL("PCM A-law / G.711 A-law"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PCM_S32LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s32le", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 32-bit little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S32BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s32be", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 32-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_U32LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_u32le", + .long_name = NULL_IF_CONFIG_SMALL("PCM unsigned 32-bit little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_U32BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_u32be", + .long_name = NULL_IF_CONFIG_SMALL("PCM unsigned 32-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S24LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s24le", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 24-bit little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S24BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s24be", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 24-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_U24LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_u24le", + .long_name = NULL_IF_CONFIG_SMALL("PCM unsigned 24-bit little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_U24BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_u24be", + .long_name = NULL_IF_CONFIG_SMALL("PCM unsigned 24-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S24DAUD, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s24daud", + .long_name = NULL_IF_CONFIG_SMALL("PCM D-Cinema audio signed 24-bit"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_ZORK, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_zork", + .long_name = NULL_IF_CONFIG_SMALL("PCM Zork"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PCM_S16LE_PLANAR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s16le_planar", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16-bit little-endian planar"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_DVD, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_dvd", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 20|24-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_F32BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f32be", + .long_name = NULL_IF_CONFIG_SMALL("PCM 32-bit floating point big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_F32LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f32le", + .long_name = NULL_IF_CONFIG_SMALL("PCM 32-bit floating point little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_F64BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f64be", + .long_name = NULL_IF_CONFIG_SMALL("PCM 64-bit floating point big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_F64LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f64le", + .long_name = NULL_IF_CONFIG_SMALL("PCM 64-bit floating point little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_BLURAY, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_bluray", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_LXF, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_lxf", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 20-bit little-endian planar"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_S302M, + .type = AVMEDIA_TYPE_AUDIO, + .name = "s302m", + .long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S8_PLANAR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s8_planar", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 8-bit planar"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S24LE_PLANAR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s24le_planar", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 24-bit little-endian planar"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S32LE_PLANAR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s32le_planar", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 32-bit little-endian planar"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S16BE_PLANAR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s16be_planar", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16-bit big-endian planar"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S64LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s64le", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 64-bit little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S64BE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s64be", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 64-bit big-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_F16LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f16le", + .long_name = NULL_IF_CONFIG_SMALL("PCM 16.8 floating point little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_F24LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_f24le", + .long_name = NULL_IF_CONFIG_SMALL("PCM 24.0 floating point little-endian"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_VIDC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_vidc", + .long_name = NULL_IF_CONFIG_SMALL("PCM Archimedes VIDC"), + .props = AV_CODEC_PROP_LOSSY, + }, + + /* various ADPCM codecs */ + { + .id = AV_CODEC_ID_ADPCM_IMA_QT, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_qt", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA QuickTime"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_WAV, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_wav", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA WAV"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_DK3, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_dk3", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Duck DK3"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_DK4, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_dk4", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Duck DK4"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_WS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_ws", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Westwood"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_SMJPEG, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_smjpeg", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Loki SDL MJPEG"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_MS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ms", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Microsoft"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_4XM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_4xm", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM 4X Movie"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_XA, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_xa", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM CDROM XA"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_ADX, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_adx", + .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_EA, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ea", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Electronic Arts"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_G726, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_g726", + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_CT, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ct", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Creative Technology"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_SWF, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_swf", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Shockwave Flash"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_YAMAHA, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_yamaha", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Yamaha"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_SBPRO_4, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_sbpro_4", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Sound Blaster Pro 4-bit"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_SBPRO_3, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_sbpro_3", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Sound Blaster Pro 2.6-bit"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_SBPRO_2, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_sbpro_2", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Sound Blaster Pro 2-bit"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_THP, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_thp", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Nintendo THP"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_AMV, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_amv", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA AMV"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_EA_R1, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ea_r1", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Electronic Arts R1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_EA_R3, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ea_r3", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Electronic Arts R3"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_EA_R2, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ea_r2", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Electronic Arts R2"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_EA_SEAD, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_ea_sead", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Electronic Arts SEAD"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_EA_EACS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_ea_eacs", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Electronic Arts EACS"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_EA_XAS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ea_xas", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Electronic Arts XAS"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_EA_MAXIS_XA, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ea_maxis_xa", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Electronic Arts Maxis CDROM XA"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_ISS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_iss", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Funcom ISS"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_G722, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_g722", + .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_APC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_apc", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA CRYO APC"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_VIMA, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_vima", + .long_name = NULL_IF_CONFIG_SMALL("LucasArts VIMA audio"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_AFC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_afc", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Nintendo Gamecube AFC"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_OKI, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_oki", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Dialogic OKI"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_DTK, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_dtk", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Nintendo Gamecube DTK"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_RAD, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_rad", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Radical"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_G726LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_g726le", + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_THP_LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_thp_le", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Nintendo THP (Little-Endian)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_PSX, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_psx", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Playstation"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_AICA, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_aica", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM Yamaha AICA"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_IMA_DAT4, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_ima_dat4", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Eurocom DAT4"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_MTAF, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_mtaf", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM MTAF"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ADPCM_AGM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_agm", + .long_name = NULL_IF_CONFIG_SMALL("ADPCM AmuseGraphics Movie AGM"), + .props = AV_CODEC_PROP_LOSSY, + }, + + /* AMR */ + { + .id = AV_CODEC_ID_AMR_NB, + .type = AVMEDIA_TYPE_AUDIO, + .name = "amr_nb", + .long_name = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AMR_WB, + .type = AVMEDIA_TYPE_AUDIO, + .name = "amr_wb", + .long_name = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"), + .props = AV_CODEC_PROP_LOSSY, + }, + + /* RealAudio codecs*/ + { + .id = AV_CODEC_ID_RA_144, + .type = AVMEDIA_TYPE_AUDIO, + .name = "ra_144", + .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_RA_288, + .type = AVMEDIA_TYPE_AUDIO, + .name = "ra_288", + .long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"), + .props = AV_CODEC_PROP_LOSSY, + }, + + /* various DPCM codecs */ + { + .id = AV_CODEC_ID_ROQ_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "roq_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM id RoQ"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_INTERPLAY_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "interplay_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Interplay"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_XAN_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "xan_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Xan"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SOL_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "sol_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Sol"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SDX2_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "sdx2_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Squareroot-Delta-Exact"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_GREMLIN_DPCM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "gremlin_dpcm", + .long_name = NULL_IF_CONFIG_SMALL("DPCM Gremlin"), + .props = AV_CODEC_PROP_LOSSY, + }, + + /* audio codecs */ + { + .id = AV_CODEC_ID_MP2, + .type = AVMEDIA_TYPE_AUDIO, + .name = "mp2", + .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MP3, + .type = AVMEDIA_TYPE_AUDIO, + .name = "mp3", + .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AAC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "aac", + .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), + .props = AV_CODEC_PROP_LOSSY, + .profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles), + }, + { + .id = AV_CODEC_ID_AC3, + .type = AVMEDIA_TYPE_AUDIO, + .name = "ac3", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DTS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dts", + .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), + .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, + .profiles = NULL_IF_CONFIG_SMALL(ff_dca_profiles), + }, + { + .id = AV_CODEC_ID_VORBIS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "vorbis", + .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DVAUDIO, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dvaudio", + .long_name = NULL_IF_CONFIG_SMALL("DV audio"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WMAV1, + .type = AVMEDIA_TYPE_AUDIO, + .name = "wmav1", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WMAV2, + .type = AVMEDIA_TYPE_AUDIO, + .name = "wmav2", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MACE3, + .type = AVMEDIA_TYPE_AUDIO, + .name = "mace3", + .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MACE6, + .type = AVMEDIA_TYPE_AUDIO, + .name = "mace6", + .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_VMDAUDIO, + .type = AVMEDIA_TYPE_AUDIO, + .name = "vmdaudio", + .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FLAC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "flac", + .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MP3ADU, + .type = AVMEDIA_TYPE_AUDIO, + .name = "mp3adu", + .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MP3ON4, + .type = AVMEDIA_TYPE_AUDIO, + .name = "mp3on4", + .long_name = NULL_IF_CONFIG_SMALL("MP3onMP4"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SHORTEN, + .type = AVMEDIA_TYPE_AUDIO, + .name = "shorten", + .long_name = NULL_IF_CONFIG_SMALL("Shorten"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ALAC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "alac", + .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_WESTWOOD_SND1, + .type = AVMEDIA_TYPE_AUDIO, + .name = "westwood_snd1", + .long_name = NULL_IF_CONFIG_SMALL("Westwood Audio (SND1)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_GSM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "gsm", + .long_name = NULL_IF_CONFIG_SMALL("GSM"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_QDM2, + .type = AVMEDIA_TYPE_AUDIO, + .name = "qdm2", + .long_name = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_COOK, + .type = AVMEDIA_TYPE_AUDIO, + .name = "cook", + .long_name = NULL_IF_CONFIG_SMALL("Cook / Cooker / Gecko (RealAudio G2)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TRUESPEECH, + .type = AVMEDIA_TYPE_AUDIO, + .name = "truespeech", + .long_name = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TTA, + .type = AVMEDIA_TYPE_AUDIO, + .name = "tta", + .long_name = NULL_IF_CONFIG_SMALL("TTA (True Audio)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_SMACKAUDIO, + .type = AVMEDIA_TYPE_AUDIO, + .name = "smackaudio", + .long_name = NULL_IF_CONFIG_SMALL("Smacker audio"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_QCELP, + .type = AVMEDIA_TYPE_AUDIO, + .name = "qcelp", + .long_name = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WAVPACK, + .type = AVMEDIA_TYPE_AUDIO, + .name = "wavpack", + .long_name = NULL_IF_CONFIG_SMALL("WavPack"), + .props = AV_CODEC_PROP_INTRA_ONLY | + AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_DSICINAUDIO, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dsicinaudio", + .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_IMC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "imc", + .long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MUSEPACK7, + .type = AVMEDIA_TYPE_AUDIO, + .name = "musepack7", + .long_name = NULL_IF_CONFIG_SMALL("Musepack SV7"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MLP, + .type = AVMEDIA_TYPE_AUDIO, + .name = "mlp", + .long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_GSM_MS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "gsm_ms", + .long_name = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ATRAC3, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac3", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3 (Adaptive TRansform Acoustic Coding 3)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_APE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "ape", + .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_NELLYMOSER, + .type = AVMEDIA_TYPE_AUDIO, + .name = "nellymoser", + .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MUSEPACK8, + .type = AVMEDIA_TYPE_AUDIO, + .name = "musepack8", + .long_name = NULL_IF_CONFIG_SMALL("Musepack SV8"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SPEEX, + .type = AVMEDIA_TYPE_AUDIO, + .name = "speex", + .long_name = NULL_IF_CONFIG_SMALL("Speex"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WMAVOICE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "wmavoice", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WMAPRO, + .type = AVMEDIA_TYPE_AUDIO, + .name = "wmapro", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_WMALOSSLESS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "wmalossless", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ATRAC3P, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac3p", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ (Adaptive TRansform Acoustic Coding 3+)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_EAC3, + .type = AVMEDIA_TYPE_AUDIO, + .name = "eac3", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SIPR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "sipr", + .long_name = NULL_IF_CONFIG_SMALL("RealAudio SIPR / ACELP.NET"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_MP1, + .type = AVMEDIA_TYPE_AUDIO, + .name = "mp1", + .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TWINVQ, + .type = AVMEDIA_TYPE_AUDIO, + .name = "twinvq", + .long_name = NULL_IF_CONFIG_SMALL("VQF TwinVQ"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TRUEHD, + .type = AVMEDIA_TYPE_AUDIO, + .name = "truehd", + .long_name = NULL_IF_CONFIG_SMALL("TrueHD"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_MP4ALS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "mp4als", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ATRAC1, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac1", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC1 (Adaptive TRansform Acoustic Coding)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_BINKAUDIO_RDFT, + .type = AVMEDIA_TYPE_AUDIO, + .name = "binkaudio_rdft", + .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_BINKAUDIO_DCT, + .type = AVMEDIA_TYPE_AUDIO, + .name = "binkaudio_dct", + .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_AAC_LATM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "aac_latm", + .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"), + .props = AV_CODEC_PROP_LOSSY, + .profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles), + }, + { + .id = AV_CODEC_ID_QDMC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "qdmc", + .long_name = NULL_IF_CONFIG_SMALL("QDesign Music"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CELT, + .type = AVMEDIA_TYPE_AUDIO, + .name = "celt", + .long_name = NULL_IF_CONFIG_SMALL("Constrained Energy Lapped Transform (CELT)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_G723_1, + .type = AVMEDIA_TYPE_AUDIO, + .name = "g723_1", + .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_G729, + .type = AVMEDIA_TYPE_AUDIO, + .name = "g729", + .long_name = NULL_IF_CONFIG_SMALL("G.729"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_8SVX_EXP, + .type = AVMEDIA_TYPE_AUDIO, + .name = "8svx_exp", + .long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_8SVX_FIB, + .type = AVMEDIA_TYPE_AUDIO, + .name = "8svx_fib", + .long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_BMV_AUDIO, + .type = AVMEDIA_TYPE_AUDIO, + .name = "bmv_audio", + .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV audio"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_RALF, + .type = AVMEDIA_TYPE_AUDIO, + .name = "ralf", + .long_name = NULL_IF_CONFIG_SMALL("RealAudio Lossless"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_IAC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "iac", + .long_name = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ILBC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "ilbc", + .long_name = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_OPUS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "opus", + .long_name = NULL_IF_CONFIG_SMALL("Opus (Opus Interactive Audio Codec)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_COMFORT_NOISE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "comfortnoise", + .long_name = NULL_IF_CONFIG_SMALL("RFC 3389 Comfort Noise"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_TAK, + .type = AVMEDIA_TYPE_AUDIO, + .name = "tak", + .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_METASOUND, + .type = AVMEDIA_TYPE_AUDIO, + .name = "metasound", + .long_name = NULL_IF_CONFIG_SMALL("Voxware MetaSound"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_PAF_AUDIO, + .type = AVMEDIA_TYPE_AUDIO, + .name = "paf_audio", + .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Audio"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ON2AVC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "avc", + .long_name = NULL_IF_CONFIG_SMALL("On2 Audio for Video Codec"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DSS_SP, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dss_sp", + .long_name = NULL_IF_CONFIG_SMALL("Digital Speech Standard - Standard Play mode (DSS SP)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_CODEC2, + .type = AVMEDIA_TYPE_AUDIO, + .name = "codec2", + .long_name = NULL_IF_CONFIG_SMALL("codec2 (very low bitrate speech codec)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FFWAVESYNTH, + .type = AVMEDIA_TYPE_AUDIO, + .name = "wavesynth", + .long_name = NULL_IF_CONFIG_SMALL("Wave synthesis pseudo-codec"), + }, + { + .id = AV_CODEC_ID_SONIC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "sonic", + .long_name = NULL_IF_CONFIG_SMALL("Sonic"), + }, + { + .id = AV_CODEC_ID_SONIC_LS, + .type = AVMEDIA_TYPE_AUDIO, + .name = "sonicls", + .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"), + }, + { + .id = AV_CODEC_ID_EVRC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "evrc", + .long_name = NULL_IF_CONFIG_SMALL("EVRC (Enhanced Variable Rate Codec)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SMV, + .type = AVMEDIA_TYPE_AUDIO, + .name = "smv", + .long_name = NULL_IF_CONFIG_SMALL("SMV (Selectable Mode Vocoder)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DSD_LSBF, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dsd_lsbf", + .long_name = NULL_IF_CONFIG_SMALL("DSD (Direct Stream Digital), least significant bit first"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DSD_MSBF, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dsd_msbf", + .long_name = NULL_IF_CONFIG_SMALL("DSD (Direct Stream Digital), most significant bit first"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DSD_LSBF_PLANAR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dsd_lsbf_planar", + .long_name = NULL_IF_CONFIG_SMALL("DSD (Direct Stream Digital), least significant bit first, planar"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DSD_MSBF_PLANAR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dsd_msbf_planar", + .long_name = NULL_IF_CONFIG_SMALL("DSD (Direct Stream Digital), most significant bit first, planar"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_4GV, + .type = AVMEDIA_TYPE_AUDIO, + .name = "4gv", + .long_name = NULL_IF_CONFIG_SMALL("4GV (Fourth Generation Vocoder)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_INTERPLAY_ACM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "interplayacm", + .long_name = NULL_IF_CONFIG_SMALL("Interplay ACM"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_XMA1, + .type = AVMEDIA_TYPE_AUDIO, + .name = "xma1", + .long_name = NULL_IF_CONFIG_SMALL("Xbox Media Audio 1"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_XMA2, + .type = AVMEDIA_TYPE_AUDIO, + .name = "xma2", + .long_name = NULL_IF_CONFIG_SMALL("Xbox Media Audio 2"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_DST, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dst", + .long_name = NULL_IF_CONFIG_SMALL("DST (Direct Stream Transfer)"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ATRAC3AL, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac3al", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3 AL (Adaptive TRansform Acoustic Coding 3 Advanced Lossless)"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_ATRAC3PAL, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac3pal", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ AL (Adaptive TRansform Acoustic Coding 3+ Advanced Lossless)"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_DOLBY_E, + .type = AVMEDIA_TYPE_AUDIO, + .name = "dolby_e", + .long_name = NULL_IF_CONFIG_SMALL("Dolby E"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_APTX, + .type = AVMEDIA_TYPE_AUDIO, + .name = "aptx", + .long_name = NULL_IF_CONFIG_SMALL("aptX (Audio Processing Technology for Bluetooth)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_APTX_HD, + .type = AVMEDIA_TYPE_AUDIO, + .name = "aptx_hd", + .long_name = NULL_IF_CONFIG_SMALL("aptX HD (Audio Processing Technology for Bluetooth)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_SBC, + .type = AVMEDIA_TYPE_AUDIO, + .name = "sbc", + .long_name = NULL_IF_CONFIG_SMALL("SBC (low-complexity subband codec)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_ATRAC9, + .type = AVMEDIA_TYPE_AUDIO, + .name = "atrac9", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC9 (Adaptive TRansform Acoustic Coding 9)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_HCOM, + .type = AVMEDIA_TYPE_AUDIO, + .name = "hcom", + .long_name = NULL_IF_CONFIG_SMALL("HCOM Audio"), + .props = AV_CODEC_PROP_LOSSY, + }, + + /* subtitle codecs */ + { + .id = AV_CODEC_ID_DVD_SUBTITLE, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "dvd_subtitle", + .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), + .props = AV_CODEC_PROP_BITMAP_SUB, + }, + { + .id = AV_CODEC_ID_DVB_SUBTITLE, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "dvb_subtitle", + .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), + .props = AV_CODEC_PROP_BITMAP_SUB, + }, + { + .id = AV_CODEC_ID_TEXT, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "text", + .long_name = NULL_IF_CONFIG_SMALL("raw UTF-8 text"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_XSUB, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "xsub", + .long_name = NULL_IF_CONFIG_SMALL("XSUB"), + .props = AV_CODEC_PROP_BITMAP_SUB, + }, + { + .id = AV_CODEC_ID_SSA, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "ssa", + .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_MOV_TEXT, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "mov_text", + .long_name = NULL_IF_CONFIG_SMALL("MOV text"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_HDMV_PGS_SUBTITLE, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "hdmv_pgs_subtitle", + .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"), + .props = AV_CODEC_PROP_BITMAP_SUB, + }, + { + .id = AV_CODEC_ID_DVB_TELETEXT, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "dvb_teletext", + .long_name = NULL_IF_CONFIG_SMALL("DVB teletext"), + }, + { + .id = AV_CODEC_ID_SRT, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "srt", + .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_MICRODVD, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "microdvd", + .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_EIA_608, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "eia_608", + .long_name = NULL_IF_CONFIG_SMALL("EIA-608 closed captions"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_JACOSUB, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "jacosub", + .long_name = NULL_IF_CONFIG_SMALL("JACOsub subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_SAMI, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "sami", + .long_name = NULL_IF_CONFIG_SMALL("SAMI subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_REALTEXT, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "realtext", + .long_name = NULL_IF_CONFIG_SMALL("RealText subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_STL, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "stl", + .long_name = NULL_IF_CONFIG_SMALL("Spruce subtitle format"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_SUBVIEWER1, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "subviewer1", + .long_name = NULL_IF_CONFIG_SMALL("SubViewer v1 subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_SUBVIEWER, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "subviewer", + .long_name = NULL_IF_CONFIG_SMALL("SubViewer subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_SUBRIP, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "subrip", + .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_WEBVTT, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "webvtt", + .long_name = NULL_IF_CONFIG_SMALL("WebVTT subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_MPL2, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "mpl2", + .long_name = NULL_IF_CONFIG_SMALL("MPL2 subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_VPLAYER, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "vplayer", + .long_name = NULL_IF_CONFIG_SMALL("VPlayer subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_PJS, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "pjs", + .long_name = NULL_IF_CONFIG_SMALL("PJS (Phoenix Japanimation Society) subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_ASS, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "ass", + .long_name = NULL_IF_CONFIG_SMALL("ASS (Advanced SSA) subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_HDMV_TEXT_SUBTITLE, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "hdmv_text_subtitle", + .long_name = NULL_IF_CONFIG_SMALL("HDMV Text subtitle"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_TTML, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "ttml", + .long_name = NULL_IF_CONFIG_SMALL("Timed Text Markup Language"), + .props = AV_CODEC_PROP_TEXT_SUB, + }, + { + .id = AV_CODEC_ID_ARIB_CAPTION, + .type = AVMEDIA_TYPE_SUBTITLE, + .name = "arib_caption", + .long_name = NULL_IF_CONFIG_SMALL("ARIB STD-B24 caption"), + .props = AV_CODEC_PROP_TEXT_SUB, + .profiles = NULL_IF_CONFIG_SMALL(ff_arib_caption_profiles), + }, + + /* other kind of codecs and pseudo-codecs */ + { + .id = AV_CODEC_ID_TTF, + .type = AVMEDIA_TYPE_DATA, + .name = "ttf", + .long_name = NULL_IF_CONFIG_SMALL("TrueType font"), + .mime_types= MT("application/x-truetype-font", "application/x-font"), + }, + { + .id = AV_CODEC_ID_SCTE_35, + .type = AVMEDIA_TYPE_DATA, + .name = "scte_35", + .long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), + }, + { + .id = AV_CODEC_ID_BINTEXT, + .type = AVMEDIA_TYPE_VIDEO, + .name = "bintext", + .long_name = NULL_IF_CONFIG_SMALL("Binary text"), + .props = AV_CODEC_PROP_INTRA_ONLY, + }, + { + .id = AV_CODEC_ID_XBIN, + .type = AVMEDIA_TYPE_VIDEO, + .name = "xbin", + .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text"), + .props = AV_CODEC_PROP_INTRA_ONLY, + }, + { + .id = AV_CODEC_ID_IDF, + .type = AVMEDIA_TYPE_VIDEO, + .name = "idf", + .long_name = NULL_IF_CONFIG_SMALL("iCEDraw text"), + .props = AV_CODEC_PROP_INTRA_ONLY, + }, + { + .id = AV_CODEC_ID_OTF, + .type = AVMEDIA_TYPE_DATA, + .name = "otf", + .long_name = NULL_IF_CONFIG_SMALL("OpenType font"), + .mime_types= MT("application/vnd.ms-opentype"), + }, + { + .id = AV_CODEC_ID_SMPTE_KLV, + .type = AVMEDIA_TYPE_DATA, + .name = "klv", + .long_name = NULL_IF_CONFIG_SMALL("SMPTE 336M Key-Length-Value (KLV) metadata"), + }, + { + .id = AV_CODEC_ID_DVD_NAV, + .type = AVMEDIA_TYPE_DATA, + .name = "dvd_nav_packet", + .long_name = NULL_IF_CONFIG_SMALL("DVD Nav packet"), + }, + { + .id = AV_CODEC_ID_TIMED_ID3, + .type = AVMEDIA_TYPE_DATA, + .name = "timed_id3", + .long_name = NULL_IF_CONFIG_SMALL("timed ID3 metadata"), + }, + { + .id = AV_CODEC_ID_BIN_DATA, + .type = AVMEDIA_TYPE_DATA, + .name = "bin_data", + .long_name = NULL_IF_CONFIG_SMALL("binary data"), + .mime_types= MT("application/octet-stream"), + }, + { + .id = AV_CODEC_ID_WRAPPED_AVFRAME, + .type = AVMEDIA_TYPE_VIDEO, + .name = "wrapped_avframe", + .long_name = NULL_IF_CONFIG_SMALL("AVFrame to AVPacket passthrough"), + .props = AV_CODEC_PROP_LOSSLESS, + }, +}; + +static int descriptor_compare(const void *key, const void *member) +{ + enum AVCodecID id = *(const enum AVCodecID *) key; + const AVCodecDescriptor *desc = member; + + return id - desc->id; +} + +const AVCodecDescriptor *avcodec_descriptor_get(enum AVCodecID id) +{ + return bsearch(&id, codec_descriptors, FF_ARRAY_ELEMS(codec_descriptors), + sizeof(codec_descriptors[0]), descriptor_compare); +} + +const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev) +{ + if (!prev) + return &codec_descriptors[0]; + if (prev - codec_descriptors < FF_ARRAY_ELEMS(codec_descriptors) - 1) + return prev + 1; + return NULL; +} + +const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name) +{ + const AVCodecDescriptor *desc = NULL; + + while ((desc = avcodec_descriptor_next(desc))) + if (!strcmp(desc->name, name)) + return desc; + return NULL; +} + +enum AVMediaType avcodec_get_type(enum AVCodecID codec_id) +{ + const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id); + return desc ? desc->type : AVMEDIA_TYPE_UNKNOWN; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/codec_list.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/codec_list.c new file mode 100644 index 000000000..7a4fa626f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/codec_list.c @@ -0,0 +1,9 @@ +static const AVCodec * const codec_list[] = { + &ff_aac_encoder, + &ff_opus_encoder, + &ff_libopus_encoder, + &ff_aac_decoder, + &ff_aac_fixed_decoder, + &ff_aac_latm_decoder, + &ff_libopus_decoder, + NULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/d3d11va.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/d3d11va.c new file mode 100644 index 000000000..9967f322c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/d3d11va.c @@ -0,0 +1,48 @@ +/* + * Direct3D11 HW acceleration + * + * copyright (c) 2015 Steve Lhomme + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" + +#if CONFIG_D3D11VA +#include "libavutil/error.h" +#include "libavutil/mem.h" + +#include "d3d11va.h" + +AVD3D11VAContext *av_d3d11va_alloc_context(void) +{ + AVD3D11VAContext* res = av_mallocz(sizeof(AVD3D11VAContext)); + if (!res) + return NULL; + res->context_mutex = INVALID_HANDLE_VALUE; + return res; +} +#else +struct AVD3D11VAContext *av_d3d11va_alloc_context(void); + +struct AVD3D11VAContext *av_d3d11va_alloc_context(void) +{ + return NULL; +} +#endif /* CONFIG_D3D11VA */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/d3d11va.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/d3d11va.h new file mode 100644 index 000000000..6816b6c1e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/d3d11va.h @@ -0,0 +1,112 @@ +/* + * Direct3D11 HW acceleration + * + * copyright (c) 2009 Laurent Aimar + * copyright (c) 2015 Steve Lhomme + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_D3D11VA_H +#define AVCODEC_D3D11VA_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_d3d11va + * Public libavcodec D3D11VA header. + */ + +#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0602 +#endif + +#include +#include + +/** + * @defgroup lavc_codec_hwaccel_d3d11va Direct3D11 + * @ingroup lavc_codec_hwaccel + * + * @{ + */ + +#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for Direct3D11 and old UVD/UVD+ ATI video cards +#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO 2 ///< Work around for Direct3D11 and old Intel GPUs with ClearVideo interface + +/** + * This structure is used to provides the necessary configurations and data + * to the Direct3D11 FFmpeg HWAccel implementation. + * + * The application must make it available as AVCodecContext.hwaccel_context. + * + * Use av_d3d11va_alloc_context() exclusively to allocate an AVD3D11VAContext. + */ +typedef struct AVD3D11VAContext { + /** + * D3D11 decoder object + */ + ID3D11VideoDecoder *decoder; + + /** + * D3D11 VideoContext + */ + ID3D11VideoContext *video_context; + + /** + * D3D11 configuration used to create the decoder + */ + D3D11_VIDEO_DECODER_CONFIG *cfg; + + /** + * The number of surface in the surface array + */ + unsigned surface_count; + + /** + * The array of Direct3D surfaces used to create the decoder + */ + ID3D11VideoDecoderOutputView **surface; + + /** + * A bit field configuring the workarounds needed for using the decoder + */ + uint64_t workaround; + + /** + * Private to the FFmpeg AVHWAccel implementation + */ + unsigned report_id; + + /** + * Mutex to access video_context + */ + HANDLE context_mutex; +} AVD3D11VAContext; + +/** + * Allocate an AVD3D11VAContext. + * + * @return Newly-allocated AVD3D11VAContext or NULL on failure. + */ +AVD3D11VAContext *av_d3d11va_alloc_context(void); + +/** + * @} + */ + +#endif /* AVCODEC_D3D11VA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dct.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dct.h new file mode 100644 index 000000000..0a03e256d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dct.h @@ -0,0 +1,69 @@ +/* + * (I)DCT Transforms + * Copyright (c) 2009 Peter Ross + * Copyright (c) 2010 Alex Converse + * Copyright (c) 2010 Vitor Sessak + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(AVCODEC_DCT_H) && (!defined(FFT_FLOAT) || FFT_FLOAT) +#define AVCODEC_DCT_H + +#include +#include + +#include "rdft.h" + +struct DCTContext { + int nbits; + int inverse; + RDFTContext rdft; + const float *costab; + FFTSample *csc2; + void (*dct_calc)(struct DCTContext *s, FFTSample *data); + void (*dct32)(FFTSample *out, const FFTSample *in); +}; + +/** + * Set up DCT. + * @param nbits size of the input array: + * (1 << nbits) for DCT-II, DCT-III and DST-I + * (1 << nbits) + 1 for DCT-I + * + * @note the first element of the input of DST-I is ignored + */ +int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType type); +void ff_dct_end (DCTContext *s); + +void ff_dct_init_x86(DCTContext *s); + +void ff_fdct_ifast(int16_t *data); +void ff_fdct_ifast248(int16_t *data); +void ff_jpeg_fdct_islow_8(int16_t *data); +void ff_jpeg_fdct_islow_10(int16_t *data); +void ff_fdct248_islow_8(int16_t *data); +void ff_fdct248_islow_10(int16_t *data); + +void ff_j_rev_dct(int16_t *data); +void ff_j_rev_dct4(int16_t *data); +void ff_j_rev_dct2(int16_t *data); +void ff_j_rev_dct1(int16_t *data); +void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +#endif /* AVCODEC_DCT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/decode.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/decode.c new file mode 100644 index 000000000..6c31166ec --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/decode.c @@ -0,0 +1,2062 @@ +/* + * generic decoding-related code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "config.h" + +#if CONFIG_ICONV +# include +#endif + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/intmath.h" +#include "libavutil/opt.h" + +#include "avcodec.h" +#include "bytestream.h" +#include "decode.h" +#include "hwaccel.h" +#include "internal.h" +#include "thread.h" + +static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt) +{ + int size = 0, ret; + const uint8_t *data; + uint32_t flags; + int64_t val; + + data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); + if (!data) + return 0; + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { + av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " + "changes, but PARAM_CHANGE side data was sent to it.\n"); + ret = AVERROR(EINVAL); + goto fail2; + } + + if (size < 4) + goto fail; + + flags = bytestream_get_le32(&data); + size -= 4; + + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { + if (size < 4) + goto fail; + val = bytestream_get_le32(&data); + if (val <= 0 || val > INT_MAX) { + av_log(avctx, AV_LOG_ERROR, "Invalid channel count"); + ret = AVERROR_INVALIDDATA; + goto fail2; + } + avctx->channels = val; + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { + if (size < 8) + goto fail; + avctx->channel_layout = bytestream_get_le64(&data); + size -= 8; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { + if (size < 4) + goto fail; + val = bytestream_get_le32(&data); + if (val <= 0 || val > INT_MAX) { + av_log(avctx, AV_LOG_ERROR, "Invalid sample rate"); + ret = AVERROR_INVALIDDATA; + goto fail2; + } + avctx->sample_rate = val; + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { + if (size < 8) + goto fail; + avctx->width = bytestream_get_le32(&data); + avctx->height = bytestream_get_le32(&data); + size -= 8; + ret = ff_set_dimensions(avctx, avctx->width, avctx->height); + if (ret < 0) + goto fail2; + } + + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); + ret = AVERROR_INVALIDDATA; +fail2: + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return ret; + } + return 0; +} + +static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) +{ + int ret = 0; + + av_packet_unref(avci->last_pkt_props); + if (pkt) { + ret = av_packet_copy_props(avci->last_pkt_props, pkt); + if (!ret) + avci->last_pkt_props->size = pkt->size; // HACK: Needed for ff_decode_frame_props(). + } + return ret; +} + +static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) +{ + int ret; + + /* move the original frame to our backup */ + av_frame_unref(avci->to_free); + av_frame_move_ref(avci->to_free, frame); + + /* now copy everything except the AVBufferRefs back + * note that we make a COPY of the side data, so calling av_frame_free() on + * the caller's frame will work properly */ + ret = av_frame_copy_props(frame, avci->to_free); + if (ret < 0) + return ret; + + memcpy(frame->data, avci->to_free->data, sizeof(frame->data)); + memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize)); + if (avci->to_free->extended_data != avci->to_free->data) { + int planes = avci->to_free->channels; + int size = planes * sizeof(*frame->extended_data); + + if (!size) { + av_frame_unref(frame); + return AVERROR_BUG; + } + + frame->extended_data = av_malloc(size); + if (!frame->extended_data) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + memcpy(frame->extended_data, avci->to_free->extended_data, + size); + } else + frame->extended_data = frame->data; + + frame->format = avci->to_free->format; + frame->width = avci->to_free->width; + frame->height = avci->to_free->height; + frame->channel_layout = avci->to_free->channel_layout; + frame->nb_samples = avci->to_free->nb_samples; + frame->channels = avci->to_free->channels; + + return 0; +} + +int ff_decode_bsfs_init(AVCodecContext *avctx) +{ + AVCodecInternal *avci = avctx->internal; + DecodeFilterContext *s = &avci->filter; + const char *bsfs_str; + int ret; + + if (s->nb_bsfs) + return 0; + + bsfs_str = avctx->codec->bsfs ? avctx->codec->bsfs : "null"; + while (bsfs_str && *bsfs_str) { + AVBSFContext **tmp; + const AVBitStreamFilter *filter; + char *bsf, *bsf_options_str, *bsf_name; + + bsf = av_get_token(&bsfs_str, ","); + if (!bsf) { + ret = AVERROR(ENOMEM); + goto fail; + } + bsf_name = av_strtok(bsf, "=", &bsf_options_str); + if (!bsf_name) { + av_freep(&bsf); + ret = AVERROR(ENOMEM); + goto fail; + } + + filter = av_bsf_get_by_name(bsf_name); + if (!filter) { + av_log(avctx, AV_LOG_ERROR, "A non-existing bitstream filter %s " + "requested by a decoder. This is a bug, please report it.\n", + bsf_name); + av_freep(&bsf); + ret = AVERROR_BUG; + goto fail; + } + + tmp = av_realloc_array(s->bsfs, s->nb_bsfs + 1, sizeof(*s->bsfs)); + if (!tmp) { + av_freep(&bsf); + ret = AVERROR(ENOMEM); + goto fail; + } + s->bsfs = tmp; + s->nb_bsfs++; + + ret = av_bsf_alloc(filter, &s->bsfs[s->nb_bsfs - 1]); + if (ret < 0) { + av_freep(&bsf); + goto fail; + } + + if (s->nb_bsfs == 1) { + /* We do not currently have an API for passing the input timebase into decoders, + * but no filters used here should actually need it. + * So we make up some plausible-looking number (the MPEG 90kHz timebase) */ + s->bsfs[s->nb_bsfs - 1]->time_base_in = (AVRational){ 1, 90000 }; + ret = avcodec_parameters_from_context(s->bsfs[s->nb_bsfs - 1]->par_in, + avctx); + } else { + s->bsfs[s->nb_bsfs - 1]->time_base_in = s->bsfs[s->nb_bsfs - 2]->time_base_out; + ret = avcodec_parameters_copy(s->bsfs[s->nb_bsfs - 1]->par_in, + s->bsfs[s->nb_bsfs - 2]->par_out); + } + if (ret < 0) { + av_freep(&bsf); + goto fail; + } + + if (bsf_options_str && filter->priv_class) { + const AVOption *opt = av_opt_next(s->bsfs[s->nb_bsfs - 1]->priv_data, NULL); + const char * shorthand[2] = {NULL}; + + if (opt) + shorthand[0] = opt->name; + + ret = av_opt_set_from_string(s->bsfs[s->nb_bsfs - 1]->priv_data, bsf_options_str, shorthand, "=", ":"); + if (ret < 0) { + if (ret != AVERROR(ENOMEM)) { + av_log(avctx, AV_LOG_ERROR, "Invalid options for bitstream filter %s " + "requested by the decoder. This is a bug, please report it.\n", + bsf_name); + ret = AVERROR_BUG; + } + av_freep(&bsf); + goto fail; + } + } + av_freep(&bsf); + + ret = av_bsf_init(s->bsfs[s->nb_bsfs - 1]); + if (ret < 0) + goto fail; + + if (*bsfs_str) + bsfs_str++; + } + + return 0; +fail: + ff_decode_bsfs_uninit(avctx); + return ret; +} + +/* try to get one output packet from the filter chain */ +static int bsfs_poll(AVCodecContext *avctx, AVPacket *pkt) +{ + DecodeFilterContext *s = &avctx->internal->filter; + int idx, ret; + + /* start with the last filter in the chain */ + idx = s->nb_bsfs - 1; + while (idx >= 0) { + /* request a packet from the currently selected filter */ + ret = av_bsf_receive_packet(s->bsfs[idx], pkt); + if (ret == AVERROR(EAGAIN)) { + /* no packets available, try the next filter up the chain */ + ret = 0; + idx--; + continue; + } else if (ret < 0 && ret != AVERROR_EOF) { + return ret; + } + + /* got a packet or EOF -- pass it to the caller or to the next filter + * down the chain */ + if (idx == s->nb_bsfs - 1) { + return ret; + } else { + idx++; + ret = av_bsf_send_packet(s->bsfs[idx], ret < 0 ? NULL : pkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Error pre-processing a packet before decoding\n"); + av_packet_unref(pkt); + return ret; + } + } + } + + return AVERROR(EAGAIN); +} + +int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + if (avci->draining) + return AVERROR_EOF; + + ret = bsfs_poll(avctx, pkt); + if (ret == AVERROR_EOF) + avci->draining = 1; + if (ret < 0) + return ret; + + ret = extract_packet_props(avctx->internal, pkt); + if (ret < 0) + goto finish; + + ret = apply_param_change(avctx, pkt); + if (ret < 0) + goto finish; + + if (avctx->codec->receive_frame) + avci->compat_decode_consumed += pkt->size; + + return 0; +finish: + av_packet_unref(pkt); + return ret; +} + +/** + * Attempt to guess proper monotonic timestamps for decoded video frames + * which might have incorrect times. Input timestamps may wrap around, in + * which case the output will as well. + * + * @param pts the pts field of the decoded AVPacket, as passed through + * AVFrame.pts + * @param dts the dts field of the decoded AVPacket + * @return one of the input values, may be AV_NOPTS_VALUE + */ +static int64_t guess_correct_pts(AVCodecContext *ctx, + int64_t reordered_pts, int64_t dts) +{ + int64_t pts = AV_NOPTS_VALUE; + + if (dts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts; + ctx->pts_correction_last_dts = dts; + } else if (reordered_pts != AV_NOPTS_VALUE) + ctx->pts_correction_last_dts = reordered_pts; + + if (reordered_pts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts; + ctx->pts_correction_last_pts = reordered_pts; + } else if(dts != AV_NOPTS_VALUE) + ctx->pts_correction_last_pts = dts; + + if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) + && reordered_pts != AV_NOPTS_VALUE) + pts = reordered_pts; + else + pts = dts; + + return pts; +} + +/* + * The core of the receive_frame_wrapper for the decoders implementing + * the simple API. Certain decoders might consume partial packets without + * returning any output, so this function needs to be called in a loop until it + * returns EAGAIN. + **/ +static int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + DecodeSimpleContext *ds = &avci->ds; + AVPacket *pkt = ds->in_pkt; + // copy to ensure we do not change pkt + int got_frame, actual_got_frame; + int ret; + + if (!pkt->data && !avci->draining) { + av_packet_unref(pkt); + ret = ff_decode_get_packet(avctx, pkt); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + // Some codecs (at least wma lossless) will crash when feeding drain packets + // after EOF was signaled. + if (avci->draining_done) + return AVERROR_EOF; + + if (!pkt->data && + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || + avctx->active_thread_type & FF_THREAD_FRAME)) + return AVERROR_EOF; + + got_frame = 0; + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) { + ret = ff_thread_decode_frame(avctx, frame, &got_frame, pkt); + } else { + ret = avctx->codec->decode(avctx, frame, &got_frame, pkt); + + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) + frame->pkt_dts = pkt->dts; + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if(!avctx->has_b_frames) + frame->pkt_pos = pkt->pos; + //FIXME these should be under if(!avctx->has_b_frames) + /* get_buffer is supposed to set frame parameters */ + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { + if (!frame->sample_aspect_ratio.num) frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + if (!frame->width) frame->width = avctx->width; + if (!frame->height) frame->height = avctx->height; + if (frame->format == AV_PIX_FMT_NONE) frame->format = avctx->pix_fmt; + } + } + } + emms_c(); + actual_got_frame = got_frame; + + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if (frame->flags & AV_FRAME_FLAG_DISCARD) + got_frame = 0; + if (got_frame) + frame->best_effort_timestamp = guess_correct_pts(avctx, + frame->pts, + frame->pkt_dts); + } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + uint8_t *side; + int side_size; + uint32_t discard_padding = 0; + uint8_t skip_reason = 0; + uint8_t discard_reason = 0; + + if (ret >= 0 && got_frame) { + frame->best_effort_timestamp = guess_correct_pts(avctx, + frame->pts, + frame->pkt_dts); + if (frame->format == AV_SAMPLE_FMT_NONE) + frame->format = avctx->sample_fmt; + if (!frame->channel_layout) + frame->channel_layout = avctx->channel_layout; + if (!frame->channels) + frame->channels = avctx->channels; + if (!frame->sample_rate) + frame->sample_rate = avctx->sample_rate; + } + + side= av_packet_get_side_data(avci->last_pkt_props, AV_PKT_DATA_SKIP_SAMPLES, &side_size); + if(side && side_size>=10) { + avctx->internal->skip_samples = AV_RL32(side) * avctx->internal->skip_samples_multiplier; + discard_padding = AV_RL32(side + 4); + av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n", + avctx->internal->skip_samples, (int)discard_padding); + skip_reason = AV_RL8(side + 8); + discard_reason = AV_RL8(side + 9); + } + + if ((frame->flags & AV_FRAME_FLAG_DISCARD) && got_frame && + !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { + avctx->internal->skip_samples = FFMAX(0, avctx->internal->skip_samples - frame->nb_samples); + got_frame = 0; + } + + if (avctx->internal->skip_samples > 0 && got_frame && + !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { + if(frame->nb_samples <= avctx->internal->skip_samples){ + got_frame = 0; + avctx->internal->skip_samples -= frame->nb_samples; + av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n", + avctx->internal->skip_samples); + } else { + av_samples_copy(frame->extended_data, frame->extended_data, 0, avctx->internal->skip_samples, + frame->nb_samples - avctx->internal->skip_samples, avctx->channels, frame->format); + if(avctx->pkt_timebase.num && avctx->sample_rate) { + int64_t diff_ts = av_rescale_q(avctx->internal->skip_samples, + (AVRational){1, avctx->sample_rate}, + avctx->pkt_timebase); + if(frame->pts!=AV_NOPTS_VALUE) + frame->pts += diff_ts; +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + if(frame->pkt_pts!=AV_NOPTS_VALUE) + frame->pkt_pts += diff_ts; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if(frame->pkt_dts!=AV_NOPTS_VALUE) + frame->pkt_dts += diff_ts; + if (frame->pkt_duration >= diff_ts) + frame->pkt_duration -= diff_ts; + } else { + av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n"); + } + av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n", + avctx->internal->skip_samples, frame->nb_samples); + frame->nb_samples -= avctx->internal->skip_samples; + avctx->internal->skip_samples = 0; + } + } + + if (discard_padding > 0 && discard_padding <= frame->nb_samples && got_frame && + !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { + if (discard_padding == frame->nb_samples) { + got_frame = 0; + } else { + if(avctx->pkt_timebase.num && avctx->sample_rate) { + int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding, + (AVRational){1, avctx->sample_rate}, + avctx->pkt_timebase); + frame->pkt_duration = diff_ts; + } else { + av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n"); + } + av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n", + (int)discard_padding, frame->nb_samples); + frame->nb_samples -= discard_padding; + } + } + + if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL) && got_frame) { + AVFrameSideData *fside = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10); + if (fside) { + AV_WL32(fside->data, avctx->internal->skip_samples); + AV_WL32(fside->data + 4, discard_padding); + AV_WL8(fside->data + 8, skip_reason); + AV_WL8(fside->data + 9, discard_reason); + avctx->internal->skip_samples = 0; + } + } + } + + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO && + !avci->showed_multi_packet_warning && + ret >= 0 && ret != pkt->size && !(avctx->codec->capabilities & AV_CODEC_CAP_SUBFRAMES)) { + av_log(avctx, AV_LOG_WARNING, "Multiple frames in a packet.\n"); + avci->showed_multi_packet_warning = 1; + } + + if (!got_frame) + av_frame_unref(frame); + + if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO && !(avctx->flags & AV_CODEC_FLAG_TRUNCATED)) + ret = pkt->size; + +#if FF_API_AVCTX_TIMEBASE + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); +#endif + + /* do not stop draining when actual_got_frame != 0 or ret < 0 */ + /* got_frame == 0 but actual_got_frame != 0 when frame is discarded */ + if (avctx->internal->draining && !actual_got_frame) { + if (ret < 0) { + /* prevent infinite loop if a decoder wrongly always return error on draining */ + /* reasonable nb_errors_max = maximum b frames + thread count */ + int nb_errors_max = 20 + (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME ? + avctx->thread_count : 1); + + if (avci->nb_draining_errors++ >= nb_errors_max) { + av_log(avctx, AV_LOG_ERROR, "Too many errors when draining, this is a bug. " + "Stop draining and force EOF.\n"); + avci->draining_done = 1; + ret = AVERROR_BUG; + } + } else { + avci->draining_done = 1; + } + } + + avci->compat_decode_consumed += ret; + + if (ret >= pkt->size || ret < 0) { + av_packet_unref(pkt); + } else { + int consumed = ret; + + pkt->data += consumed; + pkt->size -= consumed; + avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment. + pkt->pts = AV_NOPTS_VALUE; + pkt->dts = AV_NOPTS_VALUE; + avci->last_pkt_props->pts = AV_NOPTS_VALUE; + avci->last_pkt_props->dts = AV_NOPTS_VALUE; + } + + if (got_frame) + av_assert0(frame->buf[0]); + + return ret < 0 ? ret : 0; +} + +static int decode_simple_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + int ret; + + while (!frame->buf[0]) { + ret = decode_simple_internal(avctx, frame); + if (ret < 0) + return ret; + } + + return 0; +} + +static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + av_assert0(!frame->buf[0]); + + if (avctx->codec->receive_frame) + ret = avctx->codec->receive_frame(avctx, frame); + else + ret = decode_simple_receive_frame(avctx, frame); + + if (ret == AVERROR_EOF) + avci->draining_done = 1; + + if (!ret) { + /* the only case where decode data is not set should be decoders + * that do not call ff_get_buffer() */ + av_assert0((frame->private_ref && frame->private_ref->size == sizeof(FrameDecodeData)) || + !(avctx->codec->capabilities & AV_CODEC_CAP_DR1)); + + if (frame->private_ref) { + FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data; + + if (fdd->post_process) { + ret = fdd->post_process(avctx, frame); + if (ret < 0) { + av_frame_unref(frame); + return ret; + } + } + } + } + + /* free the per-frame decode data */ + av_buffer_unref(&frame->private_ref); + + return ret; +} + +int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avctx->internal->draining) + return AVERROR_EOF; + + if (avpkt && !avpkt->size && avpkt->data) + return AVERROR(EINVAL); + + av_packet_unref(avci->buffer_pkt); + if (avpkt && (avpkt->data || avpkt->side_data_elems)) { + ret = av_packet_ref(avci->buffer_pkt, avpkt); + if (ret < 0) + return ret; + } + + ret = av_bsf_send_packet(avci->filter.bsfs[0], avci->buffer_pkt); + if (ret < 0) { + av_packet_unref(avci->buffer_pkt); + return ret; + } + + if (!avci->buffer_frame->buf[0]) { + ret = decode_receive_frame_internal(avctx, avci->buffer_frame); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + } + + return 0; +} + +static int apply_cropping(AVCodecContext *avctx, AVFrame *frame) +{ + /* make sure we are noisy about decoders returning invalid cropping data */ + if (frame->crop_left >= INT_MAX - frame->crop_right || + frame->crop_top >= INT_MAX - frame->crop_bottom || + (frame->crop_left + frame->crop_right) >= frame->width || + (frame->crop_top + frame->crop_bottom) >= frame->height) { + av_log(avctx, AV_LOG_WARNING, + "Invalid cropping information set by a decoder: " + "%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER"/%"SIZE_SPECIFIER" " + "(frame size %dx%d). This is a bug, please report it\n", + frame->crop_left, frame->crop_right, frame->crop_top, frame->crop_bottom, + frame->width, frame->height); + frame->crop_left = 0; + frame->crop_right = 0; + frame->crop_top = 0; + frame->crop_bottom = 0; + return 0; + } + + if (!avctx->apply_cropping) + return 0; + + return av_frame_apply_cropping(frame, avctx->flags & AV_CODEC_FLAG_UNALIGNED ? + AV_FRAME_CROP_UNALIGNED : 0); +} + +int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + int ret, changed; + + av_frame_unref(frame); + + if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avci->buffer_frame->buf[0]) { + av_frame_move_ref(frame, avci->buffer_frame); + } else { + ret = decode_receive_frame_internal(avctx, frame); + if (ret < 0) + return ret; + } + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + ret = apply_cropping(avctx, frame); + if (ret < 0) { + av_frame_unref(frame); + return ret; + } + } + + avctx->frame_number++; + + if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED) { + + if (avctx->frame_number == 1) { + avci->initial_format = frame->format; + switch(avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + avci->initial_width = frame->width; + avci->initial_height = frame->height; + break; + case AVMEDIA_TYPE_AUDIO: + avci->initial_sample_rate = frame->sample_rate ? frame->sample_rate : + avctx->sample_rate; + avci->initial_channels = frame->channels; + avci->initial_channel_layout = frame->channel_layout; + break; + } + } + + if (avctx->frame_number > 1) { + changed = avci->initial_format != frame->format; + + switch(avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + changed |= avci->initial_width != frame->width || + avci->initial_height != frame->height; + break; + case AVMEDIA_TYPE_AUDIO: + changed |= avci->initial_sample_rate != frame->sample_rate || + avci->initial_sample_rate != avctx->sample_rate || + avci->initial_channels != frame->channels || + avci->initial_channel_layout != frame->channel_layout; + break; + } + + if (changed) { + avci->changed_frames_dropped++; + av_log(avctx, AV_LOG_INFO, "dropped changed frame #%d pts %"PRId64 + " drop count: %d \n", + avctx->frame_number, frame->pts, + avci->changed_frames_dropped); + av_frame_unref(frame); + return AVERROR_INPUT_CHANGED; + } + } + } + return 0; +} + +static int compat_decode(AVCodecContext *avctx, AVFrame *frame, + int *got_frame, const AVPacket *pkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret = 0; + + av_assert0(avci->compat_decode_consumed == 0); + + if (avci->draining_done && pkt && pkt->size != 0) { + av_log(avctx, AV_LOG_WARNING, "Got unexpected packet after EOF\n"); + avcodec_flush_buffers(avctx); + } + + *got_frame = 0; + avci->compat_decode = 1; + + if (avci->compat_decode_partial_size > 0 && + avci->compat_decode_partial_size != pkt->size) { + av_log(avctx, AV_LOG_ERROR, + "Got unexpected packet size after a partial decode\n"); + ret = AVERROR(EINVAL); + goto finish; + } + + if (!avci->compat_decode_partial_size) { + ret = avcodec_send_packet(avctx, pkt); + if (ret == AVERROR_EOF) + ret = 0; + else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each decode call, so this should not + * ever happen */ + ret = AVERROR_BUG; + goto finish; + } else if (ret < 0) + goto finish; + } + + while (ret >= 0) { + ret = avcodec_receive_frame(avctx, frame); + if (ret < 0) { + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + ret = 0; + goto finish; + } + + if (frame != avci->compat_decode_frame) { + if (!avctx->refcounted_frames) { + ret = unrefcount_frame(avci, frame); + if (ret < 0) + goto finish; + } + + *got_frame = 1; + frame = avci->compat_decode_frame; + } else { + if (!avci->compat_decode_warned) { + av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_decode_* " + "API cannot return all the frames for this decoder. " + "Some frames will be dropped. Update your code to the " + "new decoding API to fix this.\n"); + avci->compat_decode_warned = 1; + } + } + + if (avci->draining || (!avctx->codec->bsfs && avci->compat_decode_consumed < pkt->size)) + break; + } + +finish: + if (ret == 0) { + /* if there are any bsfs then assume full packet is always consumed */ + if (avctx->codec->bsfs) + ret = pkt->size; + else + ret = FFMIN(avci->compat_decode_consumed, pkt->size); + } + avci->compat_decode_consumed = 0; + avci->compat_decode_partial_size = (ret >= 0) ? pkt->size - ret : 0; + + return ret; +} + +int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const AVPacket *avpkt) +{ + return compat_decode(avctx, picture, got_picture_ptr, avpkt); +} + +int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, + AVFrame *frame, + int *got_frame_ptr, + const AVPacket *avpkt) +{ + return compat_decode(avctx, frame, got_frame_ptr, avpkt); +} + +static void get_subtitle_defaults(AVSubtitle *sub) +{ + memset(sub, 0, sizeof(*sub)); + sub->pts = AV_NOPTS_VALUE; +} + +#define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */ +static int recode_subtitle(AVCodecContext *avctx, + AVPacket *outpkt, const AVPacket *inpkt) +{ +#if CONFIG_ICONV + iconv_t cd = (iconv_t)-1; + int ret = 0; + char *inb, *outb; + size_t inl, outl; + AVPacket tmp; +#endif + + if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0) + return 0; + +#if CONFIG_ICONV + cd = iconv_open("UTF-8", avctx->sub_charenc); + av_assert0(cd != (iconv_t)-1); + + inb = inpkt->data; + inl = inpkt->size; + + if (inl >= INT_MAX / UTF8_MAX_BYTES - AV_INPUT_BUFFER_PADDING_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Subtitles packet is too big for recoding\n"); + ret = AVERROR(ENOMEM); + goto end; + } + + ret = av_new_packet(&tmp, inl * UTF8_MAX_BYTES); + if (ret < 0) + goto end; + outpkt->buf = tmp.buf; + outpkt->data = tmp.data; + outpkt->size = tmp.size; + outb = outpkt->data; + outl = outpkt->size; + + if (iconv(cd, &inb, &inl, &outb, &outl) == (size_t)-1 || + iconv(cd, NULL, NULL, &outb, &outl) == (size_t)-1 || + outl >= outpkt->size || inl != 0) { + ret = FFMIN(AVERROR(errno), -1); + av_log(avctx, AV_LOG_ERROR, "Unable to recode subtitle event \"%s\" " + "from %s to UTF-8\n", inpkt->data, avctx->sub_charenc); + av_packet_unref(&tmp); + goto end; + } + outpkt->size -= outl; + memset(outpkt->data + outpkt->size, 0, outl); + +end: + if (cd != (iconv_t)-1) + iconv_close(cd); + return ret; +#else + av_log(avctx, AV_LOG_ERROR, "requesting subtitles recoding without iconv"); + return AVERROR(EINVAL); +#endif +} + +static int utf8_check(const uint8_t *str) +{ + const uint8_t *byte; + uint32_t codepoint, min; + + while (*str) { + byte = str; + GET_UTF8(codepoint, *(byte++), return 0;); + min = byte - str == 1 ? 0 : byte - str == 2 ? 0x80 : + 1 << (5 * (byte - str) - 4); + if (codepoint < min || codepoint >= 0x110000 || + codepoint == 0xFFFE /* BOM */ || + codepoint >= 0xD800 && codepoint <= 0xDFFF /* surrogates */) + return 0; + str = byte; + } + return 1; +} + +#if FF_API_ASS_TIMING +static void insert_ts(AVBPrint *buf, int ts) +{ + if (ts == -1) { + av_bprintf(buf, "9:59:59.99,"); + } else { + int h, m, s; + + h = ts/360000; ts -= 360000*h; + m = ts/ 6000; ts -= 6000*m; + s = ts/ 100; ts -= 100*s; + av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts); + } +} + +static int convert_sub_to_old_ass_form(AVSubtitle *sub, const AVPacket *pkt, AVRational tb) +{ + int i; + AVBPrint buf; + + av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); + + for (i = 0; i < sub->num_rects; i++) { + char *final_dialog; + const char *dialog; + AVSubtitleRect *rect = sub->rects[i]; + int ts_start, ts_duration = -1; + long int layer; + + if (rect->type != SUBTITLE_ASS || !strncmp(rect->ass, "Dialogue: ", 10)) + continue; + + av_bprint_clear(&buf); + + /* skip ReadOrder */ + dialog = strchr(rect->ass, ','); + if (!dialog) + continue; + dialog++; + + /* extract Layer or Marked */ + layer = strtol(dialog, (char**)&dialog, 10); + if (*dialog != ',') + continue; + dialog++; + + /* rescale timing to ASS time base (ms) */ + ts_start = av_rescale_q(pkt->pts, tb, av_make_q(1, 100)); + if (pkt->duration != -1) + ts_duration = av_rescale_q(pkt->duration, tb, av_make_q(1, 100)); + sub->end_display_time = FFMAX(sub->end_display_time, 10 * ts_duration); + + /* construct ASS (standalone file form with timestamps) string */ + av_bprintf(&buf, "Dialogue: %ld,", layer); + insert_ts(&buf, ts_start); + insert_ts(&buf, ts_duration == -1 ? -1 : ts_start + ts_duration); + av_bprintf(&buf, "%s\r\n", dialog); + + final_dialog = av_strdup(buf.str); + if (!av_bprint_is_complete(&buf) || !final_dialog) { + av_freep(&final_dialog); + av_bprint_finalize(&buf, NULL); + return AVERROR(ENOMEM); + } + av_freep(&rect->ass); + rect->ass = final_dialog; + } + + av_bprint_finalize(&buf, NULL); + return 0; +} +#endif + +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt) +{ + int i, ret = 0; + + if (!avpkt->data && avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); + return AVERROR(EINVAL); + } + if (!avctx->codec) + return AVERROR(EINVAL); + if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) { + av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n"); + return AVERROR(EINVAL); + } + + *got_sub_ptr = 0; + get_subtitle_defaults(sub); + + if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) { + AVPacket pkt_recoded = *avpkt; + + ret = recode_subtitle(avctx, &pkt_recoded, avpkt); + if (ret < 0) { + *got_sub_ptr = 0; + } else { + ret = extract_packet_props(avctx->internal, &pkt_recoded); + if (ret < 0) + return ret; + + if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE) + sub->pts = av_rescale_q(avpkt->pts, + avctx->pkt_timebase, AV_TIME_BASE_Q); + ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded); + av_assert1((ret >= 0) >= !!*got_sub_ptr && + !!*got_sub_ptr >= !!sub->num_rects); + +#if FF_API_ASS_TIMING + if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS + && *got_sub_ptr && sub->num_rects) { + const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase + : avctx->time_base; + int err = convert_sub_to_old_ass_form(sub, avpkt, tb); + if (err < 0) + ret = err; + } +#endif + + if (sub->num_rects && !sub->end_display_time && avpkt->duration && + avctx->pkt_timebase.num) { + AVRational ms = { 1, 1000 }; + sub->end_display_time = av_rescale_q(avpkt->duration, + avctx->pkt_timebase, ms); + } + + if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) + sub->format = 0; + else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) + sub->format = 1; + + for (i = 0; i < sub->num_rects; i++) { + if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_IGNORE && + sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { + av_log(avctx, AV_LOG_ERROR, + "Invalid UTF-8 in decoded subtitles text; " + "maybe missing -sub_charenc option\n"); + avsubtitle_free(sub); + ret = AVERROR_INVALIDDATA; + break; + } + } + + if (avpkt->data != pkt_recoded.data) { // did we recode? + /* prevent from destroying side data from original packet */ + pkt_recoded.side_data = NULL; + pkt_recoded.side_data_elems = 0; + + av_packet_unref(&pkt_recoded); + } + } + + if (*got_sub_ptr) + avctx->frame_number++; + } + + return ret; +} + +enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *avctx, + const enum AVPixelFormat *fmt) +{ + const AVPixFmtDescriptor *desc; + const AVCodecHWConfig *config; + int i, n; + + // If a device was supplied when the codec was opened, assume that the + // user wants to use it. + if (avctx->hw_device_ctx && avctx->codec->hw_configs) { + AVHWDeviceContext *device_ctx = + (AVHWDeviceContext*)avctx->hw_device_ctx->data; + for (i = 0;; i++) { + config = &avctx->codec->hw_configs[i]->public; + if (!config) + break; + if (!(config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) + continue; + if (device_ctx->type != config->device_type) + continue; + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) { + if (config->pix_fmt == fmt[n]) + return fmt[n]; + } + } + } + // No device or other setup, so we have to choose from things which + // don't any other external information. + + // If the last element of the list is a software format, choose it + // (this should be best software format if any exist). + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++); + desc = av_pix_fmt_desc_get(fmt[n - 1]); + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + return fmt[n - 1]; + + // Finally, traverse the list in order and choose the first entry + // with no external dependencies (if there is no hardware configuration + // information available then this just picks the first entry). + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) { + for (i = 0;; i++) { + config = avcodec_get_hw_config(avctx->codec, i); + if (!config) + break; + if (config->pix_fmt == fmt[n]) + break; + } + if (!config) { + // No specific config available, so the decoder must be able + // to handle this format without any additional setup. + return fmt[n]; + } + if (config->methods & AV_CODEC_HW_CONFIG_METHOD_INTERNAL) { + // Usable with only internal setup. + return fmt[n]; + } + } + + // Nothing is usable, give up. + return AV_PIX_FMT_NONE; +} + +int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, + enum AVHWDeviceType dev_type) +{ + AVHWDeviceContext *device_ctx; + AVHWFramesContext *frames_ctx; + int ret; + + if (!avctx->hwaccel) + return AVERROR(ENOSYS); + + if (avctx->hw_frames_ctx) + return 0; + if (!avctx->hw_device_ctx) { + av_log(avctx, AV_LOG_ERROR, "A hardware frames or device context is " + "required for hardware accelerated decoding.\n"); + return AVERROR(EINVAL); + } + + device_ctx = (AVHWDeviceContext *)avctx->hw_device_ctx->data; + if (device_ctx->type != dev_type) { + av_log(avctx, AV_LOG_ERROR, "Device type %s expected for hardware " + "decoding, but got %s.\n", av_hwdevice_get_type_name(dev_type), + av_hwdevice_get_type_name(device_ctx->type)); + return AVERROR(EINVAL); + } + + ret = avcodec_get_hw_frames_parameters(avctx, + avctx->hw_device_ctx, + avctx->hwaccel->pix_fmt, + &avctx->hw_frames_ctx); + if (ret < 0) + return ret; + + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + + + if (frames_ctx->initial_pool_size) { + // We guarantee 4 base work surfaces. The function above guarantees 1 + // (the absolute minimum), so add the missing count. + frames_ctx->initial_pool_size += 3; + } + + ret = av_hwframe_ctx_init(avctx->hw_frames_ctx); + if (ret < 0) { + av_buffer_unref(&avctx->hw_frames_ctx); + return ret; + } + + return 0; +} + +int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, + AVBufferRef *device_ref, + enum AVPixelFormat hw_pix_fmt, + AVBufferRef **out_frames_ref) +{ + AVBufferRef *frames_ref = NULL; + const AVCodecHWConfigInternal *hw_config; + const AVHWAccel *hwa; + int i, ret; + + for (i = 0;; i++) { + hw_config = avctx->codec->hw_configs[i]; + if (!hw_config) + return AVERROR(ENOENT); + if (hw_config->public.pix_fmt == hw_pix_fmt) + break; + } + + hwa = hw_config->hwaccel; + if (!hwa || !hwa->frame_params) + return AVERROR(ENOENT); + + frames_ref = av_hwframe_ctx_alloc(device_ref); + if (!frames_ref) + return AVERROR(ENOMEM); + + ret = hwa->frame_params(avctx, frames_ref); + if (ret >= 0) { + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frames_ref->data; + + if (frames_ctx->initial_pool_size) { + // If the user has requested that extra output surfaces be + // available then add them here. + if (avctx->extra_hw_frames > 0) + frames_ctx->initial_pool_size += avctx->extra_hw_frames; + + // If frame threading is enabled then an extra surface per thread + // is also required. + if (avctx->active_thread_type & FF_THREAD_FRAME) + frames_ctx->initial_pool_size += avctx->thread_count; + } + + *out_frames_ref = frames_ref; + } else { + av_buffer_unref(&frames_ref); + } + return ret; +} + +static int hwaccel_init(AVCodecContext *avctx, + const AVCodecHWConfigInternal *hw_config) +{ + const AVHWAccel *hwaccel; + int err; + + hwaccel = hw_config->hwaccel; + if (hwaccel->capabilities & AV_HWACCEL_CODEC_CAP_EXPERIMENTAL && + avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + av_log(avctx, AV_LOG_WARNING, "Ignoring experimental hwaccel: %s\n", + hwaccel->name); + return AVERROR_PATCHWELCOME; + } + + if (hwaccel->priv_data_size) { + avctx->internal->hwaccel_priv_data = + av_mallocz(hwaccel->priv_data_size); + if (!avctx->internal->hwaccel_priv_data) + return AVERROR(ENOMEM); + } + + avctx->hwaccel = hwaccel; + if (hwaccel->init) { + err = hwaccel->init(avctx); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed setup for format %s: " + "hwaccel initialisation returned error.\n", + av_get_pix_fmt_name(hw_config->public.pix_fmt)); + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; + return err; + } + } + + return 0; +} + +static void hwaccel_uninit(AVCodecContext *avctx) +{ + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + + av_freep(&avctx->internal->hwaccel_priv_data); + + avctx->hwaccel = NULL; + + av_buffer_unref(&avctx->hw_frames_ctx); +} + +int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) +{ + const AVPixFmtDescriptor *desc; + enum AVPixelFormat *choices; + enum AVPixelFormat ret, user_choice; + const AVCodecHWConfigInternal *hw_config; + const AVCodecHWConfig *config; + int i, n, err; + + // Find end of list. + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++); + // Must contain at least one entry. + av_assert0(n >= 1); + // If a software format is available, it must be the last entry. + desc = av_pix_fmt_desc_get(fmt[n - 1]); + if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { + // No software format is available. + } else { + avctx->sw_pix_fmt = fmt[n - 1]; + } + + choices = av_malloc_array(n + 1, sizeof(*choices)); + if (!choices) + return AV_PIX_FMT_NONE; + + memcpy(choices, fmt, (n + 1) * sizeof(*choices)); + + for (;;) { + // Remove the previous hwaccel, if there was one. + hwaccel_uninit(avctx); + + user_choice = avctx->get_format(avctx, choices); + if (user_choice == AV_PIX_FMT_NONE) { + // Explicitly chose nothing, give up. + ret = AV_PIX_FMT_NONE; + break; + } + + desc = av_pix_fmt_desc_get(user_choice); + if (!desc) { + av_log(avctx, AV_LOG_ERROR, "Invalid format returned by " + "get_format() callback.\n"); + ret = AV_PIX_FMT_NONE; + break; + } + av_log(avctx, AV_LOG_DEBUG, "Format %s chosen by get_format().\n", + desc->name); + + for (i = 0; i < n; i++) { + if (choices[i] == user_choice) + break; + } + if (i == n) { + av_log(avctx, AV_LOG_ERROR, "Invalid return from get_format(): " + "%s not in possible list.\n", desc->name); + ret = AV_PIX_FMT_NONE; + break; + } + + if (avctx->codec->hw_configs) { + for (i = 0;; i++) { + hw_config = avctx->codec->hw_configs[i]; + if (!hw_config) + break; + if (hw_config->public.pix_fmt == user_choice) + break; + } + } else { + hw_config = NULL; + } + + if (!hw_config) { + // No config available, so no extra setup required. + ret = user_choice; + break; + } + config = &hw_config->public; + + if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX && + avctx->hw_frames_ctx) { + const AVHWFramesContext *frames_ctx = + (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (frames_ctx->format != user_choice) { + av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: " + "does not match the format of the provided frames " + "context.\n", desc->name); + goto try_again; + } + } else if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && + avctx->hw_device_ctx) { + const AVHWDeviceContext *device_ctx = + (AVHWDeviceContext*)avctx->hw_device_ctx->data; + if (device_ctx->type != config->device_type) { + av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: " + "does not match the type of the provided device " + "context.\n", desc->name); + goto try_again; + } + } else if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_INTERNAL) { + // Internal-only setup, no additional configuration. + } else if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_AD_HOC) { + // Some ad-hoc configuration we can't see and can't check. + } else { + av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: " + "missing configuration.\n", desc->name); + goto try_again; + } + if (hw_config->hwaccel) { + av_log(avctx, AV_LOG_DEBUG, "Format %s requires hwaccel " + "initialisation.\n", desc->name); + err = hwaccel_init(avctx, hw_config); + if (err < 0) + goto try_again; + } + ret = user_choice; + break; + + try_again: + av_log(avctx, AV_LOG_DEBUG, "Format %s not usable, retrying " + "get_format() without it.\n", desc->name); + for (i = 0; i < n; i++) { + if (choices[i] == user_choice) + break; + } + for (; i + 1 < n; i++) + choices[i] = choices[i + 1]; + --n; + } + + av_freep(&choices); + return ret; +} + +static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) +{ + FramePool *pool = avctx->internal->pool; + int i, ret; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: { + uint8_t *data[4]; + int linesize[4]; + int size[4] = { 0 }; + int w = frame->width; + int h = frame->height; + int tmpsize, unaligned; + + if (pool->format == frame->format && + pool->width == frame->width && pool->height == frame->height) + return 0; + + avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); + + do { + // NOTE: do not align linesizes individually, this breaks e.g. assumptions + // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 + ret = av_image_fill_linesizes(linesize, avctx->pix_fmt, w); + if (ret < 0) + return ret; + // increase alignment of w for next try (rhs gives the lowest bit set in w) + w += w & ~(w - 1); + + unaligned = 0; + for (i = 0; i < 4; i++) + unaligned |= linesize[i] % pool->stride_align[i]; + } while (unaligned); + + tmpsize = av_image_fill_pointers(data, avctx->pix_fmt, h, + NULL, linesize); + if (tmpsize < 0) + return tmpsize; + + for (i = 0; i < 3 && data[i + 1]; i++) + size[i] = data[i + 1] - data[i]; + size[i] = tmpsize - (data[i] - data[0]); + + for (i = 0; i < 4; i++) { + av_buffer_pool_uninit(&pool->pools[i]); + pool->linesize[i] = linesize[i]; + if (size[i]) { + pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, + CONFIG_MEMORY_POISONING ? + NULL : + av_buffer_allocz); + if (!pool->pools[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + } + pool->format = frame->format; + pool->width = frame->width; + pool->height = frame->height; + + break; + } + case AVMEDIA_TYPE_AUDIO: { + int ch = frame->channels; //av_get_channel_layout_nb_channels(frame->channel_layout); + int planar = av_sample_fmt_is_planar(frame->format); + int planes = planar ? ch : 1; + + if (pool->format == frame->format && pool->planes == planes && + pool->channels == ch && frame->nb_samples == pool->samples) + return 0; + + av_buffer_pool_uninit(&pool->pools[0]); + ret = av_samples_get_buffer_size(&pool->linesize[0], ch, + frame->nb_samples, frame->format, 0); + if (ret < 0) + goto fail; + + pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); + if (!pool->pools[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + pool->format = frame->format; + pool->planes = planes; + pool->channels = ch; + pool->samples = frame->nb_samples; + break; + } + default: av_assert0(0); + } + return 0; +fail: + for (i = 0; i < 4; i++) + av_buffer_pool_uninit(&pool->pools[i]); + pool->format = -1; + pool->planes = pool->channels = pool->samples = 0; + pool->width = pool->height = 0; + return ret; +} + +static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) +{ + FramePool *pool = avctx->internal->pool; + int planes = pool->planes; + int i; + + frame->linesize[0] = pool->linesize[0]; + + if (planes > AV_NUM_DATA_POINTERS) { + frame->extended_data = av_mallocz_array(planes, sizeof(*frame->extended_data)); + frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; + frame->extended_buf = av_mallocz_array(frame->nb_extended_buf, + sizeof(*frame->extended_buf)); + if (!frame->extended_data || !frame->extended_buf) { + av_freep(&frame->extended_data); + av_freep(&frame->extended_buf); + return AVERROR(ENOMEM); + } + } else { + frame->extended_data = frame->data; + av_assert0(frame->nb_extended_buf == 0); + } + + for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { + frame->buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->buf[i]) + goto fail; + frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; + } + for (i = 0; i < frame->nb_extended_buf; i++) { + frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); + if (!frame->extended_buf[i]) + goto fail; + frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; + } + + if (avctx->debug & FF_DEBUG_BUFFERS) + av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); + + return 0; +fail: + av_frame_unref(frame); + return AVERROR(ENOMEM); +} + +static int video_get_buffer(AVCodecContext *s, AVFrame *pic) +{ + FramePool *pool = s->internal->pool; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format); + int i; + + if (pic->data[0] || pic->data[1] || pic->data[2] || pic->data[3]) { + av_log(s, AV_LOG_ERROR, "pic->data[*]!=NULL in avcodec_default_get_buffer\n"); + return -1; + } + + if (!desc) { + av_log(s, AV_LOG_ERROR, + "Unable to get pixel format descriptor for format %s\n", + av_get_pix_fmt_name(pic->format)); + return AVERROR(EINVAL); + } + + memset(pic->data, 0, sizeof(pic->data)); + pic->extended_data = pic->data; + + for (i = 0; i < 4 && pool->pools[i]; i++) { + pic->linesize[i] = pool->linesize[i]; + + pic->buf[i] = av_buffer_pool_get(pool->pools[i]); + if (!pic->buf[i]) + goto fail; + + pic->data[i] = pic->buf[i]->data; + } + for (; i < AV_NUM_DATA_POINTERS; i++) { + pic->data[i] = NULL; + pic->linesize[i] = 0; + } + if (desc->flags & AV_PIX_FMT_FLAG_PAL || + ((desc->flags & FF_PSEUDOPAL) && pic->data[1])) + avpriv_set_systematic_pal2((uint32_t *)pic->data[1], pic->format); + + if (s->debug & FF_DEBUG_BUFFERS) + av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); + + return 0; +fail: + av_frame_unref(pic); + return AVERROR(ENOMEM); +} + +int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + int ret; + + if (avctx->hw_frames_ctx) { + ret = av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); + frame->width = avctx->coded_width; + frame->height = avctx->coded_height; + return ret; + } + + if ((ret = update_frame_pool(avctx, frame)) < 0) + return ret; + + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + return video_get_buffer(avctx, frame); + case AVMEDIA_TYPE_AUDIO: + return audio_get_buffer(avctx, frame); + default: + return -1; + } +} + +static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame) +{ + int size; + const uint8_t *side_metadata; + + AVDictionary **frame_md = &frame->metadata; + + side_metadata = av_packet_get_side_data(avpkt, + AV_PKT_DATA_STRINGS_METADATA, &size); + return av_packet_unpack_dictionary(side_metadata, size, frame_md); +} + +int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) +{ + const AVPacket *pkt = avctx->internal->last_pkt_props; + int i; + static const struct { + enum AVPacketSideDataType packet; + enum AVFrameSideDataType frame; + } sd[] = { + { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN }, + { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX }, + { AV_PKT_DATA_SPHERICAL, AV_FRAME_DATA_SPHERICAL }, + { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D }, + { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE }, + { AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA }, + { AV_PKT_DATA_CONTENT_LIGHT_LEVEL, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL }, + { AV_PKT_DATA_A53_CC, AV_FRAME_DATA_A53_CC }, + }; + + if (pkt) { + frame->pts = pkt->pts; +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + frame->pkt_pts = pkt->pts; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + frame->pkt_pos = pkt->pos; + frame->pkt_duration = pkt->duration; + frame->pkt_size = pkt->size; + + for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) { + int size; + uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); + if (packet_sd) { + AVFrameSideData *frame_sd = av_frame_new_side_data(frame, + sd[i].frame, + size); + if (!frame_sd) + return AVERROR(ENOMEM); + + memcpy(frame_sd->data, packet_sd, size); + } + } + add_metadata_from_side_data(pkt, frame); + + if (pkt->flags & AV_PKT_FLAG_DISCARD) { + frame->flags |= AV_FRAME_FLAG_DISCARD; + } else { + frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); + } + } + frame->reordered_opaque = avctx->reordered_opaque; + + if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED) + frame->color_primaries = avctx->color_primaries; + if (frame->color_trc == AVCOL_TRC_UNSPECIFIED) + frame->color_trc = avctx->color_trc; + if (frame->colorspace == AVCOL_SPC_UNSPECIFIED) + frame->colorspace = avctx->colorspace; + if (frame->color_range == AVCOL_RANGE_UNSPECIFIED) + frame->color_range = avctx->color_range; + if (frame->chroma_location == AVCHROMA_LOC_UNSPECIFIED) + frame->chroma_location = avctx->chroma_sample_location; + + switch (avctx->codec->type) { + case AVMEDIA_TYPE_VIDEO: + frame->format = avctx->pix_fmt; + if (!frame->sample_aspect_ratio.num) + frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + + if (frame->width && frame->height && + av_image_check_sar(frame->width, frame->height, + frame->sample_aspect_ratio) < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + frame->sample_aspect_ratio.num, + frame->sample_aspect_ratio.den); + frame->sample_aspect_ratio = (AVRational){ 0, 1 }; + } + + break; + case AVMEDIA_TYPE_AUDIO: + if (!frame->sample_rate) + frame->sample_rate = avctx->sample_rate; + if (frame->format < 0) + frame->format = avctx->sample_fmt; + if (!frame->channel_layout) { + if (avctx->channel_layout) { + if (av_get_channel_layout_nb_channels(avctx->channel_layout) != + avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "Inconsistent channel " + "configuration.\n"); + return AVERROR(EINVAL); + } + + frame->channel_layout = avctx->channel_layout; + } else { + if (avctx->channels > FF_SANE_NB_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Too many channels: %d.\n", + avctx->channels); + return AVERROR(ENOSYS); + } + } + } + frame->channels = avctx->channels; + break; + } + return 0; +} + +static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame) +{ + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + int i; + int num_planes = av_pix_fmt_count_planes(frame->format); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + int flags = desc ? desc->flags : 0; + if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL)) + num_planes = 2; + if ((flags & FF_PSEUDOPAL) && frame->data[1]) + num_planes = 2; + for (i = 0; i < num_planes; i++) { + av_assert0(frame->data[i]); + } + // For formats without data like hwaccel allow unused pointers to be non-NULL. + for (i = num_planes; num_planes > 0 && i < FF_ARRAY_ELEMS(frame->data); i++) { + if (frame->data[i]) + av_log(avctx, AV_LOG_ERROR, "Buffer returned by get_buffer2() did not zero unused plane pointers\n"); + frame->data[i] = NULL; + } + } +} + +static void decode_data_free(void *opaque, uint8_t *data) +{ + FrameDecodeData *fdd = (FrameDecodeData*)data; + + if (fdd->post_process_opaque_free) + fdd->post_process_opaque_free(fdd->post_process_opaque); + + if (fdd->hwaccel_priv_free) + fdd->hwaccel_priv_free(fdd->hwaccel_priv); + + av_freep(&fdd); +} + +int ff_attach_decode_data(AVFrame *frame) +{ + AVBufferRef *fdd_buf; + FrameDecodeData *fdd; + + av_assert1(!frame->private_ref); + av_buffer_unref(&frame->private_ref); + + fdd = av_mallocz(sizeof(*fdd)); + if (!fdd) + return AVERROR(ENOMEM); + + fdd_buf = av_buffer_create((uint8_t*)fdd, sizeof(*fdd), decode_data_free, + NULL, AV_BUFFER_FLAG_READONLY); + if (!fdd_buf) { + av_freep(&fdd); + return AVERROR(ENOMEM); + } + + frame->private_ref = fdd_buf; + + return 0; +} + +static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + const AVHWAccel *hwaccel = avctx->hwaccel; + int override_dimensions = 1; + int ret; + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + if ((ret = av_image_check_size2(FFALIGN(avctx->width, STRIDE_ALIGN), avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) { + av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n"); + return AVERROR(EINVAL); + } + + if (frame->width <= 0 || frame->height <= 0) { + frame->width = FFMAX(avctx->width, AV_CEIL_RSHIFT(avctx->coded_width, avctx->lowres)); + frame->height = FFMAX(avctx->height, AV_CEIL_RSHIFT(avctx->coded_height, avctx->lowres)); + override_dimensions = 0; + } + + if (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3]) { + av_log(avctx, AV_LOG_ERROR, "pic->data[*]!=NULL in get_buffer_internal\n"); + return AVERROR(EINVAL); + } + } + ret = ff_decode_frame_props(avctx, frame); + if (ret < 0) + return ret; + + if (hwaccel) { + if (hwaccel->alloc_frame) { + ret = hwaccel->alloc_frame(avctx, frame); + goto end; + } + } else + avctx->sw_pix_fmt = avctx->pix_fmt; + + ret = avctx->get_buffer2(avctx, frame, flags); + if (ret < 0) + goto end; + + validate_avframe_allocation(avctx, frame); + + ret = ff_attach_decode_data(frame); + if (ret < 0) + goto end; + +end: + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions && + !(avctx->codec->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) { + frame->width = avctx->width; + frame->height = avctx->height; + } + + if (ret < 0) + av_frame_unref(frame); + + return ret; +} + +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) +{ + int ret = get_buffer_internal(avctx, frame, flags); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + frame->width = frame->height = 0; + } + return ret; +} + +static int reget_buffer_internal(AVCodecContext *avctx, AVFrame *frame) +{ + AVFrame *tmp; + int ret; + + av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO); + + if (frame->data[0] && (frame->width != avctx->width || frame->height != avctx->height || frame->format != avctx->pix_fmt)) { + av_log(avctx, AV_LOG_WARNING, "Picture changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s in reget buffer()\n", + frame->width, frame->height, av_get_pix_fmt_name(frame->format), avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt)); + av_frame_unref(frame); + } + + if (!frame->data[0]) + return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); + + if (av_frame_is_writable(frame)) + return ff_decode_frame_props(avctx, frame); + + tmp = av_frame_alloc(); + if (!tmp) + return AVERROR(ENOMEM); + + av_frame_move_ref(tmp, frame); + + ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); + if (ret < 0) { + av_frame_free(&tmp); + return ret; + } + + av_frame_copy(frame, tmp); + av_frame_free(&tmp); + + return 0; +} + +int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) +{ + int ret = reget_buffer_internal(avctx, frame); + if (ret < 0) + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return ret; +} + +static void bsfs_flush(AVCodecContext *avctx) +{ + DecodeFilterContext *s = &avctx->internal->filter; + + for (int i = 0; i < s->nb_bsfs; i++) + av_bsf_flush(s->bsfs[i]); +} + +void avcodec_flush_buffers(AVCodecContext *avctx) +{ + avctx->internal->draining = 0; + avctx->internal->draining_done = 0; + avctx->internal->nb_draining_errors = 0; + av_frame_unref(avctx->internal->buffer_frame); + av_frame_unref(avctx->internal->compat_decode_frame); + av_packet_unref(avctx->internal->buffer_pkt); + avctx->internal->buffer_pkt_valid = 0; + + av_packet_unref(avctx->internal->ds.in_pkt); + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) + ff_thread_flush(avctx); + else if (avctx->codec->flush) + avctx->codec->flush(avctx); + + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; + + bsfs_flush(avctx); + + if (!avctx->refcounted_frames) + av_frame_unref(avctx->internal->to_free); +} + +void ff_decode_bsfs_uninit(AVCodecContext *avctx) +{ + DecodeFilterContext *s = &avctx->internal->filter; + int i; + + for (i = 0; i < s->nb_bsfs; i++) + av_bsf_free(&s->bsfs[i]); + av_freep(&s->bsfs); + s->nb_bsfs = 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/decode.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/decode.h new file mode 100644 index 000000000..c3e0e82f4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/decode.h @@ -0,0 +1,81 @@ +/* + * generic decoding-related code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DECODE_H +#define AVCODEC_DECODE_H + +#include "libavutil/buffer.h" +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" + +#include "avcodec.h" + +/** + * This struct stores per-frame lavc-internal data and is attached to it via + * private_ref. + */ +typedef struct FrameDecodeData { + /** + * The callback to perform some delayed processing on the frame right + * before it is returned to the caller. + * + * @note This code is called at some unspecified point after the frame is + * returned from the decoder's decode/receive_frame call. Therefore it cannot rely + * on AVCodecContext being in any specific state, so it does not get to + * access AVCodecContext directly at all. All the state it needs must be + * stored in the post_process_opaque object. + */ + int (*post_process)(void *logctx, AVFrame *frame); + void *post_process_opaque; + void (*post_process_opaque_free)(void *opaque); + + /** + * Per-frame private data for hwaccels. + */ + void *hwaccel_priv; + void (*hwaccel_priv_free)(void *priv); +} FrameDecodeData; + +/** + * Called by decoders to get the next packet for decoding. + * + * @param pkt An empty packet to be filled with data. + * @return 0 if a new reference has been successfully written to pkt + * AVERROR(EAGAIN) if no data is currently available + * AVERROR_EOF if and end of stream has been reached, so no more data + * will be available + */ +int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); + +int ff_decode_bsfs_init(AVCodecContext *avctx); + +void ff_decode_bsfs_uninit(AVCodecContext *avctx); + +/** + * Make sure avctx.hw_frames_ctx is set. If it's not set, the function will + * try to allocate it from hw_device_ctx. If that is not possible, an error + * message is printed, and an error code is returned. + */ +int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, + enum AVHWDeviceType dev_type); + +int ff_attach_decode_data(AVFrame *frame); + +#endif /* AVCODEC_DECODE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac.c new file mode 100644 index 000000000..d5870d6c0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac.c @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2007 Marco Gerards + * Copyright (C) 2009 David Conrad + * Copyright (C) 2011 Jordi Ortiz + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Dirac Decoder + * @author Marco Gerards , David Conrad, Jordi Ortiz + */ + +#include "libavutil/imgutils.h" + +#include "avcodec.h" +#include "dirac.h" +#include "golomb.h" +#include "internal.h" +#include "mpeg12data.h" + +#if CONFIG_DIRAC_PARSE + +typedef struct dirac_source_params { + unsigned width; + unsigned height; + uint8_t chroma_format; ///< 0: 444 1: 422 2: 420 + + uint8_t interlaced; + uint8_t top_field_first; + + uint8_t frame_rate_index; ///< index into dirac_frame_rate[] + uint8_t aspect_ratio_index; ///< index into dirac_aspect_ratio[] + + uint16_t clean_width; + uint16_t clean_height; + uint16_t clean_left_offset; + uint16_t clean_right_offset; + + uint8_t pixel_range_index; ///< index into dirac_pixel_range_presets[] + uint8_t color_spec_index; ///< index into dirac_color_spec_presets[] +} dirac_source_params; + +/* defaults for source parameters */ +static const dirac_source_params dirac_source_parameters_defaults[] = { + { 640, 480, 2, 0, 0, 1, 1, 640, 480, 0, 0, 1, 0 }, + { 176, 120, 2, 0, 0, 9, 2, 176, 120, 0, 0, 1, 1 }, + { 176, 144, 2, 0, 1, 10, 3, 176, 144, 0, 0, 1, 2 }, + { 352, 240, 2, 0, 0, 9, 2, 352, 240, 0, 0, 1, 1 }, + { 352, 288, 2, 0, 1, 10, 3, 352, 288, 0, 0, 1, 2 }, + { 704, 480, 2, 0, 0, 9, 2, 704, 480, 0, 0, 1, 1 }, + { 704, 576, 2, 0, 1, 10, 3, 704, 576, 0, 0, 1, 2 }, + { 720, 480, 1, 1, 0, 4, 2, 704, 480, 8, 0, 3, 1 }, + { 720, 576, 1, 1, 1, 3, 3, 704, 576, 8, 0, 3, 2 }, + + { 1280, 720, 1, 0, 1, 7, 1, 1280, 720, 0, 0, 3, 3 }, + { 1280, 720, 1, 0, 1, 6, 1, 1280, 720, 0, 0, 3, 3 }, + { 1920, 1080, 1, 1, 1, 4, 1, 1920, 1080, 0, 0, 3, 3 }, + { 1920, 1080, 1, 1, 1, 3, 1, 1920, 1080, 0, 0, 3, 3 }, + { 1920, 1080, 1, 0, 1, 7, 1, 1920, 1080, 0, 0, 3, 3 }, + { 1920, 1080, 1, 0, 1, 6, 1, 1920, 1080, 0, 0, 3, 3 }, + { 2048, 1080, 0, 0, 1, 2, 1, 2048, 1080, 0, 0, 4, 4 }, + { 4096, 2160, 0, 0, 1, 2, 1, 4096, 2160, 0, 0, 4, 4 }, + + { 3840, 2160, 1, 0, 1, 7, 1, 3840, 2160, 0, 0, 3, 3 }, + { 3840, 2160, 1, 0, 1, 6, 1, 3840, 2160, 0, 0, 3, 3 }, + { 7680, 4320, 1, 0, 1, 7, 1, 3840, 2160, 0, 0, 3, 3 }, + { 7680, 4320, 1, 0, 1, 6, 1, 3840, 2160, 0, 0, 3, 3 }, +}; + +/* [DIRAC_STD] Table 10.4 - Available preset pixel aspect ratio values */ +static const AVRational dirac_preset_aspect_ratios[] = { + { 1, 1 }, + { 10, 11 }, + { 12, 11 }, + { 40, 33 }, + { 16, 11 }, + { 4, 3 }, +}; + +/* [DIRAC_STD] Values 9,10 of 10.3.5 Frame Rate. + * Table 10.3 Available preset frame rate values + */ +static const AVRational dirac_frame_rate[] = { + { 15000, 1001 }, + { 25, 2 }, +}; + +/* [DIRAC_STD] This should be equivalent to Table 10.5 Available signal + * range presets */ +static const struct { + uint8_t bitdepth; + enum AVColorRange color_range; +} pixel_range_presets[] = { + { 8, AVCOL_RANGE_JPEG }, + { 8, AVCOL_RANGE_MPEG }, + { 10, AVCOL_RANGE_MPEG }, + { 12, AVCOL_RANGE_MPEG }, +}; + +static const enum AVColorPrimaries dirac_primaries[] = { + AVCOL_PRI_BT709, + AVCOL_PRI_SMPTE170M, + AVCOL_PRI_BT470BG, +}; + +static const struct { + enum AVColorPrimaries color_primaries; + enum AVColorSpace colorspace; + enum AVColorTransferCharacteristic color_trc; +} dirac_color_presets[] = { + { AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_BT709 }, + { AVCOL_PRI_SMPTE170M, AVCOL_SPC_BT470BG, AVCOL_TRC_BT709 }, + { AVCOL_PRI_BT470BG, AVCOL_SPC_BT470BG, AVCOL_TRC_BT709 }, + { AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_BT709 }, + { AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_UNSPECIFIED /* DCinema */ }, +}; + +/* [DIRAC_STD] Table 10.2 Supported chroma sampling formats */ +static const enum AVPixelFormat dirac_pix_fmt[][3] = { + {AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12}, + {AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P12}, + {AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P12}, +}; + +/* [DIRAC_STD] 10.3 Parse Source Parameters. + * source_parameters(base_video_format) */ +static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, + void *log_ctx) +{ + AVRational frame_rate = { 0, 0 }; + unsigned luma_depth = 8, luma_offset = 16; + int idx; + int chroma_x_shift, chroma_y_shift; + int ret; + + /* [DIRAC_STD] 10.3.2 Frame size. frame_size(video_params) */ + /* [DIRAC_STD] custom_dimensions_flag */ + if (get_bits1(gb)) { + dsh->width = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] FRAME_WIDTH */ + dsh->height = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] FRAME_HEIGHT */ + } + + /* [DIRAC_STD] 10.3.3 Chroma Sampling Format. + * chroma_sampling_format(video_params) */ + /* [DIRAC_STD] custom_chroma_format_flag */ + if (get_bits1(gb)) + /* [DIRAC_STD] CHROMA_FORMAT_INDEX */ + dsh->chroma_format = get_interleaved_ue_golomb(gb); + if (dsh->chroma_format > 2U) { + if (log_ctx) + av_log(log_ctx, AV_LOG_ERROR, "Unknown chroma format %d\n", + dsh->chroma_format); + return AVERROR_INVALIDDATA; + } + + /* [DIRAC_STD] 10.3.4 Scan Format. scan_format(video_params) */ + /* [DIRAC_STD] custom_scan_format_flag */ + if (get_bits1(gb)) + /* [DIRAC_STD] SOURCE_SAMPLING */ + dsh->interlaced = get_interleaved_ue_golomb(gb); + if (dsh->interlaced > 1U) + return AVERROR_INVALIDDATA; + + /* [DIRAC_STD] 10.3.5 Frame Rate. frame_rate(video_params) */ + if (get_bits1(gb)) { /* [DIRAC_STD] custom_frame_rate_flag */ + dsh->frame_rate_index = get_interleaved_ue_golomb(gb); + + if (dsh->frame_rate_index > 10U) + return AVERROR_INVALIDDATA; + + if (!dsh->frame_rate_index) { + /* [DIRAC_STD] FRAME_RATE_NUMER */ + frame_rate.num = get_interleaved_ue_golomb(gb); + /* [DIRAC_STD] FRAME_RATE_DENOM */ + frame_rate.den = get_interleaved_ue_golomb(gb); + } + } + /* [DIRAC_STD] preset_frame_rate(video_params, index) */ + if (dsh->frame_rate_index > 0) { + if (dsh->frame_rate_index <= 8) + frame_rate = ff_mpeg12_frame_rate_tab[dsh->frame_rate_index]; + else + /* [DIRAC_STD] Table 10.3 values 9-10 */ + frame_rate = dirac_frame_rate[dsh->frame_rate_index - 9]; + } + dsh->framerate = frame_rate; + + /* [DIRAC_STD] 10.3.6 Pixel Aspect Ratio. + * pixel_aspect_ratio(video_params) */ + if (get_bits1(gb)) { /* [DIRAC_STD] custom_pixel_aspect_ratio_flag */ + /* [DIRAC_STD] index */ + dsh->aspect_ratio_index = get_interleaved_ue_golomb(gb); + + if (dsh->aspect_ratio_index > 6U) + return AVERROR_INVALIDDATA; + + if (!dsh->aspect_ratio_index) { + dsh->sample_aspect_ratio.num = get_interleaved_ue_golomb(gb); + dsh->sample_aspect_ratio.den = get_interleaved_ue_golomb(gb); + } + } + /* [DIRAC_STD] Take value from Table 10.4 Available preset pixel + * aspect ratio values */ + if (dsh->aspect_ratio_index > 0) + dsh->sample_aspect_ratio = + dirac_preset_aspect_ratios[dsh->aspect_ratio_index - 1]; + + /* [DIRAC_STD] 10.3.7 Clean area. clean_area(video_params) */ + if (get_bits1(gb)) { /* [DIRAC_STD] custom_clean_area_flag */ + /* [DIRAC_STD] CLEAN_WIDTH */ + dsh->clean_width = get_interleaved_ue_golomb(gb); + /* [DIRAC_STD] CLEAN_HEIGHT */ + dsh->clean_height = get_interleaved_ue_golomb(gb); + /* [DIRAC_STD] CLEAN_LEFT_OFFSET */ + dsh->clean_left_offset = get_interleaved_ue_golomb(gb); + /* [DIRAC_STD] CLEAN_RIGHT_OFFSET */ + dsh->clean_right_offset = get_interleaved_ue_golomb(gb); + } + + /* [DIRAC_STD] 10.3.8 Signal range. signal_range(video_params) + * WARNING: Some adaptation seems to be done using the + * AVCOL_RANGE_MPEG/JPEG values */ + if (get_bits1(gb)) { /* [DIRAC_STD] custom_signal_range_flag */ + /* [DIRAC_STD] index */ + dsh->pixel_range_index = get_interleaved_ue_golomb(gb); + + if (dsh->pixel_range_index > 4U) + return AVERROR_INVALIDDATA; + + /* This assumes either fullrange or MPEG levels only */ + if (!dsh->pixel_range_index) { + luma_offset = get_interleaved_ue_golomb(gb); + luma_depth = av_log2(get_interleaved_ue_golomb(gb)) + 1; + get_interleaved_ue_golomb(gb); /* chroma offset */ + get_interleaved_ue_golomb(gb); /* chroma excursion */ + dsh->color_range = luma_offset ? AVCOL_RANGE_MPEG + : AVCOL_RANGE_JPEG; + } + } + /* [DIRAC_STD] Table 10.5 + * Available signal range presets <--> pixel_range_presets */ + if (dsh->pixel_range_index > 0) { + idx = dsh->pixel_range_index - 1; + luma_depth = pixel_range_presets[idx].bitdepth; + dsh->color_range = pixel_range_presets[idx].color_range; + } + + dsh->bit_depth = luma_depth; + + /* Full range 8 bts uses the same pix_fmts as limited range 8 bits */ + dsh->pixel_range_index += dsh->pixel_range_index == 1; + + if (dsh->pixel_range_index < 2U) + return AVERROR_INVALIDDATA; + + dsh->pix_fmt = dirac_pix_fmt[dsh->chroma_format][dsh->pixel_range_index-2]; + ret = av_pix_fmt_get_chroma_sub_sample(dsh->pix_fmt, &chroma_x_shift, &chroma_y_shift); + if (ret) + return ret; + + if ((dsh->width % (1<height % (1<color_spec_index = get_interleaved_ue_golomb(gb); + + if (dsh->color_spec_index > 4U) + return AVERROR_INVALIDDATA; + + dsh->color_primaries = dirac_color_presets[idx].color_primaries; + dsh->colorspace = dirac_color_presets[idx].colorspace; + dsh->color_trc = dirac_color_presets[idx].color_trc; + + if (!dsh->color_spec_index) { + /* [DIRAC_STD] 10.3.9.1 Colour primaries */ + if (get_bits1(gb)) { + idx = get_interleaved_ue_golomb(gb); + if (idx < 3U) + dsh->color_primaries = dirac_primaries[idx]; + } + /* [DIRAC_STD] 10.3.9.2 Colour matrix */ + if (get_bits1(gb)) { + idx = get_interleaved_ue_golomb(gb); + if (!idx) + dsh->colorspace = AVCOL_SPC_BT709; + else if (idx == 1) + dsh->colorspace = AVCOL_SPC_BT470BG; + } + /* [DIRAC_STD] 10.3.9.3 Transfer function */ + if (get_bits1(gb) && !get_interleaved_ue_golomb(gb)) + dsh->color_trc = AVCOL_TRC_BT709; + } + } else { + idx = dsh->color_spec_index; + dsh->color_primaries = dirac_color_presets[idx].color_primaries; + dsh->colorspace = dirac_color_presets[idx].colorspace; + dsh->color_trc = dirac_color_presets[idx].color_trc; + } + + return 0; +} + +/* [DIRAC_STD] 10. Sequence Header. sequence_header() */ +int av_dirac_parse_sequence_header(AVDiracSeqHeader **pdsh, + const uint8_t *buf, size_t buf_size, + void *log_ctx) +{ + AVDiracSeqHeader *dsh; + GetBitContext gb; + unsigned video_format, picture_coding_mode; + int ret; + + dsh = av_mallocz(sizeof(*dsh)); + if (!dsh) + return AVERROR(ENOMEM); + + ret = init_get_bits8(&gb, buf, buf_size); + if (ret < 0) + goto fail; + + /* [DIRAC_SPEC] 10.1 Parse Parameters. parse_parameters() */ + dsh->version.major = get_interleaved_ue_golomb(&gb); + dsh->version.minor = get_interleaved_ue_golomb(&gb); + dsh->profile = get_interleaved_ue_golomb(&gb); + dsh->level = get_interleaved_ue_golomb(&gb); + /* [DIRAC_SPEC] sequence_header() -> base_video_format as defined in + * 10.2 Base Video Format, table 10.1 Dirac predefined video formats */ + video_format = get_interleaved_ue_golomb(&gb); + + if (dsh->version.major < 2 && log_ctx) + av_log(log_ctx, AV_LOG_WARNING, "Stream is old and may not work\n"); + else if (dsh->version.major > 2 && log_ctx) + av_log(log_ctx, AV_LOG_WARNING, "Stream may have unhandled features\n"); + + if (video_format > 20U) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + /* Fill in defaults for the source parameters. */ + dsh->width = dirac_source_parameters_defaults[video_format].width; + dsh->height = dirac_source_parameters_defaults[video_format].height; + dsh->chroma_format = dirac_source_parameters_defaults[video_format].chroma_format; + dsh->interlaced = dirac_source_parameters_defaults[video_format].interlaced; + dsh->top_field_first = dirac_source_parameters_defaults[video_format].top_field_first; + dsh->frame_rate_index = dirac_source_parameters_defaults[video_format].frame_rate_index; + dsh->aspect_ratio_index = dirac_source_parameters_defaults[video_format].aspect_ratio_index; + dsh->clean_width = dirac_source_parameters_defaults[video_format].clean_width; + dsh->clean_height = dirac_source_parameters_defaults[video_format].clean_height; + dsh->clean_left_offset = dirac_source_parameters_defaults[video_format].clean_left_offset; + dsh->clean_right_offset = dirac_source_parameters_defaults[video_format].clean_right_offset; + dsh->pixel_range_index = dirac_source_parameters_defaults[video_format].pixel_range_index; + dsh->color_spec_index = dirac_source_parameters_defaults[video_format].color_spec_index; + + /* [DIRAC_STD] 10.3 Source Parameters + * Override the defaults. */ + ret = parse_source_parameters(dsh, &gb, log_ctx); + if (ret < 0) + goto fail; + + /* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames + * currently only used to signal field coding */ + picture_coding_mode = get_interleaved_ue_golomb(&gb); + if (picture_coding_mode != 0) { + if (log_ctx) { + av_log(log_ctx, AV_LOG_ERROR, "Unsupported picture coding mode %d", + picture_coding_mode); + } + ret = AVERROR_INVALIDDATA; + goto fail; + } + + *pdsh = dsh; + return 0; +fail: + av_freep(&dsh); + *pdsh = NULL; + return ret; +} +#else +int av_dirac_parse_sequence_header(AVDiracSeqHeader **pdsh, + const uint8_t *buf, size_t buf_size, + void *log_ctx) +{ + return AVERROR(ENOSYS); +} +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac.h new file mode 100644 index 000000000..e6d9d346d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2007 Marco Gerards + * Copyright (C) 2009 David Conrad + * Copyright (C) 2011 Jordi Ortiz + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DIRAC_H +#define AVCODEC_DIRAC_H + +/** + * @file + * Interface to Dirac Decoder/Encoder + * @author Marco Gerards + * @author David Conrad + * @author Jordi Ortiz + */ + +#include "avcodec.h" + +/** + * The spec limits the number of wavelet decompositions to 4 for both + * level 1 (VC-2) and 128 (long-gop default). + * 5 decompositions is the maximum before >16-bit buffers are needed. + * Schroedinger allows this for DD 9,7 and 13,7 wavelets only, limiting + * the others to 4 decompositions (or 3 for the fidelity filter). + * + * We use this instead of MAX_DECOMPOSITIONS to save some memory. + */ +#define MAX_DWT_LEVELS 5 + +/** + * Parse code values: + * + * Dirac Specification -> + * 9.6.1 Table 9.1 + * + * VC-2 Specification -> + * 10.4.1 Table 10.1 + */ + +enum DiracParseCodes { + DIRAC_PCODE_SEQ_HEADER = 0x00, + DIRAC_PCODE_END_SEQ = 0x10, + DIRAC_PCODE_AUX = 0x20, + DIRAC_PCODE_PAD = 0x30, + DIRAC_PCODE_PICTURE_CODED = 0x08, + DIRAC_PCODE_PICTURE_RAW = 0x48, + DIRAC_PCODE_PICTURE_LOW_DEL = 0xC8, + DIRAC_PCODE_PICTURE_HQ = 0xE8, + DIRAC_PCODE_INTER_NOREF_CO1 = 0x0A, + DIRAC_PCODE_INTER_NOREF_CO2 = 0x09, + DIRAC_PCODE_INTER_REF_CO1 = 0x0D, + DIRAC_PCODE_INTER_REF_CO2 = 0x0E, + DIRAC_PCODE_INTRA_REF_CO = 0x0C, + DIRAC_PCODE_INTRA_REF_RAW = 0x4C, + DIRAC_PCODE_INTRA_REF_PICT = 0xCC, + DIRAC_PCODE_MAGIC = 0x42424344, +}; + +typedef struct DiracVersionInfo { + int major; + int minor; +} DiracVersionInfo; + +typedef struct AVDiracSeqHeader { + unsigned width; + unsigned height; + uint8_t chroma_format; ///< 0: 444 1: 422 2: 420 + + uint8_t interlaced; + uint8_t top_field_first; + + uint8_t frame_rate_index; ///< index into dirac_frame_rate[] + uint8_t aspect_ratio_index; ///< index into dirac_aspect_ratio[] + + uint16_t clean_width; + uint16_t clean_height; + uint16_t clean_left_offset; + uint16_t clean_right_offset; + + uint8_t pixel_range_index; ///< index into dirac_pixel_range_presets[] + uint8_t color_spec_index; ///< index into dirac_color_spec_presets[] + + int profile; + int level; + + AVRational framerate; + AVRational sample_aspect_ratio; + + enum AVPixelFormat pix_fmt; + enum AVColorRange color_range; + enum AVColorPrimaries color_primaries; + enum AVColorTransferCharacteristic color_trc; + enum AVColorSpace colorspace; + + DiracVersionInfo version; + int bit_depth; +} AVDiracSeqHeader; + +/** + * Parse a Dirac sequence header. + * + * @param dsh this function will allocate and fill an AVDiracSeqHeader struct + * and write it into this pointer. The caller must free it with + * av_free(). + * @param buf the data buffer + * @param buf_size the size of the data buffer in bytes + * @param log_ctx if non-NULL, this function will log errors here + * @return 0 on success, a negative AVERROR code on failure + */ +int av_dirac_parse_sequence_header(AVDiracSeqHeader **dsh, + const uint8_t *buf, size_t buf_size, + void *log_ctx); + +#endif /* AVCODEC_DIRAC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_arith.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_arith.h new file mode 100644 index 000000000..79526a7ca --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_arith.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2007 Marco Gerards + * Copyright (C) 2009 David Conrad + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Arithmetic decoder for Dirac + * @author Marco Gerards + */ + +#ifndef AVCODEC_DIRAC_ARITH_H +#define AVCODEC_DIRAC_ARITH_H + +#include "libavutil/x86/asm.h" +#include "bytestream.h" +#include "get_bits.h" + +enum dirac_arith_contexts { + CTX_ZPZN_F1, + CTX_ZPNN_F1, + CTX_NPZN_F1, + CTX_NPNN_F1, + CTX_ZP_F2, + CTX_ZP_F3, + CTX_ZP_F4, + CTX_ZP_F5, + CTX_ZP_F6, + CTX_NP_F2, + CTX_NP_F3, + CTX_NP_F4, + CTX_NP_F5, + CTX_NP_F6, + CTX_COEFF_DATA, + CTX_SIGN_NEG, + CTX_SIGN_ZERO, + CTX_SIGN_POS, + CTX_ZERO_BLOCK, + CTX_DELTA_Q_F, + CTX_DELTA_Q_DATA, + CTX_DELTA_Q_SIGN, + + DIRAC_CTX_COUNT +}; + +// Dirac resets the arith decoder between decoding various types of data, +// so many contexts are never used simultaneously. Thus, we can reduce +// the number of contexts needed by reusing them. +#define CTX_SB_F1 CTX_ZP_F5 +#define CTX_SB_DATA 0 +#define CTX_PMODE_REF1 0 +#define CTX_PMODE_REF2 1 +#define CTX_GLOBAL_BLOCK 2 +#define CTX_MV_F1 CTX_ZP_F2 +#define CTX_MV_DATA 0 +#define CTX_DC_F1 CTX_ZP_F5 +#define CTX_DC_DATA 0 + +typedef struct { + unsigned low; + uint16_t range; + int16_t counter; + + const uint8_t *bytestream; + const uint8_t *bytestream_end; + + uint16_t contexts[DIRAC_CTX_COUNT]; + int error; + int overread; +} DiracArith; + +extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT]; +extern const uint16_t ff_dirac_prob[256]; +extern int16_t ff_dirac_prob_branchless[256][2]; + +static inline void renorm(DiracArith *c) +{ +#if HAVE_FAST_CLZ + int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15); + + c->low <<= shift; + c->range <<= shift; + c->counter += shift; +#else + while (c->range <= 0x4000) { + c->low <<= 1; + c->range <<= 1; + c->counter++; + } +#endif +} + +static inline void refill(DiracArith *c) +{ + int counter = c->counter; + + if (counter >= 0) { + int new = bytestream_get_be16(&c->bytestream); + + // the spec defines overread bits to be 1, and streams rely on this + if (c->bytestream > c->bytestream_end) { + new |= 0xff; + if (c->bytestream > c->bytestream_end+1) + new |= 0xff00; + + c->bytestream = c->bytestream_end; + c->overread ++; + if (c->overread > 4) + c->error = AVERROR_INVALIDDATA; + } + + c->low += new << counter; + counter -= 16; + } + c->counter = counter; +} + +static inline int dirac_get_arith_bit(DiracArith *c, int ctx) +{ + int prob_zero = c->contexts[ctx]; + int range_times_prob, bit; + unsigned low = c->low; + int range = c->range; + + range_times_prob = (c->range * prob_zero) >> 16; + +#if ARCH_X86 && HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_6REGS + low -= range_times_prob << 16; + range -= range_times_prob; + bit = 0; + __asm__( + "cmpl %5, %4 \n\t" + "setae %b0 \n\t" + "cmovb %3, %2 \n\t" + "cmovb %5, %1 \n\t" + : "+q"(bit), "+r"(range), "+r"(low) + : "r"(c->low), "r"(c->low>>16), + "r"(range_times_prob) + ); +#else + bit = (low >> 16) >= range_times_prob; + if (bit) { + low -= range_times_prob << 16; + range -= range_times_prob; + } else { + range = range_times_prob; + } +#endif + + c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit]; + c->low = low; + c->range = range; + + renorm(c); + refill(c); + return bit; +} + +static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx) +{ + int ret = 1; + while (!dirac_get_arith_bit(c, follow_ctx)) { + if (ret >= 0x40000000) { + av_log(NULL, AV_LOG_ERROR, "dirac_get_arith_uint overflow\n"); + c->error = AVERROR_INVALIDDATA; + return -1; + } + ret <<= 1; + ret += dirac_get_arith_bit(c, data_ctx); + follow_ctx = ff_dirac_next_ctx[follow_ctx]; + } + return ret-1; +} + +static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx) +{ + int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx); + if (ret && dirac_get_arith_bit(c, data_ctx+1)) + ret = -ret; + return ret; +} + +void ff_dirac_init_arith_tables(void); +void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length); + +#endif /* AVCODEC_DIRAC_ARITH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_dwt.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_dwt.h new file mode 100644 index 000000000..994dc21d7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_dwt.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2004-2010 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DIRAC_DWT_H +#define AVCODEC_DIRAC_DWT_H + +#include + +typedef int DWTELEM; +typedef short IDWTELEM; + +#define MAX_DWT_SUPPORT 8 +#define MAX_DECOMPOSITIONS 8 + +typedef struct DWTCompose { + uint8_t *b[MAX_DWT_SUPPORT]; + int y; +} DWTCompose; + +typedef struct DWTPlane { + int width; + int height; + int stride; + uint8_t *buf; + uint8_t *buf_base; + uint8_t *tmp; +} DWTPlane; + +struct DWTContext; + +// Possible prototypes for vertical_compose functions +typedef void (*vertical_compose_2tap)(uint8_t *b0, uint8_t *b1, int width); +typedef void (*vertical_compose_3tap)(uint8_t *b0, uint8_t *b1, uint8_t *b2, int width); +typedef void (*vertical_compose_5tap)(uint8_t *b0, uint8_t *b1, uint8_t *b2, uint8_t *b3, uint8_t *b4, int width); +typedef void (*vertical_compose_9tap)(uint8_t *dst, uint8_t *b[8], int width); + +typedef struct DWTContext { + uint8_t *buffer; + uint8_t *temp; + int width; + int height; + int stride; + int decomposition_count; + int support; + + void (*spatial_compose)(struct DWTContext *cs, int level, int width, int height, int stride); + void (*vertical_compose_l0)(void); + void (*vertical_compose_h0)(void); + void (*vertical_compose_l1)(void); + void (*vertical_compose_h1)(void); + void (*vertical_compose)(void); ///< one set of lowpass and highpass combined + void (*horizontal_compose)(uint8_t *b, uint8_t *tmp, int width); + + DWTCompose cs[MAX_DECOMPOSITIONS]; +} DWTContext; + +enum dwt_type { + DWT_SNOW_DAUB9_7, + DWT_SNOW_LEGALL5_3, + DWT_DIRAC_DD9_7, + DWT_DIRAC_LEGALL5_3, + DWT_DIRAC_DD13_7, + DWT_DIRAC_HAAR0, + DWT_DIRAC_HAAR1, + DWT_DIRAC_FIDELITY, + DWT_DIRAC_DAUB9_7, + DWT_NUM_TYPES +}; + +// -1 if an error occurred, e.g. the dwt_type isn't recognized +int ff_spatial_idwt_init(DWTContext *d, DWTPlane *p, enum dwt_type type, + int decomposition_count, int bit_depth); +void ff_spatial_idwt_init_x86(DWTContext *d, enum dwt_type type); + +void ff_spatial_idwt_slice2(DWTContext *d, int y); + +// shared stuff for simd optimizations +#define COMPOSE_53iL0(b0, b1, b2)\ + (b1 - (unsigned)((int)(b0 + (unsigned)(b2) + 2) >> 2)) + +#define COMPOSE_DIRAC53iH0(b0, b1, b2)\ + (b1 + (unsigned)((int)(b0 + (unsigned)(b2) + 1) >> 1)) + +#define COMPOSE_DD97iH0(b0, b1, b2, b3, b4)\ + (int)(((unsigned)(b2) + ((int)(9U*b1 + 9U*b3 - b4 - b0 + 8) >> 4))) + +#define COMPOSE_DD137iL0(b0, b1, b2, b3, b4)\ + (int)(((unsigned)(b2) - ((int)(9U*b1 + 9U*b3 - b4 - b0 + 16) >> 5))) + +#define COMPOSE_HAARiL0(b0, b1)\ + ((int)(b0 - (unsigned)((int)(b1 + 1U) >> 1))) + +#define COMPOSE_HAARiH0(b0, b1)\ + ((int)(b0 + (unsigned)(b1))) + +#define COMPOSE_FIDELITYiL0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\ + ((unsigned)b4 - ((int)(-8*(b0+(unsigned)b8) + 21*(b1+(unsigned)b7) - 46*(b2+(unsigned)b6) + 161*(b3+(unsigned)b5) + 128) >> 8)) + +#define COMPOSE_FIDELITYiH0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\ + ((unsigned)b4 + ((int)(-2*(b0+(unsigned)b8) + 10*(b1+(unsigned)b7) - 25*(b2+(unsigned)b6) + 81*(b3+(unsigned)b5) + 128) >> 8)) + +#define COMPOSE_DAUB97iL1(b0, b1, b2)\ + ((unsigned)(b1) - ((int)(1817*(b0 + (unsigned)b2) + 2048) >> 12)) + +#define COMPOSE_DAUB97iH1(b0, b1, b2)\ + ((unsigned)(b1) - ((int)( 113*(b0 + (unsigned)b2) + 64) >> 7)) + +#define COMPOSE_DAUB97iL0(b0, b1, b2)\ + ((unsigned)(b1) + ((int)( 217*(b0 + (unsigned)b2) + 2048) >> 12)) + +#define COMPOSE_DAUB97iH0(b0, b1, b2)\ + ((unsigned)(b1) + ((int)(6497*(b0 + (unsigned)b2) + 2048) >> 12)) + + +#endif /* AVCODEC_DWT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_vlc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_vlc.h new file mode 100644 index 000000000..42ae41b00 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dirac_vlc.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 Open Broadcast Systems Ltd. + * Author 2016 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DIRAC_VLC_H +#define AVCODEC_DIRAC_VLC_H + +#include "libavutil/avutil.h" + +/* Can be 32 bits wide for some performance gain on some machines, but it will + * incorrectly decode very long coefficients (usually only 1 or 2 per frame) */ +typedef uint64_t residual; + +#define LUT_BITS 8 + +/* Exactly 64 bytes */ +typedef struct DiracGolombLUT { + residual preamble, leftover; + int32_t ready[LUT_BITS]; + int32_t preamble_bits, leftover_bits, ready_num; + int8_t need_s, sign; +} DiracGolombLUT; + +av_cold int ff_dirac_golomb_reader_init(DiracGolombLUT **lut_ctx); + +int ff_dirac_golomb_read_32bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, + int bytes, uint8_t *dst, int coeffs); + +int ff_dirac_golomb_read_16bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, + int bytes, uint8_t *_dst, int coeffs); + +av_cold void ff_dirac_golomb_reader_end(DiracGolombLUT **lut_ctx); + +#endif /* AVCODEC_DIRAC_VLC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/diracdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/diracdsp.h new file mode 100644 index 000000000..224828d88 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/diracdsp.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010 David Conrad + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DIRACDSP_H +#define AVCODEC_DIRACDSP_H + +#include +#include + +typedef void (*dirac_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int h); +typedef void (*dirac_biweight_func)(uint8_t *dst, const uint8_t *src, int stride, int log2_denom, int weightd, int weights, int h); + +typedef struct { + void (*dirac_hpel_filter)(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, const uint8_t *src, int stride, int width, int height); + /** + * dirac_pixels_tab[width][subpel] + * width is 2 for 32, 1 for 16, 0 for 8 + * subpel is 0 for fpel and hpel (only need to copy from the first plane in src) + * 1 if an average of the first 2 planes is needed (TODO: worth it?) + * 2 for general qpel (avg of 4) + * 3 for general epel (biweight of 4 using the weights in src[4]) + * src[0-3] is each of the hpel planes + * src[4] is the 1/8 pel weights if needed + */ + void (*put_dirac_pixels_tab[3][4])(uint8_t *dst, const uint8_t *src[5], int stride, int h); + void (*avg_dirac_pixels_tab[3][4])(uint8_t *dst, const uint8_t *src[5], int stride, int h); + + void (*put_signed_rect_clamped[3])(uint8_t *dst/*align 16*/, int dst_stride, const uint8_t *src/*align 16*/, int src_stride, int width, int height/*mod 2*/); + void (*put_rect_clamped)(uint8_t *dst/*align 16*/, int dst_stride, const uint8_t *src/*align 16*/, int src_stride, int width, int height/*mod 2*/); + void (*add_rect_clamped)(uint8_t *dst/*align 16*/, const uint16_t *src/*align 16*/, int stride, const int16_t *idwt/*align 16*/, int idwt_stride, int width, int height/*mod 2*/); + void (*add_dirac_obmc[3])(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); + + /* 0-1: int16_t and int32_t asm/c, 2-3: int16 and int32_t, C only */ + void (*dequant_subband[4])(uint8_t *src, uint8_t *dst, ptrdiff_t stride, const int qf, const int qs, int tot_v, int tot_h); + + dirac_weight_func weight_dirac_pixels_tab[3]; + dirac_biweight_func biweight_dirac_pixels_tab[3]; +} DiracDSPContext; + +#define DECL_DIRAC_PIXOP(PFX, EXT) \ + void ff_ ## PFX ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h); \ + void ff_ ## PFX ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h); \ + void ff_ ## PFX ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h) + +DECL_DIRAC_PIXOP(put, c); +DECL_DIRAC_PIXOP(avg, c); +DECL_DIRAC_PIXOP(put, l2_c); +DECL_DIRAC_PIXOP(avg, l2_c); +DECL_DIRAC_PIXOP(put, l4_c); +DECL_DIRAC_PIXOP(avg, l4_c); + +void ff_diracdsp_init(DiracDSPContext *c); +void ff_diracdsp_init_x86(DiracDSPContext* c); + +#endif /* AVCODEC_DIRACDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/diractab.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/diractab.h new file mode 100644 index 000000000..2423b0729 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/diractab.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 Open Broadcast Systems Ltd. + * Author (C) 2016 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DIRACTAB_H +#define AVCODEC_DIRACTAB_H + +#include + +/* Tables here are shared between the Dirac/VC-2 decoder and the VC-2 encoder */ + +/* Default quantization tables for each wavelet transform */ +extern const uint8_t ff_dirac_default_qmat[7][4][4]; + +/* Scaling factors needed for quantization/dequantization */ +extern const int32_t ff_dirac_qscale_tab[116]; + +/* Scaling offsets needed for quantization/dequantization, for intra frames */ +extern const int32_t ff_dirac_qoffset_intra_tab[120]; + +/* Scaling offsets needed for quantization/dequantization, for inter frames */ +extern const int ff_dirac_qoffset_inter_tab[122]; + +#define DIRAC_MAX_QUANT_INDEX (FF_ARRAY_ELEMS(ff_dirac_qscale_tab)) + +#endif /* AVCODEC_DIRACTAB_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile.c new file mode 100644 index 000000000..66505c886 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile.c @@ -0,0 +1,341 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/log.h" +#include "libavutil/pixdesc.h" + +#include "avcodec.h" +#include "dv_profile.h" +#include "dv_profile_internal.h" + +#if CONFIG_DVPROFILE + +static const uint8_t dv_audio_shuffle525[10][9] = { + { 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */ + { 6, 36, 66, 26, 56, 86, 16, 46, 76 }, + { 12, 42, 72, 2, 32, 62, 22, 52, 82 }, + { 18, 48, 78, 8, 38, 68, 28, 58, 88 }, + { 24, 54, 84, 14, 44, 74, 4, 34, 64 }, + + { 1, 31, 61, 21, 51, 81, 11, 41, 71 }, /* 2nd channel */ + { 7, 37, 67, 27, 57, 87, 17, 47, 77 }, + { 13, 43, 73, 3, 33, 63, 23, 53, 83 }, + { 19, 49, 79, 9, 39, 69, 29, 59, 89 }, + { 25, 55, 85, 15, 45, 75, 5, 35, 65 }, +}; + +static const uint8_t dv_audio_shuffle625[12][9] = { + { 0, 36, 72, 26, 62, 98, 16, 52, 88 }, /* 1st channel */ + { 6, 42, 78, 32, 68, 104, 22, 58, 94 }, + { 12, 48, 84, 2, 38, 74, 28, 64, 100 }, + { 18, 54, 90, 8, 44, 80, 34, 70, 106 }, + { 24, 60, 96, 14, 50, 86, 4, 40, 76 }, + { 30, 66, 102, 20, 56, 92, 10, 46, 82 }, + + { 1, 37, 73, 27, 63, 99, 17, 53, 89 }, /* 2nd channel */ + { 7, 43, 79, 33, 69, 105, 23, 59, 95 }, + { 13, 49, 85, 3, 39, 75, 29, 65, 101 }, + { 19, 55, 91, 9, 45, 81, 35, 71, 107 }, + { 25, 61, 97, 15, 51, 87, 5, 41, 77 }, + { 31, 67, 103, 21, 57, 93, 11, 47, 83 }, +}; + +/* macroblock bit budgets */ +static const uint8_t block_sizes_dv2550[8] = { + 112, 112, 112, 112, 80, 80, 0, 0, +}; + +static const uint8_t block_sizes_dv100[8] = { + 80, 80, 80, 80, 80, 80, 64, 64, +}; + +static const AVDVProfile dv_profiles[] = { + { .dsf = 0, + .video_stype = 0x0, + .frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */ + .difseg_size = 10, + .n_difchan = 1, + .time_base = { 1001, 30000 }, + .ltc_divisor = 30, + .height = 480, + .width = 720, + .sar = { { 8, 9 }, { 32, 27 } }, + .pix_fmt = AV_PIX_FMT_YUV411P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, + .audio_stride = 90, + .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ + .audio_shuffle = dv_audio_shuffle525, }, + { .dsf = 1, + .video_stype = 0x0, + .frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */ + .difseg_size = 12, + .n_difchan = 1, + .time_base = { 1, 25 }, + .ltc_divisor = 25, + .height = 576, + .width = 720, + .sar = { { 16, 15 }, { 64, 45 } }, + .pix_fmt = AV_PIX_FMT_YUV420P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, + .audio_stride = 108, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, }, + { .dsf = 1, + .video_stype = 0x0, + .frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */ + .difseg_size = 12, + .n_difchan = 1, + .time_base = { 1, 25 }, + .ltc_divisor = 25, + .height = 576, + .width = 720, + .sar = { { 16, 15 }, { 64, 45 } }, + .pix_fmt = AV_PIX_FMT_YUV411P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, + .audio_stride = 108, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, }, + { .dsf = 0, + .video_stype = 0x4, + .frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */ + .difseg_size = 10, /* also known as "DVCPRO50" */ + .n_difchan = 2, + .time_base = { 1001, 30000 }, + .ltc_divisor = 30, + .height = 480, + .width = 720, + .sar = { { 8, 9 }, { 32, 27 } }, + .pix_fmt = AV_PIX_FMT_YUV422P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, + .audio_stride = 90, + .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ + .audio_shuffle = dv_audio_shuffle525, }, + { .dsf = 1, + .video_stype = 0x4, + .frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */ + .difseg_size = 12, /* also known as "DVCPRO50" */ + .n_difchan = 2, + .time_base = { 1, 25 }, + .ltc_divisor = 25, + .height = 576, + .width = 720, + .sar = { { 16, 15 }, { 64, 45 } }, + .pix_fmt = AV_PIX_FMT_YUV422P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, + .audio_stride = 108, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, }, + { .dsf = 0, + .video_stype = 0x14, + .frame_size = 480000, /* SMPTE-370M - 1080i60 100 Mbps */ + .difseg_size = 10, /* also known as "DVCPRO HD" */ + .n_difchan = 4, + .time_base = { 1001, 30000 }, + .ltc_divisor = 30, + .height = 1080, + .width = 1280, + .sar = { { 1, 1 }, { 3, 2 } }, + .pix_fmt = AV_PIX_FMT_YUV422P, + .bpm = 8, + .block_sizes = block_sizes_dv100, + .audio_stride = 90, + .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ + .audio_shuffle = dv_audio_shuffle525, }, + { .dsf = 1, + .video_stype = 0x14, + .frame_size = 576000, /* SMPTE-370M - 1080i50 100 Mbps */ + .difseg_size = 12, /* also known as "DVCPRO HD" */ + .n_difchan = 4, + .time_base = { 1, 25 }, + .ltc_divisor = 25, + .height = 1080, + .width = 1440, + .sar = { { 1, 1 }, { 4, 3 } }, + .pix_fmt = AV_PIX_FMT_YUV422P, + .bpm = 8, + .block_sizes = block_sizes_dv100, + .audio_stride = 108, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, }, + { .dsf = 0, + .video_stype = 0x18, + .frame_size = 240000, /* SMPTE-370M - 720p60 100 Mbps */ + .difseg_size = 10, /* also known as "DVCPRO HD" */ + .n_difchan = 2, + .time_base = { 1001, 60000 }, + .ltc_divisor = 60, + .height = 720, + .width = 960, + .sar = { { 1, 1 }, { 4, 3 } }, + .pix_fmt = AV_PIX_FMT_YUV422P, + .bpm = 8, + .block_sizes = block_sizes_dv100, + .audio_stride = 90, + .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ + .audio_shuffle = dv_audio_shuffle525, }, + { .dsf = 1, + .video_stype = 0x18, + .frame_size = 288000, /* SMPTE-370M - 720p50 100 Mbps */ + .difseg_size = 12, /* also known as "DVCPRO HD" */ + .n_difchan = 2, + .time_base = { 1, 50 }, + .ltc_divisor = 50, + .height = 720, + .width = 960, + .sar = { { 1, 1 }, { 4, 3 } }, + .pix_fmt = AV_PIX_FMT_YUV422P, + .bpm = 8, + .block_sizes = block_sizes_dv100, + .audio_stride = 90, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, }, + { .dsf = 1, + .video_stype = 0x1, + .frame_size = 144000, /* IEC 61883-5 - 625/50 (PAL) */ + .difseg_size = 12, + .n_difchan = 1, + .time_base = { 1, 25 }, + .ltc_divisor = 25, + .height = 576, + .width = 720, + .sar = { { 16, 15 }, { 64, 45 } }, + .pix_fmt = AV_PIX_FMT_YUV420P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, + .audio_stride = 108, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, } +}; + +void ff_dv_print_profiles(void *logctx, int loglevel) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++) { + const AVDVProfile *p = &dv_profiles[i]; + av_log(logctx, loglevel, + "Frame size: %dx%d; pixel format: %s, framerate: %d/%d\n", + p->width, p->height, av_get_pix_fmt_name(p->pix_fmt), + p->time_base.den, p->time_base.num); + } +} + +#endif /* CONFIG_DVPROFILE */ + +const AVDVProfile* ff_dv_frame_profile(AVCodecContext* codec, const AVDVProfile *sys, + const uint8_t *frame, unsigned buf_size) +{ +#if CONFIG_DVPROFILE + int i, dsf, stype; + + if(buf_size < DV_PROFILE_BYTES) + return NULL; + + dsf = (frame[3] & 0x80) >> 7; + stype = frame[80 * 5 + 48 + 3] & 0x1f; + + /* 576i50 25Mbps 4:1:1 is a special case */ + if ((dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) || + (stype == 31 && codec && codec->codec_tag==AV_RL32("SL25") && codec->coded_width==720 && codec->coded_height==576)) + return &dv_profiles[2]; + + if( stype == 0 + && codec + && (codec->codec_tag==AV_RL32("dvsd") || codec->codec_tag==AV_RL32("CDVC")) + && codec->coded_width ==720 + && codec->coded_height==576) + return &dv_profiles[1]; + + for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++) + if (dsf == dv_profiles[i].dsf && stype == dv_profiles[i].video_stype) + return &dv_profiles[i]; + + /* check if old sys matches and assumes corrupted input */ + if (sys && buf_size == sys->frame_size) + return sys; + + /* hack for trac issue #217, dv files created with QuickTime 3 */ + if ((frame[3] & 0x7f) == 0x3f && frame[80 * 5 + 48 + 3] == 0xff) + return &dv_profiles[dsf]; +#endif + + return NULL; +} + +const AVDVProfile *av_dv_frame_profile(const AVDVProfile *sys, + const uint8_t *frame, unsigned buf_size) +{ + return ff_dv_frame_profile(NULL, sys, frame, buf_size); +} + +const AVDVProfile *av_dv_codec_profile(int width, int height, + enum AVPixelFormat pix_fmt) +{ +#if CONFIG_DVPROFILE + return av_dv_codec_profile2(width, height, pix_fmt, (AVRational){0, 0}); +#endif + + return NULL; +} + +const AVDVProfile *av_dv_codec_profile2(int width, int height, + enum AVPixelFormat pix_fmt, + AVRational frame_rate) +{ + const AVDVProfile *p = NULL; +#if CONFIG_DVPROFILE + int i; + /* frame rate is necessary to select between 720p50 and 720p60 profiles */ + int invalid_framerate = frame_rate.num == 0 || frame_rate.den == 0; + + for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++) + if (height == dv_profiles[i].height && + pix_fmt == dv_profiles[i].pix_fmt && + width == dv_profiles[i].width) + { + if( invalid_framerate || av_div_q(dv_profiles[i].time_base, frame_rate).num == 1 ) + return &dv_profiles[i]; + + if(!p) + p = &dv_profiles[i]; + } +#endif + + return p; +} + diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile.h new file mode 100644 index 000000000..9380a66f0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile.h @@ -0,0 +1,83 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DV_PROFILE_H +#define AVCODEC_DV_PROFILE_H + +#include + +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" +#include "avcodec.h" + +/* minimum number of bytes to read from a DV stream in order to + * determine the profile */ +#define DV_PROFILE_BYTES (6 * 80) /* 6 DIF blocks */ + + +/* + * AVDVProfile is used to express the differences between various + * DV flavors. For now it's primarily used for differentiating + * 525/60 and 625/50, but the plans are to use it for various + * DV specs as well (e.g. SMPTE314M vs. IEC 61834). + */ +typedef struct AVDVProfile { + int dsf; /* value of the dsf in the DV header */ + int video_stype; /* stype for VAUX source pack */ + int frame_size; /* total size of one frame in bytes */ + int difseg_size; /* number of DIF segments per DIF channel */ + int n_difchan; /* number of DIF channels per frame */ + AVRational time_base; /* 1/framerate */ + int ltc_divisor; /* FPS from the LTS standpoint */ + int height; /* picture height in pixels */ + int width; /* picture width in pixels */ + AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */ + enum AVPixelFormat pix_fmt; /* picture pixel format */ + int bpm; /* blocks per macroblock */ + const uint8_t *block_sizes; /* AC block sizes, in bits */ + int audio_stride; /* size of audio_shuffle table */ + int audio_min_samples[3]; /* min amount of audio samples */ + /* for 48kHz, 44.1kHz and 32kHz */ + int audio_samples_dist[5]; /* how many samples are supposed to be */ + /* in each frame in a 5 frames window */ + const uint8_t (*audio_shuffle)[9]; /* PCM shuffling table */ +} AVDVProfile; + +/** + * Get a DV profile for the provided compressed frame. + * + * @param sys the profile used for the previous frame, may be NULL + * @param frame the compressed data buffer + * @param buf_size size of the buffer in bytes + * @return the DV profile for the supplied data or NULL on failure + */ +const AVDVProfile *av_dv_frame_profile(const AVDVProfile *sys, + const uint8_t *frame, unsigned buf_size); + +/** + * Get a DV profile for the provided stream parameters. + */ +const AVDVProfile *av_dv_codec_profile(int width, int height, enum AVPixelFormat pix_fmt); + +/** + * Get a DV profile for the provided stream parameters. + * The frame rate is used as a best-effort parameter. + */ +const AVDVProfile *av_dv_codec_profile2(int width, int height, enum AVPixelFormat pix_fmt, AVRational frame_rate); + +#endif /* AVCODEC_DV_PROFILE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile_internal.h new file mode 100644 index 000000000..67d3a2b79 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dv_profile_internal.h @@ -0,0 +1,35 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DV_PROFILE_INTERNAL_H +#define AVCODEC_DV_PROFILE_INTERNAL_H + +#include "dv_profile.h" + +/** + * Print all allowed DV profiles into logctx at specified logging level. + */ +void ff_dv_print_profiles(void *logctx, int loglevel); + +/** + * Get a DV profile for the provided compressed frame. + */ +const AVDVProfile* ff_dv_frame_profile(AVCodecContext* codec, const AVDVProfile *sys, + const uint8_t *frame, unsigned buf_size); + +#endif /* AVCODEC_DV_PROFILE_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dxva2.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dxva2.h new file mode 100644 index 000000000..22c93992f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/dxva2.h @@ -0,0 +1,93 @@ +/* + * DXVA2 HW acceleration + * + * copyright (c) 2009 Laurent Aimar + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DXVA2_H +#define AVCODEC_DXVA2_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_dxva2 + * Public libavcodec DXVA2 header. + */ + +#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0602 +#endif + +#include +#include +#include + +/** + * @defgroup lavc_codec_hwaccel_dxva2 DXVA2 + * @ingroup lavc_codec_hwaccel + * + * @{ + */ + +#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards +#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO 2 ///< Work around for DXVA2 and old Intel GPUs with ClearVideo interface + +/** + * This structure is used to provides the necessary configurations and data + * to the DXVA2 FFmpeg HWAccel implementation. + * + * The application must make it available as AVCodecContext.hwaccel_context. + */ +struct dxva_context { + /** + * DXVA2 decoder object + */ + IDirectXVideoDecoder *decoder; + + /** + * DXVA2 configuration used to create the decoder + */ + const DXVA2_ConfigPictureDecode *cfg; + + /** + * The number of surface in the surface array + */ + unsigned surface_count; + + /** + * The array of Direct3D surfaces used to create the decoder + */ + LPDIRECT3DSURFACE9 *surface; + + /** + * A bit field configuring the workarounds needed for using the decoder + */ + uint64_t workaround; + + /** + * Private to the FFmpeg AVHWAccel implementation + */ + unsigned report_id; +}; + +/** + * @} + */ + +#endif /* AVCODEC_DXVA2_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/encode.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/encode.c new file mode 100644 index 000000000..d12c42526 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/encode.c @@ -0,0 +1,447 @@ +/* + * generic encoding-related code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/frame.h" +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/samplefmt.h" + +#include "avcodec.h" +#include "frame_thread_encoder.h" +#include "internal.h" + +int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size) +{ + if (avpkt->size < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid negative user packet size %d\n", avpkt->size); + return AVERROR(EINVAL); + } + if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Invalid minimum required packet size %"PRId64" (max allowed is %d)\n", + size, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE); + return AVERROR(EINVAL); + } + + if (avctx && 2*min_size < size) { // FIXME The factor needs to be finetuned + av_assert0(!avpkt->data || avpkt->data != avctx->internal->byte_buffer); + if (!avpkt->data || avpkt->size < size) { + av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size); + avpkt->data = avctx->internal->byte_buffer; + avpkt->size = avctx->internal->byte_buffer_size; + } + } + + if (avpkt->data) { + AVBufferRef *buf = avpkt->buf; + + if (avpkt->size < size) { + av_log(avctx, AV_LOG_ERROR, "User packet is too small (%d < %"PRId64")\n", avpkt->size, size); + return AVERROR(EINVAL); + } + + av_init_packet(avpkt); + avpkt->buf = buf; + avpkt->size = size; + return 0; + } else { + int ret = av_new_packet(avpkt, size); + if (ret < 0) + av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %"PRId64"\n", size); + return ret; + } +} + +int ff_alloc_packet(AVPacket *avpkt, int size) +{ + return ff_alloc_packet2(NULL, avpkt, size, 0); +} + +/** + * Pad last frame with silence. + */ +static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) +{ + AVFrame *frame = NULL; + int ret; + + if (!(frame = av_frame_alloc())) + return AVERROR(ENOMEM); + + frame->format = src->format; + frame->channel_layout = src->channel_layout; + frame->channels = src->channels; + frame->nb_samples = s->frame_size; + ret = av_frame_get_buffer(frame, 32); + if (ret < 0) + goto fail; + + ret = av_frame_copy_props(frame, src); + if (ret < 0) + goto fail; + + if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0, + src->nb_samples, s->channels, s->sample_fmt)) < 0) + goto fail; + if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples, + frame->nb_samples - src->nb_samples, + s->channels, s->sample_fmt)) < 0) + goto fail; + + *dst = frame; + + return 0; + +fail: + av_frame_free(&frame); + return ret; +} + +int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + AVFrame *extended_frame = NULL; + AVFrame *padded_frame = NULL; + int ret; + AVPacket user_pkt = *avpkt; + int needs_realloc = !user_pkt.data; + + *got_packet_ptr = 0; + + if (!avctx->codec->encode2) { + av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); + return AVERROR(ENOSYS); + } + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { + av_packet_unref(avpkt); + return 0; + } + + /* ensure that extended_data is properly set */ + if (frame && !frame->extended_data) { + if (av_sample_fmt_is_planar(avctx->sample_fmt) && + avctx->channels > AV_NUM_DATA_POINTERS) { + av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, " + "with more than %d channels, but extended_data is not set.\n", + AV_NUM_DATA_POINTERS); + return AVERROR(EINVAL); + } + av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n"); + + extended_frame = av_frame_alloc(); + if (!extended_frame) + return AVERROR(ENOMEM); + + memcpy(extended_frame, frame, sizeof(AVFrame)); + extended_frame->extended_data = extended_frame->data; + frame = extended_frame; + } + + /* extract audio service type metadata */ + if (frame) { + AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); + if (sd && sd->size >= sizeof(enum AVAudioServiceType)) + avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; + } + + /* check for valid frame size */ + if (frame) { + if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { + if (frame->nb_samples > avctx->frame_size) { + av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n"); + ret = AVERROR(EINVAL); + goto end; + } + } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { + if (frame->nb_samples < avctx->frame_size && + !avctx->internal->last_audio_frame) { + ret = pad_last_frame(avctx, &padded_frame, frame); + if (ret < 0) + goto end; + + frame = padded_frame; + avctx->internal->last_audio_frame = 1; + } + + if (frame->nb_samples != avctx->frame_size) { + av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d) (avcodec_encode_audio2)\n", frame->nb_samples, avctx->frame_size); + ret = AVERROR(EINVAL); + goto end; + } + } + } + + av_assert0(avctx->codec->encode2); + + ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); + if (!ret) { + if (*got_packet_ptr) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { + if (avpkt->pts == AV_NOPTS_VALUE) + avpkt->pts = frame->pts; + if (!avpkt->duration) + avpkt->duration = ff_samples_to_time_base(avctx, + frame->nb_samples); + } + avpkt->dts = avpkt->pts; + } else { + avpkt->size = 0; + } + } + if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { + needs_realloc = 0; + if (user_pkt.data) { + if (user_pkt.size >= avpkt->size) { + memcpy(user_pkt.data, avpkt->data, avpkt->size); + } else { + av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); + avpkt->size = user_pkt.size; + ret = -1; + } + avpkt->buf = user_pkt.buf; + avpkt->data = user_pkt.data; + } else if (!avpkt->buf) { + ret = av_packet_make_refcounted(avpkt); + if (ret < 0) + goto end; + } + } + + if (!ret) { + if (needs_realloc && avpkt->data) { + ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); + if (ret >= 0) + avpkt->data = avpkt->buf->data; + } + if (frame) + avctx->frame_number++; + } + + if (ret < 0 || !*got_packet_ptr) { + av_packet_unref(avpkt); + goto end; + } + + /* NOTE: if we add any audio encoders which output non-keyframe packets, + * this needs to be moved to the encoders, but for now we can do it + * here to simplify things */ + avpkt->flags |= AV_PKT_FLAG_KEY; + +end: + av_frame_free(&padded_frame); + av_free(extended_frame); + + return ret; +} + +int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + int ret; + AVPacket user_pkt = *avpkt; + int needs_realloc = !user_pkt.data; + + *got_packet_ptr = 0; + + if (!avctx->codec->encode2) { + av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); + return AVERROR(ENOSYS); + } + + if(CONFIG_FRAME_THREAD_ENCODER && + avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME)) + return ff_thread_video_encode_frame(avctx, avpkt, frame, got_packet_ptr); + + if ((avctx->flags&AV_CODEC_FLAG_PASS1) && avctx->stats_out) + avctx->stats_out[0] = '\0'; + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { + av_packet_unref(avpkt); + return 0; + } + + if (av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) + return AVERROR(EINVAL); + + if (frame && frame->format == AV_PIX_FMT_NONE) + av_log(avctx, AV_LOG_WARNING, "AVFrame.format is not set\n"); + if (frame && (frame->width == 0 || frame->height == 0)) + av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n"); + + av_assert0(avctx->codec->encode2); + + ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); + av_assert0(ret <= 0); + + emms_c(); + + if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { + needs_realloc = 0; + if (user_pkt.data) { + if (user_pkt.size >= avpkt->size) { + memcpy(user_pkt.data, avpkt->data, avpkt->size); + } else { + av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); + avpkt->size = user_pkt.size; + ret = -1; + } + avpkt->buf = user_pkt.buf; + avpkt->data = user_pkt.data; + } else if (!avpkt->buf) { + ret = av_packet_make_refcounted(avpkt); + if (ret < 0) + return ret; + } + } + + if (!ret) { + if (!*got_packet_ptr) + avpkt->size = 0; + else if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + avpkt->pts = avpkt->dts = frame->pts; + + if (needs_realloc && avpkt->data) { + ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); + if (ret >= 0) + avpkt->data = avpkt->buf->data; + } + + if (frame) + avctx->frame_number++; + } + + if (ret < 0 || !*got_packet_ptr) + av_packet_unref(avpkt); + + return ret; +} + +int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVSubtitle *sub) +{ + int ret; + if (sub->start_display_time) { + av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); + return -1; + } + + ret = avctx->codec->encode_sub(avctx, buf, buf_size, sub); + avctx->frame_number++; + return ret; +} + +static int do_encode(AVCodecContext *avctx, const AVFrame *frame, int *got_packet) +{ + int ret; + *got_packet = 0; + + av_packet_unref(avctx->internal->buffer_pkt); + avctx->internal->buffer_pkt_valid = 0; + + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + ret = avcodec_encode_video2(avctx, avctx->internal->buffer_pkt, + frame, got_packet); + } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { + ret = avcodec_encode_audio2(avctx, avctx->internal->buffer_pkt, + frame, got_packet); + } else { + ret = AVERROR(EINVAL); + } + + if (ret >= 0 && *got_packet) { + // Encoders must always return ref-counted buffers. + // Side-data only packets have no data and can be not ref-counted. + av_assert0(!avctx->internal->buffer_pkt->data || avctx->internal->buffer_pkt->buf); + avctx->internal->buffer_pkt_valid = 1; + ret = 0; + } else { + av_packet_unref(avctx->internal->buffer_pkt); + } + + return ret; +} + +int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame) +{ + if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avctx->internal->draining) + return AVERROR_EOF; + + if (!frame) { + avctx->internal->draining = 1; + + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + return 0; + } + + if (avctx->codec->send_frame) + return avctx->codec->send_frame(avctx, frame); + + // Emulation via old API. Do it here instead of avcodec_receive_packet, because: + // 1. if the AVFrame is not refcounted, the copying will be much more + // expensive than copying the packet data + // 2. assume few users use non-refcounted AVPackets, so usually no copy is + // needed + + if (avctx->internal->buffer_pkt_valid) + return AVERROR(EAGAIN); + + return do_encode(avctx, frame, &(int){0}); +} + +int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) +{ + av_packet_unref(avpkt); + + if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avctx->codec->receive_packet) { + if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + return AVERROR_EOF; + return avctx->codec->receive_packet(avctx, avpkt); + } + + // Emulation via old API. + + if (!avctx->internal->buffer_pkt_valid) { + int got_packet; + int ret; + if (!avctx->internal->draining) + return AVERROR(EAGAIN); + ret = do_encode(avctx, NULL, &got_packet); + if (ret < 0) + return ret; + if (ret >= 0 && !got_packet) + return AVERROR_EOF; + } + + av_packet_move_ref(avpkt, avctx->internal->buffer_pkt); + avctx->internal->buffer_pkt_valid = 0; + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/error_resilience.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/error_resilience.c new file mode 100644 index 000000000..ca2287198 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/error_resilience.c @@ -0,0 +1,1366 @@ +/* + * Error resilience / concealment + * + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Error resilience / concealment. + */ + +#include + +#include "libavutil/internal.h" +#include "avcodec.h" +#include "error_resilience.h" +#include "me_cmp.h" +#include "mpegutils.h" +#include "mpegvideo.h" +#include "rectangle.h" +#include "thread.h" +#include "version.h" + +/** + * @param stride the number of MVs to get to the next row + * @param mv_step the number of MVs per row or column in a macroblock + */ +static void set_mv_strides(ERContext *s, ptrdiff_t *mv_step, ptrdiff_t *stride) +{ + if (s->avctx->codec_id == AV_CODEC_ID_H264) { + av_assert0(s->quarter_sample); + *mv_step = 4; + *stride = s->mb_width * 4; + } else { + *mv_step = 2; + *stride = s->b8_stride; + } +} + +/** + * Replace the current MB with a flat dc-only version. + */ +static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb, + uint8_t *dest_cr, int mb_x, int mb_y) +{ + int *linesize = s->cur_pic.f->linesize; + int dc, dcu, dcv, y, i; + for (i = 0; i < 4; i++) { + dc = s->dc_val[0][mb_x * 2 + (i & 1) + (mb_y * 2 + (i >> 1)) * s->b8_stride]; + if (dc < 0) + dc = 0; + else if (dc > 2040) + dc = 2040; + for (y = 0; y < 8; y++) { + int x; + for (x = 0; x < 8; x++) + dest_y[x + (i & 1) * 8 + (y + (i >> 1) * 8) * linesize[0]] = dc / 8; + } + } + dcu = s->dc_val[1][mb_x + mb_y * s->mb_stride]; + dcv = s->dc_val[2][mb_x + mb_y * s->mb_stride]; + if (dcu < 0) + dcu = 0; + else if (dcu > 2040) + dcu = 2040; + if (dcv < 0) + dcv = 0; + else if (dcv > 2040) + dcv = 2040; + + if (dest_cr) + for (y = 0; y < 8; y++) { + int x; + for (x = 0; x < 8; x++) { + dest_cb[x + y * linesize[1]] = dcu / 8; + dest_cr[x + y * linesize[2]] = dcv / 8; + } + } +} + +static void filter181(int16_t *data, int width, int height, ptrdiff_t stride) +{ + int x, y; + + /* horizontal filter */ + for (y = 1; y < height - 1; y++) { + int prev_dc = data[0 + y * stride]; + + for (x = 1; x < width - 1; x++) { + int dc; + dc = -prev_dc + + data[x + y * stride] * 8 - + data[x + 1 + y * stride]; + dc = (av_clip(dc, INT_MIN/10923, INT_MAX/10923 - 32768) * 10923 + 32768) >> 16; + prev_dc = data[x + y * stride]; + data[x + y * stride] = dc; + } + } + + /* vertical filter */ + for (x = 1; x < width - 1; x++) { + int prev_dc = data[x]; + + for (y = 1; y < height - 1; y++) { + int dc; + + dc = -prev_dc + + data[x + y * stride] * 8 - + data[x + (y + 1) * stride]; + dc = (av_clip(dc, INT_MIN/10923, INT_MAX/10923 - 32768) * 10923 + 32768) >> 16; + prev_dc = data[x + y * stride]; + data[x + y * stride] = dc; + } + } +} + +/** + * guess the dc of blocks which do not have an undamaged dc + * @param w width in 8 pixel blocks + * @param h height in 8 pixel blocks + */ +static void guess_dc(ERContext *s, int16_t *dc, int w, + int h, ptrdiff_t stride, int is_luma) +{ + int b_x, b_y; + int16_t (*col )[4] = av_malloc_array(stride, h*sizeof( int16_t)*4); + uint32_t (*dist)[4] = av_malloc_array(stride, h*sizeof(uint32_t)*4); + + if(!col || !dist) { + av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n"); + goto fail; + } + + for(b_y=0; b_y>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_x; + } + col [b_x + b_y*stride][1]= color; + dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999; + } + color= 1024; + distance= -1; + for(b_x=w-1; b_x>=0; b_x--){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_x; + } + col [b_x + b_y*stride][0]= color; + dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999; + } + } + for(b_x=0; b_x>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_y; + } + col [b_x + b_y*stride][3]= color; + dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999; + } + color= 1024; + distance= -1; + for(b_y=h-1; b_y>=0; b_y--){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_y; + } + col [b_x + b_y*stride][2]= color; + dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999; + } + } + + for (b_y = 0; b_y < h; b_y++) { + for (b_x = 0; b_x < w; b_x++) { + int mb_index, error, j; + int64_t guess, weight_sum; + mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride; + error = s->error_status_table[mb_index]; + + if (IS_INTER(s->cur_pic.mb_type[mb_index])) + continue; // inter + if (!(error & ER_DC_ERROR)) + continue; // dc-ok + + weight_sum = 0; + guess = 0; + for (j = 0; j < 4; j++) { + int64_t weight = 256 * 256 * 256 * 16 / FFMAX(dist[b_x + b_y*stride][j], 1); + guess += weight*(int64_t)col[b_x + b_y*stride][j]; + weight_sum += weight; + } + guess = (guess + weight_sum / 2) / weight_sum; + dc[b_x + b_y * stride] = guess; + } + } + +fail: + av_freep(&col); + av_freep(&dist); +} + +/** + * simple horizontal deblocking filter used for error resilience + * @param w width in 8 pixel blocks + * @param h height in 8 pixel blocks + */ +static void h_block_filter(ERContext *s, uint8_t *dst, int w, + int h, ptrdiff_t stride, int is_luma) +{ + int b_x, b_y; + ptrdiff_t mvx_stride, mvy_stride; + const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; + set_mv_strides(s, &mvx_stride, &mvy_stride); + mvx_stride >>= is_luma; + mvy_stride *= mvx_stride; + + for (b_y = 0; b_y < h; b_y++) { + for (b_x = 0; b_x < w - 1; b_x++) { + int y; + int left_status = s->error_status_table[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]; + int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]; + int left_intra = IS_INTRA(s->cur_pic.mb_type[( b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]); + int right_intra = IS_INTRA(s->cur_pic.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]); + int left_damage = left_status & ER_MB_ERROR; + int right_damage = right_status & ER_MB_ERROR; + int offset = b_x * 8 + b_y * stride * 8; + int16_t *left_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * b_x]; + int16_t *right_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)]; + if (!(left_damage || right_damage)) + continue; // both undamaged + if ((!left_intra) && (!right_intra) && + FFABS(left_mv[0] - right_mv[0]) + + FFABS(left_mv[1] + right_mv[1]) < 2) + continue; + + for (y = 0; y < 8; y++) { + int a, b, c, d; + + a = dst[offset + 7 + y * stride] - dst[offset + 6 + y * stride]; + b = dst[offset + 8 + y * stride] - dst[offset + 7 + y * stride]; + c = dst[offset + 9 + y * stride] - dst[offset + 8 + y * stride]; + + d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1); + d = FFMAX(d, 0); + if (b < 0) + d = -d; + + if (d == 0) + continue; + + if (!(left_damage && right_damage)) + d = d * 16 / 9; + + if (left_damage) { + dst[offset + 7 + y * stride] = cm[dst[offset + 7 + y * stride] + ((d * 7) >> 4)]; + dst[offset + 6 + y * stride] = cm[dst[offset + 6 + y * stride] + ((d * 5) >> 4)]; + dst[offset + 5 + y * stride] = cm[dst[offset + 5 + y * stride] + ((d * 3) >> 4)]; + dst[offset + 4 + y * stride] = cm[dst[offset + 4 + y * stride] + ((d * 1) >> 4)]; + } + if (right_damage) { + dst[offset + 8 + y * stride] = cm[dst[offset + 8 + y * stride] - ((d * 7) >> 4)]; + dst[offset + 9 + y * stride] = cm[dst[offset + 9 + y * stride] - ((d * 5) >> 4)]; + dst[offset + 10+ y * stride] = cm[dst[offset + 10 + y * stride] - ((d * 3) >> 4)]; + dst[offset + 11+ y * stride] = cm[dst[offset + 11 + y * stride] - ((d * 1) >> 4)]; + } + } + } + } +} + +/** + * simple vertical deblocking filter used for error resilience + * @param w width in 8 pixel blocks + * @param h height in 8 pixel blocks + */ +static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h, + ptrdiff_t stride, int is_luma) +{ + int b_x, b_y; + ptrdiff_t mvx_stride, mvy_stride; + const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; + set_mv_strides(s, &mvx_stride, &mvy_stride); + mvx_stride >>= is_luma; + mvy_stride *= mvx_stride; + + for (b_y = 0; b_y < h - 1; b_y++) { + for (b_x = 0; b_x < w; b_x++) { + int x; + int top_status = s->error_status_table[(b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride]; + int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]; + int top_intra = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ( b_y >> is_luma) * s->mb_stride]); + int bottom_intra = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]); + int top_damage = top_status & ER_MB_ERROR; + int bottom_damage = bottom_status & ER_MB_ERROR; + int offset = b_x * 8 + b_y * stride * 8; + + int16_t *top_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * b_x]; + int16_t *bottom_mv = s->cur_pic.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x]; + + if (!(top_damage || bottom_damage)) + continue; // both undamaged + + if ((!top_intra) && (!bottom_intra) && + FFABS(top_mv[0] - bottom_mv[0]) + + FFABS(top_mv[1] + bottom_mv[1]) < 2) + continue; + + for (x = 0; x < 8; x++) { + int a, b, c, d; + + a = dst[offset + x + 7 * stride] - dst[offset + x + 6 * stride]; + b = dst[offset + x + 8 * stride] - dst[offset + x + 7 * stride]; + c = dst[offset + x + 9 * stride] - dst[offset + x + 8 * stride]; + + d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1); + d = FFMAX(d, 0); + if (b < 0) + d = -d; + + if (d == 0) + continue; + + if (!(top_damage && bottom_damage)) + d = d * 16 / 9; + + if (top_damage) { + dst[offset + x + 7 * stride] = cm[dst[offset + x + 7 * stride] + ((d * 7) >> 4)]; + dst[offset + x + 6 * stride] = cm[dst[offset + x + 6 * stride] + ((d * 5) >> 4)]; + dst[offset + x + 5 * stride] = cm[dst[offset + x + 5 * stride] + ((d * 3) >> 4)]; + dst[offset + x + 4 * stride] = cm[dst[offset + x + 4 * stride] + ((d * 1) >> 4)]; + } + if (bottom_damage) { + dst[offset + x + 8 * stride] = cm[dst[offset + x + 8 * stride] - ((d * 7) >> 4)]; + dst[offset + x + 9 * stride] = cm[dst[offset + x + 9 * stride] - ((d * 5) >> 4)]; + dst[offset + x + 10 * stride] = cm[dst[offset + x + 10 * stride] - ((d * 3) >> 4)]; + dst[offset + x + 11 * stride] = cm[dst[offset + x + 11 * stride] - ((d * 1) >> 4)]; + } + } + } + } +} + +#define MV_FROZEN 8 +#define MV_CHANGED 4 +#define MV_UNCHANGED 2 +#define MV_LISTED 1 +static av_always_inline void add_blocklist(int (*blocklist)[2], int *blocklist_length, uint8_t *fixed, int mb_x, int mb_y, int mb_xy) +{ + if (fixed[mb_xy]) + return; + fixed[mb_xy] = MV_LISTED; + blocklist[ *blocklist_length ][0] = mb_x; + blocklist[(*blocklist_length)++][1] = mb_y; +} + +static void guess_mv(ERContext *s) +{ + int (*blocklist)[2], (*next_blocklist)[2]; + uint8_t *fixed; + const ptrdiff_t mb_stride = s->mb_stride; + const int mb_width = s->mb_width; + int mb_height = s->mb_height; + int i, depth, num_avail; + int mb_x, mb_y; + ptrdiff_t mot_step, mot_stride; + int blocklist_length, next_blocklist_length; + + if (s->last_pic.f && s->last_pic.f->data[0]) + mb_height = FFMIN(mb_height, (s->last_pic.f->height+15)>>4); + if (s->next_pic.f && s->next_pic.f->data[0]) + mb_height = FFMIN(mb_height, (s->next_pic.f->height+15)>>4); + + blocklist = (int (*)[2])s->er_temp_buffer; + next_blocklist = blocklist + s->mb_stride * s->mb_height; + fixed = (uint8_t *)(next_blocklist + s->mb_stride * s->mb_height); + + set_mv_strides(s, &mot_step, &mot_stride); + + num_avail = 0; + if (s->last_pic.motion_val[0]) + ff_thread_await_progress(s->last_pic.tf, mb_height-1, 0); + for (i = 0; i < mb_width * mb_height; i++) { + const int mb_xy = s->mb_index2xy[i]; + int f = 0; + int error = s->error_status_table[mb_xy]; + + if (IS_INTRA(s->cur_pic.mb_type[mb_xy])) + f = MV_FROZEN; // intra // FIXME check + if (!(error & ER_MV_ERROR)) + f = MV_FROZEN; // inter with undamaged MV + + fixed[mb_xy] = f; + if (f == MV_FROZEN) + num_avail++; + else if(s->last_pic.f->data[0] && s->last_pic.motion_val[0]){ + const int mb_y= mb_xy / s->mb_stride; + const int mb_x= mb_xy % s->mb_stride; + const int mot_index= (mb_x + mb_y*mot_stride) * mot_step; + s->cur_pic.motion_val[0][mot_index][0]= s->last_pic.motion_val[0][mot_index][0]; + s->cur_pic.motion_val[0][mot_index][1]= s->last_pic.motion_val[0][mot_index][1]; + s->cur_pic.ref_index[0][4*mb_xy] = s->last_pic.ref_index[0][4*mb_xy]; + } + } + + if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || + num_avail <= FFMAX(mb_width, mb_height) / 2) { + for (mb_y = 0; mb_y < mb_height; mb_y++) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + const int mb_xy = mb_x + mb_y * s->mb_stride; + int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD; + + if (IS_INTRA(s->cur_pic.mb_type[mb_xy])) + continue; + if (!(s->error_status_table[mb_xy] & ER_MV_ERROR)) + continue; + + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv, + mb_x, mb_y, 0, 0); + } + } + return; + } + + blocklist_length = 0; + for (mb_y = 0; mb_y < mb_height; mb_y++) { + for (mb_x = 0; mb_x < mb_width; mb_x++) { + const int mb_xy = mb_x + mb_y * mb_stride; + if (fixed[mb_xy] == MV_FROZEN) { + if (mb_x) add_blocklist(blocklist, &blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1); + if (mb_y) add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride); + if (mb_x+1 < mb_width) add_blocklist(blocklist, &blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1); + if (mb_y+1 < mb_height) add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride); + } + } + } + + for (depth = 0; ; depth++) { + int changed, pass, none_left; + int blocklist_index; + + none_left = 1; + changed = 1; + for (pass = 0; (changed || pass < 2) && pass < 10; pass++) { + int score_sum = 0; + + changed = 0; + for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) { + const int mb_x = blocklist[blocklist_index][0]; + const int mb_y = blocklist[blocklist_index][1]; + const int mb_xy = mb_x + mb_y * mb_stride; + int mv_predictor[8][2]; + int ref[8]; + int pred_count; + int j; + int best_score; + int best_pred; + int mot_index; + int prev_x, prev_y, prev_ref; + + if ((mb_x ^ mb_y ^ pass) & 1) + continue; + av_assert2(fixed[mb_xy] != MV_FROZEN); + + + av_assert1(!IS_INTRA(s->cur_pic.mb_type[mb_xy])); + av_assert1(s->last_pic.f && s->last_pic.f->data[0]); + + j = 0; + if (mb_x > 0) + j |= fixed[mb_xy - 1]; + if (mb_x + 1 < mb_width) + j |= fixed[mb_xy + 1]; + if (mb_y > 0) + j |= fixed[mb_xy - mb_stride]; + if (mb_y + 1 < mb_height) + j |= fixed[mb_xy + mb_stride]; + + av_assert2(j & MV_FROZEN); + + if (!(j & MV_CHANGED) && pass > 1) + continue; + + none_left = 0; + pred_count = 0; + mot_index = (mb_x + mb_y * mot_stride) * mot_step; + + if (mb_x > 0 && fixed[mb_xy - 1] > 1) { + mv_predictor[pred_count][0] = + s->cur_pic.motion_val[0][mot_index - mot_step][0]; + mv_predictor[pred_count][1] = + s->cur_pic.motion_val[0][mot_index - mot_step][1]; + ref[pred_count] = + s->cur_pic.ref_index[0][4 * (mb_xy - 1)]; + pred_count++; + } + if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) { + mv_predictor[pred_count][0] = + s->cur_pic.motion_val[0][mot_index + mot_step][0]; + mv_predictor[pred_count][1] = + s->cur_pic.motion_val[0][mot_index + mot_step][1]; + ref[pred_count] = + s->cur_pic.ref_index[0][4 * (mb_xy + 1)]; + pred_count++; + } + if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) { + mv_predictor[pred_count][0] = + s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][0]; + mv_predictor[pred_count][1] = + s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][1]; + ref[pred_count] = + s->cur_pic.ref_index[0][4 * (mb_xy - s->mb_stride)]; + pred_count++; + } + if (mb_y + 1 1) { + mv_predictor[pred_count][0] = + s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][0]; + mv_predictor[pred_count][1] = + s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][1]; + ref[pred_count] = + s->cur_pic.ref_index[0][4 * (mb_xy + s->mb_stride)]; + pred_count++; + } + if (pred_count == 0) + continue; + + if (pred_count > 1) { + int sum_x = 0, sum_y = 0, sum_r = 0; + int max_x, max_y, min_x, min_y, max_r, min_r; + + for (j = 0; j < pred_count; j++) { + sum_x += mv_predictor[j][0]; + sum_y += mv_predictor[j][1]; + sum_r += ref[j]; + if (j && ref[j] != ref[j - 1]) + goto skip_mean_and_median; + } + + /* mean */ + mv_predictor[pred_count][0] = sum_x / j; + mv_predictor[pred_count][1] = sum_y / j; + ref[pred_count] = sum_r / j; + + /* median */ + if (pred_count >= 3) { + min_y = min_x = min_r = 99999; + max_y = max_x = max_r = -99999; + } else { + min_x = min_y = max_x = max_y = min_r = max_r = 0; + } + for (j = 0; j < pred_count; j++) { + max_x = FFMAX(max_x, mv_predictor[j][0]); + max_y = FFMAX(max_y, mv_predictor[j][1]); + max_r = FFMAX(max_r, ref[j]); + min_x = FFMIN(min_x, mv_predictor[j][0]); + min_y = FFMIN(min_y, mv_predictor[j][1]); + min_r = FFMIN(min_r, ref[j]); + } + mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x; + mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y; + ref[pred_count + 1] = sum_r - max_r - min_r; + + if (pred_count == 4) { + mv_predictor[pred_count + 1][0] /= 2; + mv_predictor[pred_count + 1][1] /= 2; + ref[pred_count + 1] /= 2; + } + pred_count += 2; + } + +skip_mean_and_median: + /* zero MV */ + mv_predictor[pred_count][0] = + mv_predictor[pred_count][1] = + ref[pred_count] = 0; + pred_count++; + + prev_x = s->cur_pic.motion_val[0][mot_index][0]; + prev_y = s->cur_pic.motion_val[0][mot_index][1]; + prev_ref = s->cur_pic.ref_index[0][4 * mb_xy]; + + /* last MV */ + mv_predictor[pred_count][0] = prev_x; + mv_predictor[pred_count][1] = prev_y; + ref[pred_count] = prev_ref; + pred_count++; + + best_pred = 0; + best_score = 256 * 256 * 256 * 64; + for (j = 0; j < pred_count; j++) { + int *linesize = s->cur_pic.f->linesize; + int score = 0; + uint8_t *src = s->cur_pic.f->data[0] + + mb_x * 16 + mb_y * 16 * linesize[0]; + + s->cur_pic.motion_val[0][mot_index][0] = + s->mv[0][0][0] = mv_predictor[j][0]; + s->cur_pic.motion_val[0][mot_index][1] = + s->mv[0][0][1] = mv_predictor[j][1]; + + // predictor intra or otherwise not available + if (ref[j] < 0) + continue; + + s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD, + MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0); + + if (mb_x > 0 && fixed[mb_xy - 1] > 1) { + int k; + for (k = 0; k < 16; k++) + score += FFABS(src[k * linesize[0] - 1] - + src[k * linesize[0]]); + } + if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) { + int k; + for (k = 0; k < 16; k++) + score += FFABS(src[k * linesize[0] + 15] - + src[k * linesize[0] + 16]); + } + if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) { + int k; + for (k = 0; k < 16; k++) + score += FFABS(src[k - linesize[0]] - src[k]); + } + if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] > 1) { + int k; + for (k = 0; k < 16; k++) + score += FFABS(src[k + linesize[0] * 15] - + src[k + linesize[0] * 16]); + } + + if (score <= best_score) { // <= will favor the last MV + best_score = score; + best_pred = j; + } + } + score_sum += best_score; + s->mv[0][0][0] = mv_predictor[best_pred][0]; + s->mv[0][0][1] = mv_predictor[best_pred][1]; + + for (i = 0; i < mot_step; i++) + for (j = 0; j < mot_step; j++) { + s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0]; + s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1]; + } + + s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD, + MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0); + + + if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) { + fixed[mb_xy] = MV_CHANGED; + changed++; + } else + fixed[mb_xy] = MV_UNCHANGED; + } + } + + if (none_left) + return; + + next_blocklist_length = 0; + + for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) { + const int mb_x = blocklist[blocklist_index][0]; + const int mb_y = blocklist[blocklist_index][1]; + const int mb_xy = mb_x + mb_y * mb_stride; + + if (fixed[mb_xy] & (MV_CHANGED|MV_UNCHANGED|MV_FROZEN)) { + fixed[mb_xy] = MV_FROZEN; + if (mb_x > 0) + add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1); + if (mb_y > 0) + add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride); + if (mb_x + 1 < mb_width) + add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1); + if (mb_y + 1 < mb_height) + add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride); + } + } + av_assert0(next_blocklist_length <= mb_height * mb_width); + FFSWAP(int , blocklist_length, next_blocklist_length); + FFSWAP(void*, blocklist, next_blocklist); + } +} + +static int is_intra_more_likely(ERContext *s) +{ + int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y; + + if (!s->last_pic.f || !s->last_pic.f->data[0]) + return 1; // no previous frame available -> use spatial prediction + + if (s->avctx->error_concealment & FF_EC_FAVOR_INTER) + return 0; + + undamaged_count = 0; + for (i = 0; i < s->mb_num; i++) { + const int mb_xy = s->mb_index2xy[i]; + const int error = s->error_status_table[mb_xy]; + if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR))) + undamaged_count++; + } + + if (undamaged_count < 5) + return 0; // almost all MBs damaged -> use temporal prediction + + // prevent dsp.sad() check, that requires access to the image + if (CONFIG_XVMC && + s->avctx->hwaccel && s->avctx->hwaccel->decode_mb && + s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I) + return 1; + + skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs + is_intra_likely = 0; + + j = 0; + for (mb_y = 0; mb_y < s->mb_height - 1; mb_y++) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + int error; + const int mb_xy = mb_x + mb_y * s->mb_stride; + + error = s->error_status_table[mb_xy]; + if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR)) + continue; // skip damaged + + j++; + // skip a few to speed things up + if ((j % skip_amount) != 0) + continue; + + if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I) { + int *linesize = s->cur_pic.f->linesize; + uint8_t *mb_ptr = s->cur_pic.f->data[0] + + mb_x * 16 + mb_y * 16 * linesize[0]; + uint8_t *last_mb_ptr = s->last_pic.f->data[0] + + mb_x * 16 + mb_y * 16 * linesize[0]; + + if (s->avctx->codec_id == AV_CODEC_ID_H264) { + // FIXME + } else { + ff_thread_await_progress(s->last_pic.tf, mb_y, 0); + } + is_intra_likely += s->mecc.sad[0](NULL, last_mb_ptr, mb_ptr, + linesize[0], 16); + // FIXME need await_progress() here + is_intra_likely -= s->mecc.sad[0](NULL, last_mb_ptr, + last_mb_ptr + linesize[0] * 16, + linesize[0], 16); + } else { + if (IS_INTRA(s->cur_pic.mb_type[mb_xy])) + is_intra_likely++; + else + is_intra_likely--; + } + } + } +// av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type); + return is_intra_likely > 0; +} + +void ff_er_frame_start(ERContext *s) +{ + if (!s->avctx->error_concealment) + return; + + if (!s->mecc_inited) { + ff_me_cmp_init(&s->mecc, s->avctx); + s->mecc_inited = 1; + } + + memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END, + s->mb_stride * s->mb_height * sizeof(uint8_t)); + atomic_init(&s->error_count, 3 * s->mb_num); + s->error_occurred = 0; +} + +static int er_supported(ERContext *s) +{ + if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice || + !s->cur_pic.f || + s->cur_pic.field_picture + ) + return 0; + return 1; +} + +/** + * Add a slice. + * @param endx x component of the last macroblock, can be -1 + * for the last of the previous line + * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is + * assumed that no earlier end or error of the same type occurred + */ +void ff_er_add_slice(ERContext *s, int startx, int starty, + int endx, int endy, int status) +{ + const int start_i = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1); + const int end_i = av_clip(endx + endy * s->mb_width, 0, s->mb_num); + const int start_xy = s->mb_index2xy[start_i]; + const int end_xy = s->mb_index2xy[end_i]; + int mask = -1; + + if (s->avctx->hwaccel && s->avctx->hwaccel->decode_slice) + return; + + if (start_i > end_i || start_xy > end_xy) { + av_log(s->avctx, AV_LOG_ERROR, + "internal error, slice end before start\n"); + return; + } + + if (!s->avctx->error_concealment) + return; + + mask &= ~VP_START; + if (status & (ER_AC_ERROR | ER_AC_END)) { + mask &= ~(ER_AC_ERROR | ER_AC_END); + atomic_fetch_add(&s->error_count, start_i - end_i - 1); + } + if (status & (ER_DC_ERROR | ER_DC_END)) { + mask &= ~(ER_DC_ERROR | ER_DC_END); + atomic_fetch_add(&s->error_count, start_i - end_i - 1); + } + if (status & (ER_MV_ERROR | ER_MV_END)) { + mask &= ~(ER_MV_ERROR | ER_MV_END); + atomic_fetch_add(&s->error_count, start_i - end_i - 1); + } + + if (status & ER_MB_ERROR) { + s->error_occurred = 1; + atomic_store(&s->error_count, INT_MAX); + } + + if (mask == ~0x7F) { + memset(&s->error_status_table[start_xy], 0, + (end_xy - start_xy) * sizeof(uint8_t)); + } else { + int i; + for (i = start_xy; i < end_xy; i++) + s->error_status_table[i] &= mask; + } + + if (end_i == s->mb_num) + atomic_store(&s->error_count, INT_MAX); + else { + s->error_status_table[end_xy] &= mask; + s->error_status_table[end_xy] |= status; + } + + s->error_status_table[start_xy] |= VP_START; + + if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) && + er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) { + int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]]; + + prev_status &= ~ VP_START; + if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) { + s->error_occurred = 1; + atomic_store(&s->error_count, INT_MAX); + } + } +} + +void ff_er_frame_end(ERContext *s) +{ + int *linesize = NULL; + int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error; + int distance; + int threshold_part[4] = { 100, 100, 100 }; + int threshold = 50; + int is_intra_likely; + int size = s->b8_stride * 2 * s->mb_height; + + /* We do not support ER of field pictures yet, + * though it should not crash if enabled. */ + if (!s->avctx->error_concealment || !atomic_load(&s->error_count) || + s->avctx->lowres || + !er_supported(s) || + atomic_load(&s->error_count) == 3 * s->mb_width * + (s->avctx->skip_top + s->avctx->skip_bottom)) { + return; + } + linesize = s->cur_pic.f->linesize; + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride]; + if (status != 0x7F) + break; + } + + if ( mb_x == s->mb_width + && s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO + && (FFALIGN(s->avctx->height, 16)&16) + && atomic_load(&s->error_count) == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1) + ) { + av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n"); + return; + } + + if (s->last_pic.f) { + if (s->last_pic.f->width != s->cur_pic.f->width || + s->last_pic.f->height != s->cur_pic.f->height || + s->last_pic.f->format != s->cur_pic.f->format) { + av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n"); + memset(&s->last_pic, 0, sizeof(s->last_pic)); + } + } + if (s->next_pic.f) { + if (s->next_pic.f->width != s->cur_pic.f->width || + s->next_pic.f->height != s->cur_pic.f->height || + s->next_pic.f->format != s->cur_pic.f->format) { + av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n"); + memset(&s->next_pic, 0, sizeof(s->next_pic)); + } + } + + if (!s->cur_pic.motion_val[0] || !s->cur_pic.ref_index[0]) { + av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n"); + + for (i = 0; i < 2; i++) { + s->ref_index_buf[i] = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t)); + s->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t)); + if (!s->ref_index_buf[i] || !s->motion_val_buf[i]) + break; + s->cur_pic.ref_index[i] = s->ref_index_buf[i]->data; + s->cur_pic.motion_val[i] = (int16_t (*)[2])s->motion_val_buf[i]->data + 4; + } + if (i < 2) { + for (i = 0; i < 2; i++) { + av_buffer_unref(&s->ref_index_buf[i]); + av_buffer_unref(&s->motion_val_buf[i]); + s->cur_pic.ref_index[i] = NULL; + s->cur_pic.motion_val[i] = NULL; + } + return; + } + } + + if (s->avctx->debug & FF_DEBUG_ER) { + for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + int status = s->error_status_table[mb_x + mb_y * s->mb_stride]; + + av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status); + } + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + } + +#if 1 + /* handle overlapping slices */ + for (error_type = 1; error_type <= 3; error_type++) { + int end_ok = 0; + + for (i = s->mb_num - 1; i >= 0; i--) { + const int mb_xy = s->mb_index2xy[i]; + int error = s->error_status_table[mb_xy]; + + if (error & (1 << error_type)) + end_ok = 1; + if (error & (8 << error_type)) + end_ok = 1; + + if (!end_ok) + s->error_status_table[mb_xy] |= 1 << error_type; + + if (error & VP_START) + end_ok = 0; + } + } +#endif +#if 1 + /* handle slices with partitions of different length */ + if (s->partitioned_frame) { + int end_ok = 0; + + for (i = s->mb_num - 1; i >= 0; i--) { + const int mb_xy = s->mb_index2xy[i]; + int error = s->error_status_table[mb_xy]; + + if (error & ER_AC_END) + end_ok = 0; + if ((error & ER_MV_END) || + (error & ER_DC_END) || + (error & ER_AC_ERROR)) + end_ok = 1; + + if (!end_ok) + s->error_status_table[mb_xy]|= ER_AC_ERROR; + + if (error & VP_START) + end_ok = 0; + } + } +#endif + /* handle missing slices */ + if (s->avctx->err_recognition & AV_EF_EXPLODE) { + int end_ok = 1; + + // FIXME + 100 hack + for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) { + const int mb_xy = s->mb_index2xy[i]; + int error1 = s->error_status_table[mb_xy]; + int error2 = s->error_status_table[s->mb_index2xy[i + 1]]; + + if (error1 & VP_START) + end_ok = 1; + + if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) && + error1 != (VP_START | ER_MB_ERROR | ER_MB_END) && + ((error1 & ER_AC_END) || (error1 & ER_DC_END) || + (error1 & ER_MV_END))) { + // end & uninit + end_ok = 0; + } + + if (!end_ok) + s->error_status_table[mb_xy] |= ER_MB_ERROR; + } + } + +#if 1 + /* backward mark errors */ + distance = 9999999; + for (error_type = 1; error_type <= 3; error_type++) { + for (i = s->mb_num - 1; i >= 0; i--) { + const int mb_xy = s->mb_index2xy[i]; + int error = s->error_status_table[mb_xy]; + + if (!s->mbskip_table || !s->mbskip_table[mb_xy]) // FIXME partition specific + distance++; + if (error & (1 << error_type)) + distance = 0; + + if (s->partitioned_frame) { + if (distance < threshold_part[error_type - 1]) + s->error_status_table[mb_xy] |= 1 << error_type; + } else { + if (distance < threshold) + s->error_status_table[mb_xy] |= 1 << error_type; + } + + if (error & VP_START) + distance = 9999999; + } + } +#endif + + /* forward mark errors */ + error = 0; + for (i = 0; i < s->mb_num; i++) { + const int mb_xy = s->mb_index2xy[i]; + int old_error = s->error_status_table[mb_xy]; + + if (old_error & VP_START) { + error = old_error & ER_MB_ERROR; + } else { + error |= old_error & ER_MB_ERROR; + s->error_status_table[mb_xy] |= error; + } + } +#if 1 + /* handle not partitioned case */ + if (!s->partitioned_frame) { + for (i = 0; i < s->mb_num; i++) { + const int mb_xy = s->mb_index2xy[i]; + int error = s->error_status_table[mb_xy]; + if (error & ER_MB_ERROR) + error |= ER_MB_ERROR; + s->error_status_table[mb_xy] = error; + } + } +#endif + + dc_error = ac_error = mv_error = 0; + for (i = 0; i < s->mb_num; i++) { + const int mb_xy = s->mb_index2xy[i]; + int error = s->error_status_table[mb_xy]; + if (error & ER_DC_ERROR) + dc_error++; + if (error & ER_AC_ERROR) + ac_error++; + if (error & ER_MV_ERROR) + mv_error++; + } + av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n", + dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic.f->pict_type)); + + s->cur_pic.f->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE; + + is_intra_likely = is_intra_more_likely(s); + + /* set unknown mb-type to most likely */ + for (i = 0; i < s->mb_num; i++) { + const int mb_xy = s->mb_index2xy[i]; + int error = s->error_status_table[mb_xy]; + if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR))) + continue; + + if (is_intra_likely) + s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4; + else + s->cur_pic.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0; + } + + // change inter to intra blocks if no reference frames are available + if (!(s->last_pic.f && s->last_pic.f->data[0]) && + !(s->next_pic.f && s->next_pic.f->data[0])) + for (i = 0; i < s->mb_num; i++) { + const int mb_xy = s->mb_index2xy[i]; + if (!IS_INTRA(s->cur_pic.mb_type[mb_xy])) + s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4; + } + + /* handle inter blocks with damaged AC */ + for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + const int mb_xy = mb_x + mb_y * s->mb_stride; + const int mb_type = s->cur_pic.mb_type[mb_xy]; + const int dir = !(s->last_pic.f && s->last_pic.f->data[0]); + const int mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD; + int mv_type; + + int error = s->error_status_table[mb_xy]; + + if (IS_INTRA(mb_type)) + continue; // intra + if (error & ER_MV_ERROR) + continue; // inter with damaged MV + if (!(error & ER_AC_ERROR)) + continue; // undamaged inter + + if (IS_8X8(mb_type)) { + int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride; + int j; + mv_type = MV_TYPE_8X8; + for (j = 0; j < 4; j++) { + s->mv[0][j][0] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0]; + s->mv[0][j][1] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1]; + } + } else { + mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0]; + s->mv[0][0][1] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1]; + } + + s->decode_mb(s->opaque, 0 /* FIXME H.264 partitioned slices need this set */, + mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0); + } + } + + /* guess MVs */ + if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_B) { + for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + int xy = mb_x * 2 + mb_y * 2 * s->b8_stride; + const int mb_xy = mb_x + mb_y * s->mb_stride; + const int mb_type = s->cur_pic.mb_type[mb_xy]; + int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; + + int error = s->error_status_table[mb_xy]; + + if (IS_INTRA(mb_type)) + continue; + if (!(error & ER_MV_ERROR)) + continue; // inter with undamaged MV + if (!(error & ER_AC_ERROR)) + continue; // undamaged inter + + if (!(s->last_pic.f && s->last_pic.f->data[0])) + mv_dir &= ~MV_DIR_FORWARD; + if (!(s->next_pic.f && s->next_pic.f->data[0])) + mv_dir &= ~MV_DIR_BACKWARD; + + if (s->pp_time) { + int time_pp = s->pp_time; + int time_pb = s->pb_time; + + av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264); + ff_thread_await_progress(s->next_pic.tf, mb_y, 0); + + s->mv[0][0][0] = s->next_pic.motion_val[0][xy][0] * time_pb / time_pp; + s->mv[0][0][1] = s->next_pic.motion_val[0][xy][1] * time_pb / time_pp; + s->mv[1][0][0] = s->next_pic.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp; + s->mv[1][0][1] = s->next_pic.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp; + } else { + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mv[1][0][0] = 0; + s->mv[1][0][1] = 0; + } + + s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv, + mb_x, mb_y, 0, 0); + } + } + } else + guess_mv(s); + + /* the filters below manipulate raw image, skip them */ + if (CONFIG_XVMC && s->avctx->hwaccel && s->avctx->hwaccel->decode_mb) + goto ec_clean; + /* fill DC for inter blocks */ + for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + int dc, dcu, dcv, y, n; + int16_t *dc_ptr; + uint8_t *dest_y, *dest_cb, *dest_cr; + const int mb_xy = mb_x + mb_y * s->mb_stride; + const int mb_type = s->cur_pic.mb_type[mb_xy]; + + // error = s->error_status_table[mb_xy]; + + if (IS_INTRA(mb_type) && s->partitioned_frame) + continue; + // if (error & ER_MV_ERROR) + // continue; // inter data damaged FIXME is this good? + + dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0]; + dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1]; + dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2]; + + dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride]; + for (n = 0; n < 4; n++) { + dc = 0; + for (y = 0; y < 8; y++) { + int x; + for (x = 0; x < 8; x++) + dc += dest_y[x + (n & 1) * 8 + + (y + (n >> 1) * 8) * linesize[0]]; + } + dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3; + } + + if (!s->cur_pic.f->data[2]) + continue; + + dcu = dcv = 0; + for (y = 0; y < 8; y++) { + int x; + for (x = 0; x < 8; x++) { + dcu += dest_cb[x + y * linesize[1]]; + dcv += dest_cr[x + y * linesize[2]]; + } + } + s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3; + s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3; + } + } +#if 1 + /* guess DC for damaged blocks */ + guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1); + guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0); + guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0); +#endif + + /* filter luma DC */ + filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride); + +#if 1 + /* render DC only intra */ + for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + uint8_t *dest_y, *dest_cb, *dest_cr; + const int mb_xy = mb_x + mb_y * s->mb_stride; + const int mb_type = s->cur_pic.mb_type[mb_xy]; + + int error = s->error_status_table[mb_xy]; + + if (IS_INTER(mb_type)) + continue; + if (!(error & ER_AC_ERROR)) + continue; // undamaged + + dest_y = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0]; + dest_cb = s->cur_pic.f->data[1] + mb_x * 8 + mb_y * 8 * linesize[1]; + dest_cr = s->cur_pic.f->data[2] + mb_x * 8 + mb_y * 8 * linesize[2]; + if (!s->cur_pic.f->data[2]) + dest_cb = dest_cr = NULL; + + put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y); + } + } +#endif + + if (s->avctx->error_concealment & FF_EC_DEBLOCK) { + /* filter horizontal block boundaries */ + h_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2, + s->mb_height * 2, linesize[0], 1); + + /* filter vertical block boundaries */ + v_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2, + s->mb_height * 2, linesize[0], 1); + + if (s->cur_pic.f->data[2]) { + h_block_filter(s, s->cur_pic.f->data[1], s->mb_width, + s->mb_height, linesize[1], 0); + h_block_filter(s, s->cur_pic.f->data[2], s->mb_width, + s->mb_height, linesize[2], 0); + v_block_filter(s, s->cur_pic.f->data[1], s->mb_width, + s->mb_height, linesize[1], 0); + v_block_filter(s, s->cur_pic.f->data[2], s->mb_width, + s->mb_height, linesize[2], 0); + } + } + +ec_clean: + /* clean a few tables */ + for (i = 0; i < s->mb_num; i++) { + const int mb_xy = s->mb_index2xy[i]; + int error = s->error_status_table[mb_xy]; + + if (s->mbskip_table && s->cur_pic.f->pict_type != AV_PICTURE_TYPE_B && + (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) { + s->mbskip_table[mb_xy] = 0; + } + if (s->mbintra_table) + s->mbintra_table[mb_xy] = 1; + } + + for (i = 0; i < 2; i++) { + av_buffer_unref(&s->ref_index_buf[i]); + av_buffer_unref(&s->motion_val_buf[i]); + s->cur_pic.ref_index[i] = NULL; + s->cur_pic.motion_val[i] = NULL; + } + + memset(&s->cur_pic, 0, sizeof(ERPicture)); + memset(&s->last_pic, 0, sizeof(ERPicture)); + memset(&s->next_pic, 0, sizeof(ERPicture)); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/error_resilience.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/error_resilience.h new file mode 100644 index 000000000..664a76565 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/error_resilience.h @@ -0,0 +1,97 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_ERROR_RESILIENCE_H +#define AVCODEC_ERROR_RESILIENCE_H + +#include +#include + +#include "avcodec.h" +#include "me_cmp.h" +#include "thread.h" + +///< current MB is the first after a resync marker +#define VP_START 1 +#define ER_AC_ERROR 2 +#define ER_DC_ERROR 4 +#define ER_MV_ERROR 8 +#define ER_AC_END 16 +#define ER_DC_END 32 +#define ER_MV_END 64 + +#define ER_MB_ERROR (ER_AC_ERROR|ER_DC_ERROR|ER_MV_ERROR) +#define ER_MB_END (ER_AC_END|ER_DC_END|ER_MV_END) + +typedef struct ERPicture { + AVFrame *f; + ThreadFrame *tf; + + // it is the caller's responsibility to allocate these buffers + int16_t (*motion_val[2])[2]; + int8_t *ref_index[2]; + + uint32_t *mb_type; + int field_picture; +} ERPicture; + +typedef struct ERContext { + AVCodecContext *avctx; + MECmpContext mecc; + int mecc_inited; + + int *mb_index2xy; + int mb_num; + int mb_width, mb_height; + ptrdiff_t mb_stride; + ptrdiff_t b8_stride; + + atomic_int error_count; + int error_occurred; + uint8_t *error_status_table; + uint8_t *er_temp_buffer; + int16_t *dc_val[3]; + uint8_t *mbskip_table; + uint8_t *mbintra_table; + int mv[2][4][2]; + + ERPicture cur_pic; + ERPicture last_pic; + ERPicture next_pic; + + AVBufferRef *ref_index_buf[2]; + AVBufferRef *motion_val_buf[2]; + + uint16_t pp_time; + uint16_t pb_time; + int quarter_sample; + int partitioned_frame; + int ref_count; + + void (*decode_mb)(void *opaque, int ref, int mv_dir, int mv_type, + int (*mv)[2][4][2], + int mb_x, int mb_y, int mb_intra, int mb_skipped); + void *opaque; +} ERContext; + +void ff_er_frame_start(ERContext *s); +void ff_er_frame_end(ERContext *s); +void ff_er_add_slice(ERContext *s, int startx, int starty, int endx, int endy, + int status); + +#endif /* AVCODEC_ERROR_RESILIENCE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fdctdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fdctdsp.h new file mode 100644 index 000000000..3e1f683b9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fdctdsp.h @@ -0,0 +1,37 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_FDCTDSP_H +#define AVCODEC_FDCTDSP_H + +#include + +#include "avcodec.h" + +typedef struct FDCTDSPContext { + void (*fdct)(int16_t *block /* align 16 */); + void (*fdct248)(int16_t *block /* align 16 */); +} FDCTDSPContext; + +void ff_fdctdsp_init(FDCTDSPContext *c, AVCodecContext *avctx); +void ff_fdctdsp_init_ppc(FDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_fdctdsp_init_x86(FDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); + +#endif /* AVCODEC_FDCTDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft-internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft-internal.h new file mode 100644 index 000000000..0a8f7d05c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft-internal.h @@ -0,0 +1,94 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_FFT_INTERNAL_H +#define AVCODEC_FFT_INTERNAL_H + +#if FFT_FLOAT + +#define FIX15(v) (v) +#define sqrthalf (float)M_SQRT1_2 + +#define BF(x, y, a, b) do { \ + x = a - b; \ + y = a + b; \ + } while (0) + +#define CMUL(dre, dim, are, aim, bre, bim) do { \ + (dre) = (are) * (bre) - (aim) * (bim); \ + (dim) = (are) * (bim) + (aim) * (bre); \ + } while (0) + +#else + +#define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits))) + +#if FFT_FIXED_32 + +#define CMUL(dre, dim, are, aim, bre, bim) do { \ + int64_t accu; \ + (accu) = (int64_t)(bre) * (are); \ + (accu) -= (int64_t)(bim) * (aim); \ + (dre) = (int)(((accu) + 0x40000000) >> 31); \ + (accu) = (int64_t)(bre) * (aim); \ + (accu) += (int64_t)(bim) * (are); \ + (dim) = (int)(((accu) + 0x40000000) >> 31); \ + } while (0) + +#define FIX15(a) av_clip(SCALE_FLOAT(a, 31), -2147483647, 2147483647) + +#else /* FFT_FIXED_32 */ + +#include "fft.h" +#include "mathops.h" + +void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input); + +#define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767) + +#define sqrthalf ((int16_t)((1<<15)*M_SQRT1_2)) + +#define BF(x, y, a, b) do { \ + x = (a - b) >> 1; \ + y = (a + b) >> 1; \ + } while (0) + +#define CMULS(dre, dim, are, aim, bre, bim, sh) do { \ + (dre) = (MUL16(are, bre) - MUL16(aim, bim)) >> sh; \ + (dim) = (MUL16(are, bim) + MUL16(aim, bre)) >> sh; \ + } while (0) + +#define CMUL(dre, dim, are, aim, bre, bim) \ + CMULS(dre, dim, are, aim, bre, bim, 15) + +#define CMULL(dre, dim, are, aim, bre, bim) \ + CMULS(dre, dim, are, aim, bre, bim, 0) + +#endif /* FFT_FIXED_32 */ + +#endif /* FFT_FLOAT */ + +#define ff_imdct_calc_c FFT_NAME(ff_imdct_calc_c) +#define ff_imdct_half_c FFT_NAME(ff_imdct_half_c) +#define ff_mdct_calc_c FFT_NAME(ff_mdct_calc_c) + +void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_mdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input); + +#endif /* AVCODEC_FFT_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft.h new file mode 100644 index 000000000..c858570a2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_FFT_H +#define AVCODEC_FFT_H + +#ifndef FFT_FLOAT +#define FFT_FLOAT 1 +#endif + +#ifndef FFT_FIXED_32 +#define FFT_FIXED_32 0 +#endif + +#include +#include "config.h" +#include "libavutil/mem.h" + +#if FFT_FLOAT + +#include "avfft.h" + +#define FFT_NAME(x) x + +typedef float FFTDouble; + +#else + +#if FFT_FIXED_32 + +#define Q31(x) (int)((x)*2147483648.0 + 0.5) +#define FFT_NAME(x) x ## _fixed_32 + +typedef int32_t FFTSample; + +#else /* FFT_FIXED_32 */ + +#define FFT_NAME(x) x ## _fixed + +typedef int16_t FFTSample; + +#endif /* FFT_FIXED_32 */ + +typedef struct FFTComplex { + FFTSample re, im; +} FFTComplex; + +typedef int FFTDouble; +typedef struct FFTContext FFTContext; + +#endif /* FFT_FLOAT */ + +typedef struct FFTDComplex { + FFTDouble re, im; +} FFTDComplex; + +/* FFT computation */ + +enum fft_permutation_type { + FF_FFT_PERM_DEFAULT, + FF_FFT_PERM_SWAP_LSBS, + FF_FFT_PERM_AVX, +}; + +enum mdct_permutation_type { + FF_MDCT_PERM_NONE, + FF_MDCT_PERM_INTERLEAVE, +}; + +struct FFTContext { + int nbits; + int inverse; + uint16_t *revtab; + FFTComplex *tmp_buf; + int mdct_size; /* size of MDCT (i.e. number of input data * 2) */ + int mdct_bits; /* n = 2^nbits */ + /* pre/post rotation tables */ + FFTSample *tcos; + FFTSample *tsin; + /** + * Do the permutation needed BEFORE calling fft_calc(). + */ + void (*fft_permute)(struct FFTContext *s, FFTComplex *z); + /** + * Do a complex FFT with the parameters defined in ff_fft_init(). The + * input data must be permuted before. No 1.0/sqrt(n) normalization is done. + */ + void (*fft_calc)(struct FFTContext *s, FFTComplex *z); + void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); + void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input); + void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); + void (*mdct_calcw)(struct FFTContext *s, FFTDouble *output, const FFTSample *input); + enum fft_permutation_type fft_permutation; + enum mdct_permutation_type mdct_permutation; + uint32_t *revtab32; +}; + +#if CONFIG_HARDCODED_TABLES +#define COSTABLE_CONST const +#else +#define COSTABLE_CONST +#endif + +#define COSTABLE(size) \ + COSTABLE_CONST DECLARE_ALIGNED(32, FFTSample, FFT_NAME(ff_cos_##size))[size/2] + +extern COSTABLE(16); +extern COSTABLE(32); +extern COSTABLE(64); +extern COSTABLE(128); +extern COSTABLE(256); +extern COSTABLE(512); +extern COSTABLE(1024); +extern COSTABLE(2048); +extern COSTABLE(4096); +extern COSTABLE(8192); +extern COSTABLE(16384); +extern COSTABLE(32768); +extern COSTABLE(65536); +extern COSTABLE(131072); +extern COSTABLE_CONST FFTSample* const FFT_NAME(ff_cos_tabs)[18]; + +#define ff_init_ff_cos_tabs FFT_NAME(ff_init_ff_cos_tabs) + +/** + * Initialize the cosine table in ff_cos_tabs[index] + * @param index index in ff_cos_tabs array of the table to initialize + */ +void ff_init_ff_cos_tabs(int index); + +#define ff_fft_init FFT_NAME(ff_fft_init) +#define ff_fft_end FFT_NAME(ff_fft_end) + +/** + * Set up a complex FFT. + * @param nbits log2 of the length of the input array + * @param inverse if 0 perform the forward transform, if 1 perform the inverse + */ +int ff_fft_init(FFTContext *s, int nbits, int inverse); + +void ff_fft_init_aarch64(FFTContext *s); +void ff_fft_init_x86(FFTContext *s); +void ff_fft_init_arm(FFTContext *s); +void ff_fft_init_mips(FFTContext *s); +void ff_fft_init_ppc(FFTContext *s); + +void ff_fft_fixed_init_arm(FFTContext *s); + +void ff_fft_end(FFTContext *s); + +#define ff_mdct_init FFT_NAME(ff_mdct_init) +#define ff_mdct_end FFT_NAME(ff_mdct_end) + +int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale); +void ff_mdct_end(FFTContext *s); + +#endif /* AVCODEC_FFT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_fixed.c new file mode 100644 index 000000000..3d3bd2fca --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_fixed.c @@ -0,0 +1,21 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define FFT_FLOAT 0 +#define FFT_FIXED_32 0 +#include "fft_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_fixed_32.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_fixed_32.c new file mode 100644 index 000000000..fbdbf847e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_fixed_32.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Authors: Stanislav Ocovaj (socovaj@mips.com) + * Goran Cordasic (goran@mips.com) + * Djordje Pesut (djordje@mips.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define FFT_FLOAT 0 +#define FFT_FIXED_32 1 +#include "fft_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_float.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_float.c new file mode 100644 index 000000000..73cc98d0d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_float.c @@ -0,0 +1,21 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define FFT_FLOAT 1 +#define FFT_FIXED_32 0 +#include "fft_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_init.c new file mode 100644 index 000000000..928f1dcda --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_init.c @@ -0,0 +1,61 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" + +#include "fft.h" + +av_cold void ff_fft_init_x86(FFTContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (s->nbits > 16) + return; + +#if ARCH_X86_32 + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + s->imdct_calc = ff_imdct_calc_3dnow; + s->imdct_half = ff_imdct_half_3dnow; + s->fft_calc = ff_fft_calc_3dnow; + } + + if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) { + s->imdct_calc = ff_imdct_calc_3dnowext; + s->imdct_half = ff_imdct_half_3dnowext; + s->fft_calc = ff_fft_calc_3dnowext; + } +#endif /* ARCH_X86_32 */ + + if (EXTERNAL_SSE(cpu_flags)) { + s->imdct_calc = ff_imdct_calc_sse; + s->imdct_half = ff_imdct_half_sse; + s->fft_permute = ff_fft_permute_sse; + s->fft_calc = ff_fft_calc_sse; + s->fft_permutation = FF_FFT_PERM_SWAP_LSBS; + } + + if (EXTERNAL_AVX_FAST(cpu_flags) && s->nbits >= 5) { + s->imdct_half = ff_imdct_half_avx; + s->fft_calc = ff_fft_calc_avx; + s->fft_permutation = FF_FFT_PERM_AVX; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_init_table.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_init_table.c new file mode 100644 index 000000000..c488018f6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_init_table.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Authors: Stanislav Ocovaj (socovaj@mips.com) + * Goran Cordasic (goran@mips.com) + * Djordje Pesut (djordje@mips.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * definitions and initialization of LUT table for FFT + */ +#include "libavcodec/fft_table.h" + +const int32_t ff_w_tab_sr[MAX_FFT_SIZE/(4*16)] = { +2147483647, 2147483016, 2147481121, 2147477963, 2147473542, 2147467857, 2147460908, 2147452697, +2147443222, 2147432484, 2147420483, 2147407218, 2147392690, 2147376899, 2147359845, 2147341527, +2147321946, 2147301102, 2147278995, 2147255625, 2147230991, 2147205094, 2147177934, 2147149511, +2147119825, 2147088876, 2147056664, 2147023188, 2146988450, 2146952448, 2146915184, 2146876656, +2146836866, 2146795813, 2146753497, 2146709917, 2146665076, 2146618971, 2146571603, 2146522973, +2146473080, 2146421924, 2146369505, 2146315824, 2146260881, 2146204674, 2146147205, 2146088474, +2146028480, 2145967224, 2145904705, 2145840924, 2145775880, 2145709574, 2145642006, 2145573176, +2145503083, 2145431729, 2145359112, 2145285233, 2145210092, 2145133690, 2145056025, 2144977098, +2144896910, 2144815460, 2144732748, 2144648774, 2144563539, 2144477042, 2144389283, 2144300264, +2144209982, 2144118439, 2144025635, 2143931570, 2143836244, 2143739656, 2143641807, 2143542697, +2143442326, 2143340694, 2143237802, 2143133648, 2143028234, 2142921559, 2142813624, 2142704427, +2142593971, 2142482254, 2142369276, 2142255039, 2142139541, 2142022783, 2141904764, 2141785486, +2141664948, 2141543150, 2141420092, 2141295774, 2141170197, 2141043360, 2140915264, 2140785908, +2140655293, 2140523418, 2140390284, 2140255892, 2140120240, 2139983329, 2139845159, 2139705730, +2139565043, 2139423097, 2139279892, 2139135429, 2138989708, 2138842728, 2138694490, 2138544994, +2138394240, 2138242228, 2138088958, 2137934430, 2137778644, 2137621601, 2137463301, 2137303743, +2137142927, 2136980855, 2136817525, 2136652938, 2136487095, 2136319994, 2136151637, 2135982023, +2135811153, 2135639026, 2135465642, 2135291003, 2135115107, 2134937956, 2134759548, 2134579885, +2134398966, 2134216791, 2134033361, 2133848675, 2133662734, 2133475538, 2133287087, 2133097381, +2132906420, 2132714204, 2132520734, 2132326009, 2132130030, 2131932796, 2131734309, 2131534567, +2131333572, 2131131322, 2130927819, 2130723062, 2130517052, 2130309789, 2130101272, 2129891502, +2129680480, 2129468204, 2129254676, 2129039895, 2128823862, 2128606576, 2128388038, 2128168248, +2127947206, 2127724913, 2127501367, 2127276570, 2127050522, 2126823222, 2126594672, 2126364870, +2126133817, 2125901514, 2125667960, 2125433155, 2125197100, 2124959795, 2124721240, 2124481435, +2124240380, 2123998076, 2123754522, 2123509718, 2123263666, 2123016364, 2122767814, 2122518015, +2122266967, 2122014670, 2121761126, 2121506333, 2121250292, 2120993003, 2120734467, 2120474683, +2120213651, 2119951372, 2119687847, 2119423074, 2119157054, 2118889788, 2118621275, 2118351516, +2118080511, 2117808259, 2117534762, 2117260020, 2116984031, 2116706797, 2116428319, 2116148595, +2115867626, 2115585412, 2115301954, 2115017252, 2114731305, 2114444114, 2114155680, 2113866001, +2113575080, 2113282914, 2112989506, 2112694855, 2112398960, 2112101824, 2111803444, 2111503822, +2111202959, 2110900853, 2110597505, 2110292916, 2109987085, 2109680013, 2109371700, 2109062146, +2108751352, 2108439317, 2108126041, 2107811526, 2107495770, 2107178775, 2106860540, 2106541065, +2106220352, 2105898399, 2105575208, 2105250778, 2104925109, 2104598202, 2104270057, 2103940674, +2103610054, 2103278196, 2102945101, 2102610768, 2102275199, 2101938393, 2101600350, 2101261071, +2100920556, 2100578805, 2100235819, 2099891596, 2099546139, 2099199446, 2098851519, 2098502357, +2098151960, 2097800329, 2097447464, 2097093365, 2096738032, 2096381466, 2096023667, 2095664635, +2095304370, 2094942872, 2094580142, 2094216179, 2093850985, 2093484559, 2093116901, 2092748012, +2092377892, 2092006541, 2091633960, 2091260147, 2090885105, 2090508833, 2090131331, 2089752599, +2089372638, 2088991448, 2088609029, 2088225381, 2087840505, 2087454400, 2087067068, 2086678508, +2086288720, 2085897705, 2085505463, 2085111994, 2084717298, 2084321376, 2083924228, 2083525854, +2083126254, 2082725429, 2082323379, 2081920103, 2081515603, 2081109879, 2080702930, 2080294757, +2079885360, 2079474740, 2079062896, 2078649830, 2078235540, 2077820028, 2077403294, 2076985338, +2076566160, 2076145760, 2075724139, 2075301296, 2074877233, 2074451950, 2074025446, 2073597721, +2073168777, 2072738614, 2072307231, 2071874629, 2071440808, 2071005769, 2070569511, 2070132035, +2069693342, 2069253430, 2068812302, 2068369957, 2067926394, 2067481616, 2067035621, 2066588410, +2066139983, 2065690341, 2065239484, 2064787411, 2064334124, 2063879623, 2063423908, 2062966978, +2062508835, 2062049479, 2061588910, 2061127128, 2060664133, 2060199927, 2059734508, 2059267877, +2058800036, 2058330983, 2057860719, 2057389244, 2056916560, 2056442665, 2055967560, 2055491246, +2055013723, 2054534991, 2054055050, 2053573901, 2053091544, 2052607979, 2052123207, 2051637227, +2051150040, 2050661647, 2050172048, 2049681242, 2049189231, 2048696014, 2048201592, 2047705965, +2047209133, 2046711097, 2046211857, 2045711414, 2045209767, 2044706916, 2044202863, 2043697608, +2043191150, 2042683490, 2042174628, 2041664565, 2041153301, 2040640837, 2040127172, 2039612306, +2039096241, 2038578976, 2038060512, 2037540850, 2037019988, 2036497928, 2035974670, 2035450215, +2034924562, 2034397712, 2033869665, 2033340422, 2032809982, 2032278347, 2031745516, 2031211490, +2030676269, 2030139853, 2029602243, 2029063439, 2028523442, 2027982251, 2027439867, 2026896291, +2026351522, 2025805561, 2025258408, 2024710064, 2024160529, 2023609803, 2023057887, 2022504780, +2021950484, 2021394998, 2020838323, 2020280460, 2019721407, 2019161167, 2018599739, 2018037123, +2017473321, 2016908331, 2016342155, 2015774793, 2015206245, 2014636511, 2014065592, 2013493489, +2012920201, 2012345729, 2011770073, 2011193233, 2010615210, 2010036005, 2009455617, 2008874047, +2008291295, 2007707362, 2007122248, 2006535953, 2005948478, 2005359822, 2004769987, 2004178973, +2003586779, 2002993407, 2002398857, 2001803128, 2001206222, 2000608139, 2000008879, 1999408442, +1998806829, 1998204040, 1997600076, 1996994937, 1996388622, 1995781134, 1995172471, 1994562635, +1993951625, 1993339442, 1992726087, 1992111559, 1991495860, 1990878989, 1990260946, 1989641733, +1989021350, 1988399796, 1987777073, 1987153180, 1986528118, 1985901888, 1985274489, 1984645923, +1984016189, 1983385288, 1982753220, 1982119985, 1981485585, 1980850019, 1980213288, 1979575392, +1978936331, 1978296106, 1977654717, 1977012165, 1976368450, 1975723572, 1975077532, 1974430331, +1973781967, 1973132443, 1972481757, 1971829912, 1971176906, 1970522741, 1969867417, 1969210933, +1968553292, 1967894492, 1967234535, 1966573420, 1965911148, 1965247720, 1964583136, 1963917396, +1963250501, 1962582451, 1961913246, 1961242888, 1960571375, 1959898709, 1959224890, 1958549919, +1957873796, 1957196520, 1956518093, 1955838516, 1955157788, 1954475909, 1953792881, 1953108703, +1952423377, 1951736902, 1951049279, 1950360508, 1949670589, 1948979524, 1948287312, 1947593954, +1946899451, 1946203802, 1945507008, 1944809070, 1944109987, 1943409761, 1942708392, 1942005880, +1941302225, 1940597428, 1939891490, 1939184411, 1938476190, 1937766830, 1937056329, 1936344689, +1935631910, 1934917992, 1934202936, 1933486742, 1932769411, 1932050943, 1931331338, 1930610597, +1929888720, 1929165708, 1928441561, 1927716279, 1926989864, 1926262315, 1925533633, 1924803818, +1924072871, 1923340791, 1922607581, 1921873239, 1921137767, 1920401165, 1919663432, 1918924571, +1918184581, 1917443462, 1916701216, 1915957841, 1915213340, 1914467712, 1913720958, 1912973078, +1912224073, 1911473942, 1910722688, 1909970309, 1909216806, 1908462181, 1907706433, 1906949562, +1906191570, 1905432457, 1904672222, 1903910867, 1903148392, 1902384797, 1901620084, 1900854251, +1900087301, 1899319232, 1898550047, 1897779744, 1897008325, 1896235790, 1895462140, 1894687374, +1893911494, 1893134500, 1892356392, 1891577171, 1890796837, 1890015391, 1889232832, 1888449163, +1887664383, 1886878492, 1886091491, 1885303381, 1884514161, 1883723833, 1882932397, 1882139853, +1881346202, 1880551444, 1879755580, 1878958610, 1878160535, 1877361354, 1876561070, 1875759681, +1874957189, 1874153594, 1873348897, 1872543097, 1871736196, 1870928194, 1870119091, 1869308888, +1868497586, 1867685184, 1866871683, 1866057085, 1865241388, 1864424594, 1863606704, 1862787717, +1861967634, 1861146456, 1860324183, 1859500816, 1858676355, 1857850800, 1857024153, 1856196413, +1855367581, 1854537657, 1853706643, 1852874538, 1852041343, 1851207059, 1850371686, 1849535224, +1848697674, 1847859036, 1847019312, 1846178501, 1845336604, 1844493621, 1843649553, 1842804401, +1841958164, 1841110844, 1840262441, 1839412956, 1838562388, 1837710739, 1836858008, 1836004197, +1835149306, 1834293336, 1833436286, 1832578158, 1831718951, 1830858668, 1829997307, 1829134869, +1828271356, 1827406767, 1826541103, 1825674364, 1824806552, 1823937666, 1823067707, 1822196675, +1821324572, 1820451397, 1819577151, 1818701835, 1817825449, 1816947994, 1816069469, 1815189877, +1814309216, 1813427489, 1812544694, 1811660833, 1810775906, 1809889915, 1809002858, 1808114737, +1807225553, 1806335305, 1805443995, 1804551623, 1803658189, 1802763694, 1801868139, 1800971523, +1800073849, 1799175115, 1798275323, 1797374472, 1796472565, 1795569601, 1794665580, 1793760504, +1792854372, 1791947186, 1791038946, 1790129652, 1789219305, 1788307905, 1787395453, 1786481950, +1785567396, 1784651792, 1783735137, 1782817434, 1781898681, 1780978881, 1780058032, 1779136137, +1778213194, 1777289206, 1776364172, 1775438094, 1774510970, 1773582803, 1772653593, 1771723340, +1770792044, 1769859707, 1768926328, 1767991909, 1767056450, 1766119952, 1765182414, 1764243838, +1763304224, 1762363573, 1761421885, 1760479161, 1759535401, 1758590607, 1757644777, 1756697914, +1755750017, 1754801087, 1753851126, 1752900132, 1751948107, 1750995052, 1750040966, 1749085851, +1748129707, 1747172535, 1746214334, 1745255107, 1744294853, 1743333573, 1742371267, 1741407936, +1740443581, 1739478202, 1738511799, 1737544374, 1736575927, 1735606458, 1734635968, 1733664458, +1732691928, 1731718378, 1730743810, 1729768224, 1728791620, 1727813999, 1726835361, 1725855708, +1724875040, 1723893357, 1722910659, 1721926948, 1720942225, 1719956488, 1718969740, 1717981981, +1716993211, 1716003431, 1715012642, 1714020844, 1713028037, 1712034223, 1711039401, 1710043573, +1709046739, 1708048900, 1707050055, 1706050207, 1705049355, 1704047500, 1703044642, 1702040783, +1701035922, 1700030061, 1699023199, 1698015339, 1697006479, 1695996621, 1694985765, 1693973912, +1692961062, 1691947217, 1690932376, 1689916541, 1688899711, 1687881888, 1686863072, 1685843263, +1684822463, 1683800672, 1682777890, 1681754118, 1680729357, 1679703608, 1678676870, 1677649144, +1676620432, 1675590733, 1674560049, 1673528379, 1672495725, 1671462087, 1670427466, 1669391862, +1668355276, 1667317709, 1666279161, 1665239632, 1664199124, 1663157637, 1662115172, 1661071729, +1660027308, 1658981911, 1657935539, 1656888190, 1655839867, 1654790570, 1653740300, 1652689057, +1651636841, 1650583654, 1649529496, 1648474367, 1647418269, 1646361202, 1645303166, 1644244162, +1643184191, 1642123253, 1641061349, 1639998480, 1638934646, 1637869848, 1636804087, 1635737362, +1634669676, 1633601027, 1632531418, 1631460848, 1630389319, 1629316830, 1628243383, 1627168978, +1626093616, 1625017297, 1623940023, 1622861793, 1621782608, 1620702469, 1619621377, 1618539332, +1617456335, 1616372386, 1615287487, 1614201637, 1613114838, 1612027089, 1610938393, 1609848749, +1608758157, 1607666620, 1606574136, 1605480708, 1604386335, 1603291018, 1602194758, 1601097555, +1599999411, 1598900325, 1597800299, 1596699333, 1595597428, 1594494583, 1593390801, 1592286082, +1591180426, 1590073833, 1588966306, 1587857843, 1586748447, 1585638117, 1584526854, 1583414660, +1582301533, 1581187476, 1580072489, 1578956572, 1577839726, 1576721952, 1575603251, 1574483623, +1573363068, 1572241588, 1571119183, 1569995854, 1568871601, 1567746425, 1566620327, 1565493307, +1564365367, 1563236506, 1562106725, 1560976026, 1559844408, 1558711873, 1557578421, 1556444052, +1555308768, 1554172569, 1553035455, 1551897428, 1550758488, 1549618636, 1548477872, 1547336197, +1546193612, 1545050118, 1543905714, 1542760402, 1541614183, 1540467057, 1539319024, 1538170087, +1537020244, 1535869497, 1534717846, 1533565293, 1532411837, 1531257480, 1530102222, 1528946064, +1527789007, 1526631051, 1525472197, 1524312445, 1523151797, 1521990252, 1520827813, 1519664478, +1518500250, 1517335128, 1516169114, 1515002208, 1513834411, 1512665723, 1511496145, 1510325678, +1509154322, 1507982079, 1506808949, 1505634932, 1504460029, 1503284242, 1502107570, 1500930014, +1499751576, 1498572255, 1497392053, 1496210969, 1495029006, 1493846163, 1492662441, 1491477842, +1490292364, 1489106011, 1487918781, 1486730675, 1485541696, 1484351842, 1483161115, 1481969516, +1480777044, 1479583702, 1478389489, 1477194407, 1475998456, 1474801636, 1473603949, 1472405394, +1471205974, 1470005688, 1468804538, 1467602523, 1466399645, 1465195904, 1463991302, 1462785838, +1461579514, 1460372329, 1459164286, 1457955385, 1456745625, 1455535009, 1454323536, 1453111208, +1451898025, 1450683988, 1449469098, 1448253355, 1447036760, 1445819314, 1444601017, 1443381870, +1442161874, 1440941030, 1439719338, 1438496799, 1437273414, 1436049184, 1434824109, 1433598189, +1432371426, 1431143821, 1429915374, 1428686085, 1427455956, 1426224988, 1424993180, 1423760534, +1422527051, 1421292730, 1420057574, 1418821582, 1417584755, 1416347095, 1415108601, 1413869275, +1412629117, 1411388129, 1410146309, 1408903661, 1407660183, 1406415878, 1405170745, 1403924785, +1402678000, 1401430389, 1400181954, 1398932695, 1397682613, 1396431709, 1395179984, 1393927438, +1392674072, 1391419886, 1390164882, 1388909060, 1387652422, 1386394966, 1385136696, 1383877610, +1382617710, 1381356997, 1380095472, 1378833134, 1377569986, 1376306026, 1375041258, 1373775680, +1372509294, 1371242101, 1369974101, 1368705296, 1367435685, 1366165269, 1364894050, 1363622028, +1362349204, 1361075579, 1359801152, 1358525926, 1357249901, 1355973077, 1354695455, 1353417037, +1352137822, 1350857812, 1349577007, 1348295409, 1347013017, 1345729833, 1344445857, 1343161090, +1341875533, 1340589187, 1339302052, 1338014129, 1336725419, 1335435923, 1334145641, 1332854574, +1331562723, 1330270089, 1328976672, 1327682474, 1326387494, 1325091734, 1323795195, 1322497877, +1321199781, 1319900907, 1318601257, 1317300832, 1315999631, 1314697657, 1313394909, 1312091388, +1310787095, 1309482032, 1308176198, 1306869594, 1305562222, 1304254082, 1302945174, 1301635500, +1300325060, 1299013855, 1297701886, 1296389154, 1295075659, 1293761402, 1292446384, 1291130606, +1289814068, 1288496772, 1287178717, 1285859905, 1284540337, 1283220013, 1281898935, 1280577102, +1279254516, 1277931177, 1276607086, 1275282245, 1273956653, 1272630312, 1271303222, 1269975384, +1268646800, 1267317469, 1265987392, 1264656571, 1263325005, 1261992697, 1260659646, 1259325853, +1257991320, 1256656047, 1255320034, 1253983283, 1252645794, 1251307568, 1249968606, 1248628909, +1247288478, 1245947312, 1244605414, 1243262783, 1241919421, 1240575329, 1239230506, 1237884955, +1236538675, 1235191668, 1233843935, 1232495475, 1231146291, 1229796382, 1228445750, 1227094395, +1225742318, 1224389521, 1223036002, 1221681765, 1220326809, 1218971135, 1217614743, 1216257636, +1214899813, 1213541275, 1212182024, 1210822059, 1209461382, 1208099993, 1206737894, 1205375085, +1204011567, 1202647340, 1201282407, 1199916766, 1198550419, 1197183368, 1195815612, 1194447153, +1193077991, 1191708127, 1190337562, 1188966297, 1187594332, 1186221669, 1184848308, 1183474250, +1182099496, 1180724046, 1179347902, 1177971064, 1176593533, 1175215310, 1173836395, 1172456790, +1171076495, 1169695512, 1168313840, 1166931481, 1165548435, 1164164704, 1162780288, 1161395188, +1160009405, 1158622939, 1157235792, 1155847964, 1154459456, 1153070269, 1151680403, 1150289860, +1148898640, 1147506745, 1146114174, 1144720929, 1143327011, 1141932420, 1140537158, 1139141224, +1137744621, 1136347348, 1134949406, 1133550797, 1132151521, 1130751579, 1129350972, 1127949701, +1126547765, 1125145168, 1123741908, 1122337987, 1120933406, 1119528166, 1118122267, 1116715710, +1115308496, 1113900627, 1112492101, 1111082922, 1109673089, 1108262603, 1106851465, 1105439676, +1104027237, 1102614148, 1101200410, 1099786025, 1098370993, 1096955314, 1095538991, 1094122023, +1092704411, 1091286156, 1089867259, 1088447722, 1087027544, 1085606726, 1084185270, 1082763176, +1081340445, 1079917078, 1078493076, 1077068439, 1075643169, 1074217266, 1072790730, 1071363564, +1069935768, 1068507342, 1067078288, 1065648605, 1064218296, 1062787361, 1061355801, 1059923616, +1058490808, 1057057377, 1055623324, 1054188651, 1052753357, 1051317443, 1049880912, 1048443763, +1047005996, 1045567615, 1044128617, 1042689006, 1041248781, 1039807944, 1038366495, 1036924436, +1035481766, 1034038487, 1032594600, 1031150105, 1029705004, 1028259297, 1026812985, 1025366069, +1023918550, 1022470428, 1021021705, 1019572382, 1018122458, 1016671936, 1015220816, 1013769098, +1012316784, 1010863875, 1009410370, 1007956272, 1006501581, 1005046298, 1003590424, 1002133959, +1000676905, 999219262, 997761031, 996302214, 994842810, 993382821, 991922248, 990461091, +988999351, 987537030, 986074127, 984610645, 983146583, 981681943, 980216726, 978750932, +977284562, 975817617, 974350098, 972882006, 971413342, 969944106, 968474300, 967003923, +965532978, 964061465, 962589385, 961116739, 959643527, 958169751, 956695411, 955220508, +953745043, 952269017, 950792431, 949315286, 947837582, 946359321, 944880503, 943401129, +941921200, 940440717, 938959681, 937478092, 935995952, 934513261, 933030021, 931546231, +930061894, 928577010, 927091579, 925605603, 924119082, 922632018, 921144411, 919656262, +918167572, 916678342, 915188572, 913698265, 912207419, 910716038, 909224120, 907731667, +906238681, 904745161, 903251110, 901756526, 900261413, 898765769, 897269597, 895772898, +894275671, 892777918, 891279640, 889780838, 888281512, 886781663, 885281293, 883780402, +882278992, 880777062, 879274614, 877771649, 876268167, 874764170, 873259659, 871754633, +870249095, 868743045, 867236484, 865729413, 864221832, 862713743, 861205147, 859696043, +858186435, 856676321, 855165703, 853654582, 852142959, 850630835, 849118210, 847605086, +846091463, 844577343, 843062726, 841547612, 840032004, 838515901, 836999305, 835482217, +833964638, 832446567, 830928007, 829408958, 827889422, 826369398, 824848888, 823327893, +821806413, 820284450, 818762005, 817239078, 815715670, 814191782, 812667415, 811142571, +809617249, 808091450, 806565177, 805038429, 803511207, 801983513, 800455346, 798926709, +797397602, 795868026, 794337982, 792807470, 791276492, 789745049, 788213141, 786680769, +785147934, 783614638, 782080880, 780546663, 779011986, 777476851, 775941259, 774405210, +772868706, 771331747, 769794334, 768256469, 766718151, 765179382, 763640164, 762100496, +760560380, 759019816, 757478806, 755937350, 754395449, 752853105, 751310318, 749767089, +748223418, 746679308, 745134758, 743589770, 742044345, 740498483, 738952186, 737405453, +735858287, 734310688, 732762657, 731214195, 729665303, 728115982, 726566232, 725016055, +723465451, 721914422, 720362968, 718811090, 717258790, 715706067, 714152924, 712599360, +711045377, 709490976, 707936158, 706380923, 704825272, 703269207, 701712728, 700155836, +698598533, 697040818, 695482694, 693924160, 692365218, 690805869, 689246113, 687685952, +686125387, 684564417, 683003045, 681441272, 679879097, 678316522, 676753549, 675190177, +673626408, 672062243, 670497682, 668932727, 667367379, 665801638, 664235505, 662668981, +661102068, 659534766, 657967075, 656398998, 654830535, 653261686, 651692453, 650122837, +648552838, 646982457, 645411696, 643840556, 642269036, 640697139, 639124865, 637552215, +635979190, 634405791, 632832018, 631257873, 629683357, 628108471, 626533215, 624957590, +623381598, 621805239, 620228514, 618651424, 617073971, 615496154, 613917975, 612339436, +610760536, 609181276, 607601658, 606021683, 604441352, 602860664, 601279623, 599698227, +598116479, 596534378, 594951927, 593369126, 591785976, 590202477, 588618632, 587034440, +585449903, 583865021, 582279796, 580694229, 579108320, 577522070, 575935480, 574348552, +572761285, 571173682, 569585743, 567997469, 566408860, 564819919, 563230645, 561641039, +560051104, 558460839, 556870245, 555279324, 553688076, 552096502, 550504604, 548912382, +547319836, 545726969, 544133781, 542540273, 540946445, 539352300, 537757837, 536163058, +534567963, 532972554, 531376831, 529780796, 528184449, 526587791, 524990824, 523393547, +521795963, 520198072, 518599875, 517001373, 515402566, 513803457, 512204045, 510604332, +509004318, 507404005, 505803394, 504202485, 502601279, 500999778, 499397982, 497795892, +496193509, 494590835, 492987869, 491384614, 489781069, 488177236, 486573117, 484968710, +483364019, 481759043, 480153784, 478548243, 476942419, 475336316, 473729932, 472123270, +470516330, 468909114, 467301622, 465693854, 464085813, 462477499, 460868912, 459260055, +457650927, 456041530, 454431865, 452821933, 451211734, 449601270, 447990541, 446379549, +444768294, 443156777, 441545000, 439932963, 438320667, 436708113, 435095303, 433482236, +431868915, 430255339, 428641511, 427027430, 425413098, 423798515, 422183684, 420568604, +418953276, 417337703, 415721883, 414105819, 412489512, 410872962, 409256170, 407639137, +406021865, 404404353, 402786604, 401168618, 399550396, 397931939, 396313247, 394694323, +393075166, 391455778, 389836160, 388216313, 386596237, 384975934, 383355404, 381734649, +380113669, 378492466, 376871039, 375249392, 373627523, 372005435, 370383128, 368760603, +367137861, 365514903, 363891730, 362268343, 360644742, 359020930, 357396906, 355772673, +354148230, 352523578, 350898719, 349273654, 347648383, 346022908, 344397230, 342771348, +341145265, 339518981, 337892498, 336265816, 334638936, 333011859, 331384586, 329757119, +328129457, 326501602, 324873555, 323245317, 321616889, 319988272, 318359466, 316730474, +315101295, 313471930, 311842381, 310212649, 308582734, 306952638, 305322361, 303691904, +302061269, 300430456, 298799466, 297168301, 295536961, 293905447, 292273760, 290641901, +289009871, 287377671, 285745302, 284112765, 282480061, 280847190, 279214155, 277580955, +275947592, 274314066, 272680379, 271046532, 269412525, 267778360, 266144038, 264509558, +262874923, 261240134, 259605191, 257970095, 256334847, 254699448, 253063900, 251428203, +249792358, 248156366, 246520228, 244883945, 243247518, 241610947, 239974235, 238337382, +236700388, 235063255, 233425984, 231788575, 230151030, 228513350, 226875535, 225237587, +223599506, 221961294, 220322951, 218684479, 217045878, 215407149, 213768293, 212129312, +210490206, 208850976, 207211624, 205572149, 203932553, 202292838, 200653003, 199013051, +197372981, 195732795, 194092495, 192452080, 190811551, 189170911, 187530159, 185889297, +184248325, 182607245, 180966058, 179324764, 177683365, 176041861, 174400254, 172758544, +171116733, 169474820, 167832808, 166190698, 164548489, 162906184, 161263783, 159621287, +157978697, 156336015, 154693240, 153050374, 151407418, 149764374, 148121241, 146478021, +144834714, 143191323, 141547847, 139904288, 138260647, 136616925, 134973122, 133329239, +131685278, 130041240, 128397125, 126752935, 125108670, 123464332, 121819921, 120175438, +118530885, 116886262, 115241570, 113596810, 111951983, 110307091, 108662134, 107017112, +105372028, 103726882, 102081675, 100436408, 98791081, 97145697, 95500255, 93854758, + 92209205, 90563597, 88917937, 87272224, 85626460, 83980645, 82334782, 80688869, + 79042909, 77396903, 75750851, 74104755, 72458615, 70812432, 69166208, 67519943, + 65873638, 64227295, 62580914, 60934496, 59288042, 57641553, 55995030, 54348475, + 52701887, 51055268, 49408620, 47761942, 46115236, 44468503, 42821744, 41174960, + 39528151, 37881320, 36234466, 34587590, 32940695, 31293780, 29646846, 27999895, + 26352928, 24705945, 23058947, 21411936, 19764913, 18117878, 16470832, 14823776, + 13176712, 11529640, 9882561, 8235476, 6588387, 4941294, 3294197, 1647099 +}; + +uint16_t ff_fft_offsets_lut[21845]; + +void ff_fft_lut_init(uint16_t *table, int off, int size, int *index) +{ + if (size < 16) { + table[*index] = off >> 2; + (*index)++; + } + else { + ff_fft_lut_init(table, off, size>>1, index); + ff_fft_lut_init(table, off+(size>>1), size>>2, index); + ff_fft_lut_init(table, off+3*(size>>2), size>>2, index); + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_table.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_table.h new file mode 100644 index 000000000..ed0a6588b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_table.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Authors: Stanislav Ocovaj (socovaj@mips.com) + * Goran Cordasic (goran@mips.com) + * Djordje Pesut (djordje@mips.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * definitions and tables for FFT + */ +#ifndef AVCODEC_FFT_TABLE_H +#define AVCODEC_FFT_TABLE_H + +#include "libavcodec/fft.h" + +#define MAX_LOG2_NFFT 17 //!< Specifies maximum allowed fft size +#define MAX_FFT_SIZE (1 << MAX_LOG2_NFFT) + +extern const int32_t ff_w_tab_sr[]; +extern uint16_t ff_fft_offsets_lut[]; +void ff_fft_lut_init(uint16_t *table, int off, int size, int *index); + +#endif /* AVCODEC_FFT_TABLE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_template.c new file mode 100644 index 000000000..20a62e429 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/fft_template.c @@ -0,0 +1,639 @@ +/* + * FFT/IFFT transforms + * Copyright (c) 2008 Loren Merritt + * Copyright (c) 2002 Fabrice Bellard + * Partly based on libdjbfft by D. J. Bernstein + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * FFT/IFFT transforms. + */ + +#include +#include +#include "libavutil/mathematics.h" +#include "libavutil/thread.h" +#include "fft.h" +#include "fft-internal.h" + +#if FFT_FIXED_32 +#include "fft_table.h" + +static void av_cold fft_lut_init(void) +{ + int n = 0; + ff_fft_lut_init(ff_fft_offsets_lut, 0, 1 << 17, &n); +} + +#else /* FFT_FIXED_32 */ + +/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */ +#if !CONFIG_HARDCODED_TABLES +COSTABLE(16); +COSTABLE(32); +COSTABLE(64); +COSTABLE(128); +COSTABLE(256); +COSTABLE(512); +COSTABLE(1024); +COSTABLE(2048); +COSTABLE(4096); +COSTABLE(8192); +COSTABLE(16384); +COSTABLE(32768); +COSTABLE(65536); +COSTABLE(131072); + +static av_cold void init_ff_cos_tabs(int index) +{ + int i; + int m = 1<> 1; + if(!(i&m)) return split_radix_permutation(i, m, inverse)*2; + m >>= 1; + if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1; + else return split_radix_permutation(i, m, inverse)*4 - 1; +} + +av_cold void ff_init_ff_cos_tabs(int index) +{ +#if (!CONFIG_HARDCODED_TABLES) && (!FFT_FIXED_32) + ff_thread_once(&cos_tabs_init_once[index].control, cos_tabs_init_once[index].func); +#endif +} + +static const int avx_tab[] = { + 0, 4, 1, 5, 8, 12, 9, 13, 2, 6, 3, 7, 10, 14, 11, 15 +}; + +static int is_second_half_of_fft32(int i, int n) +{ + if (n <= 32) + return i >= 16; + else if (i < n/2) + return is_second_half_of_fft32(i, n/2); + else if (i < 3*n/4) + return is_second_half_of_fft32(i - n/2, n/4); + else + return is_second_half_of_fft32(i - 3*n/4, n/4); +} + +static av_cold void fft_perm_avx(FFTContext *s) +{ + int i; + int n = 1 << s->nbits; + + for (i = 0; i < n; i += 16) { + int k; + if (is_second_half_of_fft32(i, n)) { + for (k = 0; k < 16; k++) + s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] = + i + avx_tab[k]; + + } else { + for (k = 0; k < 16; k++) { + int j = i + k; + j = (j & ~7) | ((j >> 1) & 3) | ((j << 2) & 4); + s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] = j; + } + } + } +} + +av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) +{ + int i, j, n; + + s->revtab = NULL; + s->revtab32 = NULL; + + if (nbits < 2 || nbits > 17) + goto fail; + s->nbits = nbits; + n = 1 << nbits; + + if (nbits <= 16) { + s->revtab = av_malloc(n * sizeof(uint16_t)); + if (!s->revtab) + goto fail; + } else { + s->revtab32 = av_malloc(n * sizeof(uint32_t)); + if (!s->revtab32) + goto fail; + } + s->tmp_buf = av_malloc(n * sizeof(FFTComplex)); + if (!s->tmp_buf) + goto fail; + s->inverse = inverse; + s->fft_permutation = FF_FFT_PERM_DEFAULT; + + s->fft_permute = fft_permute_c; + s->fft_calc = fft_calc_c; +#if CONFIG_MDCT + s->imdct_calc = ff_imdct_calc_c; + s->imdct_half = ff_imdct_half_c; + s->mdct_calc = ff_mdct_calc_c; +#endif + +#if FFT_FIXED_32 + { + static AVOnce control = AV_ONCE_INIT; + ff_thread_once(&control, fft_lut_init); + } +#else /* FFT_FIXED_32 */ +#if FFT_FLOAT + if (ARCH_AARCH64) ff_fft_init_aarch64(s); + if (ARCH_ARM) ff_fft_init_arm(s); + if (ARCH_PPC) ff_fft_init_ppc(s); + if (ARCH_X86) ff_fft_init_x86(s); + if (CONFIG_MDCT) s->mdct_calcw = s->mdct_calc; + if (HAVE_MIPSFPU) ff_fft_init_mips(s); +#else + if (CONFIG_MDCT) s->mdct_calcw = ff_mdct_calcw_c; + if (ARCH_ARM) ff_fft_fixed_init_arm(s); +#endif + for(j=4; j<=nbits; j++) { + ff_init_ff_cos_tabs(j); + } +#endif /* FFT_FIXED_32 */ + + + if (s->fft_permutation == FF_FFT_PERM_AVX) { + fft_perm_avx(s); + } else { +#define PROCESS_FFT_PERM_SWAP_LSBS(num) do {\ + for(i = 0; i < n; i++) {\ + int k;\ + j = i;\ + j = (j & ~3) | ((j >> 1) & 1) | ((j << 1) & 2);\ + k = -split_radix_permutation(i, n, s->inverse) & (n - 1);\ + s->revtab##num[k] = j;\ + } \ +} while(0); + +#define PROCESS_FFT_PERM_DEFAULT(num) do {\ + for(i = 0; i < n; i++) {\ + int k;\ + j = i;\ + k = -split_radix_permutation(i, n, s->inverse) & (n - 1);\ + s->revtab##num[k] = j;\ + } \ +} while(0); + +#define SPLIT_RADIX_PERMUTATION(num) do { \ + if (s->fft_permutation == FF_FFT_PERM_SWAP_LSBS) {\ + PROCESS_FFT_PERM_SWAP_LSBS(num) \ + } else {\ + PROCESS_FFT_PERM_DEFAULT(num) \ + }\ +} while(0); + + if (s->revtab) + SPLIT_RADIX_PERMUTATION() + if (s->revtab32) + SPLIT_RADIX_PERMUTATION(32) + +#undef PROCESS_FFT_PERM_DEFAULT +#undef PROCESS_FFT_PERM_SWAP_LSBS +#undef SPLIT_RADIX_PERMUTATION + } + + return 0; + fail: + av_freep(&s->revtab); + av_freep(&s->revtab32); + av_freep(&s->tmp_buf); + return -1; +} + +static void fft_permute_c(FFTContext *s, FFTComplex *z) +{ + int j, np; + const uint16_t *revtab = s->revtab; + const uint32_t *revtab32 = s->revtab32; + np = 1 << s->nbits; + /* TODO: handle split-radix permute in a more optimal way, probably in-place */ + if (revtab) { + for(j=0;jtmp_buf[revtab[j]] = z[j]; + } else + for(j=0;jtmp_buf[revtab32[j]] = z[j]; + + memcpy(z, s->tmp_buf, np * sizeof(FFTComplex)); +} + +av_cold void ff_fft_end(FFTContext *s) +{ + av_freep(&s->revtab); + av_freep(&s->revtab32); + av_freep(&s->tmp_buf); +} + +#if FFT_FIXED_32 + +static void fft_calc_c(FFTContext *s, FFTComplex *z) { + + int nbits, i, n, num_transforms, offset, step; + int n4, n2, n34; + unsigned tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; + FFTComplex *tmpz; + const int fft_size = (1 << s->nbits); + int64_t accu; + + num_transforms = (0x2aab >> (16 - s->nbits)) | 1; + + for (n=0; n> 1) | 1; + + for (n=0; n> 31); + accu = (int64_t)Q31(M_SQRT1_2)*(int)(tmp3 - tmp4); + tmp7 = (int32_t)((accu + 0x40000000) >> 31); + accu = (int64_t)Q31(M_SQRT1_2)*(int)(tmp2 - tmp1); + tmp6 = (int32_t)((accu + 0x40000000) >> 31); + accu = (int64_t)Q31(M_SQRT1_2)*(int)(tmp3 + tmp4); + tmp8 = (int32_t)((accu + 0x40000000) >> 31); + tmp1 = tmp5 + tmp7; + tmp3 = tmp5 - tmp7; + tmp2 = tmp6 + tmp8; + tmp4 = tmp6 - tmp8; + + tmpz[5].re = tmpz[1].re - tmp1; + tmpz[1].re = tmpz[1].re + tmp1; + tmpz[5].im = tmpz[1].im - tmp2; + tmpz[1].im = tmpz[1].im + tmp2; + tmpz[7].re = tmpz[3].re - tmp4; + tmpz[3].re = tmpz[3].re + tmp4; + tmpz[7].im = tmpz[3].im + tmp3; + tmpz[3].im = tmpz[3].im - tmp3; + } + + step = 1 << ((MAX_LOG2_NFFT-4) - 4); + n4 = 4; + + for (nbits=4; nbits<=s->nbits; nbits++){ + n2 = 2*n4; + n34 = 3*n4; + num_transforms = (num_transforms >> 1) | 1; + + for (n=0; n> 31); + accu = (int64_t)w_re*tmpz[ n2+i].im; + accu -= (int64_t)w_im*tmpz[ n2+i].re; + tmp2 = (int32_t)((accu + 0x40000000) >> 31); + accu = (int64_t)w_re*tmpz[n34+i].re; + accu -= (int64_t)w_im*tmpz[n34+i].im; + tmp3 = (int32_t)((accu + 0x40000000) >> 31); + accu = (int64_t)w_re*tmpz[n34+i].im; + accu += (int64_t)w_im*tmpz[n34+i].re; + tmp4 = (int32_t)((accu + 0x40000000) >> 31); + + tmp5 = tmp1 + tmp3; + tmp1 = tmp1 - tmp3; + tmp6 = tmp2 + tmp4; + tmp2 = tmp2 - tmp4; + + tmpz[ n2+i].re = tmpz[ i].re - tmp5; + tmpz[ i].re = tmpz[ i].re + tmp5; + tmpz[ n2+i].im = tmpz[ i].im - tmp6; + tmpz[ i].im = tmpz[ i].im + tmp6; + tmpz[n34+i].re = tmpz[n4+i].re - tmp2; + tmpz[ n4+i].re = tmpz[n4+i].re + tmp2; + tmpz[n34+i].im = tmpz[n4+i].im + tmp1; + tmpz[ n4+i].im = tmpz[n4+i].im - tmp1; + + w_re_ptr += step; + w_im_ptr -= step; + } + } + step >>= 1; + n4 <<= 1; + } +} + +#else /* FFT_FIXED_32 */ + +#define BUTTERFLIES(a0,a1,a2,a3) {\ + BF(t3, t5, t5, t1);\ + BF(a2.re, a0.re, a0.re, t5);\ + BF(a3.im, a1.im, a1.im, t3);\ + BF(t4, t6, t2, t6);\ + BF(a3.re, a1.re, a1.re, t4);\ + BF(a2.im, a0.im, a0.im, t6);\ +} + +// force loading all the inputs before storing any. +// this is slightly slower for small data, but avoids store->load aliasing +// for addresses separated by large powers of 2. +#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\ + FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\ + BF(t3, t5, t5, t1);\ + BF(a2.re, a0.re, r0, t5);\ + BF(a3.im, a1.im, i1, t3);\ + BF(t4, t6, t2, t6);\ + BF(a3.re, a1.re, r1, t4);\ + BF(a2.im, a0.im, i0, t6);\ +} + +#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\ + CMUL(t1, t2, a2.re, a2.im, wre, -wim);\ + CMUL(t5, t6, a3.re, a3.im, wre, wim);\ + BUTTERFLIES(a0,a1,a2,a3)\ +} + +#define TRANSFORM_ZERO(a0,a1,a2,a3) {\ + t1 = a2.re;\ + t2 = a2.im;\ + t5 = a3.re;\ + t6 = a3.im;\ + BUTTERFLIES(a0,a1,a2,a3)\ +} + +/* z[0...8n-1], w[1...2n-1] */ +#define PASS(name)\ +static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\ +{\ + FFTDouble t1, t2, t3, t4, t5, t6;\ + int o1 = 2*n;\ + int o2 = 4*n;\ + int o3 = 6*n;\ + const FFTSample *wim = wre+o1;\ + n--;\ +\ + TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\ + TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ + do {\ + z += 2;\ + wre += 2;\ + wim -= 2;\ + TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\ + TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ + } while(--n);\ +} + +PASS(pass) +#if !CONFIG_SMALL +#undef BUTTERFLIES +#define BUTTERFLIES BUTTERFLIES_BIG +PASS(pass_big) +#endif + +#define DECL_FFT(n,n2,n4)\ +static void fft##n(FFTComplex *z)\ +{\ + fft##n2(z);\ + fft##n4(z+n4*2);\ + fft##n4(z+n4*3);\ + pass(z,FFT_NAME(ff_cos_##n),n4/2);\ +} + +static void fft4(FFTComplex *z) +{ + FFTDouble t1, t2, t3, t4, t5, t6, t7, t8; + + BF(t3, t1, z[0].re, z[1].re); + BF(t8, t6, z[3].re, z[2].re); + BF(z[2].re, z[0].re, t1, t6); + BF(t4, t2, z[0].im, z[1].im); + BF(t7, t5, z[2].im, z[3].im); + BF(z[3].im, z[1].im, t4, t8); + BF(z[3].re, z[1].re, t3, t7); + BF(z[2].im, z[0].im, t2, t5); +} + +static void fft8(FFTComplex *z) +{ + FFTDouble t1, t2, t3, t4, t5, t6; + + fft4(z); + + BF(t1, z[5].re, z[4].re, -z[5].re); + BF(t2, z[5].im, z[4].im, -z[5].im); + BF(t5, z[7].re, z[6].re, -z[7].re); + BF(t6, z[7].im, z[6].im, -z[7].im); + + BUTTERFLIES(z[0],z[2],z[4],z[6]); + TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf); +} + +#if !CONFIG_SMALL +static void fft16(FFTComplex *z) +{ + FFTDouble t1, t2, t3, t4, t5, t6; + FFTSample cos_16_1 = FFT_NAME(ff_cos_16)[1]; + FFTSample cos_16_3 = FFT_NAME(ff_cos_16)[3]; + + fft8(z); + fft4(z+8); + fft4(z+12); + + TRANSFORM_ZERO(z[0],z[4],z[8],z[12]); + TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf); + TRANSFORM(z[1],z[5],z[9],z[13],cos_16_1,cos_16_3); + TRANSFORM(z[3],z[7],z[11],z[15],cos_16_3,cos_16_1); +} +#else +DECL_FFT(16,8,4) +#endif +DECL_FFT(32,16,8) +DECL_FFT(64,32,16) +DECL_FFT(128,64,32) +DECL_FFT(256,128,64) +DECL_FFT(512,256,128) +#if !CONFIG_SMALL +#define pass pass_big +#endif +DECL_FFT(1024,512,256) +DECL_FFT(2048,1024,512) +DECL_FFT(4096,2048,1024) +DECL_FFT(8192,4096,2048) +DECL_FFT(16384,8192,4096) +DECL_FFT(32768,16384,8192) +DECL_FFT(65536,32768,16384) +DECL_FFT(131072,65536,32768) + +static void (* const fft_dispatch[])(FFTComplex*) = { + fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, + fft2048, fft4096, fft8192, fft16384, fft32768, fft65536, fft131072 +}; + +static void fft_calc_c(FFTContext *s, FFTComplex *z) +{ + fft_dispatch[s->nbits-2](z); +} +#endif /* FFT_FIXED_32 */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/frame_thread_encoder.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/frame_thread_encoder.c new file mode 100644 index 000000000..55756c4c5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/frame_thread_encoder.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "frame_thread_encoder.h" + +#include "libavutil/fifo.h" +#include "libavutil/avassert.h" +#include "libavutil/imgutils.h" +#include "libavutil/opt.h" +#include "libavutil/thread.h" +#include "avcodec.h" +#include "internal.h" +#include "thread.h" + +#define MAX_THREADS 64 +#define BUFFER_SIZE (2*MAX_THREADS) + +typedef struct{ + void *indata; + void *outdata; + int64_t return_code; + unsigned index; +} Task; + +typedef struct{ + AVCodecContext *parent_avctx; + pthread_mutex_t buffer_mutex; + + AVFifoBuffer *task_fifo; + pthread_mutex_t task_fifo_mutex; + pthread_cond_t task_fifo_cond; + + Task finished_tasks[BUFFER_SIZE]; + pthread_mutex_t finished_task_mutex; + pthread_cond_t finished_task_cond; + + unsigned task_index; + unsigned finished_task_index; + + pthread_t worker[MAX_THREADS]; + atomic_int exit; +} ThreadContext; + +static void * attribute_align_arg worker(void *v){ + AVCodecContext *avctx = v; + ThreadContext *c = avctx->internal->frame_thread_encoder; + AVPacket *pkt = NULL; + + while (!atomic_load(&c->exit)) { + int got_packet, ret; + AVFrame *frame; + Task task; + + if(!pkt) pkt = av_packet_alloc(); + if(!pkt) continue; + av_init_packet(pkt); + + pthread_mutex_lock(&c->task_fifo_mutex); + while (av_fifo_size(c->task_fifo) <= 0 || atomic_load(&c->exit)) { + if (atomic_load(&c->exit)) { + pthread_mutex_unlock(&c->task_fifo_mutex); + goto end; + } + pthread_cond_wait(&c->task_fifo_cond, &c->task_fifo_mutex); + } + av_fifo_generic_read(c->task_fifo, &task, sizeof(task), NULL); + pthread_mutex_unlock(&c->task_fifo_mutex); + frame = task.indata; + + ret = avcodec_encode_video2(avctx, pkt, frame, &got_packet); + pthread_mutex_lock(&c->buffer_mutex); + av_frame_unref(frame); + pthread_mutex_unlock(&c->buffer_mutex); + av_frame_free(&frame); + if(got_packet) { + int ret2 = av_packet_make_refcounted(pkt); + if (ret >= 0 && ret2 < 0) + ret = ret2; + } else { + pkt->data = NULL; + pkt->size = 0; + } + pthread_mutex_lock(&c->finished_task_mutex); + c->finished_tasks[task.index].outdata = pkt; pkt = NULL; + c->finished_tasks[task.index].return_code = ret; + pthread_cond_signal(&c->finished_task_cond); + pthread_mutex_unlock(&c->finished_task_mutex); + } +end: + av_free(pkt); + pthread_mutex_lock(&c->buffer_mutex); + avcodec_close(avctx); + pthread_mutex_unlock(&c->buffer_mutex); + av_freep(&avctx); + return NULL; +} + +int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ + int i=0; + ThreadContext *c; + + + if( !(avctx->thread_type & FF_THREAD_FRAME) + || !(avctx->codec->capabilities & AV_CODEC_CAP_INTRA_ONLY)) + return 0; + + if( !avctx->thread_count + && avctx->codec_id == AV_CODEC_ID_MJPEG + && !(avctx->flags & AV_CODEC_FLAG_QSCALE)) { + av_log(avctx, AV_LOG_DEBUG, + "Forcing thread count to 1 for MJPEG encoding, use -thread_type slice " + "or a constant quantizer if you want to use multiple cpu cores\n"); + avctx->thread_count = 1; + } + if( avctx->thread_count > 1 + && avctx->codec_id == AV_CODEC_ID_MJPEG + && !(avctx->flags & AV_CODEC_FLAG_QSCALE)) + av_log(avctx, AV_LOG_WARNING, + "MJPEG CBR encoding works badly with frame multi-threading, consider " + "using -threads 1, -thread_type slice or a constant quantizer.\n"); + + if (avctx->codec_id == AV_CODEC_ID_HUFFYUV || + avctx->codec_id == AV_CODEC_ID_FFVHUFF) { + int warn = 0; + int context_model = 0; + AVDictionaryEntry *con = av_dict_get(options, "context", NULL, AV_DICT_MATCH_CASE); + + if (con && con->value) + context_model = atoi(con->value); + + if (avctx->flags & AV_CODEC_FLAG_PASS1) + warn = 1; + else if(context_model > 0) { + AVDictionaryEntry *t = av_dict_get(options, "non_deterministic", + NULL, AV_DICT_MATCH_CASE); + warn = !t || !t->value || !atoi(t->value) ? 1 : 0; + } + // huffyuv does not support these with multiple frame threads currently + if (warn) { + av_log(avctx, AV_LOG_WARNING, + "Forcing thread count to 1 for huffyuv encoding with first pass or context 1\n"); + avctx->thread_count = 1; + } + } + + if(!avctx->thread_count) { + avctx->thread_count = av_cpu_count(); + avctx->thread_count = FFMIN(avctx->thread_count, MAX_THREADS); + } + + if(avctx->thread_count <= 1) + return 0; + + if(avctx->thread_count > MAX_THREADS) + return AVERROR(EINVAL); + + av_assert0(!avctx->internal->frame_thread_encoder); + c = avctx->internal->frame_thread_encoder = av_mallocz(sizeof(ThreadContext)); + if(!c) + return AVERROR(ENOMEM); + + c->parent_avctx = avctx; + + c->task_fifo = av_fifo_alloc_array(BUFFER_SIZE, sizeof(Task)); + if(!c->task_fifo) + goto fail; + + pthread_mutex_init(&c->task_fifo_mutex, NULL); + pthread_mutex_init(&c->finished_task_mutex, NULL); + pthread_mutex_init(&c->buffer_mutex, NULL); + pthread_cond_init(&c->task_fifo_cond, NULL); + pthread_cond_init(&c->finished_task_cond, NULL); + atomic_init(&c->exit, 0); + + for(i=0; ithread_count ; i++){ + AVDictionary *tmp = NULL; + int ret; + void *tmpv; + AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec); + if(!thread_avctx) + goto fail; + tmpv = thread_avctx->priv_data; + *thread_avctx = *avctx; + ret = av_opt_copy(thread_avctx, avctx); + if (ret < 0) + goto fail; + thread_avctx->priv_data = tmpv; + thread_avctx->internal = NULL; + if (avctx->codec->priv_class) { + int ret = av_opt_copy(thread_avctx->priv_data, avctx->priv_data); + if (ret < 0) + goto fail; + } else + memcpy(thread_avctx->priv_data, avctx->priv_data, avctx->codec->priv_data_size); + thread_avctx->thread_count = 1; + thread_avctx->active_thread_type &= ~FF_THREAD_FRAME; + + av_dict_copy(&tmp, options, 0); + av_dict_set(&tmp, "threads", "1", 0); + if(avcodec_open2(thread_avctx, avctx->codec, &tmp) < 0) { + av_dict_free(&tmp); + goto fail; + } + av_dict_free(&tmp); + av_assert0(!thread_avctx->internal->frame_thread_encoder); + thread_avctx->internal->frame_thread_encoder = c; + if(pthread_create(&c->worker[i], NULL, worker, thread_avctx)) { + goto fail; + } + } + + avctx->active_thread_type = FF_THREAD_FRAME; + + return 0; +fail: + avctx->thread_count = i; + av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n"); + ff_frame_thread_encoder_free(avctx); + return -1; +} + +void ff_frame_thread_encoder_free(AVCodecContext *avctx){ + int i; + ThreadContext *c= avctx->internal->frame_thread_encoder; + + pthread_mutex_lock(&c->task_fifo_mutex); + atomic_store(&c->exit, 1); + pthread_cond_broadcast(&c->task_fifo_cond); + pthread_mutex_unlock(&c->task_fifo_mutex); + + for (i=0; ithread_count; i++) { + pthread_join(c->worker[i], NULL); + } + + while (av_fifo_size(c->task_fifo) > 0) { + Task task; + AVFrame *frame; + av_fifo_generic_read(c->task_fifo, &task, sizeof(task), NULL); + frame = task.indata; + av_frame_free(&frame); + task.indata = NULL; + } + + for (i=0; ifinished_tasks[i].outdata != NULL) { + AVPacket *pkt = c->finished_tasks[i].outdata; + av_packet_free(&pkt); + c->finished_tasks[i].outdata = NULL; + } + } + + pthread_mutex_destroy(&c->task_fifo_mutex); + pthread_mutex_destroy(&c->finished_task_mutex); + pthread_mutex_destroy(&c->buffer_mutex); + pthread_cond_destroy(&c->task_fifo_cond); + pthread_cond_destroy(&c->finished_task_cond); + av_fifo_freep(&c->task_fifo); + av_freep(&avctx->internal->frame_thread_encoder); +} + +int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr){ + ThreadContext *c = avctx->internal->frame_thread_encoder; + Task task; + int ret; + + av_assert1(!*got_packet_ptr); + + if(frame){ + AVFrame *new = av_frame_alloc(); + if(!new) + return AVERROR(ENOMEM); + ret = av_frame_ref(new, frame); + if(ret < 0) { + av_frame_free(&new); + return ret; + } + + task.index = c->task_index; + task.indata = (void*)new; + pthread_mutex_lock(&c->task_fifo_mutex); + av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL); + pthread_cond_signal(&c->task_fifo_cond); + pthread_mutex_unlock(&c->task_fifo_mutex); + + c->task_index = (c->task_index+1) % BUFFER_SIZE; + } + + pthread_mutex_lock(&c->finished_task_mutex); + if (c->task_index == c->finished_task_index || + (frame && !c->finished_tasks[c->finished_task_index].outdata && + (c->task_index - c->finished_task_index) % BUFFER_SIZE <= avctx->thread_count)) { + pthread_mutex_unlock(&c->finished_task_mutex); + return 0; + } + + while (!c->finished_tasks[c->finished_task_index].outdata) { + pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex); + } + task = c->finished_tasks[c->finished_task_index]; + *pkt = *(AVPacket*)(task.outdata); + if(pkt->data) + *got_packet_ptr = 1; + av_freep(&c->finished_tasks[c->finished_task_index].outdata); + c->finished_task_index = (c->finished_task_index+1) % BUFFER_SIZE; + pthread_mutex_unlock(&c->finished_task_mutex); + + return task.return_code; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/frame_thread_encoder.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/frame_thread_encoder.h new file mode 100644 index 000000000..1f79553f2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/frame_thread_encoder.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_FRAME_THREAD_ENCODER_H +#define AVCODEC_FRAME_THREAD_ENCODER_H + +#include "avcodec.h" + +int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options); +void ff_frame_thread_encoder_free(AVCodecContext *avctx); +int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr); + +#endif /* AVCODEC_FRAME_THREAD_ENCODER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/get_bits.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/get_bits.h new file mode 100644 index 000000000..c4ab60774 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/get_bits.h @@ -0,0 +1,868 @@ +/* + * Copyright (c) 2004 Michael Niedermayer + * Copyright (c) 2016 Alexandra Hájková + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * bitstream reader API header. + */ + +#ifndef AVCODEC_GET_BITS_H +#define AVCODEC_GET_BITS_H + +#include + +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/log.h" +#include "libavutil/avassert.h" +#include "avcodec.h" +#include "mathops.h" +#include "vlc.h" + +/* + * Safe bitstream reading: + * optionally, the get_bits API can check to ensure that we + * don't read past input buffer boundaries. This is protected + * with CONFIG_SAFE_BITSTREAM_READER at the global level, and + * then below that with UNCHECKED_BITSTREAM_READER at the per- + * decoder level. This means that decoders that check internally + * can "#define UNCHECKED_BITSTREAM_READER 1" to disable + * overread checks. + * Boundary checking causes a minor performance penalty so for + * applications that won't want/need this, it can be disabled + * globally using "#define CONFIG_SAFE_BITSTREAM_READER 0". + */ +#ifndef UNCHECKED_BITSTREAM_READER +#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER +#endif + +#ifndef CACHED_BITSTREAM_READER +#define CACHED_BITSTREAM_READER 0 +#endif + +typedef struct GetBitContext { + const uint8_t *buffer, *buffer_end; +#if CACHED_BITSTREAM_READER + uint64_t cache; + unsigned bits_left; +#endif + int index; + int size_in_bits; + int size_in_bits_plus8; +} GetBitContext; + +static inline unsigned int get_bits(GetBitContext *s, int n); +static inline void skip_bits(GetBitContext *s, int n); +static inline unsigned int show_bits(GetBitContext *s, int n); + +/* Bitstream reader API docs: + * name + * arbitrary name which is used as prefix for the internal variables + * + * gb + * getbitcontext + * + * OPEN_READER(name, gb) + * load gb into local variables + * + * CLOSE_READER(name, gb) + * store local vars in gb + * + * UPDATE_CACHE(name, gb) + * Refill the internal cache from the bitstream. + * After this call at least MIN_CACHE_BITS will be available. + * + * GET_CACHE(name, gb) + * Will output the contents of the internal cache, + * next bit is MSB of 32 or 64 bits (FIXME 64 bits). + * + * SHOW_UBITS(name, gb, num) + * Will return the next num bits. + * + * SHOW_SBITS(name, gb, num) + * Will return the next num bits and do sign extension. + * + * SKIP_BITS(name, gb, num) + * Will skip over the next num bits. + * Note, this is equivalent to SKIP_CACHE; SKIP_COUNTER. + * + * SKIP_CACHE(name, gb, num) + * Will remove the next num bits from the cache (note SKIP_COUNTER + * MUST be called before UPDATE_CACHE / CLOSE_READER). + * + * SKIP_COUNTER(name, gb, num) + * Will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS). + * + * LAST_SKIP_BITS(name, gb, num) + * Like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER. + * + * BITS_LEFT(name, gb) + * Return the number of bits left + * + * For examples see get_bits, show_bits, skip_bits, get_vlc. + */ + +#if CACHED_BITSTREAM_READER +# define MIN_CACHE_BITS 64 +#elif defined LONG_BITSTREAM_READER +# define MIN_CACHE_BITS 32 +#else +# define MIN_CACHE_BITS 25 +#endif + +#if !CACHED_BITSTREAM_READER + +#define OPEN_READER_NOSIZE(name, gb) \ + unsigned int name ## _index = (gb)->index; \ + unsigned int av_unused name ## _cache + +#if UNCHECKED_BITSTREAM_READER +#define OPEN_READER(name, gb) OPEN_READER_NOSIZE(name, gb) + +#define BITS_AVAILABLE(name, gb) 1 +#else +#define OPEN_READER(name, gb) \ + OPEN_READER_NOSIZE(name, gb); \ + unsigned int name ## _size_plus8 = (gb)->size_in_bits_plus8 + +#define BITS_AVAILABLE(name, gb) name ## _index < name ## _size_plus8 +#endif + +#define CLOSE_READER(name, gb) (gb)->index = name ## _index + +# ifdef LONG_BITSTREAM_READER + +# define UPDATE_CACHE_LE(name, gb) name ## _cache = \ + AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) + +# define UPDATE_CACHE_BE(name, gb) name ## _cache = \ + AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7)) + +#else + +# define UPDATE_CACHE_LE(name, gb) name ## _cache = \ + AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) + +# define UPDATE_CACHE_BE(name, gb) name ## _cache = \ + AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7) + +#endif + + +#ifdef BITSTREAM_READER_LE + +# define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb) + +# define SKIP_CACHE(name, gb, num) name ## _cache >>= (num) + +#else + +# define UPDATE_CACHE(name, gb) UPDATE_CACHE_BE(name, gb) + +# define SKIP_CACHE(name, gb, num) name ## _cache <<= (num) + +#endif + +#if UNCHECKED_BITSTREAM_READER +# define SKIP_COUNTER(name, gb, num) name ## _index += (num) +#else +# define SKIP_COUNTER(name, gb, num) \ + name ## _index = FFMIN(name ## _size_plus8, name ## _index + (num)) +#endif + +#define BITS_LEFT(name, gb) ((int)((gb)->size_in_bits - name ## _index)) + +#define SKIP_BITS(name, gb, num) \ + do { \ + SKIP_CACHE(name, gb, num); \ + SKIP_COUNTER(name, gb, num); \ + } while (0) + +#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) + +#define SHOW_UBITS_LE(name, gb, num) zero_extend(name ## _cache, num) +#define SHOW_SBITS_LE(name, gb, num) sign_extend(name ## _cache, num) + +#define SHOW_UBITS_BE(name, gb, num) NEG_USR32(name ## _cache, num) +#define SHOW_SBITS_BE(name, gb, num) NEG_SSR32(name ## _cache, num) + +#ifdef BITSTREAM_READER_LE +# define SHOW_UBITS(name, gb, num) SHOW_UBITS_LE(name, gb, num) +# define SHOW_SBITS(name, gb, num) SHOW_SBITS_LE(name, gb, num) +#else +# define SHOW_UBITS(name, gb, num) SHOW_UBITS_BE(name, gb, num) +# define SHOW_SBITS(name, gb, num) SHOW_SBITS_BE(name, gb, num) +#endif + +#define GET_CACHE(name, gb) ((uint32_t) name ## _cache) + +#endif + +static inline int get_bits_count(const GetBitContext *s) +{ +#if CACHED_BITSTREAM_READER + return s->index - s->bits_left; +#else + return s->index; +#endif +} + +#if CACHED_BITSTREAM_READER +static inline void refill_32(GetBitContext *s, int is_le) +{ +#if !UNCHECKED_BITSTREAM_READER + if (s->index >> 3 >= s->buffer_end - s->buffer) + return; +#endif + + if (is_le) + s->cache = (uint64_t)AV_RL32(s->buffer + (s->index >> 3)) << s->bits_left | s->cache; + else + s->cache = s->cache | (uint64_t)AV_RB32(s->buffer + (s->index >> 3)) << (32 - s->bits_left); + s->index += 32; + s->bits_left += 32; +} + +static inline void refill_64(GetBitContext *s, int is_le) +{ +#if !UNCHECKED_BITSTREAM_READER + if (s->index >> 3 >= s->buffer_end - s->buffer) + return; +#endif + + if (is_le) + s->cache = AV_RL64(s->buffer + (s->index >> 3)); + else + s->cache = AV_RB64(s->buffer + (s->index >> 3)); + s->index += 64; + s->bits_left = 64; +} + +static inline uint64_t get_val(GetBitContext *s, unsigned n, int is_le) +{ + uint64_t ret; + av_assert2(n>0 && n<=63); + if (is_le) { + ret = s->cache & ((UINT64_C(1) << n) - 1); + s->cache >>= n; + } else { + ret = s->cache >> (64 - n); + s->cache <<= n; + } + s->bits_left -= n; + return ret; +} + +static inline unsigned show_val(const GetBitContext *s, unsigned n) +{ +#ifdef BITSTREAM_READER_LE + return s->cache & ((UINT64_C(1) << n) - 1); +#else + return s->cache >> (64 - n); +#endif +} +#endif + +/** + * Skips the specified number of bits. + * @param n the number of bits to skip, + * For the UNCHECKED_BITSTREAM_READER this must not cause the distance + * from the start to overflow int32_t. Staying within the bitstream + padding + * is sufficient, too. + */ +static inline void skip_bits_long(GetBitContext *s, int n) +{ +#if CACHED_BITSTREAM_READER + skip_bits(s, n); +#else +#if UNCHECKED_BITSTREAM_READER + s->index += n; +#else + s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index); +#endif +#endif +} + +#if CACHED_BITSTREAM_READER +static inline void skip_remaining(GetBitContext *s, unsigned n) +{ +#ifdef BITSTREAM_READER_LE + s->cache >>= n; +#else + s->cache <<= n; +#endif + s->bits_left -= n; +} +#endif + +/** + * Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB). + * if MSB not set it is negative + * @param n length in bits + */ +static inline int get_xbits(GetBitContext *s, int n) +{ +#if CACHED_BITSTREAM_READER + int32_t cache = show_bits(s, 32); + int sign = ~cache >> 31; + skip_remaining(s, n); + + return ((((uint32_t)(sign ^ cache)) >> (32 - n)) ^ sign) - sign; +#else + register int sign; + register int32_t cache; + OPEN_READER(re, s); + av_assert2(n>0 && n<=25); + UPDATE_CACHE(re, s); + cache = GET_CACHE(re, s); + sign = ~cache >> 31; + LAST_SKIP_BITS(re, s, n); + CLOSE_READER(re, s); + return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; +#endif +} + +#if !CACHED_BITSTREAM_READER +static inline int get_xbits_le(GetBitContext *s, int n) +{ + register int sign; + register int32_t cache; + OPEN_READER(re, s); + av_assert2(n>0 && n<=25); + UPDATE_CACHE_LE(re, s); + cache = GET_CACHE(re, s); + sign = sign_extend(~cache, n) >> 31; + LAST_SKIP_BITS(re, s, n); + CLOSE_READER(re, s); + return (zero_extend(sign ^ cache, n) ^ sign) - sign; +} +#endif + +static inline int get_sbits(GetBitContext *s, int n) +{ + register int tmp; +#if CACHED_BITSTREAM_READER + av_assert2(n>0 && n<=25); + tmp = sign_extend(get_bits(s, n), n); +#else + OPEN_READER(re, s); + av_assert2(n>0 && n<=25); + UPDATE_CACHE(re, s); + tmp = SHOW_SBITS(re, s, n); + LAST_SKIP_BITS(re, s, n); + CLOSE_READER(re, s); +#endif + return tmp; +} + +/** + * Read 1-25 bits. + */ +static inline unsigned int get_bits(GetBitContext *s, int n) +{ + register unsigned int tmp; +#if CACHED_BITSTREAM_READER + + av_assert2(n>0 && n<=32); + if (n > s->bits_left) { +#ifdef BITSTREAM_READER_LE + refill_32(s, 1); +#else + refill_32(s, 0); +#endif + if (s->bits_left < 32) + s->bits_left = n; + } + +#ifdef BITSTREAM_READER_LE + tmp = get_val(s, n, 1); +#else + tmp = get_val(s, n, 0); +#endif +#else + OPEN_READER(re, s); + av_assert2(n>0 && n<=25); + UPDATE_CACHE(re, s); + tmp = SHOW_UBITS(re, s, n); + LAST_SKIP_BITS(re, s, n); + CLOSE_READER(re, s); +#endif + av_assert2(tmp < UINT64_C(1) << n); + return tmp; +} + +/** + * Read 0-25 bits. + */ +static av_always_inline int get_bitsz(GetBitContext *s, int n) +{ + return n ? get_bits(s, n) : 0; +} + +static inline unsigned int get_bits_le(GetBitContext *s, int n) +{ +#if CACHED_BITSTREAM_READER + av_assert2(n>0 && n<=32); + if (n > s->bits_left) { + refill_32(s, 1); + if (s->bits_left < 32) + s->bits_left = n; + } + + return get_val(s, n, 1); +#else + register int tmp; + OPEN_READER(re, s); + av_assert2(n>0 && n<=25); + UPDATE_CACHE_LE(re, s); + tmp = SHOW_UBITS_LE(re, s, n); + LAST_SKIP_BITS(re, s, n); + CLOSE_READER(re, s); + return tmp; +#endif +} + +/** + * Show 1-25 bits. + */ +static inline unsigned int show_bits(GetBitContext *s, int n) +{ + register unsigned int tmp; +#if CACHED_BITSTREAM_READER + if (n > s->bits_left) +#ifdef BITSTREAM_READER_LE + refill_32(s, 1); +#else + refill_32(s, 0); +#endif + + tmp = show_val(s, n); +#else + OPEN_READER_NOSIZE(re, s); + av_assert2(n>0 && n<=25); + UPDATE_CACHE(re, s); + tmp = SHOW_UBITS(re, s, n); +#endif + return tmp; +} + +static inline void skip_bits(GetBitContext *s, int n) +{ +#if CACHED_BITSTREAM_READER + if (n < s->bits_left) + skip_remaining(s, n); + else { + n -= s->bits_left; + s->cache = 0; + s->bits_left = 0; + + if (n >= 64) { + unsigned skip = (n / 8) * 8; + + n -= skip; + s->index += skip; + } +#ifdef BITSTREAM_READER_LE + refill_64(s, 1); +#else + refill_64(s, 0); +#endif + if (n) + skip_remaining(s, n); + } +#else + OPEN_READER(re, s); + LAST_SKIP_BITS(re, s, n); + CLOSE_READER(re, s); +#endif +} + +static inline unsigned int get_bits1(GetBitContext *s) +{ +#if CACHED_BITSTREAM_READER + if (!s->bits_left) +#ifdef BITSTREAM_READER_LE + refill_64(s, 1); +#else + refill_64(s, 0); +#endif + +#ifdef BITSTREAM_READER_LE + return get_val(s, 1, 1); +#else + return get_val(s, 1, 0); +#endif +#else + unsigned int index = s->index; + uint8_t result = s->buffer[index >> 3]; +#ifdef BITSTREAM_READER_LE + result >>= index & 7; + result &= 1; +#else + result <<= index & 7; + result >>= 8 - 1; +#endif +#if !UNCHECKED_BITSTREAM_READER + if (s->index < s->size_in_bits_plus8) +#endif + index++; + s->index = index; + + return result; +#endif +} + +static inline unsigned int show_bits1(GetBitContext *s) +{ + return show_bits(s, 1); +} + +static inline void skip_bits1(GetBitContext *s) +{ + skip_bits(s, 1); +} + +/** + * Read 0-32 bits. + */ +static inline unsigned int get_bits_long(GetBitContext *s, int n) +{ + av_assert2(n>=0 && n<=32); + if (!n) { + return 0; +#if CACHED_BITSTREAM_READER + } + return get_bits(s, n); +#else + } else if (n <= MIN_CACHE_BITS) { + return get_bits(s, n); + } else { +#ifdef BITSTREAM_READER_LE + unsigned ret = get_bits(s, 16); + return ret | (get_bits(s, n - 16) << 16); +#else + unsigned ret = get_bits(s, 16) << (n - 16); + return ret | get_bits(s, n - 16); +#endif + } +#endif +} + +/** + * Read 0-64 bits. + */ +static inline uint64_t get_bits64(GetBitContext *s, int n) +{ + if (n <= 32) { + return get_bits_long(s, n); + } else { +#ifdef BITSTREAM_READER_LE + uint64_t ret = get_bits_long(s, 32); + return ret | (uint64_t) get_bits_long(s, n - 32) << 32; +#else + uint64_t ret = (uint64_t) get_bits_long(s, n - 32) << 32; + return ret | get_bits_long(s, 32); +#endif + } +} + +/** + * Read 0-32 bits as a signed integer. + */ +static inline int get_sbits_long(GetBitContext *s, int n) +{ + // sign_extend(x, 0) is undefined + if (!n) + return 0; + + return sign_extend(get_bits_long(s, n), n); +} + +/** + * Show 0-32 bits. + */ +static inline unsigned int show_bits_long(GetBitContext *s, int n) +{ + if (n <= MIN_CACHE_BITS) { + return show_bits(s, n); + } else { + GetBitContext gb = *s; + return get_bits_long(&gb, n); + } +} + +static inline int check_marker(void *logctx, GetBitContext *s, const char *msg) +{ + int bit = get_bits1(s); + if (!bit) + av_log(logctx, AV_LOG_INFO, "Marker bit missing at %d of %d %s\n", + get_bits_count(s) - 1, s->size_in_bits, msg); + + return bit; +} + +static inline int init_get_bits_xe(GetBitContext *s, const uint8_t *buffer, + int bit_size, int is_le) +{ + int buffer_size; + int ret = 0; + + if (bit_size >= INT_MAX - FFMAX(7, AV_INPUT_BUFFER_PADDING_SIZE*8) || bit_size < 0 || !buffer) { + bit_size = 0; + buffer = NULL; + ret = AVERROR_INVALIDDATA; + } + + buffer_size = (bit_size + 7) >> 3; + + s->buffer = buffer; + s->size_in_bits = bit_size; + s->size_in_bits_plus8 = bit_size + 8; + s->buffer_end = buffer + buffer_size; + s->index = 0; + +#if CACHED_BITSTREAM_READER + s->cache = 0; + s->bits_left = 0; + refill_64(s, is_le); +#endif + + return ret; +} + +/** + * Initialize GetBitContext. + * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes + * larger than the actual read bits because some optimized bitstream + * readers read 32 or 64 bit at once and could read over the end + * @param bit_size the size of the buffer in bits + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. + */ +static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, + int bit_size) +{ +#ifdef BITSTREAM_READER_LE + return init_get_bits_xe(s, buffer, bit_size, 1); +#else + return init_get_bits_xe(s, buffer, bit_size, 0); +#endif +} + +/** + * Initialize GetBitContext. + * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes + * larger than the actual read bits because some optimized bitstream + * readers read 32 or 64 bit at once and could read over the end + * @param byte_size the size of the buffer in bytes + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. + */ +static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer, + int byte_size) +{ + if (byte_size > INT_MAX / 8 || byte_size < 0) + byte_size = -1; + return init_get_bits(s, buffer, byte_size * 8); +} + +static inline int init_get_bits8_le(GetBitContext *s, const uint8_t *buffer, + int byte_size) +{ + if (byte_size > INT_MAX / 8 || byte_size < 0) + byte_size = -1; + return init_get_bits_xe(s, buffer, byte_size * 8, 1); +} + +static inline const uint8_t *align_get_bits(GetBitContext *s) +{ + int n = -get_bits_count(s) & 7; + if (n) + skip_bits(s, n); + return s->buffer + (s->index >> 3); +} + +/** + * If the vlc code is invalid and max_depth=1, then no bits will be removed. + * If the vlc code is invalid and max_depth>1, then the number of bits removed + * is undefined. + */ +#define GET_VLC(code, name, gb, table, bits, max_depth) \ + do { \ + int n, nb_bits; \ + unsigned int index; \ + \ + index = SHOW_UBITS(name, gb, bits); \ + code = table[index][0]; \ + n = table[index][1]; \ + \ + if (max_depth > 1 && n < 0) { \ + LAST_SKIP_BITS(name, gb, bits); \ + UPDATE_CACHE(name, gb); \ + \ + nb_bits = -n; \ + \ + index = SHOW_UBITS(name, gb, nb_bits) + code; \ + code = table[index][0]; \ + n = table[index][1]; \ + if (max_depth > 2 && n < 0) { \ + LAST_SKIP_BITS(name, gb, nb_bits); \ + UPDATE_CACHE(name, gb); \ + \ + nb_bits = -n; \ + \ + index = SHOW_UBITS(name, gb, nb_bits) + code; \ + code = table[index][0]; \ + n = table[index][1]; \ + } \ + } \ + SKIP_BITS(name, gb, n); \ + } while (0) + +#define GET_RL_VLC(level, run, name, gb, table, bits, \ + max_depth, need_update) \ + do { \ + int n, nb_bits; \ + unsigned int index; \ + \ + index = SHOW_UBITS(name, gb, bits); \ + level = table[index].level; \ + n = table[index].len; \ + \ + if (max_depth > 1 && n < 0) { \ + SKIP_BITS(name, gb, bits); \ + if (need_update) { \ + UPDATE_CACHE(name, gb); \ + } \ + \ + nb_bits = -n; \ + \ + index = SHOW_UBITS(name, gb, nb_bits) + level; \ + level = table[index].level; \ + n = table[index].len; \ + if (max_depth > 2 && n < 0) { \ + LAST_SKIP_BITS(name, gb, nb_bits); \ + if (need_update) { \ + UPDATE_CACHE(name, gb); \ + } \ + nb_bits = -n; \ + \ + index = SHOW_UBITS(name, gb, nb_bits) + level; \ + level = table[index].level; \ + n = table[index].len; \ + } \ + } \ + run = table[index].run; \ + SKIP_BITS(name, gb, n); \ + } while (0) + +/* Return the LUT element for the given bitstream configuration. */ +static inline int set_idx(GetBitContext *s, int code, int *n, int *nb_bits, + VLC_TYPE (*table)[2]) +{ + unsigned idx; + + *nb_bits = -*n; + idx = show_bits(s, *nb_bits) + code; + *n = table[idx][1]; + + return table[idx][0]; +} + +/** + * Parse a vlc code. + * @param bits is the number of bits which will be read at once, must be + * identical to nb_bits in init_vlc() + * @param max_depth is the number of times bits bits must be read to completely + * read the longest vlc code + * = (max_vlc_length + bits - 1) / bits + * @returns the code parsed or -1 if no vlc matches + */ +static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], + int bits, int max_depth) +{ +#if CACHED_BITSTREAM_READER + int nb_bits; + unsigned idx = show_bits(s, bits); + int code = table[idx][0]; + int n = table[idx][1]; + + if (max_depth > 1 && n < 0) { + skip_remaining(s, bits); + code = set_idx(s, code, &n, &nb_bits, table); + if (max_depth > 2 && n < 0) { + skip_remaining(s, nb_bits); + code = set_idx(s, code, &n, &nb_bits, table); + } + } + skip_remaining(s, n); + + return code; +#else + int code; + + OPEN_READER(re, s); + UPDATE_CACHE(re, s); + + GET_VLC(code, re, s, table, bits, max_depth); + + CLOSE_READER(re, s); + + return code; +#endif +} + +static inline int decode012(GetBitContext *gb) +{ + int n; + n = get_bits1(gb); + if (n == 0) + return 0; + else + return get_bits1(gb) + 1; +} + +static inline int decode210(GetBitContext *gb) +{ + if (get_bits1(gb)) + return 0; + else + return 2 - get_bits1(gb); +} + +static inline int get_bits_left(GetBitContext *gb) +{ + return gb->size_in_bits - get_bits_count(gb); +} + +static inline int skip_1stop_8data_bits(GetBitContext *gb) +{ + if (get_bits_left(gb) <= 0) + return AVERROR_INVALIDDATA; + + while (get_bits1(gb)) { + skip_bits(gb, 8); + if (get_bits_left(gb) <= 0) + return AVERROR_INVALIDDATA; + } + + return 0; +} + +#endif /* AVCODEC_GET_BITS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/golomb.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/golomb.c new file mode 100644 index 000000000..937ac22ce --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/golomb.c @@ -0,0 +1,173 @@ +/* + * exp golomb vlc stuff + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief + * exp golomb vlc stuff + * @author Michael Niedermayer + */ + +#include "libavutil/common.h" + +const uint8_t ff_golomb_vlc_len[512]={ +19,17,15,15,13,13,13,13,11,11,11,11,11,11,11,11,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,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, +5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, +5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +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,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,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,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,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,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +}; + +const uint8_t ff_ue_golomb_vlc_code[512]={ +32,32,32,32,32,32,32,32,31,32,32,32,32,32,32,32,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 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, 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, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +const int8_t ff_se_golomb_vlc_code[512]={ + 17, 17, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15, + 4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + 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, 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, -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, -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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + + +const uint8_t ff_ue_golomb_len[256]={ + 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, +11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13, +13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, +13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17, +}; + +const uint8_t ff_interleaved_golomb_vlc_len[256]={ +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +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,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,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,1,1,1,1,1,1,1,1,1,1,1, +}; + +const uint8_t ff_interleaved_ue_golomb_vlc_code[256]={ + 15,16,7, 7, 17,18,8, 8, 3, 3, 3, 3, 3, 3, 3, 3, + 19,20,9, 9, 21,22,10,10,4, 4, 4, 4, 4, 4, 4, 4, + 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, + 23,24,11,11,25,26,12,12,5, 5, 5, 5, 5, 5, 5, 5, + 27,28,13,13,29,30,14,14,6, 6, 6, 6, 6, 6, 6, 6, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +const int8_t ff_interleaved_se_golomb_vlc_code[256]={ + 8, -8, 4, 4, 9, -9, -4, -4, 2, 2, 2, 2, 2, 2, 2, 2, + 10,-10, 5, 5, 11,-11, -5, -5, -2, -2, -2, -2, -2, -2, -2, -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, + 12,-12, 6, 6, 13,-13, -6, -6, 3, 3, 3, 3, 3, 3, 3, 3, + 14,-14, 7, 7, 15,-15, -7, -7, -3, -3, -3, -3, -3, -3, -3, -3, + -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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]={ +0, 1, 0, 0, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, +4, 5, 2, 2, 6, 7, 3, 3, 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, +8, 9, 4, 4, 10,11,5, 5, 2, 2, 2, 2, 2, 2, 2, 2, +12,13,6, 6, 14,15,7, 7, 3, 3, 3, 3, 3, 3, 3, 3, +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, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/golomb.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/golomb.h new file mode 100644 index 000000000..5cdfa0945 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/golomb.h @@ -0,0 +1,747 @@ +/* + * exp golomb vlc stuff + * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2004 Alex Beregszaszi + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief + * exp golomb vlc stuff + * @author Michael Niedermayer and Alex Beregszaszi + */ + +#ifndef AVCODEC_GOLOMB_H +#define AVCODEC_GOLOMB_H + +#include + +#include "get_bits.h" +#include "put_bits.h" + +#define INVALID_VLC 0x80000000 + +extern const uint8_t ff_golomb_vlc_len[512]; +extern const uint8_t ff_ue_golomb_vlc_code[512]; +extern const int8_t ff_se_golomb_vlc_code[512]; +extern const uint8_t ff_ue_golomb_len[256]; + +extern const uint8_t ff_interleaved_golomb_vlc_len[256]; +extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256]; +extern const int8_t ff_interleaved_se_golomb_vlc_code[256]; +extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]; + +/** + * Read an unsigned Exp-Golomb code in the range 0 to 8190. + * + * @returns the read value or a negative error code. + */ +static inline int get_ue_golomb(GetBitContext *gb) +{ + unsigned int buf; + +#if CACHED_BITSTREAM_READER + buf = show_bits_long(gb, 32); + + if (buf >= (1 << 27)) { + buf >>= 32 - 9; + skip_bits_long(gb, ff_golomb_vlc_len[buf]); + + return ff_ue_golomb_vlc_code[buf]; + } else { + int log = 2 * av_log2(buf) - 31; + buf >>= log; + buf--; + skip_bits_long(gb, 32 - log); + + return buf; + } +#else + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + if (buf >= (1 << 27)) { + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_ue_golomb_vlc_code[buf]; + } else { + int log = 2 * av_log2(buf) - 31; + LAST_SKIP_BITS(re, gb, 32 - log); + CLOSE_READER(re, gb); + if (log < 7) { + av_log(NULL, AV_LOG_ERROR, "Invalid UE golomb code\n"); + return AVERROR_INVALIDDATA; + } + buf >>= log; + buf--; + + return buf; + } +#endif +} + +/** + * Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1. + */ +static inline unsigned get_ue_golomb_long(GetBitContext *gb) +{ + unsigned buf, log; + + buf = show_bits_long(gb, 32); + log = 31 - av_log2(buf); + skip_bits_long(gb, log); + + return get_bits_long(gb, log + 1) - 1; +} + +/** + * read unsigned exp golomb code, constraint to a max of 31. + * the return value is undefined if the stored value exceeds 31. + */ +static inline int get_ue_golomb_31(GetBitContext *gb) +{ + unsigned int buf; + +#if CACHED_BITSTREAM_READER + buf = show_bits_long(gb, 32); + + buf >>= 32 - 9; + skip_bits_long(gb, ff_golomb_vlc_len[buf]); +#else + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); +#endif + + return ff_ue_golomb_vlc_code[buf]; +} + +static inline unsigned get_interleaved_ue_golomb(GetBitContext *gb) +{ + uint32_t buf; + +#if CACHED_BITSTREAM_READER + buf = show_bits_long(gb, 32); + + if (buf & 0xAA800000) { + buf >>= 32 - 8; + skip_bits_long(gb, ff_interleaved_golomb_vlc_len[buf]); + + return ff_interleaved_ue_golomb_vlc_code[buf]; + } else { + unsigned ret = 1; + + do { + buf >>= 32 - 8; + skip_bits_long(gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); + + if (ff_interleaved_golomb_vlc_len[buf] != 9) { + ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1; + ret |= ff_interleaved_dirac_golomb_vlc_code[buf]; + break; + } + ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; + buf = show_bits_long(gb, 32); + } while (get_bits_left(gb) > 0); + + return ret - 1; + } +#else + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + if (buf & 0xAA800000) { + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_ue_golomb_vlc_code[buf]; + } else { + unsigned ret = 1; + + do { + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, + FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); + + if (ff_interleaved_golomb_vlc_len[buf] != 9) { + ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1; + ret |= ff_interleaved_dirac_golomb_vlc_code[buf]; + break; + } + ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + } while (ret<0x8000000U && BITS_AVAILABLE(re, gb)); + + CLOSE_READER(re, gb); + return ret - 1; + } +#endif +} + +/** + * read unsigned truncated exp golomb code. + */ +static inline int get_te0_golomb(GetBitContext *gb, int range) +{ + av_assert2(range >= 1); + + if (range == 1) + return 0; + else if (range == 2) + return get_bits1(gb) ^ 1; + else + return get_ue_golomb(gb); +} + +/** + * read unsigned truncated exp golomb code. + */ +static inline int get_te_golomb(GetBitContext *gb, int range) +{ + av_assert2(range >= 1); + + if (range == 2) + return get_bits1(gb) ^ 1; + else + return get_ue_golomb(gb); +} + +/** + * read signed exp golomb code. + */ +static inline int get_se_golomb(GetBitContext *gb) +{ + unsigned int buf; + +#if CACHED_BITSTREAM_READER + buf = show_bits_long(gb, 32); + + if (buf >= (1 << 27)) { + buf >>= 32 - 9; + skip_bits_long(gb, ff_golomb_vlc_len[buf]); + + return ff_se_golomb_vlc_code[buf]; + } else { + int log = 2 * av_log2(buf) - 31; + buf >>= log; + + skip_bits_long(gb, 32 - log); + + if (buf & 1) + buf = -(buf >> 1); + else + buf = (buf >> 1); + + return buf; + } +#else + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + if (buf >= (1 << 27)) { + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_se_golomb_vlc_code[buf]; + } else { + int log = av_log2(buf), sign; + LAST_SKIP_BITS(re, gb, 31 - log); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + buf >>= log; + + LAST_SKIP_BITS(re, gb, 32 - log); + CLOSE_READER(re, gb); + + sign = -(buf & 1); + buf = ((buf >> 1) ^ sign) - sign; + + return buf; + } +#endif +} + +static inline int get_se_golomb_long(GetBitContext *gb) +{ + unsigned int buf = get_ue_golomb_long(gb); + int sign = (buf & 1) - 1; + return ((buf >> 1) ^ sign) + 1; +} + +static inline int get_interleaved_se_golomb(GetBitContext *gb) +{ + unsigned int buf; + +#if CACHED_BITSTREAM_READER + buf = show_bits_long(gb, 32); + + if (buf & 0xAA800000) { + buf >>= 32 - 8; + skip_bits_long(gb, ff_interleaved_golomb_vlc_len[buf]); + + return ff_interleaved_se_golomb_vlc_code[buf]; + } else { + int log; + skip_bits(gb, 8); + buf |= 1 | show_bits_long(gb, 24); + + if ((buf & 0xAAAAAAAA) == 0) + return INVALID_VLC; + + for (log = 31; (buf & 0x80000000) == 0; log--) + buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + + skip_bits_long(gb, 63 - 2 * log - 8); + + return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; + } +#else + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + if (buf & 0xAA800000) { + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_se_golomb_vlc_code[buf]; + } else { + int log; + LAST_SKIP_BITS(re, gb, 8); + UPDATE_CACHE(re, gb); + buf |= 1 | (GET_CACHE(re, gb) >> 8); + + if ((buf & 0xAAAAAAAA) == 0) + return INVALID_VLC; + + for (log = 31; (buf & 0x80000000) == 0; log--) + buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + + LAST_SKIP_BITS(re, gb, 63 - 2 * log - 8); + CLOSE_READER(re, gb); + + return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; + } +#endif +} + +static inline int dirac_get_se_golomb(GetBitContext *gb) +{ + uint32_t ret = get_interleaved_ue_golomb(gb); + + if (ret) { + int sign = -get_bits1(gb); + ret = (ret ^ sign) - sign; + } + + return ret; +} + +/** + * read unsigned golomb rice code (ffv1). + */ +static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, + int esc_len) +{ + unsigned int buf; + int log; + +#if CACHED_BITSTREAM_READER + buf = show_bits_long(gb, 32); + + log = av_log2(buf); + + if (log > 31 - limit) { + buf >>= log - k; + buf += (30 - log) << k; + skip_bits_long(gb, 32 + k - log); + + return buf; + } else { + skip_bits_long(gb, limit); + buf = get_bits_long(gb, esc_len); + + return buf + limit - 1; + } +#else + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + log = av_log2(buf); + + if (log > 31 - limit) { + buf >>= log - k; + buf += (30U - log) << k; + LAST_SKIP_BITS(re, gb, 32 + k - log); + CLOSE_READER(re, gb); + + return buf; + } else { + LAST_SKIP_BITS(re, gb, limit); + UPDATE_CACHE(re, gb); + + buf = SHOW_UBITS(re, gb, esc_len); + + LAST_SKIP_BITS(re, gb, esc_len); + CLOSE_READER(re, gb); + + return buf + limit - 1; + } +#endif +} + +/** + * read unsigned golomb rice code (jpegls). + */ +static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, + int esc_len) +{ + unsigned int buf; + int log; + +#if CACHED_BITSTREAM_READER + buf = show_bits_long(gb, 32); + + log = av_log2(buf); + + if (log - k >= 1 && 32 - log < limit) { + buf >>= log - k; + buf += (30 - log) << k; + skip_bits_long(gb, 32 + k - log); + + return buf; + } else { + int i; + for (i = 0; + i < limit && get_bits1(gb) == 0 && get_bits_left(gb) > 0; + i++); + + if (i < limit - 1) { + buf = get_bits_long(gb, k); + + return buf + (i << k); + } else if (i == limit - 1) { + buf = get_bits_long(gb, esc_len); + + return buf + 1; + } else + return -1; + } +#else + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); + + log = av_log2(buf); + + av_assert2(k <= 31); + + if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) && + 32 - log < limit) { + buf >>= log - k; + buf += (30U - log) << k; + LAST_SKIP_BITS(re, gb, 32 + k - log); + CLOSE_READER(re, gb); + + return buf; + } else { + int i; + for (i = 0; i + MIN_CACHE_BITS <= limit && SHOW_UBITS(re, gb, MIN_CACHE_BITS) == 0; i += MIN_CACHE_BITS) { + if (gb->size_in_bits <= re_index) { + CLOSE_READER(re, gb); + return -1; + } + LAST_SKIP_BITS(re, gb, MIN_CACHE_BITS); + UPDATE_CACHE(re, gb); + } + for (; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) { + SKIP_BITS(re, gb, 1); + } + LAST_SKIP_BITS(re, gb, 1); + UPDATE_CACHE(re, gb); + + if (i < limit - 1) { + if (k) { + if (k > MIN_CACHE_BITS - 1) { + buf = SHOW_UBITS(re, gb, 16) << (k-16); + LAST_SKIP_BITS(re, gb, 16); + UPDATE_CACHE(re, gb); + buf |= SHOW_UBITS(re, gb, k-16); + LAST_SKIP_BITS(re, gb, k-16); + } else { + buf = SHOW_UBITS(re, gb, k); + LAST_SKIP_BITS(re, gb, k); + } + } else { + buf = 0; + } + + buf += ((SUINT)i << k); + } else if (i == limit - 1) { + buf = SHOW_UBITS(re, gb, esc_len); + LAST_SKIP_BITS(re, gb, esc_len); + + buf ++; + } else { + buf = -1; + } + CLOSE_READER(re, gb); + return buf; + } +#endif +} + +/** + * read signed golomb rice code (ffv1). + */ +static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, + int esc_len) +{ + unsigned v = get_ur_golomb(gb, k, limit, esc_len); + return (v >> 1) ^ -(v & 1); +} + +/** + * read signed golomb rice code (flac). + */ +static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, + int esc_len) +{ + unsigned v = get_ur_golomb_jpegls(gb, k, limit, esc_len); + return (v >> 1) ^ -(v & 1); +} + +/** + * read unsigned golomb rice code (shorten). + */ +static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k) +{ + return get_ur_golomb_jpegls(gb, k, INT_MAX, 0); +} + +/** + * read signed golomb rice code (shorten). + */ +static inline int get_sr_golomb_shorten(GetBitContext *gb, int k) +{ + int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0); + return (uvar >> 1) ^ -(uvar & 1); +} + +#ifdef TRACE + +static inline int get_ue(GetBitContext *s, const char *file, const char *func, + int line) +{ + int show = show_bits(s, 24); + int pos = get_bits_count(s); + int i = get_ue_golomb(s); + int len = get_bits_count(s) - pos; + int bits = show >> (24 - len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", + bits, len, i, pos, file, func, line); + + return i; +} + +static inline int get_se(GetBitContext *s, const char *file, const char *func, + int line) +{ + int show = show_bits(s, 24); + int pos = get_bits_count(s); + int i = get_se_golomb(s); + int len = get_bits_count(s) - pos; + int bits = show >> (24 - len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", + bits, len, i, pos, file, func, line); + + return i; +} + +static inline int get_te(GetBitContext *s, int r, char *file, const char *func, + int line) +{ + int show = show_bits(s, 24); + int pos = get_bits_count(s); + int i = get_te0_golomb(s, r); + int len = get_bits_count(s) - pos; + int bits = show >> (24 - len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", + bits, len, i, pos, file, func, line); + + return i; +} + +#define get_ue_golomb(a) get_ue(a, __FILE__, __func__, __LINE__) +#define get_se_golomb(a) get_se(a, __FILE__, __func__, __LINE__) +#define get_te_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) +#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __func__, __LINE__) + +#endif /* TRACE */ + +/** + * write unsigned exp golomb code. 2^16 - 2 at most + */ +static inline void set_ue_golomb(PutBitContext *pb, int i) +{ + av_assert2(i >= 0); + av_assert2(i <= 0xFFFE); + + if (i < 256) + put_bits(pb, ff_ue_golomb_len[i], i + 1); + else { + int e = av_log2(i + 1); + put_bits(pb, 2 * e + 1, i + 1); + } +} + +/** + * write unsigned exp golomb code. 2^32-2 at most. + */ +static inline void set_ue_golomb_long(PutBitContext *pb, uint32_t i) +{ + av_assert2(i <= (UINT32_MAX - 1)); + + if (i < 256) + put_bits(pb, ff_ue_golomb_len[i], i + 1); + else { + int e = av_log2(i + 1); + put_bits64(pb, 2 * e + 1, i + 1); + } +} + +/** + * write truncated unsigned exp golomb code. + */ +static inline void set_te_golomb(PutBitContext *pb, int i, int range) +{ + av_assert2(range >= 1); + av_assert2(i <= range); + + if (range == 2) + put_bits(pb, 1, i ^ 1); + else + set_ue_golomb(pb, i); +} + +/** + * write signed exp golomb code. 16 bits at most. + */ +static inline void set_se_golomb(PutBitContext *pb, int i) +{ + i = 2 * i - 1; + if (i < 0) + i ^= -1; //FIXME check if gcc does the right thing + set_ue_golomb(pb, i); +} + +/** + * write unsigned golomb rice code (ffv1). + */ +static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, + int esc_len) +{ + int e; + + av_assert2(i >= 0); + + e = i >> k; + if (e < limit) + put_bits(pb, e + k + 1, (1 << k) + av_mod_uintp2(i, k)); + else + put_bits(pb, limit + esc_len, i - limit + 1); +} + +/** + * write unsigned golomb rice code (jpegls). + */ +static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, + int limit, int esc_len) +{ + int e; + + av_assert2(i >= 0); + + e = (i >> k) + 1; + if (e < limit) { + while (e > 31) { + put_bits(pb, 31, 0); + e -= 31; + } + put_bits(pb, e, 1); + if (k) + put_sbits(pb, k, i); + } else { + while (limit > 31) { + put_bits(pb, 31, 0); + limit -= 31; + } + put_bits(pb, limit, 1); + put_bits(pb, esc_len, i - 1); + } +} + +/** + * write signed golomb rice code (ffv1). + */ +static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, + int esc_len) +{ + int v; + + v = -2 * i - 1; + v ^= (v >> 31); + + set_ur_golomb(pb, v, k, limit, esc_len); +} + +/** + * write signed golomb rice code (flac). + */ +static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, + int limit, int esc_len) +{ + int v; + + v = -2 * i - 1; + v ^= (v >> 31); + + set_ur_golomb_jpegls(pb, v, k, limit, esc_len); +} + +#endif /* AVCODEC_GOLOMB_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h263dsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h263dsp.c new file mode 100644 index 000000000..b3c0bcd45 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h263dsp.c @@ -0,0 +1,126 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/common.h" +#include "config.h" +#include "h263dsp.h" + +const uint8_t ff_h263_loop_filter_strength[32] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12 +}; + +static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale) +{ + int y; + const int strength = ff_h263_loop_filter_strength[qscale]; + + for (y = 0; y < 8; y++) { + int d1, d2, ad1; + int p0 = src[y * stride - 2]; + int p1 = src[y * stride - 1]; + int p2 = src[y * stride + 0]; + int p3 = src[y * stride + 1]; + int d = (p0 - p3 + 4 * (p2 - p1)) / 8; + + if (d < -2 * strength) + d1 = 0; + else if (d < -strength) + d1 = -2 * strength - d; + else if (d < strength) + d1 = d; + else if (d < 2 * strength) + d1 = 2 * strength - d; + else + d1 = 0; + + p1 += d1; + p2 -= d1; + if (p1 & 256) + p1 = ~(p1 >> 31); + if (p2 & 256) + p2 = ~(p2 >> 31); + + src[y * stride - 1] = p1; + src[y * stride + 0] = p2; + + ad1 = FFABS(d1) >> 1; + + d2 = av_clip((p0 - p3) / 4, -ad1, ad1); + + src[y * stride - 2] = p0 - d2; + src[y * stride + 1] = p3 + d2; + } +} + +static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale) +{ + int x; + const int strength = ff_h263_loop_filter_strength[qscale]; + + for (x = 0; x < 8; x++) { + int d1, d2, ad1; + int p0 = src[x - 2 * stride]; + int p1 = src[x - 1 * stride]; + int p2 = src[x + 0 * stride]; + int p3 = src[x + 1 * stride]; + int d = (p0 - p3 + 4 * (p2 - p1)) / 8; + + if (d < -2 * strength) + d1 = 0; + else if (d < -strength) + d1 = -2 * strength - d; + else if (d < strength) + d1 = d; + else if (d < 2 * strength) + d1 = 2 * strength - d; + else + d1 = 0; + + p1 += d1; + p2 -= d1; + if (p1 & 256) + p1 = ~(p1 >> 31); + if (p2 & 256) + p2 = ~(p2 >> 31); + + src[x - 1 * stride] = p1; + src[x + 0 * stride] = p2; + + ad1 = FFABS(d1) >> 1; + + d2 = av_clip((p0 - p3) / 4, -ad1, ad1); + + src[x - 2 * stride] = p0 - d2; + src[x + stride] = p3 + d2; + } +} + +av_cold void ff_h263dsp_init(H263DSPContext *ctx) +{ + ctx->h263_h_loop_filter = h263_h_loop_filter_c; + ctx->h263_v_loop_filter = h263_v_loop_filter_c; + + if (ARCH_X86) + ff_h263dsp_init_x86(ctx); + if (ARCH_MIPS) + ff_h263dsp_init_mips(ctx); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h263dsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h263dsp.h new file mode 100644 index 000000000..1abea3ca8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h263dsp.h @@ -0,0 +1,35 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_H263DSP_H +#define AVCODEC_H263DSP_H + +#include + +extern const uint8_t ff_h263_loop_filter_strength[32]; + +typedef struct H263DSPContext { + void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); + void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); +} H263DSPContext; + +void ff_h263dsp_init(H263DSPContext *ctx); +void ff_h263dsp_init_x86(H263DSPContext *ctx); +void ff_h263dsp_init_mips(H263DSPContext *ctx); + +#endif /* AVCODEC_H263DSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h264chroma.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h264chroma.c new file mode 100644 index 000000000..c2f1f30f5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h264chroma.c @@ -0,0 +1,59 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "h264chroma.h" + +#define BIT_DEPTH 8 +#include "h264chroma_template.c" +#undef BIT_DEPTH + +#define BIT_DEPTH 16 +#include "h264chroma_template.c" +#undef BIT_DEPTH + +#define SET_CHROMA(depth) \ + c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_ ## depth ## _c; \ + c->put_h264_chroma_pixels_tab[1] = put_h264_chroma_mc4_ ## depth ## _c; \ + c->put_h264_chroma_pixels_tab[2] = put_h264_chroma_mc2_ ## depth ## _c; \ + c->put_h264_chroma_pixels_tab[3] = put_h264_chroma_mc1_ ## depth ## _c; \ + c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_ ## depth ## _c; \ + c->avg_h264_chroma_pixels_tab[1] = avg_h264_chroma_mc4_ ## depth ## _c; \ + c->avg_h264_chroma_pixels_tab[2] = avg_h264_chroma_mc2_ ## depth ## _c; \ + c->avg_h264_chroma_pixels_tab[3] = avg_h264_chroma_mc1_ ## depth ## _c; \ + +av_cold void ff_h264chroma_init(H264ChromaContext *c, int bit_depth) +{ + if (bit_depth > 8 && bit_depth <= 16) { + SET_CHROMA(16); + } else { + SET_CHROMA(8); + } + + if (ARCH_AARCH64) + ff_h264chroma_init_aarch64(c, bit_depth); + if (ARCH_ARM) + ff_h264chroma_init_arm(c, bit_depth); + if (ARCH_PPC) + ff_h264chroma_init_ppc(c, bit_depth); + if (ARCH_X86) + ff_h264chroma_init_x86(c, bit_depth); + if (ARCH_MIPS) + ff_h264chroma_init_mips(c, bit_depth); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h264chroma.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h264chroma.h new file mode 100644 index 000000000..5c89fd12d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/h264chroma.h @@ -0,0 +1,40 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_H264CHROMA_H +#define AVCODEC_H264CHROMA_H + +#include +#include + +typedef void (*h264_chroma_mc_func)(uint8_t *dst /*align 8*/, uint8_t *src /*align 1*/, ptrdiff_t srcStride, int h, int x, int y); + +typedef struct H264ChromaContext { + h264_chroma_mc_func put_h264_chroma_pixels_tab[4]; + h264_chroma_mc_func avg_h264_chroma_pixels_tab[4]; +} H264ChromaContext; + +void ff_h264chroma_init(H264ChromaContext *c, int bit_depth); + +void ff_h264chroma_init_aarch64(H264ChromaContext *c, int bit_depth); +void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth); +void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth); +void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth); +void ff_h264chroma_init_mips(H264ChromaContext *c, int bit_depth); + +#endif /* AVCODEC_H264CHROMA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hpeldsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hpeldsp.c new file mode 100644 index 000000000..8e2fd8fcf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hpeldsp.c @@ -0,0 +1,370 @@ +/* + * Half-pel DSP functions. + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Half-pel DSP functions. + */ + +#include "libavutil/attributes.h" +#include "libavutil/intreadwrite.h" +#include "hpeldsp.h" + +#define BIT_DEPTH 8 +#include "hpel_template.c" +#include "pel_template.c" + +#define PIXOP2(OPNAME, OP) \ +static inline void OPNAME ## _no_rnd_pixels8_l2_8(uint8_t *dst, \ + const uint8_t *src1, \ + const uint8_t *src2, \ + int dst_stride, \ + int src_stride1, \ + int src_stride2, \ + int h) \ +{ \ + int i; \ + \ + for (i = 0; i < h; i++) { \ + uint32_t a, b; \ + a = AV_RN32(&src1[i * src_stride1]); \ + b = AV_RN32(&src2[i * src_stride2]); \ + OP(*((uint32_t *) &dst[i * dst_stride]), \ + no_rnd_avg32(a, b)); \ + a = AV_RN32(&src1[i * src_stride1 + 4]); \ + b = AV_RN32(&src2[i * src_stride2 + 4]); \ + OP(*((uint32_t *) &dst[i * dst_stride + 4]), \ + no_rnd_avg32(a, b)); \ + } \ +} \ + \ +static inline void OPNAME ## _no_rnd_pixels8_x2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + OPNAME ## _no_rnd_pixels8_l2_8(block, pixels, pixels + 1, \ + line_size, line_size, line_size, h); \ +} \ + \ +static inline void OPNAME ## _pixels8_x2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + OPNAME ## _pixels8_l2_8(block, pixels, pixels + 1, \ + line_size, line_size, line_size, h); \ +} \ + \ +static inline void OPNAME ## _no_rnd_pixels8_y2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + OPNAME ## _no_rnd_pixels8_l2_8(block, pixels, pixels + line_size, \ + line_size, line_size, line_size, h); \ +} \ + \ +static inline void OPNAME ## _pixels8_y2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + OPNAME ## _pixels8_l2_8(block, pixels, pixels + line_size, \ + line_size, line_size, line_size, h); \ +} \ + \ +static inline void OPNAME ## _pixels4_x2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + OPNAME ## _pixels4_l2_8(block, pixels, pixels + 1, \ + line_size, line_size, line_size, h); \ +} \ + \ +static inline void OPNAME ## _pixels4_y2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + OPNAME ## _pixels4_l2_8(block, pixels, pixels + line_size, \ + line_size, line_size, line_size, h); \ +} \ + \ +static inline void OPNAME ## _pixels2_x2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + OPNAME ## _pixels2_l2_8(block, pixels, pixels + 1, \ + line_size, line_size, line_size, h); \ +} \ + \ +static inline void OPNAME ## _pixels2_y2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + OPNAME ## _pixels2_l2_8(block, pixels, pixels + line_size, \ + line_size, line_size, line_size, h); \ +} \ + \ +static inline void OPNAME ## _pixels2_xy2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + int i, a1, b1; \ + int a0 = pixels[0]; \ + int b0 = pixels[1] + 2; \ + \ + a0 += b0; \ + b0 += pixels[2]; \ + pixels += line_size; \ + for (i = 0; i < h; i += 2) { \ + a1 = pixels[0]; \ + b1 = pixels[1]; \ + a1 += b1; \ + b1 += pixels[2]; \ + \ + block[0] = (a1 + a0) >> 2; /* FIXME non put */ \ + block[1] = (b1 + b0) >> 2; \ + \ + pixels += line_size; \ + block += line_size; \ + \ + a0 = pixels[0]; \ + b0 = pixels[1] + 2; \ + a0 += b0; \ + b0 += pixels[2]; \ + \ + block[0] = (a1 + a0) >> 2; \ + block[1] = (b1 + b0) >> 2; \ + pixels += line_size; \ + block += line_size; \ + } \ +} \ + \ +static inline void OPNAME ## _pixels4_xy2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + /* FIXME HIGH BIT DEPTH */ \ + int i; \ + const uint32_t a = AV_RN32(pixels); \ + const uint32_t b = AV_RN32(pixels + 1); \ + uint32_t l0 = (a & 0x03030303UL) + \ + (b & 0x03030303UL) + \ + 0x02020202UL; \ + uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) + \ + ((b & 0xFCFCFCFCUL) >> 2); \ + uint32_t l1, h1; \ + \ + pixels += line_size; \ + for (i = 0; i < h; i += 2) { \ + uint32_t a = AV_RN32(pixels); \ + uint32_t b = AV_RN32(pixels + 1); \ + l1 = (a & 0x03030303UL) + \ + (b & 0x03030303UL); \ + h1 = ((a & 0xFCFCFCFCUL) >> 2) + \ + ((b & 0xFCFCFCFCUL) >> 2); \ + OP(*((uint32_t *) block), h0 + h1 + \ + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \ + pixels += line_size; \ + block += line_size; \ + a = AV_RN32(pixels); \ + b = AV_RN32(pixels + 1); \ + l0 = (a & 0x03030303UL) + \ + (b & 0x03030303UL) + \ + 0x02020202UL; \ + h0 = ((a & 0xFCFCFCFCUL) >> 2) + \ + ((b & 0xFCFCFCFCUL) >> 2); \ + OP(*((uint32_t *) block), h0 + h1 + \ + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \ + pixels += line_size; \ + block += line_size; \ + } \ +} \ + \ +static inline void OPNAME ## _pixels8_xy2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + /* FIXME HIGH BIT DEPTH */ \ + int j; \ + \ + for (j = 0; j < 2; j++) { \ + int i; \ + const uint32_t a = AV_RN32(pixels); \ + const uint32_t b = AV_RN32(pixels + 1); \ + uint32_t l0 = (a & 0x03030303UL) + \ + (b & 0x03030303UL) + \ + 0x02020202UL; \ + uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) + \ + ((b & 0xFCFCFCFCUL) >> 2); \ + uint32_t l1, h1; \ + \ + pixels += line_size; \ + for (i = 0; i < h; i += 2) { \ + uint32_t a = AV_RN32(pixels); \ + uint32_t b = AV_RN32(pixels + 1); \ + l1 = (a & 0x03030303UL) + \ + (b & 0x03030303UL); \ + h1 = ((a & 0xFCFCFCFCUL) >> 2) + \ + ((b & 0xFCFCFCFCUL) >> 2); \ + OP(*((uint32_t *) block), h0 + h1 + \ + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \ + pixels += line_size; \ + block += line_size; \ + a = AV_RN32(pixels); \ + b = AV_RN32(pixels + 1); \ + l0 = (a & 0x03030303UL) + \ + (b & 0x03030303UL) + \ + 0x02020202UL; \ + h0 = ((a & 0xFCFCFCFCUL) >> 2) + \ + ((b & 0xFCFCFCFCUL) >> 2); \ + OP(*((uint32_t *) block), h0 + h1 + \ + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \ + pixels += line_size; \ + block += line_size; \ + } \ + pixels += 4 - line_size * (h + 1); \ + block += 4 - line_size * h; \ + } \ +} \ + \ +static inline void OPNAME ## _no_rnd_pixels8_xy2_8_c(uint8_t *block, \ + const uint8_t *pixels, \ + ptrdiff_t line_size, \ + int h) \ +{ \ + /* FIXME HIGH BIT DEPTH */ \ + int j; \ + \ + for (j = 0; j < 2; j++) { \ + int i; \ + const uint32_t a = AV_RN32(pixels); \ + const uint32_t b = AV_RN32(pixels + 1); \ + uint32_t l0 = (a & 0x03030303UL) + \ + (b & 0x03030303UL) + \ + 0x01010101UL; \ + uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) + \ + ((b & 0xFCFCFCFCUL) >> 2); \ + uint32_t l1, h1; \ + \ + pixels += line_size; \ + for (i = 0; i < h; i += 2) { \ + uint32_t a = AV_RN32(pixels); \ + uint32_t b = AV_RN32(pixels + 1); \ + l1 = (a & 0x03030303UL) + \ + (b & 0x03030303UL); \ + h1 = ((a & 0xFCFCFCFCUL) >> 2) + \ + ((b & 0xFCFCFCFCUL) >> 2); \ + OP(*((uint32_t *) block), h0 + h1 + \ + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \ + pixels += line_size; \ + block += line_size; \ + a = AV_RN32(pixels); \ + b = AV_RN32(pixels + 1); \ + l0 = (a & 0x03030303UL) + \ + (b & 0x03030303UL) + \ + 0x01010101UL; \ + h0 = ((a & 0xFCFCFCFCUL) >> 2) + \ + ((b & 0xFCFCFCFCUL) >> 2); \ + OP(*((uint32_t *) block), h0 + h1 + \ + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \ + pixels += line_size; \ + block += line_size; \ + } \ + pixels += 4 - line_size * (h + 1); \ + block += 4 - line_size * h; \ + } \ +} \ + \ +CALL_2X_PIXELS(OPNAME ## _pixels16_x2_8_c, \ + OPNAME ## _pixels8_x2_8_c, \ + 8) \ +CALL_2X_PIXELS(OPNAME ## _pixels16_y2_8_c, \ + OPNAME ## _pixels8_y2_8_c, \ + 8) \ +CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_8_c, \ + OPNAME ## _pixels8_xy2_8_c, \ + 8) \ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_8_c, \ + OPNAME ## _pixels8_8_c, \ + 8) \ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_x2_8_c, \ + OPNAME ## _no_rnd_pixels8_x2_8_c, \ + 8) \ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_y2_8_c, \ + OPNAME ## _no_rnd_pixels8_y2_8_c, \ + 8) \ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_8_c, \ + OPNAME ## _no_rnd_pixels8_xy2_8_c, \ + 8) \ + +#define op_avg(a, b) a = rnd_avg32(a, b) +#define op_put(a, b) a = b +#define put_no_rnd_pixels8_8_c put_pixels8_8_c +PIXOP2(avg, op_avg) +PIXOP2(put, op_put) +#undef op_avg +#undef op_put + +av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags) +{ +#define hpel_funcs(prefix, idx, num) \ + c->prefix ## _pixels_tab idx [0] = prefix ## _pixels ## num ## _8_c; \ + c->prefix ## _pixels_tab idx [1] = prefix ## _pixels ## num ## _x2_8_c; \ + c->prefix ## _pixels_tab idx [2] = prefix ## _pixels ## num ## _y2_8_c; \ + c->prefix ## _pixels_tab idx [3] = prefix ## _pixels ## num ## _xy2_8_c + + hpel_funcs(put, [0], 16); + hpel_funcs(put, [1], 8); + hpel_funcs(put, [2], 4); + hpel_funcs(put, [3], 2); + hpel_funcs(put_no_rnd, [0], 16); + hpel_funcs(put_no_rnd, [1], 8); + hpel_funcs(avg, [0], 16); + hpel_funcs(avg, [1], 8); + hpel_funcs(avg, [2], 4); + hpel_funcs(avg, [3], 2); + hpel_funcs(avg_no_rnd,, 16); + + if (ARCH_AARCH64) + ff_hpeldsp_init_aarch64(c, flags); + if (ARCH_ALPHA) + ff_hpeldsp_init_alpha(c, flags); + if (ARCH_ARM) + ff_hpeldsp_init_arm(c, flags); + if (ARCH_PPC) + ff_hpeldsp_init_ppc(c, flags); + if (ARCH_X86) + ff_hpeldsp_init_x86(c, flags); + if (ARCH_MIPS) + ff_hpeldsp_init_mips(c, flags); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hpeldsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hpeldsp.h new file mode 100644 index 000000000..768139bfc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hpeldsp.h @@ -0,0 +1,106 @@ +/* + * Half-pel DSP functions. + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Half-pel DSP functions. + */ + +#ifndef AVCODEC_HPELDSP_H +#define AVCODEC_HPELDSP_H + +#include +#include + +/* add and put pixel (decoding) */ +// blocksizes for hpel_pixels_func are 8x4,8x8 16x8 16x16 +// h for hpel_pixels_func is limited to {width/2, width} but never larger +// than 16 and never smaller than 4 +typedef void (*op_pixels_func)(uint8_t *block /*align width (8 or 16)*/, + const uint8_t *pixels /*align 1*/, + ptrdiff_t line_size, int h); + +/** + * Half-pel DSP context. + */ +typedef struct HpelDSPContext { + /** + * Halfpel motion compensation with rounding (a+b+1)>>1. + * this is an array[4][4] of motion compensation functions for 4 + * horizontal blocksizes (8,16) and the 4 halfpel positions
      + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func put_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with rounding (a+b+1)>>1. + * This is an array[4][4] of motion compensation functions for 4 + * horizontal blocksizes (8,16) and the 4 halfpel positions
      + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination into which the result is averaged (a+b+1)>>1 + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func avg_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with no rounding (a+b)>>1. + * this is an array[4][4] of motion compensation functions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions
      + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + * @note The size is kept at [4][4] to match the above pixel_tabs and avoid + * out of bounds reads in the motion estimation code. + */ + op_pixels_func put_no_rnd_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with no rounding (a+b)>>1. + * this is an array[4] of motion compensation functions for 1 + * horizontal blocksize (16) and the 4 halfpel positions
      + * *pixels_tab[0][ xhalfpel + 2*yhalfpel ] + * @param block destination into which the result is averaged (a+b)>>1 + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func avg_no_rnd_pixels_tab[4]; +} HpelDSPContext; + +void ff_hpeldsp_init(HpelDSPContext *c, int flags); + +void ff_hpeldsp_init_aarch64(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_alpha(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_arm(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags); +void ff_hpeldsp_init_mips(HpelDSPContext *c, int flags); + +#endif /* AVCODEC_HPELDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hwaccel.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hwaccel.h new file mode 100644 index 000000000..3aaa92571 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hwaccel.h @@ -0,0 +1,84 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_HWACCEL_H +#define AVCODEC_HWACCEL_H + +#include "avcodec.h" +#include "hwaccels.h" + + +#define HWACCEL_CAP_ASYNC_SAFE (1 << 0) + + +typedef struct AVCodecHWConfigInternal { + /** + * This is the structure which will be returned to the user by + * avcodec_get_hw_config(). + */ + AVCodecHWConfig public; + /** + * If this configuration uses a hwaccel, a pointer to it. + * If not, NULL. + */ + const AVHWAccel *hwaccel; +} AVCodecHWConfigInternal; + + +// These macros are used to simplify AVCodecHWConfigInternal definitions. + +#define HW_CONFIG_HWACCEL(device, frames, ad_hoc, format, device_type_, name) \ + &(const AVCodecHWConfigInternal) { \ + .public = { \ + .pix_fmt = AV_PIX_FMT_ ## format, \ + .methods = (device ? AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX : 0) | \ + (frames ? AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX : 0) | \ + (ad_hoc ? AV_CODEC_HW_CONFIG_METHOD_AD_HOC : 0), \ + .device_type = AV_HWDEVICE_TYPE_ ## device_type_, \ + }, \ + .hwaccel = &name, \ + } + +#define HW_CONFIG_INTERNAL(format) \ + &(const AVCodecHWConfigInternal) { \ + .public = { \ + .pix_fmt = AV_PIX_FMT_ ## format, \ + .methods = AV_CODEC_HW_CONFIG_METHOD_INTERNAL, \ + .device_type = AV_HWDEVICE_TYPE_NONE, \ + }, \ + .hwaccel = NULL, \ + } + +#define HWACCEL_DXVA2(codec) \ + HW_CONFIG_HWACCEL(1, 1, 1, DXVA2_VLD, DXVA2, ff_ ## codec ## _dxva2_hwaccel) +#define HWACCEL_D3D11VA2(codec) \ + HW_CONFIG_HWACCEL(1, 1, 0, D3D11, D3D11VA, ff_ ## codec ## _d3d11va2_hwaccel) +#define HWACCEL_NVDEC(codec) \ + HW_CONFIG_HWACCEL(1, 1, 0, CUDA, CUDA, ff_ ## codec ## _nvdec_hwaccel) +#define HWACCEL_VAAPI(codec) \ + HW_CONFIG_HWACCEL(1, 1, 1, VAAPI, VAAPI, ff_ ## codec ## _vaapi_hwaccel) +#define HWACCEL_VDPAU(codec) \ + HW_CONFIG_HWACCEL(1, 1, 1, VDPAU, VDPAU, ff_ ## codec ## _vdpau_hwaccel) +#define HWACCEL_VIDEOTOOLBOX(codec) \ + HW_CONFIG_HWACCEL(1, 1, 1, VIDEOTOOLBOX, VIDEOTOOLBOX, ff_ ## codec ## _videotoolbox_hwaccel) +#define HWACCEL_D3D11VA(codec) \ + HW_CONFIG_HWACCEL(0, 0, 1, D3D11VA_VLD, NONE, ff_ ## codec ## _d3d11va_hwaccel) +#define HWACCEL_XVMC(codec) \ + HW_CONFIG_HWACCEL(0, 0, 1, XVMC, NONE, ff_ ## codec ## _xvmc_hwaccel) + +#endif /* AVCODEC_HWACCEL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hwaccels.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hwaccels.h new file mode 100644 index 000000000..7d73da867 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/hwaccels.h @@ -0,0 +1,78 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_HWACCELS_H +#define AVCODEC_HWACCELS_H + +#include "avcodec.h" + +extern const AVHWAccel ff_h263_vaapi_hwaccel; +extern const AVHWAccel ff_h263_videotoolbox_hwaccel; +extern const AVHWAccel ff_h264_d3d11va_hwaccel; +extern const AVHWAccel ff_h264_d3d11va2_hwaccel; +extern const AVHWAccel ff_h264_dxva2_hwaccel; +extern const AVHWAccel ff_h264_nvdec_hwaccel; +extern const AVHWAccel ff_h264_vaapi_hwaccel; +extern const AVHWAccel ff_h264_vdpau_hwaccel; +extern const AVHWAccel ff_h264_videotoolbox_hwaccel; +extern const AVHWAccel ff_hevc_d3d11va_hwaccel; +extern const AVHWAccel ff_hevc_d3d11va2_hwaccel; +extern const AVHWAccel ff_hevc_dxva2_hwaccel; +extern const AVHWAccel ff_hevc_nvdec_hwaccel; +extern const AVHWAccel ff_hevc_vaapi_hwaccel; +extern const AVHWAccel ff_hevc_vdpau_hwaccel; +extern const AVHWAccel ff_hevc_videotoolbox_hwaccel; +extern const AVHWAccel ff_mjpeg_nvdec_hwaccel; +extern const AVHWAccel ff_mjpeg_vaapi_hwaccel; +extern const AVHWAccel ff_mpeg1_nvdec_hwaccel; +extern const AVHWAccel ff_mpeg1_vdpau_hwaccel; +extern const AVHWAccel ff_mpeg1_videotoolbox_hwaccel; +extern const AVHWAccel ff_mpeg1_xvmc_hwaccel; +extern const AVHWAccel ff_mpeg2_d3d11va_hwaccel; +extern const AVHWAccel ff_mpeg2_d3d11va2_hwaccel; +extern const AVHWAccel ff_mpeg2_nvdec_hwaccel; +extern const AVHWAccel ff_mpeg2_dxva2_hwaccel; +extern const AVHWAccel ff_mpeg2_vaapi_hwaccel; +extern const AVHWAccel ff_mpeg2_vdpau_hwaccel; +extern const AVHWAccel ff_mpeg2_videotoolbox_hwaccel; +extern const AVHWAccel ff_mpeg2_xvmc_hwaccel; +extern const AVHWAccel ff_mpeg4_nvdec_hwaccel; +extern const AVHWAccel ff_mpeg4_vaapi_hwaccel; +extern const AVHWAccel ff_mpeg4_vdpau_hwaccel; +extern const AVHWAccel ff_mpeg4_videotoolbox_hwaccel; +extern const AVHWAccel ff_vc1_d3d11va_hwaccel; +extern const AVHWAccel ff_vc1_d3d11va2_hwaccel; +extern const AVHWAccel ff_vc1_dxva2_hwaccel; +extern const AVHWAccel ff_vc1_nvdec_hwaccel; +extern const AVHWAccel ff_vc1_vaapi_hwaccel; +extern const AVHWAccel ff_vc1_vdpau_hwaccel; +extern const AVHWAccel ff_vp8_nvdec_hwaccel; +extern const AVHWAccel ff_vp8_vaapi_hwaccel; +extern const AVHWAccel ff_vp9_d3d11va_hwaccel; +extern const AVHWAccel ff_vp9_d3d11va2_hwaccel; +extern const AVHWAccel ff_vp9_dxva2_hwaccel; +extern const AVHWAccel ff_vp9_nvdec_hwaccel; +extern const AVHWAccel ff_vp9_vaapi_hwaccel; +extern const AVHWAccel ff_wmv3_d3d11va_hwaccel; +extern const AVHWAccel ff_wmv3_d3d11va2_hwaccel; +extern const AVHWAccel ff_wmv3_dxva2_hwaccel; +extern const AVHWAccel ff_wmv3_nvdec_hwaccel; +extern const AVHWAccel ff_wmv3_vaapi_hwaccel; +extern const AVHWAccel ff_wmv3_vdpau_hwaccel; + +#endif /* AVCODEC_HWACCELS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/idctdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/idctdsp.h new file mode 100644 index 000000000..ca21a31a0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/idctdsp.h @@ -0,0 +1,122 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_IDCTDSP_H +#define AVCODEC_IDCTDSP_H + +#include + +#include "config.h" + +#include "avcodec.h" + +/** + * Scantable. + */ +typedef struct ScanTable { + const uint8_t *scantable; + uint8_t permutated[64]; + uint8_t raster_end[64]; +} ScanTable; + +enum idct_permutation_type { + FF_IDCT_PERM_NONE, + FF_IDCT_PERM_LIBMPEG2, + FF_IDCT_PERM_SIMPLE, + FF_IDCT_PERM_TRANSPOSE, + FF_IDCT_PERM_PARTTRANS, + FF_IDCT_PERM_SSE2, +}; + +void ff_init_scantable(uint8_t *permutation, ScanTable *st, + const uint8_t *src_scantable); +void ff_init_scantable_permutation(uint8_t *idct_permutation, + enum idct_permutation_type perm_type); +int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, + enum idct_permutation_type perm_type); + +typedef struct IDCTDSPContext { + /* pixel ops : interface with DCT */ + void (*put_pixels_clamped)(const int16_t *block /* align 16 */, + uint8_t *av_restrict pixels /* align 8 */, + ptrdiff_t line_size); + void (*put_signed_pixels_clamped)(const int16_t *block /* align 16 */, + uint8_t *av_restrict pixels /* align 8 */, + ptrdiff_t line_size); + void (*add_pixels_clamped)(const int16_t *block /* align 16 */, + uint8_t *av_restrict pixels /* align 8 */, + ptrdiff_t line_size); + + void (*idct)(int16_t *block /* align 16 */); + + /** + * block -> idct -> clip to unsigned 8 bit -> dest. + * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...) + * @param line_size size in bytes of a horizontal line of dest + */ + void (*idct_put)(uint8_t *dest /* align 8 */, + ptrdiff_t line_size, int16_t *block /* align 16 */); + + /** + * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. + * @param line_size size in bytes of a horizontal line of dest + */ + void (*idct_add)(uint8_t *dest /* align 8 */, + ptrdiff_t line_size, int16_t *block /* align 16 */); + + /** + * IDCT input permutation. + * Several optimized IDCTs need a permutated input (relative to the + * normal order of the reference IDCT). + * This permutation must be performed before the idct_put/add. + * Note, normally this can be merged with the zigzag/alternate scan
      + * An example to avoid confusion: + * - (->decode coeffs -> zigzag reorder -> dequant -> reference IDCT -> ...) + * - (x -> reference DCT -> reference IDCT -> x) + * - (x -> reference DCT -> simple_mmx_perm = idct_permutation + * -> simple_idct_mmx -> x) + * - (-> decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant + * -> simple_idct_mmx -> ...) + */ + uint8_t idct_permutation[64]; + enum idct_permutation_type perm_type; + + int mpeg4_studio_profile; +} IDCTDSPContext; + +void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, + ptrdiff_t line_size); +void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, + ptrdiff_t line_size); + +void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx); + +void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_idctdsp_init_alpha(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_idctdsp_init_arm(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_idctdsp_init_ppc(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_idctdsp_init_mips(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); + +#endif /* AVCODEC_IDCTDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/iirfilter.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/iirfilter.c new file mode 100644 index 000000000..b20251582 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/iirfilter.c @@ -0,0 +1,327 @@ +/* + * IIR filter + * Copyright (c) 2008 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * different IIR filters implementation + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/common.h" + +#include "iirfilter.h" + +/** + * IIR filter global parameters + */ +typedef struct FFIIRFilterCoeffs { + int order; + float gain; + int *cx; + float *cy; +} FFIIRFilterCoeffs; + +/** + * IIR filter state + */ +typedef struct FFIIRFilterState { + float x[1]; +} FFIIRFilterState; + +/// maximum supported filter order +#define MAXORDER 30 + +static av_cold int butterworth_init_coeffs(void *avc, + struct FFIIRFilterCoeffs *c, + enum IIRFilterMode filt_mode, + int order, float cutoff_ratio, + float stopband) +{ + int i, j; + double wa; + double p[MAXORDER + 1][2]; + + if (filt_mode != FF_FILTER_MODE_LOWPASS) { + av_log(avc, AV_LOG_ERROR, "Butterworth filter currently only supports " + "low-pass filter mode\n"); + return -1; + } + if (order & 1) { + av_log(avc, AV_LOG_ERROR, "Butterworth filter currently only supports " + "even filter orders\n"); + return -1; + } + + wa = 2 * tan(M_PI * 0.5 * cutoff_ratio); + + c->cx[0] = 1; + for (i = 1; i < (order >> 1) + 1; i++) + c->cx[i] = c->cx[i - 1] * (order - i + 1LL) / i; + + p[0][0] = 1.0; + p[0][1] = 0.0; + for (i = 1; i <= order; i++) + p[i][0] = p[i][1] = 0.0; + for (i = 0; i < order; i++) { + double zp[2]; + double th = (i + (order >> 1) + 0.5) * M_PI / order; + double a_re, a_im, c_re, c_im; + zp[0] = cos(th) * wa; + zp[1] = sin(th) * wa; + a_re = zp[0] + 2.0; + c_re = zp[0] - 2.0; + a_im = + c_im = zp[1]; + zp[0] = (a_re * c_re + a_im * c_im) / (c_re * c_re + c_im * c_im); + zp[1] = (a_im * c_re - a_re * c_im) / (c_re * c_re + c_im * c_im); + + for (j = order; j >= 1; j--) { + a_re = p[j][0]; + a_im = p[j][1]; + p[j][0] = a_re * zp[0] - a_im * zp[1] + p[j - 1][0]; + p[j][1] = a_re * zp[1] + a_im * zp[0] + p[j - 1][1]; + } + a_re = p[0][0] * zp[0] - p[0][1] * zp[1]; + p[0][1] = p[0][0] * zp[1] + p[0][1] * zp[0]; + p[0][0] = a_re; + } + c->gain = p[order][0]; + for (i = 0; i < order; i++) { + c->gain += p[i][0]; + c->cy[i] = (-p[i][0] * p[order][0] + -p[i][1] * p[order][1]) / + (p[order][0] * p[order][0] + p[order][1] * p[order][1]); + } + c->gain /= 1 << order; + + return 0; +} + +static av_cold int biquad_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c, + enum IIRFilterMode filt_mode, int order, + float cutoff_ratio, float stopband) +{ + double cos_w0, sin_w0; + double a0, x0, x1; + + if (filt_mode != FF_FILTER_MODE_HIGHPASS && + filt_mode != FF_FILTER_MODE_LOWPASS) { + av_log(avc, AV_LOG_ERROR, "Biquad filter currently only supports " + "high-pass and low-pass filter modes\n"); + return -1; + } + if (order != 2) { + av_log(avc, AV_LOG_ERROR, "Biquad filter must have order of 2\n"); + return -1; + } + + cos_w0 = cos(M_PI * cutoff_ratio); + sin_w0 = sin(M_PI * cutoff_ratio); + + a0 = 1.0 + (sin_w0 / 2.0); + + if (filt_mode == FF_FILTER_MODE_HIGHPASS) { + c->gain = ((1.0 + cos_w0) / 2.0) / a0; + x0 = ((1.0 + cos_w0) / 2.0) / a0; + x1 = (-(1.0 + cos_w0)) / a0; + } else { // FF_FILTER_MODE_LOWPASS + c->gain = ((1.0 - cos_w0) / 2.0) / a0; + x0 = ((1.0 - cos_w0) / 2.0) / a0; + x1 = (1.0 - cos_w0) / a0; + } + c->cy[0] = (-1.0 + (sin_w0 / 2.0)) / a0; + c->cy[1] = (2.0 * cos_w0) / a0; + + // divide by gain to make the x coeffs integers. + // during filtering, the delay state will include the gain multiplication + c->cx[0] = lrintf(x0 / c->gain); + c->cx[1] = lrintf(x1 / c->gain); + + return 0; +} + +av_cold struct FFIIRFilterCoeffs *ff_iir_filter_init_coeffs(void *avc, + enum IIRFilterType filt_type, + enum IIRFilterMode filt_mode, + int order, float cutoff_ratio, + float stopband, float ripple) +{ + FFIIRFilterCoeffs *c; + int ret = 0; + + if (order <= 0 || order > MAXORDER || cutoff_ratio >= 1.0) + return NULL; + + FF_ALLOCZ_OR_GOTO(avc, c, sizeof(FFIIRFilterCoeffs), + init_fail); + FF_ALLOC_OR_GOTO(avc, c->cx, sizeof(c->cx[0]) * ((order >> 1) + 1), + init_fail); + FF_ALLOC_OR_GOTO(avc, c->cy, sizeof(c->cy[0]) * order, + init_fail); + c->order = order; + + switch (filt_type) { + case FF_FILTER_TYPE_BUTTERWORTH: + ret = butterworth_init_coeffs(avc, c, filt_mode, order, cutoff_ratio, + stopband); + break; + case FF_FILTER_TYPE_BIQUAD: + ret = biquad_init_coeffs(avc, c, filt_mode, order, cutoff_ratio, + stopband); + break; + default: + av_log(avc, AV_LOG_ERROR, "filter type is not currently implemented\n"); + goto init_fail; + } + + if (!ret) + return c; + +init_fail: + ff_iir_filter_free_coeffsp(&c); + return NULL; +} + +av_cold struct FFIIRFilterState *ff_iir_filter_init_state(int order) +{ + FFIIRFilterState *s = av_mallocz(sizeof(FFIIRFilterState) + sizeof(s->x[0]) * (order - 1)); + return s; +} + +#define CONV_S16(dest, source) dest = av_clip_int16(lrintf(source)); + +#define CONV_FLT(dest, source) dest = source; + +#define FILTER_BW_O4_1(i0, i1, i2, i3, fmt) \ + in = *src0 * c->gain + \ + c->cy[0] * s->x[i0] + \ + c->cy[1] * s->x[i1] + \ + c->cy[2] * s->x[i2] + \ + c->cy[3] * s->x[i3]; \ + res = (s->x[i0] + in) * 1 + \ + (s->x[i1] + s->x[i3]) * 4 + \ + s->x[i2] * 6; \ + CONV_ ## fmt(*dst0, res) \ + s->x[i0] = in; \ + src0 += sstep; \ + dst0 += dstep; + +#define FILTER_BW_O4(type, fmt) { \ + int i; \ + const type *src0 = src; \ + type *dst0 = dst; \ + for (i = 0; i < size; i += 4) { \ + float in, res; \ + FILTER_BW_O4_1(0, 1, 2, 3, fmt); \ + FILTER_BW_O4_1(1, 2, 3, 0, fmt); \ + FILTER_BW_O4_1(2, 3, 0, 1, fmt); \ + FILTER_BW_O4_1(3, 0, 1, 2, fmt); \ + } \ +} + +#define FILTER_DIRECT_FORM_II(type, fmt) { \ + int i; \ + const type *src0 = src; \ + type *dst0 = dst; \ + for (i = 0; i < size; i++) { \ + int j; \ + float in, res; \ + in = *src0 * c->gain; \ + for (j = 0; j < c->order; j++) \ + in += c->cy[j] * s->x[j]; \ + res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1]; \ + for (j = 1; j < c->order >> 1; j++) \ + res += (s->x[j] + s->x[c->order - j]) * c->cx[j]; \ + for (j = 0; j < c->order - 1; j++) \ + s->x[j] = s->x[j + 1]; \ + CONV_ ## fmt(*dst0, res) \ + s->x[c->order - 1] = in; \ + src0 += sstep; \ + dst0 += dstep; \ + } \ +} + +#define FILTER_O2(type, fmt) { \ + int i; \ + const type *src0 = src; \ + type *dst0 = dst; \ + for (i = 0; i < size; i++) { \ + float in = *src0 * c->gain + \ + s->x[0] * c->cy[0] + \ + s->x[1] * c->cy[1]; \ + CONV_ ## fmt(*dst0, s->x[0] + in + s->x[1] * c->cx[1]) \ + s->x[0] = s->x[1]; \ + s->x[1] = in; \ + src0 += sstep; \ + dst0 += dstep; \ + } \ +} + +void ff_iir_filter(const struct FFIIRFilterCoeffs *c, + struct FFIIRFilterState *s, int size, + const int16_t *src, ptrdiff_t sstep, + int16_t *dst, ptrdiff_t dstep) +{ + if (c->order == 2) { + FILTER_O2(int16_t, S16) + } else if (c->order == 4) { + FILTER_BW_O4(int16_t, S16) + } else { + FILTER_DIRECT_FORM_II(int16_t, S16) + } +} + +void ff_iir_filter_flt(const struct FFIIRFilterCoeffs *c, + struct FFIIRFilterState *s, int size, + const float *src, ptrdiff_t sstep, + float *dst, ptrdiff_t dstep) +{ + if (c->order == 2) { + FILTER_O2(float, FLT) + } else if (c->order == 4) { + FILTER_BW_O4(float, FLT) + } else { + FILTER_DIRECT_FORM_II(float, FLT) + } +} + +av_cold void ff_iir_filter_free_statep(struct FFIIRFilterState **state) +{ + av_freep(state); +} + +av_cold void ff_iir_filter_free_coeffsp(struct FFIIRFilterCoeffs **coeffsp) +{ + struct FFIIRFilterCoeffs *coeffs = *coeffsp; + if (coeffs) { + av_freep(&coeffs->cx); + av_freep(&coeffs->cy); + } + av_freep(coeffsp); +} + +void ff_iir_filter_init(FFIIRFilterContext *f) { + f->filter_flt = ff_iir_filter_flt; + + if (HAVE_MIPSFPU) + ff_iir_filter_init_mips(f); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/iirfilter.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/iirfilter.h new file mode 100644 index 000000000..5ffa1ce53 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/iirfilter.h @@ -0,0 +1,147 @@ +/* + * IIR filter + * Copyright (c) 2008 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * IIR filter interface + */ + +#ifndef AVCODEC_IIRFILTER_H +#define AVCODEC_IIRFILTER_H + +#include +#include + +struct FFIIRFilterCoeffs; +struct FFIIRFilterState; + +enum IIRFilterType{ + FF_FILTER_TYPE_BESSEL, + FF_FILTER_TYPE_BIQUAD, + FF_FILTER_TYPE_BUTTERWORTH, + FF_FILTER_TYPE_CHEBYSHEV, + FF_FILTER_TYPE_ELLIPTIC, +}; + +enum IIRFilterMode{ + FF_FILTER_MODE_LOWPASS, + FF_FILTER_MODE_HIGHPASS, + FF_FILTER_MODE_BANDPASS, + FF_FILTER_MODE_BANDSTOP, +}; + +typedef struct FFIIRFilterContext { + /** + * Perform IIR filtering on floating-point input samples. + * + * @param coeffs pointer to filter coefficients + * @param state pointer to filter state + * @param size input length + * @param src source samples + * @param sstep source stride + * @param dst filtered samples (destination may be the same as input) + * @param dstep destination stride + */ + void (*filter_flt)(const struct FFIIRFilterCoeffs *coeffs, + struct FFIIRFilterState *state, int size, + const float *src, ptrdiff_t sstep, float *dst, ptrdiff_t dstep); +} FFIIRFilterContext; + +/** + * Initialize FFIIRFilterContext + */ +void ff_iir_filter_init(FFIIRFilterContext *f); +void ff_iir_filter_init_mips(FFIIRFilterContext *f); + +/** + * Initialize filter coefficients. + * + * @param avc a pointer to an arbitrary struct of which the first + * field is a pointer to an AVClass struct + * @param filt_type filter type (e.g. Butterworth) + * @param filt_mode filter mode (e.g. lowpass) + * @param order filter order + * @param cutoff_ratio cutoff to input frequency ratio + * @param stopband stopband to input frequency ratio (used by bandpass and bandstop filter modes) + * @param ripple ripple factor (used only in Chebyshev filters) + * + * @return pointer to filter coefficients structure or NULL if filter cannot be created + */ +struct FFIIRFilterCoeffs* ff_iir_filter_init_coeffs(void *avc, + enum IIRFilterType filt_type, + enum IIRFilterMode filt_mode, + int order, float cutoff_ratio, + float stopband, float ripple); + +/** + * Create new filter state. + * + * @param order filter order + * + * @return pointer to new filter state or NULL if state creation fails + */ +struct FFIIRFilterState* ff_iir_filter_init_state(int order); + +/** + * Free filter coefficients. + * + * @param coeffs pointer allocated with ff_iir_filter_init_coeffs() + */ +void ff_iir_filter_free_coeffsp(struct FFIIRFilterCoeffs **coeffs); + +/** + * Free and zero filter state. + * + * @param state pointer to pointer allocated with ff_iir_filter_init_state() + */ +void ff_iir_filter_free_statep(struct FFIIRFilterState **state); + +/** + * Perform IIR filtering on signed 16-bit input samples. + * + * @param coeffs pointer to filter coefficients + * @param state pointer to filter state + * @param size input length + * @param src source samples + * @param sstep source stride + * @param dst filtered samples (destination may be the same as input) + * @param dstep destination stride + */ +void ff_iir_filter(const struct FFIIRFilterCoeffs *coeffs, struct FFIIRFilterState *state, + int size, const int16_t *src, ptrdiff_t sstep, int16_t *dst, ptrdiff_t dstep); + +/** + * Perform IIR filtering on floating-point input samples. + * + * @param coeffs pointer to filter coefficients + * @param state pointer to filter state + * @param size input length + * @param src source samples + * @param sstep source stride + * @param dst filtered samples (destination may be the same as input) + * @param dstep destination stride + */ +void ff_iir_filter_flt(const struct FFIIRFilterCoeffs *coeffs, + struct FFIIRFilterState *state, int size, + const float *src, ptrdiff_t sstep, + float *dst, ptrdiff_t dstep); + +#endif /* AVCODEC_IIRFILTER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/imgconvert.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/imgconvert.c new file mode 100644 index 000000000..1fd636c83 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/imgconvert.c @@ -0,0 +1,232 @@ +/* + * Misc image conversion routines + * Copyright (c) 2001, 2002, 2003 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * misc image conversion routines + */ + +#include "avcodec.h" +#include "internal.h" +#include "mathops.h" +#include "libavutil/avassert.h" +#include "libavutil/colorspace.h" +#include "libavutil/common.h" +#include "libavutil/pixdesc.h" +#include "libavutil/internal.h" +#include "libavutil/imgutils.h" + +#if FF_API_GETCHROMA +void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + av_assert0(desc); + *h_shift = desc->log2_chroma_w; + *v_shift = desc->log2_chroma_h; +} +#endif + +int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, + enum AVPixelFormat src_pix_fmt, + int has_alpha) +{ + return av_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); +} + +enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) +{ + return av_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr); +} + +enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) +{ + return avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr); +} + +enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list, + enum AVPixelFormat src_pix_fmt, + int has_alpha, int *loss_ptr){ + int i; + + enum AVPixelFormat best = AV_PIX_FMT_NONE; + int loss; + + for (i=0; pix_fmt_list[i] != AV_PIX_FMT_NONE; i++) { + loss = loss_ptr ? *loss_ptr : 0; + best = avcodec_find_best_pix_fmt_of_2(best, pix_fmt_list[i], src_pix_fmt, has_alpha, &loss); + } + + if (loss_ptr) + *loss_ptr = loss; + return best; +} + +#if FF_API_AVPICTURE +FF_DISABLE_DEPRECATION_WARNINGS +/* return true if yuv planar */ +static inline int is_yuv_planar(const AVPixFmtDescriptor *desc) +{ + int i; + int planes[4] = { 0 }; + + if ( desc->flags & AV_PIX_FMT_FLAG_RGB + || !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) + return 0; + + /* set the used planes */ + for (i = 0; i < desc->nb_components; i++) + planes[desc->comp[i].plane] = 1; + + /* if there is an unused plane, the format is not planar */ + for (i = 0; i < desc->nb_components; i++) + if (!planes[i]) + return 0; + return 1; +} + +int av_picture_crop(AVPicture *dst, const AVPicture *src, + enum AVPixelFormat pix_fmt, int top_band, int left_band) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int y_shift; + int x_shift; + int max_step[4]; + + if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB) + return -1; + + y_shift = desc->log2_chroma_h; + x_shift = desc->log2_chroma_w; + av_image_fill_max_pixsteps(max_step, NULL, desc); + + if (is_yuv_planar(desc)) { + dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band; + dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift); + dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift); + } else{ + if(top_band % (1<data[0] = src->data[0] + (top_band * src->linesize[0]) + (left_band * max_step[0]); + } + + dst->linesize[0] = src->linesize[0]; + dst->linesize[1] = src->linesize[1]; + dst->linesize[2] = src->linesize[2]; + return 0; +} + +int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, + enum AVPixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright, + int *color) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + uint8_t *optr; + int y_shift; + int x_shift; + int yheight; + int i, y; + int max_step[4]; + + if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB) + return -1; + + if (!is_yuv_planar(desc)) { + if (src) + return -1; //TODO: Not yet implemented + + av_image_fill_max_pixsteps(max_step, NULL, desc); + + if (padtop || padleft) { + memset(dst->data[0], color[0], + dst->linesize[0] * padtop + (padleft * max_step[0])); + } + + if (padleft || padright) { + optr = dst->data[0] + dst->linesize[0] * padtop + + (dst->linesize[0] - (padright * max_step[0])); + yheight = height - 1 - (padtop + padbottom); + for (y = 0; y < yheight; y++) { + memset(optr, color[0], (padleft + padright) * max_step[0]); + optr += dst->linesize[0]; + } + } + + if (padbottom || padright) { + optr = dst->data[0] + dst->linesize[0] * (height - padbottom) - + (padright * max_step[0]); + memset(optr, color[0], dst->linesize[0] * padbottom + + (padright * max_step[0])); + } + + return 0; + } + + for (i = 0; i < 3; i++) { + x_shift = i ? desc->log2_chroma_w : 0; + y_shift = i ? desc->log2_chroma_h : 0; + + if (padtop || padleft) { + memset(dst->data[i], color[i], + dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift)); + } + + if (padleft || padright) { + optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + + (dst->linesize[i] - (padright >> x_shift)); + yheight = (height - 1 - (padtop + padbottom)) >> y_shift; + for (y = 0; y < yheight; y++) { + memset(optr, color[i], (padleft + padright) >> x_shift); + optr += dst->linesize[i]; + } + } + + if (src) { /* first line */ + uint8_t *iptr = src->data[i]; + optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + + (padleft >> x_shift); + memcpy(optr, iptr, (width - padleft - padright) >> x_shift); + iptr += src->linesize[i]; + optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + + (dst->linesize[i] - (padright >> x_shift)); + yheight = (height - 1 - (padtop + padbottom)) >> y_shift; + for (y = 0; y < yheight; y++) { + memset(optr, color[i], (padleft + padright) >> x_shift); + memcpy(optr + ((padleft + padright) >> x_shift), iptr, + (width - padleft - padright) >> x_shift); + iptr += src->linesize[i]; + optr += dst->linesize[i]; + } + } + + if (padbottom || padright) { + optr = dst->data[i] + dst->linesize[i] * + ((height - padbottom) >> y_shift) - (padright >> x_shift); + memset(optr, color[i],dst->linesize[i] * + (padbottom >> y_shift) + (padright >> x_shift)); + } + } + + return 0; +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif /* FF_API_AVPICTURE */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/internal.h new file mode 100644 index 000000000..5096ffa1d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/internal.h @@ -0,0 +1,433 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * common internal api header. + */ + +#ifndef AVCODEC_INTERNAL_H +#define AVCODEC_INTERNAL_H + +#include + +#include "libavutil/buffer.h" +#include "libavutil/channel_layout.h" +#include "libavutil/mathematics.h" +#include "libavutil/pixfmt.h" +#include "avcodec.h" +#include "config.h" + +/** + * The codec does not modify any global variables in the init function, + * allowing to call the init function without locking any global mutexes. + */ +#define FF_CODEC_CAP_INIT_THREADSAFE (1 << 0) +/** + * The codec allows calling the close function for deallocation even if + * the init function returned a failure. Without this capability flag, a + * codec does such cleanup internally when returning failures from the + * init function and does not expect the close function to be called at + * all. + */ +#define FF_CODEC_CAP_INIT_CLEANUP (1 << 1) +/** + * Decoders marked with FF_CODEC_CAP_SETS_PKT_DTS want to set + * AVFrame.pkt_dts manually. If the flag is set, decode.c won't overwrite + * this field. If it's unset, decode.c tries to guess the pkt_dts field + * from the input AVPacket. + */ +#define FF_CODEC_CAP_SETS_PKT_DTS (1 << 2) +/** + * The decoder extracts and fills its parameters even if the frame is + * skipped due to the skip_frame setting. + */ +#define FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM (1 << 3) +/** + * The decoder sets the cropping fields in the output frames manually. + * If this cap is set, the generic code will initialize output frame + * dimensions to coded rather than display values. + */ +#define FF_CODEC_CAP_EXPORTS_CROPPING (1 << 4) +/** + * Codec initializes slice-based threading with a main function + */ +#define FF_CODEC_CAP_SLICE_THREAD_HAS_MF (1 << 5) + +#ifdef TRACE +# define ff_tlog(ctx, ...) av_log(ctx, AV_LOG_TRACE, __VA_ARGS__) +#else +# define ff_tlog(ctx, ...) do { } while(0) +#endif + + +#define FF_DEFAULT_QUANT_BIAS 999999 + +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 +#define FF_QSCALE_TYPE_H264 2 +#define FF_QSCALE_TYPE_VP56 3 + +#define FF_SANE_NB_CHANNELS 256U + +#define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1) + +#if HAVE_SIMD_ALIGN_64 +# define STRIDE_ALIGN 64 /* AVX-512 */ +#elif HAVE_SIMD_ALIGN_32 +# define STRIDE_ALIGN 32 +#elif HAVE_SIMD_ALIGN_16 +# define STRIDE_ALIGN 16 +#else +# define STRIDE_ALIGN 8 +#endif + +typedef struct FramePool { + /** + * Pools for each data plane. For audio all the planes have the same size, + * so only pools[0] is used. + */ + AVBufferPool *pools[4]; + + /* + * Pool parameters + */ + int format; + int width, height; + int stride_align[AV_NUM_DATA_POINTERS]; + int linesize[4]; + int planes; + int channels; + int samples; +} FramePool; + +typedef struct DecodeSimpleContext { + AVPacket *in_pkt; + AVFrame *out_frame; +} DecodeSimpleContext; + +typedef struct DecodeFilterContext { + AVBSFContext **bsfs; + int nb_bsfs; +} DecodeFilterContext; + +typedef struct AVCodecInternal { + /** + * Whether the parent AVCodecContext is a copy of the context which had + * init() called on it. + * This is used by multithreading - shared tables and picture pointers + * should be freed from the original context only. + */ + int is_copy; + + /** + * Whether to allocate progress for frame threading. + * + * The codec must set it to 1 if it uses ff_thread_await/report_progress(), + * then progress will be allocated in ff_thread_get_buffer(). The frames + * then MUST be freed with ff_thread_release_buffer(). + * + * If the codec does not need to call the progress functions (there are no + * dependencies between the frames), it should leave this at 0. Then it can + * decode straight to the user-provided frames (which the user will then + * free with av_frame_unref()), there is no need to call + * ff_thread_release_buffer(). + */ + int allocate_progress; + + /** + * An audio frame with less than required samples has been submitted and + * padded with silence. Reject all subsequent frames. + */ + int last_audio_frame; + + AVFrame *to_free; + + FramePool *pool; + + void *thread_ctx; + + DecodeSimpleContext ds; + DecodeFilterContext filter; + + /** + * Properties (timestamps+side data) extracted from the last packet passed + * for decoding. + */ + AVPacket *last_pkt_props; + + /** + * temporary buffer used for encoders to store their bitstream + */ + uint8_t *byte_buffer; + unsigned int byte_buffer_size; + + void *frame_thread_encoder; + + /** + * Number of audio samples to skip at the start of the next decoded frame + */ + int skip_samples; + + /** + * hwaccel-specific private data + */ + void *hwaccel_priv_data; + + /** + * checks API usage: after codec draining, flush is required to resume operation + */ + int draining; + + /** + * buffers for using new encode/decode API through legacy API + */ + AVPacket *buffer_pkt; + int buffer_pkt_valid; // encoding: packet without data can be valid + AVFrame *buffer_frame; + int draining_done; + /* set to 1 when the caller is using the old decoding API */ + int compat_decode; + int compat_decode_warned; + /* this variable is set by the decoder internals to signal to the old + * API compat wrappers the amount of data consumed from the last packet */ + size_t compat_decode_consumed; + /* when a partial packet has been consumed, this stores the remaining size + * of the packet (that should be submitted in the next decode call */ + size_t compat_decode_partial_size; + AVFrame *compat_decode_frame; + + int showed_multi_packet_warning; + + int skip_samples_multiplier; + + /* to prevent infinite loop on errors when draining */ + int nb_draining_errors; + + /* used when avctx flag AV_CODEC_FLAG_DROPCHANGED is set */ + int changed_frames_dropped; + int initial_format; + int initial_width, initial_height; + int initial_sample_rate; + int initial_channels; + uint64_t initial_channel_layout; +} AVCodecInternal; + +struct AVCodecDefault { + const uint8_t *key; + const uint8_t *value; +}; + +extern const uint8_t ff_log2_run[41]; + +/** + * Return the index into tab at which {a,b} match elements {[0],[1]} of tab. + * If there is no such matching pair then size is returned. + */ +int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b); + +unsigned int avpriv_toupper4(unsigned int x); + +void ff_color_frame(AVFrame *frame, const int color[4]); + +/** + * Maximum size in bytes of extradata. + * This value was chosen such that every bit of the buffer is + * addressable by a 32-bit signed integer as used by get_bits. + */ +#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE) + +/** + * Check AVPacket size and/or allocate data. + * + * Encoders supporting AVCodec.encode2() can use this as a convenience to + * ensure the output packet data is large enough, whether provided by the user + * or allocated in this function. + * + * @param avctx the AVCodecContext of the encoder + * @param avpkt the AVPacket + * If avpkt->data is already set, avpkt->size is checked + * to ensure it is large enough. + * If avpkt->data is NULL, a new buffer is allocated. + * avpkt->size is set to the specified size. + * All other AVPacket fields will be reset with av_init_packet(). + * @param size the minimum required packet size + * @param min_size This is a hint to the allocation algorithm, which indicates + * to what minimal size the caller might later shrink the packet + * to. Encoders often allocate packets which are larger than the + * amount of data that is written into them as the exact amount is + * not known at the time of allocation. min_size represents the + * size a packet might be shrunk to by the caller. Can be set to + * 0. setting this roughly correctly allows the allocation code + * to choose between several allocation strategies to improve + * speed slightly. + * @return non negative on success, negative error code on failure + */ +int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size); + +attribute_deprecated int ff_alloc_packet(AVPacket *avpkt, int size); + +/** + * Rescale from sample rate to AVCodecContext.time_base. + */ +static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx, + int64_t samples) +{ + if(samples == AV_NOPTS_VALUE) + return AV_NOPTS_VALUE; + return av_rescale_q(samples, (AVRational){ 1, avctx->sample_rate }, + avctx->time_base); +} + +/** + * 2^(x) for integer x + * @return correctly rounded float + */ +static av_always_inline float ff_exp2fi(int x) { + /* Normal range */ + if (-126 <= x && x <= 128) + return av_int2float((x+127) << 23); + /* Too large */ + else if (x > 128) + return INFINITY; + /* Subnormal numbers */ + else if (x > -150) + return av_int2float(1 << (x+149)); + /* Negligibly small */ + else + return 0; +} + +/** + * Get a buffer for a frame. This is a wrapper around + * AVCodecContext.get_buffer() and should be used instead calling get_buffer() + * directly. + */ +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags); + +/** + * Identical in function to av_frame_make_writable(), except it uses + * ff_get_buffer() to allocate the buffer when needed. + */ +int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame); + +int ff_thread_can_start_frame(AVCodecContext *avctx); + +int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx); + +/** + * Call avcodec_open2 recursively by decrementing counter, unlocking mutex, + * calling the function and then restoring again. Assumes the mutex is + * already locked + */ +int ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); + +/** + * Finalize buf into extradata and set its size appropriately. + */ +int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf); + +const uint8_t *avpriv_find_start_code(const uint8_t *p, + const uint8_t *end, + uint32_t *state); + +int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec); + +/** + * Check that the provided frame dimensions are valid and set them on the codec + * context. + */ +int ff_set_dimensions(AVCodecContext *s, int width, int height); + +/** + * Check that the provided sample aspect ratio is valid and set it on the codec + * context. + */ +int ff_set_sar(AVCodecContext *avctx, AVRational sar); + +/** + * Add or update AV_FRAME_DATA_MATRIXENCODING side data. + */ +int ff_side_data_update_matrix_encoding(AVFrame *frame, + enum AVMatrixEncoding matrix_encoding); + +/** + * Select the (possibly hardware accelerated) pixel format. + * This is a wrapper around AVCodecContext.get_format() and should be used + * instead of calling get_format() directly. + * + * The list of pixel formats must contain at least one valid entry, and is + * terminated with AV_PIX_FMT_NONE. If it is possible to decode to software, + * the last entry in the list must be the most accurate software format. + * If it is not possible to decode to software, AVCodecContext.sw_pix_fmt + * must be set before calling this function. + */ +int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt); + +/** + * Set various frame properties from the codec context / packet data. + */ +int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame); + +/** + * Add a CPB properties side data to an encoding context. + */ +AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx); + +int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type); + +/** + * Check AVFrame for A53 side data and allocate and fill SEI message with A53 info + * + * @param frame Raw frame to get A53 side data from + * @param prefix_len Number of bytes to allocate before SEI message + * @param data Pointer to a variable to store allocated memory + * Upon return the variable will hold NULL on error or if frame has no A53 info. + * Otherwise it will point to prefix_len uninitialized bytes followed by + * *sei_size SEI message + * @param sei_size Pointer to a variable to store generated SEI message length + * @return Zero on success, negative error code on failure + */ +int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, + void **data, size_t *sei_size); + +/** + * Get an estimated video bitrate based on frame size, frame rate and coded + * bits per pixel. + */ +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx); + +/** + * Check if a value is in the list. If not, return the default value + * + * @param ctx Context for the log msg + * @param val_name Name of the checked value, for log msg + * @param array_valid_values Array of valid int, ended with INT_MAX + * @param default_value Value return if checked value is not in the array + * @return Value or default_value. + */ +int ff_int_from_list_or_default(void *ctx, const char * val_name, int val, + const int * array_valid_values, int default_value); + +#if defined(_WIN32) && CONFIG_SHARED && !defined(BUILDING_avcodec) +# define av_export_avcodec __declspec(dllimport) +#else +# define av_export_avcodec +#endif + +#endif /* AVCODEC_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/jni.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/jni.c new file mode 100644 index 000000000..85dcf2aba --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/jni.c @@ -0,0 +1,79 @@ +/* + * JNI public API functions + * + * Copyright (c) 2015-2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#include "libavutil/error.h" +#include "jni.h" + +#if CONFIG_JNI +#include +#include + +#include "libavutil/log.h" +#include "ffjni.h" + +void *java_vm; +pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + +int av_jni_set_java_vm(void *vm, void *log_ctx) +{ + int ret = 0; + + pthread_mutex_lock(&lock); + if (java_vm == NULL) { + java_vm = vm; + } else if (java_vm != vm) { + ret = AVERROR(EINVAL); + av_log(log_ctx, AV_LOG_ERROR, "A Java virtual machine has already been set"); + } + pthread_mutex_unlock(&lock); + + return ret; +} + +void *av_jni_get_java_vm(void *log_ctx) +{ + void *vm; + + pthread_mutex_lock(&lock); + vm = java_vm; + pthread_mutex_unlock(&lock); + + return vm; +} + +#else + +int av_jni_set_java_vm(void *vm, void *log_ctx) +{ + return AVERROR(ENOSYS); +} + +void *av_jni_get_java_vm(void *log_ctx) +{ + return NULL; +} + +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/jni.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/jni.h new file mode 100644 index 000000000..dd99e9261 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/jni.h @@ -0,0 +1,46 @@ +/* + * JNI public API functions + * + * Copyright (c) 2015-2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_JNI_H +#define AVCODEC_JNI_H + +/* + * Manually set a Java virtual machine which will be used to retrieve the JNI + * environment. Once a Java VM is set it cannot be changed afterwards, meaning + * you can call multiple times av_jni_set_java_vm with the same Java VM pointer + * however it will error out if you try to set a different Java VM. + * + * @param vm Java virtual machine + * @param log_ctx context used for logging, can be NULL + * @return 0 on success, < 0 otherwise + */ +int av_jni_set_java_vm(void *vm, void *log_ctx); + +/* + * Get the Java virtual machine which has been set with av_jni_set_java_vm. + * + * @param vm Java virtual machine + * @return a pointer to the Java virtual machine + */ +void *av_jni_get_java_vm(void *log_ctx); + +#endif /* AVCODEC_JNI_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/kbdwin.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/kbdwin.c new file mode 100644 index 000000000..bf32aeb31 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/kbdwin.c @@ -0,0 +1,57 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/avassert.h" +#include "libavutil/mathematics.h" +#include "libavutil/attributes.h" +#include "kbdwin.h" + +#define BESSEL_I0_ITER 50 // default: 50 iterations of Bessel I0 approximation + +av_cold void ff_kbd_window_init(float *window, float alpha, int n) +{ + int i, j; + double sum = 0.0, bessel, tmp; + double local_window[FF_KBD_WINDOW_MAX]; + double alpha2 = (alpha * M_PI / n) * (alpha * M_PI / n); + + av_assert0(n <= FF_KBD_WINDOW_MAX); + + for (i = 0; i < n; i++) { + tmp = i * (n - i) * alpha2; + bessel = 1.0; + for (j = BESSEL_I0_ITER; j > 0; j--) + bessel = bessel * tmp / (j * j) + 1; + sum += bessel; + local_window[i] = sum; + } + + sum++; + for (i = 0; i < n; i++) + window[i] = sqrt(local_window[i] / sum); +} + +av_cold void ff_kbd_window_init_fixed(int32_t *window, float alpha, int n) +{ + int i; + float local_window[FF_KBD_WINDOW_MAX]; + + ff_kbd_window_init(local_window, alpha, n); + for (i = 0; i < n; i++) + window[i] = (int)floor(2147483647.0 * local_window[i] + 0.5); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/kbdwin.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/kbdwin.h new file mode 100644 index 000000000..4185c4206 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/kbdwin.h @@ -0,0 +1,38 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_KBDWIN_H +#define AVCODEC_KBDWIN_H + +#include + +/** + * Maximum window size for ff_kbd_window_init. + */ +#define FF_KBD_WINDOW_MAX 1024 + +/** + * Generate a Kaiser-Bessel Derived Window. + * @param window pointer to half window + * @param alpha determines window shape + * @param n size of half window, max FF_KBD_WINDOW_MAX + */ +void ff_kbd_window_init(float *window, float alpha, int n); +void ff_kbd_window_init_fixed(int32_t *window, float alpha, int n); + +#endif /* AVCODEC_KBDWIN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/latm_parser.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/latm_parser.c new file mode 100644 index 000000000..3820f58d6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/latm_parser.c @@ -0,0 +1,112 @@ +/* + * copyright (c) 2008 Paul Kendall + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC LATM parser + */ + +#include +#include "parser.h" + +#define LATM_HEADER 0x56e000 // 0x2b7 (11 bits) +#define LATM_MASK 0xFFE000 // top 11 bits +#define LATM_SIZE_MASK 0x001FFF // bottom 13 bits + +typedef struct LATMParseContext{ + ParseContext pc; + int count; +} LATMParseContext; + +/** + * Find the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int latm_find_frame_end(AVCodecParserContext *s1, const uint8_t *buf, + int buf_size) +{ + LATMParseContext *s = s1->priv_data; + ParseContext *pc = &s->pc; + int pic_found, i; + uint32_t state; + + pic_found = pc->frame_start_found; + state = pc->state; + + if (!pic_found) { + for (i = 0; i < buf_size; i++) { + state = (state<<8) | buf[i]; + if ((state & LATM_MASK) == LATM_HEADER) { + i++; + s->count = -i; + pic_found = 1; + break; + } + } + } + + if (pic_found) { + /* EOF considered as end of frame */ + if (buf_size == 0) + return 0; + if ((state & LATM_SIZE_MASK) - s->count <= buf_size) { + pc->frame_start_found = 0; + pc->state = -1; + return (state & LATM_SIZE_MASK) - s->count; + } + } + + s->count += buf_size; + pc->frame_start_found = pic_found; + pc->state = state; + + return END_NOT_FOUND; +} + +static int latm_parse(AVCodecParserContext *s1, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + LATMParseContext *s = s1->priv_data; + ParseContext *pc = &s->pc; + int next; + + if (s1->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + next = latm_find_frame_end(s1, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser ff_aac_latm_parser = { + .codec_ids = { AV_CODEC_ID_AAC_LATM }, + .priv_data_size = sizeof(LATMParseContext), + .parser_parse = latm_parse, + .parser_close = ff_parse_close +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopus.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopus.c new file mode 100644 index 000000000..16395c73d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopus.c @@ -0,0 +1,48 @@ +/* + * libopus encoder/decoder common code + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/error.h" +#include "libopus.h" + +int ff_opus_error_to_averror(int err) +{ + switch (err) { + case OPUS_BAD_ARG: + return AVERROR(EINVAL); + case OPUS_BUFFER_TOO_SMALL: + return AVERROR_UNKNOWN; + case OPUS_INTERNAL_ERROR: + return AVERROR(EFAULT); + case OPUS_INVALID_PACKET: + return AVERROR_INVALIDDATA; + case OPUS_UNIMPLEMENTED: + return AVERROR(ENOSYS); + case OPUS_INVALID_STATE: + return AVERROR_UNKNOWN; + case OPUS_ALLOC_FAIL: + return AVERROR(ENOMEM); + default: + return AVERROR(EINVAL); + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopus.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopus.h new file mode 100644 index 000000000..a8223d1d6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopus.h @@ -0,0 +1,27 @@ +/* + * libopus encoder/decoder common code + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_LIBOPUS_H +#define AVCODEC_LIBOPUS_H + +int ff_opus_error_to_averror(int err); + +#endif /* AVCODEC_LIBOPUS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopusdec.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopusdec.c new file mode 100644 index 000000000..1724a4990 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopusdec.c @@ -0,0 +1,245 @@ +/* + * Opus decoder using libopus + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/ffmath.h" +#include "libavutil/opt.h" + +#include "avcodec.h" +#include "internal.h" +#include "vorbis.h" +#include "mathops.h" +#include "libopus.h" + +struct libopus_context { + AVClass *class; + OpusMSDecoder *dec; + int pre_skip; +#ifndef OPUS_SET_GAIN + union { int i; double d; } gain; +#endif +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST + int apply_phase_inv; +#endif +}; + +#define OPUS_HEAD_SIZE 19 + +static av_cold int libopus_decode_init(AVCodecContext *avc) +{ + struct libopus_context *opus = avc->priv_data; + int ret, channel_map = 0, gain_db = 0, nb_streams, nb_coupled; + uint8_t mapping_arr[8] = { 0, 1 }, *mapping; + + avc->channels = avc->extradata_size >= 10 ? avc->extradata[9] : (avc->channels == 1) ? 1 : 2; + if (avc->channels <= 0) { + av_log(avc, AV_LOG_WARNING, + "Invalid number of channels %d, defaulting to stereo\n", avc->channels); + avc->channels = 2; + } + + avc->sample_rate = 48000; + avc->sample_fmt = avc->request_sample_fmt == AV_SAMPLE_FMT_FLT ? + AV_SAMPLE_FMT_FLT : AV_SAMPLE_FMT_S16; + avc->channel_layout = avc->channels > 8 ? 0 : + ff_vorbis_channel_layouts[avc->channels - 1]; + + if (avc->extradata_size >= OPUS_HEAD_SIZE) { + opus->pre_skip = AV_RL16(avc->extradata + 10); + gain_db = sign_extend(AV_RL16(avc->extradata + 16), 16); + channel_map = AV_RL8 (avc->extradata + 18); + } + if (avc->extradata_size >= OPUS_HEAD_SIZE + 2 + avc->channels) { + nb_streams = avc->extradata[OPUS_HEAD_SIZE + 0]; + nb_coupled = avc->extradata[OPUS_HEAD_SIZE + 1]; + if (nb_streams + nb_coupled != avc->channels) + av_log(avc, AV_LOG_WARNING, "Inconsistent channel mapping.\n"); + mapping = avc->extradata + OPUS_HEAD_SIZE + 2; + } else { + if (avc->channels > 2 || channel_map) { + av_log(avc, AV_LOG_ERROR, + "No channel mapping for %d channels.\n", avc->channels); + return AVERROR(EINVAL); + } + nb_streams = 1; + nb_coupled = avc->channels > 1; + mapping = mapping_arr; + } + + if (avc->channels > 2 && avc->channels <= 8) { + const uint8_t *vorbis_offset = ff_vorbis_channel_layout_offsets[avc->channels - 1]; + int ch; + + /* Remap channels from Vorbis order to ffmpeg order */ + for (ch = 0; ch < avc->channels; ch++) + mapping_arr[ch] = mapping[vorbis_offset[ch]]; + mapping = mapping_arr; + } + + opus->dec = opus_multistream_decoder_create(avc->sample_rate, avc->channels, + nb_streams, nb_coupled, + mapping, &ret); + if (!opus->dec) { + av_log(avc, AV_LOG_ERROR, "Unable to create decoder: %s\n", + opus_strerror(ret)); + return ff_opus_error_to_averror(ret); + } + +#ifdef OPUS_SET_GAIN + ret = opus_multistream_decoder_ctl(opus->dec, OPUS_SET_GAIN(gain_db)); + if (ret != OPUS_OK) + av_log(avc, AV_LOG_WARNING, "Failed to set gain: %s\n", + opus_strerror(ret)); +#else + { + double gain_lin = ff_exp10(gain_db / (20.0 * 256)); + if (avc->sample_fmt == AV_SAMPLE_FMT_FLT) + opus->gain.d = gain_lin; + else + opus->gain.i = FFMIN(gain_lin * 65536, INT_MAX); + } +#endif + +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST + ret = opus_multistream_decoder_ctl(opus->dec, + OPUS_SET_PHASE_INVERSION_DISABLED(!opus->apply_phase_inv)); + if (ret != OPUS_OK) + av_log(avc, AV_LOG_WARNING, + "Unable to set phase inversion: %s\n", + opus_strerror(ret)); +#endif + + /* Decoder delay (in samples) at 48kHz */ + avc->delay = avc->internal->skip_samples = opus->pre_skip; + + return 0; +} + +static av_cold int libopus_decode_close(AVCodecContext *avc) +{ + struct libopus_context *opus = avc->priv_data; + + if (opus->dec) { + opus_multistream_decoder_destroy(opus->dec); + opus->dec = NULL; + } + return 0; +} + +#define MAX_FRAME_SIZE (960 * 6) + +static int libopus_decode(AVCodecContext *avc, void *data, + int *got_frame_ptr, AVPacket *pkt) +{ + struct libopus_context *opus = avc->priv_data; + AVFrame *frame = data; + int ret, nb_samples; + + frame->nb_samples = MAX_FRAME_SIZE; + if ((ret = ff_get_buffer(avc, frame, 0)) < 0) + return ret; + + if (avc->sample_fmt == AV_SAMPLE_FMT_S16) + nb_samples = opus_multistream_decode(opus->dec, pkt->data, pkt->size, + (opus_int16 *)frame->data[0], + frame->nb_samples, 0); + else + nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size, + (float *)frame->data[0], + frame->nb_samples, 0); + + if (nb_samples < 0) { + av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n", + opus_strerror(nb_samples)); + return ff_opus_error_to_averror(nb_samples); + } + +#ifndef OPUS_SET_GAIN + { + int i = avc->channels * nb_samples; + if (avc->sample_fmt == AV_SAMPLE_FMT_FLT) { + float *pcm = (float *)frame->data[0]; + for (; i > 0; i--, pcm++) + *pcm = av_clipf(*pcm * opus->gain.d, -1, 1); + } else { + int16_t *pcm = (int16_t *)frame->data[0]; + for (; i > 0; i--, pcm++) + *pcm = av_clip_int16(((int64_t)opus->gain.i * *pcm) >> 16); + } + } +#endif + + frame->nb_samples = nb_samples; + *got_frame_ptr = 1; + + return pkt->size; +} + +static void libopus_flush(AVCodecContext *avc) +{ + struct libopus_context *opus = avc->priv_data; + + opus_multistream_decoder_ctl(opus->dec, OPUS_RESET_STATE); + /* The stream can have been extracted by a tool that is not Opus-aware. + Therefore, any packet can become the first of the stream. */ + avc->internal->skip_samples = opus->pre_skip; +} + + +#define OFFSET(x) offsetof(struct libopus_context, x) +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM +static const AVOption libopusdec_options[] = { +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST + { "apply_phase_inv", "Apply intensity stereo phase inversion", OFFSET(apply_phase_inv), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, +#endif + { NULL }, +}; + +static const AVClass libopusdec_class = { + .class_name = "libopusdec", + .item_name = av_default_item_name, + .option = libopusdec_options, + .version = LIBAVUTIL_VERSION_INT, +}; + + +AVCodec ff_libopus_decoder = { + .name = "libopus", + .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_OPUS, + .priv_data_size = sizeof(struct libopus_context), + .init = libopus_decode_init, + .close = libopus_decode_close, + .decode = libopus_decode, + .flush = libopus_flush, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, + AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE }, + .priv_class = &libopusdec_class, + .wrapper_name = "libopus", +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopusenc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopusenc.c new file mode 100644 index 000000000..7c025a66d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/libopusenc.c @@ -0,0 +1,594 @@ +/* + * Opus encoder using libopus + * Copyright (c) 2012 Nathan Caldwell + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/opt.h" +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" +#include "libopus.h" +#include "vorbis.h" +#include "audio_frame_queue.h" + +typedef struct LibopusEncOpts { + int vbr; + int application; + int packet_loss; + int complexity; + float frame_duration; + int packet_size; + int max_bandwidth; + int mapping_family; +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST + int apply_phase_inv; +#endif +} LibopusEncOpts; + +typedef struct LibopusEncContext { + AVClass *class; + OpusMSEncoder *enc; + int stream_count; + uint8_t *samples; + LibopusEncOpts opts; + AudioFrameQueue afq; + const uint8_t *encoder_channel_map; +} LibopusEncContext; + +static const uint8_t opus_coupled_streams[8] = { + 0, 1, 1, 2, 2, 2, 2, 3 +}; + +/* Opus internal to Vorbis channel order mapping written in the header */ +static const uint8_t opus_vorbis_channel_map[8][8] = { + { 0 }, + { 0, 1 }, + { 0, 2, 1 }, + { 0, 1, 2, 3 }, + { 0, 4, 1, 2, 3 }, + { 0, 4, 1, 2, 3, 5 }, + { 0, 4, 1, 2, 3, 5, 6 }, + { 0, 6, 1, 2, 3, 4, 5, 7 }, +}; + +/* libavcodec to libopus channel order mapping, passed to libopus */ +static const uint8_t libavcodec_libopus_channel_map[8][8] = { + { 0 }, + { 0, 1 }, + { 0, 1, 2 }, + { 0, 1, 2, 3 }, + { 0, 1, 3, 4, 2 }, + { 0, 1, 4, 5, 2, 3 }, + { 0, 1, 5, 6, 2, 4, 3 }, + { 0, 1, 6, 7, 4, 5, 2, 3 }, +}; + +static void libopus_write_header(AVCodecContext *avctx, int stream_count, + int coupled_stream_count, + int mapping_family, + const uint8_t *channel_mapping) +{ + uint8_t *p = avctx->extradata; + int channels = avctx->channels; + + bytestream_put_buffer(&p, "OpusHead", 8); + bytestream_put_byte(&p, 1); /* Version */ + bytestream_put_byte(&p, channels); + bytestream_put_le16(&p, avctx->initial_padding); /* Lookahead samples at 48kHz */ + bytestream_put_le32(&p, avctx->sample_rate); /* Original sample rate */ + bytestream_put_le16(&p, 0); /* Gain of 0dB is recommended. */ + + /* Channel mapping */ + bytestream_put_byte(&p, mapping_family); + if (mapping_family != 0) { + bytestream_put_byte(&p, stream_count); + bytestream_put_byte(&p, coupled_stream_count); + bytestream_put_buffer(&p, channel_mapping, channels); + } +} + +static int libopus_configure_encoder(AVCodecContext *avctx, OpusMSEncoder *enc, + LibopusEncOpts *opts) +{ + int ret; + + if (avctx->global_quality) { + av_log(avctx, AV_LOG_ERROR, + "Quality-based encoding not supported, " + "please specify a bitrate and VBR setting.\n"); + return AVERROR(EINVAL); + } + + ret = opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(avctx->bit_rate)); + if (ret != OPUS_OK) { + av_log(avctx, AV_LOG_ERROR, + "Failed to set bitrate: %s\n", opus_strerror(ret)); + return ret; + } + + ret = opus_multistream_encoder_ctl(enc, + OPUS_SET_COMPLEXITY(opts->complexity)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, + "Unable to set complexity: %s\n", opus_strerror(ret)); + + ret = opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(!!opts->vbr)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, + "Unable to set VBR: %s\n", opus_strerror(ret)); + + ret = opus_multistream_encoder_ctl(enc, + OPUS_SET_VBR_CONSTRAINT(opts->vbr == 2)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, + "Unable to set constrained VBR: %s\n", opus_strerror(ret)); + + ret = opus_multistream_encoder_ctl(enc, + OPUS_SET_PACKET_LOSS_PERC(opts->packet_loss)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, + "Unable to set expected packet loss percentage: %s\n", + opus_strerror(ret)); + + if (avctx->cutoff) { + ret = opus_multistream_encoder_ctl(enc, + OPUS_SET_MAX_BANDWIDTH(opts->max_bandwidth)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, + "Unable to set maximum bandwidth: %s\n", opus_strerror(ret)); + } + +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST + ret = opus_multistream_encoder_ctl(enc, + OPUS_SET_PHASE_INVERSION_DISABLED(!opts->apply_phase_inv)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, + "Unable to set phase inversion: %s\n", + opus_strerror(ret)); +#endif + return OPUS_OK; +} + +static int libopus_check_max_channels(AVCodecContext *avctx, + int max_channels) { + if (avctx->channels > max_channels) { + av_log(avctx, AV_LOG_ERROR, "Opus mapping family undefined for %d channels.\n", + avctx->channels); + return AVERROR(EINVAL); + } + + return 0; +} + +static int libopus_check_vorbis_layout(AVCodecContext *avctx, int mapping_family) { + av_assert2(avctx->channels < FF_ARRAY_ELEMS(ff_vorbis_channel_layouts)); + + if (!avctx->channel_layout) { + av_log(avctx, AV_LOG_WARNING, + "No channel layout specified. Opus encoder will use Vorbis " + "channel layout for %d channels.\n", avctx->channels); + } else if (avctx->channel_layout != ff_vorbis_channel_layouts[avctx->channels - 1]) { + char name[32]; + av_get_channel_layout_string(name, sizeof(name), avctx->channels, + avctx->channel_layout); + av_log(avctx, AV_LOG_ERROR, + "Invalid channel layout %s for specified mapping family %d.\n", + name, mapping_family); + + return AVERROR(EINVAL); + } + + return 0; +} + +static int libopus_validate_layout_and_get_channel_map( + AVCodecContext *avctx, + int mapping_family, + const uint8_t ** channel_map_result) +{ + const uint8_t * channel_map = NULL; + int ret; + + switch (mapping_family) { + case -1: + ret = libopus_check_max_channels(avctx, 8); + if (ret == 0) { + ret = libopus_check_vorbis_layout(avctx, mapping_family); + /* Channels do not need to be reordered. */ + } + + break; + case 0: + ret = libopus_check_max_channels(avctx, 2); + if (ret == 0) { + ret = libopus_check_vorbis_layout(avctx, mapping_family); + } + break; + case 1: + /* Opus expects channels to be in Vorbis order. */ + ret = libopus_check_max_channels(avctx, 8); + if (ret == 0) { + ret = libopus_check_vorbis_layout(avctx, mapping_family); + channel_map = ff_vorbis_channel_layout_offsets[avctx->channels - 1]; + } + break; + case 255: + ret = libopus_check_max_channels(avctx, 254); + break; + default: + av_log(avctx, AV_LOG_WARNING, + "Unknown channel mapping family %d. Output channel layout may be invalid.\n", + mapping_family); + ret = 0; + } + + *channel_map_result = channel_map; + return ret; +} + +static av_cold int libopus_encode_init(AVCodecContext *avctx) +{ + LibopusEncContext *opus = avctx->priv_data; + OpusMSEncoder *enc; + uint8_t libopus_channel_mapping[255]; + int ret = OPUS_OK; + int av_ret; + int coupled_stream_count, header_size, frame_size; + int mapping_family; + + frame_size = opus->opts.frame_duration * 48000 / 1000; + switch (frame_size) { + case 120: + case 240: + if (opus->opts.application != OPUS_APPLICATION_RESTRICTED_LOWDELAY) + av_log(avctx, AV_LOG_WARNING, + "LPC mode cannot be used with a frame duration of less " + "than 10ms. Enabling restricted low-delay mode.\n" + "Use a longer frame duration if this is not what you want.\n"); + /* Frame sizes less than 10 ms can only use MDCT mode, so switching to + * RESTRICTED_LOWDELAY avoids an unnecessary extra 2.5ms lookahead. */ + opus->opts.application = OPUS_APPLICATION_RESTRICTED_LOWDELAY; + case 480: + case 960: + case 1920: + case 2880: +#ifdef OPUS_FRAMESIZE_120_MS + case 3840: + case 4800: + case 5760: +#endif + opus->opts.packet_size = + avctx->frame_size = frame_size * avctx->sample_rate / 48000; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Invalid frame duration: %g.\n" + "Frame duration must be exactly one of: 2.5, 5, 10, 20, 40" +#ifdef OPUS_FRAMESIZE_120_MS + ", 60, 80, 100 or 120.\n", +#else + " or 60.\n", +#endif + opus->opts.frame_duration); + return AVERROR(EINVAL); + } + + if (avctx->compression_level < 0 || avctx->compression_level > 10) { + av_log(avctx, AV_LOG_WARNING, + "Compression level must be in the range 0 to 10. " + "Defaulting to 10.\n"); + opus->opts.complexity = 10; + } else { + opus->opts.complexity = avctx->compression_level; + } + + if (avctx->cutoff) { + switch (avctx->cutoff) { + case 4000: + opus->opts.max_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + break; + case 6000: + opus->opts.max_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + break; + case 8000: + opus->opts.max_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + break; + case 12000: + opus->opts.max_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + break; + case 20000: + opus->opts.max_bandwidth = OPUS_BANDWIDTH_FULLBAND; + break; + default: + av_log(avctx, AV_LOG_WARNING, + "Invalid frequency cutoff: %d. Using default maximum bandwidth.\n" + "Cutoff frequency must be exactly one of: 4000, 6000, 8000, 12000 or 20000.\n", + avctx->cutoff); + avctx->cutoff = 0; + } + } + + /* Channels may need to be reordered to match opus mapping. */ + av_ret = libopus_validate_layout_and_get_channel_map(avctx, opus->opts.mapping_family, + &opus->encoder_channel_map); + if (av_ret) { + return av_ret; + } + + if (opus->opts.mapping_family == -1) { + /* By default, use mapping family 1 for the header but use the older + * libopus multistream API to avoid surround masking. */ + + /* Set the mapping family so that the value is correct in the header */ + mapping_family = avctx->channels > 2 ? 1 : 0; + coupled_stream_count = opus_coupled_streams[avctx->channels - 1]; + opus->stream_count = avctx->channels - coupled_stream_count; + memcpy(libopus_channel_mapping, + opus_vorbis_channel_map[avctx->channels - 1], + avctx->channels * sizeof(*libopus_channel_mapping)); + + enc = opus_multistream_encoder_create( + avctx->sample_rate, avctx->channels, opus->stream_count, + coupled_stream_count, + libavcodec_libopus_channel_map[avctx->channels - 1], + opus->opts.application, &ret); + } else { + /* Use the newer multistream API. The encoder will set the channel + * mapping and coupled stream counts to its internal defaults and will + * use surround masking analysis to save bits. */ + mapping_family = opus->opts.mapping_family; + enc = opus_multistream_surround_encoder_create( + avctx->sample_rate, avctx->channels, mapping_family, + &opus->stream_count, &coupled_stream_count, libopus_channel_mapping, + opus->opts.application, &ret); + } + + if (ret != OPUS_OK) { + av_log(avctx, AV_LOG_ERROR, + "Failed to create encoder: %s\n", opus_strerror(ret)); + return ff_opus_error_to_averror(ret); + } + + if (!avctx->bit_rate) { + /* Sane default copied from opusenc */ + avctx->bit_rate = 64000 * opus->stream_count + + 32000 * coupled_stream_count; + av_log(avctx, AV_LOG_WARNING, + "No bit rate set. Defaulting to %"PRId64" bps.\n", avctx->bit_rate); + } + + if (avctx->bit_rate < 500 || avctx->bit_rate > 256000 * avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "The bit rate %"PRId64" bps is unsupported. " + "Please choose a value between 500 and %d.\n", avctx->bit_rate, + 256000 * avctx->channels); + ret = AVERROR(EINVAL); + goto fail; + } + + ret = libopus_configure_encoder(avctx, enc, &opus->opts); + if (ret != OPUS_OK) { + ret = ff_opus_error_to_averror(ret); + goto fail; + } + + /* Header includes channel mapping table if and only if mapping family is NOT 0 */ + header_size = 19 + (mapping_family == 0 ? 0 : 2 + avctx->channels); + avctx->extradata = av_malloc(header_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate extradata.\n"); + ret = AVERROR(ENOMEM); + goto fail; + } + avctx->extradata_size = header_size; + + opus->samples = av_mallocz_array(frame_size, avctx->channels * + av_get_bytes_per_sample(avctx->sample_fmt)); + if (!opus->samples) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate samples buffer.\n"); + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = opus_multistream_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&avctx->initial_padding)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, + "Unable to get number of lookahead samples: %s\n", + opus_strerror(ret)); + + libopus_write_header(avctx, opus->stream_count, coupled_stream_count, + mapping_family, libopus_channel_mapping); + + ff_af_queue_init(avctx, &opus->afq); + + opus->enc = enc; + + return 0; + +fail: + opus_multistream_encoder_destroy(enc); + av_freep(&avctx->extradata); + return ret; +} + +static void libopus_copy_samples_with_channel_map( + uint8_t *dst, const uint8_t *src, const uint8_t *channel_map, + int nb_channels, int nb_samples, int bytes_per_sample) { + int sample, channel; + for (sample = 0; sample < nb_samples; ++sample) { + for (channel = 0; channel < nb_channels; ++channel) { + const size_t src_pos = bytes_per_sample * (nb_channels * sample + channel); + const size_t dst_pos = bytes_per_sample * (nb_channels * sample + channel_map[channel]); + + memcpy(&dst[dst_pos], &src[src_pos], bytes_per_sample); + } + } +} + +static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + LibopusEncContext *opus = avctx->priv_data; + const int bytes_per_sample = av_get_bytes_per_sample(avctx->sample_fmt); + const int sample_size = avctx->channels * bytes_per_sample; + uint8_t *audio; + int ret; + int discard_padding; + + if (frame) { + ret = ff_af_queue_add(&opus->afq, frame); + if (ret < 0) + return ret; + if (opus->encoder_channel_map != NULL) { + audio = opus->samples; + libopus_copy_samples_with_channel_map( + audio, frame->data[0], opus->encoder_channel_map, + avctx->channels, frame->nb_samples, bytes_per_sample); + } else if (frame->nb_samples < opus->opts.packet_size) { + audio = opus->samples; + memcpy(audio, frame->data[0], frame->nb_samples * sample_size); + } else + audio = frame->data[0]; + } else { + if (!opus->afq.remaining_samples || (!opus->afq.frame_alloc && !opus->afq.frame_count)) + return 0; + audio = opus->samples; + memset(audio, 0, opus->opts.packet_size * sample_size); + } + + /* Maximum packet size taken from opusenc in opus-tools. 120ms packets + * consist of 6 frames in one packet. The maximum frame size is 1275 + * bytes along with the largest possible packet header of 7 bytes. */ + if ((ret = ff_alloc_packet2(avctx, avpkt, (1275 * 6 + 7) * opus->stream_count, 0)) < 0) + return ret; + + if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) + ret = opus_multistream_encode_float(opus->enc, (float *)audio, + opus->opts.packet_size, + avpkt->data, avpkt->size); + else + ret = opus_multistream_encode(opus->enc, (opus_int16 *)audio, + opus->opts.packet_size, + avpkt->data, avpkt->size); + + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Error encoding frame: %s\n", opus_strerror(ret)); + return ff_opus_error_to_averror(ret); + } + + av_shrink_packet(avpkt, ret); + + ff_af_queue_remove(&opus->afq, opus->opts.packet_size, + &avpkt->pts, &avpkt->duration); + + discard_padding = opus->opts.packet_size - avpkt->duration; + // Check if subtraction resulted in an overflow + if ((discard_padding < opus->opts.packet_size) != (avpkt->duration > 0)) { + av_packet_unref(avpkt); + av_free(avpkt); + return AVERROR(EINVAL); + } + if (discard_padding > 0) { + uint8_t* side_data = av_packet_new_side_data(avpkt, + AV_PKT_DATA_SKIP_SAMPLES, + 10); + if(!side_data) { + av_packet_unref(avpkt); + av_free(avpkt); + return AVERROR(ENOMEM); + } + AV_WL32(side_data + 4, discard_padding); + } + + *got_packet_ptr = 1; + + return 0; +} + +static av_cold int libopus_encode_close(AVCodecContext *avctx) +{ + LibopusEncContext *opus = avctx->priv_data; + + opus_multistream_encoder_destroy(opus->enc); + + ff_af_queue_close(&opus->afq); + + av_freep(&opus->samples); + av_freep(&avctx->extradata); + + return 0; +} + +#define OFFSET(x) offsetof(LibopusEncContext, opts.x) +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption libopus_options[] = { + { "application", "Intended application type", OFFSET(application), AV_OPT_TYPE_INT, { .i64 = OPUS_APPLICATION_AUDIO }, OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY, FLAGS, "application" }, + { "voip", "Favor improved speech intelligibility", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_VOIP }, 0, 0, FLAGS, "application" }, + { "audio", "Favor faithfulness to the input", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO }, 0, 0, FLAGS, "application" }, + { "lowdelay", "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" }, + { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 120.0, FLAGS }, + { "packet_loss", "Expected packet loss percentage", OFFSET(packet_loss), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, FLAGS }, + { "vbr", "Variable bit rate mode", OFFSET(vbr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 2, FLAGS, "vbr" }, + { "off", "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" }, + { "on", "Use variable bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "vbr" }, + { "constrained", "Use constrained VBR", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, "vbr" }, + { "mapping_family", "Channel Mapping Family", OFFSET(mapping_family), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, FLAGS, "mapping_family" }, +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST + { "apply_phase_inv", "Apply intensity stereo phase inversion", OFFSET(apply_phase_inv), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, +#endif + { NULL }, +}; + +static const AVClass libopus_class = { + .class_name = "libopus", + .item_name = av_default_item_name, + .option = libopus_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVCodecDefault libopus_defaults[] = { + { "b", "0" }, + { "compression_level", "10" }, + { NULL }, +}; + +static const int libopus_sample_rates[] = { + 48000, 24000, 16000, 12000, 8000, 0, +}; + +AVCodec ff_libopus_encoder = { + .name = "libopus", + .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_OPUS, + .priv_data_size = sizeof(LibopusEncContext), + .init = libopus_encode_init, + .encode2 = libopus_encode, + .close = libopus_encode_close, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_FLT, + AV_SAMPLE_FMT_NONE }, + .supported_samplerates = libopus_sample_rates, + .priv_class = &libopus_class, + .defaults = libopus_defaults, + .wrapper_name = "libopus", +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.c new file mode 100644 index 000000000..f8da1e126 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.c @@ -0,0 +1,325 @@ +/* + * LPC utility code + * Copyright (c) 2006 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/common.h" +#include "libavutil/lls.h" + +#define LPC_USE_DOUBLE +#include "lpc.h" +#include "libavutil/avassert.h" + + +/** + * Apply Welch window function to audio block + */ +static void lpc_apply_welch_window_c(const int32_t *data, int len, + double *w_data) +{ + int i, n2; + double w; + double c; + + n2 = (len >> 1); + c = 2.0 / (len - 1.0); + + if (len & 1) { + for(i=0; i qmax) && (sh > min_shift)) { + sh--; + } + + /* since negative shift values are unsupported in decoder, scale down + coefficients instead */ + if(sh == 0 && cmax > qmax) { + double scale = ((double)qmax) / cmax; + for(i=0; i=min_order-1; i--) { + if(ref[i] > 0.10) { + est = i+1; + break; + } + } + return est; +} + +int ff_lpc_calc_ref_coefs(LPCContext *s, + const int32_t *samples, int order, double *ref) +{ + double autoc[MAX_LPC_ORDER + 1]; + + s->lpc_apply_welch_window(samples, s->blocksize, s->windowed_samples); + s->lpc_compute_autocorr(s->windowed_samples, s->blocksize, order, autoc); + compute_ref_coefs(autoc, order, ref, NULL); + + return order; +} + +double ff_lpc_calc_ref_coefs_f(LPCContext *s, const float *samples, int len, + int order, double *ref) +{ + int i; + double signal = 0.0f, avg_err = 0.0f; + double autoc[MAX_LPC_ORDER+1] = {0}, error[MAX_LPC_ORDER+1] = {0}; + const double a = 0.5f, b = 1.0f - a; + + /* Apply windowing */ + for (i = 0; i <= len / 2; i++) { + double weight = a - b*cos((2*M_PI*i)/(len - 1)); + s->windowed_samples[i] = weight*samples[i]; + s->windowed_samples[len-1-i] = weight*samples[len-1-i]; + } + + s->lpc_compute_autocorr(s->windowed_samples, len, order, autoc); + signal = autoc[0]; + compute_ref_coefs(autoc, order, ref, error); + for (i = 0; i < order; i++) + avg_err = (avg_err + error[i])/2.0f; + return signal/avg_err; +} + +/** + * Calculate LPC coefficients for multiple orders + * + * @param lpc_type LPC method for determining coefficients, + * see #FFLPCType for details + */ +int ff_lpc_calc_coefs(LPCContext *s, + const int32_t *samples, int blocksize, int min_order, + int max_order, int precision, + int32_t coefs[][MAX_LPC_ORDER], int *shift, + enum FFLPCType lpc_type, int lpc_passes, + int omethod, int min_shift, int max_shift, int zero_shift) +{ + double autoc[MAX_LPC_ORDER+1]; + double ref[MAX_LPC_ORDER] = { 0 }; + double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER]; + int i, j, pass = 0; + int opt_order; + + av_assert2(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER && + lpc_type > FF_LPC_TYPE_FIXED); + av_assert0(lpc_type == FF_LPC_TYPE_CHOLESKY || lpc_type == FF_LPC_TYPE_LEVINSON); + + /* reinit LPC context if parameters have changed */ + if (blocksize != s->blocksize || max_order != s->max_order || + lpc_type != s->lpc_type) { + ff_lpc_end(s); + ff_lpc_init(s, blocksize, max_order, lpc_type); + } + + if(lpc_passes <= 0) + lpc_passes = 2; + + if (lpc_type == FF_LPC_TYPE_LEVINSON || (lpc_type == FF_LPC_TYPE_CHOLESKY && lpc_passes > 1)) { + s->lpc_apply_welch_window(samples, blocksize, s->windowed_samples); + + s->lpc_compute_autocorr(s->windowed_samples, blocksize, max_order, autoc); + + compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1); + + for(i=0; ills_models; + LOCAL_ALIGNED(32, double, var, [FFALIGN(MAX_LPC_ORDER+1,4)]); + double av_uninit(weight); + memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var)); + + for(j=0; j>pass) + fabs(eval - var[0]); + inv = 1/eval; + rinv = sqrt(inv); + for(j=0; j<=max_order; j++) + var[j] *= rinv; + weight += inv; + }else + weight++; + + m[pass&1].update_lls(&m[pass&1], var); + } + avpriv_solve_lls(&m[pass&1], 0.001, 0); + } + + for(i=0; i0; i--) + ref[i] = ref[i-1] - ref[i]; + } + + opt_order = max_order; + + if(omethod == ORDER_METHOD_EST) { + opt_order = estimate_best_order(ref, min_order, max_order); + i = opt_order-1; + quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], + min_shift, max_shift, zero_shift); + } else { + for(i=min_order-1; iblocksize = blocksize; + s->max_order = max_order; + s->lpc_type = lpc_type; + + s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) * + sizeof(*s->windowed_samples)); + if (!s->windowed_buffer) + return AVERROR(ENOMEM); + s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4); + + s->lpc_apply_welch_window = lpc_apply_welch_window_c; + s->lpc_compute_autocorr = lpc_compute_autocorr_c; + + if (ARCH_X86) + ff_lpc_init_x86(s); + + return 0; +} + +av_cold void ff_lpc_end(LPCContext *s) +{ + av_freep(&s->windowed_buffer); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.h new file mode 100644 index 000000000..88ca247f8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/lpc.h @@ -0,0 +1,212 @@ +/* + * LPC utility code + * Copyright (c) 2006 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_LPC_H +#define AVCODEC_LPC_H + +#include +#include "libavutil/avassert.h" +#include "libavutil/lls.h" +#include "aac_defines.h" + +#define ORDER_METHOD_EST 0 +#define ORDER_METHOD_2LEVEL 1 +#define ORDER_METHOD_4LEVEL 2 +#define ORDER_METHOD_8LEVEL 3 +#define ORDER_METHOD_SEARCH 4 +#define ORDER_METHOD_LOG 5 + +#define MIN_LPC_ORDER 1 +#define MAX_LPC_ORDER 32 + +/** + * LPC analysis type + */ +enum FFLPCType { + FF_LPC_TYPE_DEFAULT = -1, ///< use the codec default LPC type + FF_LPC_TYPE_NONE = 0, ///< do not use LPC prediction or use all zero coefficients + FF_LPC_TYPE_FIXED = 1, ///< fixed LPC coefficients + FF_LPC_TYPE_LEVINSON = 2, ///< Levinson-Durbin recursion + FF_LPC_TYPE_CHOLESKY = 3, ///< Cholesky factorization + FF_LPC_TYPE_NB , ///< Not part of ABI +}; + +typedef struct LPCContext { + int blocksize; + int max_order; + enum FFLPCType lpc_type; + double *windowed_buffer; + double *windowed_samples; + + /** + * Apply a Welch window to an array of input samples. + * The output samples have the same scale as the input, but are in double + * sample format. + * @param data input samples + * @param len number of input samples + * @param w_data output samples + */ + void (*lpc_apply_welch_window)(const int32_t *data, int len, + double *w_data); + /** + * Perform autocorrelation on input samples with delay of 0 to lag. + * @param data input samples. + * constraints: no alignment needed, but must have at + * least lag*sizeof(double) valid bytes preceding it, and + * size must be at least (len+1)*sizeof(double) if data is + * 16-byte aligned or (len+2)*sizeof(double) if data is + * unaligned. + * @param len number of input samples to process + * @param lag maximum delay to calculate + * @param autoc output autocorrelation coefficients. + * constraints: array size must be at least lag+1. + */ + void (*lpc_compute_autocorr)(const double *data, int len, int lag, + double *autoc); + + // TODO: these should be allocated to reduce ABI compatibility issues + LLSModel lls_models[2]; +} LPCContext; + + +/** + * Calculate LPC coefficients for multiple orders + */ +int ff_lpc_calc_coefs(LPCContext *s, + const int32_t *samples, int blocksize, int min_order, + int max_order, int precision, + int32_t coefs[][MAX_LPC_ORDER], int *shift, + enum FFLPCType lpc_type, int lpc_passes, + int omethod, int min_shift, int max_shift, int zero_shift); + +int ff_lpc_calc_ref_coefs(LPCContext *s, + const int32_t *samples, int order, double *ref); + +double ff_lpc_calc_ref_coefs_f(LPCContext *s, const float *samples, int len, + int order, double *ref); + +/** + * Initialize LPCContext. + */ +int ff_lpc_init(LPCContext *s, int blocksize, int max_order, + enum FFLPCType lpc_type); +void ff_lpc_init_x86(LPCContext *s); + +/** + * Uninitialize LPCContext. + */ +void ff_lpc_end(LPCContext *s); + +#if USE_FIXED +typedef int LPC_TYPE; +typedef unsigned LPC_TYPE_U; +#else +#ifdef LPC_USE_DOUBLE +typedef double LPC_TYPE; +typedef double LPC_TYPE_U; +#else +typedef float LPC_TYPE; +typedef float LPC_TYPE_U; +#endif +#endif // USE_FIXED + +/** + * Schur recursion. + * Produces reflection coefficients from autocorrelation data. + */ +static inline void compute_ref_coefs(const LPC_TYPE *autoc, int max_order, + LPC_TYPE *ref, LPC_TYPE *error) +{ + int i, j; + LPC_TYPE err; + LPC_TYPE gen0[MAX_LPC_ORDER], gen1[MAX_LPC_ORDER]; + + for (i = 0; i < max_order; i++) + gen0[i] = gen1[i] = autoc[i + 1]; + + err = autoc[0]; + ref[0] = -gen1[0] / err; + err += gen1[0] * ref[0]; + if (error) + error[0] = err; + for (i = 1; i < max_order; i++) { + for (j = 0; j < max_order - i; j++) { + gen1[j] = gen1[j + 1] + ref[i - 1] * gen0[j]; + gen0[j] = gen1[j + 1] * ref[i - 1] + gen0[j]; + } + ref[i] = -gen1[0] / err; + err += gen1[0] * ref[i]; + if (error) + error[i] = err; + } +} + +/** + * Levinson-Durbin recursion. + * Produce LPC coefficients from autocorrelation data. + */ +static inline int AAC_RENAME(compute_lpc_coefs)(const LPC_TYPE *autoc, int max_order, + LPC_TYPE *lpc, int lpc_stride, int fail, + int normalize) +{ + int i, j; + LPC_TYPE err = 0; + LPC_TYPE *lpc_last = lpc; + + av_assert2(normalize || !fail); + + if (normalize) + err = *autoc++; + + if (fail && (autoc[max_order - 1] == 0 || err <= 0)) + return -1; + + for(i=0; i>1; j++) { + LPC_TYPE f = lpc_last[ j]; + LPC_TYPE b = lpc_last[i-1-j]; + lpc[ j] = f + (LPC_TYPE_U)AAC_MUL26(r, b); + lpc[i-1-j] = b + (LPC_TYPE_U)AAC_MUL26(r, f); + } + + if (fail && err < 0) + return -1; + + lpc_last = lpc; + lpc += lpc_stride; + } + + return 0; +} + +#endif /* AVCODEC_LPC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mathops.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mathops.h new file mode 100644 index 000000000..1c3566431 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mathops.h @@ -0,0 +1,251 @@ +/* + * simple math operations + * Copyright (c) 2001, 2002 Fabrice Bellard + * Copyright (c) 2006 Michael Niedermayer et al + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVCODEC_MATHOPS_H +#define AVCODEC_MATHOPS_H + +#include + +#include "libavutil/common.h" +#include "libavutil/reverse.h" +#include "config.h" + +#define MAX_NEG_CROP 1024 + +extern const uint32_t ff_inverse[257]; +extern const uint8_t ff_sqrt_tab[256]; +extern const uint8_t ff_crop_tab[256 + 2 * MAX_NEG_CROP]; +extern const uint8_t ff_zigzag_direct[64]; +extern const uint8_t ff_zigzag_scan[16+1]; + +#if ARCH_ARM +# include "arm/mathops.h" +#elif ARCH_AVR32 +# include "avr32/mathops.h" +#elif ARCH_MIPS +# include "mips/mathops.h" +#elif ARCH_PPC +# include "ppc/mathops.h" +#elif ARCH_X86 +# include "x86/mathops.h" +#endif + +/* generic implementation */ + +#ifndef MUL64 +# define MUL64(a,b) ((int64_t)(a) * (int64_t)(b)) +#endif + +#ifndef MULL +# define MULL(a,b,s) (MUL64(a, b) >> (s)) +#endif + +#ifndef MULH +static av_always_inline int MULH(int a, int b){ + return MUL64(a, b) >> 32; +} +#endif + +#ifndef UMULH +static av_always_inline unsigned UMULH(unsigned a, unsigned b){ + return ((uint64_t)(a) * (uint64_t)(b))>>32; +} +#endif + +#ifndef MAC64 +# define MAC64(d, a, b) ((d) += MUL64(a, b)) +#endif + +#ifndef MLS64 +# define MLS64(d, a, b) ((d) -= MUL64(a, b)) +#endif + +/* signed 16x16 -> 32 multiply add accumulate */ +#ifndef MAC16 +# define MAC16(rt, ra, rb) rt += (ra) * (rb) +#endif + +/* signed 16x16 -> 32 multiply */ +#ifndef MUL16 +# define MUL16(ra, rb) ((ra) * (rb)) +#endif + +#ifndef MLS16 +# define MLS16(rt, ra, rb) ((rt) -= (ra) * (rb)) +#endif + +/* median of 3 */ +#ifndef mid_pred +#define mid_pred mid_pred +static inline av_const int mid_pred(int a, int b, int c) +{ + if(a>b){ + if(c>b){ + if(c>a) b=a; + else b=c; + } + }else{ + if(b>c){ + if(c>a) b=c; + else b=a; + } + } + return b; +} +#endif + +#ifndef median4 +#define median4 median4 +static inline av_const int median4(int a, int b, int c, int d) +{ + if (a < b) { + if (c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2; + else return (FFMIN(b, c) + FFMAX(a, d)) / 2; + } else { + if (c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2; + else return (FFMIN(a, c) + FFMAX(b, d)) / 2; + } +} +#endif + +#ifndef sign_extend +static inline av_const int sign_extend(int val, unsigned bits) +{ + unsigned shift = 8 * sizeof(int) - bits; + union { unsigned u; int s; } v = { (unsigned) val << shift }; + return v.s >> shift; +} +#endif + +#ifndef zero_extend +static inline av_const unsigned zero_extend(unsigned val, unsigned bits) +{ + return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits); +} +#endif + +#ifndef COPY3_IF_LT +#define COPY3_IF_LT(x, y, a, b, c, d)\ +if ((y) < (x)) {\ + (x) = (y);\ + (a) = (b);\ + (c) = (d);\ +} +#endif + +#ifndef MASK_ABS +#define MASK_ABS(mask, level) do { \ + mask = level >> 31; \ + level = (level ^ mask) - mask; \ + } while (0) +#endif + +#ifndef NEG_SSR32 +# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) +#endif + +#ifndef NEG_USR32 +# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) +#endif + +#if HAVE_BIGENDIAN +# ifndef PACK_2U8 +# define PACK_2U8(a,b) (((a) << 8) | (b)) +# endif +# ifndef PACK_4U8 +# define PACK_4U8(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) +# endif +# ifndef PACK_2U16 +# define PACK_2U16(a,b) (((a) << 16) | (b)) +# endif +#else +# ifndef PACK_2U8 +# define PACK_2U8(a,b) (((b) << 8) | (a)) +# endif +# ifndef PACK_4U2 +# define PACK_4U8(a,b,c,d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a)) +# endif +# ifndef PACK_2U16 +# define PACK_2U16(a,b) (((b) << 16) | (a)) +# endif +#endif + +#ifndef PACK_2S8 +# define PACK_2S8(a,b) PACK_2U8((a)&255, (b)&255) +#endif +#ifndef PACK_4S8 +# define PACK_4S8(a,b,c,d) PACK_4U8((a)&255, (b)&255, (c)&255, (d)&255) +#endif +#ifndef PACK_2S16 +# define PACK_2S16(a,b) PACK_2U16((a)&0xffff, (b)&0xffff) +#endif + +#ifndef FASTDIV +# define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32)) +#endif /* FASTDIV */ + +#ifndef ff_sqrt +#define ff_sqrt ff_sqrt +static inline av_const unsigned int ff_sqrt(unsigned int a) +{ + unsigned int b; + + if (a < 255) return (ff_sqrt_tab[a + 1] - 1) >> 4; + else if (a < (1 << 12)) b = ff_sqrt_tab[a >> 4] >> 2; +#if !CONFIG_SMALL + else if (a < (1 << 14)) b = ff_sqrt_tab[a >> 6] >> 1; + else if (a < (1 << 16)) b = ff_sqrt_tab[a >> 8] ; +#endif + else { + int s = av_log2_16bit(a >> 16) >> 1; + unsigned int c = a >> (s + 2); + b = ff_sqrt_tab[c >> (s + 8)]; + b = FASTDIV(c,b) + (b << s); + } + + return b - (a < b * b); +} +#endif + +static inline av_const float ff_sqrf(float a) +{ + return a*a; +} + +static inline int8_t ff_u8_to_s8(uint8_t a) +{ + union { + uint8_t u8; + int8_t s8; + } b; + b.u8 = a; + return b.s8; +} + +static av_always_inline uint32_t bitswap_32(uint32_t x) +{ + return (uint32_t)ff_reverse[ x & 0xFF] << 24 | + (uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 | + (uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 | + (uint32_t)ff_reverse[ x >> 24]; +} + +#endif /* AVCODEC_MATHOPS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mathtables.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mathtables.c new file mode 100644 index 000000000..81eabc7a6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mathtables.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "mathops.h" + +/* a*inverse[b]>>32 == a/b for all 0<=a<=16909558 && 2<=b<=256 + * for a>16909558, is an overestimate by less than 1 part in 1<<24 */ +const uint32_t ff_inverse[257]={ + 0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757, + 536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154, + 268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709, + 178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333, + 134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367, + 107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283, + 89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315, + 76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085, + 67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498, + 59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675, + 53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441, + 48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183, + 44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712, + 41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400, + 38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163, + 35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641, + 33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573, + 31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737, + 29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493, + 28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373, + 26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368, + 25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671, + 24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767, + 23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740, + 22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751, + 21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635, + 20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593, + 19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944, + 19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933, + 18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575, + 17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532, + 17318417, 17248865, 17179870, 17111424, 17043522, 16976156, 16909321, 16843010, + 16777216 +}; + +const uint8_t ff_sqrt_tab[256]={ + 0, 16, 23, 28, 32, 36, 40, 43, 46, 48, 51, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 77, 79, 80, 82, 84, 85, 87, 88, 90, + 91, 92, 94, 95, 96, 98, 99,100,102,103,104,105,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127, +128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,144,145,146,147,148,149,150,151,151,152,153,154,155,156,156, +157,158,159,160,160,161,162,163,164,164,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,176,177,178,179,179,180,181, +182,182,183,184,184,185,186,186,187,188,188,189,190,190,191,192,192,193,194,194,195,196,196,197,198,198,199,200,200,201,202,202, +203,204,204,205,205,206,207,207,208,208,209,210,210,211,212,212,213,213,214,215,215,216,216,217,218,218,219,219,220,220,221,222, +222,223,223,224,224,225,226,226,227,227,228,228,229,230,230,231,231,232,232,233,233,234,235,235,236,236,237,237,238,238,239,239, +240,240,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,253,254,254,255,255,255 +}; + +#define times4(x) x, x, x, x +#define times256(x) times4(times4(times4(times4(times4(x))))) + +const uint8_t ff_crop_tab[256 + 2 * MAX_NEG_CROP] = { +times256(0x00), +0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, +0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, +0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, +0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, +0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, +0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, +0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, +0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F, +0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, +0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, +0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, +0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, +0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, +0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, +0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, +0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, +times256(0xFF) +}; + +const uint8_t ff_zigzag_direct[64] = { + 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 +}; + +const uint8_t ff_zigzag_scan[16+1] = { + 0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4, + 1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4, + 1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4, + 3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.asm new file mode 100644 index 000000000..2a2cdbd21 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.asm @@ -0,0 +1,221 @@ +;****************************************************************************** +;* SIMD optimized non-power-of-two MDCT functions +;* +;* Copyright (C) 2017 Rostislav Pehlivanov +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +perm_neg: dd 2, 5, 3, 4, 6, 1, 7, 0 +perm_pos: dd 0, 7, 1, 6, 4, 3, 5, 2 +sign_adjust_r: times 4 dd 0x80000000, 0x00000000 + +sign_adjust_5: dd 0x00000000, 0x80000000, 0x80000000, 0x00000000 + +SECTION .text + +%if ARCH_X86_64 + +;***************************************************************************************** +;void ff_fft15_avx(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); +;***************************************************************************************** +%macro FFT5 3 ; %1 - in_offset, %2 - dst1 (64bit used), %3 - dst2 + VBROADCASTSD m0, [inq + %1] ; in[ 0].re, in[ 0].im, in[ 0].re, in[ 0].im + movsd xm1, [inq + 1*16 + 8 + %1] ; in[ 3].re, in[ 3].im, 0, 0 + movsd xm4, [inq + 6*16 + 0 + %1] ; in[12].re, in[12].im, 0, 0 + movhps xm1, [inq + 3*16 + 0 + %1] ; in[ 3].re, in[ 3].im, in[ 6].re, in[ 6].im + movhps xm4, [inq + 4*16 + 8 + %1] ; in[12].re, in[12].im, in[ 9].re, in[ 9].im + + subps xm2, xm1, xm4 ; t[2].im, t[2].re, t[3].im, t[3].re + addps xm1, xm4 ; t[0].re, t[0].im, t[1].re, t[1].im + + movhlps %2, xm1 ; t[0].re, t[1].re, t[0].im, t[1].im + addps %2, xm1 + addps %2, xm0 ; DC[0].re, DC[0].im, junk... + movlhps %2, %2 ; DC[0].re, DC[0].im, DC[0].re, DC[0].im + + shufps xm3, xm1, xm2, q0110 ; t[0].re, t[0].im, t[2].re, t[2].im + shufps xm1, xm2, q2332 ; t[1].re, t[1].im, t[3].re, t[3].im + + mulps xm%3, xm1, xm5 + mulps xm4, xm3, xm6 + mulps xm1, xm6 + + xorps xm1, xm7 + mulps xm3, xm5 + addsubps xm3, xm1 ; t[0].re, t[0].im, t[2].re, t[2].im + subps xm%3, xm4 ; t[4].re, t[4].im, t[5].re, t[5].im + + movhlps xm2, xm%3, xm3 ; t[2].re, t[2].im, t[5].re, t[5].im + movlhps xm3, xm%3 ; t[0].re, t[0].im, t[4].re, t[4].im + + xorps xm2, xm7 + addps xm%3, xm2, xm3 + subps xm3, xm2 + + shufps xm3, xm3, q1032 + vinsertf128 m%3, m%3, xm3, 1 ; All ACs (tmp[1] through to tmp[4]) + addps m%3, m%3, m0 ; Finally offset with DCs +%endmacro + +%macro BUTTERFLIES_DC 1 ; %1 - exptab_offset + mulps xm0, xm9, [exptabq + %1 + 16*0] + mulps xm1, xm10, [exptabq + %1 + 16*1] + + haddps xm0, xm1 + movhlps xm1, xm0 ; t[0].re, t[1].re, t[0].im, t[1].im + + addps xm0, xm1 + addps xm0, xm8 + + movsd [outq], xm0 +%endmacro + +%macro BUTTERFLIES_AC 1 ; %1 - exptab_offset + mulps m0, m12, [exptabq + 64*0 + 0*mmsize + %1] + mulps m1, m12, [exptabq + 64*0 + 1*mmsize + %1] + mulps m2, m13, [exptabq + 64*1 + 0*mmsize + %1] + mulps m3, m13, [exptabq + 64*1 + 1*mmsize + %1] + + addps m0, m0, m2 + addps m1, m1, m3 + addps m0, m0, m11 + + shufps m1, m1, m1, q2301 + addps m0, m0, m1 + + vextractf128 xm1, m0, 1 + + movlps [outq + strideq*1], xm0 + movhps [outq + strideq*2], xm0 + movlps [outq + stride3q], xm1 + movhps [outq + strideq*4], xm1 +%endmacro + +INIT_YMM avx +cglobal fft15, 4, 5, 14, out, in, exptab, stride, stride5 + shl strideq, 3 + + movaps xm5, [exptabq + 480 + 16*0] + movaps xm6, [exptabq + 480 + 16*1] + movaps xm7, [sign_adjust_5] + + FFT5 0, xm8, 11 + FFT5 8, xm9, 12 + FFT5 16, xm10, 13 + +%define stride3q inq + lea stride3q, [strideq + strideq*2] + lea stride5q, [strideq + strideq*4] + + BUTTERFLIES_DC (8*6 + 4*0)*2*4 + BUTTERFLIES_AC (8*0 + 0*0)*2*4 + + add outq, stride5q + BUTTERFLIES_DC (8*6 + 4*1)*2*4 + BUTTERFLIES_AC (8*2 + 0*0)*2*4 + + add outq, stride5q + BUTTERFLIES_DC (8*6 + 4*2)*2*4 + BUTTERFLIES_AC (8*4 + 0*0)*2*4 + + RET + +%endif ; ARCH_X86_64 + +;******************************************************************************************************* +;void ff_mdct15_postreindex(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); +;******************************************************************************************************* +%macro LUT_LOAD_4D 3 + mov r4d, [lutq + %3q*4 + 0] + movsd xmm%1, [inq + r4q*8] + mov r4d, [lutq + %3q*4 + 4] + movhps xmm%1, [inq + r4q*8] +%if cpuflag(avx2) + mov r4d, [lutq + %3q*4 + 8] + movsd %2, [inq + r4q*8] + mov r4d, [lutq + %3q*4 + 12] + movhps %2, [inq + r4q*8] + vinsertf128 %1, %1, %2, 1 +%endif +%endmacro + +%macro POSTROTATE_FN 1 +cglobal mdct15_postreindex, 5, 7, 8 + cpuflag(avx2)*2, out, in, exp, lut, len8, offset_p, offset_n + + xor offset_nq, offset_nq + lea offset_pq, [len8q*2 - %1] + + movaps m7, [sign_adjust_r] + +%if cpuflag(avx2) + movaps m8, [perm_pos] + movaps m9, [perm_neg] +%endif + +.loop: + movups m0, [expq + offset_pq*8] ; exp[p0].re, exp[p0].im, exp[p1].re, exp[p1].im, exp[p2].re, exp[p2].im, exp[p3].re, exp[p3].im + movups m1, [expq + offset_nq*8] ; exp[n3].re, exp[n3].im, exp[n2].re, exp[n2].im, exp[n1].re, exp[n1].im, exp[n0].re, exp[n0].im + + LUT_LOAD_4D m3, xm4, offset_p ; in[p0].re, in[p0].im, in[p1].re, in[p1].im, in[p2].re, in[p2].im, in[p3].re, in[p3].im + LUT_LOAD_4D m4, xm5, offset_n ; in[n3].re, in[n3].im, in[n2].re, in[n2].im, in[n1].re, in[n1].im, in[n0].re, in[n0].im + + mulps m5, m3, m0 ; in[p].reim * exp[p].reim + mulps m6, m4, m1 ; in[n].reim * exp[n].reim + + xorps m5, m7 ; in[p].re *= -1, in[p].im *= 1 + xorps m6, m7 ; in[n].re *= -1, in[n].im *= 1 + + shufps m3, m3, m3, q2301 ; in[p].imre + shufps m4, m4, m4, q2301 ; in[n].imre + + mulps m3, m0 ; in[p].imre * exp[p].reim + mulps m4, m1 ; in[n].imre * exp[n].reim + + haddps m3, m6 ; out[n0].im, out[n1].im, out[n3].re, out[n2].re, out[n2].im, out[n3].im, out[n1].re, out[n0].re + haddps m5, m4 ; out[p0].re, out[p1].re, out[p3].im, out[p2].im, out[p2].re, out[p3].re, out[p1].im, out[p0].im + +%if cpuflag(avx2) + vpermps m3, m9, m3 ; out[n3].im, out[n3].re, out[n2].im, out[n2].re, out[n1].im, out[n1].re, out[n0].im, out[n0].re + vpermps m5, m8, m5 ; out[p0].re, out[p0].im, out[p1].re, out[p1].im, out[p2].re, out[p2].im, out[p3].re, out[p3].im +%else + shufps m3, m3, m3, q0312 + shufps m5, m5, m5, q2130 +%endif + + movups [outq + offset_nq*8], m3 + movups [outq + offset_pq*8], m5 + + sub offset_pq, %1 + add offset_nq, %1 + cmp offset_nq, offset_pq + jle .loop + + REP_RET +%endmacro + +INIT_XMM sse3 +POSTROTATE_FN 2 + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +POSTROTATE_FN 4 +%endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.c new file mode 100644 index 000000000..6f35059bf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Celt non-power of 2 iMDCT + */ + +#include +#include +#include + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/common.h" + +#include "mdct15.h" + +#define FFT_FLOAT 1 +#include "fft-internal.h" + +#define CMUL3(c, a, b) CMUL((c).re, (c).im, (a).re, (a).im, (b).re, (b).im) + +av_cold void ff_mdct15_uninit(MDCT15Context **ps) +{ + MDCT15Context *s = *ps; + + if (!s) + return; + + ff_fft_end(&s->ptwo_fft); + + av_freep(&s->pfa_prereindex); + av_freep(&s->pfa_postreindex); + av_freep(&s->twiddle_exptab); + av_freep(&s->tmp); + + av_freep(ps); +} + +static inline int init_pfa_reindex_tabs(MDCT15Context *s) +{ + int i, j; + const int b_ptwo = s->ptwo_fft.nbits; /* Bits for the power of two FFTs */ + const int l_ptwo = 1 << b_ptwo; /* Total length for the power of two FFTs */ + const int inv_1 = l_ptwo << ((4 - b_ptwo) & 3); /* (2^b_ptwo)^-1 mod 15 */ + const int inv_2 = 0xeeeeeeef & ((1U << b_ptwo) - 1); /* 15^-1 mod 2^b_ptwo */ + + s->pfa_prereindex = av_malloc_array(15 * l_ptwo, sizeof(*s->pfa_prereindex)); + if (!s->pfa_prereindex) + return 1; + + s->pfa_postreindex = av_malloc_array(15 * l_ptwo, sizeof(*s->pfa_postreindex)); + if (!s->pfa_postreindex) + return 1; + + /* Pre/Post-reindex */ + for (i = 0; i < l_ptwo; i++) { + for (j = 0; j < 15; j++) { + const int q_pre = ((l_ptwo * j)/15 + i) >> b_ptwo; + const int q_post = (((j*inv_1)/15) + (i*inv_2)) >> b_ptwo; + const int k_pre = 15*i + (j - q_pre*15)*(1 << b_ptwo); + const int k_post = i*inv_2*15 + j*inv_1 - 15*q_post*l_ptwo; + s->pfa_prereindex[i*15 + j] = k_pre << 1; + s->pfa_postreindex[k_post] = l_ptwo*j + i; + } + } + + return 0; +} + +/* Stride is hardcoded to 3 */ +static inline void fft5(FFTComplex *out, FFTComplex *in, FFTComplex exptab[2]) +{ + FFTComplex z0[4], t[6]; + + t[0].re = in[3].re + in[12].re; + t[0].im = in[3].im + in[12].im; + t[1].im = in[3].re - in[12].re; + t[1].re = in[3].im - in[12].im; + t[2].re = in[6].re + in[ 9].re; + t[2].im = in[6].im + in[ 9].im; + t[3].im = in[6].re - in[ 9].re; + t[3].re = in[6].im - in[ 9].im; + + out[0].re = in[0].re + in[3].re + in[6].re + in[9].re + in[12].re; + out[0].im = in[0].im + in[3].im + in[6].im + in[9].im + in[12].im; + + t[4].re = exptab[0].re * t[2].re - exptab[1].re * t[0].re; + t[4].im = exptab[0].re * t[2].im - exptab[1].re * t[0].im; + t[0].re = exptab[0].re * t[0].re - exptab[1].re * t[2].re; + t[0].im = exptab[0].re * t[0].im - exptab[1].re * t[2].im; + t[5].re = exptab[0].im * t[3].re - exptab[1].im * t[1].re; + t[5].im = exptab[0].im * t[3].im - exptab[1].im * t[1].im; + t[1].re = exptab[0].im * t[1].re + exptab[1].im * t[3].re; + t[1].im = exptab[0].im * t[1].im + exptab[1].im * t[3].im; + + z0[0].re = t[0].re - t[1].re; + z0[0].im = t[0].im - t[1].im; + z0[1].re = t[4].re + t[5].re; + z0[1].im = t[4].im + t[5].im; + + z0[2].re = t[4].re - t[5].re; + z0[2].im = t[4].im - t[5].im; + z0[3].re = t[0].re + t[1].re; + z0[3].im = t[0].im + t[1].im; + + out[1].re = in[0].re + z0[3].re; + out[1].im = in[0].im + z0[0].im; + out[2].re = in[0].re + z0[2].re; + out[2].im = in[0].im + z0[1].im; + out[3].re = in[0].re + z0[1].re; + out[3].im = in[0].im + z0[2].im; + out[4].re = in[0].re + z0[0].re; + out[4].im = in[0].im + z0[3].im; +} + +static void fft15_c(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride) +{ + int k; + FFTComplex tmp1[5], tmp2[5], tmp3[5]; + + fft5(tmp1, in + 0, exptab + 19); + fft5(tmp2, in + 1, exptab + 19); + fft5(tmp3, in + 2, exptab + 19); + + for (k = 0; k < 5; k++) { + FFTComplex t[2]; + + CMUL3(t[0], tmp2[k], exptab[k]); + CMUL3(t[1], tmp3[k], exptab[2 * k]); + out[stride*k].re = tmp1[k].re + t[0].re + t[1].re; + out[stride*k].im = tmp1[k].im + t[0].im + t[1].im; + + CMUL3(t[0], tmp2[k], exptab[k + 5]); + CMUL3(t[1], tmp3[k], exptab[2 * (k + 5)]); + out[stride*(k + 5)].re = tmp1[k].re + t[0].re + t[1].re; + out[stride*(k + 5)].im = tmp1[k].im + t[0].im + t[1].im; + + CMUL3(t[0], tmp2[k], exptab[k + 10]); + CMUL3(t[1], tmp3[k], exptab[2 * k + 5]); + out[stride*(k + 10)].re = tmp1[k].re + t[0].re + t[1].re; + out[stride*(k + 10)].im = tmp1[k].im + t[0].im + t[1].im; + } +} + +static void mdct15(MDCT15Context *s, float *dst, const float *src, ptrdiff_t stride) +{ + int i, j; + const int len4 = s->len4, len3 = len4 * 3, len8 = len4 >> 1; + const int l_ptwo = 1 << s->ptwo_fft.nbits; + FFTComplex fft15in[15]; + + /* Folding and pre-reindexing */ + for (i = 0; i < l_ptwo; i++) { + for (j = 0; j < 15; j++) { + const int k = s->pfa_prereindex[i*15 + j]; + FFTComplex tmp, exp = s->twiddle_exptab[k >> 1]; + if (k < len4) { + tmp.re = -src[ len4 + k] + src[1*len4 - 1 - k]; + tmp.im = -src[ len3 + k] - src[1*len3 - 1 - k]; + } else { + tmp.re = -src[ len4 + k] - src[5*len4 - 1 - k]; + tmp.im = src[-len4 + k] - src[1*len3 - 1 - k]; + } + CMUL(fft15in[j].im, fft15in[j].re, tmp.re, tmp.im, exp.re, exp.im); + } + s->fft15(s->tmp + s->ptwo_fft.revtab[i], fft15in, s->exptab, l_ptwo); + } + + /* Then a 15xN FFT (where N is a power of two) */ + for (i = 0; i < 15; i++) + s->ptwo_fft.fft_calc(&s->ptwo_fft, s->tmp + l_ptwo*i); + + /* Reindex again, apply twiddles and output */ + for (i = 0; i < len8; i++) { + const int i0 = len8 + i, i1 = len8 - i - 1; + const int s0 = s->pfa_postreindex[i0], s1 = s->pfa_postreindex[i1]; + + CMUL(dst[2*i1*stride + stride], dst[2*i0*stride], s->tmp[s0].re, s->tmp[s0].im, + s->twiddle_exptab[i0].im, s->twiddle_exptab[i0].re); + CMUL(dst[2*i0*stride + stride], dst[2*i1*stride], s->tmp[s1].re, s->tmp[s1].im, + s->twiddle_exptab[i1].im, s->twiddle_exptab[i1].re); + } +} + +static void imdct15_half(MDCT15Context *s, float *dst, const float *src, + ptrdiff_t stride) +{ + FFTComplex fft15in[15]; + FFTComplex *z = (FFTComplex *)dst; + int i, j, len8 = s->len4 >> 1, l_ptwo = 1 << s->ptwo_fft.nbits; + const float *in1 = src, *in2 = src + (s->len2 - 1) * stride; + + /* Reindex input, putting it into a buffer and doing an Nx15 FFT */ + for (i = 0; i < l_ptwo; i++) { + for (j = 0; j < 15; j++) { + const int k = s->pfa_prereindex[i*15 + j]; + FFTComplex tmp = { in2[-k*stride], in1[k*stride] }; + CMUL3(fft15in[j], tmp, s->twiddle_exptab[k >> 1]); + } + s->fft15(s->tmp + s->ptwo_fft.revtab[i], fft15in, s->exptab, l_ptwo); + } + + /* Then a 15xN FFT (where N is a power of two) */ + for (i = 0; i < 15; i++) + s->ptwo_fft.fft_calc(&s->ptwo_fft, s->tmp + l_ptwo*i); + + /* Reindex again, apply twiddles and output */ + s->postreindex(z, s->tmp, s->twiddle_exptab, s->pfa_postreindex, len8); +} + +static void postrotate_c(FFTComplex *out, FFTComplex *in, FFTComplex *exp, + int *lut, ptrdiff_t len8) +{ + int i; + + /* Reindex again, apply twiddles and output */ + for (i = 0; i < len8; i++) { + const int i0 = len8 + i, i1 = len8 - i - 1; + const int s0 = lut[i0], s1 = lut[i1]; + + CMUL(out[i1].re, out[i0].im, in[s1].im, in[s1].re, exp[i1].im, exp[i1].re); + CMUL(out[i0].re, out[i1].im, in[s0].im, in[s0].re, exp[i0].im, exp[i0].re); + } +} + +av_cold int ff_mdct15_init(MDCT15Context **ps, int inverse, int N, double scale) +{ + MDCT15Context *s; + double alpha, theta; + int len2 = 15 * (1 << N); + int len = 2 * len2; + int i; + + /* Tested and verified to work on everything in between */ + if ((N < 2) || (N > 13)) + return AVERROR(EINVAL); + + s = av_mallocz(sizeof(*s)); + if (!s) + return AVERROR(ENOMEM); + + s->fft_n = N - 1; + s->len4 = len2 / 2; + s->len2 = len2; + s->inverse = inverse; + s->fft15 = fft15_c; + s->mdct = mdct15; + s->imdct_half = imdct15_half; + s->postreindex = postrotate_c; + + if (ff_fft_init(&s->ptwo_fft, N - 1, s->inverse) < 0) + goto fail; + + if (init_pfa_reindex_tabs(s)) + goto fail; + + s->tmp = av_malloc_array(len, 2 * sizeof(*s->tmp)); + if (!s->tmp) + goto fail; + + s->twiddle_exptab = av_malloc_array(s->len4, sizeof(*s->twiddle_exptab)); + if (!s->twiddle_exptab) + goto fail; + + theta = 0.125f + (scale < 0 ? s->len4 : 0); + scale = sqrt(fabs(scale)); + for (i = 0; i < s->len4; i++) { + alpha = 2 * M_PI * (i + theta) / len; + s->twiddle_exptab[i].re = cosf(alpha) * scale; + s->twiddle_exptab[i].im = sinf(alpha) * scale; + } + + /* 15-point FFT exptab */ + for (i = 0; i < 19; i++) { + if (i < 15) { + double theta = (2.0f * M_PI * i) / 15.0f; + if (!s->inverse) + theta *= -1; + s->exptab[i].re = cosf(theta); + s->exptab[i].im = sinf(theta); + } else { /* Wrap around to simplify fft15 */ + s->exptab[i] = s->exptab[i - 15]; + } + } + + /* 5-point FFT exptab */ + s->exptab[19].re = cosf(2.0f * M_PI / 5.0f); + s->exptab[19].im = sinf(2.0f * M_PI / 5.0f); + s->exptab[20].re = cosf(1.0f * M_PI / 5.0f); + s->exptab[20].im = sinf(1.0f * M_PI / 5.0f); + + /* Invert the phase for an inverse transform, do nothing for a forward transform */ + if (s->inverse) { + s->exptab[19].im *= -1; + s->exptab[20].im *= -1; + } + + if (ARCH_X86) + ff_mdct15_init_x86(s); + + *ps = s; + + return 0; + +fail: + ff_mdct15_uninit(&s); + return AVERROR(ENOMEM); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.h new file mode 100644 index 000000000..42e60f3e1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MDCT15_H +#define AVCODEC_MDCT15_H + +#include + +#include "fft.h" + +typedef struct MDCT15Context { + int fft_n; + int len2; + int len4; + int inverse; + int *pfa_prereindex; + int *pfa_postreindex; + + FFTContext ptwo_fft; + FFTComplex *tmp; + FFTComplex *twiddle_exptab; + + DECLARE_ALIGNED(32, FFTComplex, exptab)[64]; + + /* 15-point FFT */ + void (*fft15)(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); + + /* PFA postrotate and exptab */ + void (*postreindex)(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); + + /* Calculate a full 2N -> N MDCT */ + void (*mdct)(struct MDCT15Context *s, float *dst, const float *src, ptrdiff_t stride); + + /* Calculate the middle half of the iMDCT */ + void (*imdct_half)(struct MDCT15Context *s, float *dst, const float *src, + ptrdiff_t stride); +} MDCT15Context; + +/* Init an (i)MDCT of the length 2 * 15 * (2^N) */ +int ff_mdct15_init(MDCT15Context **ps, int inverse, int N, double scale); +void ff_mdct15_uninit(MDCT15Context **ps); + +void ff_mdct15_init_x86(MDCT15Context *s); + +#endif /* AVCODEC_MDCT15_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15_init.c new file mode 100644 index 000000000..444801d9c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct15_init.c @@ -0,0 +1,99 @@ +/* + * SIMD optimized non-power-of-two MDCT functions + * + * Copyright (C) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/x86/cpu.h" +#include "libavcodec/mdct15.h" + +void ff_mdct15_postreindex_sse3(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); +void ff_mdct15_postreindex_avx2(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); + +void ff_fft15_avx(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); + +static void perm_twiddles(MDCT15Context *s) +{ + int k; + FFTComplex tmp[30]; + + /* 5-point FFT twiddles */ + s->exptab[60].re = s->exptab[60].im = s->exptab[19].re; + s->exptab[61].re = s->exptab[61].im = s->exptab[19].im; + s->exptab[62].re = s->exptab[62].im = s->exptab[20].re; + s->exptab[63].re = s->exptab[63].im = s->exptab[20].im; + + /* 15-point FFT twiddles */ + for (k = 0; k < 5; k++) { + tmp[6*k + 0] = s->exptab[k + 0]; + tmp[6*k + 2] = s->exptab[k + 5]; + tmp[6*k + 4] = s->exptab[k + 10]; + + tmp[6*k + 1] = s->exptab[2 * (k + 0)]; + tmp[6*k + 3] = s->exptab[2 * (k + 5)]; + tmp[6*k + 5] = s->exptab[2 * k + 5 ]; + } + + for (k = 0; k < 6; k++) { + FFTComplex ac_exp[] = { + { tmp[6*1 + k].re, tmp[6*1 + k].re }, + { tmp[6*2 + k].re, tmp[6*2 + k].re }, + { tmp[6*3 + k].re, tmp[6*3 + k].re }, + { tmp[6*4 + k].re, tmp[6*4 + k].re }, + { tmp[6*1 + k].im, -tmp[6*1 + k].im }, + { tmp[6*2 + k].im, -tmp[6*2 + k].im }, + { tmp[6*3 + k].im, -tmp[6*3 + k].im }, + { tmp[6*4 + k].im, -tmp[6*4 + k].im }, + }; + memcpy(s->exptab + 8*k, ac_exp, 8*sizeof(FFTComplex)); + } + + /* Specialcase when k = 0 */ + for (k = 0; k < 3; k++) { + FFTComplex dc_exp[] = { + { tmp[2*k + 0].re, -tmp[2*k + 0].im }, + { tmp[2*k + 0].im, tmp[2*k + 0].re }, + { tmp[2*k + 1].re, -tmp[2*k + 1].im }, + { tmp[2*k + 1].im, tmp[2*k + 1].re }, + }; + memcpy(s->exptab + 8*6 + 4*k, dc_exp, 4*sizeof(FFTComplex)); + } +} + +av_cold void ff_mdct15_init_x86(MDCT15Context *s) +{ + int adjust_twiddles = 0; + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE3(cpu_flags)) + s->postreindex = ff_mdct15_postreindex_sse3; + + if (ARCH_X86_64 && EXTERNAL_AVX(cpu_flags)) { + s->fft15 = ff_fft15_avx; + adjust_twiddles = 1; + } + + if (ARCH_X86_64 && EXTERNAL_AVX2_FAST(cpu_flags)) + s->postreindex = ff_mdct15_postreindex_avx2; + + if (adjust_twiddles) + perm_twiddles(s); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct_fixed.c new file mode 100644 index 000000000..aabf0c88f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mdct_fixed.c @@ -0,0 +1,65 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define FFT_FLOAT 0 +#define FFT_FIXED_32 0 +#include "mdct_template.c" + +/* same as ff_mdct_calcw_c with double-width unscaled output */ +void ff_mdct_calcw_c(FFTContext *s, FFTDouble *out, const FFTSample *input) +{ + int i, j, n, n8, n4, n2, n3; + FFTDouble re, im; + const uint16_t *revtab = s->revtab; + const FFTSample *tcos = s->tcos; + const FFTSample *tsin = s->tsin; + FFTComplex *x = s->tmp_buf; + FFTDComplex *o = (FFTDComplex *)out; + + n = 1 << s->mdct_bits; + n2 = n >> 1; + n4 = n >> 2; + n8 = n >> 3; + n3 = 3 * n4; + + /* pre rotation */ + for(i=0;ifft_calc(s, x); + + /* post rotation */ + for(i=0;i +#include +#include "libavutil/common.h" +#include "libavutil/libm.h" +#include "libavutil/mathematics.h" +#include "fft.h" +#include "fft-internal.h" + +/** + * @file + * MDCT/IMDCT transforms. + */ + +#if FFT_FLOAT +# define RSCALE(x, y) ((x) + (y)) +#else +#if FFT_FIXED_32 +# define RSCALE(x, y) ((int)((x) + (unsigned)(y) + 32) >> 6) +#else /* FFT_FIXED_32 */ +# define RSCALE(x, y) ((int)((x) + (unsigned)(y)) >> 1) +#endif /* FFT_FIXED_32 */ +#endif + +/** + * init MDCT or IMDCT computation. + */ +av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale) +{ + int n, n4, i; + double alpha, theta; + int tstep; + + memset(s, 0, sizeof(*s)); + n = 1 << nbits; + s->mdct_bits = nbits; + s->mdct_size = n; + n4 = n >> 2; + s->mdct_permutation = FF_MDCT_PERM_NONE; + + if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0) + goto fail; + + s->tcos = av_malloc_array(n/2, sizeof(FFTSample)); + if (!s->tcos) + goto fail; + + switch (s->mdct_permutation) { + case FF_MDCT_PERM_NONE: + s->tsin = s->tcos + n4; + tstep = 1; + break; + case FF_MDCT_PERM_INTERLEAVE: + s->tsin = s->tcos + 1; + tstep = 2; + break; + default: + goto fail; + } + + theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0); + scale = sqrt(fabs(scale)); + for(i=0;itcos[i*tstep] = lrint(-cos(alpha) * 2147483648.0); + s->tsin[i*tstep] = lrint(-sin(alpha) * 2147483648.0); +#else + s->tcos[i*tstep] = FIX15(-cos(alpha) * scale); + s->tsin[i*tstep] = FIX15(-sin(alpha) * scale); +#endif + } + return 0; + fail: + ff_mdct_end(s); + return -1; +} + +/** + * Compute the middle half of the inverse MDCT of size N = 2^nbits, + * thus excluding the parts that can be derived by symmetry + * @param output N/2 samples + * @param input N/2 samples + */ +void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input) +{ + int k, n8, n4, n2, n, j; + const uint16_t *revtab = s->revtab; + const FFTSample *tcos = s->tcos; + const FFTSample *tsin = s->tsin; + const FFTSample *in1, *in2; + FFTComplex *z = (FFTComplex *)output; + + n = 1 << s->mdct_bits; + n2 = n >> 1; + n4 = n >> 2; + n8 = n >> 3; + + /* pre rotation */ + in1 = input; + in2 = input + n2 - 1; + for(k = 0; k < n4; k++) { + j=revtab[k]; + CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]); + in1 += 2; + in2 -= 2; + } + s->fft_calc(s, z); + + /* post rotation + reordering */ + for(k = 0; k < n8; k++) { + FFTSample r0, i0, r1, i1; + CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]); + CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]); + z[n8-k-1].re = r0; + z[n8-k-1].im = i0; + z[n8+k ].re = r1; + z[n8+k ].im = i1; + } +} + +/** + * Compute inverse MDCT of size N = 2^nbits + * @param output N samples + * @param input N/2 samples + */ +void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input) +{ + int k; + int n = 1 << s->mdct_bits; + int n2 = n >> 1; + int n4 = n >> 2; + + ff_imdct_half_c(s, output+n4, input); + + for(k = 0; k < n4; k++) { + output[k] = -output[n2-k-1]; + output[n-k-1] = output[n2+k]; + } +} + +/** + * Compute MDCT of size N = 2^nbits + * @param input N samples + * @param out N/2 samples + */ +void ff_mdct_calc_c(FFTContext *s, FFTSample *out, const FFTSample *input) +{ + int i, j, n, n8, n4, n2, n3; + FFTDouble re, im; + const uint16_t *revtab = s->revtab; + const FFTSample *tcos = s->tcos; + const FFTSample *tsin = s->tsin; + FFTComplex *x = (FFTComplex *)out; + + n = 1 << s->mdct_bits; + n2 = n >> 1; + n4 = n >> 2; + n8 = n >> 3; + n3 = 3 * n4; + + /* pre rotation */ + for(i=0;ifft_calc(s, x); + + /* post rotation */ + for(i=0;itcos); + ff_fft_end(s); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/me_cmp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/me_cmp.c new file mode 100644 index 000000000..ae248c52f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/me_cmp.c @@ -0,0 +1,1098 @@ +/* + * DSP utils + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/internal.h" +#include "avcodec.h" +#include "copy_block.h" +#include "simple_idct.h" +#include "me_cmp.h" +#include "mpegvideo.h" +#include "config.h" + +/* (i - 256) * (i - 256) */ +const uint32_t ff_square_tab[512] = { + 65536, 65025, 64516, 64009, 63504, 63001, 62500, 62001, 61504, 61009, 60516, 60025, 59536, 59049, 58564, 58081, + 57600, 57121, 56644, 56169, 55696, 55225, 54756, 54289, 53824, 53361, 52900, 52441, 51984, 51529, 51076, 50625, + 50176, 49729, 49284, 48841, 48400, 47961, 47524, 47089, 46656, 46225, 45796, 45369, 44944, 44521, 44100, 43681, + 43264, 42849, 42436, 42025, 41616, 41209, 40804, 40401, 40000, 39601, 39204, 38809, 38416, 38025, 37636, 37249, + 36864, 36481, 36100, 35721, 35344, 34969, 34596, 34225, 33856, 33489, 33124, 32761, 32400, 32041, 31684, 31329, + 30976, 30625, 30276, 29929, 29584, 29241, 28900, 28561, 28224, 27889, 27556, 27225, 26896, 26569, 26244, 25921, + 25600, 25281, 24964, 24649, 24336, 24025, 23716, 23409, 23104, 22801, 22500, 22201, 21904, 21609, 21316, 21025, + 20736, 20449, 20164, 19881, 19600, 19321, 19044, 18769, 18496, 18225, 17956, 17689, 17424, 17161, 16900, 16641, + 16384, 16129, 15876, 15625, 15376, 15129, 14884, 14641, 14400, 14161, 13924, 13689, 13456, 13225, 12996, 12769, + 12544, 12321, 12100, 11881, 11664, 11449, 11236, 11025, 10816, 10609, 10404, 10201, 10000, 9801, 9604, 9409, + 9216, 9025, 8836, 8649, 8464, 8281, 8100, 7921, 7744, 7569, 7396, 7225, 7056, 6889, 6724, 6561, + 6400, 6241, 6084, 5929, 5776, 5625, 5476, 5329, 5184, 5041, 4900, 4761, 4624, 4489, 4356, 4225, + 4096, 3969, 3844, 3721, 3600, 3481, 3364, 3249, 3136, 3025, 2916, 2809, 2704, 2601, 2500, 2401, + 2304, 2209, 2116, 2025, 1936, 1849, 1764, 1681, 1600, 1521, 1444, 1369, 1296, 1225, 1156, 1089, + 1024, 961, 900, 841, 784, 729, 676, 625, 576, 529, 484, 441, 400, 361, 324, 289, + 256, 225, 196, 169, 144, 121, 100, 81, 64, 49, 36, 25, 16, 9, 4, 1, + 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, + 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, + 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, + 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, + 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241, + 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, + 9216, 9409, 9604, 9801, 10000, 10201, 10404, 10609, 10816, 11025, 11236, 11449, 11664, 11881, 12100, 12321, + 12544, 12769, 12996, 13225, 13456, 13689, 13924, 14161, 14400, 14641, 14884, 15129, 15376, 15625, 15876, 16129, + 16384, 16641, 16900, 17161, 17424, 17689, 17956, 18225, 18496, 18769, 19044, 19321, 19600, 19881, 20164, 20449, + 20736, 21025, 21316, 21609, 21904, 22201, 22500, 22801, 23104, 23409, 23716, 24025, 24336, 24649, 24964, 25281, + 25600, 25921, 26244, 26569, 26896, 27225, 27556, 27889, 28224, 28561, 28900, 29241, 29584, 29929, 30276, 30625, + 30976, 31329, 31684, 32041, 32400, 32761, 33124, 33489, 33856, 34225, 34596, 34969, 35344, 35721, 36100, 36481, + 36864, 37249, 37636, 38025, 38416, 38809, 39204, 39601, 40000, 40401, 40804, 41209, 41616, 42025, 42436, 42849, + 43264, 43681, 44100, 44521, 44944, 45369, 45796, 46225, 46656, 47089, 47524, 47961, 48400, 48841, 49284, 49729, + 50176, 50625, 51076, 51529, 51984, 52441, 52900, 53361, 53824, 54289, 54756, 55225, 55696, 56169, 56644, 57121, + 57600, 58081, 58564, 59049, 59536, 60025, 60516, 61009, 61504, 62001, 62500, 63001, 63504, 64009, 64516, 65025, +}; + +static int sse4_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + const uint32_t *sq = ff_square_tab + 256; + + for (i = 0; i < h; i++) { + s += sq[pix1[0] - pix2[0]]; + s += sq[pix1[1] - pix2[1]]; + s += sq[pix1[2] - pix2[2]]; + s += sq[pix1[3] - pix2[3]]; + pix1 += stride; + pix2 += stride; + } + return s; +} + +static int sse8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + const uint32_t *sq = ff_square_tab + 256; + + for (i = 0; i < h; i++) { + s += sq[pix1[0] - pix2[0]]; + s += sq[pix1[1] - pix2[1]]; + s += sq[pix1[2] - pix2[2]]; + s += sq[pix1[3] - pix2[3]]; + s += sq[pix1[4] - pix2[4]]; + s += sq[pix1[5] - pix2[5]]; + s += sq[pix1[6] - pix2[6]]; + s += sq[pix1[7] - pix2[7]]; + pix1 += stride; + pix2 += stride; + } + return s; +} + +static int sse16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + const uint32_t *sq = ff_square_tab + 256; + + for (i = 0; i < h; i++) { + s += sq[pix1[0] - pix2[0]]; + s += sq[pix1[1] - pix2[1]]; + s += sq[pix1[2] - pix2[2]]; + s += sq[pix1[3] - pix2[3]]; + s += sq[pix1[4] - pix2[4]]; + s += sq[pix1[5] - pix2[5]]; + s += sq[pix1[6] - pix2[6]]; + s += sq[pix1[7] - pix2[7]]; + s += sq[pix1[8] - pix2[8]]; + s += sq[pix1[9] - pix2[9]]; + s += sq[pix1[10] - pix2[10]]; + s += sq[pix1[11] - pix2[11]]; + s += sq[pix1[12] - pix2[12]]; + s += sq[pix1[13] - pix2[13]]; + s += sq[pix1[14] - pix2[14]]; + s += sq[pix1[15] - pix2[15]]; + + pix1 += stride; + pix2 += stride; + } + return s; +} + +static int sum_abs_dctelem_c(int16_t *block) +{ + int sum = 0, i; + + for (i = 0; i < 64; i++) + sum += FFABS(block[i]); + return sum; +} + +#define avg2(a, b) (((a) + (b) + 1) >> 1) +#define avg4(a, b, c, d) (((a) + (b) + (c) + (d) + 2) >> 2) + +static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + + for (i = 0; i < h; i++) { + s += abs(pix1[0] - pix2[0]); + s += abs(pix1[1] - pix2[1]); + s += abs(pix1[2] - pix2[2]); + s += abs(pix1[3] - pix2[3]); + s += abs(pix1[4] - pix2[4]); + s += abs(pix1[5] - pix2[5]); + s += abs(pix1[6] - pix2[6]); + s += abs(pix1[7] - pix2[7]); + s += abs(pix1[8] - pix2[8]); + s += abs(pix1[9] - pix2[9]); + s += abs(pix1[10] - pix2[10]); + s += abs(pix1[11] - pix2[11]); + s += abs(pix1[12] - pix2[12]); + s += abs(pix1[13] - pix2[13]); + s += abs(pix1[14] - pix2[14]); + s += abs(pix1[15] - pix2[15]); + pix1 += stride; + pix2 += stride; + } + return s; +} + +static inline int pix_median_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i, j; + +#define V(x) (pix1[x] - pix2[x]) + + s += abs(V(0)); + s += abs(V(1) - V(0)); + s += abs(V(2) - V(1)); + s += abs(V(3) - V(2)); + s += abs(V(4) - V(3)); + s += abs(V(5) - V(4)); + s += abs(V(6) - V(5)); + s += abs(V(7) - V(6)); + s += abs(V(8) - V(7)); + s += abs(V(9) - V(8)); + s += abs(V(10) - V(9)); + s += abs(V(11) - V(10)); + s += abs(V(12) - V(11)); + s += abs(V(13) - V(12)); + s += abs(V(14) - V(13)); + s += abs(V(15) - V(14)); + + pix1 += stride; + pix2 += stride; + + for (i = 1; i < h; i++) { + s += abs(V(0) - V(-stride)); + for (j = 1; j < 16; j++) + s += abs(V(j) - mid_pred(V(j-stride), V(j-1), V(j-stride) + V(j-1) - V(j-stride-1))); + pix1 += stride; + pix2 += stride; + + } +#undef V + return s; +} + +static int pix_abs16_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + + for (i = 0; i < h; i++) { + s += abs(pix1[0] - avg2(pix2[0], pix2[1])); + s += abs(pix1[1] - avg2(pix2[1], pix2[2])); + s += abs(pix1[2] - avg2(pix2[2], pix2[3])); + s += abs(pix1[3] - avg2(pix2[3], pix2[4])); + s += abs(pix1[4] - avg2(pix2[4], pix2[5])); + s += abs(pix1[5] - avg2(pix2[5], pix2[6])); + s += abs(pix1[6] - avg2(pix2[6], pix2[7])); + s += abs(pix1[7] - avg2(pix2[7], pix2[8])); + s += abs(pix1[8] - avg2(pix2[8], pix2[9])); + s += abs(pix1[9] - avg2(pix2[9], pix2[10])); + s += abs(pix1[10] - avg2(pix2[10], pix2[11])); + s += abs(pix1[11] - avg2(pix2[11], pix2[12])); + s += abs(pix1[12] - avg2(pix2[12], pix2[13])); + s += abs(pix1[13] - avg2(pix2[13], pix2[14])); + s += abs(pix1[14] - avg2(pix2[14], pix2[15])); + s += abs(pix1[15] - avg2(pix2[15], pix2[16])); + pix1 += stride; + pix2 += stride; + } + return s; +} + +static int pix_abs16_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + uint8_t *pix3 = pix2 + stride; + + for (i = 0; i < h; i++) { + s += abs(pix1[0] - avg2(pix2[0], pix3[0])); + s += abs(pix1[1] - avg2(pix2[1], pix3[1])); + s += abs(pix1[2] - avg2(pix2[2], pix3[2])); + s += abs(pix1[3] - avg2(pix2[3], pix3[3])); + s += abs(pix1[4] - avg2(pix2[4], pix3[4])); + s += abs(pix1[5] - avg2(pix2[5], pix3[5])); + s += abs(pix1[6] - avg2(pix2[6], pix3[6])); + s += abs(pix1[7] - avg2(pix2[7], pix3[7])); + s += abs(pix1[8] - avg2(pix2[8], pix3[8])); + s += abs(pix1[9] - avg2(pix2[9], pix3[9])); + s += abs(pix1[10] - avg2(pix2[10], pix3[10])); + s += abs(pix1[11] - avg2(pix2[11], pix3[11])); + s += abs(pix1[12] - avg2(pix2[12], pix3[12])); + s += abs(pix1[13] - avg2(pix2[13], pix3[13])); + s += abs(pix1[14] - avg2(pix2[14], pix3[14])); + s += abs(pix1[15] - avg2(pix2[15], pix3[15])); + pix1 += stride; + pix2 += stride; + pix3 += stride; + } + return s; +} + +static int pix_abs16_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + uint8_t *pix3 = pix2 + stride; + + for (i = 0; i < h; i++) { + s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1])); + s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2])); + s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3])); + s += abs(pix1[3] - avg4(pix2[3], pix2[4], pix3[3], pix3[4])); + s += abs(pix1[4] - avg4(pix2[4], pix2[5], pix3[4], pix3[5])); + s += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6])); + s += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7])); + s += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8])); + s += abs(pix1[8] - avg4(pix2[8], pix2[9], pix3[8], pix3[9])); + s += abs(pix1[9] - avg4(pix2[9], pix2[10], pix3[9], pix3[10])); + s += abs(pix1[10] - avg4(pix2[10], pix2[11], pix3[10], pix3[11])); + s += abs(pix1[11] - avg4(pix2[11], pix2[12], pix3[11], pix3[12])); + s += abs(pix1[12] - avg4(pix2[12], pix2[13], pix3[12], pix3[13])); + s += abs(pix1[13] - avg4(pix2[13], pix2[14], pix3[13], pix3[14])); + s += abs(pix1[14] - avg4(pix2[14], pix2[15], pix3[14], pix3[15])); + s += abs(pix1[15] - avg4(pix2[15], pix2[16], pix3[15], pix3[16])); + pix1 += stride; + pix2 += stride; + pix3 += stride; + } + return s; +} + +static inline int pix_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + + for (i = 0; i < h; i++) { + s += abs(pix1[0] - pix2[0]); + s += abs(pix1[1] - pix2[1]); + s += abs(pix1[2] - pix2[2]); + s += abs(pix1[3] - pix2[3]); + s += abs(pix1[4] - pix2[4]); + s += abs(pix1[5] - pix2[5]); + s += abs(pix1[6] - pix2[6]); + s += abs(pix1[7] - pix2[7]); + pix1 += stride; + pix2 += stride; + } + return s; +} + +static inline int pix_median_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i, j; + +#define V(x) (pix1[x] - pix2[x]) + + s += abs(V(0)); + s += abs(V(1) - V(0)); + s += abs(V(2) - V(1)); + s += abs(V(3) - V(2)); + s += abs(V(4) - V(3)); + s += abs(V(5) - V(4)); + s += abs(V(6) - V(5)); + s += abs(V(7) - V(6)); + + pix1 += stride; + pix2 += stride; + + for (i = 1; i < h; i++) { + s += abs(V(0) - V(-stride)); + for (j = 1; j < 8; j++) + s += abs(V(j) - mid_pred(V(j-stride), V(j-1), V(j-stride) + V(j-1) - V(j-stride-1))); + pix1 += stride; + pix2 += stride; + + } +#undef V + return s; +} + +static int pix_abs8_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + + for (i = 0; i < h; i++) { + s += abs(pix1[0] - avg2(pix2[0], pix2[1])); + s += abs(pix1[1] - avg2(pix2[1], pix2[2])); + s += abs(pix1[2] - avg2(pix2[2], pix2[3])); + s += abs(pix1[3] - avg2(pix2[3], pix2[4])); + s += abs(pix1[4] - avg2(pix2[4], pix2[5])); + s += abs(pix1[5] - avg2(pix2[5], pix2[6])); + s += abs(pix1[6] - avg2(pix2[6], pix2[7])); + s += abs(pix1[7] - avg2(pix2[7], pix2[8])); + pix1 += stride; + pix2 += stride; + } + return s; +} + +static int pix_abs8_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + uint8_t *pix3 = pix2 + stride; + + for (i = 0; i < h; i++) { + s += abs(pix1[0] - avg2(pix2[0], pix3[0])); + s += abs(pix1[1] - avg2(pix2[1], pix3[1])); + s += abs(pix1[2] - avg2(pix2[2], pix3[2])); + s += abs(pix1[3] - avg2(pix2[3], pix3[3])); + s += abs(pix1[4] - avg2(pix2[4], pix3[4])); + s += abs(pix1[5] - avg2(pix2[5], pix3[5])); + s += abs(pix1[6] - avg2(pix2[6], pix3[6])); + s += abs(pix1[7] - avg2(pix2[7], pix3[7])); + pix1 += stride; + pix2 += stride; + pix3 += stride; + } + return s; +} + +static int pix_abs8_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int s = 0, i; + uint8_t *pix3 = pix2 + stride; + + for (i = 0; i < h; i++) { + s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1])); + s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2])); + s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3])); + s += abs(pix1[3] - avg4(pix2[3], pix2[4], pix3[3], pix3[4])); + s += abs(pix1[4] - avg4(pix2[4], pix2[5], pix3[4], pix3[5])); + s += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6])); + s += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7])); + s += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8])); + pix1 += stride; + pix2 += stride; + pix3 += stride; + } + return s; +} + +static int nsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, + ptrdiff_t stride, int h) +{ + int score1 = 0, score2 = 0, x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < 16; x++) + score1 += (s1[x] - s2[x]) * (s1[x] - s2[x]); + if (y + 1 < h) { + for (x = 0; x < 15; x++) + score2 += FFABS(s1[x] - s1[x + stride] - + s1[x + 1] + s1[x + stride + 1]) - + FFABS(s2[x] - s2[x + stride] - + s2[x + 1] + s2[x + stride + 1]); + } + s1 += stride; + s2 += stride; + } + + if (c) + return score1 + FFABS(score2) * c->avctx->nsse_weight; + else + return score1 + FFABS(score2) * 8; +} + +static int nsse8_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, + ptrdiff_t stride, int h) +{ + int score1 = 0, score2 = 0, x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < 8; x++) + score1 += (s1[x] - s2[x]) * (s1[x] - s2[x]); + if (y + 1 < h) { + for (x = 0; x < 7; x++) + score2 += FFABS(s1[x] - s1[x + stride] - + s1[x + 1] + s1[x + stride + 1]) - + FFABS(s2[x] - s2[x + stride] - + s2[x + 1] + s2[x + stride + 1]); + } + s1 += stride; + s2 += stride; + } + + if (c) + return score1 + FFABS(score2) * c->avctx->nsse_weight; + else + return score1 + FFABS(score2) * 8; +} + +static int zero_cmp(MpegEncContext *s, uint8_t *a, uint8_t *b, + ptrdiff_t stride, int h) +{ + return 0; +} + +void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type) +{ + int i; + + memset(cmp, 0, sizeof(void *) * 6); + + for (i = 0; i < 6; i++) { + switch (type & 0xFF) { + case FF_CMP_SAD: + cmp[i] = c->sad[i]; + break; + case FF_CMP_MEDIAN_SAD: + cmp[i] = c->median_sad[i]; + break; + case FF_CMP_SATD: + cmp[i] = c->hadamard8_diff[i]; + break; + case FF_CMP_SSE: + cmp[i] = c->sse[i]; + break; + case FF_CMP_DCT: + cmp[i] = c->dct_sad[i]; + break; + case FF_CMP_DCT264: + cmp[i] = c->dct264_sad[i]; + break; + case FF_CMP_DCTMAX: + cmp[i] = c->dct_max[i]; + break; + case FF_CMP_PSNR: + cmp[i] = c->quant_psnr[i]; + break; + case FF_CMP_BIT: + cmp[i] = c->bit[i]; + break; + case FF_CMP_RD: + cmp[i] = c->rd[i]; + break; + case FF_CMP_VSAD: + cmp[i] = c->vsad[i]; + break; + case FF_CMP_VSSE: + cmp[i] = c->vsse[i]; + break; + case FF_CMP_ZERO: + cmp[i] = zero_cmp; + break; + case FF_CMP_NSSE: + cmp[i] = c->nsse[i]; + break; +#if CONFIG_DWT + case FF_CMP_W53: + cmp[i]= c->w53[i]; + break; + case FF_CMP_W97: + cmp[i]= c->w97[i]; + break; +#endif + default: + av_log(NULL, AV_LOG_ERROR, + "internal error in cmp function selection\n"); + } + } +} + +#define BUTTERFLY2(o1, o2, i1, i2) \ + o1 = (i1) + (i2); \ + o2 = (i1) - (i2); + +#define BUTTERFLY1(x, y) \ + { \ + int a, b; \ + a = x; \ + b = y; \ + x = a + b; \ + y = a - b; \ + } + +#define BUTTERFLYA(x, y) (FFABS((x) + (y)) + FFABS((x) - (y))) + +static int hadamard8_diff8x8_c(MpegEncContext *s, uint8_t *dst, + uint8_t *src, ptrdiff_t stride, int h) +{ + int i, temp[64], sum = 0; + + av_assert2(h == 8); + + for (i = 0; i < 8; i++) { + // FIXME: try pointer walks + BUTTERFLY2(temp[8 * i + 0], temp[8 * i + 1], + src[stride * i + 0] - dst[stride * i + 0], + src[stride * i + 1] - dst[stride * i + 1]); + BUTTERFLY2(temp[8 * i + 2], temp[8 * i + 3], + src[stride * i + 2] - dst[stride * i + 2], + src[stride * i + 3] - dst[stride * i + 3]); + BUTTERFLY2(temp[8 * i + 4], temp[8 * i + 5], + src[stride * i + 4] - dst[stride * i + 4], + src[stride * i + 5] - dst[stride * i + 5]); + BUTTERFLY2(temp[8 * i + 6], temp[8 * i + 7], + src[stride * i + 6] - dst[stride * i + 6], + src[stride * i + 7] - dst[stride * i + 7]); + + BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 2]); + BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 3]); + BUTTERFLY1(temp[8 * i + 4], temp[8 * i + 6]); + BUTTERFLY1(temp[8 * i + 5], temp[8 * i + 7]); + + BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 4]); + BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 5]); + BUTTERFLY1(temp[8 * i + 2], temp[8 * i + 6]); + BUTTERFLY1(temp[8 * i + 3], temp[8 * i + 7]); + } + + for (i = 0; i < 8; i++) { + BUTTERFLY1(temp[8 * 0 + i], temp[8 * 1 + i]); + BUTTERFLY1(temp[8 * 2 + i], temp[8 * 3 + i]); + BUTTERFLY1(temp[8 * 4 + i], temp[8 * 5 + i]); + BUTTERFLY1(temp[8 * 6 + i], temp[8 * 7 + i]); + + BUTTERFLY1(temp[8 * 0 + i], temp[8 * 2 + i]); + BUTTERFLY1(temp[8 * 1 + i], temp[8 * 3 + i]); + BUTTERFLY1(temp[8 * 4 + i], temp[8 * 6 + i]); + BUTTERFLY1(temp[8 * 5 + i], temp[8 * 7 + i]); + + sum += BUTTERFLYA(temp[8 * 0 + i], temp[8 * 4 + i]) + + BUTTERFLYA(temp[8 * 1 + i], temp[8 * 5 + i]) + + BUTTERFLYA(temp[8 * 2 + i], temp[8 * 6 + i]) + + BUTTERFLYA(temp[8 * 3 + i], temp[8 * 7 + i]); + } + return sum; +} + +static int hadamard8_intra8x8_c(MpegEncContext *s, uint8_t *src, + uint8_t *dummy, ptrdiff_t stride, int h) +{ + int i, temp[64], sum = 0; + + av_assert2(h == 8); + + for (i = 0; i < 8; i++) { + // FIXME: try pointer walks + BUTTERFLY2(temp[8 * i + 0], temp[8 * i + 1], + src[stride * i + 0], src[stride * i + 1]); + BUTTERFLY2(temp[8 * i + 2], temp[8 * i + 3], + src[stride * i + 2], src[stride * i + 3]); + BUTTERFLY2(temp[8 * i + 4], temp[8 * i + 5], + src[stride * i + 4], src[stride * i + 5]); + BUTTERFLY2(temp[8 * i + 6], temp[8 * i + 7], + src[stride * i + 6], src[stride * i + 7]); + + BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 2]); + BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 3]); + BUTTERFLY1(temp[8 * i + 4], temp[8 * i + 6]); + BUTTERFLY1(temp[8 * i + 5], temp[8 * i + 7]); + + BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 4]); + BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 5]); + BUTTERFLY1(temp[8 * i + 2], temp[8 * i + 6]); + BUTTERFLY1(temp[8 * i + 3], temp[8 * i + 7]); + } + + for (i = 0; i < 8; i++) { + BUTTERFLY1(temp[8 * 0 + i], temp[8 * 1 + i]); + BUTTERFLY1(temp[8 * 2 + i], temp[8 * 3 + i]); + BUTTERFLY1(temp[8 * 4 + i], temp[8 * 5 + i]); + BUTTERFLY1(temp[8 * 6 + i], temp[8 * 7 + i]); + + BUTTERFLY1(temp[8 * 0 + i], temp[8 * 2 + i]); + BUTTERFLY1(temp[8 * 1 + i], temp[8 * 3 + i]); + BUTTERFLY1(temp[8 * 4 + i], temp[8 * 6 + i]); + BUTTERFLY1(temp[8 * 5 + i], temp[8 * 7 + i]); + + sum += + BUTTERFLYA(temp[8 * 0 + i], temp[8 * 4 + i]) + + BUTTERFLYA(temp[8 * 1 + i], temp[8 * 5 + i]) + + BUTTERFLYA(temp[8 * 2 + i], temp[8 * 6 + i]) + + BUTTERFLYA(temp[8 * 3 + i], temp[8 * 7 + i]); + } + + sum -= FFABS(temp[8 * 0] + temp[8 * 4]); // -mean + + return sum; +} + +static int dct_sad8x8_c(MpegEncContext *s, uint8_t *src1, + uint8_t *src2, ptrdiff_t stride, int h) +{ + LOCAL_ALIGNED_16(int16_t, temp, [64]); + + av_assert2(h == 8); + + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); + s->fdsp.fdct(temp); + return s->mecc.sum_abs_dctelem(temp); +} + +#if CONFIG_GPL +#define DCT8_1D \ + { \ + const int s07 = SRC(0) + SRC(7); \ + const int s16 = SRC(1) + SRC(6); \ + const int s25 = SRC(2) + SRC(5); \ + const int s34 = SRC(3) + SRC(4); \ + const int a0 = s07 + s34; \ + const int a1 = s16 + s25; \ + const int a2 = s07 - s34; \ + const int a3 = s16 - s25; \ + const int d07 = SRC(0) - SRC(7); \ + const int d16 = SRC(1) - SRC(6); \ + const int d25 = SRC(2) - SRC(5); \ + const int d34 = SRC(3) - SRC(4); \ + const int a4 = d16 + d25 + (d07 + (d07 >> 1)); \ + const int a5 = d07 - d34 - (d25 + (d25 >> 1)); \ + const int a6 = d07 + d34 - (d16 + (d16 >> 1)); \ + const int a7 = d16 - d25 + (d34 + (d34 >> 1)); \ + DST(0, a0 + a1); \ + DST(1, a4 + (a7 >> 2)); \ + DST(2, a2 + (a3 >> 1)); \ + DST(3, a5 + (a6 >> 2)); \ + DST(4, a0 - a1); \ + DST(5, a6 - (a5 >> 2)); \ + DST(6, (a2 >> 1) - a3); \ + DST(7, (a4 >> 2) - a7); \ + } + +static int dct264_sad8x8_c(MpegEncContext *s, uint8_t *src1, + uint8_t *src2, ptrdiff_t stride, int h) +{ + int16_t dct[8][8]; + int i, sum = 0; + + s->pdsp.diff_pixels_unaligned(dct[0], src1, src2, stride); + +#define SRC(x) dct[i][x] +#define DST(x, v) dct[i][x] = v + for (i = 0; i < 8; i++) + DCT8_1D +#undef SRC +#undef DST + +#define SRC(x) dct[x][i] +#define DST(x, v) sum += FFABS(v) + for (i = 0; i < 8; i++) + DCT8_1D +#undef SRC +#undef DST + return sum; +} +#endif + +static int dct_max8x8_c(MpegEncContext *s, uint8_t *src1, + uint8_t *src2, ptrdiff_t stride, int h) +{ + LOCAL_ALIGNED_16(int16_t, temp, [64]); + int sum = 0, i; + + av_assert2(h == 8); + + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); + s->fdsp.fdct(temp); + + for (i = 0; i < 64; i++) + sum = FFMAX(sum, FFABS(temp[i])); + + return sum; +} + +static int quant_psnr8x8_c(MpegEncContext *s, uint8_t *src1, + uint8_t *src2, ptrdiff_t stride, int h) +{ + LOCAL_ALIGNED_16(int16_t, temp, [64 * 2]); + int16_t *const bak = temp + 64; + int sum = 0, i; + + av_assert2(h == 8); + s->mb_intra = 0; + + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); + + memcpy(bak, temp, 64 * sizeof(int16_t)); + + s->block_last_index[0 /* FIXME */] = + s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i); + s->dct_unquantize_inter(s, temp, 0, s->qscale); + ff_simple_idct_int16_8bit(temp); // FIXME + + for (i = 0; i < 64; i++) + sum += (temp[i] - bak[i]) * (temp[i] - bak[i]); + + return sum; +} + +static int rd8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, + ptrdiff_t stride, int h) +{ + const uint8_t *scantable = s->intra_scantable.permutated; + LOCAL_ALIGNED_16(int16_t, temp, [64]); + LOCAL_ALIGNED_16(uint8_t, lsrc1, [64]); + LOCAL_ALIGNED_16(uint8_t, lsrc2, [64]); + int i, last, run, bits, level, distortion, start_i; + const int esc_length = s->ac_esc_length; + uint8_t *length, *last_length; + + av_assert2(h == 8); + + copy_block8(lsrc1, src1, 8, stride, 8); + copy_block8(lsrc2, src2, 8, stride, 8); + + s->pdsp.diff_pixels(temp, lsrc1, lsrc2, 8); + + s->block_last_index[0 /* FIXME */] = + last = + s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i); + + bits = 0; + + if (s->mb_intra) { + start_i = 1; + length = s->intra_ac_vlc_length; + last_length = s->intra_ac_vlc_last_length; + bits += s->luma_dc_vlc_length[temp[0] + 256]; // FIXME: chroma + } else { + start_i = 0; + length = s->inter_ac_vlc_length; + last_length = s->inter_ac_vlc_last_length; + } + + if (last >= start_i) { + run = 0; + for (i = start_i; i < last; i++) { + int j = scantable[i]; + level = temp[j]; + + if (level) { + level += 64; + if ((level & (~127)) == 0) + bits += length[UNI_AC_ENC_INDEX(run, level)]; + else + bits += esc_length; + run = 0; + } else + run++; + } + i = scantable[last]; + + level = temp[i] + 64; + + av_assert2(level - 64); + + if ((level & (~127)) == 0) { + bits += last_length[UNI_AC_ENC_INDEX(run, level)]; + } else + bits += esc_length; + } + + if (last >= 0) { + if (s->mb_intra) + s->dct_unquantize_intra(s, temp, 0, s->qscale); + else + s->dct_unquantize_inter(s, temp, 0, s->qscale); + } + + s->idsp.idct_add(lsrc2, 8, temp); + + distortion = s->mecc.sse[1](NULL, lsrc2, lsrc1, 8, 8); + + return distortion + ((bits * s->qscale * s->qscale * 109 + 64) >> 7); +} + +static int bit8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, + ptrdiff_t stride, int h) +{ + const uint8_t *scantable = s->intra_scantable.permutated; + LOCAL_ALIGNED_16(int16_t, temp, [64]); + int i, last, run, bits, level, start_i; + const int esc_length = s->ac_esc_length; + uint8_t *length, *last_length; + + av_assert2(h == 8); + + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); + + s->block_last_index[0 /* FIXME */] = + last = + s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i); + + bits = 0; + + if (s->mb_intra) { + start_i = 1; + length = s->intra_ac_vlc_length; + last_length = s->intra_ac_vlc_last_length; + bits += s->luma_dc_vlc_length[temp[0] + 256]; // FIXME: chroma + } else { + start_i = 0; + length = s->inter_ac_vlc_length; + last_length = s->inter_ac_vlc_last_length; + } + + if (last >= start_i) { + run = 0; + for (i = start_i; i < last; i++) { + int j = scantable[i]; + level = temp[j]; + + if (level) { + level += 64; + if ((level & (~127)) == 0) + bits += length[UNI_AC_ENC_INDEX(run, level)]; + else + bits += esc_length; + run = 0; + } else + run++; + } + i = scantable[last]; + + level = temp[i] + 64; + + av_assert2(level - 64); + + if ((level & (~127)) == 0) + bits += last_length[UNI_AC_ENC_INDEX(run, level)]; + else + bits += esc_length; + } + + return bits; +} + +#define VSAD_INTRA(size) \ +static int vsad_intra ## size ## _c(MpegEncContext *c, \ + uint8_t *s, uint8_t *dummy, \ + ptrdiff_t stride, int h) \ +{ \ + int score = 0, x, y; \ + \ + for (y = 1; y < h; y++) { \ + for (x = 0; x < size; x += 4) { \ + score += FFABS(s[x] - s[x + stride]) + \ + FFABS(s[x + 1] - s[x + stride + 1]) + \ + FFABS(s[x + 2] - s[x + 2 + stride]) + \ + FFABS(s[x + 3] - s[x + 3 + stride]); \ + } \ + s += stride; \ + } \ + \ + return score; \ +} +VSAD_INTRA(8) +VSAD_INTRA(16) + +#define VSAD(size) \ +static int vsad ## size ## _c(MpegEncContext *c, \ + uint8_t *s1, uint8_t *s2, \ + ptrdiff_t stride, int h) \ +{ \ + int score = 0, x, y; \ + \ + for (y = 1; y < h; y++) { \ + for (x = 0; x < size; x++) \ + score += FFABS(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]); \ + s1 += stride; \ + s2 += stride; \ + } \ + \ + return score; \ +} +VSAD(8) +VSAD(16) + +#define SQ(a) ((a) * (a)) +#define VSSE_INTRA(size) \ +static int vsse_intra ## size ## _c(MpegEncContext *c, \ + uint8_t *s, uint8_t *dummy, \ + ptrdiff_t stride, int h) \ +{ \ + int score = 0, x, y; \ + \ + for (y = 1; y < h; y++) { \ + for (x = 0; x < size; x += 4) { \ + score += SQ(s[x] - s[x + stride]) + \ + SQ(s[x + 1] - s[x + stride + 1]) + \ + SQ(s[x + 2] - s[x + stride + 2]) + \ + SQ(s[x + 3] - s[x + stride + 3]); \ + } \ + s += stride; \ + } \ + \ + return score; \ +} +VSSE_INTRA(8) +VSSE_INTRA(16) + +#define VSSE(size) \ +static int vsse ## size ## _c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, \ + ptrdiff_t stride, int h) \ +{ \ + int score = 0, x, y; \ + \ + for (y = 1; y < h; y++) { \ + for (x = 0; x < size; x++) \ + score += SQ(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]); \ + s1 += stride; \ + s2 += stride; \ + } \ + \ + return score; \ +} +VSSE(8) +VSSE(16) + +#define WRAPPER8_16_SQ(name8, name16) \ +static int name16(MpegEncContext *s, uint8_t *dst, uint8_t *src, \ + ptrdiff_t stride, int h) \ +{ \ + int score = 0; \ + \ + score += name8(s, dst, src, stride, 8); \ + score += name8(s, dst + 8, src + 8, stride, 8); \ + if (h == 16) { \ + dst += 8 * stride; \ + src += 8 * stride; \ + score += name8(s, dst, src, stride, 8); \ + score += name8(s, dst + 8, src + 8, stride, 8); \ + } \ + return score; \ +} + +WRAPPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c) +WRAPPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c) +WRAPPER8_16_SQ(dct_sad8x8_c, dct_sad16_c) +#if CONFIG_GPL +WRAPPER8_16_SQ(dct264_sad8x8_c, dct264_sad16_c) +#endif +WRAPPER8_16_SQ(dct_max8x8_c, dct_max16_c) +WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c) +WRAPPER8_16_SQ(rd8x8_c, rd16_c) +WRAPPER8_16_SQ(bit8x8_c, bit16_c) + +int ff_check_alignment(void) +{ + static int did_fail = 0; + LOCAL_ALIGNED_16(int, aligned, [4]); + + if ((intptr_t)aligned & 15) { + if (!did_fail) { +#if HAVE_MMX || HAVE_ALTIVEC + av_log(NULL, AV_LOG_ERROR, + "Compiler did not align stack variables. Libavcodec has been miscompiled\n" + "and may be very slow or crash. This is not a bug in libavcodec,\n" + "but in the compiler. You may try recompiling using gcc >= 4.2.\n" + "Do not report crashes to FFmpeg developers.\n"); +#endif + did_fail=1; + } + return -1; + } + return 0; +} + +av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx) +{ + ff_check_alignment(); + + c->sum_abs_dctelem = sum_abs_dctelem_c; + + /* TODO [0] 16 [1] 8 */ + c->pix_abs[0][0] = pix_abs16_c; + c->pix_abs[0][1] = pix_abs16_x2_c; + c->pix_abs[0][2] = pix_abs16_y2_c; + c->pix_abs[0][3] = pix_abs16_xy2_c; + c->pix_abs[1][0] = pix_abs8_c; + c->pix_abs[1][1] = pix_abs8_x2_c; + c->pix_abs[1][2] = pix_abs8_y2_c; + c->pix_abs[1][3] = pix_abs8_xy2_c; + +#define SET_CMP_FUNC(name) \ + c->name[0] = name ## 16_c; \ + c->name[1] = name ## 8x8_c; + + SET_CMP_FUNC(hadamard8_diff) + c->hadamard8_diff[4] = hadamard8_intra16_c; + c->hadamard8_diff[5] = hadamard8_intra8x8_c; + SET_CMP_FUNC(dct_sad) + SET_CMP_FUNC(dct_max) +#if CONFIG_GPL + SET_CMP_FUNC(dct264_sad) +#endif + c->sad[0] = pix_abs16_c; + c->sad[1] = pix_abs8_c; + c->sse[0] = sse16_c; + c->sse[1] = sse8_c; + c->sse[2] = sse4_c; + SET_CMP_FUNC(quant_psnr) + SET_CMP_FUNC(rd) + SET_CMP_FUNC(bit) + c->vsad[0] = vsad16_c; + c->vsad[1] = vsad8_c; + c->vsad[4] = vsad_intra16_c; + c->vsad[5] = vsad_intra8_c; + c->vsse[0] = vsse16_c; + c->vsse[1] = vsse8_c; + c->vsse[4] = vsse_intra16_c; + c->vsse[5] = vsse_intra8_c; + c->nsse[0] = nsse16_c; + c->nsse[1] = nsse8_c; +#if CONFIG_SNOW_DECODER || CONFIG_SNOW_ENCODER + ff_dsputil_init_dwt(c); +#endif + + if (ARCH_ALPHA) + ff_me_cmp_init_alpha(c, avctx); + if (ARCH_ARM) + ff_me_cmp_init_arm(c, avctx); + if (ARCH_PPC) + ff_me_cmp_init_ppc(c, avctx); + if (ARCH_X86) + ff_me_cmp_init_x86(c, avctx); + if (ARCH_MIPS) + ff_me_cmp_init_mips(c, avctx); + + c->median_sad[0] = pix_median_abs16_c; + c->median_sad[1] = pix_median_abs8_c; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/me_cmp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/me_cmp.h new file mode 100644 index 000000000..0a589e3c3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/me_cmp.h @@ -0,0 +1,95 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_ME_CMP_H +#define AVCODEC_ME_CMP_H + +#include + +#include "avcodec.h" + +extern const uint32_t ff_square_tab[512]; + + +/* minimum alignment rules ;) + * If you notice errors in the align stuff, need more alignment for some ASM code + * for some CPU or need to use a function with less aligned data then send a mail + * to the ffmpeg-devel mailing list, ... + * + * !warning These alignments might not match reality, (missing attribute((align)) + * stuff somewhere possible). + * I (Michael) did not check them, these are just the alignments which I think + * could be reached easily ... + * + * !future video codecs might need functions with less strict alignment + */ + +struct MpegEncContext; +/* Motion estimation: + * h is limited to { width / 2, width, 2 * width }, + * but never larger than 16 and never smaller than 2. + * Although currently h < 4 is not used as functions with + * width < 8 are neither used nor implemented. */ +typedef int (*me_cmp_func)(struct MpegEncContext *c, + uint8_t *blk1 /* align width (8 or 16) */, + uint8_t *blk2 /* align 1 */, ptrdiff_t stride, + int h); + +typedef struct MECmpContext { + int (*sum_abs_dctelem)(int16_t *block /* align 16 */); + + me_cmp_func sad[6]; /* identical to pix_absAxA except additional void * */ + me_cmp_func sse[6]; + me_cmp_func hadamard8_diff[6]; + me_cmp_func dct_sad[6]; + me_cmp_func quant_psnr[6]; + me_cmp_func bit[6]; + me_cmp_func rd[6]; + me_cmp_func vsad[6]; + me_cmp_func vsse[6]; + me_cmp_func nsse[6]; + me_cmp_func w53[6]; + me_cmp_func w97[6]; + me_cmp_func dct_max[6]; + me_cmp_func dct264_sad[6]; + + me_cmp_func me_pre_cmp[6]; + me_cmp_func me_cmp[6]; + me_cmp_func me_sub_cmp[6]; + me_cmp_func mb_cmp[6]; + me_cmp_func ildct_cmp[6]; // only width 16 used + me_cmp_func frame_skip_cmp[6]; // only width 8 used + + me_cmp_func pix_abs[2][4]; + me_cmp_func median_sad[6]; +} MECmpContext; + +int ff_check_alignment(void); + +void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx); +void ff_me_cmp_init_alpha(MECmpContext *c, AVCodecContext *avctx); +void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx); +void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx); +void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx); +void ff_me_cmp_init_mips(MECmpContext *c, AVCodecContext *avctx); + +void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type); + +void ff_dsputil_init_dwt(MECmpContext *c); + +#endif /* AVCODEC_ME_CMP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec.c new file mode 100644 index 000000000..aa14624fd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec.c @@ -0,0 +1,149 @@ +/* + * Android MediaCodec public API functions + * + * Copyright (c) 2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/error.h" + +#include "mediacodec.h" + +#if CONFIG_MEDIACODEC + +#include + +#include "libavcodec/avcodec.h" +#include "libavutil/mem.h" + +#include "ffjni.h" +#include "mediacodecdec_common.h" +#include "version.h" + +AVMediaCodecContext *av_mediacodec_alloc_context(void) +{ + return av_mallocz(sizeof(AVMediaCodecContext)); +} + +int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface) +{ + int ret = 0; + JNIEnv *env = NULL; + + env = ff_jni_get_env(avctx); + if (!env) { + return AVERROR_EXTERNAL; + } + + ctx->surface = (*env)->NewGlobalRef(env, surface); + if (ctx->surface) { + avctx->hwaccel_context = ctx; + } else { + av_log(avctx, AV_LOG_ERROR, "Could not create new global reference\n"); + ret = AVERROR_EXTERNAL; + } + + return ret; +} + +void av_mediacodec_default_free(AVCodecContext *avctx) +{ + JNIEnv *env = NULL; + + AVMediaCodecContext *ctx = avctx->hwaccel_context; + + if (!ctx) { + return; + } + + env = ff_jni_get_env(avctx); + if (!env) { + return; + } + + if (ctx->surface) { + (*env)->DeleteGlobalRef(env, ctx->surface); + ctx->surface = NULL; + } + + av_freep(&avctx->hwaccel_context); +} + +int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) +{ + MediaCodecDecContext *ctx = buffer->ctx; + int released = atomic_fetch_add(&buffer->released, 1); + + if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) { + atomic_fetch_sub(&ctx->hw_buffer_count, 1); + av_log(ctx->avctx, AV_LOG_DEBUG, + "Releasing output buffer %zd (%p) ts=%"PRId64" with render=%d [%d pending]\n", + buffer->index, buffer, buffer->pts, render, atomic_load(&ctx->hw_buffer_count)); + return ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, render); + } + + return 0; +} + +int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time) +{ + MediaCodecDecContext *ctx = buffer->ctx; + int released = atomic_fetch_add(&buffer->released, 1); + + if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) { + atomic_fetch_sub(&ctx->hw_buffer_count, 1); + av_log(ctx->avctx, AV_LOG_DEBUG, + "Rendering output buffer %zd (%p) ts=%"PRId64" with time=%"PRId64" [%d pending]\n", + buffer->index, buffer, buffer->pts, time, atomic_load(&ctx->hw_buffer_count)); + return ff_AMediaCodec_releaseOutputBufferAtTime(ctx->codec, buffer->index, time); + } + + return 0; +} + +#else + +#include + +AVMediaCodecContext *av_mediacodec_alloc_context(void) +{ + return NULL; +} + +int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface) +{ + return AVERROR(ENOSYS); +} + +void av_mediacodec_default_free(AVCodecContext *avctx) +{ +} + +int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) +{ + return AVERROR(ENOSYS); +} + +int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time) +{ + return AVERROR(ENOSYS); +} + +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec.h new file mode 100644 index 000000000..4c8545df0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec.h @@ -0,0 +1,101 @@ +/* + * Android MediaCodec public API + * + * Copyright (c) 2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MEDIACODEC_H +#define AVCODEC_MEDIACODEC_H + +#include "libavcodec/avcodec.h" + +/** + * This structure holds a reference to a android/view/Surface object that will + * be used as output by the decoder. + * + */ +typedef struct AVMediaCodecContext { + + /** + * android/view/Surface object reference. + */ + void *surface; + +} AVMediaCodecContext; + +/** + * Allocate and initialize a MediaCodec context. + * + * When decoding with MediaCodec is finished, the caller must free the + * MediaCodec context with av_mediacodec_default_free. + * + * @return a pointer to a newly allocated AVMediaCodecContext on success, NULL otherwise + */ +AVMediaCodecContext *av_mediacodec_alloc_context(void); + +/** + * Convenience function that sets up the MediaCodec context. + * + * @param avctx codec context + * @param ctx MediaCodec context to initialize + * @param surface reference to an android/view/Surface + * @return 0 on success, < 0 otherwise + */ +int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface); + +/** + * This function must be called to free the MediaCodec context initialized with + * av_mediacodec_default_init(). + * + * @param avctx codec context + */ +void av_mediacodec_default_free(AVCodecContext *avctx); + +/** + * Opaque structure representing a MediaCodec buffer to render. + */ +typedef struct MediaCodecBuffer AVMediaCodecBuffer; + +/** + * Release a MediaCodec buffer and render it to the surface that is associated + * with the decoder. This function should only be called once on a given + * buffer, once released the underlying buffer returns to the codec, thus + * subsequent calls to this function will have no effect. + * + * @param buffer the buffer to render + * @param render 1 to release and render the buffer to the surface or 0 to + * discard the buffer + * @return 0 on success, < 0 otherwise + */ +int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render); + +/** + * Release a MediaCodec buffer and render it at the given time to the surface + * that is associated with the decoder. The timestamp must be within one second + * of the current java/lang/System#nanoTime() (which is implemented using + * CLOCK_MONOTONIC on Android). See the Android MediaCodec documentation + * of android/media/MediaCodec#releaseOutputBuffer(int,long) for more details. + * + * @param buffer the buffer to render + * @param time timestamp in nanoseconds of when to render the buffer + * @return 0 on success, < 0 otherwise + */ +int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time); + +#endif /* AVCODEC_MEDIACODEC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_surface.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_surface.h new file mode 100644 index 000000000..0178b8ae7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_surface.h @@ -0,0 +1,31 @@ +/* + * Android MediaCodec Surface functions + * + * Copyright (c) 2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MEDIACODEC_SURFACE_H +#define AVCODEC_MEDIACODEC_SURFACE_H + +#include "libavcodec/avcodec.h" + +void *ff_mediacodec_surface_ref(void *surface, void *log_ctx); +int ff_mediacodec_surface_unref(void *surface, void *log_ctx); + +#endif /* AVCODEC_MEDIACODEC_SURFACE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_sw_buffer.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_sw_buffer.h new file mode 100644 index 000000000..574fb529d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_sw_buffer.h @@ -0,0 +1,62 @@ +/* + * Android MediaCodec software buffer copy functions + * + * Copyright (c) 2015-2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MEDIACODEC_SW_BUFFER_H +#define AVCODEC_MEDIACODEC_SW_BUFFER_H + +#include + +#include "libavutil/frame.h" + +#include "avcodec.h" +#include "mediacodec_wrapper.h" +#include "mediacodecdec_common.h" + +void ff_mediacodec_sw_buffer_copy_yuv420_planar(AVCodecContext *avctx, + MediaCodecDecContext *s, + uint8_t *data, + size_t size, + FFAMediaCodecBufferInfo *info, + AVFrame *frame); + +void ff_mediacodec_sw_buffer_copy_yuv420_semi_planar(AVCodecContext *avctx, + MediaCodecDecContext *s, + uint8_t *data, + size_t size, + FFAMediaCodecBufferInfo *info, + AVFrame *frame); + +void ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar(AVCodecContext *avctx, + MediaCodecDecContext *s, + uint8_t *data, + size_t size, + FFAMediaCodecBufferInfo *info, + AVFrame *frame); + +void ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar_64x32Tile2m8ka(AVCodecContext *avctx, + MediaCodecDecContext *s, + uint8_t *data, + size_t size, + FFAMediaCodecBufferInfo *info, + AVFrame *frame); + +#endif /* AVCODEC_MEDIACODEC_SW_BUFFER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_wrapper.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_wrapper.h new file mode 100644 index 000000000..b106ff315 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodec_wrapper.h @@ -0,0 +1,131 @@ +/* + * Android MediaCodec Wrapper + * + * Copyright (c) 2015-2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MEDIACODEC_WRAPPER_H +#define AVCODEC_MEDIACODEC_WRAPPER_H + +#include +#include + +#include "avcodec.h" + +/** + * The following API around MediaCodec and MediaFormat is based on the + * NDK one provided by Google since Android 5.0. + * + * Differences from the NDK API: + * + * Buffers returned by ff_AMediaFormat_toString and ff_AMediaFormat_getString + * are newly allocated buffer and must be freed by the user after use. + * + * The MediaCrypto API is not implemented. + * + * ff_AMediaCodec_infoTryAgainLater, ff_AMediaCodec_infoOutputBuffersChanged, + * ff_AMediaCodec_infoOutputFormatChanged, ff_AMediaCodec_cleanOutputBuffers + * ff_AMediaCodec_getName and ff_AMediaCodec_getBufferFlagEndOfStream are not + * part of the original NDK API and are convenience functions to hide JNI + * implementation. + * + * The API around MediaCodecList is not part of the NDK (and is lacking as + * we still need to retrieve the codec name to work around faulty decoders + * and encoders). + * + * For documentation, please refers to NdkMediaCodec.h NdkMediaFormat.h and + * http://developer.android.com/reference/android/media/MediaCodec.html. + * + */ + +int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx); + +char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx); + +struct FFAMediaFormat; +typedef struct FFAMediaFormat FFAMediaFormat; + +FFAMediaFormat *ff_AMediaFormat_new(void); +int ff_AMediaFormat_delete(FFAMediaFormat* format); + +char* ff_AMediaFormat_toString(FFAMediaFormat* format); + +int ff_AMediaFormat_getInt32(FFAMediaFormat* format, const char *name, int32_t *out); +int ff_AMediaFormat_getInt64(FFAMediaFormat* format, const char *name, int64_t *out); +int ff_AMediaFormat_getFloat(FFAMediaFormat* format, const char *name, float *out); +int ff_AMediaFormat_getBuffer(FFAMediaFormat* format, const char *name, void** data, size_t *size); +int ff_AMediaFormat_getString(FFAMediaFormat* format, const char *name, const char **out); + +void ff_AMediaFormat_setInt32(FFAMediaFormat* format, const char* name, int32_t value); +void ff_AMediaFormat_setInt64(FFAMediaFormat* format, const char* name, int64_t value); +void ff_AMediaFormat_setFloat(FFAMediaFormat* format, const char* name, float value); +void ff_AMediaFormat_setString(FFAMediaFormat* format, const char* name, const char* value); +void ff_AMediaFormat_setBuffer(FFAMediaFormat* format, const char* name, void* data, size_t size); + +struct FFAMediaCodec; +typedef struct FFAMediaCodec FFAMediaCodec; +typedef struct FFAMediaCodecCryptoInfo FFAMediaCodecCryptoInfo; + +struct FFAMediaCodecBufferInfo { + int32_t offset; + int32_t size; + int64_t presentationTimeUs; + uint32_t flags; +}; +typedef struct FFAMediaCodecBufferInfo FFAMediaCodecBufferInfo; + +char *ff_AMediaCodec_getName(FFAMediaCodec *codec); + +FFAMediaCodec* ff_AMediaCodec_createCodecByName(const char *name); +FFAMediaCodec* ff_AMediaCodec_createDecoderByType(const char *mime_type); +FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime_type); + +int ff_AMediaCodec_configure(FFAMediaCodec* codec, const FFAMediaFormat* format, void* surface, void *crypto, uint32_t flags); +int ff_AMediaCodec_start(FFAMediaCodec* codec); +int ff_AMediaCodec_stop(FFAMediaCodec* codec); +int ff_AMediaCodec_flush(FFAMediaCodec* codec); +int ff_AMediaCodec_delete(FFAMediaCodec* codec); + +uint8_t* ff_AMediaCodec_getInputBuffer(FFAMediaCodec* codec, size_t idx, size_t *out_size); +uint8_t* ff_AMediaCodec_getOutputBuffer(FFAMediaCodec* codec, size_t idx, size_t *out_size); + +ssize_t ff_AMediaCodec_dequeueInputBuffer(FFAMediaCodec* codec, int64_t timeoutUs); +int ff_AMediaCodec_queueInputBuffer(FFAMediaCodec* codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags); + +ssize_t ff_AMediaCodec_dequeueOutputBuffer(FFAMediaCodec* codec, FFAMediaCodecBufferInfo *info, int64_t timeoutUs); +FFAMediaFormat* ff_AMediaCodec_getOutputFormat(FFAMediaCodec* codec); + +int ff_AMediaCodec_releaseOutputBuffer(FFAMediaCodec* codec, size_t idx, int render); +int ff_AMediaCodec_releaseOutputBufferAtTime(FFAMediaCodec *codec, size_t idx, int64_t timestampNs); + +int ff_AMediaCodec_infoTryAgainLater(FFAMediaCodec *codec, ssize_t idx); +int ff_AMediaCodec_infoOutputBuffersChanged(FFAMediaCodec *codec, ssize_t idx); +int ff_AMediaCodec_infoOutputFormatChanged(FFAMediaCodec *codec, ssize_t indx); + +int ff_AMediaCodec_getBufferFlagCodecConfig (FFAMediaCodec *codec); +int ff_AMediaCodec_getBufferFlagEndOfStream(FFAMediaCodec *codec); +int ff_AMediaCodec_getBufferFlagKeyFrame(FFAMediaCodec *codec); + +int ff_AMediaCodec_getConfigureFlagEncode(FFAMediaCodec *codec); + +int ff_AMediaCodec_cleanOutputBuffers(FFAMediaCodec *codec); + +int ff_Build_SDK_INT(AVCodecContext *avctx); + +#endif /* AVCODEC_MEDIACODEC_WRAPPER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodecdec_common.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodecdec_common.h new file mode 100644 index 000000000..0b21129fe --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mediacodecdec_common.h @@ -0,0 +1,109 @@ +/* + * Android MediaCodec decoder + * + * Copyright (c) 2015-2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MEDIACODECDEC_COMMON_H +#define AVCODEC_MEDIACODECDEC_COMMON_H + +#include +#include +#include +#include + +#include "libavutil/frame.h" +#include "libavutil/pixfmt.h" + +#include "avcodec.h" +#include "mediacodec_wrapper.h" + +typedef struct MediaCodecDecContext { + + AVCodecContext *avctx; + atomic_int refcount; + atomic_int hw_buffer_count; + + char *codec_name; + + FFAMediaCodec *codec; + FFAMediaFormat *format; + + void *surface; + + int started; + int draining; + int flushing; + int eos; + + int width; + int height; + int stride; + int slice_height; + int color_format; + int crop_top; + int crop_bottom; + int crop_left; + int crop_right; + int display_width; + int display_height; + + uint64_t output_buffer_count; + ssize_t current_input_buffer; + + bool delay_flush; + atomic_int serial; + +} MediaCodecDecContext; + +int ff_mediacodec_dec_init(AVCodecContext *avctx, + MediaCodecDecContext *s, + const char *mime, + FFAMediaFormat *format); + +int ff_mediacodec_dec_send(AVCodecContext *avctx, + MediaCodecDecContext *s, + AVPacket *pkt, + bool wait); + +int ff_mediacodec_dec_receive(AVCodecContext *avctx, + MediaCodecDecContext *s, + AVFrame *frame, + bool wait); + +int ff_mediacodec_dec_flush(AVCodecContext *avctx, + MediaCodecDecContext *s); + +int ff_mediacodec_dec_close(AVCodecContext *avctx, + MediaCodecDecContext *s); + +int ff_mediacodec_dec_is_flushing(AVCodecContext *avctx, + MediaCodecDecContext *s); + +typedef struct MediaCodecBuffer { + + MediaCodecDecContext *ctx; + ssize_t index; + int64_t pts; + atomic_int released; + int serial; + +} MediaCodecBuffer; + +#endif /* AVCODEC_MEDIACODECDEC_COMMON_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc.h new file mode 100644 index 000000000..d7ddc35ef --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc.h @@ -0,0 +1,111 @@ +/* + * MJPEG encoder + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-2004 Michael Niedermayer + * + * Support for external huffman table, various fixes (AVID workaround), + * aspecting, new decode_frame mechanism and apple mjpeg-b support + * by Alex Beregszaszi + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * MJPEG encoder. + */ + +#ifndef AVCODEC_MJPEGENC_H +#define AVCODEC_MJPEGENC_H + +#include + +#include "mjpeg.h" +#include "mpegvideo.h" +#include "put_bits.h" + +/** + * Buffer of JPEG frame data. + * + * Optimal Huffman table generation requires the frame data to be loaded into + * a buffer so that the tables can be computed. + * There are at most mb_width*mb_height*12*64 of these per frame. + */ +typedef struct MJpegHuffmanCode { + // 0=DC lum, 1=DC chrom, 2=AC lum, 3=AC chrom + uint8_t table_id; ///< The Huffman table id associated with the data. + uint8_t code; ///< The exponent. + uint16_t mant; ///< The mantissa. +} MJpegHuffmanCode; + +/** + * Holds JPEG frame data and Huffman table data. + */ +typedef struct MJpegContext { + //FIXME use array [3] instead of lumi / chroma, for easier addressing + uint8_t huff_size_dc_luminance[12]; ///< DC luminance Huffman table size. + uint16_t huff_code_dc_luminance[12]; ///< DC luminance Huffman table codes. + uint8_t huff_size_dc_chrominance[12]; ///< DC chrominance Huffman table size. + uint16_t huff_code_dc_chrominance[12]; ///< DC chrominance Huffman table codes. + + uint8_t huff_size_ac_luminance[256]; ///< AC luminance Huffman table size. + uint16_t huff_code_ac_luminance[256]; ///< AC luminance Huffman table codes. + uint8_t huff_size_ac_chrominance[256]; ///< AC chrominance Huffman table size. + uint16_t huff_code_ac_chrominance[256]; ///< AC chrominance Huffman table codes. + + /** Storage for AC luminance VLC (in MpegEncContext) */ + uint8_t uni_ac_vlc_len[64 * 64 * 2]; + /** Storage for AC chrominance VLC (in MpegEncContext) */ + uint8_t uni_chroma_ac_vlc_len[64 * 64 * 2]; + + // Default DC tables have exactly 12 values + uint8_t bits_dc_luminance[17]; ///< DC luminance Huffman bits. + uint8_t val_dc_luminance[12]; ///< DC luminance Huffman values. + uint8_t bits_dc_chrominance[17]; ///< DC chrominance Huffman bits. + uint8_t val_dc_chrominance[12]; ///< DC chrominance Huffman values. + + // 8-bit JPEG has max 256 values + uint8_t bits_ac_luminance[17]; ///< AC luminance Huffman bits. + uint8_t val_ac_luminance[256]; ///< AC luminance Huffman values. + uint8_t bits_ac_chrominance[17]; ///< AC chrominance Huffman bits. + uint8_t val_ac_chrominance[256]; ///< AC chrominance Huffman values. + + size_t huff_ncode; ///< Number of current entries in the buffer. + MJpegHuffmanCode *huff_buffer; ///< Buffer for Huffman code values. +} MJpegContext; + +/** + * Enum for the Huffman encoding strategy. + */ +enum HuffmanTableOption { + HUFFMAN_TABLE_DEFAULT = 0, ///< Use the default Huffman tables. + HUFFMAN_TABLE_OPTIMAL = 1, ///< Compute and use optimal Huffman tables. + NB_HUFFMAN_TABLE_OPTION = 2 +}; + +static inline void put_marker(PutBitContext *p, enum JpegMarker code) +{ + put_bits(p, 8, 0xff); + put_bits(p, 8, code); +} + +int ff_mjpeg_encode_init(MpegEncContext *s); +void ff_mjpeg_encode_close(MpegEncContext *s); +void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]); + +#endif /* AVCODEC_MJPEGENC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_common.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_common.h new file mode 100644 index 000000000..e8698d18c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_common.h @@ -0,0 +1,46 @@ +/* + * lossless JPEG shared bits + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MJPEGENC_COMMON_H +#define AVCODEC_MJPEGENC_COMMON_H + +#include + +#include "avcodec.h" +#include "idctdsp.h" +#include "mpegvideo.h" +#include "put_bits.h" + +void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, + ScanTable *intra_scantable, int pred, + uint16_t luma_intra_matrix[64], + uint16_t chroma_intra_matrix[64]); +void ff_mjpeg_encode_picture_frame(MpegEncContext *s); +void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits); +void ff_mjpeg_escape_FF(PutBitContext *pb, int start); +int ff_mjpeg_encode_stuffing(MpegEncContext *s); +void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[4], int vsample[4]); + +void ff_mjpeg_encode_dc(PutBitContext *pb, int val, + uint8_t *huff_size, uint16_t *huff_code); + +av_cold void ff_init_uni_ac_vlc(const uint8_t huff_size_ac[256], uint8_t *uni_ac_vlc_len); + +#endif /* AVCODEC_MJPEGENC_COMMON_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_huffman.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_huffman.c new file mode 100644 index 000000000..0e63f8066 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_huffman.c @@ -0,0 +1,192 @@ +/* + * MJPEG encoder + * Copyright (c) 2016 William Ma, Ted Ying, Jerry Jiang + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/error.h" +#include "libavutil/qsort.h" +#include "mjpegenc_huffman.h" + +/** + * Comparison function for two PTables by prob + * + * @param a First PTable to compare + * @param b Second PTable to compare + * @return < 0 for less than, 0 for equals, > 0 for greater than + */ +static int compare_by_prob(const void *a, const void *b) +{ + PTable a_val = *(PTable *) a; + PTable b_val = *(PTable *) b; + return a_val.prob - b_val.prob; +} + +/** + * Comparison function for two HuffTables by length + * + * @param a First HuffTable to compare + * @param b Second HuffTable to compare + * @return < 0 for less than, 0 for equals, > 0 for greater than + */ +static int compare_by_length(const void *a, const void *b) +{ + HuffTable a_val = *(HuffTable *) a; + HuffTable b_val = *(HuffTable *) b; + return a_val.length - b_val.length; +} + +/** + * Computes the length of the Huffman encoding for each distinct input value. + * Uses package merge algorithm as follows: + * 1. start with an empty list, lets call it list(0), set i = 0 + * 2. add 1 entry to list(i) for each symbol we have and give each a score equal to the probability of the respective symbol + * 3. merge the 2 symbols of least score and put them in list(i+1), and remove them from list(i). The new score will be the sum of the 2 scores + * 4. if there is more than 1 symbol left in the current list(i), then goto 3 + * 5. i++ + * 6. if i < 16 goto 2 + * 7. select the n-1 elements in the last list with the lowest score (n = the number of symbols) + * 8. the length of the huffman code for symbol s will be equal to the number of times the symbol occurs in the select elements + * Go to guru.multimedia.cx/small-tasks-for-ffmpeg/ for more details + * + * All probabilities should be positive integers. The output is sorted by code, + * not by length. + * + * @param prob_table input array of a PTable for each distinct input value + * @param distincts output array of a HuffTable that will be populated by this function + * @param size size of the prob_table array + * @param max_length max length of an encoding + */ +void ff_mjpegenc_huffman_compute_bits(PTable *prob_table, HuffTable *distincts, int size, int max_length) +{ + PackageMergerList list_a, list_b, *to = &list_a, *from = &list_b, *temp; + + int times, i, j, k; + + int nbits[257] = {0}; + + int min; + + av_assert0(max_length > 0); + + to->nitems = 0; + from->nitems = 0; + to->item_idx[0] = 0; + from->item_idx[0] = 0; + AV_QSORT(prob_table, size, PTable, compare_by_prob); + + for (times = 0; times <= max_length; times++) { + to->nitems = 0; + to->item_idx[0] = 0; + + j = 0; + k = 0; + + if (times < max_length) { + i = 0; + } + while (i < size || j + 1 < from->nitems) { + to->nitems++; + to->item_idx[to->nitems] = to->item_idx[to->nitems - 1]; + if (i < size && + (j + 1 >= from->nitems || + prob_table[i].prob < + from->probability[j] + from->probability[j + 1])) { + to->items[to->item_idx[to->nitems]++] = prob_table[i].value; + to->probability[to->nitems - 1] = prob_table[i].prob; + i++; + } else { + for (k = from->item_idx[j]; k < from->item_idx[j + 2]; k++) { + to->items[to->item_idx[to->nitems]++] = from->items[k]; + } + to->probability[to->nitems - 1] = + from->probability[j] + from->probability[j + 1]; + j += 2; + } + } + temp = to; + to = from; + from = temp; + } + + min = (size - 1 < from->nitems) ? size - 1 : from->nitems; + for (i = 0; i < from->item_idx[min]; i++) { + nbits[from->items[i]]++; + } + // we don't want to return the 256 bit count (it was just in here to prevent + // all 1s encoding) + j = 0; + for (i = 0; i < 256; i++) { + if (nbits[i] > 0) { + distincts[j].code = i; + distincts[j].length = nbits[i]; + j++; + } + } +} + +void ff_mjpeg_encode_huffman_init(MJpegEncHuffmanContext *s) +{ + memset(s->val_count, 0, sizeof(s->val_count)); +} + +/** + * Produces a Huffman encoding with a given input + * + * @param s input to encode + * @param bits output array where the ith character represents how many input values have i length encoding + * @param val output array of input values sorted by their encoded length + * @param max_nval maximum number of distinct input values + */ +void ff_mjpeg_encode_huffman_close(MJpegEncHuffmanContext *s, uint8_t bits[17], + uint8_t val[], int max_nval) +{ + int i, j; + int nval = 0; + PTable val_counts[257]; + HuffTable distincts[256]; + + for (i = 0; i < 256; i++) { + if (s->val_count[i]) nval++; + } + av_assert0 (nval <= max_nval); + + j = 0; + for (i = 0; i < 256; i++) { + if (s->val_count[i]) { + val_counts[j].value = i; + val_counts[j].prob = s->val_count[i]; + j++; + } + } + val_counts[j].value = 256; + val_counts[j].prob = 0; + ff_mjpegenc_huffman_compute_bits(val_counts, distincts, nval + 1, 16); + AV_QSORT(distincts, nval, HuffTable, compare_by_length); + + memset(bits, 0, sizeof(bits[0]) * 17); + for (i = 0; i < nval; i++) { + val[i] = distincts[i].code; + bits[distincts[i].length]++; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_huffman.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_huffman.h new file mode 100644 index 000000000..5fe65504e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mjpegenc_huffman.h @@ -0,0 +1,76 @@ +/* + * MJPEG encoder + * Copyright (c) 2016 William Ma, Ted Ying, Jerry Jiang + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Huffman table generation for MJPEG encoder. + */ + +#ifndef AVCODEC_MJPEGENC_HUFFMAN_H +#define AVCODEC_MJPEGENC_HUFFMAN_H + +#include + +typedef struct MJpegEncHuffmanContext { + int val_count[256]; +} MJpegEncHuffmanContext; + +// Uses the package merge algorithm to compute the Huffman table. +void ff_mjpeg_encode_huffman_init(MJpegEncHuffmanContext *s); +static inline void ff_mjpeg_encode_huffman_increment(MJpegEncHuffmanContext *s, + uint8_t val) +{ + s->val_count[val]++; +} +void ff_mjpeg_encode_huffman_close(MJpegEncHuffmanContext *s, + uint8_t bits[17], uint8_t val[], + int max_nval); + + +/** + * Used to assign a occurrence count or "probability" to an input value + */ +typedef struct PTable { + int value; ///< input value + int prob; ///< number of occurences of this value in input +} PTable; + +/** + * Used to store intermediate lists in the package merge algorithm + */ +typedef struct PackageMergerList { + int nitems; ///< number of items in the list and probability ex. 4 + int item_idx[515]; ///< index range for each item in items 0, 2, 5, 9, 13 + int probability[514]; ///< probability of each item 3, 8, 18, 46 + int items[257 * 16]; ///< chain of all individual values that make up items A, B, A, B, C, A, B, C, D, C, D, D, E +} PackageMergerList; + +/** + * Used to store optimal huffman encoding results + */ +typedef struct HuffTable { + int code; ///< code is the input value + int length; ///< length of the encoding +} HuffTable; + +void ff_mjpegenc_huffman_compute_bits(PTable *prob_table, HuffTable *distincts, + int size, int max_length); +#endif /* AVCODEC_MJPEGENC_HUFFMAN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/motion_est.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/motion_est.c new file mode 100644 index 000000000..759eea479 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/motion_est.c @@ -0,0 +1,1741 @@ +/* + * Motion estimation + * Copyright (c) 2000,2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * new motion estimation (X1/EPZS) by Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Motion estimation. + */ + +#include +#include +#include + +#include "avcodec.h" +#include "internal.h" +#include "mathops.h" +#include "motion_est.h" +#include "mpegutils.h" +#include "mpegvideo.h" + +#define P_LEFT P[1] +#define P_TOP P[2] +#define P_TOPRIGHT P[3] +#define P_MEDIAN P[4] +#define P_MV1 P[9] + +#define ME_MAP_SHIFT 3 +#define ME_MAP_MV_BITS 11 + +static int sad_hpel_motion_search(MpegEncContext * s, + int *mx_ptr, int *my_ptr, int dmin, + int src_index, int ref_index, + int size, int h); + +static inline unsigned update_map_generation(MotionEstContext *c) +{ + c->map_generation+= 1<<(ME_MAP_MV_BITS*2); + if(c->map_generation==0){ + c->map_generation= 1<<(ME_MAP_MV_BITS*2); + memset(c->map, 0, sizeof(uint32_t)*ME_MAP_SIZE); + } + return c->map_generation; +} + +/* shape adaptive search stuff */ +typedef struct Minima{ + int height; + int x, y; + int checked; +}Minima; + +static int minima_cmp(const void *a, const void *b){ + const Minima *da = (const Minima *) a; + const Minima *db = (const Minima *) b; + + return da->height - db->height; +} + +#define FLAG_QPEL 1 //must be 1 +#define FLAG_CHROMA 2 +#define FLAG_DIRECT 4 + +static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){ + const int offset[3]= { + y*c-> stride + x, + ((y*c->uvstride + x)>>1), + ((y*c->uvstride + x)>>1), + }; + int i; + for(i=0; i<3; i++){ + c->src[0][i]= src [i] + offset[i]; + c->ref[0][i]= ref [i] + offset[i]; + } + if(ref_index){ + for(i=0; i<3; i++){ + c->ref[ref_index][i]= ref2[i] + offset[i]; + } + } +} + +static int get_flags(MotionEstContext *c, int direct, int chroma){ + return ((c->avctx->flags&AV_CODEC_FLAG_QPEL) ? FLAG_QPEL : 0) + + (direct ? FLAG_DIRECT : 0) + + (chroma ? FLAG_CHROMA : 0); +} + +static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby, + const int size, const int h, int ref_index, int src_index, + me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel){ + MotionEstContext * const c= &s->me; + const int stride= c->stride; + const int hx= subx + (x<<(1+qpel)); + const int hy= suby + (y<<(1+qpel)); + uint8_t * const * const ref= c->ref[ref_index]; + uint8_t * const * const src= c->src[src_index]; + int d; + //FIXME check chroma 4mv, (no crashes ...) + av_assert2(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1)); + if(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1)){ + const int time_pp= s->pp_time; + const int time_pb= s->pb_time; + const int mask= 2*qpel+1; + if(s->mv_type==MV_TYPE_8X8){ + int i; + for(i=0; i<4; i++){ + int fx = c->direct_basis_mv[i][0] + hx; + int fy = c->direct_basis_mv[i][1] + hy; + int bx = hx ? fx - c->co_located_mv[i][0] : c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(qpel+4)); + int by = hy ? fy - c->co_located_mv[i][1] : c->co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(qpel+4)); + int fxy= (fx&mask) + ((fy&mask)<<(qpel+1)); + int bxy= (bx&mask) + ((by&mask)<<(qpel+1)); + + uint8_t *dst= c->temp + 8*(i&1) + 8*stride*(i>>1); + if(qpel){ + c->qpel_put[1][fxy](dst, ref[0] + (fx>>2) + (fy>>2)*stride, stride); + c->qpel_avg[1][bxy](dst, ref[8] + (bx>>2) + (by>>2)*stride, stride); + }else{ + c->hpel_put[1][fxy](dst, ref[0] + (fx>>1) + (fy>>1)*stride, stride, 8); + c->hpel_avg[1][bxy](dst, ref[8] + (bx>>1) + (by>>1)*stride, stride, 8); + } + } + }else{ + int fx = c->direct_basis_mv[0][0] + hx; + int fy = c->direct_basis_mv[0][1] + hy; + int bx = hx ? fx - c->co_located_mv[0][0] : (c->co_located_mv[0][0]*(time_pb - time_pp)/time_pp); + int by = hy ? fy - c->co_located_mv[0][1] : (c->co_located_mv[0][1]*(time_pb - time_pp)/time_pp); + int fxy= (fx&mask) + ((fy&mask)<<(qpel+1)); + int bxy= (bx&mask) + ((by&mask)<<(qpel+1)); + + if(qpel){ + c->qpel_put[1][fxy](c->temp , ref[0] + (fx>>2) + (fy>>2)*stride , stride); + c->qpel_put[1][fxy](c->temp + 8 , ref[0] + (fx>>2) + (fy>>2)*stride + 8 , stride); + c->qpel_put[1][fxy](c->temp + 8*stride, ref[0] + (fx>>2) + (fy>>2)*stride + 8*stride, stride); + c->qpel_put[1][fxy](c->temp + 8 + 8*stride, ref[0] + (fx>>2) + (fy>>2)*stride + 8 + 8*stride, stride); + c->qpel_avg[1][bxy](c->temp , ref[8] + (bx>>2) + (by>>2)*stride , stride); + c->qpel_avg[1][bxy](c->temp + 8 , ref[8] + (bx>>2) + (by>>2)*stride + 8 , stride); + c->qpel_avg[1][bxy](c->temp + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride + 8*stride, stride); + c->qpel_avg[1][bxy](c->temp + 8 + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride + 8 + 8*stride, stride); + }else{ + av_assert2((fx>>1) + 16*s->mb_x >= -16); + av_assert2((fy>>1) + 16*s->mb_y >= -16); + av_assert2((fx>>1) + 16*s->mb_x <= s->width); + av_assert2((fy>>1) + 16*s->mb_y <= s->height); + av_assert2((bx>>1) + 16*s->mb_x >= -16); + av_assert2((by>>1) + 16*s->mb_y >= -16); + av_assert2((bx>>1) + 16*s->mb_x <= s->width); + av_assert2((by>>1) + 16*s->mb_y <= s->height); + + c->hpel_put[0][fxy](c->temp, ref[0] + (fx>>1) + (fy>>1)*stride, stride, 16); + c->hpel_avg[0][bxy](c->temp, ref[8] + (bx>>1) + (by>>1)*stride, stride, 16); + } + } + d = cmp_func(s, c->temp, src[0], stride, 16); + }else + d= 256*256*256*32; + return d; +} + +static av_always_inline int cmp_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby, + const int size, const int h, int ref_index, int src_index, + me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel, int chroma){ + MotionEstContext * const c= &s->me; + const int stride= c->stride; + const int uvstride= c->uvstride; + const int dxy= subx + (suby<<(1+qpel)); //FIXME log2_subpel? + const int hx= subx + x*(1<<(1+qpel)); + const int hy= suby + y*(1<<(1+qpel)); + uint8_t * const * const ref= c->ref[ref_index]; + uint8_t * const * const src= c->src[src_index]; + int d; + //FIXME check chroma 4mv, (no crashes ...) + int uvdxy; /* no, it might not be used uninitialized */ + if(dxy){ + if(qpel){ + if (h << size == 16) { + c->qpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride); //FIXME prototype (add h) + } else if (size == 0 && h == 8) { + c->qpel_put[1][dxy](c->temp , ref[0] + x + y*stride , stride); + c->qpel_put[1][dxy](c->temp + 8, ref[0] + x + y*stride + 8, stride); + } else + av_assert2(0); + if(chroma){ + int cx= hx/2; + int cy= hy/2; + cx= (cx>>1)|(cx&1); + cy= (cy>>1)|(cy&1); + uvdxy= (cx&1) + 2*(cy&1); + // FIXME x/y wrong, but MPEG-4 qpel is sick anyway, we should drop as much of it as possible in favor for H.264 + } + }else{ + c->hpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride, h); + if(chroma) + uvdxy= dxy | (x&1) | (2*(y&1)); + } + d = cmp_func(s, c->temp, src[0], stride, h); + }else{ + d = cmp_func(s, src[0], ref[0] + x + y*stride, stride, h); + if(chroma) + uvdxy= (x&1) + 2*(y&1); + } + if(chroma){ + uint8_t * const uvtemp= c->temp + 16*stride; + c->hpel_put[size+1][uvdxy](uvtemp , ref[1] + (x>>1) + (y>>1)*uvstride, uvstride, h>>1); + c->hpel_put[size+1][uvdxy](uvtemp+8, ref[2] + (x>>1) + (y>>1)*uvstride, uvstride, h>>1); + d += chroma_cmp_func(s, uvtemp , src[1], uvstride, h>>1); + d += chroma_cmp_func(s, uvtemp+8, src[2], uvstride, h>>1); + } + return d; +} + +static int cmp_simple(MpegEncContext *s, const int x, const int y, + int ref_index, int src_index, + me_cmp_func cmp_func, me_cmp_func chroma_cmp_func){ + return cmp_inline(s,x,y,0,0,0,16,ref_index,src_index, cmp_func, chroma_cmp_func, 0, 0); +} + +static int cmp_fpel_internal(MpegEncContext *s, const int x, const int y, + const int size, const int h, int ref_index, int src_index, + me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ + if(flags&FLAG_DIRECT){ + return cmp_direct_inline(s,x,y,0,0,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags&FLAG_QPEL); + }else{ + return cmp_inline(s,x,y,0,0,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 0, flags&FLAG_CHROMA); + } +} + +static int cmp_internal(MpegEncContext *s, const int x, const int y, const int subx, const int suby, + const int size, const int h, int ref_index, int src_index, + me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ + if(flags&FLAG_DIRECT){ + return cmp_direct_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags&FLAG_QPEL); + }else{ + return cmp_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags&FLAG_QPEL, flags&FLAG_CHROMA); + } +} + +/** @brief compares a block (either a full macroblock or a partition thereof) + against a proposed motion-compensated prediction of that block + */ +static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby, + const int size, const int h, int ref_index, int src_index, + me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ + if(av_builtin_constant_p(flags) && av_builtin_constant_p(h) && av_builtin_constant_p(size) + && av_builtin_constant_p(subx) && av_builtin_constant_p(suby) + && flags==0 && h==16 && size==0 && subx==0 && suby==0){ + return cmp_simple(s,x,y,ref_index,src_index, cmp_func, chroma_cmp_func); + }else if(av_builtin_constant_p(subx) && av_builtin_constant_p(suby) + && subx==0 && suby==0){ + return cmp_fpel_internal(s,x,y,size,h,ref_index,src_index, cmp_func, chroma_cmp_func,flags); + }else{ + return cmp_internal(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags); + } +} + +static int cmp_hpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby, + const int size, const int h, int ref_index, int src_index, + me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ + if(flags&FLAG_DIRECT){ + return cmp_direct_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 0); + }else{ + return cmp_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 0, flags&FLAG_CHROMA); + } +} + +static int cmp_qpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby, + const int size, const int h, int ref_index, int src_index, + me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ + if(flags&FLAG_DIRECT){ + return cmp_direct_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 1); + }else{ + return cmp_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 1, flags&FLAG_CHROMA); + } +} + +#include "motion_est_template.c" + +static int zero_cmp(MpegEncContext *s, uint8_t *a, uint8_t *b, + ptrdiff_t stride, int h) +{ + return 0; +} + +static void zero_hpel(uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h){ +} + +int ff_init_me(MpegEncContext *s){ + MotionEstContext * const c= &s->me; + int cache_size= FFMIN(ME_MAP_SIZE>>ME_MAP_SHIFT, 1<avctx->dia_size)&255, FFABS(s->avctx->pre_dia_size)&255); + + if(FFMIN(s->avctx->dia_size, s->avctx->pre_dia_size) < -FFMIN(ME_MAP_SIZE, MAX_SAB_SIZE)){ + av_log(s->avctx, AV_LOG_ERROR, "ME_MAP size is too small for SAB diamond\n"); + return -1; + } + + c->avctx= s->avctx; + + if(s->codec_id == AV_CODEC_ID_H261) + c->avctx->me_sub_cmp = c->avctx->me_cmp; + + if(cache_size < 2*dia_size && !c->stride){ + av_log(s->avctx, AV_LOG_INFO, "ME_MAP size may be a little small for the selected diamond size\n"); + } + + ff_set_cmp(&s->mecc, s->mecc.me_pre_cmp, c->avctx->me_pre_cmp); + ff_set_cmp(&s->mecc, s->mecc.me_cmp, c->avctx->me_cmp); + ff_set_cmp(&s->mecc, s->mecc.me_sub_cmp, c->avctx->me_sub_cmp); + ff_set_cmp(&s->mecc, s->mecc.mb_cmp, c->avctx->mb_cmp); + + c->flags = get_flags(c, 0, c->avctx->me_cmp &FF_CMP_CHROMA); + c->sub_flags= get_flags(c, 0, c->avctx->me_sub_cmp&FF_CMP_CHROMA); + c->mb_flags = get_flags(c, 0, c->avctx->mb_cmp &FF_CMP_CHROMA); + +/*FIXME s->no_rounding b_type*/ + if (s->avctx->flags & AV_CODEC_FLAG_QPEL) { + c->sub_motion_search= qpel_motion_search; + c->qpel_avg = s->qdsp.avg_qpel_pixels_tab; + if (s->no_rounding) + c->qpel_put = s->qdsp.put_no_rnd_qpel_pixels_tab; + else + c->qpel_put = s->qdsp.put_qpel_pixels_tab; + }else{ + if(c->avctx->me_sub_cmp&FF_CMP_CHROMA) + c->sub_motion_search= hpel_motion_search; + else if( c->avctx->me_sub_cmp == FF_CMP_SAD + && c->avctx-> me_cmp == FF_CMP_SAD + && c->avctx-> mb_cmp == FF_CMP_SAD) + c->sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles + else + c->sub_motion_search= hpel_motion_search; + } + c->hpel_avg = s->hdsp.avg_pixels_tab; + if (s->no_rounding) + c->hpel_put = s->hdsp.put_no_rnd_pixels_tab; + else + c->hpel_put = s->hdsp.put_pixels_tab; + + if(s->linesize){ + c->stride = s->linesize; + c->uvstride= s->uvlinesize; + }else{ + c->stride = 16*s->mb_width + 32; + c->uvstride= 8*s->mb_width + 16; + } + + /* 8x8 fullpel search would need a 4x4 chroma compare, which we do + * not have yet, and even if we had, the motion estimation code + * does not expect it. */ + if (s->codec_id != AV_CODEC_ID_SNOW) { + if ((c->avctx->me_cmp & FF_CMP_CHROMA) /* && !s->mecc.me_cmp[2] */) + s->mecc.me_cmp[2] = zero_cmp; + if ((c->avctx->me_sub_cmp & FF_CMP_CHROMA) && !s->mecc.me_sub_cmp[2]) + s->mecc.me_sub_cmp[2] = zero_cmp; + c->hpel_put[2][0]= c->hpel_put[2][1]= + c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel; + } + + if(s->codec_id == AV_CODEC_ID_H261){ + c->sub_motion_search= no_sub_motion_search; + } + + return 0; +} + +#define CHECK_SAD_HALF_MV(suffix, x, y) \ +{\ + d = s->mecc.pix_abs[size][(x ? 1 : 0) + (y ? 2 : 0)](NULL, pix, ptr + ((x) >> 1), stride, h); \ + d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*penalty_factor;\ + COPY3_IF_LT(dminh, d, dx, x, dy, y)\ +} + +static int sad_hpel_motion_search(MpegEncContext * s, + int *mx_ptr, int *my_ptr, int dmin, + int src_index, int ref_index, + int size, int h) +{ + MotionEstContext * const c= &s->me; + const int penalty_factor= c->sub_penalty_factor; + int mx, my, dminh; + uint8_t *pix, *ptr; + int stride= c->stride; + LOAD_COMMON + + av_assert2(c->sub_flags == 0); + + if(c->skip){ + *mx_ptr = 0; + *my_ptr = 0; + return dmin; + } + + pix = c->src[src_index][0]; + + mx = *mx_ptr; + my = *my_ptr; + ptr = c->ref[ref_index][0] + (my * stride) + mx; + + dminh = dmin; + + if (mx > xmin && mx < xmax && + my > ymin && my < ymax) { + int dx=0, dy=0; + int d, pen_x, pen_y; + const int index= my*(1<mb_x + s->mb_y*s->mb_stride; + + s->p_mv_table[xy][0] = mx; + s->p_mv_table[xy][1] = my; + + /* has already been set to the 4 MV if 4MV is done */ + if(mv4){ + int mot_xy= s->block_index[0]; + + s->current_picture.motion_val[0][mot_xy ][0] = mx; + s->current_picture.motion_val[0][mot_xy ][1] = my; + s->current_picture.motion_val[0][mot_xy + 1][0] = mx; + s->current_picture.motion_val[0][mot_xy + 1][1] = my; + + mot_xy += s->b8_stride; + s->current_picture.motion_val[0][mot_xy ][0] = mx; + s->current_picture.motion_val[0][mot_xy ][1] = my; + s->current_picture.motion_val[0][mot_xy + 1][0] = mx; + s->current_picture.motion_val[0][mot_xy + 1][1] = my; + } +} + +/** + * get fullpel ME search limits. + */ +static inline void get_limits(MpegEncContext *s, int x, int y) +{ + MotionEstContext * const c= &s->me; + int range= c->avctx->me_range >> (1 + !!(c->flags&FLAG_QPEL)); + int max_range = MAX_MV >> (1 + !!(c->flags&FLAG_QPEL)); +/* + if(c->avctx->me_range) c->range= c->avctx->me_range >> 1; + else c->range= 16; +*/ + if (s->unrestricted_mv) { + c->xmin = - x - 16; + c->ymin = - y - 16; + c->xmax = - x + s->width; + c->ymax = - y + s->height; + } else if (s->out_format == FMT_H261){ + // Search range of H.261 is different from other codec standards + c->xmin = (x > 15) ? - 15 : 0; + c->ymin = (y > 15) ? - 15 : 0; + c->xmax = (x < s->mb_width * 16 - 16) ? 15 : 0; + c->ymax = (y < s->mb_height * 16 - 16) ? 15 : 0; + } else { + c->xmin = - x; + c->ymin = - y; + c->xmax = - x + s->mb_width *16 - 16; + c->ymax = - y + s->mb_height*16 - 16; + } + if(!range || range > max_range) + range = max_range; + if(range){ + c->xmin = FFMAX(c->xmin,-range); + c->xmax = FFMIN(c->xmax, range); + c->ymin = FFMAX(c->ymin,-range); + c->ymax = FFMIN(c->ymax, range); + } +} + +static inline void init_mv4_ref(MotionEstContext *c){ + const int stride= c->stride; + + c->ref[1][0] = c->ref[0][0] + 8; + c->ref[2][0] = c->ref[0][0] + 8*stride; + c->ref[3][0] = c->ref[2][0] + 8; + c->src[1][0] = c->src[0][0] + 8; + c->src[2][0] = c->src[0][0] + 8*stride; + c->src[3][0] = c->src[2][0] + 8; +} + +static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) +{ + MotionEstContext * const c= &s->me; + const int size= 1; + const int h=8; + int block; + int P[10][2]; + int dmin_sum=0, mx4_sum=0, my4_sum=0, i; + int same=1; + const int stride= c->stride; + uint8_t *mv_penalty= c->current_mv_penalty; + int safety_clipping= s->unrestricted_mv && (s->width&15) && (s->height&15); + + init_mv4_ref(c); + + for(block=0; block<4; block++){ + int mx4, my4; + int pred_x4, pred_y4; + int dmin4; + static const int off[4]= {2, 1, 1, -1}; + const int mot_stride = s->b8_stride; + const int mot_xy = s->block_index[block]; + + if(safety_clipping){ + c->xmax = - 16*s->mb_x + s->width - 8*(block &1); + c->ymax = - 16*s->mb_y + s->height - 8*(block>>1); + } + + P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; + P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; + + if(P_LEFT[0] > (c->xmax<xmax<first_slice_line && block<2) { + c->pred_x= pred_x4= P_LEFT[0]; + c->pred_y= pred_y4= P_LEFT[1]; + } else { + P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0]; + P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; + P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0]; + P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1]; + if(P_TOP[1] > (c->ymax<ymax<xmin<xmin< (c->xmax<xmax< (c->ymax<ymax<pred_x= pred_x4 = P_MEDIAN[0]; + c->pred_y= pred_y4 = P_MEDIAN[1]; + } + P_MV1[0]= mx; + P_MV1[1]= my; + if(safety_clipping) + for(i=1; i<10; i++){ + if (s->first_slice_line && block<2 && i>1 && i<9) + continue; + if (i>4 && i<9) + continue; + if(P[i][0] > (c->xmax<xmax< (c->ymax<ymax<p_mv_table, (1<<16)>>shift, 1); + + dmin4= c->sub_motion_search(s, &mx4, &my4, dmin4, block, block, size, h); + + if (s->mecc.me_sub_cmp[0] != s->mecc.mb_cmp[0]) { + int dxy; + const int offset= ((block&1) + (block>>1)*stride)*8; + uint8_t *dest_y = c->scratchpad + offset; + if(s->quarter_sample){ + uint8_t *ref= c->ref[block][0] + (mx4>>2) + (my4>>2)*stride; + dxy = ((my4 & 3) << 2) | (mx4 & 3); + + if(s->no_rounding) + s->qdsp.put_no_rnd_qpel_pixels_tab[1][dxy](dest_y, ref, stride); + else + s->qdsp.put_qpel_pixels_tab[1][dxy](dest_y, ref, stride); + }else{ + uint8_t *ref= c->ref[block][0] + (mx4>>1) + (my4>>1)*stride; + dxy = ((my4 & 1) << 1) | (mx4 & 1); + + if(s->no_rounding) + s->hdsp.put_no_rnd_pixels_tab[1][dxy](dest_y , ref , stride, h); + else + s->hdsp.put_pixels_tab [1][dxy](dest_y , ref , stride, h); + } + dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*c->mb_penalty_factor; + }else + dmin_sum+= dmin4; + + if(s->quarter_sample){ + mx4_sum+= mx4/2; + my4_sum+= my4/2; + }else{ + mx4_sum+= mx4; + my4_sum+= my4; + } + + s->current_picture.motion_val[0][s->block_index[block]][0] = mx4; + s->current_picture.motion_val[0][s->block_index[block]][1] = my4; + + if(mx4 != mx || my4 != my) same=0; + } + + if(same) + return INT_MAX; + + if (s->mecc.me_sub_cmp[0] != s->mecc.mb_cmp[0]) { + dmin_sum += s->mecc.mb_cmp[0](s, + s->new_picture.f->data[0] + + s->mb_x * 16 + s->mb_y * 16 * stride, + c->scratchpad, stride, 16); + } + + if(c->avctx->mb_cmp&FF_CMP_CHROMA){ + int dxy; + int mx, my; + int offset; + + mx= ff_h263_round_chroma(mx4_sum); + my= ff_h263_round_chroma(my4_sum); + dxy = ((my & 1) << 1) | (mx & 1); + + offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize; + + if(s->no_rounding){ + s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad , s->last_picture.f->data[1] + offset, s->uvlinesize, 8); + s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad + 8, s->last_picture.f->data[2] + offset, s->uvlinesize, 8); + }else{ + s->hdsp.put_pixels_tab [1][dxy](c->scratchpad , s->last_picture.f->data[1] + offset, s->uvlinesize, 8); + s->hdsp.put_pixels_tab [1][dxy](c->scratchpad + 8, s->last_picture.f->data[2] + offset, s->uvlinesize, 8); + } + + dmin_sum += s->mecc.mb_cmp[1](s, s->new_picture.f->data[1] + s->mb_x * 8 + s->mb_y * 8 * s->uvlinesize, c->scratchpad, s->uvlinesize, 8); + dmin_sum += s->mecc.mb_cmp[1](s, s->new_picture.f->data[2] + s->mb_x * 8 + s->mb_y * 8 * s->uvlinesize, c->scratchpad + 8, s->uvlinesize, 8); + } + + c->pred_x= mx; + c->pred_y= my; + + switch(c->avctx->mb_cmp&0xFF){ + /*case FF_CMP_SSE: + return dmin_sum+ 32*s->qscale*s->qscale;*/ + case FF_CMP_RD: + return dmin_sum; + default: + return dmin_sum+ 11*c->mb_penalty_factor; + } +} + +static inline void init_interlaced_ref(MpegEncContext *s, int ref_index){ + MotionEstContext * const c= &s->me; + + c->ref[1+ref_index][0] = c->ref[0+ref_index][0] + s->linesize; + c->src[1][0] = c->src[0][0] + s->linesize; + if(c->flags & FLAG_CHROMA){ + c->ref[1+ref_index][1] = c->ref[0+ref_index][1] + s->uvlinesize; + c->ref[1+ref_index][2] = c->ref[0+ref_index][2] + s->uvlinesize; + c->src[1][1] = c->src[0][1] + s->uvlinesize; + c->src[1][2] = c->src[0][2] + s->uvlinesize; + } +} + +static int interlaced_search(MpegEncContext *s, int ref_index, + int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my, int user_field_select) +{ + MotionEstContext * const c= &s->me; + const int size=0; + const int h=8; + int block; + int P[10][2]; + uint8_t * const mv_penalty= c->current_mv_penalty; + int same=1; + const int stride= 2*s->linesize; + int dmin_sum= 0; + const int mot_stride= s->mb_stride; + const int xy= s->mb_x + s->mb_y*mot_stride; + + c->ymin>>=1; + c->ymax>>=1; + c->stride<<=1; + c->uvstride<<=1; + init_interlaced_ref(s, ref_index); + + for(block=0; block<2; block++){ + int field_select; + int best_dmin= INT_MAX; + int best_field= -1; + + for(field_select=0; field_select<2; field_select++){ + int dmin, mx_i, my_i; + int16_t (*mv_table)[2]= mv_tables[block][field_select]; + + if(user_field_select){ + av_assert1(field_select==0 || field_select==1); + av_assert1(field_select_tables[block][xy]==0 || field_select_tables[block][xy]==1); + if(field_select_tables[block][xy] != field_select) + continue; + } + + P_LEFT[0] = mv_table[xy - 1][0]; + P_LEFT[1] = mv_table[xy - 1][1]; + if(P_LEFT[0] > (c->xmax<<1)) P_LEFT[0] = (c->xmax<<1); + + c->pred_x= P_LEFT[0]; + c->pred_y= P_LEFT[1]; + + if(!s->first_slice_line){ + P_TOP[0] = mv_table[xy - mot_stride][0]; + P_TOP[1] = mv_table[xy - mot_stride][1]; + P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0]; + P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1]; + if(P_TOP[1] > (c->ymax<<1)) P_TOP[1] = (c->ymax<<1); + if(P_TOPRIGHT[0] < (c->xmin<<1)) P_TOPRIGHT[0]= (c->xmin<<1); + if(P_TOPRIGHT[0] > (c->xmax<<1)) P_TOPRIGHT[0]= (c->xmax<<1); + if(P_TOPRIGHT[1] > (c->ymax<<1)) P_TOPRIGHT[1]= (c->ymax<<1); + + P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); + P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); + } + P_MV1[0]= mx; //FIXME not correct if block != field_select + P_MV1[1]= my / 2; + + dmin = epzs_motion_search2(s, &mx_i, &my_i, P, block, field_select+ref_index, mv_table, (1<<16)>>1, 0); + + dmin= c->sub_motion_search(s, &mx_i, &my_i, dmin, block, field_select+ref_index, size, h); + + mv_table[xy][0]= mx_i; + mv_table[xy][1]= my_i; + + if (s->mecc.me_sub_cmp[0] != s->mecc.mb_cmp[0]) { + int dxy; + + //FIXME chroma ME + uint8_t *ref= c->ref[field_select+ref_index][0] + (mx_i>>1) + (my_i>>1)*stride; + dxy = ((my_i & 1) << 1) | (mx_i & 1); + + if(s->no_rounding){ + s->hdsp.put_no_rnd_pixels_tab[size][dxy](c->scratchpad, ref , stride, h); + }else{ + s->hdsp.put_pixels_tab [size][dxy](c->scratchpad, ref , stride, h); + } + dmin = s->mecc.mb_cmp[size](s, c->src[block][0], c->scratchpad, stride, h); + dmin+= (mv_penalty[mx_i-c->pred_x] + mv_penalty[my_i-c->pred_y] + 1)*c->mb_penalty_factor; + }else + dmin+= c->mb_penalty_factor; //field_select bits + + dmin += field_select != block; //slightly prefer same field + + if(dmin < best_dmin){ + best_dmin= dmin; + best_field= field_select; + } + } + { + int16_t (*mv_table)[2]= mv_tables[block][best_field]; + + if(mv_table[xy][0] != mx) same=0; //FIXME check if these checks work and are any good at all + if(mv_table[xy][1]&1) same=0; + if(mv_table[xy][1]*2 != my) same=0; + if(best_field != block) same=0; + } + + field_select_tables[block][xy]= best_field; + dmin_sum += best_dmin; + } + + c->ymin<<=1; + c->ymax<<=1; + c->stride>>=1; + c->uvstride>>=1; + + if(same) + return INT_MAX; + + switch(c->avctx->mb_cmp&0xFF){ + /*case FF_CMP_SSE: + return dmin_sum+ 32*s->qscale*s->qscale;*/ + case FF_CMP_RD: + return dmin_sum; + default: + return dmin_sum+ 11*c->mb_penalty_factor; + } +} + +static inline int get_penalty_factor(int lambda, int lambda2, int type){ + switch(type&0xFF){ + default: + case FF_CMP_SAD: + return lambda>>FF_LAMBDA_SHIFT; + case FF_CMP_DCT: + return (3*lambda)>>(FF_LAMBDA_SHIFT+1); + case FF_CMP_W53: + return (4*lambda)>>(FF_LAMBDA_SHIFT); + case FF_CMP_W97: + return (2*lambda)>>(FF_LAMBDA_SHIFT); + case FF_CMP_SATD: + case FF_CMP_DCT264: + return (2*lambda)>>FF_LAMBDA_SHIFT; + case FF_CMP_RD: + case FF_CMP_PSNR: + case FF_CMP_SSE: + case FF_CMP_NSSE: + return lambda2>>FF_LAMBDA_SHIFT; + case FF_CMP_BIT: + case FF_CMP_MEDIAN_SAD: + return 1; + } +} + +void ff_estimate_p_frame_motion(MpegEncContext * s, + int mb_x, int mb_y) +{ + MotionEstContext * const c= &s->me; + uint8_t *pix, *ppix; + int sum, mx = 0, my = 0, dmin = 0; + int varc; ///< the variance of the block (sum of squared (p[y][x]-average)) + int vard; ///< sum of squared differences with the estimated motion vector + int P[10][2]; + const int shift= 1+s->quarter_sample; + int mb_type=0; + Picture * const pic= &s->current_picture; + + init_ref(c, s->new_picture.f->data, s->last_picture.f->data, NULL, 16*mb_x, 16*mb_y, 0); + + av_assert0(s->quarter_sample==0 || s->quarter_sample==1); + av_assert0(s->linesize == c->stride); + av_assert0(s->uvlinesize == c->uvstride); + + c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); + c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp); + c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp); + c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV; + + get_limits(s, 16*mb_x, 16*mb_y); + c->skip=0; + + /* intra / predictive decision */ + pix = c->src[0][0]; + sum = s->mpvencdsp.pix_sum(pix, s->linesize); + varc = s->mpvencdsp.pix_norm1(pix, s->linesize) - + (((unsigned) sum * sum) >> 8) + 500; + + pic->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8; + pic->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8; + c->mb_var_sum_temp += (varc+128)>>8; + + if (s->motion_est != FF_ME_ZERO) { + const int mot_stride = s->b8_stride; + const int mot_xy = s->block_index[0]; + + P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; + P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; + + if (P_LEFT[0] > (c->xmax << shift)) + P_LEFT[0] = c->xmax << shift; + + if (!s->first_slice_line) { + P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0]; + P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; + P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][0]; + P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1]; + if (P_TOP[1] > (c->ymax << shift)) + P_TOP[1] = c->ymax << shift; + if (P_TOPRIGHT[0] < (c->xmin * (1 << shift))) + P_TOPRIGHT[0] = c->xmin * (1 << shift); + if (P_TOPRIGHT[1] > (c->ymax * (1 << shift))) + P_TOPRIGHT[1] = c->ymax * (1 << shift); + + P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); + P_MEDIAN[1] = mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); + + if (s->out_format == FMT_H263) { + c->pred_x = P_MEDIAN[0]; + c->pred_y = P_MEDIAN[1]; + } else { /* MPEG-1 at least */ + c->pred_x = P_LEFT[0]; + c->pred_y = P_LEFT[1]; + } + } else { + c->pred_x = P_LEFT[0]; + c->pred_y = P_LEFT[1]; + } + dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16); + } + + /* At this point (mx,my) are full-pell and the relative displacement */ + ppix = c->ref[0][0] + (my * s->linesize) + mx; + + vard = s->mecc.sse[0](NULL, pix, ppix, s->linesize, 16); + + pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8; + c->mc_mb_var_sum_temp += (vard+128)>>8; + + if (c->avctx->mb_decision > FF_MB_DECISION_SIMPLE) { + int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100); + int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20; + c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score); + + if (vard*2 + 200*256 > varc) + mb_type|= CANDIDATE_MB_TYPE_INTRA; + if (varc*2 + 200*256 > vard || s->qscale > 24){ +// if (varc*2 + 200*256 + 50*(s->lambda2>>FF_LAMBDA_SHIFT) > vard){ + mb_type|= CANDIDATE_MB_TYPE_INTER; + c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); + if (s->mpv_flags & FF_MPV_FLAG_MV0) + if(mx || my) + mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference + }else{ + mx <<=shift; + my <<=shift; + } + if ((s->avctx->flags & AV_CODEC_FLAG_4MV) + && !c->skip && varc>50<<8 && vard>10<<8){ + if(h263_mv4_search(s, mx, my, shift) < INT_MAX) + mb_type|=CANDIDATE_MB_TYPE_INTER4V; + + set_p_mv_tables(s, mx, my, 0); + }else + set_p_mv_tables(s, mx, my, 1); + if ((s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) + && !c->skip){ //FIXME varc/d checks + if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX) + mb_type |= CANDIDATE_MB_TYPE_INTER_I; + } + }else{ + int intra_score, i; + mb_type= CANDIDATE_MB_TYPE_INTER; + + dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); + if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip) + dmin= get_mb_score(s, mx, my, 0, 0, 0, 16, 1); + + if ((s->avctx->flags & AV_CODEC_FLAG_4MV) + && !c->skip && varc>50<<8 && vard>10<<8){ + int dmin4= h263_mv4_search(s, mx, my, shift); + if(dmin4 < dmin){ + mb_type= CANDIDATE_MB_TYPE_INTER4V; + dmin=dmin4; + } + } + if ((s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) + && !c->skip){ //FIXME varc/d checks + int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0); + if(dmin_i < dmin){ + mb_type = CANDIDATE_MB_TYPE_INTER_I; + dmin= dmin_i; + } + } + + set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V); + + /* get intra luma score */ + if((c->avctx->mb_cmp&0xFF)==FF_CMP_SSE){ + intra_score= varc - 500; + }else{ + unsigned mean = (sum+128)>>8; + mean*= 0x01010101; + + for(i=0; i<16; i++){ + *(uint32_t*)(&c->scratchpad[i*s->linesize+ 0]) = mean; + *(uint32_t*)(&c->scratchpad[i*s->linesize+ 4]) = mean; + *(uint32_t*)(&c->scratchpad[i*s->linesize+ 8]) = mean; + *(uint32_t*)(&c->scratchpad[i*s->linesize+12]) = mean; + } + + intra_score= s->mecc.mb_cmp[0](s, c->scratchpad, pix, s->linesize, 16); + } + intra_score += c->mb_penalty_factor*16; + + if(intra_score < dmin){ + mb_type= CANDIDATE_MB_TYPE_INTRA; + s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup + }else + s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = 0; + + { + int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100); + int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20; + c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score); + } + } + + s->mb_type[mb_y*s->mb_stride + mb_x]= mb_type; +} + +int ff_pre_estimate_p_frame_motion(MpegEncContext * s, + int mb_x, int mb_y) +{ + MotionEstContext * const c= &s->me; + int mx, my, dmin; + int P[10][2]; + const int shift= 1+s->quarter_sample; + const int xy= mb_x + mb_y*s->mb_stride; + init_ref(c, s->new_picture.f->data, s->last_picture.f->data, NULL, 16*mb_x, 16*mb_y, 0); + + av_assert0(s->quarter_sample==0 || s->quarter_sample==1); + + c->pre_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_pre_cmp); + c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV; + + get_limits(s, 16*mb_x, 16*mb_y); + c->skip=0; + + P_LEFT[0] = s->p_mv_table[xy + 1][0]; + P_LEFT[1] = s->p_mv_table[xy + 1][1]; + + if(P_LEFT[0] < (c->xmin<xmin<first_slice_line) { + c->pred_x= P_LEFT[0]; + c->pred_y= P_LEFT[1]; + P_TOP[0]= P_TOPRIGHT[0]= P_MEDIAN[0]= + P_TOP[1]= P_TOPRIGHT[1]= P_MEDIAN[1]= 0; //FIXME + } else { + P_TOP[0] = s->p_mv_table[xy + s->mb_stride ][0]; + P_TOP[1] = s->p_mv_table[xy + s->mb_stride ][1]; + P_TOPRIGHT[0] = s->p_mv_table[xy + s->mb_stride - 1][0]; + P_TOPRIGHT[1] = s->p_mv_table[xy + s->mb_stride - 1][1]; + if(P_TOP[1] < (c->ymin<ymin< (c->xmax<xmax<ymin<ymin<pred_x = P_MEDIAN[0]; + c->pred_y = P_MEDIAN[1]; + } + + dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16); + + s->p_mv_table[xy][0] = mx<p_mv_table[xy][1] = my<me; + int mx = 0, my = 0, dmin = 0; + int P[10][2]; + const int shift= 1+s->quarter_sample; + const int mot_stride = s->mb_stride; + const int mot_xy = mb_y*mot_stride + mb_x; + uint8_t * const mv_penalty= c->mv_penalty[f_code] + MAX_DMV; + int mv_scale; + + c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); + c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp); + c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp); + c->current_mv_penalty= mv_penalty; + + get_limits(s, 16*mb_x, 16*mb_y); + + if (s->motion_est != FF_ME_ZERO) { + P_LEFT[0] = mv_table[mot_xy - 1][0]; + P_LEFT[1] = mv_table[mot_xy - 1][1]; + + if (P_LEFT[0] > (c->xmax << shift)) P_LEFT[0] = (c->xmax << shift); + + /* special case for first line */ + if (!s->first_slice_line) { + P_TOP[0] = mv_table[mot_xy - mot_stride ][0]; + P_TOP[1] = mv_table[mot_xy - mot_stride ][1]; + P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0]; + P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1][1]; + if (P_TOP[1] > (c->ymax << shift)) P_TOP[1] = (c->ymax << shift); + if (P_TOPRIGHT[0] < (c->xmin << shift)) P_TOPRIGHT[0] = (c->xmin << shift); + if (P_TOPRIGHT[1] > (c->ymax << shift)) P_TOPRIGHT[1] = (c->ymax << shift); + + P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); + P_MEDIAN[1] = mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); + } + c->pred_x = P_LEFT[0]; + c->pred_y = P_LEFT[1]; + + if(mv_table == s->b_forw_mv_table){ + mv_scale= (s->pb_time<<16) / (s->pp_time<pb_time - s->pp_time)<<16) / (s->pp_time<p_mv_table, mv_scale, 0, 16); + } + + dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, ref_index, 0, 16); + + if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip) + dmin= get_mb_score(s, mx, my, 0, ref_index, 0, 16, 1); + +// s->mb_type[mb_y*s->mb_width + mb_x]= mb_type; + mv_table[mot_xy][0]= mx; + mv_table[mot_xy][1]= my; + + return dmin; +} + +static inline int check_bidir_mv(MpegEncContext * s, + int motion_fx, int motion_fy, + int motion_bx, int motion_by, + int pred_fx, int pred_fy, + int pred_bx, int pred_by, + int size, int h) +{ + //FIXME optimize? + //FIXME better f_code prediction (max mv & distance) + //FIXME pointers + MotionEstContext * const c= &s->me; + uint8_t * const mv_penalty_f= c->mv_penalty[s->f_code] + MAX_DMV; // f_code of the prev frame + uint8_t * const mv_penalty_b= c->mv_penalty[s->b_code] + MAX_DMV; // f_code of the prev frame + int stride= c->stride; + uint8_t *dest_y = c->scratchpad; + uint8_t *ptr; + int dxy; + int src_x, src_y; + int fbmin; + uint8_t **src_data= c->src[0]; + uint8_t **ref_data= c->ref[0]; + uint8_t **ref2_data= c->ref[2]; + + if(s->quarter_sample){ + dxy = ((motion_fy & 3) << 2) | (motion_fx & 3); + src_x = motion_fx >> 2; + src_y = motion_fy >> 2; + + ptr = ref_data[0] + (src_y * stride) + src_x; + s->qdsp.put_qpel_pixels_tab[0][dxy](dest_y, ptr, stride); + + dxy = ((motion_by & 3) << 2) | (motion_bx & 3); + src_x = motion_bx >> 2; + src_y = motion_by >> 2; + + ptr = ref2_data[0] + (src_y * stride) + src_x; + s->qdsp.avg_qpel_pixels_tab[size][dxy](dest_y, ptr, stride); + }else{ + dxy = ((motion_fy & 1) << 1) | (motion_fx & 1); + src_x = motion_fx >> 1; + src_y = motion_fy >> 1; + + ptr = ref_data[0] + (src_y * stride) + src_x; + s->hdsp.put_pixels_tab[size][dxy](dest_y , ptr , stride, h); + + dxy = ((motion_by & 1) << 1) | (motion_bx & 1); + src_x = motion_bx >> 1; + src_y = motion_by >> 1; + + ptr = ref2_data[0] + (src_y * stride) + src_x; + s->hdsp.avg_pixels_tab[size][dxy](dest_y , ptr , stride, h); + } + + fbmin = (mv_penalty_f[motion_fx-pred_fx] + mv_penalty_f[motion_fy-pred_fy])*c->mb_penalty_factor + +(mv_penalty_b[motion_bx-pred_bx] + mv_penalty_b[motion_by-pred_by])*c->mb_penalty_factor + + s->mecc.mb_cmp[size](s, src_data[0], dest_y, stride, h); // FIXME new_pic + + if(c->avctx->mb_cmp&FF_CMP_CHROMA){ + } + //FIXME CHROMA !!! + + return fbmin; +} + +/* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/ +static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y) +{ + MotionEstContext * const c= &s->me; + const int mot_stride = s->mb_stride; + const int xy = mb_y *mot_stride + mb_x; + int fbmin; + int pred_fx= s->b_bidir_forw_mv_table[xy-1][0]; + int pred_fy= s->b_bidir_forw_mv_table[xy-1][1]; + int pred_bx= s->b_bidir_back_mv_table[xy-1][0]; + int pred_by= s->b_bidir_back_mv_table[xy-1][1]; + int motion_fx= s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0]; + int motion_fy= s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1]; + int motion_bx= s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0]; + int motion_by= s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1]; + const int flags= c->sub_flags; + const int qpel= flags&FLAG_QPEL; + const int shift= 1+qpel; + const int xmin= c->xmin<ymin<xmax<ymax<avctx->bidir_refine){ + int end; + static const uint8_t limittab[5]={0,8,32,64,80}; + const int limit= limittab[s->avctx->bidir_refine]; + static const int8_t vect[][4]={ +{ 0, 0, 0, 1}, { 0, 0, 0,-1}, { 0, 0, 1, 0}, { 0, 0,-1, 0}, { 0, 1, 0, 0}, { 0,-1, 0, 0}, { 1, 0, 0, 0}, {-1, 0, 0, 0}, + +{ 0, 0, 1, 1}, { 0, 0,-1,-1}, { 0, 1, 1, 0}, { 0,-1,-1, 0}, { 1, 1, 0, 0}, {-1,-1, 0, 0}, { 1, 0, 0, 1}, {-1, 0, 0,-1}, +{ 0, 1, 0, 1}, { 0,-1, 0,-1}, { 1, 0, 1, 0}, {-1, 0,-1, 0}, +{ 0, 0,-1, 1}, { 0, 0, 1,-1}, { 0,-1, 1, 0}, { 0, 1,-1, 0}, {-1, 1, 0, 0}, { 1,-1, 0, 0}, { 1, 0, 0,-1}, {-1, 0, 0, 1}, +{ 0,-1, 0, 1}, { 0, 1, 0,-1}, {-1, 0, 1, 0}, { 1, 0,-1, 0}, + +{ 0, 1, 1, 1}, { 0,-1,-1,-1}, { 1, 1, 1, 0}, {-1,-1,-1, 0}, { 1, 1, 0, 1}, {-1,-1, 0,-1}, { 1, 0, 1, 1}, {-1, 0,-1,-1}, +{ 0,-1, 1, 1}, { 0, 1,-1,-1}, {-1, 1, 1, 0}, { 1,-1,-1, 0}, { 1, 1, 0,-1}, {-1,-1, 0, 1}, { 1, 0,-1, 1}, {-1, 0, 1,-1}, +{ 0, 1,-1, 1}, { 0,-1, 1,-1}, { 1,-1, 1, 0}, {-1, 1,-1, 0}, {-1, 1, 0, 1}, { 1,-1, 0,-1}, { 1, 0, 1,-1}, {-1, 0,-1, 1}, +{ 0, 1, 1,-1}, { 0,-1,-1, 1}, { 1, 1,-1, 0}, {-1,-1, 1, 0}, { 1,-1, 0, 1}, {-1, 1, 0,-1}, {-1, 0, 1, 1}, { 1, 0,-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,-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}, + }; + static const uint8_t hash[]={ +HASH8( 0, 0, 0, 1), HASH8( 0, 0, 0,-1), HASH8( 0, 0, 1, 0), HASH8( 0, 0,-1, 0), HASH8( 0, 1, 0, 0), HASH8( 0,-1, 0, 0), HASH8( 1, 0, 0, 0), HASH8(-1, 0, 0, 0), + +HASH8( 0, 0, 1, 1), HASH8( 0, 0,-1,-1), HASH8( 0, 1, 1, 0), HASH8( 0,-1,-1, 0), HASH8( 1, 1, 0, 0), HASH8(-1,-1, 0, 0), HASH8( 1, 0, 0, 1), HASH8(-1, 0, 0,-1), +HASH8( 0, 1, 0, 1), HASH8( 0,-1, 0,-1), HASH8( 1, 0, 1, 0), HASH8(-1, 0,-1, 0), +HASH8( 0, 0,-1, 1), HASH8( 0, 0, 1,-1), HASH8( 0,-1, 1, 0), HASH8( 0, 1,-1, 0), HASH8(-1, 1, 0, 0), HASH8( 1,-1, 0, 0), HASH8( 1, 0, 0,-1), HASH8(-1, 0, 0, 1), +HASH8( 0,-1, 0, 1), HASH8( 0, 1, 0,-1), HASH8(-1, 0, 1, 0), HASH8( 1, 0,-1, 0), + +HASH8( 0, 1, 1, 1), HASH8( 0,-1,-1,-1), HASH8( 1, 1, 1, 0), HASH8(-1,-1,-1, 0), HASH8( 1, 1, 0, 1), HASH8(-1,-1, 0,-1), HASH8( 1, 0, 1, 1), HASH8(-1, 0,-1,-1), +HASH8( 0,-1, 1, 1), HASH8( 0, 1,-1,-1), HASH8(-1, 1, 1, 0), HASH8( 1,-1,-1, 0), HASH8( 1, 1, 0,-1), HASH8(-1,-1, 0, 1), HASH8( 1, 0,-1, 1), HASH8(-1, 0, 1,-1), +HASH8( 0, 1,-1, 1), HASH8( 0,-1, 1,-1), HASH8( 1,-1, 1, 0), HASH8(-1, 1,-1, 0), HASH8(-1, 1, 0, 1), HASH8( 1,-1, 0,-1), HASH8( 1, 0, 1,-1), HASH8(-1, 0,-1, 1), +HASH8( 0, 1, 1,-1), HASH8( 0,-1,-1, 1), HASH8( 1, 1,-1, 0), HASH8(-1,-1, 1, 0), HASH8( 1,-1, 0, 1), HASH8(-1, 1, 0,-1), HASH8(-1, 0, 1, 1), HASH8( 1, 0,-1,-1), + +HASH8( 1, 1, 1, 1), HASH8(-1,-1,-1,-1), +HASH8( 1, 1, 1,-1), HASH8(-1,-1,-1, 1), HASH8( 1, 1,-1, 1), HASH8(-1,-1, 1,-1), HASH8( 1,-1, 1, 1), HASH8(-1, 1,-1,-1), HASH8(-1, 1, 1, 1), HASH8( 1,-1,-1,-1), +HASH8( 1, 1,-1,-1), HASH8(-1,-1, 1, 1), HASH8( 1,-1,-1, 1), HASH8(-1, 1, 1,-1), HASH8( 1,-1, 1,-1), HASH8(-1, 1,-1, 1), +}; + +#define CHECK_BIDIR(fx,fy,bx,by)\ + if( !map[(hashidx+HASH(fx,fy,bx,by))&255]\ + &&(fx<=0 || motion_fx+fx<=xmax) && (fy<=0 || motion_fy+fy<=ymax) && (bx<=0 || motion_bx+bx<=xmax) && (by<=0 || motion_by+by<=ymax)\ + &&(fx>=0 || motion_fx+fx>=xmin) && (fy>=0 || motion_fy+fy>=ymin) && (bx>=0 || motion_bx+bx>=xmin) && (by>=0 || motion_by+by>=ymin)){\ + int score;\ + map[(hashidx+HASH(fx,fy,bx,by))&255] = 1;\ + score= check_bidir_mv(s, motion_fx+fx, motion_fy+fy, motion_bx+bx, motion_by+by, pred_fx, pred_fy, pred_bx, pred_by, 0, 16);\ + if(score < fbmin){\ + hashidx += HASH(fx,fy,bx,by);\ + fbmin= score;\ + motion_fx+=fx;\ + motion_fy+=fy;\ + motion_bx+=bx;\ + motion_by+=by;\ + end=0;\ + }\ + } +#define CHECK_BIDIR2(a,b,c,d)\ +CHECK_BIDIR(a,b,c,d)\ +CHECK_BIDIR(-(a),-(b),-(c),-(d)) + + do{ + int i; + int borderdist=0; + end=1; + + CHECK_BIDIR2(0,0,0,1) + CHECK_BIDIR2(0,0,1,0) + CHECK_BIDIR2(0,1,0,0) + CHECK_BIDIR2(1,0,0,0) + + for(i=8; ib_bidir_forw_mv_table[xy][0]= motion_fx; + s->b_bidir_forw_mv_table[xy][1]= motion_fy; + s->b_bidir_back_mv_table[xy][0]= motion_bx; + s->b_bidir_back_mv_table[xy][1]= motion_by; + + return fbmin; +} + +static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) +{ + MotionEstContext * const c= &s->me; + int P[10][2]; + const int mot_stride = s->mb_stride; + const int mot_xy = mb_y*mot_stride + mb_x; + const int shift= 1+s->quarter_sample; + int dmin, i; + const int time_pp= s->pp_time; + const int time_pb= s->pb_time; + int mx, my, xmin, xmax, ymin, ymax; + int16_t (*mv_table)[2]= s->b_direct_mv_table; + + c->current_mv_penalty= c->mv_penalty[1] + MAX_DMV; + ymin= xmin=(-32)>>shift; + ymax= xmax= 31>>shift; + + if (IS_8X8(s->next_picture.mb_type[mot_xy])) { + s->mv_type= MV_TYPE_8X8; + }else{ + s->mv_type= MV_TYPE_16X16; + } + + for(i=0; i<4; i++){ + int index= s->block_index[i]; + int min, max; + + c->co_located_mv[i][0] = s->next_picture.motion_val[0][index][0]; + c->co_located_mv[i][1] = s->next_picture.motion_val[0][index][1]; + c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3)); + c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3)); +// c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3); +// c->direct_basis_mv[1][i][1]= c->co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(shift+3); + + max= FFMAX(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift; + min= FFMIN(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift; + max+= 16*mb_x + 1; // +-1 is for the simpler rounding + min+= 16*mb_x - 1; + xmax= FFMIN(xmax, s->width - max); + xmin= FFMAX(xmin, - 16 - min); + + max= FFMAX(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift; + min= FFMIN(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift; + max+= 16*mb_y + 1; // +-1 is for the simpler rounding + min+= 16*mb_y - 1; + ymax= FFMIN(ymax, s->height - max); + ymin= FFMAX(ymin, - 16 - min); + + if(s->mv_type == MV_TYPE_16X16) break; + } + + av_assert2(xmax <= 15 && ymax <= 15 && xmin >= -16 && ymin >= -16); + + if(xmax < 0 || xmin >0 || ymax < 0 || ymin > 0){ + s->b_direct_mv_table[mot_xy][0]= 0; + s->b_direct_mv_table[mot_xy][1]= 0; + + return 256*256*256*64; + } + + c->xmin= xmin; + c->ymin= ymin; + c->xmax= xmax; + c->ymax= ymax; + c->flags |= FLAG_DIRECT; + c->sub_flags |= FLAG_DIRECT; + c->pred_x=0; + c->pred_y=0; + + P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin<first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped + P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin<sub_flags&FLAG_QPEL) + dmin = qpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); + else + dmin = hpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); + + if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip) + dmin= get_mb_score(s, mx, my, 0, 0, 0, 16, 1); + + get_limits(s, 16*mb_x, 16*mb_y); //restore c->?min/max, maybe not needed + + mv_table[mot_xy][0]= mx; + mv_table[mot_xy][1]= my; + c->flags &= ~FLAG_DIRECT; + c->sub_flags &= ~FLAG_DIRECT; + + return dmin; +} + +void ff_estimate_b_frame_motion(MpegEncContext * s, + int mb_x, int mb_y) +{ + MotionEstContext * const c= &s->me; + const int penalty_factor= c->mb_penalty_factor; + int fmin, bmin, dmin, fbmin, bimin, fimin; + int type=0; + const int xy = mb_y*s->mb_stride + mb_x; + init_ref(c, s->new_picture.f->data, s->last_picture.f->data, + s->next_picture.f->data, 16 * mb_x, 16 * mb_y, 2); + + get_limits(s, 16*mb_x, 16*mb_y); + + c->skip=0; + + if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]) { + int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0 + + score= ((unsigned)(score*score + 128*256))>>16; + c->mc_mb_var_sum_temp += score; + s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE + s->mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_DIRECT0; + + return; + } + + if (s->codec_id == AV_CODEC_ID_MPEG4) + dmin= direct_search(s, mb_x, mb_y); + else + dmin= INT_MAX; +// FIXME penalty stuff for non-MPEG-4 + c->skip=0; + fmin = estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) + + 3 * penalty_factor; + + c->skip=0; + bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) + + 2 * penalty_factor; + ff_dlog(s, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); + + c->skip=0; + fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor; + ff_dlog(s, "%d %d %d %d\n", dmin, fmin, bmin, fbmin); + + if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) { +//FIXME mb type penalty + c->skip=0; + c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV; + fimin= interlaced_search(s, 0, + s->b_field_mv_table[0], s->b_field_select_table[0], + s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0); + c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_DMV; + bimin= interlaced_search(s, 2, + s->b_field_mv_table[1], s->b_field_select_table[1], + s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0); + }else + fimin= bimin= INT_MAX; + + { + int score= fmin; + type = CANDIDATE_MB_TYPE_FORWARD; + + if (dmin <= score){ + score = dmin; + type = CANDIDATE_MB_TYPE_DIRECT; + } + if(bmin>16; + c->mc_mb_var_sum_temp += score; + s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE + } + + if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ + type= CANDIDATE_MB_TYPE_FORWARD | CANDIDATE_MB_TYPE_BACKWARD | CANDIDATE_MB_TYPE_BIDIR | CANDIDATE_MB_TYPE_DIRECT; + if(fimin < INT_MAX) + type |= CANDIDATE_MB_TYPE_FORWARD_I; + if(bimin < INT_MAX) + type |= CANDIDATE_MB_TYPE_BACKWARD_I; + if(fimin < INT_MAX && bimin < INT_MAX){ + type |= CANDIDATE_MB_TYPE_BIDIR_I; + } + //FIXME something smarter + if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //do not try direct mode if it is invalid for this MB + if (s->codec_id == AV_CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT && + s->mpv_flags & FF_MPV_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy]) + type |= CANDIDATE_MB_TYPE_DIRECT0; + } + + s->mb_type[mb_y*s->mb_stride + mb_x]= type; +} + +/* find best f_code for ME which do unlimited searches */ +int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) +{ + if (s->motion_est != FF_ME_ZERO) { + int score[8]; + int i, y, range= s->avctx->me_range ? s->avctx->me_range : (INT_MAX/2); + uint8_t * fcode_tab= s->fcode_tab; + int best_fcode=-1; + int best_score=-10000000; + + if(s->msmpeg4_version) + range= FFMIN(range, 16); + else if(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) + range= FFMIN(range, 256); + + for(i=0; i<8; i++) score[i]= s->mb_num*(8-i); + + for(y=0; ymb_height; y++){ + int x; + int xy= y*s->mb_stride; + for(x=0; xmb_width; x++){ + if(s->mb_type[xy] & type){ + int mx= mv_table[xy][0]; + int my= mv_table[xy][1]; + int fcode= FFMAX(fcode_tab[mx + MAX_MV], + fcode_tab[my + MAX_MV]); + int j; + + if(mx >= range || mx < -range || + my >= range || my < -range) + continue; + + for(j=0; jpict_type==AV_PICTURE_TYPE_B || s->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy]) + score[j]-= 170; + } + } + xy++; + } + } + + for(i=1; i<8; i++){ + if(score[i] > best_score){ + best_score= score[i]; + best_fcode= i; + } + } + + return best_fcode; + }else{ + return 1; + } +} + +void ff_fix_long_p_mvs(MpegEncContext * s) +{ + MotionEstContext * const c= &s->me; + const int f_code= s->f_code; + int y, range; + av_assert0(s->pict_type==AV_PICTURE_TYPE_P); + + range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code); + + av_assert0(range <= 16 || !s->msmpeg4_version); + av_assert0(range <=256 || !(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)); + + if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range; + + if (s->avctx->flags & AV_CODEC_FLAG_4MV) { + const int wrap= s->b8_stride; + + /* clip / convert to intra 8x8 type MVs */ + for(y=0; ymb_height; y++){ + int xy= y*2*wrap; + int i= y*s->mb_stride; + int x; + + for(x=0; xmb_width; x++){ + if(s->mb_type[i]&CANDIDATE_MB_TYPE_INTER4V){ + int block; + for(block=0; block<4; block++){ + int off= (block& 1) + (block>>1)*wrap; + int mx = s->current_picture.motion_val[0][ xy + off ][0]; + int my = s->current_picture.motion_val[0][ xy + off ][1]; + + if( mx >=range || mx <-range + || my >=range || my <-range){ + s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V; + s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA; + s->current_picture.mb_type[i] = CANDIDATE_MB_TYPE_INTRA; + } + } + } + xy+=2; + i++; + } + } + } +} + +/** + * @param truncate 1 for truncation, 0 for using intra + */ +void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select, + int16_t (*mv_table)[2], int f_code, int type, int truncate) +{ + MotionEstContext * const c= &s->me; + int y, h_range, v_range; + + // RAL: 8 in MPEG-1, 16 in MPEG-4 + int range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code); + + if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range; + + h_range= range; + v_range= field_select_table ? range>>1 : range; + + /* clip / convert to intra 16x16 type MVs */ + for(y=0; ymb_height; y++){ + int x; + int xy= y*s->mb_stride; + for(x=0; xmb_width; x++){ + if (s->mb_type[xy] & type){ // RAL: "type" test added... + if (!field_select_table || field_select_table[xy] == field_select) { + if( mv_table[xy][0] >=h_range || mv_table[xy][0] <-h_range + || mv_table[xy][1] >=v_range || mv_table[xy][1] <-v_range){ + + if(truncate){ + if (mv_table[xy][0] > h_range-1) mv_table[xy][0]= h_range-1; + else if(mv_table[xy][0] < -h_range ) mv_table[xy][0]= -h_range; + if (mv_table[xy][1] > v_range-1) mv_table[xy][1]= v_range-1; + else if(mv_table[xy][1] < -v_range ) mv_table[xy][1]= -v_range; + }else{ + s->mb_type[xy] &= ~type; + s->mb_type[xy] |= CANDIDATE_MB_TYPE_INTRA; + mv_table[xy][0]= + mv_table[xy][1]= 0; + } + } + } + } + xy++; + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/motion_est.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/motion_est.h new file mode 100644 index 000000000..3b3a8d734 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/motion_est.h @@ -0,0 +1,135 @@ +/* + * Motion estimation + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MOTION_EST_H +#define AVCODEC_MOTION_EST_H + +#include + +#include "avcodec.h" +#include "hpeldsp.h" +#include "qpeldsp.h" + +struct MpegEncContext; + +#if ARCH_IA64 // Limit static arrays to avoid gcc failing "short data segment overflowed" +#define MAX_MV 1024 +#else +#define MAX_MV 4096 +#endif +#define MAX_DMV (2*MAX_MV) +#define ME_MAP_SIZE 64 + +#define FF_ME_ZERO 0 +#define FF_ME_EPZS 1 +#define FF_ME_XONE 2 + +/** + * Motion estimation context. + */ +typedef struct MotionEstContext { + AVCodecContext *avctx; + int skip; ///< set if ME is skipped for the current MB + int co_located_mv[4][2]; ///< mv from last P-frame for direct mode ME + int direct_basis_mv[4][2]; + uint8_t *scratchpad; /**< data area for the ME algo, so that + * the ME does not need to malloc/free. */ + uint8_t *best_mb; + uint8_t *temp_mb[2]; + uint8_t *temp; + int best_bits; + uint32_t *map; ///< map to avoid duplicate evaluations + uint32_t *score_map; ///< map to store the scores + unsigned map_generation; + int pre_penalty_factor; + int penalty_factor; /**< an estimate of the bits required to + * code a given mv value, e.g. (1,0) takes + * more bits than (0,0). We have to + * estimate whether any reduction in + * residual is worth the extra bits. */ + int sub_penalty_factor; + int mb_penalty_factor; + int flags; + int sub_flags; + int mb_flags; + int pre_pass; ///< = 1 for the pre pass + int dia_size; + int xmin; + int xmax; + int ymin; + int ymax; + int pred_x; + int pred_y; + uint8_t *src[4][4]; + uint8_t *ref[4][4]; + int stride; + int uvstride; + /* temp variables for picture complexity calculation */ + int64_t mc_mb_var_sum_temp; + int64_t mb_var_sum_temp; + int scene_change_score; + + op_pixels_func(*hpel_put)[4]; + op_pixels_func(*hpel_avg)[4]; + qpel_mc_func(*qpel_put)[16]; + qpel_mc_func(*qpel_avg)[16]; + uint8_t (*mv_penalty)[MAX_DMV * 2 + 1]; ///< bit amount needed to encode a MV + uint8_t *current_mv_penalty; + int (*sub_motion_search)(struct MpegEncContext *s, + int *mx_ptr, int *my_ptr, int dmin, + int src_index, int ref_index, + int size, int h); +} MotionEstContext; + +static inline int ff_h263_round_chroma(int x) +{ + //FIXME static or not? + static const uint8_t h263_chroma_roundtab[16] = { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, + }; + return h263_chroma_roundtab[x & 0xf] + (x >> 3); +} + +int ff_init_me(struct MpegEncContext *s); + +void ff_estimate_p_frame_motion(struct MpegEncContext *s, int mb_x, int mb_y); +void ff_estimate_b_frame_motion(struct MpegEncContext *s, int mb_x, int mb_y); + +int ff_pre_estimate_p_frame_motion(struct MpegEncContext *s, + int mb_x, int mb_y); + +int ff_epzs_motion_search(struct MpegEncContext *s, int *mx_ptr, int *my_ptr, + int P[10][2], int src_index, int ref_index, + int16_t (*last_mv)[2], int ref_mv_scale, int size, + int h); + +int ff_get_mb_score(struct MpegEncContext *s, int mx, int my, int src_index, + int ref_index, int size, int h, int add_rate); + +int ff_get_best_fcode(struct MpegEncContext *s, + int16_t (*mv_table)[2], int type); + +void ff_fix_long_p_mvs(struct MpegEncContext *s); +void ff_fix_long_mvs(struct MpegEncContext *s, uint8_t *field_select_table, + int field_select, int16_t (*mv_table)[2], int f_code, + int type, int truncate); + +#endif /* AVCODEC_MOTION_EST_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12.c new file mode 100644 index 000000000..ab6c19c61 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12.c @@ -0,0 +1,332 @@ +/* + * MPEG-1/2 decoder + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * MPEG-1/2 decoder + */ + +#define UNCHECKED_BITSTREAM_READER 1 + +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/timecode.h" + +#include "internal.h" +#include "avcodec.h" +#include "mpegvideo.h" +#include "error_resilience.h" +#include "mpeg12.h" +#include "mpeg12data.h" +#include "mpegvideodata.h" +#include "bytestream.h" +#include "thread.h" + +uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; + +static const uint8_t table_mb_ptype[7][2] = { + { 3, 5 }, // 0x01 MB_INTRA + { 1, 2 }, // 0x02 MB_PAT + { 1, 3 }, // 0x08 MB_FOR + { 1, 1 }, // 0x0A MB_FOR|MB_PAT + { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA + { 1, 5 }, // 0x12 MB_QUANT|MB_PAT + { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT +}; + +static const uint8_t table_mb_btype[11][2] = { + { 3, 5 }, // 0x01 MB_INTRA + { 2, 3 }, // 0x04 MB_BACK + { 3, 3 }, // 0x06 MB_BACK|MB_PAT + { 2, 4 }, // 0x08 MB_FOR + { 3, 4 }, // 0x0A MB_FOR|MB_PAT + { 2, 2 }, // 0x0C MB_FOR|MB_BACK + { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT + { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA + { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT + { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT + { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT +}; + +av_cold void ff_init_2d_vlc_rl(RLTable *rl, unsigned static_size, int flags) +{ + int i; + VLC_TYPE table[680][2] = {{0}}; + VLC vlc = { .table = table, .table_allocated = static_size }; + av_assert0(static_size <= FF_ARRAY_ELEMS(table)); + init_vlc(&vlc, TEX_VLC_BITS, rl->n + 2, &rl->table_vlc[0][1], 4, 2, &rl->table_vlc[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC | flags); + + for (i = 0; i < vlc.table_size; i++) { + int code = vlc.table[i][0]; + int len = vlc.table[i][1]; + int level, run; + + if (len == 0) { // illegal code + run = 65; + level = MAX_LEVEL; + } else if (len<0) { //more bits needed + run = 0; + level = code; + } else { + if (code == rl->n) { //esc + run = 65; + level = 0; + } else if (code == rl->n+1) { //eob + run = 0; + level = 127; + } else { + run = rl->table_run [code] + 1; + level = rl->table_level[code]; + } + } + rl->rl_vlc[0][i].len = len; + rl->rl_vlc[0][i].level = level; + rl->rl_vlc[0][i].run = run; + } +} + +av_cold void ff_mpeg12_common_init(MpegEncContext *s) +{ + + s->y_dc_scale_table = + s->c_dc_scale_table = ff_mpeg2_dc_scale_table[s->intra_dc_precision]; + +} + +void ff_mpeg1_clean_buffers(MpegEncContext *s) +{ + s->last_dc[0] = 1 << (7 + s->intra_dc_precision); + s->last_dc[1] = s->last_dc[0]; + s->last_dc[2] = s->last_dc[0]; + memset(s->last_mv, 0, sizeof(s->last_mv)); +} + + +/******************************************/ +/* decoding */ + +VLC ff_mv_vlc; + +VLC ff_dc_lum_vlc; +VLC ff_dc_chroma_vlc; + +VLC ff_mbincr_vlc; +VLC ff_mb_ptype_vlc; +VLC ff_mb_btype_vlc; +VLC ff_mb_pat_vlc; + +av_cold void ff_mpeg12_init_vlcs(void) +{ + static int done = 0; + + if (!done) { + done = 1; + + INIT_VLC_STATIC(&ff_dc_lum_vlc, DC_VLC_BITS, 12, + ff_mpeg12_vlc_dc_lum_bits, 1, 1, + ff_mpeg12_vlc_dc_lum_code, 2, 2, 512); + INIT_VLC_STATIC(&ff_dc_chroma_vlc, DC_VLC_BITS, 12, + ff_mpeg12_vlc_dc_chroma_bits, 1, 1, + ff_mpeg12_vlc_dc_chroma_code, 2, 2, 514); + INIT_VLC_STATIC(&ff_mv_vlc, MV_VLC_BITS, 17, + &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1, + &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 518); + INIT_VLC_STATIC(&ff_mbincr_vlc, MBINCR_VLC_BITS, 36, + &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1, + &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 538); + INIT_VLC_STATIC(&ff_mb_pat_vlc, MB_PAT_VLC_BITS, 64, + &ff_mpeg12_mbPatTable[0][1], 2, 1, + &ff_mpeg12_mbPatTable[0][0], 2, 1, 512); + + INIT_VLC_STATIC(&ff_mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7, + &table_mb_ptype[0][1], 2, 1, + &table_mb_ptype[0][0], 2, 1, 64); + INIT_VLC_STATIC(&ff_mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, + &table_mb_btype[0][1], 2, 1, + &table_mb_btype[0][0], 2, 1, 64); + ff_rl_init(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); + ff_rl_init(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); + + INIT_2D_VLC_RL(ff_rl_mpeg1, 680, 0); + INIT_2D_VLC_RL(ff_rl_mpeg2, 674, 0); + } +} + +/** + * Find the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s) +{ + int i; + uint32_t state = pc->state; + + /* EOF considered as end of frame */ + if (buf_size == 0) + return 0; + +/* + 0 frame start -> 1/4 + 1 first_SEQEXT -> 0/2 + 2 first field start -> 3/0 + 3 second_SEQEXT -> 2/0 + 4 searching end +*/ + + for (i = 0; i < buf_size; i++) { + av_assert1(pc->frame_start_found >= 0 && pc->frame_start_found <= 4); + if (pc->frame_start_found & 1) { + if (state == EXT_START_CODE && (buf[i] & 0xF0) != 0x80) + pc->frame_start_found--; + else if (state == EXT_START_CODE + 2) { + if ((buf[i] & 3) == 3) + pc->frame_start_found = 0; + else + pc->frame_start_found = (pc->frame_start_found + 1) & 3; + } + state++; + } else { + i = avpriv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1; + if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) { + i++; + pc->frame_start_found = 4; + } + if (state == SEQ_END_CODE) { + pc->frame_start_found = 0; + pc->state=-1; + return i+1; + } + if (pc->frame_start_found == 2 && state == SEQ_START_CODE) + pc->frame_start_found = 0; + if (pc->frame_start_found < 4 && state == EXT_START_CODE) + pc->frame_start_found++; + if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) { + if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) { + pc->frame_start_found = 0; + pc->state = -1; + return i - 3; + } + } + if (pc->frame_start_found == 0 && s && state == PICTURE_START_CODE) { + ff_fetch_timestamp(s, i - 3, 1, i > 3); + } + } + } + pc->state = state; + return END_NOT_FOUND; +} + +#define MAX_INDEX (64 - 1) + +int ff_mpeg1_decode_block_intra(GetBitContext *gb, + const uint16_t *quant_matrix, + uint8_t *const scantable, int last_dc[3], + int16_t *block, int index, int qscale) +{ + int dc, diff, i = 0, component; + RLTable *rl = &ff_rl_mpeg1; + + /* DC coefficient */ + component = index <= 3 ? 0 : index - 4 + 1; + + diff = decode_dc(gb, component); + if (diff >= 0xffff) + return AVERROR_INVALIDDATA; + + dc = last_dc[component]; + dc += diff; + last_dc[component] = dc; + + block[0] = dc * quant_matrix[0]; + + { + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + if (((int32_t)GET_CACHE(re, gb)) <= (int32_t)0xBFFFFFFF) + goto end; + + /* now quantify & encode AC coefficients */ + while (1) { + int level, run, j; + + GET_RL_VLC(level, run, re, gb, rl->rl_vlc[0], + TEX_VLC_BITS, 2, 0); + + if (level != 0) { + i += run; + if (i > MAX_INDEX) + break; + + j = scantable[i]; + level = (level * qscale * quant_matrix[j]) >> 4; + level = (level - 1) | 1; + level = (level ^ SHOW_SBITS(re, gb, 1)) - + SHOW_SBITS(re, gb, 1); + SKIP_BITS(re, gb, 1); + } else { + /* escape */ + run = SHOW_UBITS(re, gb, 6) + 1; + LAST_SKIP_BITS(re, gb, 6); + UPDATE_CACHE(re, gb); + level = SHOW_SBITS(re, gb, 8); + SKIP_BITS(re, gb, 8); + + if (level == -128) { + level = SHOW_UBITS(re, gb, 8) - 256; + SKIP_BITS(re, gb, 8); + } else if (level == 0) { + level = SHOW_UBITS(re, gb, 8); + SKIP_BITS(re, gb, 8); + } + + i += run; + if (i > MAX_INDEX) + break; + + j = scantable[i]; + if (level < 0) { + level = -level; + level = (level * qscale * quant_matrix[j]) >> 4; + level = (level - 1) | 1; + level = -level; + } else { + level = (level * qscale * quant_matrix[j]) >> 4; + level = (level - 1) | 1; + } + } + + block[j] = level; + if (((int32_t)GET_CACHE(re, gb)) <= (int32_t)0xBFFFFFFF) + break; + + UPDATE_CACHE(re, gb); + } +end: + LAST_SKIP_BITS(re, gb, 2); + CLOSE_READER(re, gb); + } + + if (i > MAX_INDEX) + i = AVERROR_INVALIDDATA; + + return i; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12.h new file mode 100644 index 000000000..1ec99f17e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12.h @@ -0,0 +1,80 @@ +/* + * MPEG-1/2 common code + * Copyright (c) 2007 Aurelien Jacobs + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MPEG12_H +#define AVCODEC_MPEG12_H + +#include "mpeg12vlc.h" +#include "mpegvideo.h" + +extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; + +void ff_mpeg12_common_init(MpegEncContext *s); + +#define INIT_2D_VLC_RL(rl, static_size, flags)\ +{\ + static RL_VLC_ELEM rl_vlc_table[static_size];\ + rl.rl_vlc[0] = rl_vlc_table;\ + ff_init_2d_vlc_rl(&rl, static_size, flags);\ +} + +void ff_init_2d_vlc_rl(RLTable *rl, unsigned static_size, int flags); + +static inline int decode_dc(GetBitContext *gb, int component) +{ + int code, diff; + + if (component == 0) { + code = get_vlc2(gb, ff_dc_lum_vlc.table, DC_VLC_BITS, 2); + } else { + code = get_vlc2(gb, ff_dc_chroma_vlc.table, DC_VLC_BITS, 2); + } + if (code < 0){ + av_log(NULL, AV_LOG_ERROR, "invalid dc code at\n"); + return 0xffff; + } + if (code == 0) { + diff = 0; + } else { + diff = get_xbits(gb, code); + } + return diff; +} + +int ff_mpeg1_decode_block_intra(GetBitContext *gb, + const uint16_t *quant_matrix, + uint8_t *const scantable, int last_dc[3], + int16_t *block, int index, int qscale); + +void ff_mpeg1_clean_buffers(MpegEncContext *s); +int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s); + +void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64], + int motion_x, int motion_y); +void ff_mpeg1_encode_init(MpegEncContext *s); +void ff_mpeg1_encode_slice_header(MpegEncContext *s); + +void ff_mpeg12_find_best_frame_rate(AVRational frame_rate, + int *code, int *ext_n, int *ext_d, + int nonstandard); + +#endif /* AVCODEC_MPEG12_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12data.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12data.c new file mode 100644 index 000000000..4da96d7da --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12data.c @@ -0,0 +1,412 @@ +/* + * MPEG-1/2 tables + * copyright (c) 2000,2001 Fabrice Bellard + * copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * MPEG-1/2 tables. + */ + +#include "mpeg12data.h" + +const uint16_t ff_mpeg1_default_intra_matrix[256] = { + 8, 16, 19, 22, 26, 27, 29, 34, + 16, 16, 22, 24, 27, 29, 34, 37, + 19, 22, 26, 27, 29, 34, 34, 38, + 22, 22, 26, 27, 29, 34, 37, 40, + 22, 26, 27, 29, 32, 35, 40, 48, + 26, 27, 29, 32, 35, 40, 48, 58, + 26, 27, 29, 34, 38, 46, 56, 69, + 27, 29, 35, 38, 46, 56, 69, 83 +}; + +const uint16_t ff_mpeg1_default_non_intra_matrix[64] = { + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, +}; + +const uint16_t ff_mpeg12_vlc_dc_lum_code[12] = { + 0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x1ff, +}; +const unsigned char ff_mpeg12_vlc_dc_lum_bits[12] = { + 3, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 9, +}; + +const uint16_t ff_mpeg12_vlc_dc_chroma_code[12] = { + 0x0, 0x1, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x3fe, 0x3ff, +}; +const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12] = { + 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, +}; + +static const uint16_t mpeg1_vlc[113][2] = { + { 0x3, 2 }, { 0x4, 4 }, { 0x5, 5 }, { 0x6, 7 }, + { 0x26, 8 }, { 0x21, 8 }, { 0xa, 10 }, { 0x1d, 12 }, + { 0x18, 12 }, { 0x13, 12 }, { 0x10, 12 }, { 0x1a, 13 }, + { 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, { 0x1f, 14 }, + { 0x1e, 14 }, { 0x1d, 14 }, { 0x1c, 14 }, { 0x1b, 14 }, + { 0x1a, 14 }, { 0x19, 14 }, { 0x18, 14 }, { 0x17, 14 }, + { 0x16, 14 }, { 0x15, 14 }, { 0x14, 14 }, { 0x13, 14 }, + { 0x12, 14 }, { 0x11, 14 }, { 0x10, 14 }, { 0x18, 15 }, + { 0x17, 15 }, { 0x16, 15 }, { 0x15, 15 }, { 0x14, 15 }, + { 0x13, 15 }, { 0x12, 15 }, { 0x11, 15 }, { 0x10, 15 }, + { 0x3, 3 }, { 0x6, 6 }, { 0x25, 8 }, { 0xc, 10 }, + { 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x1f, 15 }, + { 0x1e, 15 }, { 0x1d, 15 }, { 0x1c, 15 }, { 0x1b, 15 }, + { 0x1a, 15 }, { 0x19, 15 }, { 0x13, 16 }, { 0x12, 16 }, + { 0x11, 16 }, { 0x10, 16 }, { 0x5, 4 }, { 0x4, 7 }, + { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, { 0x7, 5 }, + { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, { 0x6, 5 }, + { 0xf, 10 }, { 0x12, 12 }, { 0x7, 6 }, { 0x9, 10 }, + { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, { 0x14, 16 }, + { 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12 }, + { 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 }, + { 0x23, 8 }, { 0x1a, 16 }, { 0x22, 8 }, { 0x19, 16 }, + { 0x20, 8 }, { 0x18, 16 }, { 0xe, 10 }, { 0x17, 16 }, + { 0xd, 10 }, { 0x16, 16 }, { 0x8, 10 }, { 0x15, 16 }, + { 0x1f, 12 }, { 0x1a, 12 }, { 0x19, 12 }, { 0x17, 12 }, + { 0x16, 12 }, { 0x1f, 13 }, { 0x1e, 13 }, { 0x1d, 13 }, + { 0x1c, 13 }, { 0x1b, 13 }, { 0x1f, 16 }, { 0x1e, 16 }, + { 0x1d, 16 }, { 0x1c, 16 }, { 0x1b, 16 }, + { 0x1, 6 }, /* escape */ + { 0x2, 2 }, /* EOB */ +}; + +static const uint16_t mpeg2_vlc[113][2] = { + {0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5}, + {0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7}, + {0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8}, + {0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14}, + {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14}, + {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14}, + {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14}, + {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15}, + {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15}, + {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15}, + {0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8}, + {0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15}, + {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15}, + {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16}, + {0x11,16}, {0x10,16}, {0x05, 5}, {0x07, 7}, + {0xfc, 8}, {0x0c,10}, {0x14,13}, {0x07, 5}, + {0x26, 8}, {0x1c,12}, {0x13,13}, {0x06, 6}, + {0xfd, 8}, {0x12,12}, {0x07, 6}, {0x04, 9}, + {0x12,13}, {0x06, 7}, {0x1e,12}, {0x14,16}, + {0x04, 7}, {0x15,12}, {0x05, 7}, {0x11,12}, + {0x78, 7}, {0x11,13}, {0x7a, 7}, {0x10,13}, + {0x21, 8}, {0x1a,16}, {0x25, 8}, {0x19,16}, + {0x24, 8}, {0x18,16}, {0x05, 9}, {0x17,16}, + {0x07, 9}, {0x16,16}, {0x0d,10}, {0x15,16}, + {0x1f,12}, {0x1a,12}, {0x19,12}, {0x17,12}, + {0x16,12}, {0x1f,13}, {0x1e,13}, {0x1d,13}, + {0x1c,13}, {0x1b,13}, {0x1f,16}, {0x1e,16}, + {0x1d,16}, {0x1c,16}, {0x1b,16}, + {0x01,6}, /* escape */ + {0x06,4}, /* EOB */ +}; + +static const int8_t mpeg1_level[111] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 1, 2, 3, 4, 5, 1, + 2, 3, 4, 1, 2, 3, 1, 2, + 3, 1, 2, 3, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, +}; + +static const int8_t mpeg1_run[111] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 3, + 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, + 13, 13, 14, 14, 15, 15, 16, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, +}; + +RLTable ff_rl_mpeg1 = { + 111, + 111, + mpeg1_vlc, + mpeg1_run, + mpeg1_level, +}; + +RLTable ff_rl_mpeg2 = { + 111, + 111, + mpeg2_vlc, + mpeg1_run, + mpeg1_level, +}; + +const uint8_t ff_mpeg12_mbAddrIncrTable[36][2] = { + {0x1, 1}, + {0x3, 3}, + {0x2, 3}, + {0x3, 4}, + {0x2, 4}, + {0x3, 5}, + {0x2, 5}, + {0x7, 7}, + {0x6, 7}, + {0xb, 8}, + {0xa, 8}, + {0x9, 8}, + {0x8, 8}, + {0x7, 8}, + {0x6, 8}, + {0x17, 10}, + {0x16, 10}, + {0x15, 10}, + {0x14, 10}, + {0x13, 10}, + {0x12, 10}, + {0x23, 11}, + {0x22, 11}, + {0x21, 11}, + {0x20, 11}, + {0x1f, 11}, + {0x1e, 11}, + {0x1d, 11}, + {0x1c, 11}, + {0x1b, 11}, + {0x1a, 11}, + {0x19, 11}, + {0x18, 11}, + {0x8, 11}, /* escape */ + {0xf, 11}, /* stuffing */ + {0x0, 8}, /* end (and 15 more 0 bits should follow) */ +}; + +const uint8_t ff_mpeg12_mbPatTable[64][2] = { + {0x1, 9}, + {0xb, 5}, + {0x9, 5}, + {0xd, 6}, + {0xd, 4}, + {0x17, 7}, + {0x13, 7}, + {0x1f, 8}, + {0xc, 4}, + {0x16, 7}, + {0x12, 7}, + {0x1e, 8}, + {0x13, 5}, + {0x1b, 8}, + {0x17, 8}, + {0x13, 8}, + {0xb, 4}, + {0x15, 7}, + {0x11, 7}, + {0x1d, 8}, + {0x11, 5}, + {0x19, 8}, + {0x15, 8}, + {0x11, 8}, + {0xf, 6}, + {0xf, 8}, + {0xd, 8}, + {0x3, 9}, + {0xf, 5}, + {0xb, 8}, + {0x7, 8}, + {0x7, 9}, + {0xa, 4}, + {0x14, 7}, + {0x10, 7}, + {0x1c, 8}, + {0xe, 6}, + {0xe, 8}, + {0xc, 8}, + {0x2, 9}, + {0x10, 5}, + {0x18, 8}, + {0x14, 8}, + {0x10, 8}, + {0xe, 5}, + {0xa, 8}, + {0x6, 8}, + {0x6, 9}, + {0x12, 5}, + {0x1a, 8}, + {0x16, 8}, + {0x12, 8}, + {0xd, 5}, + {0x9, 8}, + {0x5, 8}, + {0x5, 9}, + {0xc, 5}, + {0x8, 8}, + {0x4, 8}, + {0x4, 9}, + {0x7, 3}, + {0xa, 5}, + {0x8, 5}, + {0xc, 6} +}; + +const uint8_t ff_mpeg12_mbMotionVectorTable[17][2] = { +{ 0x1, 1 }, +{ 0x1, 2 }, +{ 0x1, 3 }, +{ 0x1, 4 }, +{ 0x3, 6 }, +{ 0x5, 7 }, +{ 0x4, 7 }, +{ 0x3, 7 }, +{ 0xb, 9 }, +{ 0xa, 9 }, +{ 0x9, 9 }, +{ 0x11, 10 }, +{ 0x10, 10 }, +{ 0xf, 10 }, +{ 0xe, 10 }, +{ 0xd, 10 }, +{ 0xc, 10 }, +}; + +const AVRational ff_mpeg2_frame_rate_tab[] = { + { 1, 1}, + { 2, 1}, + { 3, 1}, + { 4, 1}, + { 5, 1}, + { 6, 1}, + { 8, 1}, + { 9, 1}, + { 10, 1}, + { 12, 1}, + { 15, 1}, + { 16, 1}, + { 18, 1}, + { 20, 1}, + { 24, 1}, + { 25, 1}, + { 30, 1}, + { 32, 1}, + { 36, 1}, + { 40, 1}, + { 45, 1}, + { 48, 1}, + { 50, 1}, + { 60, 1}, + { 72, 1}, + { 75, 1}, + { 80, 1}, + { 90, 1}, + { 96, 1}, + { 100, 1}, + { 120, 1}, + { 150, 1}, + { 180, 1}, + { 200, 1}, + { 240, 1}, + { 750, 1001}, + { 800, 1001}, + { 960, 1001}, + { 1000, 1001}, + { 1200, 1001}, + { 1250, 1001}, + { 1500, 1001}, + { 1600, 1001}, + { 1875, 1001}, + { 2000, 1001}, + { 2400, 1001}, + { 2500, 1001}, + { 3000, 1001}, + { 3750, 1001}, + { 4000, 1001}, + { 4800, 1001}, + { 5000, 1001}, + { 6000, 1001}, + { 7500, 1001}, + { 8000, 1001}, + { 10000, 1001}, + { 12000, 1001}, + { 15000, 1001}, + { 20000, 1001}, + { 24000, 1001}, + { 30000, 1001}, + { 60000, 1001}, + { 0, 0}, +}; + +const float ff_mpeg1_aspect[16]={ + 0.0000, + 1.0000, + 0.6735, + 0.7031, + + 0.7615, + 0.8055, + 0.8437, + 0.8935, + + 0.9157, + 0.9815, + 1.0255, + 1.0695, + + 1.0950, + 1.1575, + 1.2015, +}; + +const AVRational ff_mpeg2_aspect[16]={ + {0,1}, + {1,1}, + {4,3}, + {16,9}, + {221,100}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12data.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12data.h new file mode 100644 index 000000000..f51faf460 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12data.h @@ -0,0 +1,57 @@ +/* + * MPEG-1/2 tables + * copyright (c) 2000,2001 Fabrice Bellard + * copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * MPEG-1/2 tables. + */ + +#ifndef AVCODEC_MPEG12DATA_H +#define AVCODEC_MPEG12DATA_H + +#include +#include "libavutil/rational.h" +#include "rl.h" + +extern const uint16_t ff_mpeg1_default_intra_matrix[]; +extern const uint16_t ff_mpeg1_default_non_intra_matrix[64]; + +extern const uint16_t ff_mpeg12_vlc_dc_lum_code[12]; +extern const unsigned char ff_mpeg12_vlc_dc_lum_bits[12]; +extern const uint16_t ff_mpeg12_vlc_dc_chroma_code[12]; +extern const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12]; + +extern RLTable ff_rl_mpeg1; +extern RLTable ff_rl_mpeg2; + +extern const uint8_t ff_mpeg12_mbAddrIncrTable[36][2]; +extern const uint8_t ff_mpeg12_mbPatTable[64][2]; + +extern const uint8_t ff_mpeg12_mbMotionVectorTable[17][2]; + +extern const AVRational ff_mpeg12_frame_rate_tab[]; +extern const AVRational ff_mpeg2_frame_rate_tab[]; + +extern const float ff_mpeg1_aspect[16]; +extern const AVRational ff_mpeg2_aspect[16]; + +#endif /* AVCODEC_MPEG12DATA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12framerate.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12framerate.c new file mode 100644 index 000000000..ab3d35117 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12framerate.c @@ -0,0 +1,103 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/rational.h" + +#include "mpeg12.h" +#include "mpeg12data.h" + +const AVRational ff_mpeg12_frame_rate_tab[16] = { + { 0, 0}, + {24000, 1001}, + { 24, 1}, + { 25, 1}, + {30000, 1001}, + { 30, 1}, + { 50, 1}, + {60000, 1001}, + { 60, 1}, + // Xing's 15fps: (9) + { 15, 1}, + // libmpeg3's "Unofficial economy rates": (10-13) + { 5, 1}, + { 10, 1}, + { 12, 1}, + { 15, 1}, + { 0, 0}, +}; + +void ff_mpeg12_find_best_frame_rate(AVRational frame_rate, + int *code, int *ext_n, int *ext_d, + int nonstandard) +{ + int mpeg2 = ext_n && ext_d; + int max_code = nonstandard ? 12 : 8; + int c, n, d, best_c, best_n, best_d; + AVRational best_error = { INT_MAX, 1 }; + + // Default to NTSC if the inputs make no sense. + best_c = 4; + best_n = best_d = 1; + + for (c = 1; c <= max_code; c++) { + if (av_cmp_q(frame_rate, ff_mpeg12_frame_rate_tab[c]) == 0) { + best_c = c; + goto found; + } + } + + for (c = 1; c <= max_code; c++) { + for (n = 1; n <= (mpeg2 ? 4 : 1); n++) { + for (d = 1; d <= (mpeg2 ? 32 : 1); d++) { + AVRational test, error; + int cmp; + + test = av_mul_q(ff_mpeg12_frame_rate_tab[c], + (AVRational) { n, d }); + + cmp = av_cmp_q(test, frame_rate); + if (cmp == 0) { + best_c = c; + best_n = n; + best_d = d; + goto found; + } + + if (cmp < 0) + error = av_div_q(frame_rate, test); + else + error = av_div_q(test, frame_rate); + + cmp = av_cmp_q(error, best_error); + if (cmp < 0 || (cmp == 0 && n == 1 && d == 1)) { + best_c = c; + best_n = n; + best_d = d; + best_error = error; + } + } + } + } + +found: + *code = best_c; + if (mpeg2) { + *ext_n = best_n - 1; + *ext_d = best_d - 1; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12vlc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12vlc.h new file mode 100644 index 000000000..c5abae96b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg12vlc.h @@ -0,0 +1,52 @@ +/* + * MPEG-1/2 VLC + * copyright (c) 2000,2001 Fabrice Bellard + * copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * MPEG-1/2 VLC. + */ + +#ifndef AVCODEC_MPEG12VLC_H +#define AVCODEC_MPEG12VLC_H + +#include "vlc.h" + +#define DC_VLC_BITS 9 +#define MV_VLC_BITS 9 +#define TEX_VLC_BITS 9 + +#define MBINCR_VLC_BITS 9 +#define MB_PAT_VLC_BITS 9 +#define MB_PTYPE_VLC_BITS 6 +#define MB_BTYPE_VLC_BITS 6 + +extern VLC ff_dc_lum_vlc; +extern VLC ff_dc_chroma_vlc; +extern VLC ff_mbincr_vlc; +extern VLC ff_mb_ptype_vlc; +extern VLC ff_mb_btype_vlc; +extern VLC ff_mb_pat_vlc; +extern VLC ff_mv_vlc; + +void ff_mpeg12_init_vlcs(void); + +#endif /* AVCODEC_MPEG12VLC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg4audio.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg4audio.c new file mode 100644 index 000000000..219714752 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg4audio.c @@ -0,0 +1,169 @@ +/* + * MPEG-4 Audio common code + * Copyright (c) 2008 Baptiste Coudurier + * Copyright (c) 2009 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "get_bits.h" +#include "put_bits.h" +#include "mpeg4audio.h" + +/** + * Parse MPEG-4 audio configuration for ALS object type. + * @param[in] gb bit reader context + * @param[in] c MPEG4AudioConfig structure to fill + * @return on success 0 is returned, otherwise a value < 0 + */ +static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c) +{ + if (get_bits_left(gb) < 112) + return AVERROR_INVALIDDATA; + + if (get_bits_long(gb, 32) != MKBETAG('A','L','S','\0')) + return AVERROR_INVALIDDATA; + + // override AudioSpecificConfig channel configuration and sample rate + // which are buggy in old ALS conformance files + c->sample_rate = get_bits_long(gb, 32); + + if (c->sample_rate <= 0) { + av_log(NULL, AV_LOG_ERROR, "Invalid sample rate %d\n", c->sample_rate); + return AVERROR_INVALIDDATA; + } + + // skip number of samples + skip_bits_long(gb, 32); + + // read number of channels + c->chan_config = 0; + c->channels = get_bits(gb, 16) + 1; + + return 0; +} + +/* XXX: make sure to update the copies in the different encoders if you change + * this table */ +const int avpriv_mpeg4audio_sample_rates[16] = { + 96000, 88200, 64000, 48000, 44100, 32000, + 24000, 22050, 16000, 12000, 11025, 8000, 7350 +}; + +const uint8_t ff_mpeg4audio_channels[8] = { + 0, 1, 2, 3, 4, 5, 6, 8 +}; + +static inline int get_object_type(GetBitContext *gb) +{ + int object_type = get_bits(gb, 5); + if (object_type == AOT_ESCAPE) + object_type = 32 + get_bits(gb, 6); + return object_type; +} + +static inline int get_sample_rate(GetBitContext *gb, int *index) +{ + *index = get_bits(gb, 4); + return *index == 0x0f ? get_bits(gb, 24) : + avpriv_mpeg4audio_sample_rates[*index]; +} + +int ff_mpeg4audio_get_config_gb(MPEG4AudioConfig *c, GetBitContext *gb, + int sync_extension) +{ + int specific_config_bitindex, ret; + int start_bit_index = get_bits_count(gb); + c->object_type = get_object_type(gb); + c->sample_rate = get_sample_rate(gb, &c->sampling_index); + c->chan_config = get_bits(gb, 4); + if (c->chan_config < FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) + c->channels = ff_mpeg4audio_channels[c->chan_config]; + c->sbr = -1; + c->ps = -1; + if (c->object_type == AOT_SBR || (c->object_type == AOT_PS && + // check for W6132 Annex YYYY draft MP3onMP4 + !(show_bits(gb, 3) & 0x03 && !(show_bits(gb, 9) & 0x3F)))) { + if (c->object_type == AOT_PS) + c->ps = 1; + c->ext_object_type = AOT_SBR; + c->sbr = 1; + c->ext_sample_rate = get_sample_rate(gb, &c->ext_sampling_index); + c->object_type = get_object_type(gb); + if (c->object_type == AOT_ER_BSAC) + c->ext_chan_config = get_bits(gb, 4); + } else { + c->ext_object_type = AOT_NULL; + c->ext_sample_rate = 0; + } + specific_config_bitindex = get_bits_count(gb); + + if (c->object_type == AOT_ALS) { + skip_bits(gb, 5); + if (show_bits_long(gb, 24) != MKBETAG('\0','A','L','S')) + skip_bits_long(gb, 24); + + specific_config_bitindex = get_bits_count(gb); + + ret = parse_config_ALS(gb, c); + if (ret < 0) + return ret; + } + + if (c->ext_object_type != AOT_SBR && sync_extension) { + while (get_bits_left(gb) > 15) { + if (show_bits(gb, 11) == 0x2b7) { // sync extension + get_bits(gb, 11); + c->ext_object_type = get_object_type(gb); + if (c->ext_object_type == AOT_SBR && (c->sbr = get_bits1(gb)) == 1) { + c->ext_sample_rate = get_sample_rate(gb, &c->ext_sampling_index); + if (c->ext_sample_rate == c->sample_rate) + c->sbr = -1; + } + if (get_bits_left(gb) > 11 && get_bits(gb, 11) == 0x548) + c->ps = get_bits1(gb); + break; + } else + get_bits1(gb); // skip 1 bit + } + } + + //PS requires SBR + if (!c->sbr) + c->ps = 0; + //Limit implicit PS to the HE-AACv2 Profile + if ((c->ps == -1 && c->object_type != AOT_AAC_LC) || c->channels & ~0x01) + c->ps = 0; + + return specific_config_bitindex - start_bit_index; +} + +int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, + int bit_size, int sync_extension) +{ + GetBitContext gb; + int ret; + + if (bit_size <= 0) + return AVERROR_INVALIDDATA; + + ret = init_get_bits(&gb, buf, bit_size); + if (ret < 0) + return ret; + + return ff_mpeg4audio_get_config_gb(c, &gb, sync_extension); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg4audio.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg4audio.h new file mode 100644 index 000000000..b9cea8af1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpeg4audio.h @@ -0,0 +1,162 @@ +/* + * MPEG-4 Audio common header + * Copyright (c) 2008 Baptiste Coudurier + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MPEG4AUDIO_H +#define AVCODEC_MPEG4AUDIO_H + +#include + +#include "libavutil/attributes.h" + +#include "get_bits.h" +#include "internal.h" +#include "put_bits.h" + +typedef struct MPEG4AudioConfig { + int object_type; + int sampling_index; + int sample_rate; + int chan_config; + int sbr; ///< -1 implicit, 1 presence + int ext_object_type; + int ext_sampling_index; + int ext_sample_rate; + int ext_chan_config; + int channels; + int ps; ///< -1 implicit, 1 presence + int frame_length_short; +} MPEG4AudioConfig; + +extern av_export_avcodec const int avpriv_mpeg4audio_sample_rates[16]; +extern const uint8_t ff_mpeg4audio_channels[8]; + +/** + * Parse MPEG-4 systems extradata from a potentially unaligned GetBitContext to retrieve audio configuration. + * @param[in] c MPEG4AudioConfig structure to fill. + * @param[in] gb Extradata from container. + * @param[in] sync_extension look for a sync extension after config if true. + * @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata. + */ +int ff_mpeg4audio_get_config_gb(MPEG4AudioConfig *c, GetBitContext *gb, + int sync_extension); + +/** + * Parse MPEG-4 systems extradata from a raw buffer to retrieve audio configuration. + * @param[in] c MPEG4AudioConfig structure to fill. + * @param[in] buf Extradata from container. + * @param[in] bit_size Extradata size in bits. + * @param[in] sync_extension look for a sync extension after config if true. + * @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata. + */ +int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, + int bit_size, int sync_extension); + +enum AudioObjectType { + AOT_NULL, + // Support? Name + AOT_AAC_MAIN, ///< Y Main + AOT_AAC_LC, ///< Y Low Complexity + AOT_AAC_SSR, ///< N (code in SoC repo) Scalable Sample Rate + AOT_AAC_LTP, ///< Y Long Term Prediction + AOT_SBR, ///< Y Spectral Band Replication + AOT_AAC_SCALABLE, ///< N Scalable + AOT_TWINVQ, ///< N Twin Vector Quantizer + AOT_CELP, ///< N Code Excited Linear Prediction + AOT_HVXC, ///< N Harmonic Vector eXcitation Coding + AOT_TTSI = 12, ///< N Text-To-Speech Interface + AOT_MAINSYNTH, ///< N Main Synthesis + AOT_WAVESYNTH, ///< N Wavetable Synthesis + AOT_MIDI, ///< N General MIDI + AOT_SAFX, ///< N Algorithmic Synthesis and Audio Effects + AOT_ER_AAC_LC, ///< N Error Resilient Low Complexity + AOT_ER_AAC_LTP = 19, ///< N Error Resilient Long Term Prediction + AOT_ER_AAC_SCALABLE, ///< N Error Resilient Scalable + AOT_ER_TWINVQ, ///< N Error Resilient Twin Vector Quantizer + AOT_ER_BSAC, ///< N Error Resilient Bit-Sliced Arithmetic Coding + AOT_ER_AAC_LD, ///< N Error Resilient Low Delay + AOT_ER_CELP, ///< N Error Resilient Code Excited Linear Prediction + AOT_ER_HVXC, ///< N Error Resilient Harmonic Vector eXcitation Coding + AOT_ER_HILN, ///< N Error Resilient Harmonic and Individual Lines plus Noise + AOT_ER_PARAM, ///< N Error Resilient Parametric + AOT_SSC, ///< N SinuSoidal Coding + AOT_PS, ///< N Parametric Stereo + AOT_SURROUND, ///< N MPEG Surround + AOT_ESCAPE, ///< Y Escape Value + AOT_L1, ///< Y Layer 1 + AOT_L2, ///< Y Layer 2 + AOT_L3, ///< Y Layer 3 + AOT_DST, ///< N Direct Stream Transfer + AOT_ALS, ///< Y Audio LosslesS + AOT_SLS, ///< N Scalable LosslesS + AOT_SLS_NON_CORE, ///< N Scalable LosslesS (non core) + AOT_ER_AAC_ELD, ///< N Error Resilient Enhanced Low Delay + AOT_SMR_SIMPLE, ///< N Symbolic Music Representation Simple + AOT_SMR_MAIN, ///< N Symbolic Music Representation Main + AOT_USAC_NOSBR, ///< N Unified Speech and Audio Coding (no SBR) + AOT_SAOC, ///< N Spatial Audio Object Coding + AOT_LD_SURROUND, ///< N Low Delay MPEG Surround + AOT_USAC, ///< N Unified Speech and Audio Coding +}; + +#define MAX_PCE_SIZE 320 /// 16; bits -= 16) + ff_pce_copy_bits(pb, gb, 16); + if (bits) + ff_pce_copy_bits(pb, gb, bits); + avpriv_align_put_bits(pb); + align_get_bits(gb); + comment_size = ff_pce_copy_bits(pb, gb, 8); + for (; comment_size > 0; comment_size--) + ff_pce_copy_bits(pb, gb, 8); + + return put_bits_count(pb) - offset; +} + +#endif /* AVCODEC_MPEG4AUDIO_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegpicture.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegpicture.c new file mode 100644 index 000000000..ecbd77d50 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegpicture.c @@ -0,0 +1,483 @@ +/* + * Mpeg video formats-related picture management functions + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/pixdesc.h" +#include "libavutil/imgutils.h" + +#include "avcodec.h" +#include "motion_est.h" +#include "mpegpicture.h" +#include "mpegutils.h" + +static int make_tables_writable(Picture *pic) +{ + int ret, i; +#define MAKE_WRITABLE(table) \ +do {\ + if (pic->table &&\ + (ret = av_buffer_make_writable(&pic->table)) < 0)\ + return ret;\ +} while (0) + + MAKE_WRITABLE(mb_var_buf); + MAKE_WRITABLE(mc_mb_var_buf); + MAKE_WRITABLE(mb_mean_buf); + MAKE_WRITABLE(mbskip_table_buf); + MAKE_WRITABLE(qscale_table_buf); + MAKE_WRITABLE(mb_type_buf); + + for (i = 0; i < 2; i++) { + MAKE_WRITABLE(motion_val_buf[i]); + MAKE_WRITABLE(ref_index_buf[i]); + } + + return 0; +} + +int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, + ScratchpadContext *sc, int linesize) +{ +# define EMU_EDGE_HEIGHT (4 * 70) + int alloc_size = FFALIGN(FFABS(linesize) + 64, 32); + + if (avctx->hwaccel) + return 0; + + if (linesize < 24) { + av_log(avctx, AV_LOG_ERROR, "Image too small, temporary buffers cannot function\n"); + return AVERROR_PATCHWELCOME; + } + + if (av_image_check_size2(alloc_size, EMU_EDGE_HEIGHT, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0) + return AVERROR(ENOMEM); + + // edge emu needs blocksize + filter length - 1 + // (= 17x17 for halfpel / 21x21 for H.264) + // VC-1 computes luma and chroma simultaneously and needs 19X19 + 9x9 + // at uvlinesize. It supports only YUV420 so 24x24 is enough + // linesize * interlaced * MBsize + // we also use this buffer for encoding in encode_mb_internal() needig an additional 32 lines + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, sc->edge_emu_buffer, alloc_size, EMU_EDGE_HEIGHT, + fail); + + FF_ALLOCZ_ARRAY_OR_GOTO(avctx, me->scratchpad, alloc_size, 4 * 16 * 2, + fail) + me->temp = me->scratchpad; + sc->rd_scratchpad = me->scratchpad; + sc->b_scratchpad = me->scratchpad; + sc->obmc_scratchpad = me->scratchpad + 16; + + return 0; +fail: + av_freep(&sc->edge_emu_buffer); + return AVERROR(ENOMEM); +} + +/** + * Allocate a frame buffer + */ +static int alloc_frame_buffer(AVCodecContext *avctx, Picture *pic, + MotionEstContext *me, ScratchpadContext *sc, + int chroma_x_shift, int chroma_y_shift, + int linesize, int uvlinesize) +{ + int edges_needed = av_codec_is_encoder(avctx->codec); + int r, ret; + + pic->tf.f = pic->f; + if (avctx->codec_id != AV_CODEC_ID_WMV3IMAGE && + avctx->codec_id != AV_CODEC_ID_VC1IMAGE && + avctx->codec_id != AV_CODEC_ID_MSS2) { + if (edges_needed) { + pic->f->width = avctx->width + 2 * EDGE_WIDTH; + pic->f->height = avctx->height + 2 * EDGE_WIDTH; + } + + r = ff_thread_get_buffer(avctx, &pic->tf, + pic->reference ? AV_GET_BUFFER_FLAG_REF : 0); + } else { + pic->f->width = avctx->width; + pic->f->height = avctx->height; + pic->f->format = avctx->pix_fmt; + r = avcodec_default_get_buffer2(avctx, pic->f, 0); + } + + if (r < 0 || !pic->f->buf[0]) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n", + r, pic->f->data[0]); + return -1; + } + + if (edges_needed) { + int i; + for (i = 0; pic->f->data[i]; i++) { + int offset = (EDGE_WIDTH >> (i ? chroma_y_shift : 0)) * + pic->f->linesize[i] + + (EDGE_WIDTH >> (i ? chroma_x_shift : 0)); + pic->f->data[i] += offset; + } + pic->f->width = avctx->width; + pic->f->height = avctx->height; + } + + if (avctx->hwaccel) { + assert(!pic->hwaccel_picture_private); + if (avctx->hwaccel->frame_priv_data_size) { + pic->hwaccel_priv_buf = av_buffer_allocz(avctx->hwaccel->frame_priv_data_size); + if (!pic->hwaccel_priv_buf) { + av_log(avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n"); + return -1; + } + pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data; + } + } + + if ((linesize && linesize != pic->f->linesize[0]) || + (uvlinesize && uvlinesize != pic->f->linesize[1])) { + av_log(avctx, AV_LOG_ERROR, + "get_buffer() failed (stride changed: linesize=%d/%d uvlinesize=%d/%d)\n", + linesize, pic->f->linesize[0], + uvlinesize, pic->f->linesize[1]); + ff_mpeg_unref_picture(avctx, pic); + return -1; + } + + if (av_pix_fmt_count_planes(pic->f->format) > 2 && + pic->f->linesize[1] != pic->f->linesize[2]) { + av_log(avctx, AV_LOG_ERROR, + "get_buffer() failed (uv stride mismatch)\n"); + ff_mpeg_unref_picture(avctx, pic); + return -1; + } + + if (!sc->edge_emu_buffer && + (ret = ff_mpeg_framesize_alloc(avctx, me, sc, + pic->f->linesize[0])) < 0) { + av_log(avctx, AV_LOG_ERROR, + "get_buffer() failed to allocate context scratch buffers.\n"); + ff_mpeg_unref_picture(avctx, pic); + return ret; + } + + return 0; +} + +static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encoding, int out_format, + int mb_stride, int mb_width, int mb_height, int b8_stride) +{ + const int big_mb_num = mb_stride * (mb_height + 1) + 1; + const int mb_array_size = mb_stride * mb_height; + const int b8_array_size = b8_stride * mb_height * 2; + int i; + + + pic->mbskip_table_buf = av_buffer_allocz(mb_array_size + 2); + pic->qscale_table_buf = av_buffer_allocz(big_mb_num + mb_stride); + pic->mb_type_buf = av_buffer_allocz((big_mb_num + mb_stride) * + sizeof(uint32_t)); + if (!pic->mbskip_table_buf || !pic->qscale_table_buf || !pic->mb_type_buf) + return AVERROR(ENOMEM); + + if (encoding) { + pic->mb_var_buf = av_buffer_allocz(mb_array_size * sizeof(int16_t)); + pic->mc_mb_var_buf = av_buffer_allocz(mb_array_size * sizeof(int16_t)); + pic->mb_mean_buf = av_buffer_allocz(mb_array_size); + if (!pic->mb_var_buf || !pic->mc_mb_var_buf || !pic->mb_mean_buf) + return AVERROR(ENOMEM); + } + + if (out_format == FMT_H263 || encoding || +#if FF_API_DEBUG_MV + avctx->debug_mv || +#endif + (avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS)) { + int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t); + int ref_index_size = 4 * mb_array_size; + + for (i = 0; mv_size && i < 2; i++) { + pic->motion_val_buf[i] = av_buffer_allocz(mv_size); + pic->ref_index_buf[i] = av_buffer_allocz(ref_index_size); + if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) + return AVERROR(ENOMEM); + } + } + + pic->alloc_mb_width = mb_width; + pic->alloc_mb_height = mb_height; + + return 0; +} + +/** + * Allocate a Picture. + * The pixels are allocated/set by calling get_buffer() if shared = 0 + */ +int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, + ScratchpadContext *sc, int shared, int encoding, + int chroma_x_shift, int chroma_y_shift, int out_format, + int mb_stride, int mb_width, int mb_height, int b8_stride, + ptrdiff_t *linesize, ptrdiff_t *uvlinesize) +{ + int i, ret; + + if (pic->qscale_table_buf) + if ( pic->alloc_mb_width != mb_width + || pic->alloc_mb_height != mb_height) + ff_free_picture_tables(pic); + + if (shared) { + av_assert0(pic->f->data[0]); + pic->shared = 1; + } else { + av_assert0(!pic->f->buf[0]); + if (alloc_frame_buffer(avctx, pic, me, sc, + chroma_x_shift, chroma_y_shift, + *linesize, *uvlinesize) < 0) + return -1; + + *linesize = pic->f->linesize[0]; + *uvlinesize = pic->f->linesize[1]; + } + + if (!pic->qscale_table_buf) + ret = alloc_picture_tables(avctx, pic, encoding, out_format, + mb_stride, mb_width, mb_height, b8_stride); + else + ret = make_tables_writable(pic); + if (ret < 0) + goto fail; + + if (encoding) { + pic->mb_var = (uint16_t*)pic->mb_var_buf->data; + pic->mc_mb_var = (uint16_t*)pic->mc_mb_var_buf->data; + pic->mb_mean = pic->mb_mean_buf->data; + } + + pic->mbskip_table = pic->mbskip_table_buf->data; + pic->qscale_table = pic->qscale_table_buf->data + 2 * mb_stride + 1; + pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * mb_stride + 1; + + if (pic->motion_val_buf[0]) { + for (i = 0; i < 2; i++) { + pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4; + pic->ref_index[i] = pic->ref_index_buf[i]->data; + } + } + + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "Error allocating a picture.\n"); + ff_mpeg_unref_picture(avctx, pic); + ff_free_picture_tables(pic); + return AVERROR(ENOMEM); +} + +/** + * Deallocate a picture. + */ +void ff_mpeg_unref_picture(AVCodecContext *avctx, Picture *pic) +{ + int off = offsetof(Picture, mb_mean) + sizeof(pic->mb_mean); + + pic->tf.f = pic->f; + /* WM Image / Screen codecs allocate internal buffers with different + * dimensions / colorspaces; ignore user-defined callbacks for these. */ + if (avctx->codec_id != AV_CODEC_ID_WMV3IMAGE && + avctx->codec_id != AV_CODEC_ID_VC1IMAGE && + avctx->codec_id != AV_CODEC_ID_MSS2) + ff_thread_release_buffer(avctx, &pic->tf); + else if (pic->f) + av_frame_unref(pic->f); + + av_buffer_unref(&pic->hwaccel_priv_buf); + + if (pic->needs_realloc) + ff_free_picture_tables(pic); + + memset((uint8_t*)pic + off, 0, sizeof(*pic) - off); +} + +int ff_update_picture_tables(Picture *dst, Picture *src) +{ + int i; + +#define UPDATE_TABLE(table) \ +do { \ + if (src->table && \ + (!dst->table || dst->table->buffer != src->table->buffer)) { \ + av_buffer_unref(&dst->table); \ + dst->table = av_buffer_ref(src->table); \ + if (!dst->table) { \ + ff_free_picture_tables(dst); \ + return AVERROR(ENOMEM); \ + } \ + } \ +} while (0) + + UPDATE_TABLE(mb_var_buf); + UPDATE_TABLE(mc_mb_var_buf); + UPDATE_TABLE(mb_mean_buf); + UPDATE_TABLE(mbskip_table_buf); + UPDATE_TABLE(qscale_table_buf); + UPDATE_TABLE(mb_type_buf); + for (i = 0; i < 2; i++) { + UPDATE_TABLE(motion_val_buf[i]); + UPDATE_TABLE(ref_index_buf[i]); + } + + dst->mb_var = src->mb_var; + dst->mc_mb_var = src->mc_mb_var; + dst->mb_mean = src->mb_mean; + dst->mbskip_table = src->mbskip_table; + dst->qscale_table = src->qscale_table; + dst->mb_type = src->mb_type; + for (i = 0; i < 2; i++) { + dst->motion_val[i] = src->motion_val[i]; + dst->ref_index[i] = src->ref_index[i]; + } + + dst->alloc_mb_width = src->alloc_mb_width; + dst->alloc_mb_height = src->alloc_mb_height; + + return 0; +} + +int ff_mpeg_ref_picture(AVCodecContext *avctx, Picture *dst, Picture *src) +{ + int ret; + + av_assert0(!dst->f->buf[0]); + av_assert0(src->f->buf[0]); + + src->tf.f = src->f; + dst->tf.f = dst->f; + ret = ff_thread_ref_frame(&dst->tf, &src->tf); + if (ret < 0) + goto fail; + + ret = ff_update_picture_tables(dst, src); + if (ret < 0) + goto fail; + + if (src->hwaccel_picture_private) { + dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf); + if (!dst->hwaccel_priv_buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data; + } + + dst->field_picture = src->field_picture; + dst->mb_var_sum = src->mb_var_sum; + dst->mc_mb_var_sum = src->mc_mb_var_sum; + dst->b_frame_score = src->b_frame_score; + dst->needs_realloc = src->needs_realloc; + dst->reference = src->reference; + dst->shared = src->shared; + + memcpy(dst->encoding_error, src->encoding_error, + sizeof(dst->encoding_error)); + + return 0; +fail: + ff_mpeg_unref_picture(avctx, dst); + return ret; +} + +static inline int pic_is_unused(Picture *pic) +{ + if (!pic->f->buf[0]) + return 1; + if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF)) + return 1; + return 0; +} + +static int find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) +{ + int i; + + if (shared) { + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (!picture[i].f->buf[0]) + return i; + } + } else { + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (pic_is_unused(&picture[i])) + return i; + } + } + + av_log(avctx, AV_LOG_FATAL, + "Internal error, picture buffer overflow\n"); + /* We could return -1, but the codec would crash trying to draw into a + * non-existing frame anyway. This is safer than waiting for a random crash. + * Also the return of this is never useful, an encoder must only allocate + * as much as allowed in the specification. This has no relationship to how + * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large + * enough for such valid streams). + * Plus, a decoder has to check stream validity and remove frames if too + * many reference frames are around. Waiting for "OOM" is not correct at + * all. Similarly, missing reference frames have to be replaced by + * interpolated/MC frames, anything else is a bug in the codec ... + */ + abort(); + return -1; +} + +int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) +{ + int ret = find_unused_picture(avctx, picture, shared); + + if (ret >= 0 && ret < MAX_PICTURE_COUNT) { + if (picture[ret].needs_realloc) { + picture[ret].needs_realloc = 0; + ff_free_picture_tables(&picture[ret]); + ff_mpeg_unref_picture(avctx, &picture[ret]); + } + } + return ret; +} + +void ff_free_picture_tables(Picture *pic) +{ + int i; + + pic->alloc_mb_width = + pic->alloc_mb_height = 0; + + av_buffer_unref(&pic->mb_var_buf); + av_buffer_unref(&pic->mc_mb_var_buf); + av_buffer_unref(&pic->mb_mean_buf); + av_buffer_unref(&pic->mbskip_table_buf); + av_buffer_unref(&pic->qscale_table_buf); + av_buffer_unref(&pic->mb_type_buf); + + for (i = 0; i < 2; i++) { + av_buffer_unref(&pic->motion_val_buf[i]); + av_buffer_unref(&pic->ref_index_buf[i]); + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegpicture.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegpicture.h new file mode 100644 index 000000000..2db3d6733 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegpicture.h @@ -0,0 +1,114 @@ +/* + * Mpeg video formats-related defines and utility functions + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MPEGPICTURE_H +#define AVCODEC_MPEGPICTURE_H + +#include + +#include "libavutil/frame.h" + +#include "avcodec.h" +#include "motion_est.h" +#include "thread.h" + +#define MAX_PICTURE_COUNT 36 +#define EDGE_WIDTH 16 + +typedef struct ScratchpadContext { + uint8_t *edge_emu_buffer; ///< temporary buffer for if MVs point to out-of-frame data + uint8_t *rd_scratchpad; ///< scratchpad for rate distortion mb decision + uint8_t *obmc_scratchpad; + uint8_t *b_scratchpad; ///< scratchpad used for writing into write only buffers +} ScratchpadContext; + +/** + * Picture. + */ +typedef struct Picture { + struct AVFrame *f; + ThreadFrame tf; + + AVBufferRef *qscale_table_buf; + int8_t *qscale_table; + + AVBufferRef *motion_val_buf[2]; + int16_t (*motion_val[2])[2]; + + AVBufferRef *mb_type_buf; + uint32_t *mb_type; ///< types and macros are defined in mpegutils.h + + AVBufferRef *mbskip_table_buf; + uint8_t *mbskip_table; + + AVBufferRef *ref_index_buf[2]; + int8_t *ref_index[2]; + + AVBufferRef *mb_var_buf; + uint16_t *mb_var; ///< Table for MB variances + + AVBufferRef *mc_mb_var_buf; + uint16_t *mc_mb_var; ///< Table for motion compensated MB variances + + int alloc_mb_width; ///< mb_width used to allocate tables + int alloc_mb_height; ///< mb_height used to allocate tables + + AVBufferRef *mb_mean_buf; + uint8_t *mb_mean; ///< Table for MB luminance + + AVBufferRef *hwaccel_priv_buf; + void *hwaccel_picture_private; ///< Hardware accelerator private data + + int field_picture; ///< whether or not the picture was encoded in separate fields + + int64_t mb_var_sum; ///< sum of MB variance for current frame + int64_t mc_mb_var_sum; ///< motion compensated MB variance for current frame + + int b_frame_score; + int needs_realloc; ///< Picture needs to be reallocated (eg due to a frame size change) + + int reference; + int shared; + + uint64_t encoding_error[AV_NUM_DATA_POINTERS]; +} Picture; + +/** + * Allocate a Picture. + * The pixels are allocated/set by calling get_buffer() if shared = 0. + */ +int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, + ScratchpadContext *sc, int shared, int encoding, + int chroma_x_shift, int chroma_y_shift, int out_format, + int mb_stride, int mb_width, int mb_height, int b8_stride, + ptrdiff_t *linesize, ptrdiff_t *uvlinesize); + +int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, + ScratchpadContext *sc, int linesize); + +int ff_mpeg_ref_picture(AVCodecContext *avctx, Picture *dst, Picture *src); +void ff_mpeg_unref_picture(AVCodecContext *avctx, Picture *picture); + +void ff_free_picture_tables(Picture *pic); +int ff_update_picture_tables(Picture *dst, Picture *src); + +int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared); + +#endif /* AVCODEC_MPEGPICTURE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegutils.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegutils.c new file mode 100644 index 000000000..3f9454061 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegutils.c @@ -0,0 +1,393 @@ +/* + * Mpeg video formats-related defines and utility functions + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/pixdesc.h" +#include "libavutil/motion_vector.h" +#include "libavutil/avassert.h" + +#include "avcodec.h" +#include "mpegutils.h" + +static int add_mb(AVMotionVector *mb, uint32_t mb_type, + int dst_x, int dst_y, + int motion_x, int motion_y, int motion_scale, + int direction) +{ + mb->w = IS_8X8(mb_type) || IS_8X16(mb_type) ? 8 : 16; + mb->h = IS_8X8(mb_type) || IS_16X8(mb_type) ? 8 : 16; + mb->motion_x = motion_x; + mb->motion_y = motion_y; + mb->motion_scale = motion_scale; + mb->dst_x = dst_x; + mb->dst_y = dst_y; + mb->src_x = dst_x + motion_x / motion_scale; + mb->src_y = dst_y + motion_y / motion_scale; + mb->source = direction ? 1 : -1; + mb->flags = 0; // XXX: does mb_type contain extra information that could be exported here? + return 1; +} + +void ff_draw_horiz_band(AVCodecContext *avctx, + AVFrame *cur, AVFrame *last, + int y, int h, int picture_structure, + int first_field, int low_delay) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + int vshift = desc->log2_chroma_h; + const int field_pic = picture_structure != PICT_FRAME; + if (field_pic) { + h <<= 1; + y <<= 1; + } + + h = FFMIN(h, avctx->height - y); + + if (field_pic && first_field && + !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) + return; + + if (avctx->draw_horiz_band) { + AVFrame *src; + int offset[AV_NUM_DATA_POINTERS]; + int i; + + if (cur->pict_type == AV_PICTURE_TYPE_B || low_delay || + (avctx->slice_flags & SLICE_FLAG_CODED_ORDER)) + src = cur; + else if (last) + src = last; + else + return; + + if (cur->pict_type == AV_PICTURE_TYPE_B && + picture_structure == PICT_FRAME && + avctx->codec_id != AV_CODEC_ID_SVQ3) { + for (i = 0; i < AV_NUM_DATA_POINTERS; i++) + offset[i] = 0; + } else { + offset[0]= y * src->linesize[0]; + offset[1]= + offset[2]= (y >> vshift) * src->linesize[1]; + for (i = 3; i < AV_NUM_DATA_POINTERS; i++) + offset[i] = 0; + } + + emms_c(); + + avctx->draw_horiz_band(avctx, src, offset, + y, picture_structure, h); + } +} + +void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_table, + uint32_t *mbtype_table, int8_t *qscale_table, int16_t (*motion_val[2])[2], + int *low_delay, + int mb_width, int mb_height, int mb_stride, int quarter_sample) +{ + if ((avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS) && mbtype_table && motion_val[0]) { + const int shift = 1 + quarter_sample; + const int scale = 1 << shift; + const int mv_sample_log2 = avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_SVQ3 ? 2 : 1; + const int mv_stride = (mb_width << mv_sample_log2) + + (avctx->codec->id == AV_CODEC_ID_H264 ? 0 : 1); + int mb_x, mb_y, mbcount = 0; + + /* size is width * height * 2 * 4 where 2 is for directions and 4 is + * for the maximum number of MB (4 MB in case of IS_8x8) */ + AVMotionVector *mvs = av_malloc_array(mb_width * mb_height, 2 * 4 * sizeof(AVMotionVector)); + if (!mvs) + return; + + for (mb_y = 0; mb_y < mb_height; mb_y++) { + for (mb_x = 0; mb_x < mb_width; mb_x++) { + int i, direction, mb_type = mbtype_table[mb_x + mb_y * mb_stride]; + for (direction = 0; direction < 2; direction++) { + if (!USES_LIST(mb_type, direction)) + continue; + if (IS_8X8(mb_type)) { + for (i = 0; i < 4; i++) { + int sx = mb_x * 16 + 4 + 8 * (i & 1); + int sy = mb_y * 16 + 4 + 8 * (i >> 1); + int xy = (mb_x * 2 + (i & 1) + + (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1); + int mx = motion_val[direction][xy][0]; + int my = motion_val[direction][xy][1]; + mbcount += add_mb(mvs + mbcount, mb_type, sx, sy, mx, my, scale, direction); + } + } else if (IS_16X8(mb_type)) { + for (i = 0; i < 2; i++) { + int sx = mb_x * 16 + 8; + int sy = mb_y * 16 + 4 + 8 * i; + int xy = (mb_x * 2 + (mb_y * 2 + i) * mv_stride) << (mv_sample_log2 - 1); + int mx = motion_val[direction][xy][0]; + int my = motion_val[direction][xy][1]; + + if (IS_INTERLACED(mb_type)) + my *= 2; + + mbcount += add_mb(mvs + mbcount, mb_type, sx, sy, mx, my, scale, direction); + } + } else if (IS_8X16(mb_type)) { + for (i = 0; i < 2; i++) { + int sx = mb_x * 16 + 4 + 8 * i; + int sy = mb_y * 16 + 8; + int xy = (mb_x * 2 + i + mb_y * 2 * mv_stride) << (mv_sample_log2 - 1); + int mx = motion_val[direction][xy][0]; + int my = motion_val[direction][xy][1]; + + if (IS_INTERLACED(mb_type)) + my *= 2; + + mbcount += add_mb(mvs + mbcount, mb_type, sx, sy, mx, my, scale, direction); + } + } else { + int sx = mb_x * 16 + 8; + int sy = mb_y * 16 + 8; + int xy = (mb_x + mb_y * mv_stride) << mv_sample_log2; + int mx = motion_val[direction][xy][0]; + int my = motion_val[direction][xy][1]; + mbcount += add_mb(mvs + mbcount, mb_type, sx, sy, mx, my, scale, direction); + } + } + } + } + + if (mbcount) { + AVFrameSideData *sd; + + av_log(avctx, AV_LOG_DEBUG, "Adding %d MVs info to frame %d\n", mbcount, avctx->frame_number); + sd = av_frame_new_side_data(pict, AV_FRAME_DATA_MOTION_VECTORS, mbcount * sizeof(AVMotionVector)); + if (!sd) { + av_freep(&mvs); + return; + } + memcpy(sd->data, mvs, mbcount * sizeof(AVMotionVector)); + } + + av_freep(&mvs); + } + + /* TODO: export all the following to make them accessible for users (and filters) */ + if (avctx->hwaccel || !mbtype_table) + return; + + + if (avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) { + int x,y; + + av_log(avctx, AV_LOG_DEBUG, "New frame, type: %c\n", + av_get_picture_type_char(pict->pict_type)); + for (y = 0; y < mb_height; y++) { + for (x = 0; x < mb_width; x++) { + if (avctx->debug & FF_DEBUG_SKIP) { + int count = mbskip_table ? mbskip_table[x + y * mb_stride] : 0; + if (count > 9) + count = 9; + av_log(avctx, AV_LOG_DEBUG, "%1d", count); + } + if (avctx->debug & FF_DEBUG_QP) { + av_log(avctx, AV_LOG_DEBUG, "%2d", + qscale_table[x + y * mb_stride]); + } + if (avctx->debug & FF_DEBUG_MB_TYPE) { + int mb_type = mbtype_table[x + y * mb_stride]; + // Type & MV direction + if (IS_PCM(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "P"); + else if (IS_INTRA(mb_type) && IS_ACPRED(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "A"); + else if (IS_INTRA4x4(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "i"); + else if (IS_INTRA16x16(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "I"); + else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "d"); + else if (IS_DIRECT(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "D"); + else if (IS_GMC(mb_type) && IS_SKIP(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "g"); + else if (IS_GMC(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "G"); + else if (IS_SKIP(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "S"); + else if (!USES_LIST(mb_type, 1)) + av_log(avctx, AV_LOG_DEBUG, ">"); + else if (!USES_LIST(mb_type, 0)) + av_log(avctx, AV_LOG_DEBUG, "<"); + else { + av_assert2(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1)); + av_log(avctx, AV_LOG_DEBUG, "X"); + } + + // segmentation + if (IS_8X8(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "+"); + else if (IS_16X8(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "-"); + else if (IS_8X16(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "|"); + else if (IS_INTRA(mb_type) || IS_16X16(mb_type)) + av_log(avctx, AV_LOG_DEBUG, " "); + else + av_log(avctx, AV_LOG_DEBUG, "?"); + + + if (IS_INTERLACED(mb_type)) + av_log(avctx, AV_LOG_DEBUG, "="); + else + av_log(avctx, AV_LOG_DEBUG, " "); + } + } + av_log(avctx, AV_LOG_DEBUG, "\n"); + } + } + +#if FF_API_DEBUG_MV + if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || + (avctx->debug_mv)) { + int mb_y; + int i, ret; + int h_chroma_shift, v_chroma_shift, block_height; + const int mv_sample_log2 = avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_SVQ3 ? 2 : 1; + const int mv_stride = (mb_width << mv_sample_log2) + + (avctx->codec->id == AV_CODEC_ID_H264 ? 0 : 1); + + if (low_delay) + *low_delay = 0; // needed to see the vectors without trashing the buffers + + ret = av_pix_fmt_get_chroma_sub_sample (avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); + if (ret) + return ret; + + av_frame_make_writable(pict); + + pict->opaque = NULL; + block_height = 16 >> v_chroma_shift; + + for (mb_y = 0; mb_y < mb_height; mb_y++) { + int mb_x; + for (mb_x = 0; mb_x < mb_width; mb_x++) { + const int mb_index = mb_x + mb_y * mb_stride; + if ((avctx->debug & FF_DEBUG_VIS_QP)) { + uint64_t c = (qscale_table[mb_index] * 128 / 31) * + 0x0101010101010101ULL; + int y; + for (y = 0; y < block_height; y++) { + *(uint64_t *)(pict->data[1] + 8 * mb_x + + (block_height * mb_y + y) * + pict->linesize[1]) = c; + *(uint64_t *)(pict->data[2] + 8 * mb_x + + (block_height * mb_y + y) * + pict->linesize[2]) = c; + } + } + if ((avctx->debug & FF_DEBUG_VIS_MB_TYPE) && + motion_val[0]) { + int mb_type = mbtype_table[mb_index]; + uint64_t u,v; + int y; +#define COLOR(theta, r) \ + u = (int)(128 + r * cos(theta * M_PI / 180)); \ + v = (int)(128 + r * sin(theta * M_PI / 180)); + + + u = v = 128; + if (IS_PCM(mb_type)) { + COLOR(120, 48) + } else if ((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) || + IS_INTRA16x16(mb_type)) { + COLOR(30, 48) + } else if (IS_INTRA4x4(mb_type)) { + COLOR(90, 48) + } else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type)) { + // COLOR(120, 48) + } else if (IS_DIRECT(mb_type)) { + COLOR(150, 48) + } else if (IS_GMC(mb_type) && IS_SKIP(mb_type)) { + COLOR(170, 48) + } else if (IS_GMC(mb_type)) { + COLOR(190, 48) + } else if (IS_SKIP(mb_type)) { + // COLOR(180, 48) + } else if (!USES_LIST(mb_type, 1)) { + COLOR(240, 48) + } else if (!USES_LIST(mb_type, 0)) { + COLOR(0, 48) + } else { + av_assert2(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1)); + COLOR(300,48) + } + + u *= 0x0101010101010101ULL; + v *= 0x0101010101010101ULL; + for (y = 0; y < block_height; y++) { + *(uint64_t *)(pict->data[1] + 8 * mb_x + + (block_height * mb_y + y) * pict->linesize[1]) = u; + *(uint64_t *)(pict->data[2] + 8 * mb_x + + (block_height * mb_y + y) * pict->linesize[2]) = v; + } + + // segmentation + if (IS_8X8(mb_type) || IS_16X8(mb_type)) { + *(uint64_t *)(pict->data[0] + 16 * mb_x + 0 + + (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL; + *(uint64_t *)(pict->data[0] + 16 * mb_x + 8 + + (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL; + } + if (IS_8X8(mb_type) || IS_8X16(mb_type)) { + for (y = 0; y < 16; y++) + pict->data[0][16 * mb_x + 8 + (16 * mb_y + y) * + pict->linesize[0]] ^= 0x80; + } + if (IS_8X8(mb_type) && mv_sample_log2 >= 2) { + int dm = 1 << (mv_sample_log2 - 2); + for (i = 0; i < 4; i++) { + int sx = mb_x * 16 + 8 * (i & 1); + int sy = mb_y * 16 + 8 * (i >> 1); + int xy = (mb_x * 2 + (i & 1) + + (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1); + // FIXME bidir + int32_t *mv = (int32_t *) &motion_val[0][xy]; + if (mv[0] != mv[dm] || + mv[dm * mv_stride] != mv[dm * (mv_stride + 1)]) + for (y = 0; y < 8; y++) + pict->data[0][sx + 4 + (sy + y) * pict->linesize[0]] ^= 0x80; + if (mv[0] != mv[dm * mv_stride] || mv[dm] != mv[dm * (mv_stride + 1)]) + *(uint64_t *)(pict->data[0] + sx + (sy + 4) * + pict->linesize[0]) ^= 0x8080808080808080ULL; + } + } + + if (IS_INTERLACED(mb_type) && + avctx->codec->id == AV_CODEC_ID_H264) { + // hmm + } + } + if (mbskip_table) + mbskip_table[mb_index] = 0; + } + } + } +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegutils.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegutils.h new file mode 100644 index 000000000..1ed21c19b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegutils.h @@ -0,0 +1,148 @@ +/* + * Mpeg video formats-related defines and utility functions + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MPEGUTILS_H +#define AVCODEC_MPEGUTILS_H + +#include + +#include "libavutil/frame.h" + +#include "avcodec.h" +#include "version.h" + +/** + * Return value for header parsers if frame is not coded. + * */ +#define FRAME_SKIPPED 100 + +/* picture type */ +#define PICT_TOP_FIELD 1 +#define PICT_BOTTOM_FIELD 2 +#define PICT_FRAME 3 + +/** + * Value of Picture.reference when Picture is not a reference picture, but + * is held for delayed output. + */ +#define DELAYED_PIC_REF 4 + +#define MAX_MB_BYTES (30 * 16 * 16 * 3 / 8 + 120) +#define MAX_FCODE 7 + +/* MB types */ +#define MB_TYPE_INTRA4x4 (1 << 0) +#define MB_TYPE_INTRA16x16 (1 << 1) // FIXME H.264-specific +#define MB_TYPE_INTRA_PCM (1 << 2) // FIXME H.264-specific +#define MB_TYPE_16x16 (1 << 3) +#define MB_TYPE_16x8 (1 << 4) +#define MB_TYPE_8x16 (1 << 5) +#define MB_TYPE_8x8 (1 << 6) +#define MB_TYPE_INTERLACED (1 << 7) +#define MB_TYPE_DIRECT2 (1 << 8) // FIXME +#define MB_TYPE_ACPRED (1 << 9) +#define MB_TYPE_GMC (1 << 10) +#define MB_TYPE_SKIP (1 << 11) +#define MB_TYPE_P0L0 (1 << 12) +#define MB_TYPE_P1L0 (1 << 13) +#define MB_TYPE_P0L1 (1 << 14) +#define MB_TYPE_P1L1 (1 << 15) +#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) +#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) +#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) +#define MB_TYPE_QUANT (1 << 16) +#define MB_TYPE_CBP (1 << 17) + +#define MB_TYPE_INTRA MB_TYPE_INTRA4x4 // default mb_type if there is just one type + +#define IS_INTRA4x4(a) ((a) & MB_TYPE_INTRA4x4) +#define IS_INTRA16x16(a) ((a) & MB_TYPE_INTRA16x16) +#define IS_PCM(a) ((a) & MB_TYPE_INTRA_PCM) +#define IS_INTRA(a) ((a) & 7) +#define IS_INTER(a) ((a) & (MB_TYPE_16x16 | MB_TYPE_16x8 | \ + MB_TYPE_8x16 | MB_TYPE_8x8)) +#define IS_SKIP(a) ((a) & MB_TYPE_SKIP) +#define IS_INTRA_PCM(a) ((a) & MB_TYPE_INTRA_PCM) +#define IS_INTERLACED(a) ((a) & MB_TYPE_INTERLACED) +#define IS_DIRECT(a) ((a) & MB_TYPE_DIRECT2) +#define IS_GMC(a) ((a) & MB_TYPE_GMC) +#define IS_16X16(a) ((a) & MB_TYPE_16x16) +#define IS_16X8(a) ((a) & MB_TYPE_16x8) +#define IS_8X16(a) ((a) & MB_TYPE_8x16) +#define IS_8X8(a) ((a) & MB_TYPE_8x8) +#define IS_SUB_8X8(a) ((a) & MB_TYPE_16x16) // note reused +#define IS_SUB_8X4(a) ((a) & MB_TYPE_16x8) // note reused +#define IS_SUB_4X8(a) ((a) & MB_TYPE_8x16) // note reused +#define IS_SUB_4X4(a) ((a) & MB_TYPE_8x8) // note reused +#define IS_ACPRED(a) ((a) & MB_TYPE_ACPRED) +#define IS_QUANT(a) ((a) & MB_TYPE_QUANT) +#define IS_DIR(a, part, list) ((a) & (MB_TYPE_P0L0 << ((part) + 2 * (list)))) + +// does this mb use listX, note does not work if subMBs +#define USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0 | MB_TYPE_P1L0) << (2 * (list)))) + +#define HAS_CBP(a) ((a) & MB_TYPE_CBP) + +/* MB types for encoding */ +#define CANDIDATE_MB_TYPE_INTRA (1 << 0) +#define CANDIDATE_MB_TYPE_INTER (1 << 1) +#define CANDIDATE_MB_TYPE_INTER4V (1 << 2) +#define CANDIDATE_MB_TYPE_SKIPPED (1 << 3) + +#define CANDIDATE_MB_TYPE_DIRECT (1 << 4) +#define CANDIDATE_MB_TYPE_FORWARD (1 << 5) +#define CANDIDATE_MB_TYPE_BACKWARD (1 << 6) +#define CANDIDATE_MB_TYPE_BIDIR (1 << 7) + +#define CANDIDATE_MB_TYPE_INTER_I (1 << 8) +#define CANDIDATE_MB_TYPE_FORWARD_I (1 << 9) +#define CANDIDATE_MB_TYPE_BACKWARD_I (1 << 10) +#define CANDIDATE_MB_TYPE_BIDIR_I (1 << 11) + +#define CANDIDATE_MB_TYPE_DIRECT0 (1 << 12) + +#define INPLACE_OFFSET 16 + +enum OutputFormat { + FMT_MPEG1, + FMT_H261, + FMT_H263, + FMT_MJPEG, +}; + + +/** + * Draw a horizontal band if supported. + * + * @param h is the normal height, this will be reduced automatically if needed + */ +void ff_draw_horiz_band(AVCodecContext *avctx, AVFrame *cur, AVFrame *last, + int y, int h, int picture_structure, int first_field, + int low_delay); + +/** + * Print debugging info for the given picture. + */ +void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_table, + uint32_t *mbtype_table, int8_t *qscale_table, int16_t (*motion_val[2])[2], + int *low_delay, + int mb_width, int mb_height, int mb_stride, int quarter_sample); + +#endif /* AVCODEC_MPEGUTILS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideo.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideo.c new file mode 100644 index 000000000..dbb6ab9b3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideo.c @@ -0,0 +1,2356 @@ +/* + * The simplest mpeg encoder (well, it was the simplest!) + * Copyright (c) 2000,2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * 4MV & hq & B-frame encoding stuff by Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * The simplest mpeg encoder (well, it was the simplest!). + */ + +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/motion_vector.h" +#include "libavutil/timer.h" +#include "avcodec.h" +#include "blockdsp.h" +#include "h264chroma.h" +#include "idctdsp.h" +#include "internal.h" +#include "mathops.h" +#include "mpeg_er.h" +#include "mpegutils.h" +#include "mpegvideo.h" +#include "mpegvideodata.h" +#include "mjpegenc.h" +#include "msmpeg4.h" +#include "qpeldsp.h" +#include "thread.h" +#include "wmv2.h" +#include + +static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + int i, level, nCoeffs; + const uint16_t *quant_matrix; + + nCoeffs= s->block_last_index[n]; + + block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale; + /* XXX: only MPEG-1 */ + quant_matrix = s->intra_matrix; + for(i=1;i<=nCoeffs;i++) { + int j= s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + if (level < 0) { + level = -level; + level = (int)(level * qscale * quant_matrix[j]) >> 3; + level = (level - 1) | 1; + level = -level; + } else { + level = (int)(level * qscale * quant_matrix[j]) >> 3; + level = (level - 1) | 1; + } + block[j] = level; + } + } +} + +static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + int i, level, nCoeffs; + const uint16_t *quant_matrix; + + nCoeffs= s->block_last_index[n]; + + quant_matrix = s->inter_matrix; + for(i=0; i<=nCoeffs; i++) { + int j= s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + if (level < 0) { + level = -level; + level = (((level << 1) + 1) * qscale * + ((int) (quant_matrix[j]))) >> 4; + level = (level - 1) | 1; + level = -level; + } else { + level = (((level << 1) + 1) * qscale * + ((int) (quant_matrix[j]))) >> 4; + level = (level - 1) | 1; + } + block[j] = level; + } + } +} + +static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + int i, level, nCoeffs; + const uint16_t *quant_matrix; + + if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale]; + else qscale <<= 1; + + if(s->alternate_scan) nCoeffs= 63; + else nCoeffs= s->block_last_index[n]; + + block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale; + quant_matrix = s->intra_matrix; + for(i=1;i<=nCoeffs;i++) { + int j= s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + if (level < 0) { + level = -level; + level = (int)(level * qscale * quant_matrix[j]) >> 4; + level = -level; + } else { + level = (int)(level * qscale * quant_matrix[j]) >> 4; + } + block[j] = level; + } + } +} + +static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + int i, level, nCoeffs; + const uint16_t *quant_matrix; + int sum=-1; + + if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale]; + else qscale <<= 1; + + if(s->alternate_scan) nCoeffs= 63; + else nCoeffs= s->block_last_index[n]; + + block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale; + sum += block[0]; + quant_matrix = s->intra_matrix; + for(i=1;i<=nCoeffs;i++) { + int j= s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + if (level < 0) { + level = -level; + level = (int)(level * qscale * quant_matrix[j]) >> 4; + level = -level; + } else { + level = (int)(level * qscale * quant_matrix[j]) >> 4; + } + block[j] = level; + sum+=level; + } + } + block[63]^=sum&1; +} + +static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + int i, level, nCoeffs; + const uint16_t *quant_matrix; + int sum=-1; + + if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale]; + else qscale <<= 1; + + if(s->alternate_scan) nCoeffs= 63; + else nCoeffs= s->block_last_index[n]; + + quant_matrix = s->inter_matrix; + for(i=0; i<=nCoeffs; i++) { + int j= s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + if (level < 0) { + level = -level; + level = (((level << 1) + 1) * qscale * + ((int) (quant_matrix[j]))) >> 5; + level = -level; + } else { + level = (((level << 1) + 1) * qscale * + ((int) (quant_matrix[j]))) >> 5; + } + block[j] = level; + sum+=level; + } + } + block[63]^=sum&1; +} + +static void dct_unquantize_h263_intra_c(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + int i, level, qmul, qadd; + int nCoeffs; + + av_assert2(s->block_last_index[n]>=0 || s->h263_aic); + + qmul = qscale << 1; + + if (!s->h263_aic) { + block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale; + qadd = (qscale - 1) | 1; + }else{ + qadd = 0; + } + if(s->ac_pred) + nCoeffs=63; + else + nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; + + for(i=1; i<=nCoeffs; i++) { + level = block[i]; + if (level) { + if (level < 0) { + level = level * qmul - qadd; + } else { + level = level * qmul + qadd; + } + block[i] = level; + } + } +} + +static void dct_unquantize_h263_inter_c(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + int i, level, qmul, qadd; + int nCoeffs; + + av_assert2(s->block_last_index[n]>=0); + + qadd = (qscale - 1) | 1; + qmul = qscale << 1; + + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; + + for(i=0; i<=nCoeffs; i++) { + level = block[i]; + if (level) { + if (level < 0) { + level = level * qmul - qadd; + } else { + level = level * qmul + qadd; + } + block[i] = level; + } + } +} + + +static void gray16(uint8_t *dst, const uint8_t *src, ptrdiff_t linesize, int h) +{ + while(h--) + memset(dst + h*linesize, 128, 16); +} + +static void gray8(uint8_t *dst, const uint8_t *src, ptrdiff_t linesize, int h) +{ + while(h--) + memset(dst + h*linesize, 128, 8); +} + +/* init common dct for both encoder and decoder */ +static av_cold int dct_init(MpegEncContext *s) +{ + ff_blockdsp_init(&s->bdsp, s->avctx); + ff_h264chroma_init(&s->h264chroma, 8); //for lowres + ff_hpeldsp_init(&s->hdsp, s->avctx->flags); + ff_mpegvideodsp_init(&s->mdsp); + ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample); + + if (s->avctx->debug & FF_DEBUG_NOMC) { + int i; + for (i=0; i<4; i++) { + s->hdsp.avg_pixels_tab[0][i] = gray16; + s->hdsp.put_pixels_tab[0][i] = gray16; + s->hdsp.put_no_rnd_pixels_tab[0][i] = gray16; + + s->hdsp.avg_pixels_tab[1][i] = gray8; + s->hdsp.put_pixels_tab[1][i] = gray8; + s->hdsp.put_no_rnd_pixels_tab[1][i] = gray8; + } + } + + s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c; + s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c; + s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c; + s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c; + s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c; + if (s->avctx->flags & AV_CODEC_FLAG_BITEXACT) + s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact; + s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c; + + if (HAVE_INTRINSICS_NEON) + ff_mpv_common_init_neon(s); + + if (ARCH_ALPHA) + ff_mpv_common_init_axp(s); + if (ARCH_ARM) + ff_mpv_common_init_arm(s); + if (ARCH_PPC) + ff_mpv_common_init_ppc(s); + if (ARCH_X86) + ff_mpv_common_init_x86(s); + if (ARCH_MIPS) + ff_mpv_common_init_mips(s); + + return 0; +} + +av_cold void ff_mpv_idct_init(MpegEncContext *s) +{ + if (s->codec_id == AV_CODEC_ID_MPEG4) + s->idsp.mpeg4_studio_profile = s->studio_profile; + ff_idctdsp_init(&s->idsp, s->avctx); + + /* load & permutate scantables + * note: only wmv uses different ones + */ + if (s->alternate_scan) { + ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan); + } else { + ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct); + ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct); + } + ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan); + ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); +} + +static int alloc_picture(MpegEncContext *s, Picture *pic, int shared) +{ + return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, shared, 0, + s->chroma_x_shift, s->chroma_y_shift, s->out_format, + s->mb_stride, s->mb_width, s->mb_height, s->b8_stride, + &s->linesize, &s->uvlinesize); +} + +static int init_duplicate_context(MpegEncContext *s) +{ + int y_size = s->b8_stride * (2 * s->mb_height + 1); + int c_size = s->mb_stride * (s->mb_height + 1); + int yc_size = y_size + 2 * c_size; + int i; + + if (s->mb_height & 1) + yc_size += 2*s->b8_stride + 2*s->mb_stride; + + s->sc.edge_emu_buffer = + s->me.scratchpad = + s->me.temp = + s->sc.rd_scratchpad = + s->sc.b_scratchpad = + s->sc.obmc_scratchpad = NULL; + + if (s->encoding) { + FF_ALLOCZ_OR_GOTO(s->avctx, s->me.map, + ME_MAP_SIZE * sizeof(uint32_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->me.score_map, + ME_MAP_SIZE * sizeof(uint32_t), fail) + if (s->noise_reduction) { + FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_error_sum, + 2 * 64 * sizeof(int), fail) + } + } + FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64 * 12 * 2 * sizeof(int16_t), fail) + s->block = s->blocks[0]; + + for (i = 0; i < 12; i++) { + s->pblocks[i] = &s->block[i]; + } + + FF_ALLOCZ_OR_GOTO(s->avctx, s->block32, sizeof(*s->block32), fail) + s->dpcm_direction = 0; + FF_ALLOCZ_OR_GOTO(s->avctx, s->dpcm_macroblock, sizeof(*s->dpcm_macroblock), fail) + + if (s->avctx->codec_tag == AV_RL32("VCR2")) { + // exchange uv + FFSWAP(void *, s->pblocks[4], s->pblocks[5]); + } + + if (s->out_format == FMT_H263) { + /* ac values */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_val_base, + yc_size * sizeof(int16_t) * 16, fail); + s->ac_val[0] = s->ac_val_base + s->b8_stride + 1; + s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1; + s->ac_val[2] = s->ac_val[1] + c_size; + } + + return 0; +fail: + return -1; // free() through ff_mpv_common_end() +} + +static void free_duplicate_context(MpegEncContext *s) +{ + if (!s) + return; + + av_freep(&s->sc.edge_emu_buffer); + av_freep(&s->me.scratchpad); + s->me.temp = + s->sc.rd_scratchpad = + s->sc.b_scratchpad = + s->sc.obmc_scratchpad = NULL; + + av_freep(&s->dct_error_sum); + av_freep(&s->me.map); + av_freep(&s->me.score_map); + av_freep(&s->blocks); + av_freep(&s->block32); + av_freep(&s->dpcm_macroblock); + av_freep(&s->ac_val_base); + s->block = NULL; +} + +static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src) +{ +#define COPY(a) bak->a = src->a + COPY(sc.edge_emu_buffer); + COPY(me.scratchpad); + COPY(me.temp); + COPY(sc.rd_scratchpad); + COPY(sc.b_scratchpad); + COPY(sc.obmc_scratchpad); + COPY(me.map); + COPY(me.score_map); + COPY(blocks); + COPY(block); + COPY(block32); + COPY(dpcm_macroblock); + COPY(dpcm_direction); + COPY(start_mb_y); + COPY(end_mb_y); + COPY(me.map_generation); + COPY(pb); + COPY(dct_error_sum); + COPY(dct_count[0]); + COPY(dct_count[1]); + COPY(ac_val_base); + COPY(ac_val[0]); + COPY(ac_val[1]); + COPY(ac_val[2]); +#undef COPY +} + +int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src) +{ + MpegEncContext bak; + int i, ret; + // FIXME copy only needed parts + // START_TIMER + backup_duplicate_context(&bak, dst); + memcpy(dst, src, sizeof(MpegEncContext)); + backup_duplicate_context(dst, &bak); + for (i = 0; i < 12; i++) { + dst->pblocks[i] = &dst->block[i]; + } + if (dst->avctx->codec_tag == AV_RL32("VCR2")) { + // exchange uv + FFSWAP(void *, dst->pblocks[4], dst->pblocks[5]); + } + if (!dst->sc.edge_emu_buffer && + (ret = ff_mpeg_framesize_alloc(dst->avctx, &dst->me, + &dst->sc, dst->linesize)) < 0) { + av_log(dst->avctx, AV_LOG_ERROR, "failed to allocate context " + "scratch buffers.\n"); + return ret; + } + // STOP_TIMER("update_duplicate_context") + // about 10k cycles / 0.01 sec for 1000frames on 1ghz with 2 threads + return 0; +} + +int ff_mpeg_update_thread_context(AVCodecContext *dst, + const AVCodecContext *src) +{ + int i, ret; + MpegEncContext *s = dst->priv_data, *s1 = src->priv_data; + + if (dst == src) + return 0; + + av_assert0(s != s1); + + // FIXME can parameters change on I-frames? + // in that case dst may need a reinit + if (!s->context_initialized) { + int err; + memcpy(s, s1, sizeof(MpegEncContext)); + + s->avctx = dst; + s->bitstream_buffer = NULL; + s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0; + + if (s1->context_initialized){ +// s->picture_range_start += MAX_PICTURE_COUNT; +// s->picture_range_end += MAX_PICTURE_COUNT; + ff_mpv_idct_init(s); + if((err = ff_mpv_common_init(s)) < 0){ + memset(s, 0, sizeof(MpegEncContext)); + s->avctx = dst; + return err; + } + } + } + + if (s->height != s1->height || s->width != s1->width || s->context_reinit) { + s->context_reinit = 0; + s->height = s1->height; + s->width = s1->width; + if ((ret = ff_mpv_common_frame_size_change(s)) < 0) + return ret; + } + + s->avctx->coded_height = s1->avctx->coded_height; + s->avctx->coded_width = s1->avctx->coded_width; + s->avctx->width = s1->avctx->width; + s->avctx->height = s1->avctx->height; + + s->quarter_sample = s1->quarter_sample; + + s->coded_picture_number = s1->coded_picture_number; + s->picture_number = s1->picture_number; + + av_assert0(!s->picture || s->picture != s1->picture); + if(s->picture) + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + ff_mpeg_unref_picture(s->avctx, &s->picture[i]); + if (s1->picture && s1->picture[i].f->buf[0] && + (ret = ff_mpeg_ref_picture(s->avctx, &s->picture[i], &s1->picture[i])) < 0) + return ret; + } + +#define UPDATE_PICTURE(pic)\ +do {\ + ff_mpeg_unref_picture(s->avctx, &s->pic);\ + if (s1->pic.f && s1->pic.f->buf[0])\ + ret = ff_mpeg_ref_picture(s->avctx, &s->pic, &s1->pic);\ + else\ + ret = ff_update_picture_tables(&s->pic, &s1->pic);\ + if (ret < 0)\ + return ret;\ +} while (0) + + UPDATE_PICTURE(current_picture); + UPDATE_PICTURE(last_picture); + UPDATE_PICTURE(next_picture); + +#define REBASE_PICTURE(pic, new_ctx, old_ctx) \ + ((pic && pic >= old_ctx->picture && \ + pic < old_ctx->picture + MAX_PICTURE_COUNT) ? \ + &new_ctx->picture[pic - old_ctx->picture] : NULL) + + s->last_picture_ptr = REBASE_PICTURE(s1->last_picture_ptr, s, s1); + s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1); + s->next_picture_ptr = REBASE_PICTURE(s1->next_picture_ptr, s, s1); + + // Error/bug resilience + s->next_p_frame_damaged = s1->next_p_frame_damaged; + s->workaround_bugs = s1->workaround_bugs; + s->padding_bug_score = s1->padding_bug_score; + + // MPEG-4 timing info + memcpy(&s->last_time_base, &s1->last_time_base, + (char *) &s1->pb_field_time + sizeof(s1->pb_field_time) - + (char *) &s1->last_time_base); + + // B-frame info + s->max_b_frames = s1->max_b_frames; + s->low_delay = s1->low_delay; + s->droppable = s1->droppable; + + // DivX handling (doesn't work) + s->divx_packed = s1->divx_packed; + + if (s1->bitstream_buffer) { + if (s1->bitstream_buffer_size + + AV_INPUT_BUFFER_PADDING_SIZE > s->allocated_bitstream_buffer_size) { + av_fast_malloc(&s->bitstream_buffer, + &s->allocated_bitstream_buffer_size, + s1->allocated_bitstream_buffer_size); + if (!s->bitstream_buffer) { + s->bitstream_buffer_size = 0; + return AVERROR(ENOMEM); + } + } + s->bitstream_buffer_size = s1->bitstream_buffer_size; + memcpy(s->bitstream_buffer, s1->bitstream_buffer, + s1->bitstream_buffer_size); + memset(s->bitstream_buffer + s->bitstream_buffer_size, 0, + AV_INPUT_BUFFER_PADDING_SIZE); + } + + // linesize-dependent scratch buffer allocation + if (!s->sc.edge_emu_buffer) + if (s1->linesize) { + if (ff_mpeg_framesize_alloc(s->avctx, &s->me, + &s->sc, s1->linesize) < 0) { + av_log(s->avctx, AV_LOG_ERROR, "Failed to allocate context " + "scratch buffers.\n"); + return AVERROR(ENOMEM); + } + } else { + av_log(s->avctx, AV_LOG_ERROR, "Context scratch buffers could not " + "be allocated due to unknown size.\n"); + } + + // MPEG-2/interlacing info + memcpy(&s->progressive_sequence, &s1->progressive_sequence, + (char *) &s1->rtp_mode - (char *) &s1->progressive_sequence); + + if (!s1->first_field) { + s->last_pict_type = s1->pict_type; + if (s1->current_picture_ptr) + s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->f->quality; + } + + return 0; +} + +/** + * Set the given MpegEncContext to common defaults + * (same for encoding and decoding). + * The changed fields will not depend upon the + * prior state of the MpegEncContext. + */ +void ff_mpv_common_defaults(MpegEncContext *s) +{ + s->y_dc_scale_table = + s->c_dc_scale_table = ff_mpeg1_dc_scale_table; + s->chroma_qscale_table = ff_default_chroma_qscale_table; + s->progressive_frame = 1; + s->progressive_sequence = 1; + s->picture_structure = PICT_FRAME; + + s->coded_picture_number = 0; + s->picture_number = 0; + + s->f_code = 1; + s->b_code = 1; + + s->slice_context_count = 1; +} + +/** + * Set the given MpegEncContext to defaults for decoding. + * the changed fields will not depend upon + * the prior state of the MpegEncContext. + */ +void ff_mpv_decode_defaults(MpegEncContext *s) +{ + ff_mpv_common_defaults(s); +} + +void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx) +{ + s->avctx = avctx; + s->width = avctx->coded_width; + s->height = avctx->coded_height; + s->codec_id = avctx->codec->id; + s->workaround_bugs = avctx->workaround_bugs; + + /* convert fourcc to upper case */ + s->codec_tag = avpriv_toupper4(avctx->codec_tag); +} + +/** + * Initialize and allocates MpegEncContext fields dependent on the resolution. + */ +static int init_context_frame(MpegEncContext *s) +{ + int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; + + s->mb_width = (s->width + 15) / 16; + s->mb_stride = s->mb_width + 1; + s->b8_stride = s->mb_width * 2 + 1; + mb_array_size = s->mb_height * s->mb_stride; + mv_table_size = (s->mb_height + 2) * s->mb_stride + 1; + + /* set default edge pos, will be overridden + * in decode_header if needed */ + s->h_edge_pos = s->mb_width * 16; + s->v_edge_pos = s->mb_height * 16; + + s->mb_num = s->mb_width * s->mb_height; + + s->block_wrap[0] = + s->block_wrap[1] = + s->block_wrap[2] = + s->block_wrap[3] = s->b8_stride; + s->block_wrap[4] = + s->block_wrap[5] = s->mb_stride; + + y_size = s->b8_stride * (2 * s->mb_height + 1); + c_size = s->mb_stride * (s->mb_height + 1); + yc_size = y_size + 2 * c_size; + + if (s->mb_height & 1) + yc_size += 2*s->b8_stride + 2*s->mb_stride; + + FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int), + fail); // error resilience code looks cleaner with this + for (y = 0; y < s->mb_height; y++) + for (x = 0; x < s->mb_width; x++) + s->mb_index2xy[x + y * s->mb_width] = x + y * s->mb_stride; + + s->mb_index2xy[s->mb_height * s->mb_width] = (s->mb_height - 1) * s->mb_stride + s->mb_width; // FIXME really needed? + + if (s->encoding) { + /* Allocate MV tables */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) + s->p_mv_table = s->p_mv_table_base + s->mb_stride + 1; + s->b_forw_mv_table = s->b_forw_mv_table_base + s->mb_stride + 1; + s->b_back_mv_table = s->b_back_mv_table_base + s->mb_stride + 1; + s->b_bidir_forw_mv_table = s->b_bidir_forw_mv_table_base + s->mb_stride + 1; + s->b_bidir_back_mv_table = s->b_bidir_back_mv_table_base + s->mb_stride + 1; + s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1; + + /* Allocate MB type table */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type, mb_array_size * sizeof(uint16_t), fail) // needed for encoding + + FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail) + + FF_ALLOC_OR_GOTO(s->avctx, s->cplx_tab, + mb_array_size * sizeof(float), fail); + FF_ALLOC_OR_GOTO(s->avctx, s->bits_tab, + mb_array_size * sizeof(float), fail); + + } + + if (s->codec_id == AV_CODEC_ID_MPEG4 || + (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) { + /* interlaced direct mode decoding tables */ + for (i = 0; i < 2; i++) { + int j, k; + for (j = 0; j < 2; j++) { + for (k = 0; k < 2; k++) { + FF_ALLOCZ_OR_GOTO(s->avctx, + s->b_field_mv_table_base[i][j][k], + mv_table_size * 2 * sizeof(int16_t), + fail); + s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + + s->mb_stride + 1; + } + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], mb_array_size * 2 * sizeof(uint8_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], mv_table_size * 2 * sizeof(int16_t), fail) + s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + s->mb_stride + 1; + } + FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], mb_array_size * 2 * sizeof(uint8_t), fail) + } + } + if (s->out_format == FMT_H263) { + /* cbp values */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->coded_block_base, y_size + (s->mb_height&1)*2*s->b8_stride, fail); + s->coded_block = s->coded_block_base + s->b8_stride + 1; + + /* cbp, ac_pred, pred_dir */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table , mb_array_size * sizeof(uint8_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size * sizeof(uint8_t), fail); + } + + if (s->h263_pred || s->h263_plus || !s->encoding) { + /* dc values */ + // MN: we need these for error resilience of intra-frames + FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail); + s->dc_val[0] = s->dc_val_base + s->b8_stride + 1; + s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1; + s->dc_val[2] = s->dc_val[1] + c_size; + for (i = 0; i < yc_size; i++) + s->dc_val_base[i] = 1024; + } + + /* which mb is an intra block */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->mbintra_table, mb_array_size, fail); + memset(s->mbintra_table, 1, mb_array_size); + + /* init macroblock skip table */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size + 2, fail); + // Note the + 1 is for a quicker MPEG-4 slice_end detection + + return ff_mpeg_er_init(s); +fail: + return AVERROR(ENOMEM); +} + +static void clear_context(MpegEncContext *s) +{ + int i, j, k; + + memset(&s->next_picture, 0, sizeof(s->next_picture)); + memset(&s->last_picture, 0, sizeof(s->last_picture)); + memset(&s->current_picture, 0, sizeof(s->current_picture)); + memset(&s->new_picture, 0, sizeof(s->new_picture)); + + memset(s->thread_context, 0, sizeof(s->thread_context)); + + s->me.map = NULL; + s->me.score_map = NULL; + s->dct_error_sum = NULL; + s->block = NULL; + s->blocks = NULL; + s->block32 = NULL; + memset(s->pblocks, 0, sizeof(s->pblocks)); + s->dpcm_direction = 0; + s->dpcm_macroblock = NULL; + s->ac_val_base = NULL; + s->ac_val[0] = + s->ac_val[1] = + s->ac_val[2] =NULL; + s->sc.edge_emu_buffer = NULL; + s->me.scratchpad = NULL; + s->me.temp = + s->sc.rd_scratchpad = + s->sc.b_scratchpad = + s->sc.obmc_scratchpad = NULL; + + + s->bitstream_buffer = NULL; + s->allocated_bitstream_buffer_size = 0; + s->picture = NULL; + s->mb_type = NULL; + s->p_mv_table_base = NULL; + s->b_forw_mv_table_base = NULL; + s->b_back_mv_table_base = NULL; + s->b_bidir_forw_mv_table_base = NULL; + s->b_bidir_back_mv_table_base = NULL; + s->b_direct_mv_table_base = NULL; + s->p_mv_table = NULL; + s->b_forw_mv_table = NULL; + s->b_back_mv_table = NULL; + s->b_bidir_forw_mv_table = NULL; + s->b_bidir_back_mv_table = NULL; + s->b_direct_mv_table = NULL; + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (k = 0; k < 2; k++) { + s->b_field_mv_table_base[i][j][k] = NULL; + s->b_field_mv_table[i][j][k] = NULL; + } + s->b_field_select_table[i][j] = NULL; + s->p_field_mv_table_base[i][j] = NULL; + s->p_field_mv_table[i][j] = NULL; + } + s->p_field_select_table[i] = NULL; + } + + s->dc_val_base = NULL; + s->coded_block_base = NULL; + s->mbintra_table = NULL; + s->cbp_table = NULL; + s->pred_dir_table = NULL; + + s->mbskip_table = NULL; + + s->er.error_status_table = NULL; + s->er.er_temp_buffer = NULL; + s->mb_index2xy = NULL; + s->lambda_table = NULL; + + s->cplx_tab = NULL; + s->bits_tab = NULL; +} + +/** + * init common structure for both encoder and decoder. + * this assumes that some variables like width/height are already set + */ +av_cold int ff_mpv_common_init(MpegEncContext *s) +{ + int i, ret; + int nb_slices = (HAVE_THREADS && + s->avctx->active_thread_type & FF_THREAD_SLICE) ? + s->avctx->thread_count : 1; + + clear_context(s); + + if (s->encoding && s->avctx->slices) + nb_slices = s->avctx->slices; + + if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) + s->mb_height = (s->height + 31) / 32 * 2; + else + s->mb_height = (s->height + 15) / 16; + + if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) { + av_log(s->avctx, AV_LOG_ERROR, + "decoding to AV_PIX_FMT_NONE is not supported.\n"); + return -1; + } + + if (nb_slices > MAX_THREADS || (nb_slices > s->mb_height && s->mb_height)) { + int max_slices; + if (s->mb_height) + max_slices = FFMIN(MAX_THREADS, s->mb_height); + else + max_slices = MAX_THREADS; + av_log(s->avctx, AV_LOG_WARNING, "too many threads/slices (%d)," + " reducing to %d\n", nb_slices, max_slices); + nb_slices = max_slices; + } + + if ((s->width || s->height) && + av_image_check_size(s->width, s->height, 0, s->avctx)) + return -1; + + dct_init(s); + + /* set chroma shifts */ + ret = av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, + &s->chroma_x_shift, + &s->chroma_y_shift); + if (ret) + return ret; + + FF_ALLOCZ_OR_GOTO(s->avctx, s->picture, + MAX_PICTURE_COUNT * sizeof(Picture), fail); + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + s->picture[i].f = av_frame_alloc(); + if (!s->picture[i].f) + goto fail; + } + s->next_picture.f = av_frame_alloc(); + if (!s->next_picture.f) + goto fail; + s->last_picture.f = av_frame_alloc(); + if (!s->last_picture.f) + goto fail; + s->current_picture.f = av_frame_alloc(); + if (!s->current_picture.f) + goto fail; + s->new_picture.f = av_frame_alloc(); + if (!s->new_picture.f) + goto fail; + + if (init_context_frame(s)) + goto fail; + + s->parse_context.state = -1; + + s->context_initialized = 1; + memset(s->thread_context, 0, sizeof(s->thread_context)); + s->thread_context[0] = s; + +// if (s->width && s->height) { + if (nb_slices > 1) { + for (i = 0; i < nb_slices; i++) { + if (i) { + s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); + if (!s->thread_context[i]) + goto fail; + } + if (init_duplicate_context(s->thread_context[i]) < 0) + goto fail; + s->thread_context[i]->start_mb_y = + (s->mb_height * (i) + nb_slices / 2) / nb_slices; + s->thread_context[i]->end_mb_y = + (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; + } + } else { + if (init_duplicate_context(s) < 0) + goto fail; + s->start_mb_y = 0; + s->end_mb_y = s->mb_height; + } + s->slice_context_count = nb_slices; +// } + + return 0; + fail: + ff_mpv_common_end(s); + return -1; +} + +/** + * Frees and resets MpegEncContext fields depending on the resolution. + * Is used during resolution changes to avoid a full reinitialization of the + * codec. + */ +static void free_context_frame(MpegEncContext *s) +{ + int i, j, k; + + av_freep(&s->mb_type); + av_freep(&s->p_mv_table_base); + av_freep(&s->b_forw_mv_table_base); + av_freep(&s->b_back_mv_table_base); + av_freep(&s->b_bidir_forw_mv_table_base); + av_freep(&s->b_bidir_back_mv_table_base); + av_freep(&s->b_direct_mv_table_base); + s->p_mv_table = NULL; + s->b_forw_mv_table = NULL; + s->b_back_mv_table = NULL; + s->b_bidir_forw_mv_table = NULL; + s->b_bidir_back_mv_table = NULL; + s->b_direct_mv_table = NULL; + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (k = 0; k < 2; k++) { + av_freep(&s->b_field_mv_table_base[i][j][k]); + s->b_field_mv_table[i][j][k] = NULL; + } + av_freep(&s->b_field_select_table[i][j]); + av_freep(&s->p_field_mv_table_base[i][j]); + s->p_field_mv_table[i][j] = NULL; + } + av_freep(&s->p_field_select_table[i]); + } + + av_freep(&s->dc_val_base); + av_freep(&s->coded_block_base); + av_freep(&s->mbintra_table); + av_freep(&s->cbp_table); + av_freep(&s->pred_dir_table); + + av_freep(&s->mbskip_table); + + av_freep(&s->er.error_status_table); + av_freep(&s->er.er_temp_buffer); + av_freep(&s->mb_index2xy); + av_freep(&s->lambda_table); + + av_freep(&s->cplx_tab); + av_freep(&s->bits_tab); + + s->linesize = s->uvlinesize = 0; +} + +int ff_mpv_common_frame_size_change(MpegEncContext *s) +{ + int i, err = 0; + + if (!s->context_initialized) + return AVERROR(EINVAL); + + if (s->slice_context_count > 1) { + for (i = 0; i < s->slice_context_count; i++) { + free_duplicate_context(s->thread_context[i]); + } + for (i = 1; i < s->slice_context_count; i++) { + av_freep(&s->thread_context[i]); + } + } else + free_duplicate_context(s); + + free_context_frame(s); + + if (s->picture) + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + s->picture[i].needs_realloc = 1; + } + + s->last_picture_ptr = + s->next_picture_ptr = + s->current_picture_ptr = NULL; + + // init + if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) + s->mb_height = (s->height + 31) / 32 * 2; + else + s->mb_height = (s->height + 15) / 16; + + if ((s->width || s->height) && + (err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) + goto fail; + + if ((err = init_context_frame(s))) + goto fail; + + memset(s->thread_context, 0, sizeof(s->thread_context)); + s->thread_context[0] = s; + + if (s->width && s->height) { + int nb_slices = s->slice_context_count; + if (nb_slices > 1) { + for (i = 0; i < nb_slices; i++) { + if (i) { + s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); + if (!s->thread_context[i]) { + err = AVERROR(ENOMEM); + goto fail; + } + } + if ((err = init_duplicate_context(s->thread_context[i])) < 0) + goto fail; + s->thread_context[i]->start_mb_y = + (s->mb_height * (i) + nb_slices / 2) / nb_slices; + s->thread_context[i]->end_mb_y = + (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; + } + } else { + err = init_duplicate_context(s); + if (err < 0) + goto fail; + s->start_mb_y = 0; + s->end_mb_y = s->mb_height; + } + s->slice_context_count = nb_slices; + } + + return 0; + fail: + ff_mpv_common_end(s); + return err; +} + +/* init common structure for both encoder and decoder */ +void ff_mpv_common_end(MpegEncContext *s) +{ + int i; + + if (!s) + return ; + + if (s->slice_context_count > 1) { + for (i = 0; i < s->slice_context_count; i++) { + free_duplicate_context(s->thread_context[i]); + } + for (i = 1; i < s->slice_context_count; i++) { + av_freep(&s->thread_context[i]); + } + s->slice_context_count = 1; + } else free_duplicate_context(s); + + av_freep(&s->parse_context.buffer); + s->parse_context.buffer_size = 0; + + av_freep(&s->bitstream_buffer); + s->allocated_bitstream_buffer_size = 0; + + if (s->picture) { + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + ff_free_picture_tables(&s->picture[i]); + ff_mpeg_unref_picture(s->avctx, &s->picture[i]); + av_frame_free(&s->picture[i].f); + } + } + av_freep(&s->picture); + ff_free_picture_tables(&s->last_picture); + ff_mpeg_unref_picture(s->avctx, &s->last_picture); + av_frame_free(&s->last_picture.f); + ff_free_picture_tables(&s->current_picture); + ff_mpeg_unref_picture(s->avctx, &s->current_picture); + av_frame_free(&s->current_picture.f); + ff_free_picture_tables(&s->next_picture); + ff_mpeg_unref_picture(s->avctx, &s->next_picture); + av_frame_free(&s->next_picture.f); + ff_free_picture_tables(&s->new_picture); + ff_mpeg_unref_picture(s->avctx, &s->new_picture); + av_frame_free(&s->new_picture.f); + + free_context_frame(s); + + s->context_initialized = 0; + s->last_picture_ptr = + s->next_picture_ptr = + s->current_picture_ptr = NULL; + s->linesize = s->uvlinesize = 0; +} + + +static void gray_frame(AVFrame *frame) +{ + int i, h_chroma_shift, v_chroma_shift; + + av_pix_fmt_get_chroma_sub_sample(frame->format, &h_chroma_shift, &v_chroma_shift); + + for(i=0; iheight; i++) + memset(frame->data[0] + frame->linesize[0]*i, 0x80, frame->width); + for(i=0; iheight, v_chroma_shift); i++) { + memset(frame->data[1] + frame->linesize[1]*i, + 0x80, AV_CEIL_RSHIFT(frame->width, h_chroma_shift)); + memset(frame->data[2] + frame->linesize[2]*i, + 0x80, AV_CEIL_RSHIFT(frame->width, h_chroma_shift)); + } +} + +/** + * generic function called after decoding + * the header and before a frame is decoded. + */ +int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx) +{ + int i, ret; + Picture *pic; + s->mb_skipped = 0; + + if (!ff_thread_can_start_frame(avctx)) { + av_log(avctx, AV_LOG_ERROR, "Attempt to start a frame outside SETUP state\n"); + return -1; + } + + /* mark & release old frames */ + if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && + s->last_picture_ptr != s->next_picture_ptr && + s->last_picture_ptr->f->buf[0]) { + ff_mpeg_unref_picture(s->avctx, s->last_picture_ptr); + } + + /* release forgotten pictures */ + /* if (MPEG-124 / H.263) */ + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (&s->picture[i] != s->last_picture_ptr && + &s->picture[i] != s->next_picture_ptr && + s->picture[i].reference && !s->picture[i].needs_realloc) { + ff_mpeg_unref_picture(s->avctx, &s->picture[i]); + } + } + + ff_mpeg_unref_picture(s->avctx, &s->current_picture); + ff_mpeg_unref_picture(s->avctx, &s->last_picture); + ff_mpeg_unref_picture(s->avctx, &s->next_picture); + + /* release non reference frames */ + for (i = 0; i < MAX_PICTURE_COUNT; i++) { + if (!s->picture[i].reference) + ff_mpeg_unref_picture(s->avctx, &s->picture[i]); + } + + if (s->current_picture_ptr && !s->current_picture_ptr->f->buf[0]) { + // we already have an unused image + // (maybe it was set before reading the header) + pic = s->current_picture_ptr; + } else { + i = ff_find_unused_picture(s->avctx, s->picture, 0); + if (i < 0) { + av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n"); + return i; + } + pic = &s->picture[i]; + } + + pic->reference = 0; + if (!s->droppable) { + if (s->pict_type != AV_PICTURE_TYPE_B) + pic->reference = 3; + } + + pic->f->coded_picture_number = s->coded_picture_number++; + + if (alloc_picture(s, pic, 0) < 0) + return -1; + + s->current_picture_ptr = pic; + // FIXME use only the vars from current_pic + s->current_picture_ptr->f->top_field_first = s->top_field_first; + if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO || + s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { + if (s->picture_structure != PICT_FRAME) + s->current_picture_ptr->f->top_field_first = + (s->picture_structure == PICT_TOP_FIELD) == s->first_field; + } + s->current_picture_ptr->f->interlaced_frame = !s->progressive_frame && + !s->progressive_sequence; + s->current_picture_ptr->field_picture = s->picture_structure != PICT_FRAME; + + s->current_picture_ptr->f->pict_type = s->pict_type; + // if (s->avctx->flags && AV_CODEC_FLAG_QSCALE) + // s->current_picture_ptr->quality = s->new_picture_ptr->quality; + s->current_picture_ptr->f->key_frame = s->pict_type == AV_PICTURE_TYPE_I; + + if ((ret = ff_mpeg_ref_picture(s->avctx, &s->current_picture, + s->current_picture_ptr)) < 0) + return ret; + + if (s->pict_type != AV_PICTURE_TYPE_B) { + s->last_picture_ptr = s->next_picture_ptr; + if (!s->droppable) + s->next_picture_ptr = s->current_picture_ptr; + } + ff_dlog(s->avctx, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n", + s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr, + s->last_picture_ptr ? s->last_picture_ptr->f->data[0] : NULL, + s->next_picture_ptr ? s->next_picture_ptr->f->data[0] : NULL, + s->current_picture_ptr ? s->current_picture_ptr->f->data[0] : NULL, + s->pict_type, s->droppable); + + if ((!s->last_picture_ptr || !s->last_picture_ptr->f->buf[0]) && + (s->pict_type != AV_PICTURE_TYPE_I)) { + int h_chroma_shift, v_chroma_shift; + av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, + &h_chroma_shift, &v_chroma_shift); + if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f->buf[0]) + av_log(avctx, AV_LOG_DEBUG, + "allocating dummy last picture for B frame\n"); + else if (s->pict_type != AV_PICTURE_TYPE_I) + av_log(avctx, AV_LOG_ERROR, + "warning: first frame is no keyframe\n"); + + /* Allocate a dummy frame */ + i = ff_find_unused_picture(s->avctx, s->picture, 0); + if (i < 0) { + av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n"); + return i; + } + s->last_picture_ptr = &s->picture[i]; + + s->last_picture_ptr->reference = 3; + s->last_picture_ptr->f->key_frame = 0; + s->last_picture_ptr->f->pict_type = AV_PICTURE_TYPE_P; + + if (alloc_picture(s, s->last_picture_ptr, 0) < 0) { + s->last_picture_ptr = NULL; + return -1; + } + + if (!avctx->hwaccel) { + for(i=0; iheight; i++) + memset(s->last_picture_ptr->f->data[0] + s->last_picture_ptr->f->linesize[0]*i, + 0x80, avctx->width); + if (s->last_picture_ptr->f->data[2]) { + for(i=0; iheight, v_chroma_shift); i++) { + memset(s->last_picture_ptr->f->data[1] + s->last_picture_ptr->f->linesize[1]*i, + 0x80, AV_CEIL_RSHIFT(avctx->width, h_chroma_shift)); + memset(s->last_picture_ptr->f->data[2] + s->last_picture_ptr->f->linesize[2]*i, + 0x80, AV_CEIL_RSHIFT(avctx->width, h_chroma_shift)); + } + } + + if(s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263){ + for(i=0; iheight; i++) + memset(s->last_picture_ptr->f->data[0] + s->last_picture_ptr->f->linesize[0]*i, 16, avctx->width); + } + } + + ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 0); + ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1); + } + if ((!s->next_picture_ptr || !s->next_picture_ptr->f->buf[0]) && + s->pict_type == AV_PICTURE_TYPE_B) { + /* Allocate a dummy frame */ + i = ff_find_unused_picture(s->avctx, s->picture, 0); + if (i < 0) { + av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n"); + return i; + } + s->next_picture_ptr = &s->picture[i]; + + s->next_picture_ptr->reference = 3; + s->next_picture_ptr->f->key_frame = 0; + s->next_picture_ptr->f->pict_type = AV_PICTURE_TYPE_P; + + if (alloc_picture(s, s->next_picture_ptr, 0) < 0) { + s->next_picture_ptr = NULL; + return -1; + } + ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 0); + ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 1); + } + +#if 0 // BUFREF-FIXME + memset(s->last_picture.f->data, 0, sizeof(s->last_picture.f->data)); + memset(s->next_picture.f->data, 0, sizeof(s->next_picture.f->data)); +#endif + if (s->last_picture_ptr) { + if (s->last_picture_ptr->f->buf[0] && + (ret = ff_mpeg_ref_picture(s->avctx, &s->last_picture, + s->last_picture_ptr)) < 0) + return ret; + } + if (s->next_picture_ptr) { + if (s->next_picture_ptr->f->buf[0] && + (ret = ff_mpeg_ref_picture(s->avctx, &s->next_picture, + s->next_picture_ptr)) < 0) + return ret; + } + + av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && + s->last_picture_ptr->f->buf[0])); + + if (s->picture_structure!= PICT_FRAME) { + int i; + for (i = 0; i < 4; i++) { + if (s->picture_structure == PICT_BOTTOM_FIELD) { + s->current_picture.f->data[i] += + s->current_picture.f->linesize[i]; + } + s->current_picture.f->linesize[i] *= 2; + s->last_picture.f->linesize[i] *= 2; + s->next_picture.f->linesize[i] *= 2; + } + } + + /* set dequantizer, we can't do it during init as + * it might change for MPEG-4 and we can't do it in the header + * decode as init is not called for MPEG-4 there yet */ + if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { + s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra; + s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter; + } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) { + s->dct_unquantize_intra = s->dct_unquantize_h263_intra; + s->dct_unquantize_inter = s->dct_unquantize_h263_inter; + } else { + s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra; + s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter; + } + + if (s->avctx->debug & FF_DEBUG_NOMC) { + gray_frame(s->current_picture_ptr->f); + } + + return 0; +} + +/* called after a frame has been decoded. */ +void ff_mpv_frame_end(MpegEncContext *s) +{ + emms_c(); + + if (s->current_picture.reference) + ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0); +} + +void ff_print_debug_info(MpegEncContext *s, Picture *p, AVFrame *pict) +{ + ff_print_debug_info2(s->avctx, pict, s->mbskip_table, p->mb_type, + p->qscale_table, p->motion_val, &s->low_delay, + s->mb_width, s->mb_height, s->mb_stride, s->quarter_sample); +} + +int ff_mpv_export_qp_table(MpegEncContext *s, AVFrame *f, Picture *p, int qp_type) +{ + AVBufferRef *ref = av_buffer_ref(p->qscale_table_buf); + int offset = 2*s->mb_stride + 1; + if(!ref) + return AVERROR(ENOMEM); + av_assert0(ref->size >= offset + s->mb_stride * ((f->height+15)/16)); + ref->size -= offset; + ref->data += offset; + return av_frame_set_qp_table(f, ref, s->mb_stride, qp_type); +} + +static inline int hpel_motion_lowres(MpegEncContext *s, + uint8_t *dest, uint8_t *src, + int field_based, int field_select, + int src_x, int src_y, + int width, int height, ptrdiff_t stride, + int h_edge_pos, int v_edge_pos, + int w, int h, h264_chroma_mc_func *pix_op, + int motion_x, int motion_y) +{ + const int lowres = s->avctx->lowres; + const int op_index = FFMIN(lowres, 3); + const int s_mask = (2 << lowres) - 1; + int emu = 0; + int sx, sy; + + if (s->quarter_sample) { + motion_x /= 2; + motion_y /= 2; + } + + sx = motion_x & s_mask; + sy = motion_y & s_mask; + src_x += motion_x >> lowres + 1; + src_y += motion_y >> lowres + 1; + + src += src_y * stride + src_x; + + if ((unsigned)src_x > FFMAX( h_edge_pos - (!!sx) - w, 0) || + (unsigned)src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src, + s->linesize, s->linesize, + w + 1, (h + 1) << field_based, + src_x, src_y << field_based, + h_edge_pos, v_edge_pos); + src = s->sc.edge_emu_buffer; + emu = 1; + } + + sx = (sx << 2) >> lowres; + sy = (sy << 2) >> lowres; + if (field_select) + src += s->linesize; + pix_op[op_index](dest, src, stride, h, sx, sy); + return emu; +} + +/* apply one mpeg motion vector to the three components */ +static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, + uint8_t *dest_y, + uint8_t *dest_cb, + uint8_t *dest_cr, + int field_based, + int bottom_field, + int field_select, + uint8_t **ref_picture, + h264_chroma_mc_func *pix_op, + int motion_x, int motion_y, + int h, int mb_y) +{ + uint8_t *ptr_y, *ptr_cb, *ptr_cr; + int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, sx, sy, uvsx, uvsy; + ptrdiff_t uvlinesize, linesize; + const int lowres = s->avctx->lowres; + const int op_index = FFMIN(lowres-1+s->chroma_x_shift, 3); + const int block_s = 8>>lowres; + const int s_mask = (2 << lowres) - 1; + const int h_edge_pos = s->h_edge_pos >> lowres; + const int v_edge_pos = s->v_edge_pos >> lowres; + linesize = s->current_picture.f->linesize[0] << field_based; + uvlinesize = s->current_picture.f->linesize[1] << field_based; + + // FIXME obviously not perfect but qpel will not work in lowres anyway + if (s->quarter_sample) { + motion_x /= 2; + motion_y /= 2; + } + + if(field_based){ + motion_y += (bottom_field - field_select)*((1 << lowres)-1); + } + + sx = motion_x & s_mask; + sy = motion_y & s_mask; + src_x = s->mb_x * 2 * block_s + (motion_x >> lowres + 1); + src_y = (mb_y * 2 * block_s >> field_based) + (motion_y >> lowres + 1); + + if (s->out_format == FMT_H263) { + uvsx = ((motion_x >> 1) & s_mask) | (sx & 1); + uvsy = ((motion_y >> 1) & s_mask) | (sy & 1); + uvsrc_x = src_x >> 1; + uvsrc_y = src_y >> 1; + } else if (s->out_format == FMT_H261) { + // even chroma mv's are full pel in H261 + mx = motion_x / 4; + my = motion_y / 4; + uvsx = (2 * mx) & s_mask; + uvsy = (2 * my) & s_mask; + uvsrc_x = s->mb_x * block_s + (mx >> lowres); + uvsrc_y = mb_y * block_s + (my >> lowres); + } else { + if(s->chroma_y_shift){ + mx = motion_x / 2; + my = motion_y / 2; + uvsx = mx & s_mask; + uvsy = my & s_mask; + uvsrc_x = s->mb_x * block_s + (mx >> lowres + 1); + uvsrc_y = (mb_y * block_s >> field_based) + (my >> lowres + 1); + } else { + if(s->chroma_x_shift){ + //Chroma422 + mx = motion_x / 2; + uvsx = mx & s_mask; + uvsy = motion_y & s_mask; + uvsrc_y = src_y; + uvsrc_x = s->mb_x*block_s + (mx >> (lowres+1)); + } else { + //Chroma444 + uvsx = motion_x & s_mask; + uvsy = motion_y & s_mask; + uvsrc_x = src_x; + uvsrc_y = src_y; + } + } + } + + ptr_y = ref_picture[0] + src_y * linesize + src_x; + ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; + ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; + + if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s, 0) || uvsrc_y<0 || + (unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y, + linesize >> field_based, linesize >> field_based, + 17, 17 + field_based, + src_x, src_y << field_based, h_edge_pos, + v_edge_pos); + ptr_y = s->sc.edge_emu_buffer; + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize; + uint8_t *vbuf =ubuf + 10 * s->uvlinesize; + if (s->workaround_bugs & FF_BUG_IEDGE) + vbuf -= s->uvlinesize; + s->vdsp.emulated_edge_mc(ubuf, ptr_cb, + uvlinesize >> field_based, uvlinesize >> field_based, + 9, 9 + field_based, + uvsrc_x, uvsrc_y << field_based, + h_edge_pos >> 1, v_edge_pos >> 1); + s->vdsp.emulated_edge_mc(vbuf, ptr_cr, + uvlinesize >> field_based,uvlinesize >> field_based, + 9, 9 + field_based, + uvsrc_x, uvsrc_y << field_based, + h_edge_pos >> 1, v_edge_pos >> 1); + ptr_cb = ubuf; + ptr_cr = vbuf; + } + } + + // FIXME use this for field pix too instead of the obnoxious hack which changes picture.f->data + if (bottom_field) { + dest_y += s->linesize; + dest_cb += s->uvlinesize; + dest_cr += s->uvlinesize; + } + + if (field_select) { + ptr_y += s->linesize; + ptr_cb += s->uvlinesize; + ptr_cr += s->uvlinesize; + } + + sx = (sx << 2) >> lowres; + sy = (sy << 2) >> lowres; + pix_op[lowres - 1](dest_y, ptr_y, linesize, h, sx, sy); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + int hc = s->chroma_y_shift ? (h+1-bottom_field)>>1 : h; + uvsx = (uvsx << 2) >> lowres; + uvsy = (uvsy << 2) >> lowres; + if (hc) { + pix_op[op_index](dest_cb, ptr_cb, uvlinesize, hc, uvsx, uvsy); + pix_op[op_index](dest_cr, ptr_cr, uvlinesize, hc, uvsx, uvsy); + } + } + // FIXME h261 lowres loop filter +} + +static inline void chroma_4mv_motion_lowres(MpegEncContext *s, + uint8_t *dest_cb, uint8_t *dest_cr, + uint8_t **ref_picture, + h264_chroma_mc_func * pix_op, + int mx, int my) +{ + const int lowres = s->avctx->lowres; + const int op_index = FFMIN(lowres, 3); + const int block_s = 8 >> lowres; + const int s_mask = (2 << lowres) - 1; + const int h_edge_pos = s->h_edge_pos >> lowres + 1; + const int v_edge_pos = s->v_edge_pos >> lowres + 1; + int emu = 0, src_x, src_y, sx, sy; + ptrdiff_t offset; + uint8_t *ptr; + + if (s->quarter_sample) { + mx /= 2; + my /= 2; + } + + /* In case of 8X8, we construct a single chroma motion vector + with a special rounding */ + mx = ff_h263_round_chroma(mx); + my = ff_h263_round_chroma(my); + + sx = mx & s_mask; + sy = my & s_mask; + src_x = s->mb_x * block_s + (mx >> lowres + 1); + src_y = s->mb_y * block_s + (my >> lowres + 1); + + offset = src_y * s->uvlinesize + src_x; + ptr = ref_picture[1] + offset; + if ((unsigned) src_x > FFMAX(h_edge_pos - (!!sx) - block_s, 0) || + (unsigned) src_y > FFMAX(v_edge_pos - (!!sy) - block_s, 0)) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr, + s->uvlinesize, s->uvlinesize, + 9, 9, + src_x, src_y, h_edge_pos, v_edge_pos); + ptr = s->sc.edge_emu_buffer; + emu = 1; + } + sx = (sx << 2) >> lowres; + sy = (sy << 2) >> lowres; + pix_op[op_index](dest_cb, ptr, s->uvlinesize, block_s, sx, sy); + + ptr = ref_picture[2] + offset; + if (emu) { + s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr, + s->uvlinesize, s->uvlinesize, + 9, 9, + src_x, src_y, h_edge_pos, v_edge_pos); + ptr = s->sc.edge_emu_buffer; + } + pix_op[op_index](dest_cr, ptr, s->uvlinesize, block_s, sx, sy); +} + +/** + * motion compensation of a single macroblock + * @param s context + * @param dest_y luma destination pointer + * @param dest_cb chroma cb/u destination pointer + * @param dest_cr chroma cr/v destination pointer + * @param dir direction (0->forward, 1->backward) + * @param ref_picture array[3] of pointers to the 3 planes of the reference picture + * @param pix_op halfpel motion compensation function (average or put normally) + * the motion vectors are taken from s->mv and the MV type from s->mv_type + */ +static inline void MPV_motion_lowres(MpegEncContext *s, + uint8_t *dest_y, uint8_t *dest_cb, + uint8_t *dest_cr, + int dir, uint8_t **ref_picture, + h264_chroma_mc_func *pix_op) +{ + int mx, my; + int mb_x, mb_y, i; + const int lowres = s->avctx->lowres; + const int block_s = 8 >>lowres; + + mb_x = s->mb_x; + mb_y = s->mb_y; + + switch (s->mv_type) { + case MV_TYPE_16X16: + mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, + 0, 0, 0, + ref_picture, pix_op, + s->mv[dir][0][0], s->mv[dir][0][1], + 2 * block_s, mb_y); + break; + case MV_TYPE_8X8: + mx = 0; + my = 0; + for (i = 0; i < 4; i++) { + hpel_motion_lowres(s, dest_y + ((i & 1) + (i >> 1) * + s->linesize) * block_s, + ref_picture[0], 0, 0, + (2 * mb_x + (i & 1)) * block_s, + (2 * mb_y + (i >> 1)) * block_s, + s->width, s->height, s->linesize, + s->h_edge_pos >> lowres, s->v_edge_pos >> lowres, + block_s, block_s, pix_op, + s->mv[dir][i][0], s->mv[dir][i][1]); + + mx += s->mv[dir][i][0]; + my += s->mv[dir][i][1]; + } + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) + chroma_4mv_motion_lowres(s, dest_cb, dest_cr, ref_picture, + pix_op, mx, my); + break; + case MV_TYPE_FIELD: + if (s->picture_structure == PICT_FRAME) { + /* top field */ + mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, + 1, 0, s->field_select[dir][0], + ref_picture, pix_op, + s->mv[dir][0][0], s->mv[dir][0][1], + block_s, mb_y); + /* bottom field */ + mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, + 1, 1, s->field_select[dir][1], + ref_picture, pix_op, + s->mv[dir][1][0], s->mv[dir][1][1], + block_s, mb_y); + } else { + if (s->picture_structure != s->field_select[dir][0] + 1 && + s->pict_type != AV_PICTURE_TYPE_B && !s->first_field) { + ref_picture = s->current_picture_ptr->f->data; + + } + mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, + 0, 0, s->field_select[dir][0], + ref_picture, pix_op, + s->mv[dir][0][0], + s->mv[dir][0][1], 2 * block_s, mb_y >> 1); + } + break; + case MV_TYPE_16X8: + for (i = 0; i < 2; i++) { + uint8_t **ref2picture; + + if (s->picture_structure == s->field_select[dir][i] + 1 || + s->pict_type == AV_PICTURE_TYPE_B || s->first_field) { + ref2picture = ref_picture; + } else { + ref2picture = s->current_picture_ptr->f->data; + } + + mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, + 0, 0, s->field_select[dir][i], + ref2picture, pix_op, + s->mv[dir][i][0], s->mv[dir][i][1] + + 2 * block_s * i, block_s, mb_y >> 1); + + dest_y += 2 * block_s * s->linesize; + dest_cb += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize; + dest_cr += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize; + } + break; + case MV_TYPE_DMV: + if (s->picture_structure == PICT_FRAME) { + for (i = 0; i < 2; i++) { + int j; + for (j = 0; j < 2; j++) { + mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, + 1, j, j ^ i, + ref_picture, pix_op, + s->mv[dir][2 * i + j][0], + s->mv[dir][2 * i + j][1], + block_s, mb_y); + } + pix_op = s->h264chroma.avg_h264_chroma_pixels_tab; + } + } else { + for (i = 0; i < 2; i++) { + mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, + 0, 0, s->picture_structure != i + 1, + ref_picture, pix_op, + s->mv[dir][2 * i][0],s->mv[dir][2 * i][1], + 2 * block_s, mb_y >> 1); + + // after put we make avg of the same block + pix_op = s->h264chroma.avg_h264_chroma_pixels_tab; + + // opposite parity is always in the same + // frame if this is second field + if (!s->first_field) { + ref_picture = s->current_picture_ptr->f->data; + } + } + } + break; + default: + av_assert2(0); + } +} + +/** + * find the lowest MB row referenced in the MVs + */ +static int lowest_referenced_row(MpegEncContext *s, int dir) +{ + int my_max = INT_MIN, my_min = INT_MAX, qpel_shift = !s->quarter_sample; + int my, off, i, mvs; + + if (s->picture_structure != PICT_FRAME || s->mcsel) + goto unhandled; + + switch (s->mv_type) { + case MV_TYPE_16X16: + mvs = 1; + break; + case MV_TYPE_16X8: + mvs = 2; + break; + case MV_TYPE_8X8: + mvs = 4; + break; + default: + goto unhandled; + } + + for (i = 0; i < mvs; i++) { + my = s->mv[dir][i][1]; + my_max = FFMAX(my_max, my); + my_min = FFMIN(my_min, my); + } + + off = ((FFMAX(-my_min, my_max)<> 6; + + return av_clip(s->mb_y + off, 0, s->mb_height - 1); +unhandled: + return s->mb_height-1; +} + +/* put block[] to dest[] */ +static inline void put_dct(MpegEncContext *s, + int16_t *block, int i, uint8_t *dest, int line_size, int qscale) +{ + s->dct_unquantize_intra(s, block, i, qscale); + s->idsp.idct_put(dest, line_size, block); +} + +/* add block[] to dest[] */ +static inline void add_dct(MpegEncContext *s, + int16_t *block, int i, uint8_t *dest, int line_size) +{ + if (s->block_last_index[i] >= 0) { + s->idsp.idct_add(dest, line_size, block); + } +} + +static inline void add_dequant_dct(MpegEncContext *s, + int16_t *block, int i, uint8_t *dest, int line_size, int qscale) +{ + if (s->block_last_index[i] >= 0) { + s->dct_unquantize_inter(s, block, i, qscale); + + s->idsp.idct_add(dest, line_size, block); + } +} + +/** + * Clean dc, ac, coded_block for the current non-intra MB. + */ +void ff_clean_intra_table_entries(MpegEncContext *s) +{ + int wrap = s->b8_stride; + int xy = s->block_index[0]; + + s->dc_val[0][xy ] = + s->dc_val[0][xy + 1 ] = + s->dc_val[0][xy + wrap] = + s->dc_val[0][xy + 1 + wrap] = 1024; + /* ac pred */ + memset(s->ac_val[0][xy ], 0, 32 * sizeof(int16_t)); + memset(s->ac_val[0][xy + wrap], 0, 32 * sizeof(int16_t)); + if (s->msmpeg4_version>=3) { + s->coded_block[xy ] = + s->coded_block[xy + 1 ] = + s->coded_block[xy + wrap] = + s->coded_block[xy + 1 + wrap] = 0; + } + /* chroma */ + wrap = s->mb_stride; + xy = s->mb_x + s->mb_y * wrap; + s->dc_val[1][xy] = + s->dc_val[2][xy] = 1024; + /* ac pred */ + memset(s->ac_val[1][xy], 0, 16 * sizeof(int16_t)); + memset(s->ac_val[2][xy], 0, 16 * sizeof(int16_t)); + + s->mbintra_table[xy]= 0; +} + +/* generic function called after a macroblock has been parsed by the + decoder or after it has been encoded by the encoder. + + Important variables used: + s->mb_intra : true if intra macroblock + s->mv_dir : motion vector direction + s->mv_type : motion vector type + s->mv : motion vector + s->interlaced_dct : true if interlaced dct used (mpeg2) + */ +static av_always_inline +void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], + int lowres_flag, int is_mpeg12) +{ + const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; + + if (CONFIG_XVMC && + s->avctx->hwaccel && s->avctx->hwaccel->decode_mb) { + s->avctx->hwaccel->decode_mb(s);//xvmc uses pblocks + return; + } + + if(s->avctx->debug&FF_DEBUG_DCT_COEFF) { + /* print DCT coefficients */ + int i,j; + av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y); + for(i=0; i<6; i++){ + for(j=0; j<64; j++){ + av_log(s->avctx, AV_LOG_DEBUG, "%5d", + block[i][s->idsp.idct_permutation[j]]); + } + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + } + + s->current_picture.qscale_table[mb_xy] = s->qscale; + + /* update DC predictors for P macroblocks */ + if (!s->mb_intra) { + if (!is_mpeg12 && (s->h263_pred || s->h263_aic)) { + if(s->mbintra_table[mb_xy]) + ff_clean_intra_table_entries(s); + } else { + s->last_dc[0] = + s->last_dc[1] = + s->last_dc[2] = 128 << s->intra_dc_precision; + } + } + else if (!is_mpeg12 && (s->h263_pred || s->h263_aic)) + s->mbintra_table[mb_xy]=1; + + if ((s->avctx->flags & AV_CODEC_FLAG_PSNR) || s->frame_skip_threshold || s->frame_skip_factor || + !(s->encoding && (s->intra_only || s->pict_type == AV_PICTURE_TYPE_B) && + s->avctx->mb_decision != FF_MB_DECISION_RD)) { // FIXME precalc + uint8_t *dest_y, *dest_cb, *dest_cr; + int dct_linesize, dct_offset; + op_pixels_func (*op_pix)[4]; + qpel_mc_func (*op_qpix)[16]; + const int linesize = s->current_picture.f->linesize[0]; //not s->linesize as this would be wrong for field pics + const int uvlinesize = s->current_picture.f->linesize[1]; + const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band || lowres_flag; + const int block_size= lowres_flag ? 8>>s->avctx->lowres : 8; + + /* avoid copy if macroblock skipped in last frame too */ + /* skip only during decoding as we might trash the buffers during encoding a bit */ + if(!s->encoding){ + uint8_t *mbskip_ptr = &s->mbskip_table[mb_xy]; + + if (s->mb_skipped) { + s->mb_skipped= 0; + av_assert2(s->pict_type!=AV_PICTURE_TYPE_I); + *mbskip_ptr = 1; + } else if(!s->current_picture.reference) { + *mbskip_ptr = 1; + } else{ + *mbskip_ptr = 0; /* not skipped */ + } + } + + dct_linesize = linesize << s->interlaced_dct; + dct_offset = s->interlaced_dct ? linesize : linesize * block_size; + + if(readable){ + dest_y= s->dest[0]; + dest_cb= s->dest[1]; + dest_cr= s->dest[2]; + }else{ + dest_y = s->sc.b_scratchpad; + dest_cb= s->sc.b_scratchpad+16*linesize; + dest_cr= s->sc.b_scratchpad+32*linesize; + } + + if (!s->mb_intra) { + /* motion handling */ + /* decoding or more than one mb_type (MC was already done otherwise) */ + if(!s->encoding){ + + if(HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) { + if (s->mv_dir & MV_DIR_FORWARD) { + ff_thread_await_progress(&s->last_picture_ptr->tf, + lowest_referenced_row(s, 0), + 0); + } + if (s->mv_dir & MV_DIR_BACKWARD) { + ff_thread_await_progress(&s->next_picture_ptr->tf, + lowest_referenced_row(s, 1), + 0); + } + } + + if(lowres_flag){ + h264_chroma_mc_func *op_pix = s->h264chroma.put_h264_chroma_pixels_tab; + + if (s->mv_dir & MV_DIR_FORWARD) { + MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f->data, op_pix); + op_pix = s->h264chroma.avg_h264_chroma_pixels_tab; + } + if (s->mv_dir & MV_DIR_BACKWARD) { + MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f->data, op_pix); + } + }else{ + op_qpix = s->me.qpel_put; + if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){ + op_pix = s->hdsp.put_pixels_tab; + }else{ + op_pix = s->hdsp.put_no_rnd_pixels_tab; + } + if (s->mv_dir & MV_DIR_FORWARD) { + ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f->data, op_pix, op_qpix); + op_pix = s->hdsp.avg_pixels_tab; + op_qpix= s->me.qpel_avg; + } + if (s->mv_dir & MV_DIR_BACKWARD) { + ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f->data, op_pix, op_qpix); + } + } + } + + /* skip dequant / idct if we are really late ;) */ + if(s->avctx->skip_idct){ + if( (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) + ||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) + || s->avctx->skip_idct >= AVDISCARD_ALL) + goto skip_idct; + } + + /* add dct residue */ + if(s->encoding || !( s->msmpeg4_version || s->codec_id==AV_CODEC_ID_MPEG1VIDEO || s->codec_id==AV_CODEC_ID_MPEG2VIDEO + || (s->codec_id==AV_CODEC_ID_MPEG4 && !s->mpeg_quant))){ + add_dequant_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); + add_dequant_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); + add_dequant_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); + add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + if (s->chroma_y_shift){ + add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); + add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + }else{ + dct_linesize >>= 1; + dct_offset >>=1; + add_dequant_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); + add_dequant_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); + add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); + add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); + } + } + } else if(is_mpeg12 || (s->codec_id != AV_CODEC_ID_WMV2)){ + add_dct(s, block[0], 0, dest_y , dct_linesize); + add_dct(s, block[1], 1, dest_y + block_size, dct_linesize); + add_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize); + add_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + if(s->chroma_y_shift){//Chroma420 + add_dct(s, block[4], 4, dest_cb, uvlinesize); + add_dct(s, block[5], 5, dest_cr, uvlinesize); + }else{ + //chroma422 + dct_linesize = uvlinesize << s->interlaced_dct; + dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; + + add_dct(s, block[4], 4, dest_cb, dct_linesize); + add_dct(s, block[5], 5, dest_cr, dct_linesize); + add_dct(s, block[6], 6, dest_cb+dct_offset, dct_linesize); + add_dct(s, block[7], 7, dest_cr+dct_offset, dct_linesize); + if(!s->chroma_x_shift){//Chroma444 + add_dct(s, block[8], 8, dest_cb+block_size, dct_linesize); + add_dct(s, block[9], 9, dest_cr+block_size, dct_linesize); + add_dct(s, block[10], 10, dest_cb+block_size+dct_offset, dct_linesize); + add_dct(s, block[11], 11, dest_cr+block_size+dct_offset, dct_linesize); + } + } + }//fi gray + } + else if (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) { + ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr); + } + } else { + /* Only MPEG-4 Simple Studio Profile is supported in > 8-bit mode. + TODO: Integrate 10-bit properly into mpegvideo.c so that ER works properly */ + if (s->avctx->bits_per_raw_sample > 8){ + const int act_block_size = block_size * 2; + + if(s->dpcm_direction == 0) { + s->idsp.idct_put(dest_y, dct_linesize, (int16_t*)(*s->block32)[0]); + s->idsp.idct_put(dest_y + act_block_size, dct_linesize, (int16_t*)(*s->block32)[1]); + s->idsp.idct_put(dest_y + dct_offset, dct_linesize, (int16_t*)(*s->block32)[2]); + s->idsp.idct_put(dest_y + dct_offset + act_block_size, dct_linesize, (int16_t*)(*s->block32)[3]); + + dct_linesize = uvlinesize << s->interlaced_dct; + dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; + + s->idsp.idct_put(dest_cb, dct_linesize, (int16_t*)(*s->block32)[4]); + s->idsp.idct_put(dest_cr, dct_linesize, (int16_t*)(*s->block32)[5]); + s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, (int16_t*)(*s->block32)[6]); + s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, (int16_t*)(*s->block32)[7]); + if(!s->chroma_x_shift){//Chroma444 + s->idsp.idct_put(dest_cb + act_block_size, dct_linesize, (int16_t*)(*s->block32)[8]); + s->idsp.idct_put(dest_cr + act_block_size, dct_linesize, (int16_t*)(*s->block32)[9]); + s->idsp.idct_put(dest_cb + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[10]); + s->idsp.idct_put(dest_cr + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[11]); + } + } else if(s->dpcm_direction == 1) { + int i, w, h; + uint16_t *dest_pcm[3] = {(uint16_t*)dest_y, (uint16_t*)dest_cb, (uint16_t*)dest_cr}; + int linesize[3] = {dct_linesize, uvlinesize, uvlinesize}; + for(i = 0; i < 3; i++) { + int idx = 0; + int vsub = i ? s->chroma_y_shift : 0; + int hsub = i ? s->chroma_x_shift : 0; + for(h = 0; h < (16 >> vsub); h++){ + for(w = 0; w < (16 >> hsub); w++) + dest_pcm[i][w] = (*s->dpcm_macroblock)[i][idx++]; + dest_pcm[i] += linesize[i] / 2; + } + } + } else if(s->dpcm_direction == -1) { + int i, w, h; + uint16_t *dest_pcm[3] = {(uint16_t*)dest_y, (uint16_t*)dest_cb, (uint16_t*)dest_cr}; + int linesize[3] = {dct_linesize, uvlinesize, uvlinesize}; + for(i = 0; i < 3; i++) { + int idx = 0; + int vsub = i ? s->chroma_y_shift : 0; + int hsub = i ? s->chroma_x_shift : 0; + dest_pcm[i] += (linesize[i] / 2) * ((16 >> vsub) - 1); + for(h = (16 >> vsub)-1; h >= 1; h--){ + for(w = (16 >> hsub)-1; w >= 1; w--) + dest_pcm[i][w] = (*s->dpcm_macroblock)[i][idx++]; + dest_pcm[i] -= linesize[i] / 2; + } + } + } + } + /* dct only in intra block */ + else if(s->encoding || !(s->codec_id==AV_CODEC_ID_MPEG1VIDEO || s->codec_id==AV_CODEC_ID_MPEG2VIDEO)){ + put_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); + put_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); + put_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); + put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + if(s->chroma_y_shift){ + put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); + put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + }else{ + dct_offset >>=1; + dct_linesize >>=1; + put_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); + put_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); + put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); + put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); + } + } + }else{ + s->idsp.idct_put(dest_y, dct_linesize, block[0]); + s->idsp.idct_put(dest_y + block_size, dct_linesize, block[1]); + s->idsp.idct_put(dest_y + dct_offset, dct_linesize, block[2]); + s->idsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + if(s->chroma_y_shift){ + s->idsp.idct_put(dest_cb, uvlinesize, block[4]); + s->idsp.idct_put(dest_cr, uvlinesize, block[5]); + }else{ + + dct_linesize = uvlinesize << s->interlaced_dct; + dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; + + s->idsp.idct_put(dest_cb, dct_linesize, block[4]); + s->idsp.idct_put(dest_cr, dct_linesize, block[5]); + s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]); + s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]); + if(!s->chroma_x_shift){//Chroma444 + s->idsp.idct_put(dest_cb + block_size, dct_linesize, block[8]); + s->idsp.idct_put(dest_cr + block_size, dct_linesize, block[9]); + s->idsp.idct_put(dest_cb + block_size + dct_offset, dct_linesize, block[10]); + s->idsp.idct_put(dest_cr + block_size + dct_offset, dct_linesize, block[11]); + } + } + }//gray + } + } +skip_idct: + if(!readable){ + s->hdsp.put_pixels_tab[0][0](s->dest[0], dest_y , linesize,16); + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + s->hdsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[1], dest_cb, uvlinesize,16 >> s->chroma_y_shift); + s->hdsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[2], dest_cr, uvlinesize,16 >> s->chroma_y_shift); + } + } + } +} + +void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]) +{ +#if !CONFIG_SMALL + if(s->out_format == FMT_MPEG1) { + if(s->avctx->lowres) mpv_reconstruct_mb_internal(s, block, 1, 1); + else mpv_reconstruct_mb_internal(s, block, 0, 1); + } else +#endif + if(s->avctx->lowres) mpv_reconstruct_mb_internal(s, block, 1, 0); + else mpv_reconstruct_mb_internal(s, block, 0, 0); +} + +void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h) +{ + ff_draw_horiz_band(s->avctx, s->current_picture_ptr->f, + s->last_picture_ptr ? s->last_picture_ptr->f : NULL, y, h, s->picture_structure, + s->first_field, s->low_delay); +} + +void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename + const int linesize = s->current_picture.f->linesize[0]; //not s->linesize as this would be wrong for field pics + const int uvlinesize = s->current_picture.f->linesize[1]; + const int width_of_mb = (4 + (s->avctx->bits_per_raw_sample > 8)) - s->avctx->lowres; + const int height_of_mb = 4 - s->avctx->lowres; + + s->block_index[0]= s->b8_stride*(s->mb_y*2 ) - 2 + s->mb_x*2; + s->block_index[1]= s->b8_stride*(s->mb_y*2 ) - 1 + s->mb_x*2; + s->block_index[2]= s->b8_stride*(s->mb_y*2 + 1) - 2 + s->mb_x*2; + s->block_index[3]= s->b8_stride*(s->mb_y*2 + 1) - 1 + s->mb_x*2; + s->block_index[4]= s->mb_stride*(s->mb_y + 1) + s->b8_stride*s->mb_height*2 + s->mb_x - 1; + s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1; + //block_index is not used by mpeg2, so it is not affected by chroma_format + + s->dest[0] = s->current_picture.f->data[0] + (int)((s->mb_x - 1U) << width_of_mb); + s->dest[1] = s->current_picture.f->data[1] + (int)((s->mb_x - 1U) << (width_of_mb - s->chroma_x_shift)); + s->dest[2] = s->current_picture.f->data[2] + (int)((s->mb_x - 1U) << (width_of_mb - s->chroma_x_shift)); + + if(!(s->pict_type==AV_PICTURE_TYPE_B && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME)) + { + if(s->picture_structure==PICT_FRAME){ + s->dest[0] += s->mb_y * linesize << height_of_mb; + s->dest[1] += s->mb_y * uvlinesize << (height_of_mb - s->chroma_y_shift); + s->dest[2] += s->mb_y * uvlinesize << (height_of_mb - s->chroma_y_shift); + }else{ + s->dest[0] += (s->mb_y>>1) * linesize << height_of_mb; + s->dest[1] += (s->mb_y>>1) * uvlinesize << (height_of_mb - s->chroma_y_shift); + s->dest[2] += (s->mb_y>>1) * uvlinesize << (height_of_mb - s->chroma_y_shift); + av_assert1((s->mb_y&1) == (s->picture_structure == PICT_BOTTOM_FIELD)); + } + } +} + +void ff_mpeg_flush(AVCodecContext *avctx){ + int i; + MpegEncContext *s = avctx->priv_data; + + if (!s || !s->picture) + return; + + for (i = 0; i < MAX_PICTURE_COUNT; i++) + ff_mpeg_unref_picture(s->avctx, &s->picture[i]); + s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL; + + ff_mpeg_unref_picture(s->avctx, &s->current_picture); + ff_mpeg_unref_picture(s->avctx, &s->last_picture); + ff_mpeg_unref_picture(s->avctx, &s->next_picture); + + s->mb_x= s->mb_y= 0; + s->closed_gop= 0; + + s->parse_context.state= -1; + s->parse_context.frame_start_found= 0; + s->parse_context.overread= 0; + s->parse_context.overread_index= 0; + s->parse_context.index= 0; + s->parse_context.last_index= 0; + s->bitstream_buffer_size=0; + s->pp_time=0; +} + +/** + * set qscale and update qscale dependent variables. + */ +void ff_set_qscale(MpegEncContext * s, int qscale) +{ + if (qscale < 1) + qscale = 1; + else if (qscale > 31) + qscale = 31; + + s->qscale = qscale; + s->chroma_qscale= s->chroma_qscale_table[qscale]; + + s->y_dc_scale= s->y_dc_scale_table[ qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ]; +} + +void ff_mpv_report_decode_progress(MpegEncContext *s) +{ + if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->er.error_occurred) + ff_thread_report_progress(&s->current_picture_ptr->tf, s->mb_y, 0); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideo.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideo.h new file mode 100644 index 000000000..e1ff5f97d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideo.h @@ -0,0 +1,770 @@ +/* + * Generic DCT based hybrid video encoder + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * mpegvideo header. + */ + +#ifndef AVCODEC_MPEGVIDEO_H +#define AVCODEC_MPEGVIDEO_H + +#include + +#include "avcodec.h" +#include "blockdsp.h" +#include "error_resilience.h" +#include "fdctdsp.h" +#include "get_bits.h" +#include "h264chroma.h" +#include "h263dsp.h" +#include "hpeldsp.h" +#include "idctdsp.h" +#include "internal.h" +#include "me_cmp.h" +#include "motion_est.h" +#include "mpegpicture.h" +#include "mpegvideodsp.h" +#include "mpegvideoencdsp.h" +#include "mpegvideodata.h" +#include "pixblockdsp.h" +#include "put_bits.h" +#include "ratecontrol.h" +#include "parser.h" +#include "mpegutils.h" +#include "mpeg12data.h" +#include "qpeldsp.h" +#include "thread.h" +#include "videodsp.h" + +#include "libavutil/opt.h" +#include "libavutil/timecode.h" + +#define MAX_THREADS 32 + +#define MAX_B_FRAMES 16 + +/* Start codes. */ +#define SEQ_END_CODE 0x000001b7 +#define SEQ_START_CODE 0x000001b3 +#define GOP_START_CODE 0x000001b8 +#define PICTURE_START_CODE 0x00000100 +#define SLICE_MIN_START_CODE 0x00000101 +#define SLICE_MAX_START_CODE 0x000001af +#define EXT_START_CODE 0x000001b5 +#define USER_START_CODE 0x000001b2 +#define SLICE_START_CODE 0x000001b7 + + +/** + * MpegEncContext. + */ +typedef struct MpegEncContext { + AVClass *class; + + int y_dc_scale, c_dc_scale; + int ac_pred; + int block_last_index[12]; ///< last non zero coefficient in block + int h263_aic; ///< Advanced INTRA Coding (AIC) + + /* scantables */ + ScanTable inter_scantable; ///< if inter == intra then intra should be used to reduce the cache usage + ScanTable intra_scantable; + ScanTable intra_h_scantable; + ScanTable intra_v_scantable; + + /* WARNING: changes above this line require updates to hardcoded + * offsets used in ASM. */ + + struct AVCodecContext *avctx; + /* the following parameters must be initialized before encoding */ + int width, height;///< picture size. must be a multiple of 16 + int gop_size; + int intra_only; ///< if true, only intra pictures are generated + int64_t bit_rate; ///< wanted bit rate + enum OutputFormat out_format; ///< output format + int h263_pred; ///< use MPEG-4/H.263 ac/dc predictions + int pb_frame; ///< PB-frame mode (0 = none, 1 = base, 2 = improved) + +/* the following codec id fields are deprecated in favor of codec_id */ + int h263_plus; ///< H.263+ headers + int h263_flv; ///< use flv H.263 header + + enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */ + int fixed_qscale; ///< fixed qscale if non zero + int encoding; ///< true if we are encoding (vs decoding) + int max_b_frames; ///< max number of B-frames for encoding + int luma_elim_threshold; + int chroma_elim_threshold; + int strict_std_compliance; ///< strictly follow the std (MPEG-4, ...) + int workaround_bugs; ///< workaround bugs in encoders which cannot be detected automatically + int codec_tag; ///< internal codec_tag upper case converted from avctx codec_tag + /* the following fields are managed internally by the encoder */ + + /* sequence parameters */ + int context_initialized; + int input_picture_number; ///< used to set pic->display_picture_number, should not be used for/by anything else + int coded_picture_number; ///< used to set pic->coded_picture_number, should not be used for/by anything else + int picture_number; //FIXME remove, unclear definition + int picture_in_gop_number; ///< 0-> first pic in gop, ... + int mb_width, mb_height; ///< number of MBs horizontally & vertically + int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11 + int b8_stride; ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressing + int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replication) + int mb_num; ///< number of MBs of a picture + ptrdiff_t linesize; ///< line size, in bytes, may be different from width + ptrdiff_t uvlinesize; ///< line size, for chroma in bytes, may be different from width + Picture *picture; ///< main picture buffer + Picture **input_picture; ///< next pictures on display order for encoding + Picture **reordered_input_picture; ///< pointer to the next pictures in coded order for encoding + + int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_encode_video2() + /** + * pts difference between the first and second input frame, used for + * calculating dts of the first frame when there's a delay */ + int64_t dts_delta; + /** + * reordered pts to be used as dts for the next output frame when there's + * a delay */ + int64_t reordered_pts; + + /** bit output */ + PutBitContext pb; + + int start_mb_y; ///< start mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y) + int end_mb_y; ///< end mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y) + struct MpegEncContext *thread_context[MAX_THREADS]; + int slice_context_count; ///< number of used thread_contexts + + /** + * copy of the previous picture structure. + * note, linesize & data, might not match the previous picture (for field pictures) + */ + Picture last_picture; + + /** + * copy of the next picture structure. + * note, linesize & data, might not match the next picture (for field pictures) + */ + Picture next_picture; + + /** + * copy of the source picture structure for encoding. + * note, linesize & data, might not match the source picture (for field pictures) + */ + Picture new_picture; + + /** + * copy of the current picture structure. + * note, linesize & data, might not match the current picture (for field pictures) + */ + Picture current_picture; ///< buffer to store the decompressed current picture + + Picture *last_picture_ptr; ///< pointer to the previous picture. + Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred) + Picture *current_picture_ptr; ///< pointer to the current picture + int last_dc[3]; ///< last DC values for MPEG-1 + int16_t *dc_val_base; + int16_t *dc_val[3]; ///< used for MPEG-4 DC prediction, all 3 arrays must be continuous + const uint8_t *y_dc_scale_table; ///< qscale -> y_dc_scale table + const uint8_t *c_dc_scale_table; ///< qscale -> c_dc_scale table + const uint8_t *chroma_qscale_table; ///< qscale -> chroma_qscale (H.263) + uint8_t *coded_block_base; + uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1) + int16_t (*ac_val_base)[16]; + int16_t (*ac_val[3])[16]; ///< used for MPEG-4 AC prediction, all 3 arrays must be continuous + int mb_skipped; ///< MUST BE SET only during DECODING + uint8_t *mbskip_table; /**< used to avoid copy if macroblock skipped (for black regions for example) + and used for B-frame encoding & decoding (contains skip table of next P-frame) */ + uint8_t *mbintra_table; ///< used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding + uint8_t *cbp_table; ///< used to store cbp, ac_pred for partitioned decoding + uint8_t *pred_dir_table; ///< used to store pred_dir for partitioned decoding + + ScratchpadContext sc; + + int qscale; ///< QP + int chroma_qscale; ///< chroma QP + unsigned int lambda; ///< Lagrange multiplier used in rate distortion + unsigned int lambda2; ///< (lambda*lambda) >> FF_LAMBDA_SHIFT + int *lambda_table; + int adaptive_quant; ///< use adaptive quantization + int dquant; ///< qscale difference to prev qscale + int closed_gop; ///< MPEG1/2 GOP is closed + int pict_type; ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ... + int vbv_delay; + int last_pict_type; //FIXME removes + int last_non_b_pict_type; ///< used for MPEG-4 gmc B-frames & ratecontrol + int droppable; + int frame_rate_index; + AVRational mpeg2_frame_rate_ext; + int last_lambda_for[5]; ///< last lambda for a specific pict type + int skipdct; ///< skip dct and code zero residual + + /* motion compensation */ + int unrestricted_mv; ///< mv can point outside of the coded picture + int h263_long_vectors; ///< use horrible H.263v1 long vector mode + + BlockDSPContext bdsp; + FDCTDSPContext fdsp; + H264ChromaContext h264chroma; + HpelDSPContext hdsp; + IDCTDSPContext idsp; + MECmpContext mecc; + MpegVideoDSPContext mdsp; + MpegvideoEncDSPContext mpvencdsp; + PixblockDSPContext pdsp; + QpelDSPContext qdsp; + VideoDSPContext vdsp; + H263DSPContext h263dsp; + int f_code; ///< forward MV resolution + int b_code; ///< backward MV resolution for B-frames (MPEG-4) + int16_t (*p_mv_table_base)[2]; + int16_t (*b_forw_mv_table_base)[2]; + int16_t (*b_back_mv_table_base)[2]; + int16_t (*b_bidir_forw_mv_table_base)[2]; + int16_t (*b_bidir_back_mv_table_base)[2]; + int16_t (*b_direct_mv_table_base)[2]; + int16_t (*p_field_mv_table_base[2][2])[2]; + int16_t (*b_field_mv_table_base[2][2][2])[2]; + int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) P-frame encoding + int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode B-frame encoding + int16_t (*b_back_mv_table)[2]; ///< MV table (1MV per MB) backward mode B-frame encoding + int16_t (*b_bidir_forw_mv_table)[2]; ///< MV table (1MV per MB) bidir mode B-frame encoding + int16_t (*b_bidir_back_mv_table)[2]; ///< MV table (1MV per MB) bidir mode B-frame encoding + int16_t (*b_direct_mv_table)[2]; ///< MV table (1MV per MB) direct mode B-frame encoding + int16_t (*p_field_mv_table[2][2])[2]; ///< MV table (2MV per MB) interlaced P-frame encoding + int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced B-frame encoding + uint8_t (*p_field_select_table[2]); + uint8_t (*b_field_select_table[2][2]); + int motion_est; ///< ME algorithm + int me_penalty_compensation; + int me_pre; ///< prepass for motion estimation + int mv_dir; +#define MV_DIR_FORWARD 1 +#define MV_DIR_BACKWARD 2 +#define MV_DIRECT 4 ///< bidirectional mode where the difference equals the MV of the last P/S/I-Frame (MPEG-4) + int mv_type; +#define MV_TYPE_16X16 0 ///< 1 vector for the whole mb +#define MV_TYPE_8X8 1 ///< 4 vectors (H.263, MPEG-4 4MV) +#define MV_TYPE_16X8 2 ///< 2 vectors, one per 16x8 block +#define MV_TYPE_FIELD 3 ///< 2 vectors, one per field +#define MV_TYPE_DMV 4 ///< 2 vectors, special mpeg2 Dual Prime Vectors + /**motion vectors for a macroblock + first coordinate : 0 = forward 1 = backward + second " : depend on type + third " : 0 = x, 1 = y + */ + int mv[2][4][2]; + int field_select[2][2]; + int last_mv[2][2][2]; ///< last MV, used for MV prediction in MPEG-1 & B-frame MPEG-4 + uint8_t *fcode_tab; ///< smallest fcode needed for each MV + int16_t direct_scale_mv[2][64]; ///< precomputed to avoid divisions in ff_mpeg4_set_direct_mv + + MotionEstContext me; + + int no_rounding; /**< apply no rounding to motion compensation (MPEG-4, msmpeg4, ...) + for B-frames rounding mode is always 0 */ + + /* macroblock layer */ + int mb_x, mb_y; + int mb_skip_run; + int mb_intra; + uint16_t *mb_type; ///< Table for candidate MB types for encoding (defines in mpegutils.h) + + int block_index[6]; ///< index to current MB in block based arrays with edges + int block_wrap[6]; + uint8_t *dest[3]; + + int *mb_index2xy; ///< mb_index -> mb_x + mb_y*mb_stride + + /** matrix transmitted in the bitstream */ + uint16_t intra_matrix[64]; + uint16_t chroma_intra_matrix[64]; + uint16_t inter_matrix[64]; + uint16_t chroma_inter_matrix[64]; + int force_duplicated_matrix; ///< Force duplication of mjpeg matrices, useful for rtp streaming + + int intra_quant_bias; ///< bias for the quantizer + int inter_quant_bias; ///< bias for the quantizer + int min_qcoeff; ///< minimum encodable coefficient + int max_qcoeff; ///< maximum encodable coefficient + int ac_esc_length; ///< num of bits needed to encode the longest esc + uint8_t *intra_ac_vlc_length; + uint8_t *intra_ac_vlc_last_length; + uint8_t *intra_chroma_ac_vlc_length; + uint8_t *intra_chroma_ac_vlc_last_length; + uint8_t *inter_ac_vlc_length; + uint8_t *inter_ac_vlc_last_length; + uint8_t *luma_dc_vlc_length; +#define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level)) + + int coded_score[12]; + + /** precomputed matrix (combine qscale and DCT renorm) */ + int (*q_intra_matrix)[64]; + int (*q_chroma_intra_matrix)[64]; + int (*q_inter_matrix)[64]; + /** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/ + uint16_t (*q_intra_matrix16)[2][64]; + uint16_t (*q_chroma_intra_matrix16)[2][64]; + uint16_t (*q_inter_matrix16)[2][64]; + + /* noise reduction */ + int (*dct_error_sum)[64]; + int dct_count[2]; + uint16_t (*dct_offset)[64]; + + /* bit rate control */ + int64_t total_bits; + int frame_bits; ///< bits used for the current frame + int stuffing_bits; ///< bits used for stuffing + int next_lambda; ///< next lambda used for retrying to encode a frame + RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c + + /* statistics, used for 2-pass encoding */ + int mv_bits; + int header_bits; + int i_tex_bits; + int p_tex_bits; + int i_count; + int f_count; + int b_count; + int skip_count; + int misc_bits; ///< cbp, mb_type + int last_bits; ///< temp var used for calculating the above vars + + /* error concealment / resync */ + int resync_mb_x; ///< x position of last resync marker + int resync_mb_y; ///< y position of last resync marker + GetBitContext last_resync_gb; ///< used to search for the next resync marker + int mb_num_left; ///< number of MBs left in this video packet (for partitioned Slices only) + int next_p_frame_damaged; ///< set if the next p frame is damaged, to avoid showing trashed B-frames + + ParseContext parse_context; + + /* H.263 specific */ + int gob_index; + int obmc; ///< overlapped block motion compensation + int mb_info; ///< interval for outputting info about mb offsets as side data + int prev_mb_info, last_mb_info; + uint8_t *mb_info_ptr; + int mb_info_size; + int ehc_mode; + int rc_strategy; ///< deprecated + + /* H.263+ specific */ + int umvplus; ///< == H.263+ && unrestricted_mv + int h263_aic_dir; ///< AIC direction: 0 = left, 1 = top + int h263_slice_structured; + int alt_inter_vlc; ///< alternative inter vlc + int modified_quant; + int loop_filter; + int custom_pcf; + + /* MPEG-4 specific */ + int studio_profile; + int dct_precision; + ///< number of bits to represent the fractional part of time (encoder only) + int time_increment_bits; + int last_time_base; + int time_base; ///< time in seconds of last I,P,S Frame + int64_t time; ///< time of current frame + int64_t last_non_b_time; + uint16_t pp_time; ///< time distance between the last 2 p,s,i frames + uint16_t pb_time; ///< time distance between the last b and p,s,i frame + uint16_t pp_field_time; + uint16_t pb_field_time; ///< like above, just for interlaced + int real_sprite_warping_points; + int sprite_offset[2][2]; ///< sprite offset[isChroma][isMVY] + int sprite_delta[2][2]; ///< sprite_delta [isY][isMVY] + int mcsel; + int quant_precision; + int quarter_sample; ///< 1->qpel, 0->half pel ME/MC + int aspect_ratio_info; //FIXME remove + int sprite_warping_accuracy; + int data_partitioning; ///< data partitioning flag from header + int partitioned_frame; ///< is current frame partitioned + int low_delay; ///< no reordering needed / has no B-frames + int vo_type; + PutBitContext tex_pb; ///< used for data partitioned VOPs + PutBitContext pb2; ///< used for data partitioned VOPs + int mpeg_quant; + int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG-4 + + /* divx specific, used to workaround (many) bugs in divx5 */ + int divx_packed; + uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them + int bitstream_buffer_size; + unsigned int allocated_bitstream_buffer_size; + + /* RV10 specific */ + int rv10_version; ///< RV10 version: 0 or 3 + int rv10_first_dc_coded[3]; + + /* MJPEG specific */ + struct MJpegContext *mjpeg_ctx; + int esc_pos; + int pred; + int huffman; + + /* MSMPEG4 specific */ + int mv_table_index; + int rl_table_index; + int rl_chroma_table_index; + int dc_table_index; + int use_skip_mb_code; + int slice_height; ///< in macroblocks + int first_slice_line; ///< used in MPEG-4 too to handle resync markers + int flipflop_rounding; + int msmpeg4_version; ///< 0=not msmpeg4, 1=mp41, 2=mp42, 3=mp43/divx3 4=wmv1/7 5=wmv2/8 + int per_mb_rl_table; + int esc3_level_length; + int esc3_run_length; + /** [mb_intra][isChroma][level][run][last] */ + int (*ac_stats)[2][MAX_LEVEL+1][MAX_RUN+1][2]; + int inter_intra_pred; + int mspel; + + /* decompression specific */ + GetBitContext gb; + + /* MPEG-1 specific */ + int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & MPEG-1 specific + int last_mv_dir; ///< last mv_dir, used for B-frame encoding + uint8_t *vbv_delay_ptr; ///< pointer to vbv_delay in the bitstream + + /* MPEG-2-specific - I wished not to have to support this mess. */ + int progressive_sequence; + int mpeg_f_code[2][2]; + int a53_cc; + + // picture structure defines are loaded from mpegutils.h + int picture_structure; + + int64_t timecode_frame_start; ///< GOP timecode frame start number, in non drop frame format + int intra_dc_precision; + int frame_pred_frame_dct; + int top_field_first; + int concealment_motion_vectors; + int q_scale_type; + int brd_scale; + int intra_vlc_format; + int alternate_scan; + int seq_disp_ext; + int video_format; +#define VIDEO_FORMAT_COMPONENT 0 +#define VIDEO_FORMAT_PAL 1 +#define VIDEO_FORMAT_NTSC 2 +#define VIDEO_FORMAT_SECAM 3 +#define VIDEO_FORMAT_MAC 4 +#define VIDEO_FORMAT_UNSPECIFIED 5 + int repeat_first_field; + int chroma_420_type; + int chroma_format; +#define CHROMA_420 1 +#define CHROMA_422 2 +#define CHROMA_444 3 + int chroma_x_shift;//depend on pix_format, that depend on chroma_format + int chroma_y_shift; + + int progressive_frame; + int full_pel[2]; + int interlaced_dct; + int first_field; ///< is 1 for the first field of a field picture 0 otherwise + int drop_frame_timecode; ///< timecode is in drop frame format. + int scan_offset; ///< reserve space for SVCD scan offset user data. + + /* RTP specific */ + int rtp_mode; + int rtp_payload_size; + + char *tc_opt_str; ///< timecode option string + AVTimecode tc; ///< timecode context + + uint8_t *ptr_lastgob; + int swap_uv; //vcr2 codec is an MPEG-2 variant with U and V swapped + int pack_pblocks; //xvmc needs to keep blocks without gaps. + int16_t (*pblocks[12])[64]; + + int16_t (*block)[64]; ///< points to one of the following blocks + int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block + int (*decode_mb)(struct MpegEncContext *s, int16_t block[12][64]); // used by some codecs to avoid a switch() + + int32_t (*block32)[12][64]; + int dpcm_direction; // 0 = DCT, 1 = DPCM top to bottom scan, -1 = DPCM bottom to top scan + int16_t (*dpcm_macroblock)[3][256]; + +#define SLICE_OK 0 +#define SLICE_ERROR -1 +#define SLICE_END -2 /// clipping, 1-> use a nice continuous function to limit qscale within qmin/qmax. + */ + float rc_qsquish; + float rc_qmod_amp; + int rc_qmod_freq; + float rc_initial_cplx; + float rc_buffer_aggressivity; + float border_masking; + int lmin, lmax; + int vbv_ignore_qmax; + + char *rc_eq; + + /* temp buffers for rate control */ + float *cplx_tab, *bits_tab; + + /* flag to indicate a reinitialization is required, e.g. after + * a frame size change */ + int context_reinit; + + ERContext er; + + int error_rate; + + /* temporary frames used by b_frame_strategy = 2 */ + AVFrame *tmp_frames[MAX_B_FRAMES + 2]; + int b_frame_strategy; + int b_sensitivity; + + /* frame skip options for encoding */ + int frame_skip_threshold; + int frame_skip_factor; + int frame_skip_exp; + int frame_skip_cmp; + + int scenechange_threshold; + int noise_reduction; +} MpegEncContext; + +/* mpegvideo_enc common options */ +#define FF_MPV_FLAG_SKIP_RD 0x0001 +#define FF_MPV_FLAG_STRICT_GOP 0x0002 +#define FF_MPV_FLAG_QP_RD 0x0004 +#define FF_MPV_FLAG_CBP_RD 0x0008 +#define FF_MPV_FLAG_NAQ 0x0010 +#define FF_MPV_FLAG_MV0 0x0020 + +#define FF_MPV_OPT_CMP_FUNC \ +{ "sad", "Sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "sse", "Sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "satd", "Sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "dct", "Sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "psnr", "Sum of squared quantization errors, low quality", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "bit", "Number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "rd", "Rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "zero", "Zero", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "vsad", "Sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "vsse", "Sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "nsse", "Noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "dct264", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT264 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{ "msad", "Sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" } + +#ifndef FF_MPV_OFFSET +#define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x) +#endif +#define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM) +#define FF_MPV_COMMON_OPTS \ +FF_MPV_OPT_CMP_FUNC, \ +{ "mpv_flags", "Flags common for all mpegvideo-based encoders.", FF_MPV_OFFSET(mpv_flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "mpv_flags" },\ +{ "skip_rd", "RD optimal MB level residual skipping", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_SKIP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\ +{ "strict_gop", "Strictly enforce gop size", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_STRICT_GOP }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\ +{ "qp_rd", "Use rate distortion optimization for qp selection", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_QP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\ +{ "cbp_rd", "use rate distortion optimization for CBP", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_CBP_RD }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\ +{ "naq", "normalize adaptive quantization", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_NAQ }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\ +{ "mv0", "always try a mb with mv=<0,0>", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_MV0 }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\ +{ "luma_elim_threshold", "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)",\ + FF_MPV_OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\ +{ "chroma_elim_threshold", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)",\ + FF_MPV_OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\ +{ "quantizer_noise_shaping", NULL, FF_MPV_OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },\ +{ "error_rate", "Simulate errors in the bitstream to test error concealment.", \ + FF_MPV_OFFSET(error_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },\ +{"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", \ + FF_MPV_OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0, 99, FF_MPV_OPT_FLAGS}, \ +{"rc_qmod_amp", "experimental quantizer modulation", FF_MPV_OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \ +{"rc_qmod_freq", "experimental quantizer modulation", FF_MPV_OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS}, \ +{"rc_eq", "Set rate control equation. When computing the expression, besides the standard functions " \ + "defined in the section 'Expression Evaluation', the following functions are available: " \ + "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv " \ + "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.", \ + FF_MPV_OFFSET(rc_eq), AV_OPT_TYPE_STRING, .flags = FF_MPV_OPT_FLAGS }, \ +{"rc_init_cplx", "initial complexity for 1-pass encoding", FF_MPV_OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \ +{"rc_buf_aggressivity", "currently useless", FF_MPV_OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \ +{"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \ +{"lmin", "minimum Lagrange factor (VBR)", FF_MPV_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 = 2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"lmax", "maximum Lagrange factor (VBR)", FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"ibias", "intra quant bias", FF_MPV_OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"pbias", "inter quant bias", FF_MPV_OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"rc_strategy", "ratecontrol method", FF_MPV_OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED, "rc_strategy" }, \ + { "ffmpeg", "deprecated, does nothing", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED, "rc_strategy" }, \ + { "xvid", "deprecated, does nothing", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FF_MPV_OPT_FLAGS | AV_OPT_FLAG_DEPRECATED, "rc_strategy" }, \ +{"motion_est", "motion estimation algorithm", FF_MPV_OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_XONE, FF_MPV_OPT_FLAGS, "motion_est" }, \ +{ "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \ +{ "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \ +{ "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" }, \ +{ "force_duplicated_matrix", "Always write luma and chroma matrix for mjpeg, useful for rtp streaming.", FF_MPV_OFFSET(force_duplicated_matrix), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS }, \ +{"b_strategy", "Strategy to choose between I/P/B-frames", FF_MPV_OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, FF_MPV_OPT_FLAGS }, \ +{"b_sensitivity", "Adjust sensitivity of b_frame_strategy 1", FF_MPV_OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"brd_scale", "Downscale frames for dynamic B-frame decision", FF_MPV_OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 3, FF_MPV_OPT_FLAGS }, \ +{"skip_threshold", "Frame skip threshold", FF_MPV_OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"skip_factor", "Frame skip factor", FF_MPV_OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"skip_exp", "Frame skip exponent", FF_MPV_OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"skip_cmp", "Frame skip compare function", FF_MPV_OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \ +{"sc_threshold", "Scene change threshold", FF_MPV_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"noise_reduction", "Noise reduction", FF_MPV_OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"mpeg_quant", "Use MPEG quantizers instead of H.263", FF_MPV_OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FF_MPV_OPT_FLAGS }, \ +{"ps", "RTP payload size in bytes", FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"mepc", "Motion estimation bitrate penalty compensation (1.0 = 256)", FF_MPV_OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"mepre", "pre motion estimation", FF_MPV_OFFSET(me_pre), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \ +{"a53cc", "Use A53 Closed Captions (if available)", FF_MPV_OFFSET(a53_cc), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FF_MPV_OPT_FLAGS }, \ + +extern const AVOption ff_mpv_generic_options[]; + +/** + * Set the given MpegEncContext to common defaults (same for encoding + * and decoding). The changed fields will not depend upon the prior + * state of the MpegEncContext. + */ +void ff_mpv_common_defaults(MpegEncContext *s); + +void ff_dct_encode_init_x86(MpegEncContext *s); + +int ff_mpv_common_init(MpegEncContext *s); +void ff_mpv_common_init_arm(MpegEncContext *s); +void ff_mpv_common_init_axp(MpegEncContext *s); +void ff_mpv_common_init_neon(MpegEncContext *s); +void ff_mpv_common_init_ppc(MpegEncContext *s); +void ff_mpv_common_init_x86(MpegEncContext *s); +void ff_mpv_common_init_mips(MpegEncContext *s); + +int ff_mpv_common_frame_size_change(MpegEncContext *s); +void ff_mpv_common_end(MpegEncContext *s); + +void ff_mpv_decode_defaults(MpegEncContext *s); +void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx); +void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]); +void ff_mpv_report_decode_progress(MpegEncContext *s); + +int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx); +void ff_mpv_frame_end(MpegEncContext *s); + +int ff_mpv_encode_init(AVCodecContext *avctx); +void ff_mpv_encode_init_x86(MpegEncContext *s); + +int ff_mpv_encode_end(AVCodecContext *avctx); +int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *frame, int *got_packet); +int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t size_increase); + +void ff_clean_intra_table_entries(MpegEncContext *s); +void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h); +void ff_mpeg_flush(AVCodecContext *avctx); + +void ff_print_debug_info(MpegEncContext *s, Picture *p, AVFrame *pict); + +int ff_mpv_export_qp_table(MpegEncContext *s, AVFrame *f, Picture *p, int qp_type); + +void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix); + +int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src); +int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src); +void ff_set_qscale(MpegEncContext * s, int qscale); + +void ff_mpv_idct_init(MpegEncContext *s); +int ff_dct_encode_init(MpegEncContext *s); +void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64], uint16_t (*qmat16)[2][64], + const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra); +int ff_dct_quantize_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow); +void ff_block_permute(int16_t *block, uint8_t *permutation, + const uint8_t *scantable, int last); +void ff_init_block_index(MpegEncContext *s); + +void ff_mpv_motion(MpegEncContext *s, + uint8_t *dest_y, uint8_t *dest_cb, + uint8_t *dest_cr, int dir, + uint8_t **ref_picture, + op_pixels_func (*pix_op)[4], + qpel_mc_func (*qpix_op)[16]); + +static inline void ff_update_block_index(MpegEncContext *s){ + const int bytes_per_pixel = 1 + (s->avctx->bits_per_raw_sample > 8); + const int block_size= (8*bytes_per_pixel) >> s->avctx->lowres; + + s->block_index[0]+=2; + s->block_index[1]+=2; + s->block_index[2]+=2; + s->block_index[3]+=2; + s->block_index[4]++; + s->block_index[5]++; + s->dest[0]+= 2*block_size; + s->dest[1]+= (2 >> s->chroma_x_shift) * block_size; + s->dest[2]+= (2 >> s->chroma_x_shift) * block_size; +} + +static inline int get_bits_diff(MpegEncContext *s){ + const int bits= put_bits_count(&s->pb); + const int last= s->last_bits; + + s->last_bits = bits; + + return bits - last; +} + +static inline int mpeg_get_qscale(MpegEncContext *s) +{ + int qscale = get_bits(&s->gb, 5); + if (s->q_scale_type) + return ff_mpeg2_non_linear_qscale[qscale]; + else + return qscale << 1; +} + +#endif /* AVCODEC_MPEGVIDEO_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodata.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodata.c new file mode 100644 index 000000000..5f1d8f7c0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodata.c @@ -0,0 +1,109 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +const uint8_t ff_default_chroma_qscale_table[32] = { +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; + +const uint8_t ff_mpeg2_non_linear_qscale[32] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 10, 12, 14, 16, 18, 20, 22, + 24, 28, 32, 36, 40, 44, 48, 52, + 56, 64, 72, 80, 88, 96, 104, 112, +}; + +const uint8_t ff_mpeg1_dc_scale_table[128] = { +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static const uint8_t mpeg2_dc_scale_table1[128] = { +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +}; + +static const uint8_t mpeg2_dc_scale_table2[128] = { +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +}; + +static const uint8_t mpeg2_dc_scale_table3[128] = { +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +const uint8_t *const ff_mpeg2_dc_scale_table[4] = { + ff_mpeg1_dc_scale_table, + mpeg2_dc_scale_table1, + mpeg2_dc_scale_table2, + mpeg2_dc_scale_table3, +}; + +const uint8_t ff_alternate_horizontal_scan[64] = { + 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, +}; + +const uint8_t ff_alternate_vertical_scan[64] = { + 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, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodata.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodata.h new file mode 100644 index 000000000..14f4806d6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodata.h @@ -0,0 +1,35 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MPEGVIDEODATA_H +#define AVCODEC_MPEGVIDEODATA_H + +#include + +/* encoding scans */ +extern const uint8_t ff_alternate_horizontal_scan[64]; +extern const uint8_t ff_alternate_vertical_scan[64]; + +extern const uint8_t ff_mpeg1_dc_scale_table[128]; +extern const uint8_t * const ff_mpeg2_dc_scale_table[4]; + +extern const uint8_t ff_mpeg2_non_linear_qscale[32]; + +extern const uint8_t ff_default_chroma_qscale_table[32]; + +#endif /* AVCODEC_MPEGVIDEODATA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodsp.c new file mode 100644 index 000000000..a58e45ad4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodsp.c @@ -0,0 +1,119 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/common.h" +#include "mpegvideodsp.h" + +static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, + int x16, int y16, int rounder) +{ + const int A = (16 - x16) * (16 - y16); + const int B = (x16) * (16 - y16); + const int C = (16 - x16) * (y16); + const int D = (x16) * (y16); + int i; + + for (i = 0; i < h; i++) { + dst[0] = (A * src[0] + B * src[1] + C * src[stride + 0] + D * src[stride + 1] + rounder) >> 8; + dst[1] = (A * src[1] + B * src[2] + C * src[stride + 1] + D * src[stride + 2] + rounder) >> 8; + dst[2] = (A * src[2] + B * src[3] + C * src[stride + 2] + D * src[stride + 3] + rounder) >> 8; + dst[3] = (A * src[3] + B * src[4] + C * src[stride + 3] + D * src[stride + 4] + rounder) >> 8; + dst[4] = (A * src[4] + B * src[5] + C * src[stride + 4] + D * src[stride + 5] + rounder) >> 8; + dst[5] = (A * src[5] + B * src[6] + C * src[stride + 5] + D * src[stride + 6] + rounder) >> 8; + dst[6] = (A * src[6] + B * src[7] + C * src[stride + 6] + D * src[stride + 7] + rounder) >> 8; + dst[7] = (A * src[7] + B * src[8] + C * src[stride + 7] + D * src[stride + 8] + rounder) >> 8; + dst += stride; + src += stride; + } +} + +void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, + int width, int height) +{ + int y, vx, vy; + const int s = 1 << shift; + + width--; + height--; + + for (y = 0; y < h; y++) { + int x; + + vx = ox; + vy = oy; + for (x = 0; x < 8; x++) { // FIXME: optimize + int index; + int src_x = vx >> 16; + int src_y = vy >> 16; + int frac_x = src_x & (s - 1); + int frac_y = src_y & (s - 1); + + src_x >>= shift; + src_y >>= shift; + + if ((unsigned) src_x < width) { + if ((unsigned) src_y < height) { + index = src_x + src_y * stride; + dst[y * stride + x] = + ((src[index] * (s - frac_x) + + src[index + 1] * frac_x) * (s - frac_y) + + (src[index + stride] * (s - frac_x) + + src[index + stride + 1] * frac_x) * frac_y + + r) >> (shift * 2); + } else { + index = src_x + av_clip(src_y, 0, height) * stride; + dst[y * stride + x] = + ((src[index] * (s - frac_x) + + src[index + 1] * frac_x) * s + + r) >> (shift * 2); + } + } else { + if ((unsigned) src_y < height) { + index = av_clip(src_x, 0, width) + src_y * stride; + dst[y * stride + x] = + ((src[index] * (s - frac_y) + + src[index + stride] * frac_y) * s + + r) >> (shift * 2); + } else { + index = av_clip(src_x, 0, width) + + av_clip(src_y, 0, height) * stride; + dst[y * stride + x] = src[index]; + } + } + + vx += dxx; + vy += dyx; + } + ox += dxy; + oy += dyy; + } +} + +av_cold void ff_mpegvideodsp_init(MpegVideoDSPContext *c) +{ + c->gmc1 = gmc1_c; + c->gmc = ff_gmc_c; + + if (ARCH_PPC) + ff_mpegvideodsp_init_ppc(c); + if (ARCH_X86) + ff_mpegvideodsp_init_x86(c); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodsp.h new file mode 100644 index 000000000..293e2548d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideodsp.h @@ -0,0 +1,47 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MPEGVIDEODSP_H +#define AVCODEC_MPEGVIDEODSP_H + +#include + +void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, + int width, int height); + +typedef struct MpegVideoDSPContext { + /** + * translational global motion compensation. + */ + void (*gmc1)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */, + int srcStride, int h, int x16, int y16, int rounder); + /** + * global motion compensation. + */ + void (*gmc)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */, + int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, + int shift, int r, int width, int height); +} MpegVideoDSPContext; + +void ff_mpegvideodsp_init(MpegVideoDSPContext *c); +void ff_mpegvideodsp_init_ppc(MpegVideoDSPContext *c); +void ff_mpegvideodsp_init_x86(MpegVideoDSPContext *c); + +#endif /* AVCODEC_MPEGVIDEODSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideoencdsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideoencdsp.c new file mode 100644 index 000000000..a34ab3553 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideoencdsp.c @@ -0,0 +1,256 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "config.h" +#include "libavutil/avassert.h" +#include "libavutil/attributes.h" +#include "libavutil/imgutils.h" +#include "avcodec.h" +#include "me_cmp.h" +#include "mpegvideoencdsp.h" + +static int try_8x8basis_c(int16_t rem[64], int16_t weight[64], + int16_t basis[64], int scale) +{ + int i; + unsigned int sum = 0; + + for (i = 0; i < 8 * 8; i++) { + int b = rem[i] + ((basis[i] * scale + + (1 << (BASIS_SHIFT - RECON_SHIFT - 1))) >> + (BASIS_SHIFT - RECON_SHIFT)); + int w = weight[i]; + b >>= RECON_SHIFT; + av_assert2(-512 < b && b < 512); + + sum += (w * b) * (w * b) >> 4; + } + return sum >> 2; +} + +static void add_8x8basis_c(int16_t rem[64], int16_t basis[64], int scale) +{ + int i; + + for (i = 0; i < 8 * 8; i++) + rem[i] += (basis[i] * scale + + (1 << (BASIS_SHIFT - RECON_SHIFT - 1))) >> + (BASIS_SHIFT - RECON_SHIFT); +} + +static int pix_sum_c(uint8_t *pix, int line_size) +{ + int s = 0, i, j; + + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j += 8) { + s += pix[0]; + s += pix[1]; + s += pix[2]; + s += pix[3]; + s += pix[4]; + s += pix[5]; + s += pix[6]; + s += pix[7]; + pix += 8; + } + pix += line_size - 16; + } + return s; +} + +static int pix_norm1_c(uint8_t *pix, int line_size) +{ + int s = 0, i, j; + const uint32_t *sq = ff_square_tab + 256; + + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j += 8) { +#if HAVE_FAST_64BIT + register uint64_t x = *(uint64_t *) pix; + s += sq[x & 0xff]; + s += sq[(x >> 8) & 0xff]; + s += sq[(x >> 16) & 0xff]; + s += sq[(x >> 24) & 0xff]; + s += sq[(x >> 32) & 0xff]; + s += sq[(x >> 40) & 0xff]; + s += sq[(x >> 48) & 0xff]; + s += sq[(x >> 56) & 0xff]; +#else + register uint32_t x = *(uint32_t *) pix; + s += sq[x & 0xff]; + s += sq[(x >> 8) & 0xff]; + s += sq[(x >> 16) & 0xff]; + s += sq[(x >> 24) & 0xff]; + x = *(uint32_t *) (pix + 4); + s += sq[x & 0xff]; + s += sq[(x >> 8) & 0xff]; + s += sq[(x >> 16) & 0xff]; + s += sq[(x >> 24) & 0xff]; +#endif + pix += 8; + } + pix += line_size - 16; + } + return s; +} + +/* draw the edges of width 'w' of an image of size width, height */ +// FIXME: Check that this is OK for MPEG-4 interlaced. +static void draw_edges_8_c(uint8_t *buf, int wrap, int width, int height, + int w, int h, int sides) +{ + uint8_t *ptr = buf, *last_line; + int i; + + /* left and right */ + for (i = 0; i < height; i++) { + memset(ptr - w, ptr[0], w); + memset(ptr + width, ptr[width - 1], w); + ptr += wrap; + } + + /* top and bottom + corners */ + buf -= w; + last_line = buf + (height - 1) * wrap; + if (sides & EDGE_TOP) + for (i = 0; i < h; i++) + // top + memcpy(buf - (i + 1) * wrap, buf, width + w + w); + if (sides & EDGE_BOTTOM) + for (i = 0; i < h; i++) + // bottom + memcpy(last_line + (i + 1) * wrap, last_line, width + w + w); +} + +/* 2x2 -> 1x1 */ +static void shrink22(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w; + const uint8_t *s1, *s2; + uint8_t *d; + + for (; height > 0; height--) { + s1 = src; + s2 = s1 + src_wrap; + d = dst; + for (w = width; w >= 4; w -= 4) { + d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; + d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2; + d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2; + d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2; + s1 += 8; + s2 += 8; + d += 4; + } + for (; w > 0; w--) { + d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; + s1 += 2; + s2 += 2; + d++; + } + src += 2 * src_wrap; + dst += dst_wrap; + } +} + +/* 4x4 -> 1x1 */ +static void shrink44(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w; + const uint8_t *s1, *s2, *s3, *s4; + uint8_t *d; + + for (; height > 0; height--) { + s1 = src; + s2 = s1 + src_wrap; + s3 = s2 + src_wrap; + s4 = s3 + src_wrap; + d = dst; + for (w = width; w > 0; w--) { + d[0] = (s1[0] + s1[1] + s1[2] + s1[3] + + s2[0] + s2[1] + s2[2] + s2[3] + + s3[0] + s3[1] + s3[2] + s3[3] + + s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4; + s1 += 4; + s2 += 4; + s3 += 4; + s4 += 4; + d++; + } + src += 4 * src_wrap; + dst += dst_wrap; + } +} + +/* 8x8 -> 1x1 */ +static void shrink88(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w, i; + + for (; height > 0; height--) { + for(w = width;w > 0; w--) { + int tmp = 0; + for (i = 0; i < 8; i++) { + tmp += src[0] + src[1] + src[2] + src[3] + + src[4] + src[5] + src[6] + src[7]; + src += src_wrap; + } + *(dst++) = (tmp + 32) >> 6; + src += 8 - 8 * src_wrap; + } + src += 8 * src_wrap - 8 * width; + dst += dst_wrap - width; + } +} + +av_cold void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c, + AVCodecContext *avctx) +{ + c->try_8x8basis = try_8x8basis_c; + c->add_8x8basis = add_8x8basis_c; + + c->shrink[0] = av_image_copy_plane; + c->shrink[1] = shrink22; + c->shrink[2] = shrink44; + c->shrink[3] = shrink88; + + c->pix_sum = pix_sum_c; + c->pix_norm1 = pix_norm1_c; + + c->draw_edges = draw_edges_8_c; + + if (ARCH_ARM) + ff_mpegvideoencdsp_init_arm(c, avctx); + if (ARCH_PPC) + ff_mpegvideoencdsp_init_ppc(c, avctx); + if (ARCH_X86) + ff_mpegvideoencdsp_init_x86(c, avctx); + if (ARCH_MIPS) + ff_mpegvideoencdsp_init_mips(c, avctx); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideoencdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideoencdsp.h new file mode 100644 index 000000000..33f0282fc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/mpegvideoencdsp.h @@ -0,0 +1,58 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MPEGVIDEOENCDSP_H +#define AVCODEC_MPEGVIDEOENCDSP_H + +#include + +#include "avcodec.h" + +#define BASIS_SHIFT 16 +#define RECON_SHIFT 6 + +#define EDGE_TOP 1 +#define EDGE_BOTTOM 2 + +typedef struct MpegvideoEncDSPContext { + int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], + int16_t basis[64], int scale); + void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale); + + int (*pix_sum)(uint8_t *pix, int line_size); + int (*pix_norm1)(uint8_t *pix, int line_size); + + void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, + int src_wrap, int width, int height); + + void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, + int w, int h, int sides); +} MpegvideoEncDSPContext; + +void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c, + AVCodecContext *avctx); +void ff_mpegvideoencdsp_init_arm(MpegvideoEncDSPContext *c, + AVCodecContext *avctx); +void ff_mpegvideoencdsp_init_ppc(MpegvideoEncDSPContext *c, + AVCodecContext *avctx); +void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c, + AVCodecContext *avctx); +void ff_mpegvideoencdsp_init_mips(MpegvideoEncDSPContext *c, + AVCodecContext *avctx); + +#endif /* AVCODEC_MPEGVIDEOENCDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/null_bsf.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/null_bsf.c new file mode 100644 index 000000000..24d26dfb1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/null_bsf.c @@ -0,0 +1,35 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Null bitstream filter -- pass the input through unchanged. + */ + +#include "avcodec.h" +#include "bsf.h" + +static int null_filter(AVBSFContext *ctx, AVPacket *pkt) +{ + return ff_bsf_get_packet_ref(ctx, pkt); +} + +const AVBitStreamFilter ff_null_bsf = { + .name = "null", + .filter = null_filter, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/options.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/options.c new file mode 100644 index 000000000..35e8ac931 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/options.c @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Options definition for AVCodecContext. + */ + +#include "avcodec.h" +#include "internal.h" +#include "libavutil/avassert.h" +#include "libavutil/internal.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include + +FF_DISABLE_DEPRECATION_WARNINGS +#include "options_table.h" +FF_ENABLE_DEPRECATION_WARNINGS + +static const char* context_to_name(void* ptr) { + AVCodecContext *avc= ptr; + + if(avc && avc->codec && avc->codec->name) + return avc->codec->name; + else + return "NULL"; +} + +static void *codec_child_next(void *obj, void *prev) +{ + AVCodecContext *s = obj; + if (!prev && s->codec && s->codec->priv_class && s->priv_data) + return s->priv_data; + return NULL; +} + +static const AVClass *codec_child_class_next(const AVClass *prev) +{ + AVCodec *c = NULL; + + /* find the codec that corresponds to prev */ + while (prev && (c = av_codec_next(c))) + if (c->priv_class == prev) + break; + + /* find next codec with priv options */ + while (c = av_codec_next(c)) + if (c->priv_class) + return c->priv_class; + return NULL; +} + +static AVClassCategory get_category(void *ptr) +{ + AVCodecContext* avctx = ptr; + if(avctx->codec && avctx->codec->decode) return AV_CLASS_CATEGORY_DECODER; + else return AV_CLASS_CATEGORY_ENCODER; +} + +static const AVClass av_codec_context_class = { + .class_name = "AVCodecContext", + .item_name = context_to_name, + .option = avcodec_options, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset), + .child_next = codec_child_next, + .child_class_next = codec_child_class_next, + .category = AV_CLASS_CATEGORY_ENCODER, + .get_category = get_category, +}; + +static int init_context_defaults(AVCodecContext *s, const AVCodec *codec) +{ + int flags=0; + memset(s, 0, sizeof(AVCodecContext)); + + s->av_class = &av_codec_context_class; + + s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN; + if (codec) { + s->codec = codec; + s->codec_id = codec->id; + } + + if(s->codec_type == AVMEDIA_TYPE_AUDIO) + flags= AV_OPT_FLAG_AUDIO_PARAM; + else if(s->codec_type == AVMEDIA_TYPE_VIDEO) + flags= AV_OPT_FLAG_VIDEO_PARAM; + else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE) + flags= AV_OPT_FLAG_SUBTITLE_PARAM; + av_opt_set_defaults2(s, flags, flags); + + s->time_base = (AVRational){0,1}; + s->framerate = (AVRational){ 0, 1 }; + s->pkt_timebase = (AVRational){ 0, 1 }; + s->get_buffer2 = avcodec_default_get_buffer2; + s->get_format = avcodec_default_get_format; + s->execute = avcodec_default_execute; + s->execute2 = avcodec_default_execute2; + s->sample_aspect_ratio = (AVRational){0,1}; + s->pix_fmt = AV_PIX_FMT_NONE; + s->sw_pix_fmt = AV_PIX_FMT_NONE; + s->sample_fmt = AV_SAMPLE_FMT_NONE; + + s->reordered_opaque = AV_NOPTS_VALUE; + if(codec && codec->priv_data_size){ + if(!s->priv_data){ + s->priv_data= av_mallocz(codec->priv_data_size); + if (!s->priv_data) { + return AVERROR(ENOMEM); + } + } + if(codec->priv_class){ + *(const AVClass**)s->priv_data = codec->priv_class; + av_opt_set_defaults(s->priv_data); + } + } + if (codec && codec->defaults) { + int ret; + const AVCodecDefault *d = codec->defaults; + while (d->key) { + ret = av_opt_set(s, d->key, d->value, 0); + av_assert0(ret >= 0); + d++; + } + } + return 0; +} + +#if FF_API_GET_CONTEXT_DEFAULTS +int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) +{ + return init_context_defaults(s, codec); +} +#endif + +AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) +{ + AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); + + if (!avctx) + return NULL; + + if (init_context_defaults(avctx, codec) < 0) { + av_free(avctx); + return NULL; + } + + return avctx; +} + +void avcodec_free_context(AVCodecContext **pavctx) +{ + AVCodecContext *avctx = *pavctx; + + if (!avctx) + return; + + avcodec_close(avctx); + + av_freep(&avctx->extradata); + av_freep(&avctx->subtitle_header); + av_freep(&avctx->intra_matrix); + av_freep(&avctx->inter_matrix); + av_freep(&avctx->rc_override); + + av_freep(pavctx); +} + +#if FF_API_COPY_CONTEXT +static void copy_context_reset(AVCodecContext *avctx) +{ + int i; + + av_opt_free(avctx); +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + av_frame_free(&avctx->coded_frame); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + av_freep(&avctx->rc_override); + av_freep(&avctx->intra_matrix); + av_freep(&avctx->inter_matrix); + av_freep(&avctx->extradata); + av_freep(&avctx->subtitle_header); + av_buffer_unref(&avctx->hw_frames_ctx); + av_buffer_unref(&avctx->hw_device_ctx); + for (i = 0; i < avctx->nb_coded_side_data; i++) + av_freep(&avctx->coded_side_data[i].data); + av_freep(&avctx->coded_side_data); + avctx->subtitle_header_size = 0; + avctx->nb_coded_side_data = 0; + avctx->extradata_size = 0; +} + +int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) +{ + const AVCodec *orig_codec = dest->codec; + uint8_t *orig_priv_data = dest->priv_data; + + if (avcodec_is_open(dest)) { // check that the dest context is uninitialized + av_log(dest, AV_LOG_ERROR, + "Tried to copy AVCodecContext %p into already-initialized %p\n", + src, dest); + return AVERROR(EINVAL); + } + + copy_context_reset(dest); + + memcpy(dest, src, sizeof(*dest)); + av_opt_copy(dest, src); + + dest->priv_data = orig_priv_data; + dest->codec = orig_codec; + + if (orig_priv_data && src->codec && src->codec->priv_class && + dest->codec && dest->codec->priv_class) + av_opt_copy(orig_priv_data, src->priv_data); + + + /* set values specific to opened codecs back to their default state */ + dest->slice_offset = NULL; + dest->hwaccel = NULL; + dest->internal = NULL; +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + dest->coded_frame = NULL; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + /* reallocate values that should be allocated separately */ + dest->extradata = NULL; + dest->coded_side_data = NULL; + dest->intra_matrix = NULL; + dest->inter_matrix = NULL; + dest->rc_override = NULL; + dest->subtitle_header = NULL; + dest->hw_frames_ctx = NULL; + dest->hw_device_ctx = NULL; + dest->nb_coded_side_data = 0; + +#define alloc_and_copy_or_fail(obj, size, pad) \ + if (src->obj && size > 0) { \ + dest->obj = av_malloc(size + pad); \ + if (!dest->obj) \ + goto fail; \ + memcpy(dest->obj, src->obj, size); \ + if (pad) \ + memset(((uint8_t *) dest->obj) + size, 0, pad); \ + } + alloc_and_copy_or_fail(extradata, src->extradata_size, + AV_INPUT_BUFFER_PADDING_SIZE); + dest->extradata_size = src->extradata_size; + alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0); + alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0); + alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0); + alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1); + av_assert0(dest->subtitle_header_size == src->subtitle_header_size); +#undef alloc_and_copy_or_fail + + if (src->hw_frames_ctx) { + dest->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); + if (!dest->hw_frames_ctx) + goto fail; + } + + return 0; + +fail: + copy_context_reset(dest); + return AVERROR(ENOMEM); +} +#endif + +const AVClass *avcodec_get_class(void) +{ + return &av_codec_context_class; +} + +#define FOFFSET(x) offsetof(AVFrame,x) + +static const AVOption frame_options[]={ +{"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0}, +{"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0}, +{"pkt_size", "", FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0}, +{"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0}, +{"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, +{"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, +{"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.i64 = -1 }, 0, INT_MAX, 0}, +{"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0}, +{"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, +{NULL}, +}; + +static const AVClass av_frame_class = { + .class_name = "AVFrame", + .item_name = NULL, + .option = frame_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVClass *avcodec_get_frame_class(void) +{ + return &av_frame_class; +} + +#define SROFFSET(x) offsetof(AVSubtitleRect,x) + +static const AVOption subtitle_rect_options[]={ +{"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, +{"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, +{"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, +{"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, +{"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, +{"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, "flags"}, +{"forced", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0}, +{NULL}, +}; + +static const AVClass av_subtitle_rect_class = { + .class_name = "AVSubtitleRect", + .item_name = NULL, + .option = subtitle_rect_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVClass *avcodec_get_subtitle_rect_class(void) +{ + return &av_subtitle_rect_class; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/options_table.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/options_table.h new file mode 100644 index 000000000..4a266eca1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/options_table.h @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPTIONS_TABLE_H +#define AVCODEC_OPTIONS_TABLE_H + +#include +#include +#include + +#include "libavutil/opt.h" +#include "avcodec.h" +#include "version.h" + +#define OFFSET(x) offsetof(AVCodecContext,x) +#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C +//these names are too long to be readable +#define V AV_OPT_FLAG_VIDEO_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM +#define S AV_OPT_FLAG_SUBTITLE_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM +#define D AV_OPT_FLAG_DECODING_PARAM + +#define AV_CODEC_DEFAULT_BITRATE 200*1000 + +static const AVOption avcodec_options[] = { +{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT64_MAX, A|V|E}, +{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = 128*1000 }, 0, INT_MAX, A|E}, +{"bt", "Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far " + "ratecontrol is willing to deviate from the target average bitrate value. This is not related " + "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.", + OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, +{"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"}, +{"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" }, +{"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"}, +{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"}, +{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"}, +{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"}, +{"pass1", "use internal 2-pass ratecontrol in first pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"}, +{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"}, +{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"}, +{"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"}, +{"truncated", "Input bitstream might be randomly truncated", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, V|D, "flags"}, +{"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"}, +{"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"}, +{"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"}, +{"bitexact", "use only bitexact functions (except (I)DCT)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"}, +{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"}, +{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"}, +{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"}, +{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"}, +{"drop_changed", "Drop frames whose parameters differ from first decoded frame", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_DROPCHANGED }, INT_MIN, INT_MAX, A|V|D, "flags"}, +{"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"}, +{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"}, +{"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"}, +{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"}, +{"export_mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_EXPORT_MVS}, INT_MIN, INT_MAX, V|D, "flags2"}, +{"skip_manual", "do not skip samples and export skip information as frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, V|D, "flags2"}, +{"ass_ro_flush_noop", "do not reset ASS ReadOrder field on flush", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_RO_FLUSH_NOOP}, INT_MIN, INT_MAX, S|D, "flags2"}, +{"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, INT_MAX}, +{"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E}, +{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, +{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, +{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E}, +{"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|E}, +{"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"delay", NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"qcomp", "video quantizer scale compression (VBR). Constant of ratecontrol equation. " + "Recommended range for default rc_eq: 0.0-1.0", + OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E}, +{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E}, +{"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E}, +{"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E}, +{"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E}, +{"bf", "set maximum number of B-frames between non-B-frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, INT_MAX, V|E}, +{"b_qfactor", "QP factor between P- and B-frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, V|E}, +{"ps", "RTP payload size in bytes", OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#if FF_API_STAT_BITS +{"mv_bits", NULL, OFFSET(mv_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"header_bits", NULL, OFFSET(header_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"i_tex_bits", NULL, OFFSET(i_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"p_tex_bits", NULL, OFFSET(p_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"i_count", NULL, OFFSET(i_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"p_count", NULL, OFFSET(p_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"skip_count", NULL, OFFSET(skip_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"misc_bits", NULL, OFFSET(misc_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"frame_bits", NULL, OFFSET(frame_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +#endif +{"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"}, +{"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"}, +{"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"}, +{"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"}, +{"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"}, +{"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"}, +{"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"}, +{"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"}, +{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"edge", "edge padding bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"}, +{"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"}, +{"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"}, +{"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"}, +{"iedge", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_IEDGE }, INT_MIN, INT_MAX, V|D, "bug"}, +{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"}, +{"b_qoffset", "QP offset between P- and B-frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, +{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"careful", "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +#if FF_API_PRIVATE_OPT +{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"maxrate", "maximum bitrate (in bits/s). Used for VBV together with bufsize.", OFFSET(rc_max_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT_MAX, V|A|E}, +{"minrate", "minimum bitrate (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.", + OFFSET(rc_min_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|E}, +{"i_qfactor", "QP factor between P- and I-frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E}, +{"i_qoffset", "QP offset between P- and I-frames", OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, -FLT_MAX, FLT_MAX, V|E}, +{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"}, +{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"}, +{"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"}, +{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"}, +{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"}, +{"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"p_mask", "inter masking", OFFSET(p_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E}, +{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"}, +{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"xvid", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"xvidmmx", "deprecated, for compatibility only", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"}, +{"simpleauto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"slice_count", NULL, OFFSET(slice_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"ec", "set error concealment strategy", OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.i64 = 3 }, INT_MIN, INT_MAX, V|D, "ec"}, +{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"}, +{"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"}, +{"favor_inter", "favor predicting from the previous frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_FAVOR_INTER }, INT_MIN, INT_MAX, V|D, "ec"}, +{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +#if FF_API_PRIVATE_OPT +{"pred", "prediction method", OFFSET(prediction_method), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "pred"}, +{"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_LEFT }, INT_MIN, INT_MAX, V|E, "pred"}, +{"plane", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_PLANE }, INT_MIN, INT_MAX, V|E, "pred"}, +{"median", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_MEDIAN }, INT_MIN, INT_MAX, V|E, "pred"}, +#endif +{"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E}, +{"sar", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E}, +{"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"}, +{"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"}, +{"rc", "rate control", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, "debug"}, +{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"}, +{"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, +{"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_DEBUG_MV +{"mv", "motion vector", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif +{"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"}, +{"green_metadata", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_GREEN_MD }, INT_MIN, INT_MAX, V|D, "debug"}, +{"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"}, +{"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"}, +{"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"}, +{"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"}, +{"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"}, +#if FF_API_DEBUG_MV +{"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"}, +{"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, +#endif +{"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"}, +{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"}, +{"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"}, +{"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"preme", "pre motion estimation", OFFSET(pre_me), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E}, +{"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +#if FF_API_CODER_TYPE +{"coder", NULL, OFFSET(coder_type), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"}, +{"vlc", "variable length coder / Huffman coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"}, +{"ac", "arithmetic coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_AC }, INT_MIN, INT_MAX, V|E, "coder"}, +{"raw", "raw (no encoding)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RAW }, INT_MIN, INT_MAX, V|E, "coder"}, +{"rle", "run-length coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RLE }, INT_MIN, INT_MAX, V|E, "coder"}, +#endif /* FF_API_CODER_TYPE */ +#if FF_API_PRIVATE_OPT +{"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, +{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"}, +{"simple", "use mbcmp", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"}, +{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"}, +{"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"}, +#if FF_API_PRIVATE_OPT +{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +#if FF_API_PRIVATE_OPT +{"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"threads", "set the number of threads", OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"}, +{"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"}, +{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 = 0 }, -8, 16, V|E}, +{"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E}, +{"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D}, +{"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D}, +{"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"}, +{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"}, +{"aac_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_MAIN }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ssr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_SSR }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ltp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LTP }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_he_v2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE_V2 }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LD }, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_eld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_ELD }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg2_aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg2_aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_es", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_hd_hra", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_HRA }, INT_MIN, INT_MAX, A|E, "profile"}, +{"dts_hd_ma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"}, +{"mpeg4_sp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"mpeg4_core", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_CORE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"mpeg4_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_MAIN }, INT_MIN, INT_MAX, V|E, "profile"}, +{"mpeg4_asp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_ADVANCED_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"}, +{"main10", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_HEVC_MAIN_10 }, INT_MIN, INT_MAX, V|E, "profile"}, +{"msbc", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_SBC_MSBC }, INT_MIN, INT_MAX, A|E, "profile"}, +{"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, +{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"}, +{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D}, +#if FF_API_PRIVATE_OPT +{"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +#endif +{"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"ildctcmp", "interlaced DCT compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"sad", "sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"sse", "sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"satd", "sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"dct", "sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"bit", "number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"rd", "rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"zero", "0", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +#if CONFIG_SNOW_ENCODER +{"w53", "5/3 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"w97", "9/7 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +#endif +{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"msad", "sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"}, +{"mblmin", "minimum macroblock Lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E}, +{"mblmax", "maximum macroblock Lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, V|E}, +#endif +{"skip_loop_filter", "skip loop filtering process for the selected frames", OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"skip_idct" , "skip IDCT/dequantization for the selected frames", OFFSET(skip_idct), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"skip_frame" , "skip decoding for the selected frames", OFFSET(skip_frame), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"none" , "discard no frame", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"default" , "discard useless frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"noref" , "discard all non-reference frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"bidir" , "discard all bidirectional frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"nokey" , "discard all frames except keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"nointra" , "discard all frames except I frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA}, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"all" , "discard all frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL }, INT_MIN, INT_MAX, V|D, "avdiscard"}, +{"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, 4, V|E}, +#if FF_API_PRIVATE_OPT +{"brd_scale", "downscale frames for dynamic B-frame decision", OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 10, V|E}, +#endif +{"keyint_min", "minimum interval between IDR-frames", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 = 25 }, INT_MIN, INT_MAX, V|E}, +{"refs", "reference frames to consider for motion compensation", OFFSET(refs), AV_OPT_TYPE_INT, {.i64 = 1 }, INT_MIN, INT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"chromaoffset", "chroma QP offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, +#endif +{"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +{"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 = 256 }, 0, INT_MAX, V|E}, +#if FF_API_PRIVATE_OPT +{"b_sensitivity", "adjust sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, V|E}, +#endif +{"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +#if FF_API_PRIVATE_OPT +{"min_prediction_order", NULL, OFFSET(min_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E}, +{"max_prediction_order", NULL, OFFSET(max_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E}, +{"timecode_frame_start", "GOP timecode frame start number, in non-drop-frame format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.i64 = -1 }, -1, INT64_MAX, V|E}, +#endif +{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX}, +{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_UINT64, {.i64 = DEFAULT }, 0, UINT64_MAX, A|E|D, "channel_layout"}, +{"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_UINT64, {.i64 = DEFAULT }, 0, UINT64_MAX, A|D, "request_channel_layout"}, +{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0.0, FLT_MAX, V|E}, +{"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT, {.dbl = 3 }, 0.0, FLT_MAX, V|E}, +{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D}, +{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt470m", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470BG }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"film", "Film", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_FILM }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"bt2020", "BT.2020", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte428", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte431", "SMPTE 431-2", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE431 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"smpte432", "SMPTE 422-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE432 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"jedec-p22", "JEDEC P22", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_JEDEC_P22 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"}, +{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_trc_type"}, +{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"gamma22", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"gamma28", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"linear", "Linear", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"log100", "Log", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"log316", "Log square root", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"iec61966-2-4", "IEC 61966-2-4", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt1361e", "BT.1361", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"iec61966-2-1", "IEC 61966-2-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt2020-10", "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt2020-12", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte2084", "SMPTE 2084", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE2084 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte428", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"arib-std-b67", "ARIB STD-B67", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_ARIB_STD_B67 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"log", "Log", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"log_sqrt", "Log square root", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"iec61966_2_4", "IEC 61966-2-4", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt1361", "BT.1361", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"iec61966_2_1", "IEC 61966-2-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt2020_10bit", "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"bt2020_12bit", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"smpte428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"}, +{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "colorspace_type"}, +{"rgb", "RGB", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"fcc", "FCC", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ycgco", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020nc", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020c", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"smpte2085", "SMPTE 2085", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE2085 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"ycocg", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"}, +{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX, V|E|D, "color_range_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"tv", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"pc", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"jpeg", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"}, +{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"left", "Left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_LEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"center", "Center", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_CENTER }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"topleft", "Top-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOPLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"top", "Top", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOP }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"bottomleft", "Bottom-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOMLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"bottom", "Bottom", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOM }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"}, +{"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX }, +{"slices", "set the number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E}, +{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, "thread_type"}, +{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, +{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, +{"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"}, +{"ma", "Main Audio Service", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"ef", "Effects", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EFFECTS }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"vi", "Visually Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"hi", "Hearing Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"di", "Dialogue", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_DIALOGUE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"co", "Commentary", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_COMMENTARY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"em", "Emergency", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"vo", "Voice Over", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"ka", "Karaoke", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, "request_sample_fmt"}, +{"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0}, +{"sub_charenc", "set input text subtitles character encoding", OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, S|D}, +{"sub_charenc_mode", "set input text subtitles character encoding mode", OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, "sub_charenc_mode"}, +{"do_nothing", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +{"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +{"ignore", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_IGNORE}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, +#if FF_API_ASS_TIMING +{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, 0, 1, S|D, "sub_text_format"}, +#else +{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS}, 0, 1, S|D, "sub_text_format"}, +#endif +{"ass", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS}, INT_MIN, INT_MAX, S|D, "sub_text_format"}, +#if FF_API_ASS_TIMING +{"ass_with_timings", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, INT_MIN, INT_MAX, S|D, "sub_text_format"}, +#endif +{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, A|V|D }, +#if FF_API_SIDEDATA_ONLY_PKT +{"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, A|V|E }, +#endif +{"apply_cropping", NULL, OFFSET(apply_cropping), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, V | D }, +{"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, V|D }, +{"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, "field_order" }, +{"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, "field_order" }, +{"tt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TT }, 0, 0, V|D|E, "field_order" }, +{"bb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BB }, 0, 0, V|D|E, "field_order" }, +{"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" }, +{"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" }, +{"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, A|V|S|D|E}, +{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, A|V|S|D }, +{"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 }, +{"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 }, +{"max_pixels", "Maximum number of pixels", OFFSET(max_pixels), AV_OPT_TYPE_INT64, {.i64 = INT_MAX }, 0, INT_MAX, A|V|S|D|E }, +{"hwaccel_flags", NULL, OFFSET(hwaccel_flags), AV_OPT_TYPE_FLAGS, {.i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, 0, UINT_MAX, V|D, "hwaccel_flags"}, +{"ignore_level", "ignore level even if the codec level used is unknown or higher than the maximum supported level reported by the hardware driver", 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, INT_MIN, INT_MAX, V | D, "hwaccel_flags" }, +{"allow_high_depth", "allow to output YUV pixel formats with a different chroma sampling than 4:2:0 and/or other than 8 bits per component", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, +{"allow_profile_mismatch", "attempt to decode anyway if HW accelerated decoder's supported profiles do not exactly match the stream", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"}, +{"extra_hw_frames", "Number of extra hardware frames to allocate for the user", OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, V|D }, +{"discard_damaged_percentage", "Percentage of damaged samples to discard a frame", OFFSET(discard_damaged_percentage), AV_OPT_TYPE_INT, {.i64 = 95 }, 0, 100, V|D }, +{NULL}, +}; + +#undef A +#undef V +#undef S +#undef E +#undef D +#undef DEFAULT +#undef OFFSET + +#endif /* AVCODEC_OPTIONS_TABLE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus.c new file mode 100644 index 000000000..f74278a7e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus.c @@ -0,0 +1,900 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Opus decoder/parser shared code + */ + +#include + +#include "libavutil/error.h" +#include "libavutil/ffmath.h" + +#include "opus_celt.h" +#include "opustab.h" +#include "internal.h" +#include "vorbis.h" + +static const uint16_t opus_frame_duration[32] = { + 480, 960, 1920, 2880, + 480, 960, 1920, 2880, + 480, 960, 1920, 2880, + 480, 960, + 480, 960, + 120, 240, 480, 960, + 120, 240, 480, 960, + 120, 240, 480, 960, + 120, 240, 480, 960, +}; + +/** + * Read a 1- or 2-byte frame length + */ +static inline int xiph_lacing_16bit(const uint8_t **ptr, const uint8_t *end) +{ + int val; + + if (*ptr >= end) + return AVERROR_INVALIDDATA; + val = *(*ptr)++; + if (val >= 252) { + if (*ptr >= end) + return AVERROR_INVALIDDATA; + val += 4 * *(*ptr)++; + } + return val; +} + +/** + * Read a multi-byte length (used for code 3 packet padding size) + */ +static inline int xiph_lacing_full(const uint8_t **ptr, const uint8_t *end) +{ + int val = 0; + int next; + + while (1) { + if (*ptr >= end || val > INT_MAX - 254) + return AVERROR_INVALIDDATA; + next = *(*ptr)++; + val += next; + if (next < 255) + break; + else + val--; + } + return val; +} + +/** + * Parse Opus packet info from raw packet data + */ +int ff_opus_parse_packet(OpusPacket *pkt, const uint8_t *buf, int buf_size, + int self_delimiting) +{ + const uint8_t *ptr = buf; + const uint8_t *end = buf + buf_size; + int padding = 0; + int frame_bytes, i; + + if (buf_size < 1) + goto fail; + + /* TOC byte */ + i = *ptr++; + pkt->code = (i ) & 0x3; + pkt->stereo = (i >> 2) & 0x1; + pkt->config = (i >> 3) & 0x1F; + + /* code 2 and code 3 packets have at least 1 byte after the TOC */ + if (pkt->code >= 2 && buf_size < 2) + goto fail; + + switch (pkt->code) { + case 0: + /* 1 frame */ + pkt->frame_count = 1; + pkt->vbr = 0; + + if (self_delimiting) { + int len = xiph_lacing_16bit(&ptr, end); + if (len < 0 || len > end - ptr) + goto fail; + end = ptr + len; + buf_size = end - buf; + } + + frame_bytes = end - ptr; + if (frame_bytes > MAX_FRAME_SIZE) + goto fail; + pkt->frame_offset[0] = ptr - buf; + pkt->frame_size[0] = frame_bytes; + break; + case 1: + /* 2 frames, equal size */ + pkt->frame_count = 2; + pkt->vbr = 0; + + if (self_delimiting) { + int len = xiph_lacing_16bit(&ptr, end); + if (len < 0 || 2 * len > end - ptr) + goto fail; + end = ptr + 2 * len; + buf_size = end - buf; + } + + frame_bytes = end - ptr; + if (frame_bytes & 1 || frame_bytes >> 1 > MAX_FRAME_SIZE) + goto fail; + pkt->frame_offset[0] = ptr - buf; + pkt->frame_size[0] = frame_bytes >> 1; + pkt->frame_offset[1] = pkt->frame_offset[0] + pkt->frame_size[0]; + pkt->frame_size[1] = frame_bytes >> 1; + break; + case 2: + /* 2 frames, different sizes */ + pkt->frame_count = 2; + pkt->vbr = 1; + + /* read 1st frame size */ + frame_bytes = xiph_lacing_16bit(&ptr, end); + if (frame_bytes < 0) + goto fail; + + if (self_delimiting) { + int len = xiph_lacing_16bit(&ptr, end); + if (len < 0 || len + frame_bytes > end - ptr) + goto fail; + end = ptr + frame_bytes + len; + buf_size = end - buf; + } + + pkt->frame_offset[0] = ptr - buf; + pkt->frame_size[0] = frame_bytes; + + /* calculate 2nd frame size */ + frame_bytes = end - ptr - pkt->frame_size[0]; + if (frame_bytes < 0 || frame_bytes > MAX_FRAME_SIZE) + goto fail; + pkt->frame_offset[1] = pkt->frame_offset[0] + pkt->frame_size[0]; + pkt->frame_size[1] = frame_bytes; + break; + case 3: + /* 1 to 48 frames, can be different sizes */ + i = *ptr++; + pkt->frame_count = (i ) & 0x3F; + padding = (i >> 6) & 0x01; + pkt->vbr = (i >> 7) & 0x01; + + if (pkt->frame_count == 0 || pkt->frame_count > MAX_FRAMES) + goto fail; + + /* read padding size */ + if (padding) { + padding = xiph_lacing_full(&ptr, end); + if (padding < 0) + goto fail; + } + + /* read frame sizes */ + if (pkt->vbr) { + /* for VBR, all frames except the final one have their size coded + in the bitstream. the last frame size is implicit. */ + int total_bytes = 0; + for (i = 0; i < pkt->frame_count - 1; i++) { + frame_bytes = xiph_lacing_16bit(&ptr, end); + if (frame_bytes < 0) + goto fail; + pkt->frame_size[i] = frame_bytes; + total_bytes += frame_bytes; + } + + if (self_delimiting) { + int len = xiph_lacing_16bit(&ptr, end); + if (len < 0 || len + total_bytes + padding > end - ptr) + goto fail; + end = ptr + total_bytes + len + padding; + buf_size = end - buf; + } + + frame_bytes = end - ptr - padding; + if (total_bytes > frame_bytes) + goto fail; + pkt->frame_offset[0] = ptr - buf; + for (i = 1; i < pkt->frame_count; i++) + pkt->frame_offset[i] = pkt->frame_offset[i-1] + pkt->frame_size[i-1]; + pkt->frame_size[pkt->frame_count-1] = frame_bytes - total_bytes; + } else { + /* for CBR, the remaining packet bytes are divided evenly between + the frames */ + if (self_delimiting) { + frame_bytes = xiph_lacing_16bit(&ptr, end); + if (frame_bytes < 0 || pkt->frame_count * frame_bytes + padding > end - ptr) + goto fail; + end = ptr + pkt->frame_count * frame_bytes + padding; + buf_size = end - buf; + } else { + frame_bytes = end - ptr - padding; + if (frame_bytes % pkt->frame_count || + frame_bytes / pkt->frame_count > MAX_FRAME_SIZE) + goto fail; + frame_bytes /= pkt->frame_count; + } + + pkt->frame_offset[0] = ptr - buf; + pkt->frame_size[0] = frame_bytes; + for (i = 1; i < pkt->frame_count; i++) { + pkt->frame_offset[i] = pkt->frame_offset[i-1] + pkt->frame_size[i-1]; + pkt->frame_size[i] = frame_bytes; + } + } + } + + pkt->packet_size = buf_size; + pkt->data_size = pkt->packet_size - padding; + + /* total packet duration cannot be larger than 120ms */ + pkt->frame_duration = opus_frame_duration[pkt->config]; + if (pkt->frame_duration * pkt->frame_count > MAX_PACKET_DUR) + goto fail; + + /* set mode and bandwidth */ + if (pkt->config < 12) { + pkt->mode = OPUS_MODE_SILK; + pkt->bandwidth = pkt->config >> 2; + } else if (pkt->config < 16) { + pkt->mode = OPUS_MODE_HYBRID; + pkt->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND + (pkt->config >= 14); + } else { + pkt->mode = OPUS_MODE_CELT; + pkt->bandwidth = (pkt->config - 16) >> 2; + /* skip medium band */ + if (pkt->bandwidth) + pkt->bandwidth++; + } + + return 0; + +fail: + memset(pkt, 0, sizeof(*pkt)); + return AVERROR_INVALIDDATA; +} + +static int channel_reorder_vorbis(int nb_channels, int channel_idx) +{ + return ff_vorbis_channel_layout_offsets[nb_channels - 1][channel_idx]; +} + +static int channel_reorder_unknown(int nb_channels, int channel_idx) +{ + return channel_idx; +} + +av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, + OpusContext *s) +{ + static const uint8_t default_channel_map[2] = { 0, 1 }; + + int (*channel_reorder)(int, int) = channel_reorder_unknown; + + const uint8_t *extradata, *channel_map; + int extradata_size; + int version, channels, map_type, streams, stereo_streams, i, j; + uint64_t layout; + + if (!avctx->extradata) { + if (avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, + "Multichannel configuration without extradata.\n"); + return AVERROR(EINVAL); + } + extradata = opus_default_extradata; + extradata_size = sizeof(opus_default_extradata); + } else { + extradata = avctx->extradata; + extradata_size = avctx->extradata_size; + } + + if (extradata_size < 19) { + av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", + extradata_size); + return AVERROR_INVALIDDATA; + } + + version = extradata[8]; + if (version > 15) { + avpriv_request_sample(avctx, "Extradata version %d", version); + return AVERROR_PATCHWELCOME; + } + + avctx->delay = AV_RL16(extradata + 10); + if (avctx->internal) + avctx->internal->skip_samples = avctx->delay; + + channels = avctx->extradata ? extradata[9] : (avctx->channels == 1) ? 1 : 2; + if (!channels) { + av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the extradata\n"); + return AVERROR_INVALIDDATA; + } + + s->gain_i = AV_RL16(extradata + 16); + if (s->gain_i) + s->gain = ff_exp10(s->gain_i / (20.0 * 256)); + + map_type = extradata[18]; + if (!map_type) { + if (channels > 2) { + av_log(avctx, AV_LOG_ERROR, + "Channel mapping 0 is only specified for up to 2 channels\n"); + return AVERROR_INVALIDDATA; + } + layout = (channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; + streams = 1; + stereo_streams = channels - 1; + channel_map = default_channel_map; + } else if (map_type == 1 || map_type == 2 || map_type == 255) { + if (extradata_size < 21 + channels) { + av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", + extradata_size); + return AVERROR_INVALIDDATA; + } + + streams = extradata[19]; + stereo_streams = extradata[20]; + if (!streams || stereo_streams > streams || + streams + stereo_streams > 255) { + av_log(avctx, AV_LOG_ERROR, + "Invalid stream/stereo stream count: %d/%d\n", streams, stereo_streams); + return AVERROR_INVALIDDATA; + } + + if (map_type == 1) { + if (channels > 8) { + av_log(avctx, AV_LOG_ERROR, + "Channel mapping 1 is only specified for up to 8 channels\n"); + return AVERROR_INVALIDDATA; + } + layout = ff_vorbis_channel_layouts[channels - 1]; + channel_reorder = channel_reorder_vorbis; + } else if (map_type == 2) { + int ambisonic_order = ff_sqrt(channels) - 1; + if (channels != ((ambisonic_order + 1) * (ambisonic_order + 1)) && + channels != ((ambisonic_order + 1) * (ambisonic_order + 1) + 2)) { + av_log(avctx, AV_LOG_ERROR, + "Channel mapping 2 is only specified for channel counts" + " which can be written as (n + 1)^2 or (n + 1)^2 + 2" + " for nonnegative integer n\n"); + return AVERROR_INVALIDDATA; + } + if (channels > 227) { + av_log(avctx, AV_LOG_ERROR, "Too many channels\n"); + return AVERROR_INVALIDDATA; + } + layout = 0; + } else + layout = 0; + + channel_map = extradata + 21; + } else { + avpriv_request_sample(avctx, "Mapping type %d", map_type); + return AVERROR_PATCHWELCOME; + } + + s->channel_maps = av_mallocz_array(channels, sizeof(*s->channel_maps)); + if (!s->channel_maps) + return AVERROR(ENOMEM); + + for (i = 0; i < channels; i++) { + ChannelMap *map = &s->channel_maps[i]; + uint8_t idx = channel_map[channel_reorder(channels, i)]; + + if (idx == 255) { + map->silence = 1; + continue; + } else if (idx >= streams + stereo_streams) { + av_log(avctx, AV_LOG_ERROR, + "Invalid channel map for output channel %d: %d\n", i, idx); + av_freep(&s->channel_maps); + return AVERROR_INVALIDDATA; + } + + /* check that we did not see this index yet */ + map->copy = 0; + for (j = 0; j < i; j++) + if (channel_map[channel_reorder(channels, j)] == idx) { + map->copy = 1; + map->copy_idx = j; + break; + } + + if (idx < 2 * stereo_streams) { + map->stream_idx = idx / 2; + map->channel_idx = idx & 1; + } else { + map->stream_idx = idx - stereo_streams; + map->channel_idx = 0; + } + } + + avctx->channels = channels; + avctx->channel_layout = layout; + s->nb_streams = streams; + s->nb_stereo_streams = stereo_streams; + + return 0; +} + +void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc) +{ + float lowband_scratch[8 * 22]; + float norm1[2 * 8 * 100]; + float *norm2 = norm1 + 8 * 100; + + int totalbits = (f->framebits << 3) - f->anticollapse_needed; + + int update_lowband = 1; + int lowband_offset = 0; + + int i, j; + + for (i = f->start_band; i < f->end_band; i++) { + uint32_t cm[2] = { (1 << f->blocks) - 1, (1 << f->blocks) - 1 }; + int band_offset = ff_celt_freq_bands[i] << f->size; + int band_size = ff_celt_freq_range[i] << f->size; + float *X = f->block[0].coeffs + band_offset; + float *Y = (f->channels == 2) ? f->block[1].coeffs + band_offset : NULL; + float *norm_loc1, *norm_loc2; + + int consumed = opus_rc_tell_frac(rc); + int effective_lowband = -1; + int b = 0; + + /* Compute how many bits we want to allocate to this band */ + if (i != f->start_band) + f->remaining -= consumed; + f->remaining2 = totalbits - consumed - 1; + if (i <= f->coded_bands - 1) { + int curr_balance = f->remaining / FFMIN(3, f->coded_bands-i); + b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[i] + curr_balance), 14); + } + + if ((ff_celt_freq_bands[i] - ff_celt_freq_range[i] >= ff_celt_freq_bands[f->start_band] || + i == f->start_band + 1) && (update_lowband || lowband_offset == 0)) + lowband_offset = i; + + if (i == f->start_band + 1) { + /* Special Hybrid Folding (RFC 8251 section 9). Copy the first band into + the second to ensure the second band never has to use the LCG. */ + int count = (ff_celt_freq_range[i] - ff_celt_freq_range[i-1]) << f->size; + + memcpy(&norm1[band_offset], &norm1[band_offset - count], count * sizeof(float)); + + if (f->channels == 2) + memcpy(&norm2[band_offset], &norm2[band_offset - count], count * sizeof(float)); + } + + /* Get a conservative estimate of the collapse_mask's for the bands we're + going to be folding from. */ + if (lowband_offset != 0 && (f->spread != CELT_SPREAD_AGGRESSIVE || + f->blocks > 1 || f->tf_change[i] < 0)) { + int foldstart, foldend; + + /* This ensures we never repeat spectral content within one band */ + effective_lowband = FFMAX(ff_celt_freq_bands[f->start_band], + ff_celt_freq_bands[lowband_offset] - ff_celt_freq_range[i]); + foldstart = lowband_offset; + while (ff_celt_freq_bands[--foldstart] > effective_lowband); + foldend = lowband_offset - 1; + while (++foldend < i && ff_celt_freq_bands[foldend] < effective_lowband + ff_celt_freq_range[i]); + + cm[0] = cm[1] = 0; + for (j = foldstart; j < foldend; j++) { + cm[0] |= f->block[0].collapse_masks[j]; + cm[1] |= f->block[f->channels - 1].collapse_masks[j]; + } + } + + if (f->dual_stereo && i == f->intensity_stereo) { + /* Switch off dual stereo to do intensity */ + f->dual_stereo = 0; + for (j = ff_celt_freq_bands[f->start_band] << f->size; j < band_offset; j++) + norm1[j] = (norm1[j] + norm2[j]) / 2; + } + + norm_loc1 = effective_lowband != -1 ? norm1 + (effective_lowband << f->size) : NULL; + norm_loc2 = effective_lowband != -1 ? norm2 + (effective_lowband << f->size) : NULL; + + if (f->dual_stereo) { + cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X, NULL, band_size, b >> 1, + f->blocks, norm_loc1, f->size, + norm1 + band_offset, 0, 1.0f, + lowband_scratch, cm[0]); + + cm[1] = f->pvq->quant_band(f->pvq, f, rc, i, Y, NULL, band_size, b >> 1, + f->blocks, norm_loc2, f->size, + norm2 + band_offset, 0, 1.0f, + lowband_scratch, cm[1]); + } else { + cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X, Y, band_size, b >> 0, + f->blocks, norm_loc1, f->size, + norm1 + band_offset, 0, 1.0f, + lowband_scratch, cm[0] | cm[1]); + cm[1] = cm[0]; + } + + f->block[0].collapse_masks[i] = (uint8_t)cm[0]; + f->block[f->channels - 1].collapse_masks[i] = (uint8_t)cm[1]; + f->remaining += f->pulses[i] + consumed; + + /* Update the folding position only as long as we have 1 bit/sample depth */ + update_lowband = (b > band_size << 3); + } +} + +#define NORMC(bits) ((bits) << (f->channels - 1) << f->size >> 2) + +void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode) +{ + int i, j, low, high, total, done, bandbits, remaining, tbits_8ths; + int skip_startband = f->start_band; + int skip_bit = 0; + int intensitystereo_bit = 0; + int dualstereo_bit = 0; + int dynalloc = 6; + int extrabits = 0; + + int boost[CELT_MAX_BANDS] = { 0 }; + int trim_offset[CELT_MAX_BANDS]; + int threshold[CELT_MAX_BANDS]; + int bits1[CELT_MAX_BANDS]; + int bits2[CELT_MAX_BANDS]; + + /* Spread */ + if (opus_rc_tell(rc) + 4 <= f->framebits) { + if (encode) + ff_opus_rc_enc_cdf(rc, f->spread, ff_celt_model_spread); + else + f->spread = ff_opus_rc_dec_cdf(rc, ff_celt_model_spread); + } else { + f->spread = CELT_SPREAD_NORMAL; + } + + /* Initialize static allocation caps */ + for (i = 0; i < CELT_MAX_BANDS; i++) + f->caps[i] = NORMC((ff_celt_static_caps[f->size][f->channels - 1][i] + 64) * ff_celt_freq_range[i]); + + /* Band boosts */ + tbits_8ths = f->framebits << 3; + for (i = f->start_band; i < f->end_band; i++) { + int quanta = ff_celt_freq_range[i] << (f->channels - 1) << f->size; + int b_dynalloc = dynalloc; + int boost_amount = f->alloc_boost[i]; + quanta = FFMIN(quanta << 3, FFMAX(6 << 3, quanta)); + + while (opus_rc_tell_frac(rc) + (b_dynalloc << 3) < tbits_8ths && boost[i] < f->caps[i]) { + int is_boost; + if (encode) { + is_boost = boost_amount--; + ff_opus_rc_enc_log(rc, is_boost, b_dynalloc); + } else { + is_boost = ff_opus_rc_dec_log(rc, b_dynalloc); + } + + if (!is_boost) + break; + + boost[i] += quanta; + tbits_8ths -= quanta; + + b_dynalloc = 1; + } + + if (boost[i]) + dynalloc = FFMAX(dynalloc - 1, 2); + } + + /* Allocation trim */ + if (opus_rc_tell_frac(rc) + (6 << 3) <= tbits_8ths) + if (encode) + ff_opus_rc_enc_cdf(rc, f->alloc_trim, ff_celt_model_alloc_trim); + else + f->alloc_trim = ff_opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim); + + /* Anti-collapse bit reservation */ + tbits_8ths = (f->framebits << 3) - opus_rc_tell_frac(rc) - 1; + f->anticollapse_needed = 0; + if (f->transient && f->size >= 2 && tbits_8ths >= ((f->size + 2) << 3)) + f->anticollapse_needed = 1 << 3; + tbits_8ths -= f->anticollapse_needed; + + /* Band skip bit reservation */ + if (tbits_8ths >= 1 << 3) + skip_bit = 1 << 3; + tbits_8ths -= skip_bit; + + /* Intensity/dual stereo bit reservation */ + if (f->channels == 2) { + intensitystereo_bit = ff_celt_log2_frac[f->end_band - f->start_band]; + if (intensitystereo_bit <= tbits_8ths) { + tbits_8ths -= intensitystereo_bit; + if (tbits_8ths >= 1 << 3) { + dualstereo_bit = 1 << 3; + tbits_8ths -= 1 << 3; + } + } else { + intensitystereo_bit = 0; + } + } + + /* Trim offsets */ + for (i = f->start_band; i < f->end_band; i++) { + int trim = f->alloc_trim - 5 - f->size; + int band = ff_celt_freq_range[i] * (f->end_band - i - 1); + int duration = f->size + 3; + int scale = duration + f->channels - 1; + + /* PVQ minimum allocation threshold, below this value the band is + * skipped */ + threshold[i] = FFMAX(3 * ff_celt_freq_range[i] << duration >> 4, + f->channels << 3); + + trim_offset[i] = trim * (band << scale) >> 6; + + if (ff_celt_freq_range[i] << f->size == 1) + trim_offset[i] -= f->channels << 3; + } + + /* Bisection */ + low = 1; + high = CELT_VECTORS - 1; + while (low <= high) { + int center = (low + high) >> 1; + done = total = 0; + + for (i = f->end_band - 1; i >= f->start_band; i--) { + bandbits = NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[center][i]); + + if (bandbits) + bandbits = FFMAX(bandbits + trim_offset[i], 0); + bandbits += boost[i]; + + if (bandbits >= threshold[i] || done) { + done = 1; + total += FFMIN(bandbits, f->caps[i]); + } else if (bandbits >= f->channels << 3) { + total += f->channels << 3; + } + } + + if (total > tbits_8ths) + high = center - 1; + else + low = center + 1; + } + high = low--; + + /* Bisection */ + for (i = f->start_band; i < f->end_band; i++) { + bits1[i] = NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[low][i]); + bits2[i] = high >= CELT_VECTORS ? f->caps[i] : + NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[high][i]); + + if (bits1[i]) + bits1[i] = FFMAX(bits1[i] + trim_offset[i], 0); + if (bits2[i]) + bits2[i] = FFMAX(bits2[i] + trim_offset[i], 0); + + if (low) + bits1[i] += boost[i]; + bits2[i] += boost[i]; + + if (boost[i]) + skip_startband = i; + bits2[i] = FFMAX(bits2[i] - bits1[i], 0); + } + + /* Bisection */ + low = 0; + high = 1 << CELT_ALLOC_STEPS; + for (i = 0; i < CELT_ALLOC_STEPS; i++) { + int center = (low + high) >> 1; + done = total = 0; + + for (j = f->end_band - 1; j >= f->start_band; j--) { + bandbits = bits1[j] + (center * bits2[j] >> CELT_ALLOC_STEPS); + + if (bandbits >= threshold[j] || done) { + done = 1; + total += FFMIN(bandbits, f->caps[j]); + } else if (bandbits >= f->channels << 3) + total += f->channels << 3; + } + if (total > tbits_8ths) + high = center; + else + low = center; + } + + /* Bisection */ + done = total = 0; + for (i = f->end_band - 1; i >= f->start_band; i--) { + bandbits = bits1[i] + (low * bits2[i] >> CELT_ALLOC_STEPS); + + if (bandbits >= threshold[i] || done) + done = 1; + else + bandbits = (bandbits >= f->channels << 3) ? + f->channels << 3 : 0; + + bandbits = FFMIN(bandbits, f->caps[i]); + f->pulses[i] = bandbits; + total += bandbits; + } + + /* Band skipping */ + for (f->coded_bands = f->end_band; ; f->coded_bands--) { + int allocation; + j = f->coded_bands - 1; + + if (j == skip_startband) { + /* all remaining bands are not skipped */ + tbits_8ths += skip_bit; + break; + } + + /* determine the number of bits available for coding "do not skip" markers */ + remaining = tbits_8ths - total; + bandbits = remaining / (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]); + remaining -= bandbits * (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]); + allocation = f->pulses[j] + bandbits * ff_celt_freq_range[j]; + allocation += FFMAX(remaining - (ff_celt_freq_bands[j] - ff_celt_freq_bands[f->start_band]), 0); + + /* a "do not skip" marker is only coded if the allocation is + * above the chosen threshold */ + if (allocation >= FFMAX(threshold[j], (f->channels + 1) << 3)) { + int do_not_skip; + if (encode) { + do_not_skip = f->coded_bands <= f->skip_band_floor; + ff_opus_rc_enc_log(rc, do_not_skip, 1); + } else { + do_not_skip = ff_opus_rc_dec_log(rc, 1); + } + + if (do_not_skip) + break; + + total += 1 << 3; + allocation -= 1 << 3; + } + + /* the band is skipped, so reclaim its bits */ + total -= f->pulses[j]; + if (intensitystereo_bit) { + total -= intensitystereo_bit; + intensitystereo_bit = ff_celt_log2_frac[j - f->start_band]; + total += intensitystereo_bit; + } + + total += f->pulses[j] = (allocation >= f->channels << 3) ? f->channels << 3 : 0; + } + + /* IS start band */ + if (encode) { + if (intensitystereo_bit) { + f->intensity_stereo = FFMIN(f->intensity_stereo, f->coded_bands); + ff_opus_rc_enc_uint(rc, f->intensity_stereo, f->coded_bands + 1 - f->start_band); + } + } else { + f->intensity_stereo = f->dual_stereo = 0; + if (intensitystereo_bit) + f->intensity_stereo = f->start_band + ff_opus_rc_dec_uint(rc, f->coded_bands + 1 - f->start_band); + } + + /* DS flag */ + if (f->intensity_stereo <= f->start_band) + tbits_8ths += dualstereo_bit; /* no intensity stereo means no dual stereo */ + else if (dualstereo_bit) + if (encode) + ff_opus_rc_enc_log(rc, f->dual_stereo, 1); + else + f->dual_stereo = ff_opus_rc_dec_log(rc, 1); + + /* Supply the remaining bits in this frame to lower bands */ + remaining = tbits_8ths - total; + bandbits = remaining / (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]); + remaining -= bandbits * (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]); + for (i = f->start_band; i < f->coded_bands; i++) { + const int bits = FFMIN(remaining, ff_celt_freq_range[i]); + f->pulses[i] += bits + bandbits * ff_celt_freq_range[i]; + remaining -= bits; + } + + /* Finally determine the allocation */ + for (i = f->start_band; i < f->coded_bands; i++) { + int N = ff_celt_freq_range[i] << f->size; + int prev_extra = extrabits; + f->pulses[i] += extrabits; + + if (N > 1) { + int dof; /* degrees of freedom */ + int temp; /* dof * channels * log(dof) */ + int fine_bits; + int max_bits; + int offset; /* fine energy quantization offset, i.e. + * extra bits assigned over the standard + * totalbits/dof */ + + extrabits = FFMAX(f->pulses[i] - f->caps[i], 0); + f->pulses[i] -= extrabits; + + /* intensity stereo makes use of an extra degree of freedom */ + dof = N * f->channels + (f->channels == 2 && N > 2 && !f->dual_stereo && i < f->intensity_stereo); + temp = dof * (ff_celt_log_freq_range[i] + (f->size << 3)); + offset = (temp >> 1) - dof * CELT_FINE_OFFSET; + if (N == 2) /* dof=2 is the only case that doesn't fit the model */ + offset += dof << 1; + + /* grant an additional bias for the first and second pulses */ + if (f->pulses[i] + offset < 2 * (dof << 3)) + offset += temp >> 2; + else if (f->pulses[i] + offset < 3 * (dof << 3)) + offset += temp >> 3; + + fine_bits = (f->pulses[i] + offset + (dof << 2)) / (dof << 3); + max_bits = FFMIN((f->pulses[i] >> 3) >> (f->channels - 1), CELT_MAX_FINE_BITS); + max_bits = FFMAX(max_bits, 0); + f->fine_bits[i] = av_clip(fine_bits, 0, max_bits); + + /* If fine_bits was rounded down or capped, + * give priority for the final fine energy pass */ + f->fine_priority[i] = (f->fine_bits[i] * (dof << 3) >= f->pulses[i] + offset); + + /* the remaining bits are assigned to PVQ */ + f->pulses[i] -= f->fine_bits[i] << (f->channels - 1) << 3; + } else { + /* all bits go to fine energy except for the sign bit */ + extrabits = FFMAX(f->pulses[i] - (f->channels << 3), 0); + f->pulses[i] -= extrabits; + f->fine_bits[i] = 0; + f->fine_priority[i] = 1; + } + + /* hand back a limited number of extra fine energy bits to this band */ + if (extrabits > 0) { + int fineextra = FFMIN(extrabits >> (f->channels + 2), + CELT_MAX_FINE_BITS - f->fine_bits[i]); + f->fine_bits[i] += fineextra; + + fineextra <<= f->channels + 2; + f->fine_priority[i] = (fineextra >= extrabits - prev_extra); + extrabits -= fineextra; + } + } + f->remaining = extrabits; + + /* skipped bands dedicate all of their bits for fine energy */ + for (; i < f->end_band; i++) { + f->fine_bits[i] = f->pulses[i] >> (f->channels - 1) >> 3; + f->pulses[i] = 0; + f->fine_priority[i] = f->fine_bits[i] < 1; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus.h new file mode 100644 index 000000000..63ecd0aff --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus.h @@ -0,0 +1,200 @@ +/* + * Opus decoder/demuxer common functions + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUS_H +#define AVCODEC_OPUS_H + +#include + +#include "libavutil/audio_fifo.h" +#include "libavutil/float_dsp.h" +#include "libavutil/frame.h" + +#include "libswresample/swresample.h" + +#include "avcodec.h" +#include "opus_rc.h" + +#define MAX_FRAME_SIZE 1275 +#define MAX_FRAMES 48 +#define MAX_PACKET_DUR 5760 + +#define CELT_SHORT_BLOCKSIZE 120 +#define CELT_OVERLAP CELT_SHORT_BLOCKSIZE +#define CELT_MAX_LOG_BLOCKS 3 +#define CELT_MAX_FRAME_SIZE (CELT_SHORT_BLOCKSIZE * (1 << CELT_MAX_LOG_BLOCKS)) +#define CELT_MAX_BANDS 21 + +#define SILK_HISTORY 322 +#define SILK_MAX_LPC 16 + +#define ROUND_MULL(a,b,s) (((MUL64(a, b) >> ((s) - 1)) + 1) >> 1) +#define ROUND_MUL16(a,b) ((MUL16(a, b) + 16384) >> 15) + +#define OPUS_TS_HEADER 0x7FE0 // 0x3ff (11 bits) +#define OPUS_TS_MASK 0xFFE0 // top 11 bits + +static const uint8_t opus_default_extradata[30] = { + 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd', + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +enum OpusMode { + OPUS_MODE_SILK, + OPUS_MODE_HYBRID, + OPUS_MODE_CELT, + + OPUS_MODE_NB +}; + +enum OpusBandwidth { + OPUS_BANDWIDTH_NARROWBAND, + OPUS_BANDWIDTH_MEDIUMBAND, + OPUS_BANDWIDTH_WIDEBAND, + OPUS_BANDWIDTH_SUPERWIDEBAND, + OPUS_BANDWIDTH_FULLBAND, + + OPUS_BANDWITH_NB +}; + +typedef struct SilkContext SilkContext; + +typedef struct CeltFrame CeltFrame; + +typedef struct OpusPacket { + int packet_size; /**< packet size */ + int data_size; /**< size of the useful data -- packet size - padding */ + int code; /**< packet code: specifies the frame layout */ + int stereo; /**< whether this packet is mono or stereo */ + int vbr; /**< vbr flag */ + int config; /**< configuration: tells the audio mode, + ** bandwidth, and frame duration */ + int frame_count; /**< frame count */ + int frame_offset[MAX_FRAMES]; /**< frame offsets */ + int frame_size[MAX_FRAMES]; /**< frame sizes */ + int frame_duration; /**< frame duration, in samples @ 48kHz */ + enum OpusMode mode; /**< mode */ + enum OpusBandwidth bandwidth; /**< bandwidth */ +} OpusPacket; + +typedef struct OpusStreamContext { + AVCodecContext *avctx; + int output_channels; + + OpusRangeCoder rc; + OpusRangeCoder redundancy_rc; + SilkContext *silk; + CeltFrame *celt; + AVFloatDSPContext *fdsp; + + float silk_buf[2][960]; + float *silk_output[2]; + DECLARE_ALIGNED(32, float, celt_buf)[2][960]; + float *celt_output[2]; + + DECLARE_ALIGNED(32, float, redundancy_buf)[2][960]; + float *redundancy_output[2]; + + /* data buffers for the final output data */ + float *out[2]; + int out_size; + + float *out_dummy; + int out_dummy_allocated_size; + + SwrContext *swr; + AVAudioFifo *celt_delay; + int silk_samplerate; + /* number of samples we still want to get from the resampler */ + int delayed_samples; + + OpusPacket packet; + + int redundancy_idx; +} OpusStreamContext; + +// a mapping between an opus stream and an output channel +typedef struct ChannelMap { + int stream_idx; + int channel_idx; + + // when a single decoded channel is mapped to multiple output channels, we + // write to the first output directly and copy from it to the others + // this field is set to 1 for those copied output channels + int copy; + // this is the index of the output channel to copy from + int copy_idx; + + // this channel is silent + int silence; +} ChannelMap; + +typedef struct OpusContext { + AVClass *av_class; + OpusStreamContext *streams; + int apply_phase_inv; + + /* current output buffers for each streams */ + float **out; + int *out_size; + /* Buffers for synchronizing the streams when they have different + * resampling delays */ + AVAudioFifo **sync_buffers; + /* number of decoded samples for each stream */ + int *decoded_samples; + + int nb_streams; + int nb_stereo_streams; + + AVFloatDSPContext *fdsp; + int16_t gain_i; + float gain; + + ChannelMap *channel_maps; +} OpusContext; + +int ff_opus_parse_packet(OpusPacket *pkt, const uint8_t *buf, int buf_size, + int self_delimited); + +int ff_opus_parse_extradata(AVCodecContext *avctx, OpusContext *s); + +int ff_silk_init(AVCodecContext *avctx, SilkContext **ps, int output_channels); +void ff_silk_free(SilkContext **ps); +void ff_silk_flush(SilkContext *s); + +/** + * Decode the LP layer of one Opus frame (which may correspond to several SILK + * frames). + */ +int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc, + float *output[2], + enum OpusBandwidth bandwidth, int coded_channels, + int duration_ms); + +/* Encode or decode CELT bands */ +void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc); + +/* Encode or decode CELT bitallocation */ +void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode); + +#endif /* AVCODEC_OPUS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_celt.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_celt.c new file mode 100644 index 000000000..4655172b0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_celt.c @@ -0,0 +1,576 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2016 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Opus CELT decoder + */ + +#include "opus_celt.h" +#include "opustab.h" +#include "opus_pvq.h" + +/* Use the 2D z-transform to apply prediction in both the time domain (alpha) + * and the frequency domain (beta) */ +static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc) +{ + int i, j; + float prev[2] = { 0 }; + float alpha = ff_celt_alpha_coef[f->size]; + float beta = ff_celt_beta_coef[f->size]; + const uint8_t *model = ff_celt_coarse_energy_dist[f->size][0]; + + /* intra frame */ + if (opus_rc_tell(rc) + 3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) { + alpha = 0.0f; + beta = 1.0f - (4915.0f/32768.0f); + model = ff_celt_coarse_energy_dist[f->size][1]; + } + + for (i = 0; i < CELT_MAX_BANDS; i++) { + for (j = 0; j < f->channels; j++) { + CeltBlock *block = &f->block[j]; + float value; + int available; + + if (i < f->start_band || i >= f->end_band) { + block->energy[i] = 0.0; + continue; + } + + available = f->framebits - opus_rc_tell(rc); + if (available >= 15) { + /* decode using a Laplace distribution */ + int k = FFMIN(i, 20) << 1; + value = ff_opus_rc_dec_laplace(rc, model[k] << 7, model[k+1] << 6); + } else if (available >= 2) { + int x = ff_opus_rc_dec_cdf(rc, ff_celt_model_energy_small); + value = (x>>1) ^ -(x&1); + } else if (available >= 1) { + value = -(float)ff_opus_rc_dec_log(rc, 1); + } else value = -1; + + block->energy[i] = FFMAX(-9.0f, block->energy[i]) * alpha + prev[j] + value; + prev[j] += beta * value; + } + } +} + +static void celt_decode_fine_energy(CeltFrame *f, OpusRangeCoder *rc) +{ + int i; + for (i = f->start_band; i < f->end_band; i++) { + int j; + if (!f->fine_bits[i]) + continue; + + for (j = 0; j < f->channels; j++) { + CeltBlock *block = &f->block[j]; + int q2; + float offset; + q2 = ff_opus_rc_get_raw(rc, f->fine_bits[i]); + offset = (q2 + 0.5f) * (1 << (14 - f->fine_bits[i])) / 16384.0f - 0.5f; + block->energy[i] += offset; + } + } +} + +static void celt_decode_final_energy(CeltFrame *f, OpusRangeCoder *rc) +{ + int priority, i, j; + int bits_left = f->framebits - opus_rc_tell(rc); + + for (priority = 0; priority < 2; priority++) { + for (i = f->start_band; i < f->end_band && bits_left >= f->channels; i++) { + if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS) + continue; + + for (j = 0; j < f->channels; j++) { + int q2; + float offset; + q2 = ff_opus_rc_get_raw(rc, 1); + offset = (q2 - 0.5f) * (1 << (14 - f->fine_bits[i] - 1)) / 16384.0f; + f->block[j].energy[i] += offset; + bits_left--; + } + } + } +} + +static void celt_decode_tf_changes(CeltFrame *f, OpusRangeCoder *rc) +{ + int i, diff = 0, tf_select = 0, tf_changed = 0, tf_select_bit; + int consumed, bits = f->transient ? 2 : 4; + + consumed = opus_rc_tell(rc); + tf_select_bit = (f->size != 0 && consumed+bits+1 <= f->framebits); + + for (i = f->start_band; i < f->end_band; i++) { + if (consumed+bits+tf_select_bit <= f->framebits) { + diff ^= ff_opus_rc_dec_log(rc, bits); + consumed = opus_rc_tell(rc); + tf_changed |= diff; + } + f->tf_change[i] = diff; + bits = f->transient ? 4 : 5; + } + + if (tf_select_bit && ff_celt_tf_select[f->size][f->transient][0][tf_changed] != + ff_celt_tf_select[f->size][f->transient][1][tf_changed]) + tf_select = ff_opus_rc_dec_log(rc, 1); + + for (i = f->start_band; i < f->end_band; i++) { + f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]]; + } +} + +static void celt_denormalize(CeltFrame *f, CeltBlock *block, float *data) +{ + int i, j; + + for (i = f->start_band; i < f->end_band; i++) { + float *dst = data + (ff_celt_freq_bands[i] << f->size); + float log_norm = block->energy[i] + ff_celt_mean_energy[i]; + float norm = exp2f(FFMIN(log_norm, 32.0f)); + + for (j = 0; j < ff_celt_freq_range[i] << f->size; j++) + dst[j] *= norm; + } +} + +static void celt_postfilter_apply_transition(CeltBlock *block, float *data) +{ + const int T0 = block->pf_period_old; + const int T1 = block->pf_period; + + float g00, g01, g02; + float g10, g11, g12; + + float x0, x1, x2, x3, x4; + + int i; + + if (block->pf_gains[0] == 0.0 && + block->pf_gains_old[0] == 0.0) + return; + + g00 = block->pf_gains_old[0]; + g01 = block->pf_gains_old[1]; + g02 = block->pf_gains_old[2]; + g10 = block->pf_gains[0]; + g11 = block->pf_gains[1]; + g12 = block->pf_gains[2]; + + x1 = data[-T1 + 1]; + x2 = data[-T1]; + x3 = data[-T1 - 1]; + x4 = data[-T1 - 2]; + + for (i = 0; i < CELT_OVERLAP; i++) { + float w = ff_celt_window2[i]; + x0 = data[i - T1 + 2]; + + data[i] += (1.0 - w) * g00 * data[i - T0] + + (1.0 - w) * g01 * (data[i - T0 - 1] + data[i - T0 + 1]) + + (1.0 - w) * g02 * (data[i - T0 - 2] + data[i - T0 + 2]) + + w * g10 * x2 + + w * g11 * (x1 + x3) + + w * g12 * (x0 + x4); + x4 = x3; + x3 = x2; + x2 = x1; + x1 = x0; + } +} + +static void celt_postfilter(CeltFrame *f, CeltBlock *block) +{ + int len = f->blocksize * f->blocks; + const int filter_len = len - 2 * CELT_OVERLAP; + + celt_postfilter_apply_transition(block, block->buf + 1024); + + block->pf_period_old = block->pf_period; + memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains)); + + block->pf_period = block->pf_period_new; + memcpy(block->pf_gains, block->pf_gains_new, sizeof(block->pf_gains)); + + if (len > CELT_OVERLAP) { + celt_postfilter_apply_transition(block, block->buf + 1024 + CELT_OVERLAP); + + if (block->pf_gains[0] > FLT_EPSILON && filter_len > 0) + f->opusdsp.postfilter(block->buf + 1024 + 2 * CELT_OVERLAP, + block->pf_period, block->pf_gains, + filter_len); + + block->pf_period_old = block->pf_period; + memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains)); + } + + memmove(block->buf, block->buf + len, (1024 + CELT_OVERLAP / 2) * sizeof(float)); +} + +static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed) +{ + int i; + + memset(f->block[0].pf_gains_new, 0, sizeof(f->block[0].pf_gains_new)); + memset(f->block[1].pf_gains_new, 0, sizeof(f->block[1].pf_gains_new)); + + if (f->start_band == 0 && consumed + 16 <= f->framebits) { + int has_postfilter = ff_opus_rc_dec_log(rc, 1); + if (has_postfilter) { + float gain; + int tapset, octave, period; + + octave = ff_opus_rc_dec_uint(rc, 6); + period = (16 << octave) + ff_opus_rc_get_raw(rc, 4 + octave) - 1; + gain = 0.09375f * (ff_opus_rc_get_raw(rc, 3) + 1); + tapset = (opus_rc_tell(rc) + 2 <= f->framebits) ? + ff_opus_rc_dec_cdf(rc, ff_celt_model_tapset) : 0; + + for (i = 0; i < 2; i++) { + CeltBlock *block = &f->block[i]; + + block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD); + block->pf_gains_new[0] = gain * ff_celt_postfilter_taps[tapset][0]; + block->pf_gains_new[1] = gain * ff_celt_postfilter_taps[tapset][1]; + block->pf_gains_new[2] = gain * ff_celt_postfilter_taps[tapset][2]; + } + } + + consumed = opus_rc_tell(rc); + } + + return consumed; +} + +static void process_anticollapse(CeltFrame *f, CeltBlock *block, float *X) +{ + int i, j, k; + + for (i = f->start_band; i < f->end_band; i++) { + int renormalize = 0; + float *xptr; + float prev[2]; + float Ediff, r; + float thresh, sqrt_1; + int depth; + + /* depth in 1/8 bits */ + depth = (1 + f->pulses[i]) / (ff_celt_freq_range[i] << f->size); + thresh = exp2f(-1.0 - 0.125f * depth); + sqrt_1 = 1.0f / sqrtf(ff_celt_freq_range[i] << f->size); + + xptr = X + (ff_celt_freq_bands[i] << f->size); + + prev[0] = block->prev_energy[0][i]; + prev[1] = block->prev_energy[1][i]; + if (f->channels == 1) { + CeltBlock *block1 = &f->block[1]; + + prev[0] = FFMAX(prev[0], block1->prev_energy[0][i]); + prev[1] = FFMAX(prev[1], block1->prev_energy[1][i]); + } + Ediff = block->energy[i] - FFMIN(prev[0], prev[1]); + Ediff = FFMAX(0, Ediff); + + /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because + short blocks don't have the same energy as long */ + r = exp2f(1 - Ediff); + if (f->size == 3) + r *= M_SQRT2; + r = FFMIN(thresh, r) * sqrt_1; + for (k = 0; k < 1 << f->size; k++) { + /* Detect collapse */ + if (!(block->collapse_masks[i] & 1 << k)) { + /* Fill with noise */ + for (j = 0; j < ff_celt_freq_range[i]; j++) + xptr[(j << f->size) + k] = (celt_rng(f) & 0x8000) ? r : -r; + renormalize = 1; + } + } + + /* We just added some energy, so we need to renormalize */ + if (renormalize) + celt_renormalize_vector(xptr, ff_celt_freq_range[i] << f->size, 1.0f); + } +} + +int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, + float **output, int channels, int frame_size, + int start_band, int end_band) +{ + int i, j, downmix = 0; + int consumed; // bits of entropy consumed thus far for this frame + MDCT15Context *imdct; + + if (channels != 1 && channels != 2) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid number of coded channels: %d\n", + channels); + return AVERROR_INVALIDDATA; + } + if (start_band < 0 || start_band > end_band || end_band > CELT_MAX_BANDS) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid start/end band: %d %d\n", + start_band, end_band); + return AVERROR_INVALIDDATA; + } + + f->silence = 0; + f->transient = 0; + f->anticollapse = 0; + f->flushed = 0; + f->channels = channels; + f->start_band = start_band; + f->end_band = end_band; + f->framebits = rc->rb.bytes * 8; + + f->size = av_log2(frame_size / CELT_SHORT_BLOCKSIZE); + if (f->size > CELT_MAX_LOG_BLOCKS || + frame_size != CELT_SHORT_BLOCKSIZE * (1 << f->size)) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid CELT frame size: %d\n", + frame_size); + return AVERROR_INVALIDDATA; + } + + if (!f->output_channels) + f->output_channels = channels; + + for (i = 0; i < f->channels; i++) { + memset(f->block[i].coeffs, 0, sizeof(f->block[i].coeffs)); + memset(f->block[i].collapse_masks, 0, sizeof(f->block[i].collapse_masks)); + } + + consumed = opus_rc_tell(rc); + + /* obtain silence flag */ + if (consumed >= f->framebits) + f->silence = 1; + else if (consumed == 1) + f->silence = ff_opus_rc_dec_log(rc, 15); + + + if (f->silence) { + consumed = f->framebits; + rc->total_bits += f->framebits - opus_rc_tell(rc); + } + + /* obtain post-filter options */ + consumed = parse_postfilter(f, rc, consumed); + + /* obtain transient flag */ + if (f->size != 0 && consumed+3 <= f->framebits) + f->transient = ff_opus_rc_dec_log(rc, 3); + + f->blocks = f->transient ? 1 << f->size : 1; + f->blocksize = frame_size / f->blocks; + + imdct = f->imdct[f->transient ? 0 : f->size]; + + if (channels == 1) { + for (i = 0; i < CELT_MAX_BANDS; i++) + f->block[0].energy[i] = FFMAX(f->block[0].energy[i], f->block[1].energy[i]); + } + + celt_decode_coarse_energy(f, rc); + celt_decode_tf_changes (f, rc); + ff_celt_bitalloc (f, rc, 0); + celt_decode_fine_energy (f, rc); + ff_celt_quant_bands (f, rc); + + if (f->anticollapse_needed) + f->anticollapse = ff_opus_rc_get_raw(rc, 1); + + celt_decode_final_energy(f, rc); + + /* apply anti-collapse processing and denormalization to + * each coded channel */ + for (i = 0; i < f->channels; i++) { + CeltBlock *block = &f->block[i]; + + if (f->anticollapse) + process_anticollapse(f, block, f->block[i].coeffs); + + celt_denormalize(f, block, f->block[i].coeffs); + } + + /* stereo -> mono downmix */ + if (f->output_channels < f->channels) { + f->dsp->vector_fmac_scalar(f->block[0].coeffs, f->block[1].coeffs, 1.0, FFALIGN(frame_size, 16)); + downmix = 1; + } else if (f->output_channels > f->channels) + memcpy(f->block[1].coeffs, f->block[0].coeffs, frame_size * sizeof(float)); + + if (f->silence) { + for (i = 0; i < 2; i++) { + CeltBlock *block = &f->block[i]; + + for (j = 0; j < FF_ARRAY_ELEMS(block->energy); j++) + block->energy[j] = CELT_ENERGY_SILENCE; + } + memset(f->block[0].coeffs, 0, sizeof(f->block[0].coeffs)); + memset(f->block[1].coeffs, 0, sizeof(f->block[1].coeffs)); + } + + /* transform and output for each output channel */ + for (i = 0; i < f->output_channels; i++) { + CeltBlock *block = &f->block[i]; + + /* iMDCT and overlap-add */ + for (j = 0; j < f->blocks; j++) { + float *dst = block->buf + 1024 + j * f->blocksize; + + imdct->imdct_half(imdct, dst + CELT_OVERLAP / 2, f->block[i].coeffs + j, + f->blocks); + f->dsp->vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2, + ff_celt_window, CELT_OVERLAP / 2); + } + + if (downmix) + f->dsp->vector_fmul_scalar(&block->buf[1024], &block->buf[1024], 0.5f, frame_size); + + /* postfilter */ + celt_postfilter(f, block); + + /* deemphasis */ + block->emph_coeff = f->opusdsp.deemphasis(output[i], + &block->buf[1024 - frame_size], + block->emph_coeff, frame_size); + } + + if (channels == 1) + memcpy(f->block[1].energy, f->block[0].energy, sizeof(f->block[0].energy)); + + for (i = 0; i < 2; i++ ) { + CeltBlock *block = &f->block[i]; + + if (!f->transient) { + memcpy(block->prev_energy[1], block->prev_energy[0], sizeof(block->prev_energy[0])); + memcpy(block->prev_energy[0], block->energy, sizeof(block->prev_energy[0])); + } else { + for (j = 0; j < CELT_MAX_BANDS; j++) + block->prev_energy[0][j] = FFMIN(block->prev_energy[0][j], block->energy[j]); + } + + for (j = 0; j < f->start_band; j++) { + block->prev_energy[0][j] = CELT_ENERGY_SILENCE; + block->energy[j] = 0.0; + } + for (j = f->end_band; j < CELT_MAX_BANDS; j++) { + block->prev_energy[0][j] = CELT_ENERGY_SILENCE; + block->energy[j] = 0.0; + } + } + + f->seed = rc->range; + + return 0; +} + +void ff_celt_flush(CeltFrame *f) +{ + int i, j; + + if (f->flushed) + return; + + for (i = 0; i < 2; i++) { + CeltBlock *block = &f->block[i]; + + for (j = 0; j < CELT_MAX_BANDS; j++) + block->prev_energy[0][j] = block->prev_energy[1][j] = CELT_ENERGY_SILENCE; + + memset(block->energy, 0, sizeof(block->energy)); + memset(block->buf, 0, sizeof(block->buf)); + + memset(block->pf_gains, 0, sizeof(block->pf_gains)); + memset(block->pf_gains_old, 0, sizeof(block->pf_gains_old)); + memset(block->pf_gains_new, 0, sizeof(block->pf_gains_new)); + + block->emph_coeff = 0.0; + } + f->seed = 0; + + f->flushed = 1; +} + +void ff_celt_free(CeltFrame **f) +{ + CeltFrame *frm = *f; + int i; + + if (!frm) + return; + + for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++) + ff_mdct15_uninit(&frm->imdct[i]); + + ff_celt_pvq_uninit(&frm->pvq); + + av_freep(&frm->dsp); + av_freep(f); +} + +int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels, + int apply_phase_inv) +{ + CeltFrame *frm; + int i, ret; + + if (output_channels != 1 && output_channels != 2) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n", + output_channels); + return AVERROR(EINVAL); + } + + frm = av_mallocz(sizeof(*frm)); + if (!frm) + return AVERROR(ENOMEM); + + frm->avctx = avctx; + frm->output_channels = output_channels; + frm->apply_phase_inv = apply_phase_inv; + + for (i = 0; i < FF_ARRAY_ELEMS(frm->imdct); i++) + if ((ret = ff_mdct15_init(&frm->imdct[i], 1, i + 3, -1.0f/32768)) < 0) + goto fail; + + if ((ret = ff_celt_pvq_init(&frm->pvq, 0)) < 0) + goto fail; + + frm->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!frm->dsp) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ff_opus_dsp_init(&frm->opusdsp); + ff_celt_flush(frm); + + *f = frm; + + return 0; +fail: + ff_celt_free(&frm); + return ret; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_celt.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_celt.h new file mode 100644 index 000000000..7c1c5316b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_celt.h @@ -0,0 +1,171 @@ +/* + * Opus decoder/demuxer common functions + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2016 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUS_CELT_H +#define AVCODEC_OPUS_CELT_H + +#include + +#include "opus.h" +#include "opus_pvq.h" +#include "opusdsp.h" + +#include "mdct15.h" +#include "libavutil/float_dsp.h" +#include "libavutil/libm.h" + +#define CELT_VECTORS 11 +#define CELT_ALLOC_STEPS 6 +#define CELT_FINE_OFFSET 21 +#define CELT_MAX_FINE_BITS 8 +#define CELT_NORM_SCALE 16384 +#define CELT_QTHETA_OFFSET 4 +#define CELT_QTHETA_OFFSET_TWOPHASE 16 +#define CELT_POSTFILTER_MINPERIOD 15 +#define CELT_ENERGY_SILENCE (-28.0f) + +typedef struct CeltPVQ CeltPVQ; + +enum CeltSpread { + CELT_SPREAD_NONE, + CELT_SPREAD_LIGHT, + CELT_SPREAD_NORMAL, + CELT_SPREAD_AGGRESSIVE +}; + +enum CeltBlockSize { + CELT_BLOCK_120, + CELT_BLOCK_240, + CELT_BLOCK_480, + CELT_BLOCK_960, + + CELT_BLOCK_NB +}; + +typedef struct CeltBlock { + float energy[CELT_MAX_BANDS]; + float lin_energy[CELT_MAX_BANDS]; + float error_energy[CELT_MAX_BANDS]; + float prev_energy[2][CELT_MAX_BANDS]; + + uint8_t collapse_masks[CELT_MAX_BANDS]; + + /* buffer for mdct output + postfilter */ + DECLARE_ALIGNED(32, float, buf)[2048]; + DECLARE_ALIGNED(32, float, coeffs)[CELT_MAX_FRAME_SIZE]; + + /* Used by the encoder */ + DECLARE_ALIGNED(32, float, overlap)[FFALIGN(CELT_OVERLAP, 16)]; + DECLARE_ALIGNED(32, float, samples)[FFALIGN(CELT_MAX_FRAME_SIZE, 16)]; + + /* postfilter parameters */ + int pf_period_new; + float pf_gains_new[3]; + int pf_period; + float pf_gains[3]; + int pf_period_old; + float pf_gains_old[3]; + + float emph_coeff; +} CeltBlock; + +struct CeltFrame { + // constant values that do not change during context lifetime + AVCodecContext *avctx; + MDCT15Context *imdct[4]; + AVFloatDSPContext *dsp; + CeltBlock block[2]; + CeltPVQ *pvq; + OpusDSP opusdsp; + int channels; + int output_channels; + int apply_phase_inv; + + enum CeltBlockSize size; + int start_band; + int end_band; + int coded_bands; + int transient; + int pfilter; + int skip_band_floor; + int tf_select; + int alloc_trim; + int alloc_boost[CELT_MAX_BANDS]; + int blocks; /* number of iMDCT blocks in the frame, depends on transient */ + int blocksize; /* size of each block */ + int silence; /* Frame is filled with silence */ + int anticollapse_needed; /* Whether to expect an anticollapse bit */ + int anticollapse; /* Encoded anticollapse bit */ + int intensity_stereo; + int dual_stereo; + int flushed; + uint32_t seed; + enum CeltSpread spread; + + /* Encoder PF coeffs */ + int pf_octave; + int pf_period; + int pf_tapset; + float pf_gain; + + /* Bit allocation */ + int framebits; + int remaining; + int remaining2; + int caps [CELT_MAX_BANDS]; + int fine_bits [CELT_MAX_BANDS]; + int fine_priority[CELT_MAX_BANDS]; + int pulses [CELT_MAX_BANDS]; + int tf_change [CELT_MAX_BANDS]; +}; + +/* LCG for noise generation */ +static av_always_inline uint32_t celt_rng(CeltFrame *f) +{ + f->seed = 1664525 * f->seed + 1013904223; + return f->seed; +} + +static av_always_inline void celt_renormalize_vector(float *X, int N, float gain) +{ + int i; + float g = 1e-15f; + for (i = 0; i < N; i++) + g += X[i] * X[i]; + g = gain / sqrtf(g); + + for (i = 0; i < N; i++) + X[i] *= g; +} + +int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels, + int apply_phase_inv); + +void ff_celt_free(CeltFrame **f); + +void ff_celt_flush(CeltFrame *f); + +int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, float **output, + int coded_channels, int frame_size, int startband, int endband); + +#endif /* AVCODEC_OPUS_CELT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_pvq.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_pvq.c new file mode 100644 index 000000000..9c21d6729 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_pvq.c @@ -0,0 +1,917 @@ +/* + * Copyright (c) 2007-2008 CSIRO + * Copyright (c) 2007-2009 Xiph.Org Foundation + * Copyright (c) 2008-2009 Gregory Maxwell + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "opustab.h" +#include "opus_pvq.h" + +#define CELT_PVQ_U(n, k) (ff_celt_pvq_u_row[FFMIN(n, k)][FFMAX(n, k)]) +#define CELT_PVQ_V(n, k) (CELT_PVQ_U(n, k) + CELT_PVQ_U(n, (k) + 1)) + +static inline int16_t celt_cos(int16_t x) +{ + x = (MUL16(x, x) + 4096) >> 13; + x = (32767-x) + ROUND_MUL16(x, (-7651 + ROUND_MUL16(x, (8277 + ROUND_MUL16(-626, x))))); + return x + 1; +} + +static inline int celt_log2tan(int isin, int icos) +{ + int lc, ls; + lc = opus_ilog(icos); + ls = opus_ilog(isin); + icos <<= 15 - lc; + isin <<= 15 - ls; + return (ls << 11) - (lc << 11) + + ROUND_MUL16(isin, ROUND_MUL16(isin, -2597) + 7932) - + ROUND_MUL16(icos, ROUND_MUL16(icos, -2597) + 7932); +} + +static inline int celt_bits2pulses(const uint8_t *cache, int bits) +{ + // TODO: Find the size of cache and make it into an array in the parameters list + int i, low = 0, high; + + high = cache[0]; + bits--; + + for (i = 0; i < 6; i++) { + int center = (low + high + 1) >> 1; + if (cache[center] >= bits) + high = center; + else + low = center; + } + + return (bits - (low == 0 ? -1 : cache[low]) <= cache[high] - bits) ? low : high; +} + +static inline int celt_pulses2bits(const uint8_t *cache, int pulses) +{ + // TODO: Find the size of cache and make it into an array in the parameters list + return (pulses == 0) ? 0 : cache[pulses] + 1; +} + +static inline void celt_normalize_residual(const int * av_restrict iy, float * av_restrict X, + int N, float g) +{ + int i; + for (i = 0; i < N; i++) + X[i] = g * iy[i]; +} + +static void celt_exp_rotation_impl(float *X, uint32_t len, uint32_t stride, + float c, float s) +{ + float *Xptr; + int i; + + Xptr = X; + for (i = 0; i < len - stride; i++) { + float x1 = Xptr[0]; + float x2 = Xptr[stride]; + Xptr[stride] = c * x2 + s * x1; + *Xptr++ = c * x1 - s * x2; + } + + Xptr = &X[len - 2 * stride - 1]; + for (i = len - 2 * stride - 1; i >= 0; i--) { + float x1 = Xptr[0]; + float x2 = Xptr[stride]; + Xptr[stride] = c * x2 + s * x1; + *Xptr-- = c * x1 - s * x2; + } +} + +static inline void celt_exp_rotation(float *X, uint32_t len, + uint32_t stride, uint32_t K, + enum CeltSpread spread, const int encode) +{ + uint32_t stride2 = 0; + float c, s; + float gain, theta; + int i; + + if (2*K >= len || spread == CELT_SPREAD_NONE) + return; + + gain = (float)len / (len + (20 - 5*spread) * K); + theta = M_PI * gain * gain / 4; + + c = cosf(theta); + s = sinf(theta); + + if (len >= stride << 3) { + stride2 = 1; + /* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding. + It's basically incrementing long as (stride2+0.5)^2 < len/stride. */ + while ((stride2 * stride2 + stride2) * stride + (stride >> 2) < len) + stride2++; + } + + len /= stride; + for (i = 0; i < stride; i++) { + if (encode) { + celt_exp_rotation_impl(X + i * len, len, 1, c, -s); + if (stride2) + celt_exp_rotation_impl(X + i * len, len, stride2, s, -c); + } else { + if (stride2) + celt_exp_rotation_impl(X + i * len, len, stride2, s, c); + celt_exp_rotation_impl(X + i * len, len, 1, c, s); + } + } +} + +static inline uint32_t celt_extract_collapse_mask(const int *iy, uint32_t N, uint32_t B) +{ + int i, j, N0 = N / B; + uint32_t collapse_mask = 0; + + if (B <= 1) + return 1; + + for (i = 0; i < B; i++) + for (j = 0; j < N0; j++) + collapse_mask |= (!!iy[i*N0+j]) << i; + return collapse_mask; +} + +static inline void celt_stereo_merge(float *X, float *Y, float mid, int N) +{ + int i; + float xp = 0, side = 0; + float E[2]; + float mid2; + float gain[2]; + + /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */ + for (i = 0; i < N; i++) { + xp += X[i] * Y[i]; + side += Y[i] * Y[i]; + } + + /* Compensating for the mid normalization */ + xp *= mid; + mid2 = mid; + E[0] = mid2 * mid2 + side - 2 * xp; + E[1] = mid2 * mid2 + side + 2 * xp; + if (E[0] < 6e-4f || E[1] < 6e-4f) { + for (i = 0; i < N; i++) + Y[i] = X[i]; + return; + } + + gain[0] = 1.0f / sqrtf(E[0]); + gain[1] = 1.0f / sqrtf(E[1]); + + for (i = 0; i < N; i++) { + float value[2]; + /* Apply mid scaling (side is already scaled) */ + value[0] = mid * X[i]; + value[1] = Y[i]; + X[i] = gain[0] * (value[0] - value[1]); + Y[i] = gain[1] * (value[0] + value[1]); + } +} + +static void celt_interleave_hadamard(float *tmp, float *X, int N0, + int stride, int hadamard) +{ + int i, j, N = N0*stride; + const uint8_t *order = &ff_celt_hadamard_order[hadamard ? stride - 2 : 30]; + + for (i = 0; i < stride; i++) + for (j = 0; j < N0; j++) + tmp[j*stride+i] = X[order[i]*N0+j]; + + memcpy(X, tmp, N*sizeof(float)); +} + +static void celt_deinterleave_hadamard(float *tmp, float *X, int N0, + int stride, int hadamard) +{ + int i, j, N = N0*stride; + const uint8_t *order = &ff_celt_hadamard_order[hadamard ? stride - 2 : 30]; + + for (i = 0; i < stride; i++) + for (j = 0; j < N0; j++) + tmp[order[i]*N0+j] = X[j*stride+i]; + + memcpy(X, tmp, N*sizeof(float)); +} + +static void celt_haar1(float *X, int N0, int stride) +{ + int i, j; + N0 >>= 1; + for (i = 0; i < stride; i++) { + for (j = 0; j < N0; j++) { + float x0 = X[stride * (2 * j + 0) + i]; + float x1 = X[stride * (2 * j + 1) + i]; + X[stride * (2 * j + 0) + i] = (x0 + x1) * M_SQRT1_2; + X[stride * (2 * j + 1) + i] = (x0 - x1) * M_SQRT1_2; + } + } +} + +static inline int celt_compute_qn(int N, int b, int offset, int pulse_cap, + int stereo) +{ + int qn, qb; + int N2 = 2 * N - 1; + if (stereo && N == 2) + N2--; + + /* The upper limit ensures that in a stereo split with itheta==16384, we'll + * always have enough bits left over to code at least one pulse in the + * side; otherwise it would collapse, since it doesn't get folded. */ + qb = FFMIN3(b - pulse_cap - (4 << 3), (b + N2 * offset) / N2, 8 << 3); + qn = (qb < (1 << 3 >> 1)) ? 1 : ((ff_celt_qn_exp2[qb & 0x7] >> (14 - (qb >> 3))) + 1) >> 1 << 1; + return qn; +} + +/* Convert the quantized vector to an index */ +static inline uint32_t celt_icwrsi(uint32_t N, uint32_t K, const int *y) +{ + int i, idx = 0, sum = 0; + for (i = N - 1; i >= 0; i--) { + const uint32_t i_s = CELT_PVQ_U(N - i, sum + FFABS(y[i]) + 1); + idx += CELT_PVQ_U(N - i, sum) + (y[i] < 0)*i_s; + sum += FFABS(y[i]); + } + return idx; +} + +// this code was adapted from libopus +static inline uint64_t celt_cwrsi(uint32_t N, uint32_t K, uint32_t i, int *y) +{ + uint64_t norm = 0; + uint32_t q, p; + int s, val; + int k0; + + while (N > 2) { + /*Lots of pulses case:*/ + if (K >= N) { + const uint32_t *row = ff_celt_pvq_u_row[N]; + + /* Are the pulses in this dimension negative? */ + p = row[K + 1]; + s = -(i >= p); + i -= p & s; + + /*Count how many pulses were placed in this dimension.*/ + k0 = K; + q = row[N]; + if (q > i) { + K = N; + do { + p = ff_celt_pvq_u_row[--K][N]; + } while (p > i); + } else + for (p = row[K]; p > i; p = row[K]) + K--; + + i -= p; + val = (k0 - K + s) ^ s; + norm += val * val; + *y++ = val; + } else { /*Lots of dimensions case:*/ + /*Are there any pulses in this dimension at all?*/ + p = ff_celt_pvq_u_row[K ][N]; + q = ff_celt_pvq_u_row[K + 1][N]; + + if (p <= i && i < q) { + i -= p; + *y++ = 0; + } else { + /*Are the pulses in this dimension negative?*/ + s = -(i >= q); + i -= q & s; + + /*Count how many pulses were placed in this dimension.*/ + k0 = K; + do p = ff_celt_pvq_u_row[--K][N]; + while (p > i); + + i -= p; + val = (k0 - K + s) ^ s; + norm += val * val; + *y++ = val; + } + } + N--; + } + + /* N == 2 */ + p = 2 * K + 1; + s = -(i >= p); + i -= p & s; + k0 = K; + K = (i + 1) / 2; + + if (K) + i -= 2 * K - 1; + + val = (k0 - K + s) ^ s; + norm += val * val; + *y++ = val; + + /* N==1 */ + s = -i; + val = (K + s) ^ s; + norm += val * val; + *y = val; + + return norm; +} + +static inline void celt_encode_pulses(OpusRangeCoder *rc, int *y, uint32_t N, uint32_t K) +{ + ff_opus_rc_enc_uint(rc, celt_icwrsi(N, K, y), CELT_PVQ_V(N, K)); +} + +static inline float celt_decode_pulses(OpusRangeCoder *rc, int *y, uint32_t N, uint32_t K) +{ + const uint32_t idx = ff_opus_rc_dec_uint(rc, CELT_PVQ_V(N, K)); + return celt_cwrsi(N, K, idx, y); +} + +/* + * Faster than libopus's search, operates entirely in the signed domain. + * Slightly worse/better depending on N, K and the input vector. + */ +static float ppp_pvq_search_c(float *X, int *y, int K, int N) +{ + int i, y_norm = 0; + float res = 0.0f, xy_norm = 0.0f; + + for (i = 0; i < N; i++) + res += FFABS(X[i]); + + res = K/(res + FLT_EPSILON); + + for (i = 0; i < N; i++) { + y[i] = lrintf(res*X[i]); + y_norm += y[i]*y[i]; + xy_norm += y[i]*X[i]; + K -= FFABS(y[i]); + } + + while (K) { + int max_idx = 0, phase = FFSIGN(K); + float max_num = 0.0f; + float max_den = 1.0f; + y_norm += 1.0f; + + for (i = 0; i < N; i++) { + /* If the sum has been overshot and the best place has 0 pulses allocated + * to it, attempting to decrease it further will actually increase the + * sum. Prevent this by disregarding any 0 positions when decrementing. */ + const int ca = 1 ^ ((y[i] == 0) & (phase < 0)); + const int y_new = y_norm + 2*phase*FFABS(y[i]); + float xy_new = xy_norm + 1*phase*FFABS(X[i]); + xy_new = xy_new * xy_new; + if (ca && (max_den*xy_new) > (y_new*max_num)) { + max_den = y_new; + max_num = xy_new; + max_idx = i; + } + } + + K -= phase; + + phase *= FFSIGN(X[max_idx]); + xy_norm += 1*phase*X[max_idx]; + y_norm += 2*phase*y[max_idx]; + y[max_idx] += phase; + } + + return (float)y_norm; +} + +static uint32_t celt_alg_quant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_t K, + enum CeltSpread spread, uint32_t blocks, float gain, + CeltPVQ *pvq) +{ + int *y = pvq->qcoeff; + + celt_exp_rotation(X, N, blocks, K, spread, 1); + gain /= sqrtf(pvq->pvq_search(X, y, K, N)); + celt_encode_pulses(rc, y, N, K); + celt_normalize_residual(y, X, N, gain); + celt_exp_rotation(X, N, blocks, K, spread, 0); + return celt_extract_collapse_mask(y, N, blocks); +} + +/** Decode pulse vector and combine the result with the pitch vector to produce + the final normalised signal in the current band. */ +static uint32_t celt_alg_unquant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_t K, + enum CeltSpread spread, uint32_t blocks, float gain, + CeltPVQ *pvq) +{ + int *y = pvq->qcoeff; + + gain /= sqrtf(celt_decode_pulses(rc, y, N, K)); + celt_normalize_residual(y, X, N, gain); + celt_exp_rotation(X, N, blocks, K, spread, 0); + return celt_extract_collapse_mask(y, N, blocks); +} + +static int celt_calc_theta(const float *X, const float *Y, int coupling, int N) +{ + int i; + float e[2] = { 0.0f, 0.0f }; + if (coupling) { /* Coupling case */ + for (i = 0; i < N; i++) { + e[0] += (X[i] + Y[i])*(X[i] + Y[i]); + e[1] += (X[i] - Y[i])*(X[i] - Y[i]); + } + } else { + for (i = 0; i < N; i++) { + e[0] += X[i]*X[i]; + e[1] += Y[i]*Y[i]; + } + } + return lrintf(32768.0f*atan2f(sqrtf(e[1]), sqrtf(e[0]))/M_PI); +} + +static void celt_stereo_is_decouple(float *X, float *Y, float e_l, float e_r, int N) +{ + int i; + const float energy_n = 1.0f/(sqrtf(e_l*e_l + e_r*e_r) + FLT_EPSILON); + e_l *= energy_n; + e_r *= energy_n; + for (i = 0; i < N; i++) + X[i] = e_l*X[i] + e_r*Y[i]; +} + +static void celt_stereo_ms_decouple(float *X, float *Y, int N) +{ + int i; + for (i = 0; i < N; i++) { + const float Xret = X[i]; + X[i] = (X[i] + Y[i])*M_SQRT1_2; + Y[i] = (Y[i] - Xret)*M_SQRT1_2; + } +} + +static av_always_inline uint32_t quant_band_template(CeltPVQ *pvq, CeltFrame *f, + OpusRangeCoder *rc, + const int band, float *X, + float *Y, int N, int b, + uint32_t blocks, float *lowband, + int duration, float *lowband_out, + int level, float gain, + float *lowband_scratch, + int fill, int quant) +{ + int i; + const uint8_t *cache; + int stereo = !!Y, split = stereo; + int imid = 0, iside = 0; + uint32_t N0 = N; + int N_B = N / blocks; + int N_B0 = N_B; + int B0 = blocks; + int time_divide = 0; + int recombine = 0; + int inv = 0; + float mid = 0, side = 0; + int longblocks = (B0 == 1); + uint32_t cm = 0; + + if (N == 1) { + float *x = X; + for (i = 0; i <= stereo; i++) { + int sign = 0; + if (f->remaining2 >= 1 << 3) { + if (quant) { + sign = x[0] < 0; + ff_opus_rc_put_raw(rc, sign, 1); + } else { + sign = ff_opus_rc_get_raw(rc, 1); + } + f->remaining2 -= 1 << 3; + } + x[0] = 1.0f - 2.0f*sign; + x = Y; + } + if (lowband_out) + lowband_out[0] = X[0]; + return 1; + } + + if (!stereo && level == 0) { + int tf_change = f->tf_change[band]; + int k; + if (tf_change > 0) + recombine = tf_change; + /* Band recombining to increase frequency resolution */ + + if (lowband && + (recombine || ((N_B & 1) == 0 && tf_change < 0) || B0 > 1)) { + for (i = 0; i < N; i++) + lowband_scratch[i] = lowband[i]; + lowband = lowband_scratch; + } + + for (k = 0; k < recombine; k++) { + if (quant || lowband) + celt_haar1(quant ? X : lowband, N >> k, 1 << k); + fill = ff_celt_bit_interleave[fill & 0xF] | ff_celt_bit_interleave[fill >> 4] << 2; + } + blocks >>= recombine; + N_B <<= recombine; + + /* Increasing the time resolution */ + while ((N_B & 1) == 0 && tf_change < 0) { + if (quant || lowband) + celt_haar1(quant ? X : lowband, N_B, blocks); + fill |= fill << blocks; + blocks <<= 1; + N_B >>= 1; + time_divide++; + tf_change++; + } + B0 = blocks; + N_B0 = N_B; + + /* Reorganize the samples in time order instead of frequency order */ + if (B0 > 1 && (quant || lowband)) + celt_deinterleave_hadamard(pvq->hadamard_tmp, quant ? X : lowband, + N_B >> recombine, B0 << recombine, + longblocks); + } + + /* If we need 1.5 more bit than we can produce, split the band in two. */ + cache = ff_celt_cache_bits + + ff_celt_cache_index[(duration + 1) * CELT_MAX_BANDS + band]; + if (!stereo && duration >= 0 && b > cache[cache[0]] + 12 && N > 2) { + N >>= 1; + Y = X + N; + split = 1; + duration -= 1; + if (blocks == 1) + fill = (fill & 1) | (fill << 1); + blocks = (blocks + 1) >> 1; + } + + if (split) { + int qn; + int itheta = quant ? celt_calc_theta(X, Y, stereo, N) : 0; + int mbits, sbits, delta; + int qalloc; + int pulse_cap; + int offset; + int orig_fill; + int tell; + + /* Decide on the resolution to give to the split parameter theta */ + pulse_cap = ff_celt_log_freq_range[band] + duration * 8; + offset = (pulse_cap >> 1) - (stereo && N == 2 ? CELT_QTHETA_OFFSET_TWOPHASE : + CELT_QTHETA_OFFSET); + qn = (stereo && band >= f->intensity_stereo) ? 1 : + celt_compute_qn(N, b, offset, pulse_cap, stereo); + tell = opus_rc_tell_frac(rc); + if (qn != 1) { + if (quant) + itheta = (itheta*qn + 8192) >> 14; + /* Entropy coding of the angle. We use a uniform pdf for the + * time split, a step for stereo, and a triangular one for the rest. */ + if (quant) { + if (stereo && N > 2) + ff_opus_rc_enc_uint_step(rc, itheta, qn / 2); + else if (stereo || B0 > 1) + ff_opus_rc_enc_uint(rc, itheta, qn + 1); + else + ff_opus_rc_enc_uint_tri(rc, itheta, qn); + itheta = itheta * 16384 / qn; + if (stereo) { + if (itheta == 0) + celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band], + f->block[1].lin_energy[band], N); + else + celt_stereo_ms_decouple(X, Y, N); + } + } else { + if (stereo && N > 2) + itheta = ff_opus_rc_dec_uint_step(rc, qn / 2); + else if (stereo || B0 > 1) + itheta = ff_opus_rc_dec_uint(rc, qn+1); + else + itheta = ff_opus_rc_dec_uint_tri(rc, qn); + itheta = itheta * 16384 / qn; + } + } else if (stereo) { + if (quant) { + inv = itheta > 8192; + if (inv) { + for (i = 0; i < N; i++) + Y[i] *= -1; + } + celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band], + f->block[1].lin_energy[band], N); + + if (b > 2 << 3 && f->remaining2 > 2 << 3) { + ff_opus_rc_enc_log(rc, inv, 2); + } else { + inv = 0; + } + } else { + inv = (b > 2 << 3 && f->remaining2 > 2 << 3) ? ff_opus_rc_dec_log(rc, 2) : 0; + inv = f->apply_phase_inv ? inv : 0; + } + itheta = 0; + } + qalloc = opus_rc_tell_frac(rc) - tell; + b -= qalloc; + + orig_fill = fill; + if (itheta == 0) { + imid = 32767; + iside = 0; + fill = av_mod_uintp2(fill, blocks); + delta = -16384; + } else if (itheta == 16384) { + imid = 0; + iside = 32767; + fill &= ((1 << blocks) - 1) << blocks; + delta = 16384; + } else { + imid = celt_cos(itheta); + iside = celt_cos(16384-itheta); + /* This is the mid vs side allocation that minimizes squared error + in that band. */ + delta = ROUND_MUL16((N - 1) << 7, celt_log2tan(iside, imid)); + } + + mid = imid / 32768.0f; + side = iside / 32768.0f; + + /* This is a special case for N=2 that only works for stereo and takes + advantage of the fact that mid and side are orthogonal to encode + the side with just one bit. */ + if (N == 2 && stereo) { + int c; + int sign = 0; + float tmp; + float *x2, *y2; + mbits = b; + /* Only need one bit for the side */ + sbits = (itheta != 0 && itheta != 16384) ? 1 << 3 : 0; + mbits -= sbits; + c = (itheta > 8192); + f->remaining2 -= qalloc+sbits; + + x2 = c ? Y : X; + y2 = c ? X : Y; + if (sbits) { + if (quant) { + sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; + ff_opus_rc_put_raw(rc, sign, 1); + } else { + sign = ff_opus_rc_get_raw(rc, 1); + } + } + sign = 1 - 2 * sign; + /* We use orig_fill here because we want to fold the side, but if + itheta==16384, we'll have cleared the low bits of fill. */ + cm = pvq->quant_band(pvq, f, rc, band, x2, NULL, N, mbits, blocks, lowband, duration, + lowband_out, level, gain, lowband_scratch, orig_fill); + /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), + and there's no need to worry about mixing with the other channel. */ + y2[0] = -sign * x2[1]; + y2[1] = sign * x2[0]; + X[0] *= mid; + X[1] *= mid; + Y[0] *= side; + Y[1] *= side; + tmp = X[0]; + X[0] = tmp - Y[0]; + Y[0] = tmp + Y[0]; + tmp = X[1]; + X[1] = tmp - Y[1]; + Y[1] = tmp + Y[1]; + } else { + /* "Normal" split code */ + float *next_lowband2 = NULL; + float *next_lowband_out1 = NULL; + int next_level = 0; + int rebalance; + uint32_t cmt; + + /* Give more bits to low-energy MDCTs than they would + * otherwise deserve */ + if (B0 > 1 && !stereo && (itheta & 0x3fff)) { + if (itheta > 8192) + /* Rough approximation for pre-echo masking */ + delta -= delta >> (4 - duration); + else + /* Corresponds to a forward-masking slope of + * 1.5 dB per 10 ms */ + delta = FFMIN(0, delta + (N << 3 >> (5 - duration))); + } + mbits = av_clip((b - delta) / 2, 0, b); + sbits = b - mbits; + f->remaining2 -= qalloc; + + if (lowband && !stereo) + next_lowband2 = lowband + N; /* >32-bit split case */ + + /* Only stereo needs to pass on lowband_out. + * Otherwise, it's handled at the end */ + if (stereo) + next_lowband_out1 = lowband_out; + else + next_level = level + 1; + + rebalance = f->remaining2; + if (mbits >= sbits) { + /* In stereo mode, we do not apply a scaling to the mid + * because we need the normalized mid for folding later */ + cm = pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks, + lowband, duration, next_lowband_out1, next_level, + stereo ? 1.0f : (gain * mid), lowband_scratch, fill); + rebalance = mbits - (rebalance - f->remaining2); + if (rebalance > 3 << 3 && itheta != 0) + sbits += rebalance - (3 << 3); + + /* For a stereo split, the high bits of fill are always zero, + * so no folding will be done to the side. */ + cmt = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks, + next_lowband2, duration, NULL, next_level, + gain * side, NULL, fill >> blocks); + cm |= cmt << ((B0 >> 1) & (stereo - 1)); + } else { + /* For a stereo split, the high bits of fill are always zero, + * so no folding will be done to the side. */ + cm = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks, + next_lowband2, duration, NULL, next_level, + gain * side, NULL, fill >> blocks); + cm <<= ((B0 >> 1) & (stereo - 1)); + rebalance = sbits - (rebalance - f->remaining2); + if (rebalance > 3 << 3 && itheta != 16384) + mbits += rebalance - (3 << 3); + + /* In stereo mode, we do not apply a scaling to the mid because + * we need the normalized mid for folding later */ + cm |= pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks, + lowband, duration, next_lowband_out1, next_level, + stereo ? 1.0f : (gain * mid), lowband_scratch, fill); + } + } + } else { + /* This is the basic no-split case */ + uint32_t q = celt_bits2pulses(cache, b); + uint32_t curr_bits = celt_pulses2bits(cache, q); + f->remaining2 -= curr_bits; + + /* Ensures we can never bust the budget */ + while (f->remaining2 < 0 && q > 0) { + f->remaining2 += curr_bits; + curr_bits = celt_pulses2bits(cache, --q); + f->remaining2 -= curr_bits; + } + + if (q != 0) { + /* Finally do the actual (de)quantization */ + if (quant) { + cm = celt_alg_quant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1), + f->spread, blocks, gain, pvq); + } else { + cm = celt_alg_unquant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1), + f->spread, blocks, gain, pvq); + } + } else { + /* If there's no pulse, fill the band anyway */ + uint32_t cm_mask = (1 << blocks) - 1; + fill &= cm_mask; + if (fill) { + if (!lowband) { + /* Noise */ + for (i = 0; i < N; i++) + X[i] = (((int32_t)celt_rng(f)) >> 20); + cm = cm_mask; + } else { + /* Folded spectrum */ + for (i = 0; i < N; i++) { + /* About 48 dB below the "normal" folding level */ + X[i] = lowband[i] + (((celt_rng(f)) & 0x8000) ? 1.0f / 256 : -1.0f / 256); + } + cm = fill; + } + celt_renormalize_vector(X, N, gain); + } else { + memset(X, 0, N*sizeof(float)); + } + } + } + + /* This code is used by the decoder and by the resynthesis-enabled encoder */ + if (stereo) { + if (N > 2) + celt_stereo_merge(X, Y, mid, N); + if (inv) { + for (i = 0; i < N; i++) + Y[i] *= -1; + } + } else if (level == 0) { + int k; + + /* Undo the sample reorganization going from time order to frequency order */ + if (B0 > 1) + celt_interleave_hadamard(pvq->hadamard_tmp, X, N_B >> recombine, + B0 << recombine, longblocks); + + /* Undo time-freq changes that we did earlier */ + N_B = N_B0; + blocks = B0; + for (k = 0; k < time_divide; k++) { + blocks >>= 1; + N_B <<= 1; + cm |= cm >> blocks; + celt_haar1(X, N_B, blocks); + } + + for (k = 0; k < recombine; k++) { + cm = ff_celt_bit_deinterleave[cm]; + celt_haar1(X, N0>>k, 1<pvq_search = ppp_pvq_search_c; + s->quant_band = encode ? pvq_encode_band : pvq_decode_band; + + if (CONFIG_OPUS_ENCODER && ARCH_X86) + ff_celt_pvq_init_x86(s); + + *pvq = s; + + return 0; +} + +void av_cold ff_celt_pvq_uninit(CeltPVQ **pvq) +{ + av_freep(pvq); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_pvq.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_pvq.h new file mode 100644 index 000000000..52f9a4e6d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_pvq.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2016 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUS_PVQ_H +#define AVCODEC_OPUS_PVQ_H + +#include "opus_celt.h" + +#define QUANT_FN(name) uint32_t (name)(struct CeltPVQ *pvq, CeltFrame *f, \ + OpusRangeCoder *rc, const int band, float *X, \ + float *Y, int N, int b, uint32_t blocks, \ + float *lowband, int duration, \ + float *lowband_out, int level, float gain, \ + float *lowband_scratch, int fill) + +struct CeltPVQ { + DECLARE_ALIGNED(32, int, qcoeff )[256]; + DECLARE_ALIGNED(32, float, hadamard_tmp)[256]; + + float (*pvq_search)(float *X, int *y, int K, int N); + QUANT_FN(*quant_band); +}; + +void ff_celt_pvq_init_x86(struct CeltPVQ *s); + +int ff_celt_pvq_init(struct CeltPVQ **pvq, int encode); +void ff_celt_pvq_uninit(struct CeltPVQ **pvq); + +#endif /* AVCODEC_OPUS_PVQ_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_rc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_rc.c new file mode 100644 index 000000000..c432eb90c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_rc.c @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "opus_rc.h" + +#define OPUS_RC_BITS 32 +#define OPUS_RC_SYM 8 +#define OPUS_RC_CEIL ((1 << OPUS_RC_SYM) - 1) +#define OPUS_RC_TOP (1u << 31) +#define OPUS_RC_BOT (OPUS_RC_TOP >> OPUS_RC_SYM) +#define OPUS_RC_SHIFT (OPUS_RC_BITS - OPUS_RC_SYM - 1) + +static av_always_inline void opus_rc_enc_carryout(OpusRangeCoder *rc, int cbuf) +{ + const int cb = cbuf >> OPUS_RC_SYM, mb = (OPUS_RC_CEIL + cb) & OPUS_RC_CEIL; + if (cbuf == OPUS_RC_CEIL) { + rc->ext++; + return; + } + rc->rng_cur[0] = rc->rem + cb; + rc->rng_cur += (rc->rem >= 0); + for (; rc->ext > 0; rc->ext--) + *rc->rng_cur++ = mb; + av_assert0(rc->rng_cur < rc->rb.position); + rc->rem = cbuf & OPUS_RC_CEIL; /* Propagate */ +} + +static av_always_inline void opus_rc_dec_normalize(OpusRangeCoder *rc) +{ + while (rc->range <= OPUS_RC_BOT) { + rc->value = ((rc->value << OPUS_RC_SYM) | (get_bits(&rc->gb, OPUS_RC_SYM) ^ OPUS_RC_CEIL)) & (OPUS_RC_TOP - 1); + rc->range <<= OPUS_RC_SYM; + rc->total_bits += OPUS_RC_SYM; + } +} + +static av_always_inline void opus_rc_enc_normalize(OpusRangeCoder *rc) +{ + while (rc->range <= OPUS_RC_BOT) { + opus_rc_enc_carryout(rc, rc->value >> OPUS_RC_SHIFT); + rc->value = (rc->value << OPUS_RC_SYM) & (OPUS_RC_TOP - 1); + rc->range <<= OPUS_RC_SYM; + rc->total_bits += OPUS_RC_SYM; + } +} + +static av_always_inline void opus_rc_dec_update(OpusRangeCoder *rc, uint32_t scale, + uint32_t low, uint32_t high, + uint32_t total) +{ + rc->value -= scale * (total - high); + rc->range = low ? scale * (high - low) + : rc->range - scale * (total - high); + opus_rc_dec_normalize(rc); +} + +/* Main encoding function, this needs to go fast */ +static av_always_inline void opus_rc_enc_update(OpusRangeCoder *rc, uint32_t b, uint32_t p, + uint32_t p_tot, const int ptwo) +{ + uint32_t rscaled, cnd = !!b; + if (ptwo) /* Whole function is inlined so hopefully branch is optimized out */ + rscaled = rc->range >> ff_log2(p_tot); + else + rscaled = rc->range/p_tot; + rc->value += cnd*(rc->range - rscaled*(p_tot - b)); + rc->range = (!cnd)*(rc->range - rscaled*(p_tot - p)) + cnd*rscaled*(p - b); + opus_rc_enc_normalize(rc); +} + +uint32_t ff_opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf) +{ + unsigned int k, scale, total, symbol, low, high; + + total = *cdf++; + + scale = rc->range / total; + symbol = rc->value / scale + 1; + symbol = total - FFMIN(symbol, total); + + for (k = 0; cdf[k] <= symbol; k++); + high = cdf[k]; + low = k ? cdf[k-1] : 0; + + opus_rc_dec_update(rc, scale, low, high, total); + + return k; +} + +void ff_opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf) +{ + opus_rc_enc_update(rc, (!!val)*cdf[val], cdf[val + 1], cdf[0], 1); +} + +uint32_t ff_opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits) +{ + uint32_t k, scale; + scale = rc->range >> bits; // in this case, scale = symbol + + if (rc->value >= scale) { + rc->value -= scale; + rc->range -= scale; + k = 0; + } else { + rc->range = scale; + k = 1; + } + opus_rc_dec_normalize(rc); + return k; +} + +void ff_opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits) +{ + bits = (1 << bits) - 1; + opus_rc_enc_update(rc, (!!val)*bits, bits + !!val, bits + 1, 1); +} + +/** + * CELT: read 1-25 raw bits at the end of the frame, backwards byte-wise + */ +uint32_t ff_opus_rc_get_raw(OpusRangeCoder *rc, uint32_t count) +{ + uint32_t value = 0; + + while (rc->rb.bytes && rc->rb.cachelen < count) { + rc->rb.cacheval |= *--rc->rb.position << rc->rb.cachelen; + rc->rb.cachelen += 8; + rc->rb.bytes--; + } + + value = av_mod_uintp2(rc->rb.cacheval, count); + rc->rb.cacheval >>= count; + rc->rb.cachelen -= count; + rc->total_bits += count; + + return value; +} + +/** + * CELT: write 0 - 31 bits to the rawbits buffer + */ +void ff_opus_rc_put_raw(OpusRangeCoder *rc, uint32_t val, uint32_t count) +{ + const int to_write = FFMIN(32 - rc->rb.cachelen, count); + + rc->total_bits += count; + rc->rb.cacheval |= av_mod_uintp2(val, to_write) << rc->rb.cachelen; + rc->rb.cachelen = (rc->rb.cachelen + to_write) % 32; + + if (!rc->rb.cachelen && count) { + AV_WB32((uint8_t *)rc->rb.position, rc->rb.cacheval); + rc->rb.bytes += 4; + rc->rb.position -= 4; + rc->rb.cachelen = count - to_write; + rc->rb.cacheval = av_mod_uintp2(val >> to_write, rc->rb.cachelen); + av_assert0(rc->rng_cur < rc->rb.position); + } +} + +/** + * CELT: read a uniform distribution + */ +uint32_t ff_opus_rc_dec_uint(OpusRangeCoder *rc, uint32_t size) +{ + uint32_t bits, k, scale, total; + + bits = opus_ilog(size - 1); + total = (bits > 8) ? ((size - 1) >> (bits - 8)) + 1 : size; + + scale = rc->range / total; + k = rc->value / scale + 1; + k = total - FFMIN(k, total); + opus_rc_dec_update(rc, scale, k, k + 1, total); + + if (bits > 8) { + k = k << (bits - 8) | ff_opus_rc_get_raw(rc, bits - 8); + return FFMIN(k, size - 1); + } else + return k; +} + +/** + * CELT: write a uniformly distributed integer + */ +void ff_opus_rc_enc_uint(OpusRangeCoder *rc, uint32_t val, uint32_t size) +{ + const int ps = FFMAX(opus_ilog(size - 1) - 8, 0); + opus_rc_enc_update(rc, val >> ps, (val >> ps) + 1, ((size - 1) >> ps) + 1, 0); + ff_opus_rc_put_raw(rc, val, ps); +} + +uint32_t ff_opus_rc_dec_uint_step(OpusRangeCoder *rc, int k0) +{ + /* Use a probability of 3 up to itheta=8192 and then use 1 after */ + uint32_t k, scale, symbol, total = (k0+1)*3 + k0; + scale = rc->range / total; + symbol = rc->value / scale + 1; + symbol = total - FFMIN(symbol, total); + + k = (symbol < (k0+1)*3) ? symbol/3 : symbol - (k0+1)*2; + + opus_rc_dec_update(rc, scale, (k <= k0) ? 3*(k+0) : (k-1-k0) + 3*(k0+1), + (k <= k0) ? 3*(k+1) : (k-0-k0) + 3*(k0+1), total); + return k; +} + +void ff_opus_rc_enc_uint_step(OpusRangeCoder *rc, uint32_t val, int k0) +{ + const uint32_t a = val <= k0, b = 2*a + 1; + k0 = (k0 + 1) << 1; + val = b*(val + k0) - 3*a*k0; + opus_rc_enc_update(rc, val, val + b, (k0 << 1) - 1, 0); +} + +uint32_t ff_opus_rc_dec_uint_tri(OpusRangeCoder *rc, int qn) +{ + uint32_t k, scale, symbol, total, low, center; + + total = ((qn>>1) + 1) * ((qn>>1) + 1); + scale = rc->range / total; + center = rc->value / scale + 1; + center = total - FFMIN(center, total); + + if (center < total >> 1) { + k = (ff_sqrt(8 * center + 1) - 1) >> 1; + low = k * (k + 1) >> 1; + symbol = k + 1; + } else { + k = (2*(qn + 1) - ff_sqrt(8*(total - center - 1) + 1)) >> 1; + low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1); + symbol = qn + 1 - k; + } + + opus_rc_dec_update(rc, scale, low, low + symbol, total); + + return k; +} + +void ff_opus_rc_enc_uint_tri(OpusRangeCoder *rc, uint32_t k, int qn) +{ + uint32_t symbol, low, total; + + total = ((qn>>1) + 1) * ((qn>>1) + 1); + + if (k <= qn >> 1) { + low = k * (k + 1) >> 1; + symbol = k + 1; + } else { + low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1); + symbol = qn + 1 - k; + } + + opus_rc_enc_update(rc, low, low + symbol, total, 0); +} + +int ff_opus_rc_dec_laplace(OpusRangeCoder *rc, uint32_t symbol, int decay) +{ + /* extends the range coder to model a Laplace distribution */ + int value = 0; + uint32_t scale, low = 0, center; + + scale = rc->range >> 15; + center = rc->value / scale + 1; + center = (1 << 15) - FFMIN(center, 1 << 15); + + if (center >= symbol) { + value++; + low = symbol; + symbol = 1 + ((32768 - 32 - symbol) * (16384-decay) >> 15); + + while (symbol > 1 && center >= low + 2 * symbol) { + value++; + symbol *= 2; + low += symbol; + symbol = (((symbol - 2) * decay) >> 15) + 1; + } + + if (symbol <= 1) { + int distance = (center - low) >> 1; + value += distance; + low += 2 * distance; + } + + if (center < low + symbol) + value *= -1; + else + low += symbol; + } + + opus_rc_dec_update(rc, scale, low, FFMIN(low + symbol, 32768), 32768); + + return value; +} + +void ff_opus_rc_enc_laplace(OpusRangeCoder *rc, int *value, uint32_t symbol, int decay) +{ + uint32_t low = symbol; + int i = 1, val = FFABS(*value), pos = *value > 0; + if (!val) { + opus_rc_enc_update(rc, 0, symbol, 1 << 15, 1); + return; + } + symbol = ((32768 - 32 - symbol)*(16384 - decay)) >> 15; + for (; i < val && symbol; i++) { + low += (symbol << 1) + 2; + symbol = (symbol*decay) >> 14; + } + if (symbol) { + low += (++symbol)*pos; + } else { + const int distance = FFMIN(val - i, (((32768 - low) - !pos) >> 1) - 1); + low += pos + (distance << 1); + symbol = FFMIN(1, 32768 - low); + *value = FFSIGN(*value)*(distance + i); + } + opus_rc_enc_update(rc, low, low + symbol, 1 << 15, 1); +} + +int ff_opus_rc_dec_init(OpusRangeCoder *rc, const uint8_t *data, int size) +{ + int ret = init_get_bits8(&rc->gb, data, size); + if (ret < 0) + return ret; + + rc->range = 128; + rc->value = 127 - get_bits(&rc->gb, 7); + rc->total_bits = 9; + opus_rc_dec_normalize(rc); + + return 0; +} + +void ff_opus_rc_dec_raw_init(OpusRangeCoder *rc, const uint8_t *rightend, uint32_t bytes) +{ + rc->rb.position = rightend; + rc->rb.bytes = bytes; + rc->rb.cachelen = 0; + rc->rb.cacheval = 0; +} + +void ff_opus_rc_enc_end(OpusRangeCoder *rc, uint8_t *dst, int size) +{ + int rng_bytes, bits = OPUS_RC_BITS - opus_ilog(rc->range); + uint32_t mask = (OPUS_RC_TOP - 1) >> bits; + uint32_t end = (rc->value + mask) & ~mask; + + if ((end | mask) >= rc->value + rc->range) { + bits++; + mask >>= 1; + end = (rc->value + mask) & ~mask; + } + + /* Finish what's left */ + while (bits > 0) { + opus_rc_enc_carryout(rc, end >> OPUS_RC_SHIFT); + end = (end << OPUS_RC_SYM) & (OPUS_RC_TOP - 1); + bits -= OPUS_RC_SYM; + } + + /* Flush out anything left or marked */ + if (rc->rem >= 0 || rc->ext > 0) + opus_rc_enc_carryout(rc, 0); + + rng_bytes = rc->rng_cur - rc->buf; + memcpy(dst, rc->buf, rng_bytes); + + rc->waste = size*8 - (rc->rb.bytes*8 + rc->rb.cachelen) - rng_bytes*8; + + /* Put the rawbits part, if any */ + if (rc->rb.bytes || rc->rb.cachelen) { + int i, lap; + uint8_t *rb_src, *rb_dst; + ff_opus_rc_put_raw(rc, 0, 32 - rc->rb.cachelen); + rb_src = rc->buf + OPUS_MAX_PACKET_SIZE + 12 - rc->rb.bytes; + rb_dst = dst + FFMAX(size - rc->rb.bytes, 0); + lap = &dst[rng_bytes] - rb_dst; + for (i = 0; i < lap; i++) + rb_dst[i] |= rb_src[i]; + memcpy(&rb_dst[lap], &rb_src[lap], FFMAX(rc->rb.bytes - lap, 0)); + } +} + +void ff_opus_rc_enc_init(OpusRangeCoder *rc) +{ + rc->value = 0; + rc->range = OPUS_RC_TOP; + rc->total_bits = OPUS_RC_BITS + 1; + rc->rem = -1; + rc->ext = 0; + rc->rng_cur = rc->buf; + ff_opus_rc_dec_raw_init(rc, rc->buf + OPUS_MAX_PACKET_SIZE + 8, 0); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_rc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_rc.h new file mode 100644 index 000000000..627f83229 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opus_rc.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUS_RC_H +#define AVCODEC_OPUS_RC_H + +#include +#include "get_bits.h" + +#define OPUS_MAX_PACKET_SIZE 1275 + +#define opus_ilog(i) (av_log2(i) + !!(i)) + +typedef struct RawBitsContext { + const uint8_t *position; + uint32_t bytes; + uint32_t cachelen; + uint32_t cacheval; +} RawBitsContext; + +typedef struct OpusRangeCoder { + GetBitContext gb; + RawBitsContext rb; + uint32_t range; + uint32_t value; + uint32_t total_bits; + + /* Encoder */ + uint8_t buf[OPUS_MAX_PACKET_SIZE + 12]; /* memcpy vs (memmove + overreading) */ + uint8_t *rng_cur; /* Current range coded byte */ + int ext; /* Awaiting propagation */ + int rem; /* Carryout flag */ + + /* Encoding stats */ + int waste; +} OpusRangeCoder; + +/** + * CELT: estimate bits of entropy that have thus far been consumed for the + * current CELT frame, to integer and fractional (1/8th bit) precision + */ +static av_always_inline uint32_t opus_rc_tell(const OpusRangeCoder *rc) +{ + return rc->total_bits - av_log2(rc->range) - 1; +} + +static av_always_inline uint32_t opus_rc_tell_frac(const OpusRangeCoder *rc) +{ + uint32_t i, total_bits, rcbuffer, range; + + total_bits = rc->total_bits << 3; + rcbuffer = av_log2(rc->range) + 1; + range = rc->range >> (rcbuffer-16); + + for (i = 0; i < 3; i++) { + int bit; + range = range * range >> 15; + bit = range >> 16; + rcbuffer = rcbuffer << 1 | bit; + range >>= bit; + } + + return total_bits - rcbuffer; +} + +uint32_t ff_opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf); +void ff_opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf); + +uint32_t ff_opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits); +void ff_opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits); + +uint32_t ff_opus_rc_dec_uint_step(OpusRangeCoder *rc, int k0); +void ff_opus_rc_enc_uint_step(OpusRangeCoder *rc, uint32_t val, int k0); + +uint32_t ff_opus_rc_dec_uint_tri(OpusRangeCoder *rc, int qn); +void ff_opus_rc_enc_uint_tri(OpusRangeCoder *rc, uint32_t k, int qn); + +uint32_t ff_opus_rc_dec_uint(OpusRangeCoder *rc, uint32_t size); +void ff_opus_rc_enc_uint(OpusRangeCoder *rc, uint32_t val, uint32_t size); + +uint32_t ff_opus_rc_get_raw(OpusRangeCoder *rc, uint32_t count); +void ff_opus_rc_put_raw(OpusRangeCoder *rc, uint32_t val, uint32_t count); + +int ff_opus_rc_dec_laplace(OpusRangeCoder *rc, uint32_t symbol, int decay); +void ff_opus_rc_enc_laplace(OpusRangeCoder *rc, int *value, uint32_t symbol, int decay); + +int ff_opus_rc_dec_init(OpusRangeCoder *rc, const uint8_t *data, int size); +void ff_opus_rc_dec_raw_init(OpusRangeCoder *rc, const uint8_t *rightend, uint32_t bytes); + +void ff_opus_rc_enc_end(OpusRangeCoder *rc, uint8_t *dst, int size); +void ff_opus_rc_enc_init(OpusRangeCoder *rc); + +#define OPUS_RC_CHECKPOINT_UPDATE(rc) \ + rc_rollback_bits = opus_rc_tell_frac(rc); \ + rc_rollback_ctx = *rc + +#define OPUS_RC_CHECKPOINT_SPAWN(rc) \ + uint32_t rc_rollback_bits = opus_rc_tell_frac(rc); \ + OpusRangeCoder rc_rollback_ctx = *rc \ + +#define OPUS_RC_CHECKPOINT_BITS(rc) \ + (opus_rc_tell_frac(rc) - rc_rollback_bits) + +#define OPUS_RC_CHECKPOINT_ROLLBACK(rc) \ + memcpy(rc, &rc_rollback_ctx, sizeof(OpusRangeCoder)); \ + +#endif /* AVCODEC_OPUS_RC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusdsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusdsp.c new file mode 100644 index 000000000..0e179c98c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusdsp.c @@ -0,0 +1,67 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "opusdsp.h" + +static void postfilter_c(float *data, int period, float *gains, int len) +{ + const float g0 = gains[0]; + const float g1 = gains[1]; + const float g2 = gains[2]; + + float x4 = data[-period - 2]; + float x3 = data[-period - 1]; + float x2 = data[-period + 0]; + float x1 = data[-period + 1]; + + for (int i = 0; i < len; i++) { + float x0 = data[i - period + 2]; + data[i] += g0 * x2 + + g1 * (x1 + x3) + + g2 * (x0 + x4); + x4 = x3; + x3 = x2; + x2 = x1; + x1 = x0; + } +} + +static float deemphasis_c(float *y, float *x, float coeff, int len) +{ + float state = coeff; + + for (int i = 0; i < len; i++) { + const float tmp = x[i] + state; + state = tmp * CELT_EMPH_COEFF; + y[i] = tmp; + } + + return state; +} + +av_cold void ff_opus_dsp_init(OpusDSP *ctx) +{ + ctx->postfilter = postfilter_c; + ctx->deemphasis = deemphasis_c; + + if (ARCH_X86) + ff_opus_dsp_init_x86(ctx); + + if (ARCH_AARCH64) + ff_opus_dsp_init_aarch64(ctx); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusdsp.h new file mode 100644 index 000000000..ee3186dd4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusdsp.h @@ -0,0 +1,36 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUSDSP_H +#define AVCODEC_OPUSDSP_H + +#include "libavutil/common.h" + +#define CELT_EMPH_COEFF 0.8500061035f + +typedef struct OpusDSP { + void (*postfilter)(float *data, int period, float *gains, int len); + float (*deemphasis)(float *out, float *in, float coeff, int len); +} OpusDSP; + +void ff_opus_dsp_init(OpusDSP *ctx); + +void ff_opus_dsp_init_x86(OpusDSP *ctx); +void ff_opus_dsp_init_aarch64(OpusDSP *ctx); + +#endif /* AVCODEC_OPUSDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc.c new file mode 100644 index 000000000..3c08ebcf6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc.c @@ -0,0 +1,738 @@ +/* + * Opus encoder + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "opusenc.h" +#include "opus_pvq.h" +#include "opusenc_psy.h" +#include "opustab.h" + +#include "libavutil/float_dsp.h" +#include "libavutil/opt.h" +#include "internal.h" +#include "bytestream.h" +#include "audio_frame_queue.h" + +typedef struct OpusEncContext { + AVClass *av_class; + OpusEncOptions options; + OpusPsyContext psyctx; + AVCodecContext *avctx; + AudioFrameQueue afq; + AVFloatDSPContext *dsp; + MDCT15Context *mdct[CELT_BLOCK_NB]; + CeltPVQ *pvq; + struct FFBufQueue bufqueue; + + uint8_t enc_id[64]; + int enc_id_bits; + + OpusPacketInfo packet; + + int channels; + + CeltFrame *frame; + OpusRangeCoder *rc; + + /* Actual energy the decoder will have */ + float last_quantized_energy[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; + + DECLARE_ALIGNED(32, float, scratch)[2048]; +} OpusEncContext; + +static void opus_write_extradata(AVCodecContext *avctx) +{ + uint8_t *bs = avctx->extradata; + + bytestream_put_buffer(&bs, "OpusHead", 8); + bytestream_put_byte (&bs, 0x1); + bytestream_put_byte (&bs, avctx->channels); + bytestream_put_le16 (&bs, avctx->initial_padding); + bytestream_put_le32 (&bs, avctx->sample_rate); + bytestream_put_le16 (&bs, 0x0); + bytestream_put_byte (&bs, 0x0); /* Default layout */ +} + +static int opus_gen_toc(OpusEncContext *s, uint8_t *toc, int *size, int *fsize_needed) +{ + int tmp = 0x0, extended_toc = 0; + static const int toc_cfg[][OPUS_MODE_NB][OPUS_BANDWITH_NB] = { + /* Silk Hybrid Celt Layer */ + /* NB MB WB SWB FB NB MB WB SWB FB NB MB WB SWB FB Bandwidth */ + { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 17, 0, 21, 25, 29 } }, /* 2.5 ms */ + { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 18, 0, 22, 26, 30 } }, /* 5 ms */ + { { 1, 5, 9, 0, 0 }, { 0, 0, 0, 13, 15 }, { 19, 0, 23, 27, 31 } }, /* 10 ms */ + { { 2, 6, 10, 0, 0 }, { 0, 0, 0, 14, 16 }, { 20, 0, 24, 28, 32 } }, /* 20 ms */ + { { 3, 7, 11, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }, /* 40 ms */ + { { 4, 8, 12, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }, /* 60 ms */ + }; + int cfg = toc_cfg[s->packet.framesize][s->packet.mode][s->packet.bandwidth]; + *fsize_needed = 0; + if (!cfg) + return 1; + if (s->packet.frames == 2) { /* 2 packets */ + if (s->frame[0].framebits == s->frame[1].framebits) { /* same size */ + tmp = 0x1; + } else { /* different size */ + tmp = 0x2; + *fsize_needed = 1; /* put frame sizes in the packet */ + } + } else if (s->packet.frames > 2) { + tmp = 0x3; + extended_toc = 1; + } + tmp |= (s->channels > 1) << 2; /* Stereo or mono */ + tmp |= (cfg - 1) << 3; /* codec configuration */ + *toc++ = tmp; + if (extended_toc) { + for (int i = 0; i < (s->packet.frames - 1); i++) + *fsize_needed |= (s->frame[i].framebits != s->frame[i + 1].framebits); + tmp = (*fsize_needed) << 7; /* vbr flag */ + tmp |= (0) << 6; /* padding flag */ + tmp |= s->packet.frames; + *toc++ = tmp; + } + *size = 1 + extended_toc; + return 0; +} + +static void celt_frame_setup_input(OpusEncContext *s, CeltFrame *f) +{ + AVFrame *cur = NULL; + const int subframesize = s->avctx->frame_size; + int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize; + + cur = ff_bufqueue_get(&s->bufqueue); + + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *b = &f->block[ch]; + const void *input = cur->extended_data[ch]; + size_t bps = av_get_bytes_per_sample(cur->format); + memcpy(b->overlap, input, bps*cur->nb_samples); + } + + av_frame_free(&cur); + + for (int sf = 0; sf < subframes; sf++) { + if (sf != (subframes - 1)) + cur = ff_bufqueue_get(&s->bufqueue); + else + cur = ff_bufqueue_peek(&s->bufqueue, 0); + + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *b = &f->block[ch]; + const void *input = cur->extended_data[ch]; + const size_t bps = av_get_bytes_per_sample(cur->format); + const size_t left = (subframesize - cur->nb_samples)*bps; + const size_t len = FFMIN(subframesize, cur->nb_samples)*bps; + memcpy(&b->samples[sf*subframesize], input, len); + memset(&b->samples[cur->nb_samples], 0, left); + } + + /* Last frame isn't popped off and freed yet - we need it for overlap */ + if (sf != (subframes - 1)) + av_frame_free(&cur); + } +} + +/* Apply the pre emphasis filter */ +static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f) +{ + const int subframesize = s->avctx->frame_size; + const int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize; + + /* Filter overlap */ + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *b = &f->block[ch]; + float m = b->emph_coeff; + for (int i = 0; i < CELT_OVERLAP; i++) { + float sample = b->overlap[i]; + b->overlap[i] = sample - m; + m = sample * CELT_EMPH_COEFF; + } + b->emph_coeff = m; + } + + /* Filter the samples but do not update the last subframe's coeff - overlap ^^^ */ + for (int sf = 0; sf < subframes; sf++) { + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *b = &f->block[ch]; + float m = b->emph_coeff; + for (int i = 0; i < subframesize; i++) { + float sample = b->samples[sf*subframesize + i]; + b->samples[sf*subframesize + i] = sample - m; + m = sample * CELT_EMPH_COEFF; + } + if (sf != (subframes - 1)) + b->emph_coeff = m; + } + } +} + +/* Create the window and do the mdct */ +static void celt_frame_mdct(OpusEncContext *s, CeltFrame *f) +{ + float *win = s->scratch, *temp = s->scratch + 1920; + + if (f->transient) { + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *b = &f->block[ch]; + float *src1 = b->overlap; + for (int t = 0; t < f->blocks; t++) { + float *src2 = &b->samples[CELT_OVERLAP*t]; + s->dsp->vector_fmul(win, src1, ff_celt_window, 128); + s->dsp->vector_fmul_reverse(&win[CELT_OVERLAP], src2, + ff_celt_window - 8, 128); + src1 = src2; + s->mdct[0]->mdct(s->mdct[0], b->coeffs + t, win, f->blocks); + } + } + } else { + int blk_len = OPUS_BLOCK_SIZE(f->size), wlen = OPUS_BLOCK_SIZE(f->size + 1); + int rwin = blk_len - CELT_OVERLAP, lap_dst = (wlen - blk_len - CELT_OVERLAP) >> 1; + memset(win, 0, wlen*sizeof(float)); + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *b = &f->block[ch]; + + /* Overlap */ + s->dsp->vector_fmul(temp, b->overlap, ff_celt_window, 128); + memcpy(win + lap_dst, temp, CELT_OVERLAP*sizeof(float)); + + /* Samples, flat top window */ + memcpy(&win[lap_dst + CELT_OVERLAP], b->samples, rwin*sizeof(float)); + + /* Samples, windowed */ + s->dsp->vector_fmul_reverse(temp, b->samples + rwin, + ff_celt_window - 8, 128); + memcpy(win + lap_dst + blk_len, temp, CELT_OVERLAP*sizeof(float)); + + s->mdct[f->size]->mdct(s->mdct[f->size], b->coeffs, win, 1); + } + } + + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *block = &f->block[ch]; + for (int i = 0; i < CELT_MAX_BANDS; i++) { + float ener = 0.0f; + int band_offset = ff_celt_freq_bands[i] << f->size; + int band_size = ff_celt_freq_range[i] << f->size; + float *coeffs = &block->coeffs[band_offset]; + + for (int j = 0; j < band_size; j++) + ener += coeffs[j]*coeffs[j]; + + block->lin_energy[i] = sqrtf(ener) + FLT_EPSILON; + ener = 1.0f/block->lin_energy[i]; + + for (int j = 0; j < band_size; j++) + coeffs[j] *= ener; + + block->energy[i] = log2f(block->lin_energy[i]) - ff_celt_mean_energy[i]; + + /* CELT_ENERGY_SILENCE is what the decoder uses and its not -infinity */ + block->energy[i] = FFMAX(block->energy[i], CELT_ENERGY_SILENCE); + } + } +} + +static void celt_enc_tf(CeltFrame *f, OpusRangeCoder *rc) +{ + int tf_select = 0, diff = 0, tf_changed = 0, tf_select_needed; + int bits = f->transient ? 2 : 4; + + tf_select_needed = ((f->size && (opus_rc_tell(rc) + bits + 1) <= f->framebits)); + + for (int i = f->start_band; i < f->end_band; i++) { + if ((opus_rc_tell(rc) + bits + tf_select_needed) <= f->framebits) { + const int tbit = (diff ^ 1) == f->tf_change[i]; + ff_opus_rc_enc_log(rc, tbit, bits); + diff ^= tbit; + tf_changed |= diff; + } + bits = f->transient ? 4 : 5; + } + + if (tf_select_needed && ff_celt_tf_select[f->size][f->transient][0][tf_changed] != + ff_celt_tf_select[f->size][f->transient][1][tf_changed]) { + ff_opus_rc_enc_log(rc, f->tf_select, 1); + tf_select = f->tf_select; + } + + for (int i = f->start_band; i < f->end_band; i++) + f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]]; +} + +static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f) +{ + float gain = f->pf_gain; + int txval, octave = f->pf_octave, period = f->pf_period, tapset = f->pf_tapset; + + ff_opus_rc_enc_log(rc, f->pfilter, 1); + if (!f->pfilter) + return; + + /* Octave */ + txval = FFMIN(octave, 6); + ff_opus_rc_enc_uint(rc, txval, 6); + octave = txval; + /* Period */ + txval = av_clip(period - (16 << octave) + 1, 0, (1 << (4 + octave)) - 1); + ff_opus_rc_put_raw(rc, period, 4 + octave); + period = txval + (16 << octave) - 1; + /* Gain */ + txval = FFMIN(((int)(gain / 0.09375f)) - 1, 7); + ff_opus_rc_put_raw(rc, txval, 3); + gain = 0.09375f * (txval + 1); + /* Tapset */ + if ((opus_rc_tell(rc) + 2) <= f->framebits) + ff_opus_rc_enc_cdf(rc, tapset, ff_celt_model_tapset); + else + tapset = 0; + /* Finally create the coeffs */ + for (int i = 0; i < 2; i++) { + CeltBlock *block = &f->block[i]; + + block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD); + block->pf_gains_new[0] = gain * ff_celt_postfilter_taps[tapset][0]; + block->pf_gains_new[1] = gain * ff_celt_postfilter_taps[tapset][1]; + block->pf_gains_new[2] = gain * ff_celt_postfilter_taps[tapset][2]; + } +} + +static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f, + float last_energy[][CELT_MAX_BANDS], int intra) +{ + float alpha, beta, prev[2] = { 0, 0 }; + const uint8_t *pmod = ff_celt_coarse_energy_dist[f->size][intra]; + + /* Inter is really just differential coding */ + if (opus_rc_tell(rc) + 3 <= f->framebits) + ff_opus_rc_enc_log(rc, intra, 3); + else + intra = 0; + + if (intra) { + alpha = 0.0f; + beta = 1.0f - (4915.0f/32768.0f); + } else { + alpha = ff_celt_alpha_coef[f->size]; + beta = ff_celt_beta_coef[f->size]; + } + + for (int i = f->start_band; i < f->end_band; i++) { + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *block = &f->block[ch]; + const int left = f->framebits - opus_rc_tell(rc); + const float last = FFMAX(-9.0f, last_energy[ch][i]); + float diff = block->energy[i] - prev[ch] - last*alpha; + int q_en = lrintf(diff); + if (left >= 15) { + ff_opus_rc_enc_laplace(rc, &q_en, pmod[i << 1] << 7, pmod[(i << 1) + 1] << 6); + } else if (left >= 2) { + q_en = av_clip(q_en, -1, 1); + ff_opus_rc_enc_cdf(rc, 2*q_en + 3*(q_en < 0), ff_celt_model_energy_small); + } else if (left >= 1) { + q_en = av_clip(q_en, -1, 0); + ff_opus_rc_enc_log(rc, (q_en & 1), 1); + } else q_en = -1; + + block->error_energy[i] = q_en - diff; + prev[ch] += beta * q_en; + } + } +} + +static void celt_quant_coarse(CeltFrame *f, OpusRangeCoder *rc, + float last_energy[][CELT_MAX_BANDS]) +{ + uint32_t inter, intra; + OPUS_RC_CHECKPOINT_SPAWN(rc); + + exp_quant_coarse(rc, f, last_energy, 1); + intra = OPUS_RC_CHECKPOINT_BITS(rc); + + OPUS_RC_CHECKPOINT_ROLLBACK(rc); + + exp_quant_coarse(rc, f, last_energy, 0); + inter = OPUS_RC_CHECKPOINT_BITS(rc); + + if (inter > intra) { /* Unlikely */ + OPUS_RC_CHECKPOINT_ROLLBACK(rc); + exp_quant_coarse(rc, f, last_energy, 1); + } +} + +static void celt_quant_fine(CeltFrame *f, OpusRangeCoder *rc) +{ + for (int i = f->start_band; i < f->end_band; i++) { + if (!f->fine_bits[i]) + continue; + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *block = &f->block[ch]; + int quant, lim = (1 << f->fine_bits[i]); + float offset, diff = 0.5f - block->error_energy[i]; + quant = av_clip(floor(diff*lim), 0, lim - 1); + ff_opus_rc_put_raw(rc, quant, f->fine_bits[i]); + offset = 0.5f - ((quant + 0.5f) * (1 << (14 - f->fine_bits[i])) / 16384.0f); + block->error_energy[i] -= offset; + } + } +} + +static void celt_quant_final(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame *f) +{ + for (int priority = 0; priority < 2; priority++) { + for (int i = f->start_band; i < f->end_band && (f->framebits - opus_rc_tell(rc)) >= f->channels; i++) { + if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS) + continue; + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *block = &f->block[ch]; + const float err = block->error_energy[i]; + const float offset = 0.5f * (1 << (14 - f->fine_bits[i] - 1)) / 16384.0f; + const int sign = FFABS(err + offset) < FFABS(err - offset); + ff_opus_rc_put_raw(rc, sign, 1); + block->error_energy[i] -= offset*(1 - 2*sign); + } + } + } +} + +static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc, + CeltFrame *f, int index) +{ + ff_opus_rc_enc_init(rc); + + ff_opus_psy_celt_frame_init(&s->psyctx, f, index); + + celt_frame_setup_input(s, f); + + if (f->silence) { + if (f->framebits >= 16) + ff_opus_rc_enc_log(rc, 1, 15); /* Silence (if using explicit singalling) */ + for (int ch = 0; ch < s->channels; ch++) + memset(s->last_quantized_energy[ch], 0.0f, sizeof(float)*CELT_MAX_BANDS); + return; + } + + /* Filters */ + celt_apply_preemph_filter(s, f); + if (f->pfilter) { + ff_opus_rc_enc_log(rc, 0, 15); + celt_enc_quant_pfilter(rc, f); + } + + /* Transform */ + celt_frame_mdct(s, f); + + /* Need to handle transient/non-transient switches at any point during analysis */ + while (ff_opus_psy_celt_frame_process(&s->psyctx, f, index)) + celt_frame_mdct(s, f); + + ff_opus_rc_enc_init(rc); + + /* Silence */ + ff_opus_rc_enc_log(rc, 0, 15); + + /* Pitch filter */ + if (!f->start_band && opus_rc_tell(rc) + 16 <= f->framebits) + celt_enc_quant_pfilter(rc, f); + + /* Transient flag */ + if (f->size && opus_rc_tell(rc) + 3 <= f->framebits) + ff_opus_rc_enc_log(rc, f->transient, 3); + + /* Main encoding */ + celt_quant_coarse (f, rc, s->last_quantized_energy); + celt_enc_tf (f, rc); + ff_celt_bitalloc (f, rc, 1); + celt_quant_fine (f, rc); + ff_celt_quant_bands(f, rc); + + /* Anticollapse bit */ + if (f->anticollapse_needed) + ff_opus_rc_put_raw(rc, f->anticollapse, 1); + + /* Final per-band energy adjustments from leftover bits */ + celt_quant_final(s, rc, f); + + for (int ch = 0; ch < f->channels; ch++) { + CeltBlock *block = &f->block[ch]; + for (int i = 0; i < CELT_MAX_BANDS; i++) + s->last_quantized_energy[ch][i] = block->energy[i] + block->error_energy[i]; + } +} + +static inline int write_opuslacing(uint8_t *dst, int v) +{ + dst[0] = FFMIN(v - FFALIGN(v - 255, 4), v); + dst[1] = v - dst[0] >> 2; + return 1 + (v >= 252); +} + +static void opus_packet_assembler(OpusEncContext *s, AVPacket *avpkt) +{ + int offset, fsize_needed; + + /* Write toc */ + opus_gen_toc(s, avpkt->data, &offset, &fsize_needed); + + /* Frame sizes if needed */ + if (fsize_needed) { + for (int i = 0; i < s->packet.frames - 1; i++) { + offset += write_opuslacing(avpkt->data + offset, + s->frame[i].framebits >> 3); + } + } + + /* Packets */ + for (int i = 0; i < s->packet.frames; i++) { + ff_opus_rc_enc_end(&s->rc[i], avpkt->data + offset, + s->frame[i].framebits >> 3); + offset += s->frame[i].framebits >> 3; + } + + avpkt->size = offset; +} + +/* Used as overlap for the first frame and padding for the last encoded packet */ +static AVFrame *spawn_empty_frame(OpusEncContext *s) +{ + AVFrame *f = av_frame_alloc(); + if (!f) + return NULL; + f->format = s->avctx->sample_fmt; + f->nb_samples = s->avctx->frame_size; + f->channel_layout = s->avctx->channel_layout; + if (av_frame_get_buffer(f, 4)) { + av_frame_free(&f); + return NULL; + } + for (int i = 0; i < s->channels; i++) { + size_t bps = av_get_bytes_per_sample(f->format); + memset(f->extended_data[i], 0, bps*f->nb_samples); + } + return f; +} + +static int opus_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + OpusEncContext *s = avctx->priv_data; + int ret, frame_size, alloc_size = 0; + + if (frame) { /* Add new frame to queue */ + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) + return ret; + ff_bufqueue_add(avctx, &s->bufqueue, av_frame_clone(frame)); + } else { + ff_opus_psy_signal_eof(&s->psyctx); + if (!s->afq.remaining_samples || !avctx->frame_number) + return 0; /* We've been flushed and there's nothing left to encode */ + } + + /* Run the psychoacoustic system */ + if (ff_opus_psy_process(&s->psyctx, &s->packet)) + return 0; + + frame_size = OPUS_BLOCK_SIZE(s->packet.framesize); + + if (!frame) { + /* This can go negative, that's not a problem, we only pad if positive */ + int pad_empty = s->packet.frames*(frame_size/s->avctx->frame_size) - s->bufqueue.available + 1; + /* Pad with empty 2.5 ms frames to whatever framesize was decided, + * this should only happen at the very last flush frame. The frames + * allocated here will be freed (because they have no other references) + * after they get used by celt_frame_setup_input() */ + for (int i = 0; i < pad_empty; i++) { + AVFrame *empty = spawn_empty_frame(s); + if (!empty) + return AVERROR(ENOMEM); + ff_bufqueue_add(avctx, &s->bufqueue, empty); + } + } + + for (int i = 0; i < s->packet.frames; i++) { + celt_encode_frame(s, &s->rc[i], &s->frame[i], i); + alloc_size += s->frame[i].framebits >> 3; + } + + /* Worst case toc + the frame lengths if needed */ + alloc_size += 2 + s->packet.frames*2; + + if ((ret = ff_alloc_packet2(avctx, avpkt, alloc_size, 0)) < 0) + return ret; + + /* Assemble packet */ + opus_packet_assembler(s, avpkt); + + /* Update the psychoacoustic system */ + ff_opus_psy_postencode_update(&s->psyctx, s->frame, s->rc); + + /* Remove samples from queue and skip if needed */ + ff_af_queue_remove(&s->afq, s->packet.frames*frame_size, &avpkt->pts, &avpkt->duration); + if (s->packet.frames*frame_size > avpkt->duration) { + uint8_t *side = av_packet_new_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, 10); + if (!side) + return AVERROR(ENOMEM); + AV_WL32(&side[4], s->packet.frames*frame_size - avpkt->duration + 120); + } + + *got_packet_ptr = 1; + + return 0; +} + +static av_cold int opus_encode_end(AVCodecContext *avctx) +{ + OpusEncContext *s = avctx->priv_data; + + for (int i = 0; i < CELT_BLOCK_NB; i++) + ff_mdct15_uninit(&s->mdct[i]); + + ff_celt_pvq_uninit(&s->pvq); + av_freep(&s->dsp); + av_freep(&s->frame); + av_freep(&s->rc); + ff_af_queue_close(&s->afq); + ff_opus_psy_end(&s->psyctx); + ff_bufqueue_discard_all(&s->bufqueue); + av_freep(&avctx->extradata); + + return 0; +} + +static av_cold int opus_encode_init(AVCodecContext *avctx) +{ + int ret, max_frames; + OpusEncContext *s = avctx->priv_data; + + s->avctx = avctx; + s->channels = avctx->channels; + + /* Opus allows us to change the framesize on each packet (and each packet may + * have multiple frames in it) but we can't change the codec's frame size on + * runtime, so fix it to the lowest possible number of samples and use a queue + * to accumulate AVFrames until we have enough to encode whatever the encoder + * decides is the best */ + avctx->frame_size = 120; + /* Initial padding will change if SILK is ever supported */ + avctx->initial_padding = 120; + + if (!avctx->bit_rate) { + int coupled = ff_opus_default_coupled_streams[s->channels - 1]; + avctx->bit_rate = coupled*(96000) + (s->channels - coupled*2)*(48000); + } else if (avctx->bit_rate < 6000 || avctx->bit_rate > 255000 * s->channels) { + int64_t clipped_rate = av_clip(avctx->bit_rate, 6000, 255000 * s->channels); + av_log(avctx, AV_LOG_ERROR, "Unsupported bitrate %"PRId64" kbps, clipping to %"PRId64" kbps\n", + avctx->bit_rate/1000, clipped_rate/1000); + avctx->bit_rate = clipped_rate; + } + + /* Extradata */ + avctx->extradata_size = 19; + avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + opus_write_extradata(avctx); + + ff_af_queue_init(avctx, &s->afq); + + if ((ret = ff_celt_pvq_init(&s->pvq, 1)) < 0) + return ret; + + if (!(s->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT))) + return AVERROR(ENOMEM); + + /* I have no idea why a base scaling factor of 68 works, could be the twiddles */ + for (int i = 0; i < CELT_BLOCK_NB; i++) + if ((ret = ff_mdct15_init(&s->mdct[i], 0, i + 3, 68 << (CELT_BLOCK_NB - 1 - i)))) + return AVERROR(ENOMEM); + + /* Zero out previous energy (matters for inter first frame) */ + for (int ch = 0; ch < s->channels; ch++) + memset(s->last_quantized_energy[ch], 0.0f, sizeof(float)*CELT_MAX_BANDS); + + /* Allocate an empty frame to use as overlap for the first frame of audio */ + ff_bufqueue_add(avctx, &s->bufqueue, spawn_empty_frame(s)); + if (!ff_bufqueue_peek(&s->bufqueue, 0)) + return AVERROR(ENOMEM); + + if ((ret = ff_opus_psy_init(&s->psyctx, s->avctx, &s->bufqueue, &s->options))) + return ret; + + /* Frame structs and range coder buffers */ + max_frames = ceilf(FFMIN(s->options.max_delay_ms, 120.0f)/2.5f); + s->frame = av_malloc(max_frames*sizeof(CeltFrame)); + if (!s->frame) + return AVERROR(ENOMEM); + s->rc = av_malloc(max_frames*sizeof(OpusRangeCoder)); + if (!s->rc) + return AVERROR(ENOMEM); + + for (int i = 0; i < max_frames; i++) { + s->frame[i].dsp = s->dsp; + s->frame[i].avctx = s->avctx; + s->frame[i].seed = 0; + s->frame[i].pvq = s->pvq; + s->frame[i].apply_phase_inv = 1; + s->frame[i].block[0].emph_coeff = s->frame[i].block[1].emph_coeff = 0.0f; + } + + return 0; +} + +#define OPUSENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM +static const AVOption opusenc_options[] = { + { "opus_delay", "Maximum delay in milliseconds", offsetof(OpusEncContext, options.max_delay_ms), AV_OPT_TYPE_FLOAT, { .dbl = OPUS_MAX_LOOKAHEAD }, 2.5f, OPUS_MAX_LOOKAHEAD, OPUSENC_FLAGS, "max_delay_ms" }, + { NULL }, +}; + +static const AVClass opusenc_class = { + .class_name = "Opus encoder", + .item_name = av_default_item_name, + .option = opusenc_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVCodecDefault opusenc_defaults[] = { + { "b", "0" }, + { "compression_level", "10" }, + { NULL }, +}; + +AVCodec ff_opus_encoder = { + .name = "opus", + .long_name = NULL_IF_CONFIG_SMALL("Opus"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_OPUS, + .defaults = opusenc_defaults, + .priv_class = &opusenc_class, + .priv_data_size = sizeof(OpusEncContext), + .init = opus_encode_init, + .encode2 = opus_encode_frame, + .close = opus_encode_end, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, + .capabilities = AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY, + .supported_samplerates = (const int []){ 48000, 0 }, + .channel_layouts = (const uint64_t []){ AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, 0 }, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc.h new file mode 100644 index 000000000..b9162ebec --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc.h @@ -0,0 +1,54 @@ +/* + * Opus encoder + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUSENC_H +#define AVCODEC_OPUSENC_H + +#include "internal.h" +#include "opus_celt.h" + +/* Determines the maximum delay the psychoacoustic system will use for lookahead */ +#define FF_BUFQUEUE_SIZE 145 +#include "libavfilter/bufferqueue.h" + +#define OPUS_MAX_LOOKAHEAD ((FF_BUFQUEUE_SIZE - 1)*2.5f) + +#define OPUS_MAX_CHANNELS 2 + +/* 120 ms / 2.5 ms = 48 frames (extremely improbable, but the encoder'll work) */ +#define OPUS_MAX_FRAMES_PER_PACKET 48 + +#define OPUS_BLOCK_SIZE(x) (2 * 15 * (1 << ((x) + 2))) + +#define OPUS_SAMPLES_TO_BLOCK_SIZE(x) (ff_log2((x) / (2 * 15)) - 2) + +typedef struct OpusEncOptions { + float max_delay_ms; +} OpusEncOptions; + +typedef struct OpusPacketInfo { + enum OpusMode mode; + enum OpusBandwidth bandwidth; + int framesize; + int frames; +} OpusPacketInfo; + +#endif /* AVCODEC_OPUSENC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_psy.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_psy.c new file mode 100644 index 000000000..5a50db942 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_psy.c @@ -0,0 +1,612 @@ +/* + * Opus encoder + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "opusenc_psy.h" +#include "opus_pvq.h" +#include "opustab.h" +#include "mdct15.h" +#include "libavutil/qsort.h" + +static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int band, + float *bits, float lambda) +{ + int i, b = 0; + uint32_t cm[2] = { (1 << f->blocks) - 1, (1 << f->blocks) - 1 }; + const int band_size = ff_celt_freq_range[band] << f->size; + float buf[176 * 2], lowband_scratch[176], norm1[176], norm2[176]; + float dist, cost, err_x = 0.0f, err_y = 0.0f; + float *X = buf; + float *X_orig = f->block[0].coeffs + (ff_celt_freq_bands[band] << f->size); + float *Y = (f->channels == 2) ? &buf[176] : NULL; + float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] << f->size); + OPUS_RC_CHECKPOINT_SPAWN(rc); + + memcpy(X, X_orig, band_size*sizeof(float)); + if (Y) + memcpy(Y, Y_orig, band_size*sizeof(float)); + + f->remaining2 = ((f->framebits << 3) - f->anticollapse_needed) - opus_rc_tell_frac(rc) - 1; + if (band <= f->coded_bands - 1) { + int curr_balance = f->remaining / FFMIN(3, f->coded_bands - band); + b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[band] + curr_balance), 14); + } + + if (f->dual_stereo) { + pvq->quant_band(pvq, f, rc, band, X, NULL, band_size, b / 2, f->blocks, NULL, + f->size, norm1, 0, 1.0f, lowband_scratch, cm[0]); + + pvq->quant_band(pvq, f, rc, band, Y, NULL, band_size, b / 2, f->blocks, NULL, + f->size, norm2, 0, 1.0f, lowband_scratch, cm[1]); + } else { + pvq->quant_band(pvq, f, rc, band, X, Y, band_size, b, f->blocks, NULL, f->size, + norm1, 0, 1.0f, lowband_scratch, cm[0] | cm[1]); + } + + for (i = 0; i < band_size; i++) { + err_x += (X[i] - X_orig[i])*(X[i] - X_orig[i]); + if (Y) + err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]); + } + + dist = sqrtf(err_x) + sqrtf(err_y); + cost = OPUS_RC_CHECKPOINT_BITS(rc)/8.0f; + *bits += cost; + + OPUS_RC_CHECKPOINT_ROLLBACK(rc); + + return lambda*dist*cost; +} + +/* Populate metrics without taking into consideration neighbouring steps */ +static void step_collect_psy_metrics(OpusPsyContext *s, int index) +{ + int silence = 0, ch, i, j; + OpusPsyStep *st = s->steps[index]; + + st->index = index; + + for (ch = 0; ch < s->avctx->channels; ch++) { + const int lap_size = (1 << s->bsize_analysis); + for (i = 1; i <= FFMIN(lap_size, index); i++) { + const int offset = i*120; + AVFrame *cur = ff_bufqueue_peek(s->bufqueue, index - i); + memcpy(&s->scratch[offset], cur->extended_data[ch], cur->nb_samples*sizeof(float)); + } + for (i = 0; i < lap_size; i++) { + const int offset = i*120 + lap_size; + AVFrame *cur = ff_bufqueue_peek(s->bufqueue, index + i); + memcpy(&s->scratch[offset], cur->extended_data[ch], cur->nb_samples*sizeof(float)); + } + + s->dsp->vector_fmul(s->scratch, s->scratch, s->window[s->bsize_analysis], + (OPUS_BLOCK_SIZE(s->bsize_analysis) << 1)); + + s->mdct[s->bsize_analysis]->mdct(s->mdct[s->bsize_analysis], st->coeffs[ch], s->scratch, 1); + + for (i = 0; i < CELT_MAX_BANDS; i++) + st->bands[ch][i] = &st->coeffs[ch][ff_celt_freq_bands[i] << s->bsize_analysis]; + } + + for (ch = 0; ch < s->avctx->channels; ch++) { + for (i = 0; i < CELT_MAX_BANDS; i++) { + float avg_c_s, energy = 0.0f, dist_dev = 0.0f; + const int range = ff_celt_freq_range[i] << s->bsize_analysis; + const float *coeffs = st->bands[ch][i]; + for (j = 0; j < range; j++) + energy += coeffs[j]*coeffs[j]; + + st->energy[ch][i] += sqrtf(energy); + silence |= !!st->energy[ch][i]; + avg_c_s = energy / range; + + for (j = 0; j < range; j++) { + const float c_s = coeffs[j]*coeffs[j]; + dist_dev += (avg_c_s - c_s)*(avg_c_s - c_s); + } + + st->tone[ch][i] += sqrtf(dist_dev); + } + } + + st->silence = !silence; + + if (s->avctx->channels > 1) { + for (i = 0; i < CELT_MAX_BANDS; i++) { + float incompat = 0.0f; + const float *coeffs1 = st->bands[0][i]; + const float *coeffs2 = st->bands[1][i]; + const int range = ff_celt_freq_range[i] << s->bsize_analysis; + for (j = 0; j < range; j++) + incompat += (coeffs1[j] - coeffs2[j])*(coeffs1[j] - coeffs2[j]); + st->stereo[i] = sqrtf(incompat); + } + } + + for (ch = 0; ch < s->avctx->channels; ch++) { + for (i = 0; i < CELT_MAX_BANDS; i++) { + OpusBandExcitation *ex = &s->ex[ch][i]; + float bp_e = bessel_filter(&s->bfilter_lo[ch][i], st->energy[ch][i]); + bp_e = bessel_filter(&s->bfilter_hi[ch][i], bp_e); + bp_e *= bp_e; + if (bp_e > ex->excitation) { + st->change_amp[ch][i] = bp_e - ex->excitation; + st->total_change += st->change_amp[ch][i]; + ex->excitation = ex->excitation_init = bp_e; + ex->excitation_dist = 0.0f; + } + if (ex->excitation > 0.0f) { + ex->excitation -= av_clipf((1/expf(ex->excitation_dist)), ex->excitation_init/20, ex->excitation_init/1.09); + ex->excitation = FFMAX(ex->excitation, 0.0f); + ex->excitation_dist += 1.0f; + } + } + } +} + +static void search_for_change_points(OpusPsyContext *s, float tgt_change, + int offset_s, int offset_e, int resolution, + int level) +{ + int i; + float c_change = 0.0f; + if ((offset_e - offset_s) <= resolution) + return; + for (i = offset_s; i < offset_e; i++) { + c_change += s->steps[i]->total_change; + if (c_change > tgt_change) + break; + } + if (i == offset_e) + return; + search_for_change_points(s, tgt_change / 2.0f, offset_s, i + 0, resolution, level + 1); + s->inflection_points[s->inflection_points_count++] = i; + search_for_change_points(s, tgt_change / 2.0f, i + 1, offset_e, resolution, level + 1); +} + +static int flush_silent_frames(OpusPsyContext *s) +{ + int fsize, silent_frames; + + for (silent_frames = 0; silent_frames < s->buffered_steps; silent_frames++) + if (!s->steps[silent_frames]->silence) + break; + if (--silent_frames < 0) + return 0; + + for (fsize = CELT_BLOCK_960; fsize > CELT_BLOCK_120; fsize--) { + if ((1 << fsize) > silent_frames) + continue; + s->p.frames = FFMIN(silent_frames / (1 << fsize), 48 >> fsize); + s->p.framesize = fsize; + return 1; + } + + return 0; +} + +/* Main function which decides frame size and frames per current packet */ +static void psy_output_groups(OpusPsyContext *s) +{ + int max_delay_samples = (s->options->max_delay_ms*s->avctx->sample_rate)/1000; + int max_bsize = FFMIN(OPUS_SAMPLES_TO_BLOCK_SIZE(max_delay_samples), CELT_BLOCK_960); + + /* These don't change for now */ + s->p.mode = OPUS_MODE_CELT; + s->p.bandwidth = OPUS_BANDWIDTH_FULLBAND; + + /* Flush silent frames ASAP */ + if (s->steps[0]->silence && flush_silent_frames(s)) + return; + + s->p.framesize = FFMIN(max_bsize, CELT_BLOCK_960); + s->p.frames = 1; +} + +int ff_opus_psy_process(OpusPsyContext *s, OpusPacketInfo *p) +{ + int i; + float total_energy_change = 0.0f; + + if (s->buffered_steps < s->max_steps && !s->eof) { + const int awin = (1 << s->bsize_analysis); + if (++s->steps_to_process >= awin) { + step_collect_psy_metrics(s, s->buffered_steps - awin + 1); + s->steps_to_process = 0; + } + if ((++s->buffered_steps) < s->max_steps) + return 1; + } + + for (i = 0; i < s->buffered_steps; i++) + total_energy_change += s->steps[i]->total_change; + + search_for_change_points(s, total_energy_change / 2.0f, 0, + s->buffered_steps, 1, 0); + + psy_output_groups(s); + + p->frames = s->p.frames; + p->framesize = s->p.framesize; + p->mode = s->p.mode; + p->bandwidth = s->p.bandwidth; + + return 0; +} + +void ff_opus_psy_celt_frame_init(OpusPsyContext *s, CeltFrame *f, int index) +{ + int i, neighbouring_points = 0, start_offset = 0; + int radius = (1 << s->p.framesize), step_offset = radius*index; + int silence = 1; + + f->start_band = (s->p.mode == OPUS_MODE_HYBRID) ? 17 : 0; + f->end_band = ff_celt_band_end[s->p.bandwidth]; + f->channels = s->avctx->channels; + f->size = s->p.framesize; + + for (i = 0; i < (1 << f->size); i++) + silence &= s->steps[index*(1 << f->size) + i]->silence; + + f->silence = silence; + if (f->silence) { + f->framebits = 0; /* Otherwise the silence flag eats up 16(!) bits */ + return; + } + + for (i = 0; i < s->inflection_points_count; i++) { + if (s->inflection_points[i] >= step_offset) { + start_offset = i; + break; + } + } + + for (i = start_offset; i < FFMIN(radius, s->inflection_points_count - start_offset); i++) { + if (s->inflection_points[i] < (step_offset + radius)) { + neighbouring_points++; + } + } + + /* Transient flagging */ + f->transient = neighbouring_points > 0; + f->blocks = f->transient ? OPUS_BLOCK_SIZE(s->p.framesize)/CELT_OVERLAP : 1; + + /* Some sane defaults */ + f->pfilter = 0; + f->pf_gain = 0.5f; + f->pf_octave = 2; + f->pf_period = 1; + f->pf_tapset = 2; + + /* More sane defaults */ + f->tf_select = 0; + f->anticollapse = 1; + f->alloc_trim = 5; + f->skip_band_floor = f->end_band; + f->intensity_stereo = f->end_band; + f->dual_stereo = 0; + f->spread = CELT_SPREAD_NORMAL; + memset(f->tf_change, 0, sizeof(int)*CELT_MAX_BANDS); + memset(f->alloc_boost, 0, sizeof(int)*CELT_MAX_BANDS); +} + +static void celt_gauge_psy_weight(OpusPsyContext *s, OpusPsyStep **start, + CeltFrame *f_out) +{ + int i, f, ch; + int frame_size = OPUS_BLOCK_SIZE(s->p.framesize); + float rate, frame_bits = 0; + + /* Used for the global ROTATE flag */ + float tonal = 0.0f; + + /* Pseudo-weights */ + float band_score[CELT_MAX_BANDS] = { 0 }; + float max_score = 1.0f; + + /* Pass one - one loop around each band, computing unquant stuff */ + for (i = 0; i < CELT_MAX_BANDS; i++) { + float weight = 0.0f; + float tonal_contrib = 0.0f; + for (f = 0; f < (1 << s->p.framesize); f++) { + weight = start[f]->stereo[i]; + for (ch = 0; ch < s->avctx->channels; ch++) { + weight += start[f]->change_amp[ch][i] + start[f]->tone[ch][i] + start[f]->energy[ch][i]; + tonal_contrib += start[f]->tone[ch][i]; + } + } + tonal += tonal_contrib; + band_score[i] = weight; + } + + tonal /= (float)CELT_MAX_BANDS; + + for (i = 0; i < CELT_MAX_BANDS; i++) { + if (band_score[i] > max_score) + max_score = band_score[i]; + } + + for (i = 0; i < CELT_MAX_BANDS; i++) { + f_out->alloc_boost[i] = (int)((band_score[i]/max_score)*3.0f); + frame_bits += band_score[i]*8.0f; + } + + tonal /= 1333136.0f; + f_out->spread = av_clip_uintp2(lrintf(tonal), 2); + + rate = ((float)s->avctx->bit_rate) + frame_bits*frame_size*16; + rate *= s->lambda; + rate /= s->avctx->sample_rate/frame_size; + + f_out->framebits = lrintf(rate); + f_out->framebits = FFMIN(f_out->framebits, OPUS_MAX_PACKET_SIZE*8); + f_out->framebits = FFALIGN(f_out->framebits, 8); +} + +static int bands_dist(OpusPsyContext *s, CeltFrame *f, float *total_dist) +{ + int i, tdist = 0.0f; + OpusRangeCoder dump; + + ff_opus_rc_enc_init(&dump); + ff_celt_bitalloc(f, &dump, 1); + + for (i = 0; i < CELT_MAX_BANDS; i++) { + float bits = 0.0f; + float dist = pvq_band_cost(f->pvq, f, &dump, i, &bits, s->lambda); + tdist += dist; + } + + *total_dist = tdist; + + return 0; +} + +static void celt_search_for_dual_stereo(OpusPsyContext *s, CeltFrame *f) +{ + float td1, td2; + f->dual_stereo = 0; + + if (s->avctx->channels < 2) + return; + + bands_dist(s, f, &td1); + f->dual_stereo = 1; + bands_dist(s, f, &td2); + + f->dual_stereo = td2 < td1; + s->dual_stereo_used += td2 < td1; +} + +static void celt_search_for_intensity(OpusPsyContext *s, CeltFrame *f) +{ + int i, best_band = CELT_MAX_BANDS - 1; + float dist, best_dist = FLT_MAX; + /* TODO: fix, make some heuristic up here using the lambda value */ + float end_band = 0; + + if (s->avctx->channels < 2) + return; + + for (i = f->end_band; i >= end_band; i--) { + f->intensity_stereo = i; + bands_dist(s, f, &dist); + if (best_dist > dist) { + best_dist = dist; + best_band = i; + } + } + + f->intensity_stereo = best_band; + s->avg_is_band = (s->avg_is_band + f->intensity_stereo)/2.0f; +} + +static int celt_search_for_tf(OpusPsyContext *s, OpusPsyStep **start, CeltFrame *f) +{ + int i, j, k, cway, config[2][CELT_MAX_BANDS] = { { 0 } }; + float score[2] = { 0 }; + + for (cway = 0; cway < 2; cway++) { + int mag[2]; + int base = f->transient ? 120 : 960; + + for (i = 0; i < 2; i++) { + int c = ff_celt_tf_select[f->size][f->transient][cway][i]; + mag[i] = c < 0 ? base >> FFABS(c) : base << FFABS(c); + } + + for (i = 0; i < CELT_MAX_BANDS; i++) { + float iscore0 = 0.0f; + float iscore1 = 0.0f; + for (j = 0; j < (1 << f->size); j++) { + for (k = 0; k < s->avctx->channels; k++) { + iscore0 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[0]; + iscore1 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[1]; + } + } + config[cway][i] = FFABS(iscore0 - 1.0f) < FFABS(iscore1 - 1.0f); + score[cway] += config[cway][i] ? iscore1 : iscore0; + } + } + + f->tf_select = score[0] < score[1]; + memcpy(f->tf_change, config[f->tf_select], sizeof(int)*CELT_MAX_BANDS); + + return 0; +} + +int ff_opus_psy_celt_frame_process(OpusPsyContext *s, CeltFrame *f, int index) +{ + int start_transient_flag = f->transient; + OpusPsyStep **start = &s->steps[index * (1 << s->p.framesize)]; + + if (f->silence) + return 0; + + celt_gauge_psy_weight(s, start, f); + celt_search_for_intensity(s, f); + celt_search_for_dual_stereo(s, f); + celt_search_for_tf(s, start, f); + + if (f->transient != start_transient_flag) { + f->blocks = f->transient ? OPUS_BLOCK_SIZE(s->p.framesize)/CELT_OVERLAP : 1; + s->redo_analysis = 1; + return 1; + } + + s->redo_analysis = 0; + + return 0; +} + +void ff_opus_psy_postencode_update(OpusPsyContext *s, CeltFrame *f, OpusRangeCoder *rc) +{ + int i, frame_size = OPUS_BLOCK_SIZE(s->p.framesize); + int steps_out = s->p.frames*(frame_size/120); + void *tmp[FF_BUFQUEUE_SIZE]; + float ideal_fbits; + + for (i = 0; i < steps_out; i++) + memset(s->steps[i], 0, sizeof(OpusPsyStep)); + + for (i = 0; i < s->max_steps; i++) + tmp[i] = s->steps[i]; + + for (i = 0; i < s->max_steps; i++) { + const int i_new = i - steps_out; + s->steps[i_new < 0 ? s->max_steps + i_new : i_new] = tmp[i]; + } + + for (i = steps_out; i < s->buffered_steps; i++) + s->steps[i]->index -= steps_out; + + ideal_fbits = s->avctx->bit_rate/(s->avctx->sample_rate/frame_size); + + for (i = 0; i < s->p.frames; i++) { + s->avg_is_band += f[i].intensity_stereo; + s->lambda *= ideal_fbits / f[i].framebits; + } + + s->avg_is_band /= (s->p.frames + 1); + + s->cs_num = 0; + s->steps_to_process = 0; + s->buffered_steps -= steps_out; + s->total_packets_out += s->p.frames; + s->inflection_points_count = 0; +} + +av_cold int ff_opus_psy_init(OpusPsyContext *s, AVCodecContext *avctx, + struct FFBufQueue *bufqueue, OpusEncOptions *options) +{ + int i, ch, ret; + + s->redo_analysis = 0; + s->lambda = 1.0f; + s->options = options; + s->avctx = avctx; + s->bufqueue = bufqueue; + s->max_steps = ceilf(s->options->max_delay_ms/2.5f); + s->bsize_analysis = CELT_BLOCK_960; + s->avg_is_band = CELT_MAX_BANDS - 1; + s->inflection_points_count = 0; + + s->inflection_points = av_mallocz(sizeof(*s->inflection_points)*s->max_steps); + if (!s->inflection_points) { + ret = AVERROR(ENOMEM); + goto fail; + } + + s->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); + if (!s->dsp) { + ret = AVERROR(ENOMEM); + goto fail; + } + + for (ch = 0; ch < s->avctx->channels; ch++) { + for (i = 0; i < CELT_MAX_BANDS; i++) { + bessel_init(&s->bfilter_hi[ch][i], 1.0f, 19.0f, 100.0f, 1); + bessel_init(&s->bfilter_lo[ch][i], 1.0f, 20.0f, 100.0f, 0); + } + } + + for (i = 0; i < s->max_steps; i++) { + s->steps[i] = av_mallocz(sizeof(OpusPsyStep)); + if (!s->steps[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + + for (i = 0; i < CELT_BLOCK_NB; i++) { + float tmp; + const int len = OPUS_BLOCK_SIZE(i); + s->window[i] = av_malloc(2*len*sizeof(float)); + if (!s->window[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + generate_window_func(s->window[i], 2*len, WFUNC_SINE, &tmp); + if ((ret = ff_mdct15_init(&s->mdct[i], 0, i + 3, 68 << (CELT_BLOCK_NB - 1 - i)))) + goto fail; + } + + return 0; + +fail: + av_freep(&s->inflection_points); + av_freep(&s->dsp); + + for (i = 0; i < CELT_BLOCK_NB; i++) { + ff_mdct15_uninit(&s->mdct[i]); + av_freep(&s->window[i]); + } + + for (i = 0; i < s->max_steps; i++) + av_freep(&s->steps[i]); + + return ret; +} + +void ff_opus_psy_signal_eof(OpusPsyContext *s) +{ + s->eof = 1; +} + +av_cold int ff_opus_psy_end(OpusPsyContext *s) +{ + int i; + + av_freep(&s->inflection_points); + av_freep(&s->dsp); + + for (i = 0; i < CELT_BLOCK_NB; i++) { + ff_mdct15_uninit(&s->mdct[i]); + av_freep(&s->window[i]); + } + + for (i = 0; i < s->max_steps; i++) + av_freep(&s->steps[i]); + + av_log(s->avctx, AV_LOG_INFO, "Average Intensity Stereo band: %0.1f\n", s->avg_is_band); + av_log(s->avctx, AV_LOG_INFO, "Dual Stereo used: %0.2f%%\n", ((float)s->dual_stereo_used/s->total_packets_out)*100.0f); + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_psy.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_psy.h new file mode 100644 index 000000000..b91e4f1b8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_psy.h @@ -0,0 +1,104 @@ +/* + * Opus encoder + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUSENC_PSY_H +#define AVCODEC_OPUSENC_PSY_H + +#include "opusenc.h" +#include "opusenc_utils.h" +#include "libavfilter/window_func.h" + +/* Each step is 2.5ms */ +typedef struct OpusPsyStep { + int index; /* Current index */ + int silence; + float energy[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; /* Masking effects included */ + float tone[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; /* Tonality */ + float stereo[CELT_MAX_BANDS]; /* IS/MS compatibility */ + float change_amp[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; /* Jump over last frame */ + float total_change; /* Total change */ + + float *bands[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; + float coeffs[OPUS_MAX_CHANNELS][OPUS_BLOCK_SIZE(CELT_BLOCK_960)]; +} OpusPsyStep; + +typedef struct OpusBandExcitation { + float excitation; + float excitation_dist; + float excitation_init; +} OpusBandExcitation; + +typedef struct PsyChain { + int start; + int end; +} PsyChain; + +typedef struct OpusPsyContext { + AVCodecContext *avctx; + AVFloatDSPContext *dsp; + struct FFBufQueue *bufqueue; + OpusEncOptions *options; + + PsyChain cs[128]; + int cs_num; + + OpusBandExcitation ex[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; + FFBesselFilter bfilter_lo[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; + FFBesselFilter bfilter_hi[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; + + OpusPsyStep *steps[FF_BUFQUEUE_SIZE + 1]; + int max_steps; + + float *window[CELT_BLOCK_NB]; + MDCT15Context *mdct[CELT_BLOCK_NB]; + int bsize_analysis; + + DECLARE_ALIGNED(32, float, scratch)[2048]; + + /* Stats */ + float rc_waste; + float avg_is_band; + int64_t dual_stereo_used; + int64_t total_packets_out; + + /* State */ + FFBesselFilter lambda_lp; + OpusPacketInfo p; + int redo_analysis; + int buffered_steps; + int steps_to_process; + int eof; + float lambda; + int *inflection_points; + int inflection_points_count; +} OpusPsyContext; + +int ff_opus_psy_process (OpusPsyContext *s, OpusPacketInfo *p); +void ff_opus_psy_celt_frame_init (OpusPsyContext *s, CeltFrame *f, int index); +int ff_opus_psy_celt_frame_process(OpusPsyContext *s, CeltFrame *f, int index); +void ff_opus_psy_postencode_update (OpusPsyContext *s, CeltFrame *f, OpusRangeCoder *rc); + +int ff_opus_psy_init(OpusPsyContext *s, AVCodecContext *avctx, + struct FFBufQueue *bufqueue, OpusEncOptions *options); +void ff_opus_psy_signal_eof(OpusPsyContext *s); +int ff_opus_psy_end(OpusPsyContext *s); + +#endif /* AVCODEC_OPUSENC_PSY_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_utils.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_utils.h new file mode 100644 index 000000000..be82e1376 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opusenc_utils.h @@ -0,0 +1,87 @@ +/* + * Opus encoder + * Copyright (c) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUSENC_UTILS_H +#define AVCODEC_OPUSENC_UTILS_H + +#include "opus.h" + +typedef struct FFBesselFilter { + float a[3]; + float b[2]; + float x[3]; + float y[3]; +} FFBesselFilter; + +/* Fills the coefficients, returns 1 if filter will be unstable */ +static inline int bessel_reinit(FFBesselFilter *s, float n, float f0, float fs, + int highpass) +{ + int unstable; + float c, cfreq, w0, k1, k2; + + if (!highpass) { + c = (1.0f/sqrtf(sqrtf(pow(2.0f, 1.0f/n) - 3.0f/4.0f) - 0.5f))/sqrtf(3.0f); + cfreq = c*f0/fs; + unstable = (cfreq <= 0.0f || cfreq >= 1.0f/4.0f); + } else { + c = sqrtf(3.0f)*sqrtf(sqrtf(pow(2.0f, 1.0f/n) - 3.0f/4.0f) - 0.5f); + cfreq = 0.5f - c*f0/fs; + unstable = (cfreq <= 3.0f/8.0f || cfreq >= 1.0f/2.0f); + } + + w0 = tanf(M_PI*cfreq); + k1 = 3.0f * w0; + k2 = 3.0f * w0; + + s->a[0] = k2/(1.0f + k1 + k2); + s->a[1] = 2.0f * s->a[0]; + s->a[2] = s->a[0]; + s->b[0] = 2.0f * s->a[0] * (1.0f/k2 - 1.0f); + s->b[1] = 1.0f - (s->a[0] + s->a[1] + s->a[2] + s->b[0]); + + if (highpass) { + s->a[1] *= -1; + s->b[0] *= -1; + } + + return unstable; +} + +static inline int bessel_init(FFBesselFilter *s, float n, float f0, float fs, + int highpass) +{ + memset(s, 0, sizeof(FFBesselFilter)); + return bessel_reinit(s, n, f0, fs, highpass); +} + +static inline float bessel_filter(FFBesselFilter *s, float x) +{ + s->x[2] = s->x[1]; + s->x[1] = s->x[0]; + s->x[0] = x; + s->y[2] = s->y[1]; + s->y[1] = s->y[0]; + s->y[0] = s->a[0]*s->x[0] + s->a[1]*s->x[1] + s->a[2]*s->x[2] + s->b[0]*s->y[1] + s->b[1]*s->y[2]; + return s->y[0]; +} + +#endif /* AVCODEC_OPUSENC_UTILS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opustab.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opustab.c new file mode 100644 index 000000000..fb340e07e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opustab.c @@ -0,0 +1,1158 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2016 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "opustab.h" + +const uint8_t ff_opus_default_coupled_streams[] = { 0, 1, 1, 2, 2, 2, 2, 3 }; + +const uint8_t ff_celt_band_end[] = { 13, 17, 17, 19, 21 }; + +const uint16_t ff_silk_model_stereo_s1[] = { + 256, 7, 9, 10, 11, 12, 22, 46, 54, 55, 56, 59, 82, 174, 197, 200, + 201, 202, 210, 234, 244, 245, 246, 247, 249, 256 +}; + +const uint16_t ff_silk_model_stereo_s2[] = {256, 85, 171, 256}; + +const uint16_t ff_silk_model_stereo_s3[] = {256, 51, 102, 154, 205, 256}; + +const uint16_t ff_silk_model_mid_only[] = {256, 192, 256}; + +const uint16_t ff_silk_model_frame_type_inactive[] = {256, 26, 256}; + +const uint16_t ff_silk_model_frame_type_active[] = {256, 24, 98, 246, 256}; + +const uint16_t ff_silk_model_gain_highbits[3][9] = { + {256, 32, 144, 212, 241, 253, 254, 255, 256}, + {256, 2, 19, 64, 124, 186, 233, 252, 256}, + {256, 1, 4, 30, 101, 195, 245, 254, 256} +}; + +const uint16_t ff_silk_model_gain_lowbits[] = {256, 32, 64, 96, 128, 160, 192, 224, 256}; + +const uint16_t ff_silk_model_gain_delta[] = { + 256, 6, 11, 22, 53, 185, 206, 214, 218, 221, 223, 225, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 +}; +const uint16_t ff_silk_model_lsf_s1[2][2][33] = { + { + { // NB or MB, unvoiced + 256, 44, 78, 108, 127, 148, 160, 171, 174, 177, 179, 195, 197, 199, 200, 205, + 207, 208, 211, 214, 215, 216, 218, 220, 222, 225, 226, 235, 244, 246, 253, 255, 256 + }, { // NB or MB, voiced + 256, 1, 11, 12, 20, 23, 31, 39, 53, 66, 80, 81, 95, 107, 120, 131, + 142, 154, 165, 175, 185, 196, 204, 213, 221, 228, 236, 237, 238, 244, 245, 251, 256 + } + }, { + { // WB, unvoiced + 256, 31, 52, 55, 72, 73, 81, 98, 102, 103, 121, 137, 141, 143, 146, 147, + 157, 158, 161, 177, 188, 204, 206, 208, 211, 213, 224, 225, 229, 238, 246, 253, 256 + }, { // WB, voiced + 256, 1, 5, 21, 26, 44, 55, 60, 74, 89, 90, 93, 105, 118, 132, 146, + 152, 166, 178, 180, 186, 187, 199, 211, 222, 232, 235, 245, 250, 251, 252, 253, 256 + } + } +}; + +const uint16_t ff_silk_model_lsf_s2[32][10] = { + // NB, MB + { 256, 1, 2, 3, 18, 242, 253, 254, 255, 256 }, + { 256, 1, 2, 4, 38, 221, 253, 254, 255, 256 }, + { 256, 1, 2, 6, 48, 197, 252, 254, 255, 256 }, + { 256, 1, 2, 10, 62, 185, 246, 254, 255, 256 }, + { 256, 1, 4, 20, 73, 174, 248, 254, 255, 256 }, + { 256, 1, 4, 21, 76, 166, 239, 254, 255, 256 }, + { 256, 1, 8, 32, 85, 159, 226, 252, 255, 256 }, + { 256, 1, 2, 20, 83, 161, 219, 249, 255, 256 }, + + // WB + { 256, 1, 2, 3, 12, 244, 253, 254, 255, 256 }, + { 256, 1, 2, 4, 32, 218, 253, 254, 255, 256 }, + { 256, 1, 2, 5, 47, 199, 252, 254, 255, 256 }, + { 256, 1, 2, 12, 61, 187, 252, 254, 255, 256 }, + { 256, 1, 5, 24, 72, 172, 249, 254, 255, 256 }, + { 256, 1, 2, 16, 70, 170, 242, 254, 255, 256 }, + { 256, 1, 2, 17, 78, 165, 226, 251, 255, 256 }, + { 256, 1, 8, 29, 79, 156, 237, 254, 255, 256 } +}; + +const uint16_t ff_silk_model_lsf_s2_ext[] = { 256, 156, 216, 240, 249, 253, 255, 256 }; + +const uint16_t ff_silk_model_lsf_interpolation_offset[] = { 256, 13, 35, 64, 75, 256 }; + +const uint16_t ff_silk_model_pitch_highbits[] = { + 256, 3, 6, 12, 23, 44, 74, 106, 125, 136, 146, 158, 171, 184, 196, 207, + 216, 224, 231, 237, 241, 243, 245, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 +}; + +const uint16_t ff_silk_model_pitch_lowbits_nb[] = { 256, 64, 128, 192, 256 }; + +const uint16_t ff_silk_model_pitch_lowbits_mb[] = { 256, 43, 85, 128, 171, 213, 256 }; + +const uint16_t ff_silk_model_pitch_lowbits_wb[] = { 256, 32, 64, 96, 128, 160, 192, 224, 256 }; + +const uint16_t ff_silk_model_pitch_delta[] = { + 256, 46, 48, 50, 53, 57, 63, 73, 88, 114, 152, 182, 204, 219, 229, 236, + 242, 246, 250, 252, 254, 256 +}; + +const uint16_t ff_silk_model_pitch_contour_nb10ms[] = { 256, 143, 193, 256 }; + +const uint16_t ff_silk_model_pitch_contour_nb20ms[] = { + 256, 68, 80, 101, 118, 137, 159, 189, 213, 230, 246, 256 +}; + +const uint16_t ff_silk_model_pitch_contour_mbwb10ms[] = { + 256, 91, 137, 176, 195, 209, 221, 229, 236, 242, 247, 252, 256 +}; + +const uint16_t ff_silk_model_pitch_contour_mbwb20ms[] = { + 256, 33, 55, 73, 89, 104, 118, 132, 145, 158, 168, 177, 186, 194, 200, 206, + 212, 217, 221, 225, 229, 232, 235, 238, 240, 242, 244, 246, 248, 250, 252, 253, + 254, 255, 256 +}; + +const uint16_t ff_silk_model_ltp_filter[] = { 256, 77, 157, 256 }; + +const uint16_t ff_silk_model_ltp_filter0_sel[] = { + 256, 185, 200, 213, 226, 235, 244, 250, 256 +}; + +const uint16_t ff_silk_model_ltp_filter1_sel[] = { + 256, 57, 91, 112, 132, 147, 160, 172, 185, 195, 205, 214, 224, 233, 241, 248, 256 +}; + +const uint16_t ff_silk_model_ltp_filter2_sel[] = { + 256, 15, 31, 45, 57, 69, 81, 92, 103, 114, 124, 133, 142, 151, 160, 168, + 176, 184, 192, 199, 206, 212, 218, 223, 227, 232, 236, 240, 244, 247, 251, 254, 256 +}; + +const uint16_t ff_silk_model_ltp_scale_index[] = { 256, 128, 192, 256 }; + +const uint16_t ff_silk_model_lcg_seed[] = { 256, 64, 128, 192, 256 }; + +const uint16_t ff_silk_model_exc_rate[2][10] = { + { 256, 15, 66, 78, 124, 169, 182, 215, 242, 256 }, // unvoiced + { 256, 33, 63, 99, 116, 150, 199, 217, 238, 256 } // voiced +}; + +const uint16_t ff_silk_model_pulse_count[11][19] = { + { 256, 131, 205, 230, 238, 241, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 }, + { 256, 58, 151, 211, 234, 241, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 }, + { 256, 43, 94, 140, 173, 197, 213, 224, 232, + 238, 241, 244, 247, 249, 250, 251, 253, 254, 256 }, + { 256, 17, 69, 140, 197, 228, 240, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 }, + { 256, 6, 27, 68, 121, 170, 205, 226, 237, + 243, 246, 248, 250, 251, 252, 253, 254, 255, 256 }, + { 256, 7, 21, 43, 71, 100, 128, 153, 173, + 190, 203, 214, 223, 230, 235, 239, 243, 246, 256 }, + { 256, 2, 7, 21, 50, 92, 138, 179, 210, + 229, 240, 246, 249, 251, 252, 253, 254, 255, 256 }, + { 256, 1, 3, 7, 17, 36, 65, 100, 137, + 171, 199, 219, 233, 241, 246, 250, 252, 254, 256 }, + { 256, 1, 3, 5, 10, 19, 33, 53, 77, + 104, 132, 158, 181, 201, 216, 227, 235, 241, 256 }, + { 256, 1, 2, 3, 9, 36, 94, 150, 189, + 214, 228, 238, 244, 247, 250, 252, 253, 254, 256 }, + { 256, 2, 3, 9, 36, 94, 150, 189, 214, + 228, 238, 244, 247, 250, 252, 253, 254, 256, 256 } +}; + +const uint16_t ff_silk_model_pulse_location[4][168] = { + { + 256, 126, 256, + 256, 56, 198, 256, + 256, 25, 126, 230, 256, + 256, 12, 72, 180, 244, 256, + 256, 7, 42, 126, 213, 250, 256, + 256, 4, 24, 83, 169, 232, 253, 256, + 256, 3, 15, 53, 125, 200, 242, 254, 256, + 256, 2, 10, 35, 89, 162, 221, 248, 255, 256, + 256, 2, 7, 24, 63, 126, 191, 233, 251, 255, 256, + 256, 1, 5, 17, 45, 94, 157, 211, 241, 252, 255, 256, + 256, 1, 5, 13, 33, 70, 125, 182, 223, 245, 253, 255, 256, + 256, 1, 4, 11, 26, 54, 98, 151, 199, 232, 248, 254, 255, 256, + 256, 1, 3, 9, 21, 42, 77, 124, 172, 212, 237, 249, 254, 255, 256, + 256, 1, 2, 6, 16, 33, 60, 97, 144, 187, 220, 241, 250, 254, 255, 256, + 256, 1, 2, 3, 11, 25, 47, 80, 120, 163, 201, 229, 245, 253, 254, 255, 256, + 256, 1, 2, 3, 4, 17, 35, 62, 98, 139, 180, 214, 238, 252, 253, 254, 255, 256 + },{ + 256, 127, 256, + 256, 53, 202, 256, + 256, 22, 127, 233, 256, + 256, 11, 72, 183, 246, 256, + 256, 6, 41, 127, 215, 251, 256, + 256, 4, 24, 83, 170, 232, 253, 256, + 256, 3, 16, 56, 127, 200, 241, 254, 256, + 256, 3, 12, 39, 92, 162, 218, 246, 255, 256, + 256, 3, 11, 30, 67, 124, 185, 229, 249, 255, 256, + 256, 3, 10, 25, 53, 97, 151, 200, 233, 250, 255, 256, + 256, 1, 8, 21, 43, 77, 123, 171, 209, 237, 251, 255, 256, + 256, 1, 2, 13, 35, 62, 97, 139, 186, 219, 244, 254, 255, 256, + 256, 1, 2, 8, 22, 48, 85, 128, 171, 208, 234, 248, 254, 255, 256, + 256, 1, 2, 6, 16, 36, 67, 107, 149, 189, 220, 240, 250, 254, 255, 256, + 256, 1, 2, 5, 13, 29, 55, 90, 128, 166, 201, 227, 243, 251, 254, 255, 256, + 256, 1, 2, 4, 10, 22, 43, 73, 109, 147, 183, 213, 234, 246, 252, 254, 255, 256 + },{ + 256, 127, 256, + 256, 49, 206, 256, + 256, 20, 127, 236, 256, + 256, 11, 71, 184, 246, 256, + 256, 7, 43, 127, 214, 250, 256, + 256, 6, 30, 87, 169, 229, 252, 256, + 256, 5, 23, 62, 126, 194, 236, 252, 256, + 256, 6, 20, 49, 96, 157, 209, 239, 253, 256, + 256, 1, 16, 39, 74, 125, 175, 215, 245, 255, 256, + 256, 1, 2, 23, 55, 97, 149, 195, 236, 254, 255, 256, + 256, 1, 7, 23, 50, 86, 128, 170, 206, 233, 249, 255, 256, + 256, 1, 6, 18, 39, 70, 108, 148, 186, 217, 238, 250, 255, 256, + 256, 1, 4, 13, 30, 56, 90, 128, 166, 200, 226, 243, 252, 255, 256, + 256, 1, 4, 11, 25, 47, 76, 110, 146, 180, 209, 231, 245, 252, 255, 256, + 256, 1, 3, 8, 19, 37, 62, 93, 128, 163, 194, 219, 237, 248, 253, 255, 256, + 256, 1, 2, 6, 15, 30, 51, 79, 111, 145, 177, 205, 226, 241, 250, 254, 255, 256 + },{ + 256, 128, 256, + 256, 42, 214, 256, + 256, 21, 128, 235, 256, + 256, 12, 72, 184, 245, 256, + 256, 8, 42, 128, 214, 249, 256, + 256, 8, 31, 86, 176, 231, 251, 256, + 256, 5, 20, 58, 130, 202, 238, 253, 256, + 256, 6, 18, 45, 97, 174, 221, 241, 251, 256, + 256, 6, 25, 53, 88, 128, 168, 203, 231, 250, 256, + 256, 4, 18, 40, 71, 108, 148, 185, 216, 238, 252, 256, + 256, 3, 13, 31, 57, 90, 128, 166, 199, 225, 243, 253, 256, + 256, 2, 10, 23, 44, 73, 109, 147, 183, 212, 233, 246, 254, 256, + 256, 1, 6, 16, 33, 58, 90, 128, 166, 198, 223, 240, 250, 255, 256, + 256, 1, 5, 12, 25, 46, 75, 110, 146, 181, 210, 231, 244, 251, 255, 256, + 256, 1, 3, 8, 18, 35, 60, 92, 128, 164, 196, 221, 238, 248, 253, 255, 256, + 256, 1, 3, 7, 14, 27, 48, 76, 110, 146, 180, 208, 229, 242, 249, 253, 255, 256 + } +}; + +const uint16_t ff_silk_model_excitation_lsb[] = {256, 136, 256}; + +const uint16_t ff_silk_model_excitation_sign[3][2][7][3] = { + { // Inactive + { // Low offset + {256, 2, 256}, + {256, 207, 256}, + {256, 189, 256}, + {256, 179, 256}, + {256, 174, 256}, + {256, 163, 256}, + {256, 157, 256} + }, { // High offset + {256, 58, 256}, + {256, 245, 256}, + {256, 238, 256}, + {256, 232, 256}, + {256, 225, 256}, + {256, 220, 256}, + {256, 211, 256} + } + }, { // Unvoiced + { // Low offset + {256, 1, 256}, + {256, 210, 256}, + {256, 190, 256}, + {256, 178, 256}, + {256, 169, 256}, + {256, 162, 256}, + {256, 152, 256} + }, { // High offset + {256, 48, 256}, + {256, 242, 256}, + {256, 235, 256}, + {256, 224, 256}, + {256, 214, 256}, + {256, 205, 256}, + {256, 190, 256} + } + }, { // Voiced + { // Low offset + {256, 1, 256}, + {256, 162, 256}, + {256, 152, 256}, + {256, 147, 256}, + {256, 144, 256}, + {256, 141, 256}, + {256, 138, 256} + }, { // High offset + {256, 8, 256}, + {256, 203, 256}, + {256, 187, 256}, + {256, 176, 256}, + {256, 168, 256}, + {256, 161, 256}, + {256, 154, 256} + } + } +}; + +const int16_t ff_silk_stereo_weights[] = { + -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, + 820, 2950, 5000, 6500, 7526, 8266, 10050, 13732 +}; + +const uint8_t ff_silk_lsf_s2_model_sel_nbmb[32][10] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 3, 1, 2, 2, 1, 2, 1, 1, 1 }, + { 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 1, 2, 2, 2, 2, 1, 2, 1, 1, 1 }, + { 2, 3, 3, 3, 3, 2, 2, 2, 2, 2 }, + { 0, 5, 3, 3, 2, 2, 2, 2, 1, 1 }, + { 0, 2, 2, 2, 2, 2, 2, 2, 2, 1 }, + { 2, 3, 6, 4, 4, 4, 5, 4, 5, 5 }, + { 2, 4, 5, 5, 4, 5, 4, 6, 4, 4 }, + { 2, 4, 4, 7, 4, 5, 4, 5, 5, 4 }, + { 4, 3, 3, 3, 2, 3, 2, 2, 2, 2 }, + { 1, 5, 5, 6, 4, 5, 4, 5, 5, 5 }, + { 2, 7, 4, 6, 5, 5, 5, 5, 5, 5 }, + { 2, 7, 5, 5, 5, 5, 5, 6, 5, 4 }, + { 3, 3, 5, 4, 4, 5, 4, 5, 4, 4 }, + { 2, 3, 3, 5, 5, 4, 4, 4, 4, 4 }, + { 2, 4, 4, 6, 4, 5, 4, 5, 5, 5 }, + { 2, 5, 4, 6, 5, 5, 5, 4, 5, 4 }, + { 2, 7, 4, 5, 4, 5, 4, 5, 5, 5 }, + { 2, 5, 4, 6, 7, 6, 5, 6, 5, 4 }, + { 3, 6, 7, 4, 6, 5, 5, 6, 4, 5 }, + { 2, 7, 6, 4, 4, 4, 5, 4, 5, 5 }, + { 4, 5, 5, 4, 6, 6, 5, 6, 5, 4 }, + { 2, 5, 5, 6, 5, 6, 4, 6, 4, 4 }, + { 4, 5, 5, 5, 3, 7, 4, 5, 5, 4 }, + { 2, 3, 4, 5, 5, 6, 4, 5, 5, 4 }, + { 2, 3, 2, 3, 3, 4, 2, 3, 3, 3 }, + { 1, 1, 2, 2, 2, 2, 2, 3, 2, 2 }, + { 4, 5, 5, 6, 6, 6, 5, 6, 4, 5 }, + { 3, 5, 5, 4, 4, 4, 4, 3, 3, 2 }, + { 2, 5, 3, 7, 5, 5, 4, 4, 5, 4 }, + { 4, 4, 5, 4, 5, 6, 5, 6, 5, 4 } +}; + +const uint8_t ff_silk_lsf_s2_model_sel_wb[32][16] = { + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, + { 10, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 8, 11 }, + { 10, 13, 13, 11, 15, 12, 12, 13, 10, 13, 12, 13, 13, 12, 11, 11 }, + { 8, 10, 9, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9 }, + { 8, 14, 13, 12, 14, 12, 15, 13, 12, 12, 12, 13, 13, 12, 12, 11 }, + { 8, 11, 13, 13, 12, 11, 11, 13, 11, 11, 11, 11, 11, 11, 10, 12 }, + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, + { 8, 10, 14, 11, 15, 10, 13, 11, 12, 13, 13, 12, 11, 11, 10, 11 }, + { 8, 14, 10, 14, 14, 12, 13, 12, 14, 13, 12, 12, 13, 11, 11, 11 }, + { 10, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, + { 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9 }, + { 10, 10, 11, 12, 13, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 11 }, + { 10, 10, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 10, 9, 11 }, + { 11, 12, 12, 12, 14, 12, 12, 13, 11, 13, 12, 12, 13, 12, 11, 12 }, + { 8, 14, 12, 13, 12, 15, 13, 10, 14, 13, 15, 12, 12, 11, 13, 11 }, + { 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 8 }, + { 9, 14, 13, 15, 13, 12, 13, 11, 12, 13, 12, 12, 12, 11, 11, 12 }, + { 9, 11, 11, 12, 12, 11, 11, 13, 10, 11, 11, 13, 13, 13, 11, 12 }, + { 10, 11, 11, 10, 10, 10, 11, 10, 9, 10, 9, 10, 9, 9, 9, 12 }, + { 8, 10, 11, 13, 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 8 }, + { 11, 12, 11, 13, 11, 11, 10, 10, 9, 9, 9, 9, 9, 10, 10, 12 }, + { 10, 14, 11, 15, 15, 12, 13, 12, 13, 11, 13, 11, 11, 10, 11, 11 }, + { 10, 11, 13, 14, 14, 11, 13, 11, 12, 12, 11, 11, 11, 11, 10, 12 }, + { 9, 11, 11, 12, 12, 12, 12, 11, 13, 13, 13, 11, 9, 9, 9, 9 }, + { 10, 13, 11, 14, 14, 12, 15, 12, 12, 13, 11, 12, 12, 11, 11, 11 }, + { 8, 14, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, + { 8, 14, 14, 11, 13, 10, 13, 13, 11, 12, 12, 15, 15, 12, 12, 12 }, + { 11, 11, 15, 11, 13, 12, 11, 11, 11, 10, 10, 11, 11, 11, 10, 11 }, + { 8, 8, 9, 8, 8, 8, 10, 9, 10, 9, 9, 10, 10, 10, 9, 9 }, + { 8, 11, 10, 13, 11, 11, 10, 11, 10, 9, 8, 8, 9, 8, 8, 9 }, + { 11, 13, 13, 12, 15, 13, 11, 11, 10, 11, 10, 10, 9, 8, 9, 8 }, + { 10, 11, 13, 11, 12, 11, 11, 11, 10, 9, 10, 14, 12, 8, 8, 8 } +}; + +const uint8_t ff_silk_lsf_pred_weights_nbmb[2][9] = { + {179, 138, 140, 148, 151, 149, 153, 151, 163}, + {116, 67, 82, 59, 92, 72, 100, 89, 92} +}; + +const uint8_t ff_silk_lsf_pred_weights_wb[2][15] = { + {175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198, 192, 182}, + { 68, 62, 66, 60, 72, 117, 85, 90, 118, 136, 151, 142, 160, 142, 155} +}; + +const uint8_t ff_silk_lsf_weight_sel_nbmb[32][9] = { + { 0, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 0, 0, 0, 1, 0 }, + { 0, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 1, 1, 0, 0, 0, 1, 0 }, + { 0, 1, 1, 0, 0, 1, 1, 0, 0 }, + { 0, 0, 1, 1, 0, 1, 0, 1, 1 }, + { 0, 0, 1, 1, 0, 0, 1, 1, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 0, 1, 1, 1, 1, 1, 0 }, + { 0, 1, 0, 1, 1, 1, 1, 1, 0 }, + { 0, 1, 1, 1, 1, 1, 1, 1, 0 }, + { 1, 0, 1, 1, 0, 1, 1, 1, 1 }, + { 0, 1, 1, 1, 1, 1, 0, 1, 0 }, + { 0, 0, 1, 1, 0, 1, 0, 1, 0 }, + { 0, 0, 1, 1, 1, 0, 1, 1, 1 }, + { 0, 1, 1, 0, 0, 1, 1, 1, 0 }, + { 0, 0, 0, 1, 1, 1, 0, 1, 0 }, + { 0, 1, 1, 0, 0, 1, 0, 1, 0 }, + { 0, 1, 1, 0, 0, 0, 1, 1, 0 }, + { 0, 0, 0, 0, 0, 1, 1, 1, 1 }, + { 0, 0, 1, 1, 0, 0, 0, 1, 1 }, + { 0, 0, 0, 1, 0, 1, 1, 1, 1 }, + { 0, 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, 1, 0, 1, 1, 0, 1, 0 }, + { 1, 0, 0, 1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 1, 1, 0, 1, 0, 1 }, + { 1, 0, 1, 1, 0, 1, 1, 1, 1 } +}; + +const uint8_t ff_silk_lsf_weight_sel_wb[32][15] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, + { 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0 }, + { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, + { 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 }, + { 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 }, + { 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 }, + { 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0 }, + { 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 }, + { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, + { 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0 }, + { 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0 }, + { 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0 }, + { 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0 }, + { 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + { 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0 } +}; + +const uint8_t ff_silk_lsf_codebook_nbmb[32][10] = { + { 12, 35, 60, 83, 108, 132, 157, 180, 206, 228 }, + { 15, 32, 55, 77, 101, 125, 151, 175, 201, 225 }, + { 19, 42, 66, 89, 114, 137, 162, 184, 209, 230 }, + { 12, 25, 50, 72, 97, 120, 147, 172, 200, 223 }, + { 26, 44, 69, 90, 114, 135, 159, 180, 205, 225 }, + { 13, 22, 53, 80, 106, 130, 156, 180, 205, 228 }, + { 15, 25, 44, 64, 90, 115, 142, 168, 196, 222 }, + { 19, 24, 62, 82, 100, 120, 145, 168, 190, 214 }, + { 22, 31, 50, 79, 103, 120, 151, 170, 203, 227 }, + { 21, 29, 45, 65, 106, 124, 150, 171, 196, 224 }, + { 30, 49, 75, 97, 121, 142, 165, 186, 209, 229 }, + { 19, 25, 52, 70, 93, 116, 143, 166, 192, 219 }, + { 26, 34, 62, 75, 97, 118, 145, 167, 194, 217 }, + { 25, 33, 56, 70, 91, 113, 143, 165, 196, 223 }, + { 21, 34, 51, 72, 97, 117, 145, 171, 196, 222 }, + { 20, 29, 50, 67, 90, 117, 144, 168, 197, 221 }, + { 22, 31, 48, 66, 95, 117, 146, 168, 196, 222 }, + { 24, 33, 51, 77, 116, 134, 158, 180, 200, 224 }, + { 21, 28, 70, 87, 106, 124, 149, 170, 194, 217 }, + { 26, 33, 53, 64, 83, 117, 152, 173, 204, 225 }, + { 27, 34, 65, 95, 108, 129, 155, 174, 210, 225 }, + { 20, 26, 72, 99, 113, 131, 154, 176, 200, 219 }, + { 34, 43, 61, 78, 93, 114, 155, 177, 205, 229 }, + { 23, 29, 54, 97, 124, 138, 163, 179, 209, 229 }, + { 30, 38, 56, 89, 118, 129, 158, 178, 200, 231 }, + { 21, 29, 49, 63, 85, 111, 142, 163, 193, 222 }, + { 27, 48, 77, 103, 133, 158, 179, 196, 215, 232 }, + { 29, 47, 74, 99, 124, 151, 176, 198, 220, 237 }, + { 33, 42, 61, 76, 93, 121, 155, 174, 207, 225 }, + { 29, 53, 87, 112, 136, 154, 170, 188, 208, 227 }, + { 24, 30, 52, 84, 131, 150, 166, 186, 203, 229 }, + { 37, 48, 64, 84, 104, 118, 156, 177, 201, 230 } +}; + +const uint8_t ff_silk_lsf_codebook_wb[32][16] = { + { 7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239 }, + { 13, 25, 41, 55, 69, 83, 98, 112, 127, 142, 157, 171, 187, 203, 220, 236 }, + { 15, 21, 34, 51, 61, 78, 92, 106, 126, 136, 152, 167, 185, 205, 225, 240 }, + { 10, 21, 36, 50, 63, 79, 95, 110, 126, 141, 157, 173, 189, 205, 221, 237 }, + { 17, 20, 37, 51, 59, 78, 89, 107, 123, 134, 150, 164, 184, 205, 224, 240 }, + { 10, 15, 32, 51, 67, 81, 96, 112, 129, 142, 158, 173, 189, 204, 220, 236 }, + { 8, 21, 37, 51, 65, 79, 98, 113, 126, 138, 155, 168, 179, 192, 209, 218 }, + { 12, 15, 34, 55, 63, 78, 87, 108, 118, 131, 148, 167, 185, 203, 219, 236 }, + { 16, 19, 32, 36, 56, 79, 91, 108, 118, 136, 154, 171, 186, 204, 220, 237 }, + { 11, 28, 43, 58, 74, 89, 105, 120, 135, 150, 165, 180, 196, 211, 226, 241 }, + { 6, 16, 33, 46, 60, 75, 92, 107, 123, 137, 156, 169, 185, 199, 214, 225 }, + { 11, 19, 30, 44, 57, 74, 89, 105, 121, 135, 152, 169, 186, 202, 218, 234 }, + { 12, 19, 29, 46, 57, 71, 88, 100, 120, 132, 148, 165, 182, 199, 216, 233 }, + { 17, 23, 35, 46, 56, 77, 92, 106, 123, 134, 152, 167, 185, 204, 222, 237 }, + { 14, 17, 45, 53, 63, 75, 89, 107, 115, 132, 151, 171, 188, 206, 221, 240 }, + { 9, 16, 29, 40, 56, 71, 88, 103, 119, 137, 154, 171, 189, 205, 222, 237 }, + { 16, 19, 36, 48, 57, 76, 87, 105, 118, 132, 150, 167, 185, 202, 218, 236 }, + { 12, 17, 29, 54, 71, 81, 94, 104, 126, 136, 149, 164, 182, 201, 221, 237 }, + { 15, 28, 47, 62, 79, 97, 115, 129, 142, 155, 168, 180, 194, 208, 223, 238 }, + { 8, 14, 30, 45, 62, 78, 94, 111, 127, 143, 159, 175, 192, 207, 223, 239 }, + { 17, 30, 49, 62, 79, 92, 107, 119, 132, 145, 160, 174, 190, 204, 220, 235 }, + { 14, 19, 36, 45, 61, 76, 91, 108, 121, 138, 154, 172, 189, 205, 222, 238 }, + { 12, 18, 31, 45, 60, 76, 91, 107, 123, 138, 154, 171, 187, 204, 221, 236 }, + { 13, 17, 31, 43, 53, 70, 83, 103, 114, 131, 149, 167, 185, 203, 220, 237 }, + { 17, 22, 35, 42, 58, 78, 93, 110, 125, 139, 155, 170, 188, 206, 224, 240 }, + { 8, 15, 34, 50, 67, 83, 99, 115, 131, 146, 162, 178, 193, 209, 224, 239 }, + { 13, 16, 41, 66, 73, 86, 95, 111, 128, 137, 150, 163, 183, 206, 225, 241 }, + { 17, 25, 37, 52, 63, 75, 92, 102, 119, 132, 144, 160, 175, 191, 212, 231 }, + { 19, 31, 49, 65, 83, 100, 117, 133, 147, 161, 174, 187, 200, 213, 227, 242 }, + { 18, 31, 52, 68, 88, 103, 117, 126, 138, 149, 163, 177, 192, 207, 223, 239 }, + { 16, 29, 47, 61, 76, 90, 106, 119, 133, 147, 161, 176, 193, 209, 224, 240 }, + { 15, 21, 35, 50, 61, 73, 86, 97, 110, 119, 129, 141, 175, 198, 218, 237 } +}; + +const uint16_t ff_silk_lsf_min_spacing_nbmb[] = { + 250, 3, 6, 3, 3, 3, 4, 3, 3, 3, 461 +}; + +const uint16_t ff_silk_lsf_min_spacing_wb[] = { + 100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347 +}; + +const uint8_t ff_silk_lsf_ordering_nbmb[] = { + 0, 9, 6, 3, 4, 5, 8, 1, 2, 7 +}; + +const uint8_t ff_silk_lsf_ordering_wb[] = { + 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1 +}; + +const int16_t ff_silk_cosine[] = { /* (0.12) */ + 4096, 4095, 4091, 4085, + 4076, 4065, 4052, 4036, + 4017, 3997, 3973, 3948, + 3920, 3889, 3857, 3822, + 3784, 3745, 3703, 3659, + 3613, 3564, 3513, 3461, + 3406, 3349, 3290, 3229, + 3166, 3102, 3035, 2967, + 2896, 2824, 2751, 2676, + 2599, 2520, 2440, 2359, + 2276, 2191, 2106, 2019, + 1931, 1842, 1751, 1660, + 1568, 1474, 1380, 1285, + 1189, 1093, 995, 897, + 799, 700, 601, 501, + 401, 301, 201, 101, + 0, -101, -201, -301, + -401, -501, -601, -700, + -799, -897, -995, -1093, + -1189, -1285, -1380, -1474, + -1568, -1660, -1751, -1842, + -1931, -2019, -2106, -2191, + -2276, -2359, -2440, -2520, + -2599, -2676, -2751, -2824, + -2896, -2967, -3035, -3102, + -3166, -3229, -3290, -3349, + -3406, -3461, -3513, -3564, + -3613, -3659, -3703, -3745, + -3784, -3822, -3857, -3889, + -3920, -3948, -3973, -3997, + -4017, -4036, -4052, -4065, + -4076, -4085, -4091, -4095, + -4096 +}; + +const uint16_t ff_silk_pitch_scale[] = { 4, 6, 8}; + +const uint16_t ff_silk_pitch_min_lag[] = { 16, 24, 32}; + +const uint16_t ff_silk_pitch_max_lag[] = {144, 216, 288}; + +const int8_t ff_silk_pitch_offset_nb10ms[3][2] = { + { 0, 0}, + { 1, 0}, + { 0, 1} +}; + +const int8_t ff_silk_pitch_offset_nb20ms[11][4] = { + { 0, 0, 0, 0}, + { 2, 1, 0, -1}, + {-1, 0, 1, 2}, + {-1, 0, 0, 1}, + {-1, 0, 0, 0}, + { 0, 0, 0, 1}, + { 0, 0, 1, 1}, + { 1, 1, 0, 0}, + { 1, 0, 0, 0}, + { 0, 0, 0, -1}, + { 1, 0, 0, -1} +}; + +const int8_t ff_silk_pitch_offset_mbwb10ms[12][2] = { + { 0, 0}, + { 0, 1}, + { 1, 0}, + {-1, 1}, + { 1, -1}, + {-1, 2}, + { 2, -1}, + {-2, 2}, + { 2, -2}, + {-2, 3}, + { 3, -2}, + {-3, 3} +}; + +const int8_t ff_silk_pitch_offset_mbwb20ms[34][4] = { + { 0, 0, 0, 0}, + { 0, 0, 1, 1}, + { 1, 1, 0, 0}, + {-1, 0, 0, 0}, + { 0, 0, 0, 1}, + { 1, 0, 0, 0}, + {-1, 0, 0, 1}, + { 0, 0, 0, -1}, + {-1, 0, 1, 2}, + { 1, 0, 0, -1}, + {-2, -1, 1, 2}, + { 2, 1, 0, -1}, + {-2, 0, 0, 2}, + {-2, 0, 1, 3}, + { 2, 1, -1, -2}, + {-3, -1, 1, 3}, + { 2, 0, 0, -2}, + { 3, 1, 0, -2}, + {-3, -1, 2, 4}, + {-4, -1, 1, 4}, + { 3, 1, -1, -3}, + {-4, -1, 2, 5}, + { 4, 2, -1, -3}, + { 4, 1, -1, -4}, + {-5, -1, 2, 6}, + { 5, 2, -1, -4}, + {-6, -2, 2, 6}, + {-5, -2, 2, 5}, + { 6, 2, -1, -5}, + {-7, -2, 3, 8}, + { 6, 2, -2, -6}, + { 5, 2, -2, -5}, + { 8, 3, -2, -7}, + {-9, -3, 3, 9} +}; + +const int8_t ff_silk_ltp_filter0_taps[8][5] = { + { 4, 6, 24, 7, 5}, + { 0, 0, 2, 0, 0}, + { 12, 28, 41, 13, -4}, + { -9, 15, 42, 25, 14}, + { 1, -2, 62, 41, -9}, + {-10, 37, 65, -4, 3}, + { -6, 4, 66, 7, -8}, + { 16, 14, 38, -3, 33} +}; + +const int8_t ff_silk_ltp_filter1_taps[16][5] = { + { 13, 22, 39, 23, 12}, + { -1, 36, 64, 27, -6}, + { -7, 10, 55, 43, 17}, + { 1, 1, 8, 1, 1}, + { 6, -11, 74, 53, -9}, + {-12, 55, 76, -12, 8}, + { -3, 3, 93, 27, -4}, + { 26, 39, 59, 3, -8}, + { 2, 0, 77, 11, 9}, + { -8, 22, 44, -6, 7}, + { 40, 9, 26, 3, 9}, + { -7, 20, 101, -7, 4}, + { 3, -8, 42, 26, 0}, + {-15, 33, 68, 2, 23}, + { -2, 55, 46, -2, 15}, + { 3, -1, 21, 16, 41} +}; + +const int8_t ff_silk_ltp_filter2_taps[32][5] = { + { -6, 27, 61, 39, 5}, + {-11, 42, 88, 4, 1}, + { -2, 60, 65, 6, -4}, + { -1, -5, 73, 56, 1}, + { -9, 19, 94, 29, -9}, + { 0, 12, 99, 6, 4}, + { 8, -19, 102, 46, -13}, + { 3, 2, 13, 3, 2}, + { 9, -21, 84, 72, -18}, + {-11, 46, 104, -22, 8}, + { 18, 38, 48, 23, 0}, + {-16, 70, 83, -21, 11}, + { 5, -11, 117, 22, -8}, + { -6, 23, 117, -12, 3}, + { 3, -8, 95, 28, 4}, + {-10, 15, 77, 60, -15}, + { -1, 4, 124, 2, -4}, + { 3, 38, 84, 24, -25}, + { 2, 13, 42, 13, 31}, + { 21, -4, 56, 46, -1}, + { -1, 35, 79, -13, 19}, + { -7, 65, 88, -9, -14}, + { 20, 4, 81, 49, -29}, + { 20, 0, 75, 3, -17}, + { 5, -9, 44, 92, -8}, + { 1, -3, 22, 69, 31}, + { -6, 95, 41, -12, 5}, + { 39, 67, 16, -4, 1}, + { 0, -6, 120, 55, -36}, + {-13, 44, 122, 4, -24}, + { 81, 5, 11, 3, 7}, + { 2, 0, 9, 10, 88} +}; + +const uint16_t ff_silk_ltp_scale_factor[] = {15565, 12288, 8192}; + +const uint8_t ff_silk_shell_blocks[3][2] = { + { 5, 10}, // NB + { 8, 15}, // MB + {10, 20} // WB +}; + +const uint8_t ff_silk_quant_offset[2][2] = { /* (0.23) */ + {25, 60}, // Inactive or Unvoiced + { 8, 25} // Voiced +}; + +const int ff_silk_stereo_interp_len[3] = { + 64, 96, 128 +}; + +const uint16_t ff_celt_model_tapset[] = { 4, 2, 3, 4 }; + +const uint16_t ff_celt_model_spread[] = { 32, 7, 9, 30, 32 }; + +const uint16_t ff_celt_model_alloc_trim[] = { + 128, 2, 4, 9, 19, 41, 87, 109, 119, 124, 126, 128 +}; + +const uint16_t ff_celt_model_energy_small[] = { 4, 2, 3, 4 }; + +const uint8_t ff_celt_freq_bands[] = { /* in steps of 200Hz */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100 +}; + +const uint8_t ff_celt_freq_range[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 6, 6, 8, 12, 18, 22 +}; + +const uint8_t ff_celt_log_freq_range[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36 +}; + +/* Positive - increased freqeuency resolution (only possible on transients) + * Negative - increased time resolution */ +const int8_t ff_celt_tf_select[4][2][2][2] = { + /* OFF ON Transient frame */ + /* OFF ON OFF ON TF select flag */ + /* OFF ON OFF ON OFF ON OFF ON TF change flag */ + { { { 0, -1 }, { 0, -1 } }, { { 0, -1 }, { 0, -1 } } }, /* 120 */ + { { { 0, -1 }, { 0, -2 } }, { { 1, 0 }, { 1, -1 } } }, /* 240 */ + { { { 0, -2 }, { 0, -3 } }, { { 2, 0 }, { 1, -1 } } }, /* 480 */ + { { { 0, -2 }, { 0, -3 } }, { { 3, 0 }, { 1, -1 } } } /* 960 */ +}; + +const float ff_celt_mean_energy[] = { + 6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f, + 4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f, + 4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f, + 4.500000f, 4.375000f, 4.625000f, 4.750000f, 4.437500f, + 3.750000f, 3.750000f, 3.750000f, 3.750000f, 3.750000f +}; + +const float ff_celt_alpha_coef[] = { + 29440.0f/32768.0f, 26112.0f/32768.0f, 21248.0f/32768.0f, 16384.0f/32768.0f +}; + +const float ff_celt_beta_coef[] = { + 1.0f - (30147.0f/32768.0f), 1.0f - (22282.0f/32768.0f), 1.0f - (12124.0f/32768.0f), 1.0f - (6554.0f/32768.0f), +}; + +const uint8_t ff_celt_coarse_energy_dist[4][2][42] = { + { + { // 120-sample inter + 72, 127, 65, 129, 66, 128, 65, 128, 64, 128, 62, 128, 64, 128, + 64, 128, 92, 78, 92, 79, 92, 78, 90, 79, 116, 41, 115, 40, + 114, 40, 132, 26, 132, 26, 145, 17, 161, 12, 176, 10, 177, 11 + }, { // 120-sample intra + 24, 179, 48, 138, 54, 135, 54, 132, 53, 134, 56, 133, 55, 132, + 55, 132, 61, 114, 70, 96, 74, 88, 75, 88, 87, 74, 89, 66, + 91, 67, 100, 59, 108, 50, 120, 40, 122, 37, 97, 43, 78, 50 + } + }, { + { // 240-sample inter + 83, 78, 84, 81, 88, 75, 86, 74, 87, 71, 90, 73, 93, 74, + 93, 74, 109, 40, 114, 36, 117, 34, 117, 34, 143, 17, 145, 18, + 146, 19, 162, 12, 165, 10, 178, 7, 189, 6, 190, 8, 177, 9 + }, { // 240-sample intra + 23, 178, 54, 115, 63, 102, 66, 98, 69, 99, 74, 89, 71, 91, + 73, 91, 78, 89, 86, 80, 92, 66, 93, 64, 102, 59, 103, 60, + 104, 60, 117, 52, 123, 44, 138, 35, 133, 31, 97, 38, 77, 45 + } + }, { + { // 480-sample inter + 61, 90, 93, 60, 105, 42, 107, 41, 110, 45, 116, 38, 113, 38, + 112, 38, 124, 26, 132, 27, 136, 19, 140, 20, 155, 14, 159, 16, + 158, 18, 170, 13, 177, 10, 187, 8, 192, 6, 175, 9, 159, 10 + }, { // 480-sample intra + 21, 178, 59, 110, 71, 86, 75, 85, 84, 83, 91, 66, 88, 73, + 87, 72, 92, 75, 98, 72, 105, 58, 107, 54, 115, 52, 114, 55, + 112, 56, 129, 51, 132, 40, 150, 33, 140, 29, 98, 35, 77, 42 + } + }, { + { // 960-sample inter + 42, 121, 96, 66, 108, 43, 111, 40, 117, 44, 123, 32, 120, 36, + 119, 33, 127, 33, 134, 34, 139, 21, 147, 23, 152, 20, 158, 25, + 154, 26, 166, 21, 173, 16, 184, 13, 184, 10, 150, 13, 139, 15 + }, { // 960-sample intra + 22, 178, 63, 114, 74, 82, 84, 83, 92, 82, 103, 62, 96, 72, + 96, 67, 101, 73, 107, 72, 113, 55, 118, 52, 125, 52, 118, 52, + 117, 55, 135, 49, 137, 39, 157, 32, 145, 29, 97, 33, 77, 40 + } + } +}; + +const uint8_t ff_celt_static_alloc[11][21] = { /* 1/32 bit/sample */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 110, 100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0 }, + { 118, 110, 103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0 }, + { 126, 119, 112, 104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0 }, + { 134, 127, 120, 114, 103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1 }, + { 144, 137, 130, 124, 113, 107, 101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1 }, + { 152, 145, 138, 132, 123, 117, 111, 105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1 }, + { 162, 155, 148, 142, 133, 127, 121, 115, 108, 102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1 }, + { 172, 165, 158, 152, 143, 137, 131, 125, 118, 112, 106, 100, 94, 87, 81, 75, 69, 63, 56, 45, 20 }, + { 200, 200, 200, 200, 200, 200, 200, 200, 198, 193, 188, 183, 178, 173, 168, 163, 158, 153, 148, 129, 104 } +}; + +const uint8_t ff_celt_static_caps[4][2][21] = { + { // 120-sample + {224, 224, 224, 224, 224, 224, 224, 224, 160, 160, + 160, 160, 185, 185, 185, 178, 178, 168, 134, 61, 37}, + {224, 224, 224, 224, 224, 224, 224, 224, 240, 240, + 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40}, + }, { // 240-sample + {160, 160, 160, 160, 160, 160, 160, 160, 185, 185, + 185, 185, 193, 193, 193, 183, 183, 172, 138, 64, 38}, + {240, 240, 240, 240, 240, 240, 240, 240, 207, 207, + 207, 207, 204, 204, 204, 193, 193, 180, 143, 66, 40}, + }, { // 480-sample + {185, 185, 185, 185, 185, 185, 185, 185, 193, 193, + 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39}, + {207, 207, 207, 207, 207, 207, 207, 207, 204, 204, + 204, 204, 201, 201, 201, 188, 188, 176, 141, 66, 40}, + }, { // 960-sample + {193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39}, + {204, 204, 204, 204, 204, 204, 204, 204, 201, 201, + 201, 201, 198, 198, 198, 187, 187, 175, 140, 66, 40} + } +}; + +const uint8_t ff_celt_cache_bits[392] = { + 40, 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, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, + 31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50, + 51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65, + 66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61, + 64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92, + 94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123, + 124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94, + 97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139, + 142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35, + 28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149, + 153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225, + 229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157, + 166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63, + 86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250, + 25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180, + 185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89, + 110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41, + 74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138, + 163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214, + 228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49, + 90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47, + 87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57, + 106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187, + 224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127, + 182, 234 +}; + +const int16_t ff_celt_cache_index[105] = { + -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, + 82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, + 41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305, + 318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240, + 305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240, + 240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387, +}; + +const uint8_t ff_celt_log2_frac[] = { + 0, 8, 13, 16, 19, 21, 23, 24, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 34, 35, 36, 36, 37, 37 +}; + +const uint8_t ff_celt_bit_interleave[] = { + 0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3 +}; + +const uint8_t ff_celt_bit_deinterleave[] = { + 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F, + 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF +}; + +const uint8_t ff_celt_hadamard_order[] = { + 1, 0, + 3, 0, 2, 1, + 7, 0, 4, 3, 6, 1, 5, 2, + 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +}; + +const uint16_t ff_celt_qn_exp2[] = { + 16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048 +}; + +const uint32_t ff_celt_pvq_u[1272] = { + /* N = 0, K = 0...176 */ + 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, + /* N = 1, K = 1...176 */ + 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, 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, + 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, 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, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* N = 2, K = 2...176 */ + 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, + 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, + 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, + 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, + 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, + 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, + 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, + 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, + 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, + 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, + 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, + /* N = 3, K = 3...176 */ + 13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613, + 685, 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861, + 1985, 2113, 2245, 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785, + 3961, 4141, 4325, 4513, 4705, 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385, + 6613, 6845, 7081, 7321, 7565, 7813, 8065, 8321, 8581, 8845, 9113, 9385, 9661, + 9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, 12325, 12641, 12961, + 13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, 16745, + 17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013, + 21425, 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765, + 26221, 26681, 27145, 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001, + 31501, 32005, 32513, 33025, 33541, 34061, 34585, 35113, 35645, 36181, 36721, + 37265, 37813, 38365, 38921, 39481, 40045, 40613, 41185, 41761, 42341, 42925, + 43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, 48985, 49613, + 50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785, + 57461, 58141, 58825, 59513, 60205, 60901, 61601, + /* N = 4, K = 4...176 */ + 63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017, + 7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775, + 30913, 34279, 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153, + 82239, 88641, 95367, 102425, 109823, 117569, 125671, 134137, 142975, 152193, + 161799, 171801, 182207, 193025, 204263, 215929, 228031, 240577, 253575, + 267033, 280959, 295361, 310247, 325625, 341503, 357889, 374791, 392217, + 410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951, + 597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609, + 833511, 863097, 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023, + 1125369, 1161471, 1198337, 1235975, 1274393, 1313599, 1353601, 1394407, + 1436025, 1478463, 1521729, 1565831, 1610777, 1656575, 1703233, 1750759, + 1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, 2163175, + 2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751, + 2699257, 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583, + 3244409, 3317311, 3391297, 3466375, 3542553, 3619839, 3698241, 3777767, + 3858425, 3940223, 4023169, 4107271, 4192537, 4278975, 4366593, 4455399, + 4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, 5209575, + 5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391, + 6154617, 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943, + 7085049, 7207551, + /* N = 5, K = 5...176 */ + 321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, 39041, + 50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401, + 330409, 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241, + 1061761, 1186369, 1321641, 1468169, 1626561, 1797441, 1981449, 2179241, + 2391489, 2618881, 2862121, 3121929, 3399041, 3694209, 4008201, 4341801, + 4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, 7815849, + 8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849, + 13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809, + 20549801, 21675201, 22846209, 24064041, 25329929, 26645121, 28010881, + 29428489, 30899241, 32424449, 34005441, 35643561, 37340169, 39096641, + 40914369, 42794761, 44739241, 46749249, 48826241, 50971689, 53187081, + 55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609, + 73612041, 76526529, 79526721, 82614281, 85790889, 89058241, 92418049, + 95872041, 99421961, 103069569, 106816641, 110664969, 114616361, 118672641, + 122835649, 127107241, 131489289, 135983681, 140592321, 145317129, 150160041, + 155123009, 160208001, 165417001, 170752009, 176215041, 181808129, 187533321, + 193392681, 199388289, 205522241, 211796649, 218213641, 224775361, 231483969, + 238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889, + 290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401, + 351257409, 360623041, 370174729, 379914921, 389846081, 399970689, 410291241, + 420810249, 431530241, 442453761, 453583369, 464921641, 476471169, 488234561, + 500214441, 512413449, 524834241, 537479489, 550351881, 563454121, 576788929, + 590359041, 604167209, 618216201, 632508801, + /* N = 6, K = 6...96 (technically V(109,5) fits in 32 bits, but that can't be + achieved by splitting an Opus band) */ + 1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, 177045, 246047, + 335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409, + 2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793, + 11326283, 13115773, 15124775, 17372905, 19880915, 22670725, 25765455, + 29189457, 32968347, 37129037, 41699767, 46710137, 52191139, 58175189, + 64696159, 71789409, 79491819, 87841821, 96879431, 106646281, 117185651, + 128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185, + 235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647, + 402823977, 433078547, 465124549, 499040399, 534906769, 572806619, 612825229, + 655050231, 699571641, 746481891, 795875861, 847850911, 902506913, 959946283, + 1020274013, 1083597703, 1150027593, 1219676595, 1292660325, 1369097135, + 1449108145, 1532817275, 1620351277, 1711839767, 1807415257, 1907213187, + 2011371957, 2120032959, + /* N = 7, K = 7...54 (technically V(60,6) fits in 32 bits, but that can't be + achieved by splitting an Opus band) */ + 8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, 880685, 1303777, + 1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233, + 19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013, + 88043969, 106114625, 127178701, 151620757, 179861305, 212358985, 249612805, + 292164445, 340600625, 395555537, 457713341, 527810725, 606639529, 695049433, + 793950709, 904317037, 1027188385, 1163673953, 1314955181, 1482288821, + 1667010073, 1870535785, 2094367717, + /* N = 8, K = 8...37 (technically V(40,7) fits in 32 bits, but that can't be + achieved by splitting an Opus band) */ + 48639, 108545, 224143, 433905, 795455, 1392065, 2340495, 3800305, 5984767, + 9173505, 13726991, 20103025, 28875327, 40754369, 56610575, 77500017, + 104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351, + 638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615, + 2229491905, + /* N = 9, K = 9...28 (technically V(29,8) fits in 32 bits, but that can't be + achieved by splitting an Opus band) */ + 265729, 598417, 1256465, 2485825, 4673345, 8405905, 14546705, 24331777, + 39490049, 62390545, 96220561, 145198913, 214828609, 312193553, 446304145, + 628496897, 872893441, 1196924561, 1621925137, 2173806145, + /* N = 10, K = 10...24 */ + 1462563, 3317445, 7059735, 14218905, 27298155, 50250765, 89129247, 152951073, + 254831667, 413442773, 654862247, 1014889769, 1541911931, 2300409629, + 3375210671, + /* N = 11, K = 11...19 (technically V(20,10) fits in 32 bits, but that can't be + achieved by splitting an Opus band) */ + 8097453, 18474633, 39753273, 81270333, 158819253, 298199265, 540279585, + 948062325, 1616336765, + /* N = 12, K = 12...18 */ + 45046719, 103274625, 224298231, 464387817, 921406335, 1759885185, + 3248227095, + /* N = 13, K = 13...16 */ + 251595969, 579168825, 1267854873, 2653649025, + /* N = 14, K = 14 */ + 1409933619 +}; + +const float ff_celt_postfilter_taps[3][3] = { + { 0.3066406250f, 0.2170410156f, 0.1296386719f }, + { 0.4638671875f, 0.2680664062f, 0.0 }, + { 0.7998046875f, 0.1000976562f, 0.0 } +}; + +DECLARE_ALIGNED(32, static const float, ff_celt_window_padded)[136] = { + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, + 6.7286966e-05f, 0.00060551348f, 0.0016815970f, 0.0032947962f, 0.0054439943f, + 0.0081276923f, 0.011344001f, 0.015090633f, 0.019364886f, 0.024163635f, + 0.029483315f, 0.035319905f, 0.041668911f, 0.048525347f, 0.055883718f, + 0.063737999f, 0.072081616f, 0.080907428f, 0.090207705f, 0.099974111f, + 0.11019769f, 0.12086883f, 0.13197729f, 0.14351214f, 0.15546177f, + 0.16781389f, 0.18055550f, 0.19367290f, 0.20715171f, 0.22097682f, + 0.23513243f, 0.24960208f, 0.26436860f, 0.27941419f, 0.29472040f, + 0.31026818f, 0.32603788f, 0.34200931f, 0.35816177f, 0.37447407f, + 0.39092462f, 0.40749142f, 0.42415215f, 0.44088423f, 0.45766484f, + 0.47447104f, 0.49127978f, 0.50806798f, 0.52481261f, 0.54149077f, + 0.55807973f, 0.57455701f, 0.59090049f, 0.60708841f, 0.62309951f, + 0.63891306f, 0.65450896f, 0.66986776f, 0.68497077f, 0.69980010f, + 0.71433873f, 0.72857055f, 0.74248043f, 0.75605424f, 0.76927895f, + 0.78214257f, 0.79463430f, 0.80674445f, 0.81846456f, 0.82978733f, + 0.84070669f, 0.85121779f, 0.86131698f, 0.87100183f, 0.88027111f, + 0.88912479f, 0.89756398f, 0.90559094f, 0.91320904f, 0.92042270f, + 0.92723738f, 0.93365955f, 0.93969656f, 0.94535671f, 0.95064907f, + 0.95558353f, 0.96017067f, 0.96442171f, 0.96834849f, 0.97196334f, + 0.97527906f, 0.97830883f, 0.98106616f, 0.98356480f, 0.98581869f, + 0.98784191f, 0.98964856f, 0.99125274f, 0.99266849f, 0.99390969f, + 0.99499004f, 0.99592297f, 0.99672162f, 0.99739874f, 0.99796667f, + 0.99843728f, 0.99882195f, 0.99913147f, 0.99937606f, 0.99956527f, + 0.99970802f, 0.99981248f, 0.99988613f, 0.99993565f, 0.99996697f, + 0.99998518f, 0.99999457f, 0.99999859f, 0.99999982f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, 1.00000000f, + 1.00000000f, 1.00000000f, 1.00000000f, +}; + +const float *ff_celt_window = &ff_celt_window_padded[8]; + +/* square of the window, used for the postfilter */ +const float ff_celt_window2[120] = { + 4.5275357e-09f, 3.66647e-07f, 2.82777e-06f, 1.08557e-05f, 2.96371e-05f, 6.60594e-05f, + 0.000128686f, 0.000227727f, 0.000374999f, 0.000583881f, 0.000869266f, 0.0012475f, + 0.0017363f, 0.00235471f, 0.00312299f, 0.00406253f, 0.00519576f, 0.00654601f, + 0.00813743f, 0.00999482f, 0.0121435f, 0.0146093f, 0.017418f, 0.0205957f, 0.0241684f, + 0.0281615f, 0.0326003f, 0.0375092f, 0.0429118f, 0.0488308f, 0.0552873f, 0.0623012f, + 0.0698908f, 0.0780723f, 0.0868601f, 0.0962664f, 0.106301f, 0.11697f, 0.12828f, + 0.140231f, 0.152822f, 0.166049f, 0.179905f, 0.194379f, 0.209457f, 0.225123f, 0.241356f, + 0.258133f, 0.275428f, 0.293212f, 0.311453f, 0.330116f, 0.349163f, 0.368556f, 0.388253f, + 0.40821f, 0.428382f, 0.448723f, 0.469185f, 0.48972f, 0.51028f, 0.530815f, 0.551277f, + 0.571618f, 0.59179f, 0.611747f, 0.631444f, 0.650837f, 0.669884f, 0.688547f, 0.706788f, + 0.724572f, 0.741867f, 0.758644f, 0.774877f, 0.790543f, 0.805621f, 0.820095f, 0.833951f, + 0.847178f, 0.859769f, 0.87172f, 0.88303f, 0.893699f, 0.903734f, 0.91314f, 0.921928f, + 0.930109f, 0.937699f, 0.944713f, 0.951169f, 0.957088f, 0.962491f, 0.9674f, 0.971838f, + 0.975832f, 0.979404f, 0.982582f, 0.985391f, 0.987857f, 0.990005f, 0.991863f, 0.993454f, + 0.994804f, 0.995937f, 0.996877f, 0.997645f, 0.998264f, 0.998753f, 0.999131f, 0.999416f, + 0.999625f, 0.999772f, 0.999871f, 0.999934f, 0.99997f, 0.999989f, 0.999997f, 0.99999964f, 1.0f, +}; + +const uint32_t * const ff_celt_pvq_u_row[15] = { + ff_celt_pvq_u + 0, ff_celt_pvq_u + 176, ff_celt_pvq_u + 351, + ff_celt_pvq_u + 525, ff_celt_pvq_u + 698, ff_celt_pvq_u + 870, + ff_celt_pvq_u + 1041, ff_celt_pvq_u + 1131, ff_celt_pvq_u + 1178, + ff_celt_pvq_u + 1207, ff_celt_pvq_u + 1226, ff_celt_pvq_u + 1240, + ff_celt_pvq_u + 1248, ff_celt_pvq_u + 1254, ff_celt_pvq_u + 1257 +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opustab.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opustab.h new file mode 100644 index 000000000..bce5a4283 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/opustab.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2016 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUSTAB_H +#define AVCODEC_OPUSTAB_H + +#include "libavutil/mem.h" + +#include + +extern const uint8_t ff_celt_band_end[]; + +extern const uint8_t ff_opus_default_coupled_streams[]; + +extern const uint16_t ff_silk_model_stereo_s1[]; +extern const uint16_t ff_silk_model_stereo_s2[]; +extern const uint16_t ff_silk_model_stereo_s3[]; +extern const uint16_t ff_silk_model_mid_only[]; + +extern const uint16_t ff_silk_model_frame_type_inactive[]; +extern const uint16_t ff_silk_model_frame_type_active[]; + +extern const uint16_t ff_silk_model_gain_highbits[3][9]; +extern const uint16_t ff_silk_model_gain_lowbits[]; +extern const uint16_t ff_silk_model_gain_delta[]; + +extern const uint16_t ff_silk_model_lsf_s1[2][2][33]; +extern const uint16_t ff_silk_model_lsf_s2[32][10]; +extern const uint16_t ff_silk_model_lsf_s2_ext[]; +extern const uint16_t ff_silk_model_lsf_interpolation_offset[]; + +extern const uint16_t ff_silk_model_pitch_highbits[]; +extern const uint16_t ff_silk_model_pitch_lowbits_nb[]; +extern const uint16_t ff_silk_model_pitch_lowbits_mb[]; +extern const uint16_t ff_silk_model_pitch_lowbits_wb[]; +extern const uint16_t ff_silk_model_pitch_delta[]; +extern const uint16_t ff_silk_model_pitch_contour_nb10ms[]; +extern const uint16_t ff_silk_model_pitch_contour_nb20ms[]; +extern const uint16_t ff_silk_model_pitch_contour_mbwb10ms[]; +extern const uint16_t ff_silk_model_pitch_contour_mbwb20ms[]; + +extern const uint16_t ff_silk_model_ltp_filter[]; +extern const uint16_t ff_silk_model_ltp_filter0_sel[]; +extern const uint16_t ff_silk_model_ltp_filter1_sel[]; +extern const uint16_t ff_silk_model_ltp_filter2_sel[]; +extern const uint16_t ff_silk_model_ltp_scale_index[]; + +extern const uint16_t ff_silk_model_lcg_seed[]; + +extern const uint16_t ff_silk_model_exc_rate[2][10]; + +extern const uint16_t ff_silk_model_pulse_count[11][19]; +extern const uint16_t ff_silk_model_pulse_location[4][168]; + +extern const uint16_t ff_silk_model_excitation_lsb[]; +extern const uint16_t ff_silk_model_excitation_sign[3][2][7][3]; + +extern const int16_t ff_silk_stereo_weights[]; + +extern const uint8_t ff_silk_lsf_s2_model_sel_nbmb[32][10]; +extern const uint8_t ff_silk_lsf_s2_model_sel_wb[32][16]; + +extern const uint8_t ff_silk_lsf_pred_weights_nbmb[2][9]; +extern const uint8_t ff_silk_lsf_pred_weights_wb[2][15]; + +extern const uint8_t ff_silk_lsf_weight_sel_nbmb[32][9]; +extern const uint8_t ff_silk_lsf_weight_sel_wb[32][15]; + +extern const uint8_t ff_silk_lsf_codebook_nbmb[32][10]; +extern const uint8_t ff_silk_lsf_codebook_wb[32][16]; + +extern const uint16_t ff_silk_lsf_min_spacing_nbmb[]; +extern const uint16_t ff_silk_lsf_min_spacing_wb[]; + +extern const uint8_t ff_silk_lsf_ordering_nbmb[]; +extern const uint8_t ff_silk_lsf_ordering_wb[]; + +extern const int16_t ff_silk_cosine[]; + +extern const uint16_t ff_silk_pitch_scale[]; +extern const uint16_t ff_silk_pitch_min_lag[]; +extern const uint16_t ff_silk_pitch_max_lag[]; + +extern const int8_t ff_silk_pitch_offset_nb10ms[3][2]; +extern const int8_t ff_silk_pitch_offset_nb20ms[11][4]; +extern const int8_t ff_silk_pitch_offset_mbwb10ms[12][2]; +extern const int8_t ff_silk_pitch_offset_mbwb20ms[34][4]; + +extern const int8_t ff_silk_ltp_filter0_taps[8][5]; +extern const int8_t ff_silk_ltp_filter1_taps[16][5]; +extern const int8_t ff_silk_ltp_filter2_taps[32][5]; + +extern const uint16_t ff_silk_ltp_scale_factor[]; + +extern const uint8_t ff_silk_shell_blocks[3][2]; + +extern const uint8_t ff_silk_quant_offset[2][2]; + +extern const int ff_silk_stereo_interp_len[3]; + +extern const uint16_t ff_celt_model_tapset[]; +extern const uint16_t ff_celt_model_spread[]; +extern const uint16_t ff_celt_model_alloc_trim[]; +extern const uint16_t ff_celt_model_energy_small[]; + +extern const uint8_t ff_celt_freq_bands[]; +extern const uint8_t ff_celt_freq_range[]; +extern const uint8_t ff_celt_log_freq_range[]; + +extern const int8_t ff_celt_tf_select[4][2][2][2]; + +extern const float ff_celt_mean_energy[]; + +extern const float ff_celt_alpha_coef[]; +extern const float ff_celt_beta_coef[]; + +extern const uint8_t ff_celt_coarse_energy_dist[4][2][42]; + +extern const uint8_t ff_celt_static_alloc[11][21]; +extern const uint8_t ff_celt_static_caps[4][2][21]; + +extern const uint8_t ff_celt_cache_bits[392]; +extern const int16_t ff_celt_cache_index[105]; + +extern const uint8_t ff_celt_log2_frac[]; + +extern const uint8_t ff_celt_bit_interleave[]; +extern const uint8_t ff_celt_bit_deinterleave[]; + +extern const uint8_t ff_celt_hadamard_order[]; + +extern const uint16_t ff_celt_qn_exp2[]; +extern const uint32_t ff_celt_pvq_u[1272]; + +extern const float ff_celt_postfilter_taps[3][3]; + +extern const float ff_celt_window2[120]; +extern const float *ff_celt_window; + +extern const uint32_t * const ff_celt_pvq_u_row[15]; + +#endif /* AVCODEC_OPUSTAB_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser.c new file mode 100644 index 000000000..3e19810a9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser.c @@ -0,0 +1,334 @@ +/* + * Audio and Video frame extraction + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/internal.h" +#include "libavutil/mem.h" + +#include "internal.h" +#include "parser.h" + +AVCodecParserContext *av_parser_init(int codec_id) +{ + AVCodecParserContext *s = NULL; + const AVCodecParser *parser; + void *i = 0; + int ret; + + if (codec_id == AV_CODEC_ID_NONE) + return NULL; + + while ((parser = av_parser_iterate(&i))) { + if (parser->codec_ids[0] == codec_id || + parser->codec_ids[1] == codec_id || + parser->codec_ids[2] == codec_id || + parser->codec_ids[3] == codec_id || + parser->codec_ids[4] == codec_id) + goto found; + } + return NULL; + +found: + s = av_mallocz(sizeof(AVCodecParserContext)); + if (!s) + goto err_out; + s->parser = (AVCodecParser*)parser; + s->priv_data = av_mallocz(parser->priv_data_size); + if (!s->priv_data) + goto err_out; + s->fetch_timestamp=1; + s->pict_type = AV_PICTURE_TYPE_I; + if (parser->parser_init) { + ret = parser->parser_init(s); + if (ret != 0) + goto err_out; + } + s->key_frame = -1; +#if FF_API_CONVERGENCE_DURATION +FF_DISABLE_DEPRECATION_WARNINGS + s->convergence_duration = 0; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + s->dts_sync_point = INT_MIN; + s->dts_ref_dts_delta = INT_MIN; + s->pts_dts_delta = INT_MIN; + s->format = -1; + + return s; + +err_out: + if (s) + av_freep(&s->priv_data); + av_free(s); + return NULL; +} + +void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove, int fuzzy) +{ + int i; + + if (!fuzzy) { + s->dts = + s->pts = AV_NOPTS_VALUE; + s->pos = -1; + s->offset = 0; + } + for (i = 0; i < AV_PARSER_PTS_NB; i++) { + if (s->cur_offset + off >= s->cur_frame_offset[i] && + (s->frame_offset < s->cur_frame_offset[i] || + (!s->frame_offset && !s->next_frame_offset)) && // first field/frame + // check disabled since MPEG-TS does not send complete PES packets + /*s->next_frame_offset + off <*/ s->cur_frame_end[i]){ + + if (!fuzzy || s->cur_frame_dts[i] != AV_NOPTS_VALUE) { + s->dts = s->cur_frame_dts[i]; + s->pts = s->cur_frame_pts[i]; + s->pos = s->cur_frame_pos[i]; + s->offset = s->next_frame_offset - s->cur_frame_offset[i]; + } + if (remove) + s->cur_frame_offset[i] = INT64_MAX; + if (s->cur_offset + off < s->cur_frame_end[i]) + break; + } + } +} + +int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts, int64_t pos) +{ + int index, i; + uint8_t dummy_buf[AV_INPUT_BUFFER_PADDING_SIZE]; + + av_assert1(avctx->codec_id != AV_CODEC_ID_NONE); + + /* Parsers only work for the specified codec ids. */ + av_assert1(avctx->codec_id == s->parser->codec_ids[0] || + avctx->codec_id == s->parser->codec_ids[1] || + avctx->codec_id == s->parser->codec_ids[2] || + avctx->codec_id == s->parser->codec_ids[3] || + avctx->codec_id == s->parser->codec_ids[4]); + + if (!(s->flags & PARSER_FLAG_FETCHED_OFFSET)) { + s->next_frame_offset = + s->cur_offset = pos; + s->flags |= PARSER_FLAG_FETCHED_OFFSET; + } + + if (buf_size == 0) { + /* padding is always necessary even if EOF, so we add it here */ + memset(dummy_buf, 0, sizeof(dummy_buf)); + buf = dummy_buf; + } else if (s->cur_offset + buf_size != s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */ + /* add a new packet descriptor */ + i = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); + s->cur_frame_start_index = i; + s->cur_frame_offset[i] = s->cur_offset; + s->cur_frame_end[i] = s->cur_offset + buf_size; + s->cur_frame_pts[i] = pts; + s->cur_frame_dts[i] = dts; + s->cur_frame_pos[i] = pos; + } + + if (s->fetch_timestamp) { + s->fetch_timestamp = 0; + s->last_pts = s->pts; + s->last_dts = s->dts; + s->last_pos = s->pos; + ff_fetch_timestamp(s, 0, 0, 0); + } + /* WARNING: the returned index can be negative */ + index = s->parser->parser_parse(s, avctx, (const uint8_t **) poutbuf, + poutbuf_size, buf, buf_size); + av_assert0(index > -0x20000000); // The API does not allow returning AVERROR codes +#define FILL(name) if(s->name > 0 && avctx->name <= 0) avctx->name = s->name + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + FILL(field_order); + } + + /* update the file pointer */ + if (*poutbuf_size) { + /* fill the data for the current frame */ + s->frame_offset = s->next_frame_offset; + + /* offset of the next frame */ + s->next_frame_offset = s->cur_offset + index; + s->fetch_timestamp = 1; + } + if (index < 0) + index = 0; + s->cur_offset += index; + return index; +} + +int av_parser_change(AVCodecParserContext *s, AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe) +{ + if (s && s->parser->split) { + if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER || + avctx->flags2 & AV_CODEC_FLAG2_LOCAL_HEADER) { + int i = s->parser->split(avctx, buf, buf_size); + buf += i; + buf_size -= i; + } + } + + /* cast to avoid warning about discarding qualifiers */ + *poutbuf = (uint8_t *) buf; + *poutbuf_size = buf_size; + if (avctx->extradata) { + if (keyframe && (avctx->flags2 & AV_CODEC_FLAG2_LOCAL_HEADER)) { + int size = buf_size + avctx->extradata_size; + + *poutbuf_size = size; + *poutbuf = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!*poutbuf) + return AVERROR(ENOMEM); + + memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); + memcpy(*poutbuf + avctx->extradata_size, buf, + buf_size + AV_INPUT_BUFFER_PADDING_SIZE); + return 1; + } + } + + return 0; +} + +void av_parser_close(AVCodecParserContext *s) +{ + if (s) { + if (s->parser->parser_close) + s->parser->parser_close(s); + av_freep(&s->priv_data); + av_free(s); + } +} + +int ff_combine_frame(ParseContext *pc, int next, + const uint8_t **buf, int *buf_size) +{ + if (pc->overread) { + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", + pc->overread, pc->state, next, pc->index, pc->overread_index); + ff_dlog(NULL, "%X %X %X %X\n", + (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); + } + + /* Copy overread bytes from last frame into buffer. */ + for (; pc->overread > 0; pc->overread--) + pc->buffer[pc->index++] = pc->buffer[pc->overread_index++]; + + if (next > *buf_size) + return AVERROR(EINVAL); + + /* flush remaining if EOF */ + if (!*buf_size && next == END_NOT_FOUND) + next = 0; + + pc->last_index = pc->index; + + /* copy into buffer end return */ + if (next == END_NOT_FOUND) { + void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, + *buf_size + pc->index + + AV_INPUT_BUFFER_PADDING_SIZE); + + if (!new_buffer) { + av_log(NULL, AV_LOG_ERROR, "Failed to reallocate parser buffer to %d\n", *buf_size + pc->index + AV_INPUT_BUFFER_PADDING_SIZE); + pc->index = 0; + return AVERROR(ENOMEM); + } + pc->buffer = new_buffer; + memcpy(&pc->buffer[pc->index], *buf, *buf_size); + pc->index += *buf_size; + return -1; + } + + av_assert0(next >= 0 || pc->buffer); + + *buf_size = + pc->overread_index = pc->index + next; + + /* append to buffer */ + if (pc->index) { + void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, + next + pc->index + + AV_INPUT_BUFFER_PADDING_SIZE); + if (!new_buffer) { + av_log(NULL, AV_LOG_ERROR, "Failed to reallocate parser buffer to %d\n", next + pc->index + AV_INPUT_BUFFER_PADDING_SIZE); + pc->overread_index = + pc->index = 0; + return AVERROR(ENOMEM); + } + pc->buffer = new_buffer; + if (next > -AV_INPUT_BUFFER_PADDING_SIZE) + memcpy(&pc->buffer[pc->index], *buf, + next + AV_INPUT_BUFFER_PADDING_SIZE); + pc->index = 0; + *buf = pc->buffer; + } + + /* store overread bytes */ + for (; next < 0; next++) { + pc->state = pc->state << 8 | pc->buffer[pc->last_index + next]; + pc->state64 = pc->state64 << 8 | pc->buffer[pc->last_index + next]; + pc->overread++; + } + + if (pc->overread) { + ff_dlog(NULL, "overread %d, state:%"PRIX32" next:%d index:%d o_index:%d\n", + pc->overread, pc->state, next, pc->index, pc->overread_index); + ff_dlog(NULL, "%X %X %X %X\n", + (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); + } + + return 0; +} + +void ff_parse_close(AVCodecParserContext *s) +{ + ParseContext *pc = s->priv_data; + + av_freep(&pc->buffer); +} + +int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size) +{ + uint32_t state = -1; + const uint8_t *ptr = buf, *end = buf + buf_size; + + while (ptr < end) { + ptr = avpriv_find_start_code(ptr, end, &state); + if (state == 0x1B3 || state == 0x1B6) + return ptr - 4 - buf; + } + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser.h new file mode 100644 index 000000000..ef35547e9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser.h @@ -0,0 +1,60 @@ +/* + * AVCodecParser prototypes and definitions + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_PARSER_H +#define AVCODEC_PARSER_H + +#include "avcodec.h" + +typedef struct ParseContext{ + uint8_t *buffer; + int index; + int last_index; + unsigned int buffer_size; + uint32_t state; ///< contains the last few bytes in MSB order + int frame_start_found; + int overread; ///< the number of bytes which where irreversibly read from the next frame + int overread_index; ///< the index into ParseContext.buffer of the overread bytes + uint64_t state64; ///< contains the last 8 bytes in MSB order +} ParseContext; + +#define END_NOT_FOUND (-100) + +/** + * Combine the (truncated) bitstream to a complete frame. + * @return -1 if no complete frame could be created, + * AVERROR(ENOMEM) if there was a memory allocation error + */ +int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size); +int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, + int buf_size); +void ff_parse_close(AVCodecParserContext *s); + +/** + * Fetch timestamps for a specific byte within the current access unit. + * @param off byte position within the access unit + * @param remove Found timestamps will be removed if set to 1, kept if set to 0. + * @param fuzzy Only use found value if it is more informative than what we already have + */ +void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove, int fuzzy); + +#endif /* AVCODEC_PARSER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser_list.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser_list.c new file mode 100644 index 000000000..6539d07a6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parser_list.c @@ -0,0 +1,3 @@ +static const AVCodecParser * const parser_list[] = { + &ff_aac_latm_parser, + NULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parsers.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parsers.c new file mode 100644 index 000000000..33a71de8a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/parsers.c @@ -0,0 +1,110 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/thread.h" + +#include "avcodec.h" + +extern AVCodecParser ff_aac_parser; +extern AVCodecParser ff_aac_latm_parser; +extern AVCodecParser ff_ac3_parser; +extern AVCodecParser ff_adx_parser; +extern AVCodecParser ff_av1_parser; +extern AVCodecParser ff_avs2_parser; +extern AVCodecParser ff_bmp_parser; +extern AVCodecParser ff_cavsvideo_parser; +extern AVCodecParser ff_cook_parser; +extern AVCodecParser ff_dca_parser; +extern AVCodecParser ff_dirac_parser; +extern AVCodecParser ff_dnxhd_parser; +extern AVCodecParser ff_dpx_parser; +extern AVCodecParser ff_dvaudio_parser; +extern AVCodecParser ff_dvbsub_parser; +extern AVCodecParser ff_dvdsub_parser; +extern AVCodecParser ff_dvd_nav_parser; +extern AVCodecParser ff_flac_parser; +extern AVCodecParser ff_g723_1_parser; +extern AVCodecParser ff_g729_parser; +extern AVCodecParser ff_gif_parser; +extern AVCodecParser ff_gsm_parser; +extern AVCodecParser ff_h261_parser; +extern AVCodecParser ff_h263_parser; +extern AVCodecParser ff_h264_parser; +extern AVCodecParser ff_hevc_parser; +extern AVCodecParser ff_mjpeg_parser; +extern AVCodecParser ff_mlp_parser; +extern AVCodecParser ff_mpeg4video_parser; +extern AVCodecParser ff_mpegaudio_parser; +extern AVCodecParser ff_mpegvideo_parser; +extern AVCodecParser ff_opus_parser; +extern AVCodecParser ff_png_parser; +extern AVCodecParser ff_pnm_parser; +extern AVCodecParser ff_rv30_parser; +extern AVCodecParser ff_rv40_parser; +extern AVCodecParser ff_sbc_parser; +extern AVCodecParser ff_sipr_parser; +extern AVCodecParser ff_tak_parser; +extern AVCodecParser ff_vc1_parser; +extern AVCodecParser ff_vorbis_parser; +extern AVCodecParser ff_vp3_parser; +extern AVCodecParser ff_vp8_parser; +extern AVCodecParser ff_vp9_parser; +extern AVCodecParser ff_xma_parser; + +#include "libavcodec/parser_list.c" + +static AVOnce av_parser_next_init = AV_ONCE_INIT; + +static void av_parser_init_next(void) +{ + AVCodecParser *prev = NULL, *p; + int i = 0; + while ((p = (AVCodecParser*)parser_list[i++])) { + if (prev) + prev->next = p; + prev = p; + } +} + +AVCodecParser *av_parser_next(const AVCodecParser *p) +{ + ff_thread_once(&av_parser_next_init, av_parser_init_next); + + if (p) + return p->next; + else + return (AVCodecParser*)parser_list[0]; +} + +const AVCodecParser *av_parser_iterate(void **opaque) +{ + uintptr_t i = (uintptr_t)*opaque; + const AVCodecParser *p = parser_list[i]; + + if (p) + *opaque = (void*)(i + 1); + + return p; +} + +void av_register_codec_parser(AVCodecParser *parser) +{ + ff_thread_once(&av_parser_next_init, av_parser_init_next); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pixblockdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pixblockdsp.h new file mode 100644 index 000000000..e036700ff --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pixblockdsp.h @@ -0,0 +1,55 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_PIXBLOCKDSP_H +#define AVCODEC_PIXBLOCKDSP_H + +#include + +#include "config.h" + +#include "avcodec.h" + +typedef struct PixblockDSPContext { + void (*get_pixels)(int16_t *av_restrict block /* align 16 */, + const uint8_t *pixels /* align 8 */, + ptrdiff_t stride); + void (*diff_pixels)(int16_t *av_restrict block /* align 16 */, + const uint8_t *s1 /* align 8 */, + const uint8_t *s2 /* align 8 */, + ptrdiff_t stride); + void (*diff_pixels_unaligned)(int16_t *av_restrict block /* align 16 */, + const uint8_t *s1, + const uint8_t *s2, + ptrdiff_t stride); + +} PixblockDSPContext; + +void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx); +void ff_pixblockdsp_init_alpha(PixblockDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_pixblockdsp_init_arm(PixblockDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_pixblockdsp_init_ppc(PixblockDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_pixblockdsp_init_x86(PixblockDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); +void ff_pixblockdsp_init_mips(PixblockDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth); + +#endif /* AVCODEC_PIXBLOCKDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/profiles.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/profiles.c new file mode 100644 index 000000000..eaf0d68d3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/profiles.c @@ -0,0 +1,179 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "avcodec.h" +#include "profiles.h" + +#if !CONFIG_SMALL + +const AVProfile ff_aac_profiles[] = { + { FF_PROFILE_AAC_LOW, "LC" }, + { FF_PROFILE_AAC_HE, "HE-AAC" }, + { FF_PROFILE_AAC_HE_V2, "HE-AACv2" }, + { FF_PROFILE_AAC_LD, "LD" }, + { FF_PROFILE_AAC_ELD, "ELD" }, + { FF_PROFILE_AAC_MAIN, "Main" }, + { FF_PROFILE_AAC_SSR, "SSR" }, + { FF_PROFILE_AAC_LTP, "LTP" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_dca_profiles[] = { + { FF_PROFILE_DTS, "DTS" }, + { FF_PROFILE_DTS_ES, "DTS-ES" }, + { FF_PROFILE_DTS_96_24, "DTS 96/24" }, + { FF_PROFILE_DTS_HD_HRA, "DTS-HD HRA" }, + { FF_PROFILE_DTS_HD_MA, "DTS-HD MA" }, + { FF_PROFILE_DTS_EXPRESS, "DTS Express" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_dnxhd_profiles[] = { + { FF_PROFILE_DNXHD, "DNXHD"}, + { FF_PROFILE_DNXHR_LB, "DNXHR LB"}, + { FF_PROFILE_DNXHR_SQ, "DNXHR SQ"}, + { FF_PROFILE_DNXHR_HQ, "DNXHR HQ" }, + { FF_PROFILE_DNXHR_HQX, "DNXHR HQX"}, + { FF_PROFILE_DNXHR_444, "DNXHR 444"}, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_h264_profiles[] = { + { FF_PROFILE_H264_BASELINE, "Baseline" }, + { FF_PROFILE_H264_CONSTRAINED_BASELINE, "Constrained Baseline" }, + { FF_PROFILE_H264_MAIN, "Main" }, + { FF_PROFILE_H264_EXTENDED, "Extended" }, + { FF_PROFILE_H264_HIGH, "High" }, + { FF_PROFILE_H264_HIGH_10, "High 10" }, + { FF_PROFILE_H264_HIGH_10_INTRA, "High 10 Intra" }, + { FF_PROFILE_H264_HIGH_422, "High 4:2:2" }, + { FF_PROFILE_H264_HIGH_422_INTRA, "High 4:2:2 Intra" }, + { FF_PROFILE_H264_HIGH_444, "High 4:4:4" }, + { FF_PROFILE_H264_HIGH_444_PREDICTIVE, "High 4:4:4 Predictive" }, + { FF_PROFILE_H264_HIGH_444_INTRA, "High 4:4:4 Intra" }, + { FF_PROFILE_H264_CAVLC_444, "CAVLC 4:4:4" }, + { FF_PROFILE_H264_MULTIVIEW_HIGH, "Multiview High" }, + { FF_PROFILE_H264_STEREO_HIGH, "Stereo High" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_hevc_profiles[] = { + { FF_PROFILE_HEVC_MAIN, "Main" }, + { FF_PROFILE_HEVC_MAIN_10, "Main 10" }, + { FF_PROFILE_HEVC_MAIN_STILL_PICTURE, "Main Still Picture" }, + { FF_PROFILE_HEVC_REXT, "Rext" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_jpeg2000_profiles[] = { + { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0, "JPEG 2000 codestream restriction 0" }, + { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1, "JPEG 2000 codestream restriction 1" }, + { FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION, "JPEG 2000 no codestream restrictions" }, + { FF_PROFILE_JPEG2000_DCINEMA_2K, "JPEG 2000 digital cinema 2K" }, + { FF_PROFILE_JPEG2000_DCINEMA_4K, "JPEG 2000 digital cinema 4K" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_mpeg2_video_profiles[] = { + { FF_PROFILE_MPEG2_422, "4:2:2" }, + { FF_PROFILE_MPEG2_HIGH, "High" }, + { FF_PROFILE_MPEG2_SS, "Spatially Scalable" }, + { FF_PROFILE_MPEG2_SNR_SCALABLE, "SNR Scalable" }, + { FF_PROFILE_MPEG2_MAIN, "Main" }, + { FF_PROFILE_MPEG2_SIMPLE, "Simple" }, + { FF_PROFILE_RESERVED, "Reserved" }, + { FF_PROFILE_RESERVED, "Reserved" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_mpeg4_video_profiles[] = { + { FF_PROFILE_MPEG4_SIMPLE, "Simple Profile" }, + { FF_PROFILE_MPEG4_SIMPLE_SCALABLE, "Simple Scalable Profile" }, + { FF_PROFILE_MPEG4_CORE, "Core Profile" }, + { FF_PROFILE_MPEG4_MAIN, "Main Profile" }, + { FF_PROFILE_MPEG4_N_BIT, "N-bit Profile" }, + { FF_PROFILE_MPEG4_SCALABLE_TEXTURE, "Scalable Texture Profile" }, + { FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION, "Simple Face Animation Profile" }, + { FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE, "Basic Animated Texture Profile" }, + { FF_PROFILE_MPEG4_HYBRID, "Hybrid Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_REAL_TIME, "Advanced Real Time Simple Profile" }, + { FF_PROFILE_MPEG4_CORE_SCALABLE, "Code Scalable Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_CODING, "Advanced Coding Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_CORE, "Advanced Core Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE, "Advanced Scalable Texture Profile" }, + { FF_PROFILE_MPEG4_SIMPLE_STUDIO, "Simple Studio Profile" }, + { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, "Advanced Simple Profile" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_vc1_profiles[] = { + { FF_PROFILE_VC1_SIMPLE, "Simple" }, + { FF_PROFILE_VC1_MAIN, "Main" }, + { FF_PROFILE_VC1_COMPLEX, "Complex" }, + { FF_PROFILE_VC1_ADVANCED, "Advanced" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_vp9_profiles[] = { + { FF_PROFILE_VP9_0, "Profile 0" }, + { FF_PROFILE_VP9_1, "Profile 1" }, + { FF_PROFILE_VP9_2, "Profile 2" }, + { FF_PROFILE_VP9_3, "Profile 3" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_av1_profiles[] = { + { FF_PROFILE_AV1_MAIN, "Main" }, + { FF_PROFILE_AV1_HIGH, "High" }, + { FF_PROFILE_AV1_PROFESSIONAL, "Professional" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_sbc_profiles[] = { + { FF_PROFILE_SBC_MSBC, "mSBC" }, + { FF_PROFILE_UNKNOWN }, +}; + +const AVProfile ff_prores_profiles[] = { + { FF_PROFILE_PRORES_PROXY, "Proxy" }, + { FF_PROFILE_PRORES_LT, "LT" }, + { FF_PROFILE_PRORES_STANDARD, "Standard" }, + { FF_PROFILE_PRORES_HQ, "HQ" }, + { FF_PROFILE_PRORES_4444, "4444" }, + { FF_PROFILE_PRORES_XQ, "XQ" }, + { FF_PROFILE_UNKNOWN } +}; + +const AVProfile ff_mjpeg_profiles[] = { + { FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT, "Baseline" }, + { FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT, "Sequential" }, + { FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT, "Progressive" }, + { FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS, "Lossless" }, + { FF_PROFILE_MJPEG_JPEG_LS, "JPEG LS" }, + { FF_PROFILE_UNKNOWN } +}; + +const AVProfile ff_arib_caption_profiles[] = { + { FF_PROFILE_ARIB_PROFILE_A, "Profile A" }, + { FF_PROFILE_ARIB_PROFILE_C, "Profile C" }, + { FF_PROFILE_UNKNOWN } +}; + +#endif /* !CONFIG_SMALL */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/profiles.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/profiles.h new file mode 100644 index 000000000..a53b67e7f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/profiles.h @@ -0,0 +1,40 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_PROFILES_H +#define AVCODEC_PROFILES_H + +#include "avcodec.h" + +extern const AVProfile ff_aac_profiles[]; +extern const AVProfile ff_dca_profiles[]; +extern const AVProfile ff_dnxhd_profiles[]; +extern const AVProfile ff_h264_profiles[]; +extern const AVProfile ff_hevc_profiles[]; +extern const AVProfile ff_jpeg2000_profiles[]; +extern const AVProfile ff_mpeg2_video_profiles[]; +extern const AVProfile ff_mpeg4_video_profiles[]; +extern const AVProfile ff_vc1_profiles[]; +extern const AVProfile ff_vp9_profiles[]; +extern const AVProfile ff_av1_profiles[]; +extern const AVProfile ff_sbc_profiles[]; +extern const AVProfile ff_prores_profiles[]; +extern const AVProfile ff_mjpeg_profiles[]; +extern const AVProfile ff_arib_caption_profiles[]; + +#endif /* AVCODEC_PROFILES_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/psymodel.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/psymodel.c new file mode 100644 index 000000000..2b5f111fb --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/psymodel.c @@ -0,0 +1,161 @@ +/* + * audio encoder psychoacoustic model + * Copyright (C) 2008 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "avcodec.h" +#include "psymodel.h" +#include "iirfilter.h" +#include "libavutil/mem.h" + +extern const FFPsyModel ff_aac_psy_model; + +av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens, + const uint8_t **bands, const int* num_bands, + int num_groups, const uint8_t *group_map) +{ + int i, j, k = 0; + + ctx->avctx = avctx; + ctx->ch = av_mallocz_array(sizeof(ctx->ch[0]), avctx->channels * 2); + ctx->group = av_mallocz_array(sizeof(ctx->group[0]), num_groups); + ctx->bands = av_malloc_array (sizeof(ctx->bands[0]), num_lens); + ctx->num_bands = av_malloc_array (sizeof(ctx->num_bands[0]), num_lens); + ctx->cutoff = avctx->cutoff; + + if (!ctx->ch || !ctx->group || !ctx->bands || !ctx->num_bands) { + ff_psy_end(ctx); + return AVERROR(ENOMEM); + } + + memcpy(ctx->bands, bands, sizeof(ctx->bands[0]) * num_lens); + memcpy(ctx->num_bands, num_bands, sizeof(ctx->num_bands[0]) * num_lens); + + /* assign channels to groups (with virtual channels for coupling) */ + for (i = 0; i < num_groups; i++) { + /* NOTE: Add 1 to handle the AAC chan_config without modification. + * This has the side effect of allowing an array of 0s to map + * to one channel per group. + */ + ctx->group[i].num_ch = group_map[i] + 1; + for (j = 0; j < ctx->group[i].num_ch * 2; j++) + ctx->group[i].ch[j] = &ctx->ch[k++]; + } + + switch (ctx->avctx->codec_id) { + case AV_CODEC_ID_AAC: + ctx->model = &ff_aac_psy_model; + break; + } + if (ctx->model->init) + return ctx->model->init(ctx); + return 0; +} + +FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel) +{ + int i = 0, ch = 0; + + while (ch <= channel) + ch += ctx->group[i++].num_ch; + + return &ctx->group[i-1]; +} + +av_cold void ff_psy_end(FFPsyContext *ctx) +{ + if (ctx->model && ctx->model->end) + ctx->model->end(ctx); + av_freep(&ctx->bands); + av_freep(&ctx->num_bands); + av_freep(&ctx->group); + av_freep(&ctx->ch); +} + +typedef struct FFPsyPreprocessContext{ + AVCodecContext *avctx; + float stereo_att; + struct FFIIRFilterCoeffs *fcoeffs; + struct FFIIRFilterState **fstate; + struct FFIIRFilterContext fiir; +}FFPsyPreprocessContext; + +#define FILT_ORDER 4 + +av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx) +{ + FFPsyPreprocessContext *ctx; + int i; + float cutoff_coeff = 0; + ctx = av_mallocz(sizeof(FFPsyPreprocessContext)); + if (!ctx) + return NULL; + ctx->avctx = avctx; + + /* AAC has its own LP method */ + if (avctx->codec_id != AV_CODEC_ID_AAC) { + if (avctx->cutoff > 0) + cutoff_coeff = 2.0 * avctx->cutoff / avctx->sample_rate; + + if (cutoff_coeff && cutoff_coeff < 0.98) + ctx->fcoeffs = ff_iir_filter_init_coeffs(avctx, FF_FILTER_TYPE_BUTTERWORTH, + FF_FILTER_MODE_LOWPASS, FILT_ORDER, + cutoff_coeff, 0.0, 0.0); + if (ctx->fcoeffs) { + ctx->fstate = av_mallocz_array(sizeof(ctx->fstate[0]), avctx->channels); + if (!ctx->fstate) { + av_free(ctx->fcoeffs); + av_free(ctx); + return NULL; + } + for (i = 0; i < avctx->channels; i++) + ctx->fstate[i] = ff_iir_filter_init_state(FILT_ORDER); + } + } + + ff_iir_filter_init(&ctx->fiir); + + return ctx; +} + +void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx, float **audio, int channels) +{ + int ch; + int frame_size = ctx->avctx->frame_size; + FFIIRFilterContext *iir = &ctx->fiir; + + if (ctx->fstate) { + for (ch = 0; ch < channels; ch++) + iir->filter_flt(ctx->fcoeffs, ctx->fstate[ch], frame_size, + &audio[ch][frame_size], 1, &audio[ch][frame_size], 1); + } +} + +av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx) +{ + int i; + ff_iir_filter_free_coeffsp(&ctx->fcoeffs); + if (ctx->fstate) + for (i = 0; i < ctx->avctx->channels; i++) + ff_iir_filter_free_statep(&ctx->fstate[i]); + av_freep(&ctx->fstate); + av_free(ctx); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/psymodel.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/psymodel.h new file mode 100644 index 000000000..e5f917d49 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/psymodel.h @@ -0,0 +1,204 @@ +/* + * audio encoder psychoacoustic model + * Copyright (C) 2008 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_PSYMODEL_H +#define AVCODEC_PSYMODEL_H + +#include "avcodec.h" + +/** maximum possible number of bands */ +#define PSY_MAX_BANDS 128 +/** maximum number of channels */ +#define PSY_MAX_CHANS 20 + +/* cutoff for VBR is purposely increased, since LP filtering actually + * hinders VBR performance rather than the opposite + */ +#define AAC_CUTOFF_FROM_BITRATE(bit_rate,channels,sample_rate) (bit_rate ? FFMIN3(FFMIN3( \ + FFMAX(bit_rate/channels/5, bit_rate/channels*15/32 - 5500), \ + 3000 + bit_rate/channels/4, \ + 12000 + bit_rate/channels/16), \ + 22000, \ + sample_rate / 2): (sample_rate / 2)) +#define AAC_CUTOFF(s) ( \ + (s->flags & AV_CODEC_FLAG_QSCALE) \ + ? s->sample_rate / 2 \ + : AAC_CUTOFF_FROM_BITRATE(s->bit_rate, s->channels, s->sample_rate) \ +) + +/** + * single band psychoacoustic information + */ +typedef struct FFPsyBand { + int bits; + float energy; + float threshold; + float spread; /* Energy spread over the band */ +} FFPsyBand; + +/** + * single channel psychoacoustic information + */ +typedef struct FFPsyChannel { + FFPsyBand psy_bands[PSY_MAX_BANDS]; ///< channel bands information + float entropy; ///< total PE for this channel +} FFPsyChannel; + +/** + * psychoacoustic information for an arbitrary group of channels + */ +typedef struct FFPsyChannelGroup { + FFPsyChannel *ch[PSY_MAX_CHANS]; ///< pointers to the individual channels in the group + uint8_t num_ch; ///< number of channels in this group + uint8_t coupling[PSY_MAX_BANDS]; ///< allow coupling for this band in the group +} FFPsyChannelGroup; + +/** + * windowing related information + */ +typedef struct FFPsyWindowInfo { + int window_type[3]; ///< window type (short/long/transitional, etc.) - current, previous and next + int window_shape; ///< window shape (sine/KBD/whatever) + int num_windows; ///< number of windows in a frame + int grouping[8]; ///< window grouping (for e.g. AAC) + float clipping[8]; ///< maximum absolute normalized intensity in the given window for clip avoidance + int *window_sizes; ///< sequence of window sizes inside one frame (for eg. WMA) +} FFPsyWindowInfo; + +/** + * context used by psychoacoustic model + */ +typedef struct FFPsyContext { + AVCodecContext *avctx; ///< encoder context + const struct FFPsyModel *model; ///< encoder-specific model functions + + FFPsyChannel *ch; ///< single channel information + FFPsyChannelGroup *group; ///< channel group information + int num_groups; ///< number of channel groups + int cutoff; ///< lowpass frequency cutoff for analysis + + uint8_t **bands; ///< scalefactor band sizes for possible frame sizes + int *num_bands; ///< number of scalefactor bands for possible frame sizes + int num_lens; ///< number of scalefactor band sets + + struct { + int size; ///< size of the bitresevoir in bits + int bits; ///< number of bits used in the bitresevoir + int alloc; ///< number of bits allocated by the psy, or -1 if no allocation was done + } bitres; + + void* model_priv_data; ///< psychoacoustic model implementation private data +} FFPsyContext; + +/** + * codec-specific psychoacoustic model implementation + */ +typedef struct FFPsyModel { + const char *name; + int (*init) (FFPsyContext *apc); + + /** + * Suggest window sequence for channel. + * + * @param ctx model context + * @param audio samples for the current frame + * @param la lookahead samples (NULL when unavailable) + * @param channel number of channel element to analyze + * @param prev_type previous window type + * + * @return suggested window information in a structure + */ + FFPsyWindowInfo (*window)(FFPsyContext *ctx, const float *audio, const float *la, int channel, int prev_type); + + /** + * Perform psychoacoustic analysis and set band info (threshold, energy) for a group of channels. + * + * @param ctx model context + * @param channel channel number of the first channel in the group to perform analysis on + * @param coeffs array of pointers to the transformed coefficients + * @param wi window information for the channels in the group + */ + void (*analyze)(FFPsyContext *ctx, int channel, const float **coeffs, const FFPsyWindowInfo *wi); + + void (*end) (FFPsyContext *apc); +} FFPsyModel; + +/** + * Initialize psychoacoustic model. + * + * @param ctx model context + * @param avctx codec context + * @param num_lens number of possible frame lengths + * @param bands scalefactor band lengths for all frame lengths + * @param num_bands number of scalefactor bands for all frame lengths + * @param num_groups number of channel groups + * @param group_map array with # of channels in group - 1, for each group + * + * @return zero if successful, a negative value if not + */ +int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens, + const uint8_t **bands, const int *num_bands, + int num_groups, const uint8_t *group_map); + +/** + * Determine what group a channel belongs to. + * + * @param ctx psymodel context + * @param channel channel to locate the group for + * + * @return pointer to the FFPsyChannelGroup this channel belongs to + */ +FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel); + +/** + * Cleanup model context at the end. + * + * @param ctx model context + */ +void ff_psy_end(FFPsyContext *ctx); + + +/************************************************************************** + * Audio preprocessing stuff. * + * This should be moved into some audio filter eventually. * + **************************************************************************/ +struct FFPsyPreprocessContext; + +/** + * psychoacoustic model audio preprocessing initialization + */ +struct FFPsyPreprocessContext *ff_psy_preprocess_init(AVCodecContext *avctx); + +/** + * Preprocess several channel in audio frame in order to compress it better. + * + * @param ctx preprocessing context + * @param audio samples to be filtered (in place) + * @param channels number of channel to preprocess + */ +void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx, float **audio, int channels); + +/** + * Cleanup audio preprocessing module. + */ +void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx); + +#endif /* AVCODEC_PSYMODEL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread.c new file mode 100644 index 000000000..572471586 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2004 Roman Shaposhnik + * Copyright (c) 2008 Alexander Strange (astrange@ithinksw.com) + * + * Many thanks to Steven M. Schultz for providing clever ideas and + * to Michael Niedermayer for writing initial + * implementation. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Multithreading support functions + * @see doc/multithreading.txt + */ + +#include "avcodec.h" +#include "internal.h" +#include "pthread_internal.h" +#include "thread.h" + +/** + * Set the threading algorithms used. + * + * Threading requires more than one thread. + * Frame threading requires entire frames to be passed to the codec, + * and introduces extra decoding delay, so is incompatible with low_delay. + * + * @param avctx The context. + */ +static void validate_thread_parameters(AVCodecContext *avctx) +{ + int frame_threading_supported = (avctx->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) + && !(avctx->flags & AV_CODEC_FLAG_TRUNCATED) + && !(avctx->flags & AV_CODEC_FLAG_LOW_DELAY) + && !(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS); + if (avctx->thread_count == 1) { + avctx->active_thread_type = 0; + } else if (frame_threading_supported && (avctx->thread_type & FF_THREAD_FRAME)) { + avctx->active_thread_type = FF_THREAD_FRAME; + } else if (avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS && + avctx->thread_type & FF_THREAD_SLICE) { + avctx->active_thread_type = FF_THREAD_SLICE; + } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_AUTO_THREADS)) { + avctx->thread_count = 1; + avctx->active_thread_type = 0; + } + + if (avctx->thread_count > MAX_AUTO_THREADS) + av_log(avctx, AV_LOG_WARNING, + "Application has requested %d threads. Using a thread count greater than %d is not recommended.\n", + avctx->thread_count, MAX_AUTO_THREADS); +} + +int ff_thread_init(AVCodecContext *avctx) +{ + validate_thread_parameters(avctx); + + if (avctx->active_thread_type&FF_THREAD_SLICE) + return ff_slice_thread_init(avctx); + else if (avctx->active_thread_type&FF_THREAD_FRAME) + return ff_frame_thread_init(avctx); + + return 0; +} + +void ff_thread_free(AVCodecContext *avctx) +{ + if (avctx->active_thread_type&FF_THREAD_FRAME) + ff_frame_thread_free(avctx, avctx->thread_count); + else + ff_slice_thread_free(avctx); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_frame.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_frame.c new file mode 100644 index 000000000..36ac0ac1e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_frame.c @@ -0,0 +1,1013 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Frame multithreading support functions + * @see doc/multithreading.txt + */ + +#include "config.h" + +#include +#include + +#include "avcodec.h" +#include "hwaccel.h" +#include "internal.h" +#include "pthread_internal.h" +#include "thread.h" +#include "version.h" + +#include "libavutil/avassert.h" +#include "libavutil/buffer.h" +#include "libavutil/common.h" +#include "libavutil/cpu.h" +#include "libavutil/frame.h" +#include "libavutil/internal.h" +#include "libavutil/log.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include "libavutil/thread.h" + +enum { + ///< Set when the thread is awaiting a packet. + STATE_INPUT_READY, + ///< Set before the codec has called ff_thread_finish_setup(). + STATE_SETTING_UP, + /** + * Set when the codec calls get_buffer(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_BUFFER, + /** + * Set when the codec calls get_format(). + * State is returned to STATE_SETTING_UP afterwards. + */ + STATE_GET_FORMAT, + ///< Set after the codec has called ff_thread_finish_setup(). + STATE_SETUP_FINISHED, +}; + +/** + * Context used by codec threads and stored in their AVCodecInternal thread_ctx. + */ +typedef struct PerThreadContext { + struct FrameThreadContext *parent; + + pthread_t thread; + int thread_init; + pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread. + pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change. + pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish. + + pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext. + pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond. + + AVCodecContext *avctx; ///< Context used to decode packets passed to this thread. + + AVPacket avpkt; ///< Input packet (for decoding) or output (for encoding). + + AVFrame *frame; ///< Output frame (for decoding) or input (for encoding). + int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call. + int result; ///< The result of the last codec decode/encode() call. + + atomic_int state; + + /** + * Array of frames passed to ff_thread_release_buffer(). + * Frames are released after all threads referencing them are finished. + */ + AVFrame *released_buffers; + int num_released_buffers; + int released_buffers_allocated; + + AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer() + int requested_flags; ///< flags passed to get_buffer() for requested_frame + + const enum AVPixelFormat *available_formats; ///< Format array for get_format() + enum AVPixelFormat result_format; ///< get_format() result + + int die; ///< Set when the thread should exit. + + int hwaccel_serializing; + int async_serializing; + + atomic_int debug_threads; ///< Set if the FF_DEBUG_THREADS option is set. +} PerThreadContext; + +/** + * Context stored in the client AVCodecInternal thread_ctx. + */ +typedef struct FrameThreadContext { + PerThreadContext *threads; ///< The contexts for each thread. + PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on. + + pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer(). + /** + * This lock is used for ensuring threads run in serial when hwaccel + * is used. + */ + pthread_mutex_t hwaccel_mutex; + pthread_mutex_t async_mutex; + pthread_cond_t async_cond; + int async_lock; + + int next_decoding; ///< The next context to submit a packet to. + int next_finished; ///< The next context to return output from. + + int delaying; /**< + * Set for the first N packets, where N is the number of threads. + * While it is set, ff_thread_en/decode_frame won't return any results. + */ +} FrameThreadContext; + +#define THREAD_SAFE_CALLBACKS(avctx) \ +((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2) + +static void async_lock(FrameThreadContext *fctx) +{ + pthread_mutex_lock(&fctx->async_mutex); + while (fctx->async_lock) + pthread_cond_wait(&fctx->async_cond, &fctx->async_mutex); + fctx->async_lock = 1; + pthread_mutex_unlock(&fctx->async_mutex); +} + +static void async_unlock(FrameThreadContext *fctx) +{ + pthread_mutex_lock(&fctx->async_mutex); + av_assert0(fctx->async_lock); + fctx->async_lock = 0; + pthread_cond_broadcast(&fctx->async_cond); + pthread_mutex_unlock(&fctx->async_mutex); +} + +/** + * Codec worker thread. + * + * Automatically calls ff_thread_finish_setup() if the codec does + * not provide an update_thread_context method, or if the codec returns + * before calling it. + */ +static attribute_align_arg void *frame_worker_thread(void *arg) +{ + PerThreadContext *p = arg; + AVCodecContext *avctx = p->avctx; + const AVCodec *codec = avctx->codec; + + pthread_mutex_lock(&p->mutex); + while (1) { + while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die) + pthread_cond_wait(&p->input_cond, &p->mutex); + + if (p->die) break; + + if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx)) + ff_thread_finish_setup(avctx); + + /* If a decoder supports hwaccel, then it must call ff_get_format(). + * Since that call must happen before ff_thread_finish_setup(), the + * decoder is required to implement update_thread_context() and call + * ff_thread_finish_setup() manually. Therefore the above + * ff_thread_finish_setup() call did not happen and hwaccel_serializing + * cannot be true here. */ + av_assert0(!p->hwaccel_serializing); + + /* if the previous thread uses hwaccel then we take the lock to ensure + * the threads don't run concurrently */ + if (avctx->hwaccel) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + + av_frame_unref(p->frame); + p->got_frame = 0; + p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt); + + if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) { + if (avctx->internal->allocate_progress) + av_log(avctx, AV_LOG_ERROR, "A frame threaded decoder did not " + "free the frame on failure. This is a bug, please report it.\n"); + av_frame_unref(p->frame); + } + + if (atomic_load(&p->state) == STATE_SETTING_UP) + ff_thread_finish_setup(avctx); + + if (p->hwaccel_serializing) { + p->hwaccel_serializing = 0; + pthread_mutex_unlock(&p->parent->hwaccel_mutex); + } + + if (p->async_serializing) { + p->async_serializing = 0; + + async_unlock(p->parent); + } + + pthread_mutex_lock(&p->progress_mutex); + + atomic_store(&p->state, STATE_INPUT_READY); + + pthread_cond_broadcast(&p->progress_cond); + pthread_cond_signal(&p->output_cond); + pthread_mutex_unlock(&p->progress_mutex); + } + pthread_mutex_unlock(&p->mutex); + + return NULL; +} + +/** + * Update the next thread's AVCodecContext with values from the reference thread's context. + * + * @param dst The destination context. + * @param src The source context. + * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread + * @return 0 on success, negative error code on failure + */ +static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user) +{ + int err = 0; + + if (dst != src && (for_user || !(src->codec_descriptor->props & AV_CODEC_PROP_INTRA_ONLY))) { + dst->time_base = src->time_base; + dst->framerate = src->framerate; + dst->width = src->width; + dst->height = src->height; + dst->pix_fmt = src->pix_fmt; + dst->sw_pix_fmt = src->sw_pix_fmt; + + dst->coded_width = src->coded_width; + dst->coded_height = src->coded_height; + + dst->has_b_frames = src->has_b_frames; + dst->idct_algo = src->idct_algo; + + dst->bits_per_coded_sample = src->bits_per_coded_sample; + dst->sample_aspect_ratio = src->sample_aspect_ratio; + + dst->profile = src->profile; + dst->level = src->level; + + dst->bits_per_raw_sample = src->bits_per_raw_sample; + dst->ticks_per_frame = src->ticks_per_frame; + dst->color_primaries = src->color_primaries; + + dst->color_trc = src->color_trc; + dst->colorspace = src->colorspace; + dst->color_range = src->color_range; + dst->chroma_sample_location = src->chroma_sample_location; + + dst->hwaccel = src->hwaccel; + dst->hwaccel_context = src->hwaccel_context; + + dst->channels = src->channels; + dst->sample_rate = src->sample_rate; + dst->sample_fmt = src->sample_fmt; + dst->channel_layout = src->channel_layout; + dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data; + + if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx || + (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) { + av_buffer_unref(&dst->hw_frames_ctx); + + if (src->hw_frames_ctx) { + dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); + if (!dst->hw_frames_ctx) + return AVERROR(ENOMEM); + } + } + + dst->hwaccel_flags = src->hwaccel_flags; + } + + if (for_user) { + dst->delay = src->thread_count - 1; +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + dst->coded_frame = src->coded_frame; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + } else { + if (dst->codec->update_thread_context) + err = dst->codec->update_thread_context(dst, src); + } + + return err; +} + +/** + * Update the next thread's AVCodecContext with values set by the user. + * + * @param dst The destination context. + * @param src The source context. + * @return 0 on success, negative error code on failure + */ +static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) +{ +#define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s); + dst->flags = src->flags; + + dst->draw_horiz_band= src->draw_horiz_band; + dst->get_buffer2 = src->get_buffer2; + + dst->opaque = src->opaque; + dst->debug = src->debug; + dst->debug_mv = src->debug_mv; + + dst->slice_flags = src->slice_flags; + dst->flags2 = src->flags2; + + copy_fields(skip_loop_filter, subtitle_header); + + dst->frame_number = src->frame_number; + dst->reordered_opaque = src->reordered_opaque; + dst->thread_safe_callbacks = src->thread_safe_callbacks; + + if (src->slice_count && src->slice_offset) { + if (dst->slice_count < src->slice_count) { + int err = av_reallocp_array(&dst->slice_offset, src->slice_count, + sizeof(*dst->slice_offset)); + if (err < 0) + return err; + } + memcpy(dst->slice_offset, src->slice_offset, + src->slice_count * sizeof(*dst->slice_offset)); + } + dst->slice_count = src->slice_count; + return 0; +#undef copy_fields +} + +/// Releases the buffers that this decoding thread was the last user of. +static void release_delayed_buffers(PerThreadContext *p) +{ + FrameThreadContext *fctx = p->parent; + + while (p->num_released_buffers > 0) { + AVFrame *f; + + pthread_mutex_lock(&fctx->buffer_mutex); + + // fix extended data in case the caller screwed it up + av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO || + p->avctx->codec_type == AVMEDIA_TYPE_AUDIO); + f = &p->released_buffers[--p->num_released_buffers]; + f->extended_data = f->data; + av_frame_unref(f); + + pthread_mutex_unlock(&fctx->buffer_mutex); + } +} + +static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, + AVPacket *avpkt) +{ + FrameThreadContext *fctx = p->parent; + PerThreadContext *prev_thread = fctx->prev_thread; + const AVCodec *codec = p->avctx->codec; + int ret; + + if (!avpkt->size && !(codec->capabilities & AV_CODEC_CAP_DELAY)) + return 0; + + pthread_mutex_lock(&p->mutex); + + ret = update_context_from_user(p->avctx, user_avctx); + if (ret) { + pthread_mutex_unlock(&p->mutex); + return ret; + } + atomic_store_explicit(&p->debug_threads, + (p->avctx->debug & FF_DEBUG_THREADS) != 0, + memory_order_relaxed); + + release_delayed_buffers(p); + + if (prev_thread) { + int err; + if (atomic_load(&prev_thread->state) == STATE_SETTING_UP) { + pthread_mutex_lock(&prev_thread->progress_mutex); + while (atomic_load(&prev_thread->state) == STATE_SETTING_UP) + pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex); + pthread_mutex_unlock(&prev_thread->progress_mutex); + } + + err = update_context_from_thread(p->avctx, prev_thread->avctx, 0); + if (err) { + pthread_mutex_unlock(&p->mutex); + return err; + } + } + + av_packet_unref(&p->avpkt); + ret = av_packet_ref(&p->avpkt, avpkt); + if (ret < 0) { + pthread_mutex_unlock(&p->mutex); + av_log(p->avctx, AV_LOG_ERROR, "av_packet_ref() failed in submit_packet()\n"); + return ret; + } + + atomic_store(&p->state, STATE_SETTING_UP); + pthread_cond_signal(&p->input_cond); + pthread_mutex_unlock(&p->mutex); + + /* + * If the client doesn't have a thread-safe get_buffer(), + * then decoding threads call back to the main thread, + * and it calls back to the client here. + */ + + if (!p->avctx->thread_safe_callbacks && ( + p->avctx->get_format != avcodec_default_get_format || + p->avctx->get_buffer2 != avcodec_default_get_buffer2)) { + while (atomic_load(&p->state) != STATE_SETUP_FINISHED && atomic_load(&p->state) != STATE_INPUT_READY) { + int call_done = 1; + pthread_mutex_lock(&p->progress_mutex); + while (atomic_load(&p->state) == STATE_SETTING_UP) + pthread_cond_wait(&p->progress_cond, &p->progress_mutex); + + switch (atomic_load_explicit(&p->state, memory_order_acquire)) { + case STATE_GET_BUFFER: + p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags); + break; + case STATE_GET_FORMAT: + p->result_format = ff_get_format(p->avctx, p->available_formats); + break; + default: + call_done = 0; + break; + } + if (call_done) { + atomic_store(&p->state, STATE_SETTING_UP); + pthread_cond_signal(&p->progress_cond); + } + pthread_mutex_unlock(&p->progress_mutex); + } + } + + fctx->prev_thread = p; + fctx->next_decoding++; + + return 0; +} + +int ff_thread_decode_frame(AVCodecContext *avctx, + AVFrame *picture, int *got_picture_ptr, + AVPacket *avpkt) +{ + FrameThreadContext *fctx = avctx->internal->thread_ctx; + int finished = fctx->next_finished; + PerThreadContext *p; + int err; + + /* release the async lock, permitting blocked hwaccel threads to + * go forward while we are in this function */ + async_unlock(fctx); + + /* + * Submit a packet to the next decoding thread. + */ + + p = &fctx->threads[fctx->next_decoding]; + err = submit_packet(p, avctx, avpkt); + if (err) + goto finish; + + /* + * If we're still receiving the initial packets, don't return a frame. + */ + + if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1))) + fctx->delaying = 0; + + if (fctx->delaying) { + *got_picture_ptr=0; + if (avpkt->size) { + err = avpkt->size; + goto finish; + } + } + + /* + * Return the next available frame from the oldest thread. + * If we're at the end of the stream, then we have to skip threads that + * didn't output a frame/error, because we don't want to accidentally signal + * EOF (avpkt->size == 0 && *got_picture_ptr == 0 && err >= 0). + */ + + do { + p = &fctx->threads[finished++]; + + if (atomic_load(&p->state) != STATE_INPUT_READY) { + pthread_mutex_lock(&p->progress_mutex); + while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY) + pthread_cond_wait(&p->output_cond, &p->progress_mutex); + pthread_mutex_unlock(&p->progress_mutex); + } + + av_frame_move_ref(picture, p->frame); + *got_picture_ptr = p->got_frame; + picture->pkt_dts = p->avpkt.dts; + err = p->result; + + /* + * A later call with avkpt->size == 0 may loop over all threads, + * including this one, searching for a frame/error to return before being + * stopped by the "finished != fctx->next_finished" condition. + * Make sure we don't mistakenly return the same frame/error again. + */ + p->got_frame = 0; + p->result = 0; + + if (finished >= avctx->thread_count) finished = 0; + } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != fctx->next_finished); + + update_context_from_thread(avctx, p->avctx, 1); + + if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0; + + fctx->next_finished = finished; + + /* return the size of the consumed packet if no error occurred */ + if (err >= 0) + err = avpkt->size; +finish: + async_lock(fctx); + return err; +} + +void ff_thread_report_progress(ThreadFrame *f, int n, int field) +{ + PerThreadContext *p; + atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; + + if (!progress || + atomic_load_explicit(&progress[field], memory_order_relaxed) >= n) + return; + + p = f->owner[field]->internal->thread_ctx; + + if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed)) + av_log(f->owner[field], AV_LOG_DEBUG, + "%p finished %d field %d\n", progress, n, field); + + pthread_mutex_lock(&p->progress_mutex); + + atomic_store_explicit(&progress[field], n, memory_order_release); + + pthread_cond_broadcast(&p->progress_cond); + pthread_mutex_unlock(&p->progress_mutex); +} + +void ff_thread_await_progress(ThreadFrame *f, int n, int field) +{ + PerThreadContext *p; + atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL; + + if (!progress || + atomic_load_explicit(&progress[field], memory_order_acquire) >= n) + return; + + p = f->owner[field]->internal->thread_ctx; + + if (atomic_load_explicit(&p->debug_threads, memory_order_relaxed)) + av_log(f->owner[field], AV_LOG_DEBUG, + "thread awaiting %d field %d from %p\n", n, field, progress); + + pthread_mutex_lock(&p->progress_mutex); + while (atomic_load_explicit(&progress[field], memory_order_relaxed) < n) + pthread_cond_wait(&p->progress_cond, &p->progress_mutex); + pthread_mutex_unlock(&p->progress_mutex); +} + +void ff_thread_finish_setup(AVCodecContext *avctx) { + PerThreadContext *p = avctx->internal->thread_ctx; + + if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; + + if (avctx->hwaccel && !p->hwaccel_serializing) { + pthread_mutex_lock(&p->parent->hwaccel_mutex); + p->hwaccel_serializing = 1; + } + + /* this assumes that no hwaccel calls happen before ff_thread_finish_setup() */ + if (avctx->hwaccel && + !(avctx->hwaccel->caps_internal & HWACCEL_CAP_ASYNC_SAFE)) { + p->async_serializing = 1; + + async_lock(p->parent); + } + + pthread_mutex_lock(&p->progress_mutex); + if(atomic_load(&p->state) == STATE_SETUP_FINISHED){ + av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); + } + + atomic_store(&p->state, STATE_SETUP_FINISHED); + + pthread_cond_broadcast(&p->progress_cond); + pthread_mutex_unlock(&p->progress_mutex); +} + +/// Waits for all threads to finish. +static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count) +{ + int i; + + async_unlock(fctx); + + for (i = 0; i < thread_count; i++) { + PerThreadContext *p = &fctx->threads[i]; + + if (atomic_load(&p->state) != STATE_INPUT_READY) { + pthread_mutex_lock(&p->progress_mutex); + while (atomic_load(&p->state) != STATE_INPUT_READY) + pthread_cond_wait(&p->output_cond, &p->progress_mutex); + pthread_mutex_unlock(&p->progress_mutex); + } + p->got_frame = 0; + } + + async_lock(fctx); +} + +void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) +{ + FrameThreadContext *fctx = avctx->internal->thread_ctx; + const AVCodec *codec = avctx->codec; + int i; + + park_frame_worker_threads(fctx, thread_count); + + if (fctx->prev_thread && fctx->prev_thread != fctx->threads) + if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) { + av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n"); + fctx->prev_thread->avctx->internal->is_copy = fctx->threads->avctx->internal->is_copy; + fctx->threads->avctx->internal->is_copy = 1; + } + + for (i = 0; i < thread_count; i++) { + PerThreadContext *p = &fctx->threads[i]; + + pthread_mutex_lock(&p->mutex); + p->die = 1; + pthread_cond_signal(&p->input_cond); + pthread_mutex_unlock(&p->mutex); + + if (p->thread_init) + pthread_join(p->thread, NULL); + p->thread_init=0; + + if (codec->close && p->avctx) + codec->close(p->avctx); + + release_delayed_buffers(p); + av_frame_free(&p->frame); + } + + for (i = 0; i < thread_count; i++) { + PerThreadContext *p = &fctx->threads[i]; + + pthread_mutex_destroy(&p->mutex); + pthread_mutex_destroy(&p->progress_mutex); + pthread_cond_destroy(&p->input_cond); + pthread_cond_destroy(&p->progress_cond); + pthread_cond_destroy(&p->output_cond); + av_packet_unref(&p->avpkt); + av_freep(&p->released_buffers); + + if (i && p->avctx) { + av_freep(&p->avctx->priv_data); + av_freep(&p->avctx->slice_offset); + } + + if (p->avctx) { + av_freep(&p->avctx->internal); + av_buffer_unref(&p->avctx->hw_frames_ctx); + } + + av_freep(&p->avctx); + } + + av_freep(&fctx->threads); + pthread_mutex_destroy(&fctx->buffer_mutex); + pthread_mutex_destroy(&fctx->hwaccel_mutex); + pthread_mutex_destroy(&fctx->async_mutex); + pthread_cond_destroy(&fctx->async_cond); + + av_freep(&avctx->internal->thread_ctx); + + if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) + av_opt_free(avctx->priv_data); + avctx->codec = NULL; +} + +int ff_frame_thread_init(AVCodecContext *avctx) +{ + int thread_count = avctx->thread_count; + const AVCodec *codec = avctx->codec; + AVCodecContext *src = avctx; + FrameThreadContext *fctx; + int i, err = 0; + + if (!thread_count) { + int nb_cpus = av_cpu_count(); +#if FF_API_DEBUG_MV + if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv) + nb_cpus = 1; +#endif + // use number of cores + 1 as thread count if there is more than one + if (nb_cpus > 1) + thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); + else + thread_count = avctx->thread_count = 1; + } + + if (thread_count <= 1) { + avctx->active_thread_type = 0; + return 0; + } + + avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext)); + if (!fctx) + return AVERROR(ENOMEM); + + fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); + if (!fctx->threads) { + av_freep(&avctx->internal->thread_ctx); + return AVERROR(ENOMEM); + } + + pthread_mutex_init(&fctx->buffer_mutex, NULL); + pthread_mutex_init(&fctx->hwaccel_mutex, NULL); + pthread_mutex_init(&fctx->async_mutex, NULL); + pthread_cond_init(&fctx->async_cond, NULL); + + fctx->async_lock = 1; + fctx->delaying = 1; + + for (i = 0; i < thread_count; i++) { + AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); + PerThreadContext *p = &fctx->threads[i]; + + pthread_mutex_init(&p->mutex, NULL); + pthread_mutex_init(&p->progress_mutex, NULL); + pthread_cond_init(&p->input_cond, NULL); + pthread_cond_init(&p->progress_cond, NULL); + pthread_cond_init(&p->output_cond, NULL); + + p->frame = av_frame_alloc(); + if (!p->frame) { + av_freep(©); + err = AVERROR(ENOMEM); + goto error; + } + + p->parent = fctx; + p->avctx = copy; + + if (!copy) { + err = AVERROR(ENOMEM); + goto error; + } + + *copy = *src; + + copy->internal = av_malloc(sizeof(AVCodecInternal)); + if (!copy->internal) { + copy->priv_data = NULL; + err = AVERROR(ENOMEM); + goto error; + } + *copy->internal = *src->internal; + copy->internal->thread_ctx = p; + copy->internal->last_pkt_props = &p->avpkt; + + if (!i) { + src = copy; + + if (codec->init) + err = codec->init(copy); + + update_context_from_thread(avctx, copy, 1); + } else { + copy->priv_data = av_malloc(codec->priv_data_size); + if (!copy->priv_data) { + err = AVERROR(ENOMEM); + goto error; + } + memcpy(copy->priv_data, src->priv_data, codec->priv_data_size); + copy->internal->is_copy = 1; + + if (codec->init_thread_copy) + err = codec->init_thread_copy(copy); + } + + if (err) goto error; + + atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); + + err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); + p->thread_init= !err; + if(!p->thread_init) + goto error; + } + + return 0; + +error: + ff_frame_thread_free(avctx, i+1); + + return err; +} + +void ff_thread_flush(AVCodecContext *avctx) +{ + int i; + FrameThreadContext *fctx = avctx->internal->thread_ctx; + + if (!fctx) return; + + park_frame_worker_threads(fctx, avctx->thread_count); + if (fctx->prev_thread) { + if (fctx->prev_thread != &fctx->threads[0]) + update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0); + } + + fctx->next_decoding = fctx->next_finished = 0; + fctx->delaying = 1; + fctx->prev_thread = NULL; + for (i = 0; i < avctx->thread_count; i++) { + PerThreadContext *p = &fctx->threads[i]; + // Make sure decode flush calls with size=0 won't return old frames + p->got_frame = 0; + av_frame_unref(p->frame); + p->result = 0; + + release_delayed_buffers(p); + + if (avctx->codec->flush) + avctx->codec->flush(p->avctx); + } +} + +int ff_thread_can_start_frame(AVCodecContext *avctx) +{ + PerThreadContext *p = avctx->internal->thread_ctx; + if ((avctx->active_thread_type&FF_THREAD_FRAME) && atomic_load(&p->state) != STATE_SETTING_UP && + (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { + return 0; + } + return 1; +} + +static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags) +{ + PerThreadContext *p = avctx->internal->thread_ctx; + int err; + + f->owner[0] = f->owner[1] = avctx; + + if (!(avctx->active_thread_type & FF_THREAD_FRAME)) + return ff_get_buffer(avctx, f->f, flags); + + if (atomic_load(&p->state) != STATE_SETTING_UP && + (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); + return -1; + } + + if (avctx->internal->allocate_progress) { + atomic_int *progress; + f->progress = av_buffer_alloc(2 * sizeof(*progress)); + if (!f->progress) { + return AVERROR(ENOMEM); + } + progress = (atomic_int*)f->progress->data; + + atomic_init(&progress[0], -1); + atomic_init(&progress[1], -1); + } + + pthread_mutex_lock(&p->parent->buffer_mutex); + if (THREAD_SAFE_CALLBACKS(avctx)) { + err = ff_get_buffer(avctx, f->f, flags); + } else { + pthread_mutex_lock(&p->progress_mutex); + p->requested_frame = f->f; + p->requested_flags = flags; + atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release); + pthread_cond_broadcast(&p->progress_cond); + + while (atomic_load(&p->state) != STATE_SETTING_UP) + pthread_cond_wait(&p->progress_cond, &p->progress_mutex); + + err = p->result; + + pthread_mutex_unlock(&p->progress_mutex); + + } + if (!THREAD_SAFE_CALLBACKS(avctx) && !avctx->codec->update_thread_context) + ff_thread_finish_setup(avctx); + if (err) + av_buffer_unref(&f->progress); + + pthread_mutex_unlock(&p->parent->buffer_mutex); + + return err; +} + +enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) +{ + enum AVPixelFormat res; + PerThreadContext *p = avctx->internal->thread_ctx; + if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks || + avctx->get_format == avcodec_default_get_format) + return ff_get_format(avctx, fmt); + if (atomic_load(&p->state) != STATE_SETTING_UP) { + av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n"); + return -1; + } + pthread_mutex_lock(&p->progress_mutex); + p->available_formats = fmt; + atomic_store(&p->state, STATE_GET_FORMAT); + pthread_cond_broadcast(&p->progress_cond); + + while (atomic_load(&p->state) != STATE_SETTING_UP) + pthread_cond_wait(&p->progress_cond, &p->progress_mutex); + + res = p->result_format; + + pthread_mutex_unlock(&p->progress_mutex); + + return res; +} + +int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) +{ + int ret = thread_get_buffer_internal(avctx, f, flags); + if (ret < 0) + av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n"); + return ret; +} + +void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) +{ + PerThreadContext *p = avctx->internal->thread_ctx; + FrameThreadContext *fctx; + AVFrame *dst, *tmp; + int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) || + THREAD_SAFE_CALLBACKS(avctx); + + if (!f->f || !f->f->buf[0]) + return; + + if (avctx->debug & FF_DEBUG_BUFFERS) + av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f); + + av_buffer_unref(&f->progress); + f->owner[0] = f->owner[1] = NULL; + + if (can_direct_free) { + av_frame_unref(f->f); + return; + } + + fctx = p->parent; + pthread_mutex_lock(&fctx->buffer_mutex); + + if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers)) + goto fail; + tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated, + (p->num_released_buffers + 1) * + sizeof(*p->released_buffers)); + if (!tmp) + goto fail; + p->released_buffers = tmp; + + dst = &p->released_buffers[p->num_released_buffers]; + av_frame_move_ref(dst, f->f); + + p->num_released_buffers++; + +fail: + pthread_mutex_unlock(&fctx->buffer_mutex); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_internal.h new file mode 100644 index 000000000..d2115cbba --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_internal.h @@ -0,0 +1,34 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_PTHREAD_INTERNAL_H +#define AVCODEC_PTHREAD_INTERNAL_H + +#include "avcodec.h" + +/* H.264 slice threading seems to be buggy with more than 16 threads, + * limit the number of threads to 16 for automatic detection */ +#define MAX_AUTO_THREADS 16 + +int ff_slice_thread_init(AVCodecContext *avctx); +void ff_slice_thread_free(AVCodecContext *avctx); + +int ff_frame_thread_init(AVCodecContext *avctx); +void ff_frame_thread_free(AVCodecContext *avctx, int thread_count); + +#endif // AVCODEC_PTHREAD_INTERNAL_H diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_slice.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_slice.c new file mode 100644 index 000000000..77cfe3c9f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/pthread_slice.c @@ -0,0 +1,242 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Slice multithreading support functions + * @see doc/multithreading.txt + */ + +#include "config.h" + +#include "avcodec.h" +#include "internal.h" +#include "pthread_internal.h" +#include "thread.h" + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/thread.h" +#include "libavutil/slicethread.h" + +typedef int (action_func)(AVCodecContext *c, void *arg); +typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); +typedef int (main_func)(AVCodecContext *c); + +typedef struct SliceThreadContext { + AVSliceThread *thread; + action_func *func; + action_func2 *func2; + main_func *mainfunc; + void *args; + int *rets; + int job_size; + + int *entries; + int entries_count; + int thread_count; + pthread_cond_t *progress_cond; + pthread_mutex_t *progress_mutex; +} SliceThreadContext; + +static void main_function(void *priv) { + AVCodecContext *avctx = priv; + SliceThreadContext *c = avctx->internal->thread_ctx; + c->mainfunc(avctx); +} + +static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads) +{ + AVCodecContext *avctx = priv; + SliceThreadContext *c = avctx->internal->thread_ctx; + int ret; + + ret = c->func ? c->func(avctx, (char *)c->args + c->job_size * jobnr) + : c->func2(avctx, c->args, jobnr, threadnr); + if (c->rets) + c->rets[jobnr] = ret; +} + +void ff_slice_thread_free(AVCodecContext *avctx) +{ + SliceThreadContext *c = avctx->internal->thread_ctx; + int i; + + avpriv_slicethread_free(&c->thread); + + for (i = 0; i < c->thread_count; i++) { + pthread_mutex_destroy(&c->progress_mutex[i]); + pthread_cond_destroy(&c->progress_cond[i]); + } + + av_freep(&c->entries); + av_freep(&c->progress_mutex); + av_freep(&c->progress_cond); + av_freep(&avctx->internal->thread_ctx); +} + +static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size) +{ + SliceThreadContext *c = avctx->internal->thread_ctx; + + if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1) + return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size); + + if (job_count <= 0) + return 0; + + c->job_size = job_size; + c->args = arg; + c->func = func; + c->rets = ret; + + avpriv_slicethread_execute(c->thread, job_count, !!c->mainfunc ); + return 0; +} + +static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count) +{ + SliceThreadContext *c = avctx->internal->thread_ctx; + c->func2 = func2; + return thread_execute(avctx, NULL, arg, ret, job_count, 0); +} + +int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, action_func2* func2, main_func *mainfunc, void *arg, int *ret, int job_count) +{ + SliceThreadContext *c = avctx->internal->thread_ctx; + c->func2 = func2; + c->mainfunc = mainfunc; + return thread_execute(avctx, NULL, arg, ret, job_count, 0); +} + +int ff_slice_thread_init(AVCodecContext *avctx) +{ + SliceThreadContext *c; + int thread_count = avctx->thread_count; + static void (*mainfunc)(void *); + + // We cannot do this in the encoder init as the threads are created before + if (av_codec_is_encoder(avctx->codec) && + avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && + avctx->height > 2800) + thread_count = avctx->thread_count = 1; + + if (!thread_count) { + int nb_cpus = av_cpu_count(); + if (avctx->height) + nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16); + // use number of cores + 1 as thread count if there is more than one + if (nb_cpus > 1) + thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); + else + thread_count = avctx->thread_count = 1; + } + + if (thread_count <= 1) { + avctx->active_thread_type = 0; + return 0; + } + + avctx->internal->thread_ctx = c = av_mallocz(sizeof(*c)); + mainfunc = avctx->codec->caps_internal & FF_CODEC_CAP_SLICE_THREAD_HAS_MF ? &main_function : NULL; + if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, mainfunc, thread_count)) <= 1) { + if (c) + avpriv_slicethread_free(&c->thread); + av_freep(&avctx->internal->thread_ctx); + avctx->thread_count = 1; + avctx->active_thread_type = 0; + return 0; + } + avctx->thread_count = thread_count; + + avctx->execute = thread_execute; + avctx->execute2 = thread_execute2; + return 0; +} + +void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n) +{ + SliceThreadContext *p = avctx->internal->thread_ctx; + int *entries = p->entries; + + pthread_mutex_lock(&p->progress_mutex[thread]); + entries[field] +=n; + pthread_cond_signal(&p->progress_cond[thread]); + pthread_mutex_unlock(&p->progress_mutex[thread]); +} + +void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift) +{ + SliceThreadContext *p = avctx->internal->thread_ctx; + int *entries = p->entries; + + if (!entries || !field) return; + + thread = thread ? thread - 1 : p->thread_count - 1; + + pthread_mutex_lock(&p->progress_mutex[thread]); + while ((entries[field - 1] - entries[field]) < shift){ + pthread_cond_wait(&p->progress_cond[thread], &p->progress_mutex[thread]); + } + pthread_mutex_unlock(&p->progress_mutex[thread]); +} + +int ff_alloc_entries(AVCodecContext *avctx, int count) +{ + int i; + + if (avctx->active_thread_type & FF_THREAD_SLICE) { + SliceThreadContext *p = avctx->internal->thread_ctx; + + if (p->entries) { + av_assert0(p->thread_count == avctx->thread_count); + av_freep(&p->entries); + } + + p->thread_count = avctx->thread_count; + p->entries = av_mallocz_array(count, sizeof(int)); + + if (!p->progress_mutex) { + p->progress_mutex = av_malloc_array(p->thread_count, sizeof(pthread_mutex_t)); + p->progress_cond = av_malloc_array(p->thread_count, sizeof(pthread_cond_t)); + } + + if (!p->entries || !p->progress_mutex || !p->progress_cond) { + av_freep(&p->entries); + av_freep(&p->progress_mutex); + av_freep(&p->progress_cond); + return AVERROR(ENOMEM); + } + p->entries_count = count; + + for (i = 0; i < p->thread_count; i++) { + pthread_mutex_init(&p->progress_mutex[i], NULL); + pthread_cond_init(&p->progress_cond[i], NULL); + } + } + + return 0; +} + +void ff_reset_entries(AVCodecContext *avctx) +{ + SliceThreadContext *p = avctx->internal->thread_ctx; + memset(p->entries, 0, p->entries_count * sizeof(int)); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/put_bits.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/put_bits.h new file mode 100644 index 000000000..1ceb1cc76 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/put_bits.h @@ -0,0 +1,365 @@ +/* + * copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * bitstream writer API + */ + +#ifndef AVCODEC_PUT_BITS_H +#define AVCODEC_PUT_BITS_H + +#include +#include + +#include "libavutil/intreadwrite.h" +#include "libavutil/avassert.h" + +typedef struct PutBitContext { + uint32_t bit_buf; + int bit_left; + uint8_t *buf, *buf_ptr, *buf_end; + int size_in_bits; +} PutBitContext; + +/** + * Initialize the PutBitContext s. + * + * @param buffer the buffer where to put bits + * @param buffer_size the size in bytes of buffer + */ +static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, + int buffer_size) +{ + if (buffer_size < 0) { + buffer_size = 0; + buffer = NULL; + } + + s->size_in_bits = 8 * buffer_size; + s->buf = buffer; + s->buf_end = s->buf + buffer_size; + s->buf_ptr = s->buf; + s->bit_left = 32; + s->bit_buf = 0; +} + +/** + * Rebase the bit writer onto a reallocated buffer. + * + * @param buffer the buffer where to put bits + * @param buffer_size the size in bytes of buffer, + * must be larger than the previous size + */ +static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer, + int buffer_size) +{ + av_assert0(8*buffer_size > s->size_in_bits); + + s->buf_end = buffer + buffer_size; + s->buf_ptr = buffer + (s->buf_ptr - s->buf); + s->buf = buffer; + s->size_in_bits = 8 * buffer_size; +} + +/** + * @return the total number of bits written to the bitstream. + */ +static inline int put_bits_count(PutBitContext *s) +{ + return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; +} + +/** + * @return the number of bits available in the bitstream. + */ +static inline int put_bits_left(PutBitContext* s) +{ + return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; +} + +/** + * Pad the end of the output stream with zeros. + */ +static inline void flush_put_bits(PutBitContext *s) +{ +#ifndef BITSTREAM_WRITER_LE + if (s->bit_left < 32) + s->bit_buf <<= s->bit_left; +#endif + while (s->bit_left < 32) { + av_assert0(s->buf_ptr < s->buf_end); +#ifdef BITSTREAM_WRITER_LE + *s->buf_ptr++ = s->bit_buf; + s->bit_buf >>= 8; +#else + *s->buf_ptr++ = s->bit_buf >> 24; + s->bit_buf <<= 8; +#endif + s->bit_left += 8; + } + s->bit_left = 32; + s->bit_buf = 0; +} + +static inline void flush_put_bits_le(PutBitContext *s) +{ + while (s->bit_left < 32) { + av_assert0(s->buf_ptr < s->buf_end); + *s->buf_ptr++ = s->bit_buf; + s->bit_buf >>= 8; + s->bit_left += 8; + } + s->bit_left = 32; + s->bit_buf = 0; +} + +#ifdef BITSTREAM_WRITER_LE +#define avpriv_align_put_bits align_put_bits_unsupported_here +#define avpriv_put_string ff_put_string_unsupported_here +#define avpriv_copy_bits avpriv_copy_bits_unsupported_here +#else +/** + * Pad the bitstream with zeros up to the next byte boundary. + */ +void avpriv_align_put_bits(PutBitContext *s); + +/** + * Put the string string in the bitstream. + * + * @param terminate_string 0-terminates the written string if value is 1 + */ +void avpriv_put_string(PutBitContext *pb, const char *string, + int terminate_string); + +/** + * Copy the content of src to the bitstream. + * + * @param length the number of bits of src to copy + */ +void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length); +#endif + +/** + * Write up to 31 bits into a bitstream. + * Use put_bits32 to write 32 bits. + */ +static inline void put_bits(PutBitContext *s, int n, unsigned int value) +{ + unsigned int bit_buf; + int bit_left; + + av_assert2(n <= 31 && value < (1U << n)); + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + + /* XXX: optimize */ +#ifdef BITSTREAM_WRITER_LE + bit_buf |= value << (32 - bit_left); + if (n >= bit_left) { + if (3 < s->buf_end - s->buf_ptr) { + AV_WL32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = value >> bit_left; + bit_left += 32; + } + bit_left -= n; +#else + if (n < bit_left) { + bit_buf = (bit_buf << n) | value; + bit_left -= n; + } else { + bit_buf <<= bit_left; + bit_buf |= value >> (n - bit_left); + if (3 < s->buf_end - s->buf_ptr) { + AV_WB32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_left += 32 - n; + bit_buf = value; + } +#endif + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} + +static inline void put_bits_le(PutBitContext *s, int n, unsigned int value) +{ + unsigned int bit_buf; + int bit_left; + + av_assert2(n <= 31 && value < (1U << n)); + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + + bit_buf |= value << (32 - bit_left); + if (n >= bit_left) { + if (3 < s->buf_end - s->buf_ptr) { + AV_WL32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = value >> bit_left; + bit_left += 32; + } + bit_left -= n; + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} + +static inline void put_sbits(PutBitContext *pb, int n, int32_t value) +{ + av_assert2(n >= 0 && n <= 31); + + put_bits(pb, n, av_mod_uintp2(value, n)); +} + +/** + * Write exactly 32 bits into a bitstream. + */ +static void av_unused put_bits32(PutBitContext *s, uint32_t value) +{ + unsigned int bit_buf; + int bit_left; + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + +#ifdef BITSTREAM_WRITER_LE + bit_buf |= value << (32 - bit_left); + if (3 < s->buf_end - s->buf_ptr) { + AV_WL32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = (uint64_t)value >> bit_left; +#else + bit_buf = (uint64_t)bit_buf << bit_left; + bit_buf |= value >> (32 - bit_left); + if (3 < s->buf_end - s->buf_ptr) { + AV_WB32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } + bit_buf = value; +#endif + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} + +/** + * Write up to 64 bits into a bitstream. + */ +static inline void put_bits64(PutBitContext *s, int n, uint64_t value) +{ + av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n))); + + if (n < 32) + put_bits(s, n, value); + else if (n == 32) + put_bits32(s, value); + else if (n < 64) { + uint32_t lo = value & 0xffffffff; + uint32_t hi = value >> 32; +#ifdef BITSTREAM_WRITER_LE + put_bits32(s, lo); + put_bits(s, n - 32, hi); +#else + put_bits(s, n - 32, hi); + put_bits32(s, lo); +#endif + } else { + uint32_t lo = value & 0xffffffff; + uint32_t hi = value >> 32; +#ifdef BITSTREAM_WRITER_LE + put_bits32(s, lo); + put_bits32(s, hi); +#else + put_bits32(s, hi); + put_bits32(s, lo); +#endif + + } +} + +/** + * Return the pointer to the byte where the bitstream writer will put + * the next bit. + */ +static inline uint8_t *put_bits_ptr(PutBitContext *s) +{ + return s->buf_ptr; +} + +/** + * Skip the given number of bytes. + * PutBitContext must be flushed & aligned to a byte boundary before calling this. + */ +static inline void skip_put_bytes(PutBitContext *s, int n) +{ + av_assert2((put_bits_count(s) & 7) == 0); + av_assert2(s->bit_left == 32); + av_assert0(n <= s->buf_end - s->buf_ptr); + s->buf_ptr += n; +} + +/** + * Skip the given number of bits. + * Must only be used if the actual values in the bitstream do not matter. + * If n is 0 the behavior is undefined. + */ +static inline void skip_put_bits(PutBitContext *s, int n) +{ + s->bit_left -= n; + s->buf_ptr -= 4 * (s->bit_left >> 5); + s->bit_left &= 31; +} + +/** + * Change the end of the buffer. + * + * @param size the new size in bytes of the buffer where to put bits + */ +static inline void set_put_bits_buffer_size(PutBitContext *s, int size) +{ + av_assert0(size <= INT_MAX/8 - 32); + s->buf_end = s->buf + size; + s->size_in_bits = 8*size; +} + +#endif /* AVCODEC_PUT_BITS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qpeldsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qpeldsp.c new file mode 100644 index 000000000..6e52b3365 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qpeldsp.c @@ -0,0 +1,816 @@ +/* + * quarterpel DSP functions + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * quarterpel DSP functions + */ + +#include +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "copy_block.h" +#include "qpeldsp.h" +#include "diracdsp.h" + +#define BIT_DEPTH 8 +#include "hpel_template.c" +#include "pel_template.c" +#include "qpel_template.c" + +#define QPEL_MC(r, OPNAME, RND, OP) \ +static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, const uint8_t *src, \ + int dstStride, int srcStride, \ + int h) \ +{ \ + const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \ + int i; \ + \ + for (i = 0; i < h; i++) { \ + OP(dst[0], (src[0] + src[1]) * 20 - (src[0] + src[2]) * 6 + (src[1] + src[3]) * 3 - (src[2] + src[4])); \ + OP(dst[1], (src[1] + src[2]) * 20 - (src[0] + src[3]) * 6 + (src[0] + src[4]) * 3 - (src[1] + src[5])); \ + OP(dst[2], (src[2] + src[3]) * 20 - (src[1] + src[4]) * 6 + (src[0] + src[5]) * 3 - (src[0] + src[6])); \ + OP(dst[3], (src[3] + src[4]) * 20 - (src[2] + src[5]) * 6 + (src[1] + src[6]) * 3 - (src[0] + src[7])); \ + OP(dst[4], (src[4] + src[5]) * 20 - (src[3] + src[6]) * 6 + (src[2] + src[7]) * 3 - (src[1] + src[8])); \ + OP(dst[5], (src[5] + src[6]) * 20 - (src[4] + src[7]) * 6 + (src[3] + src[8]) * 3 - (src[2] + src[8])); \ + OP(dst[6], (src[6] + src[7]) * 20 - (src[5] + src[8]) * 6 + (src[4] + src[8]) * 3 - (src[3] + src[7])); \ + OP(dst[7], (src[7] + src[8]) * 20 - (src[6] + src[8]) * 6 + (src[5] + src[7]) * 3 - (src[4] + src[6])); \ + dst += dstStride; \ + src += srcStride; \ + } \ +} \ + \ +static void OPNAME ## mpeg4_qpel8_v_lowpass(uint8_t *dst, const uint8_t *src, \ + int dstStride, int srcStride) \ +{ \ + const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \ + const int w = 8; \ + int i; \ + \ + for (i = 0; i < w; i++) { \ + const int src0 = src[0 * srcStride]; \ + const int src1 = src[1 * srcStride]; \ + const int src2 = src[2 * srcStride]; \ + const int src3 = src[3 * srcStride]; \ + const int src4 = src[4 * srcStride]; \ + const int src5 = src[5 * srcStride]; \ + const int src6 = src[6 * srcStride]; \ + const int src7 = src[7 * srcStride]; \ + const int src8 = src[8 * srcStride]; \ + OP(dst[0 * dstStride], (src0 + src1) * 20 - (src0 + src2) * 6 + (src1 + src3) * 3 - (src2 + src4)); \ + OP(dst[1 * dstStride], (src1 + src2) * 20 - (src0 + src3) * 6 + (src0 + src4) * 3 - (src1 + src5)); \ + OP(dst[2 * dstStride], (src2 + src3) * 20 - (src1 + src4) * 6 + (src0 + src5) * 3 - (src0 + src6)); \ + OP(dst[3 * dstStride], (src3 + src4) * 20 - (src2 + src5) * 6 + (src1 + src6) * 3 - (src0 + src7)); \ + OP(dst[4 * dstStride], (src4 + src5) * 20 - (src3 + src6) * 6 + (src2 + src7) * 3 - (src1 + src8)); \ + OP(dst[5 * dstStride], (src5 + src6) * 20 - (src4 + src7) * 6 + (src3 + src8) * 3 - (src2 + src8)); \ + OP(dst[6 * dstStride], (src6 + src7) * 20 - (src5 + src8) * 6 + (src4 + src8) * 3 - (src3 + src7)); \ + OP(dst[7 * dstStride], (src7 + src8) * 20 - (src6 + src8) * 6 + (src5 + src7) * 3 - (src4 + src6)); \ + dst++; \ + src++; \ + } \ +} \ + \ +static void OPNAME ## mpeg4_qpel16_h_lowpass(uint8_t *dst, \ + const uint8_t *src, \ + int dstStride, int srcStride, \ + int h) \ +{ \ + const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \ + int i; \ + \ + for (i = 0; i < h; i++) { \ + OP(dst[0], (src[0] + src[1]) * 20 - (src[0] + src[2]) * 6 + (src[1] + src[3]) * 3 - (src[2] + src[4])); \ + OP(dst[1], (src[1] + src[2]) * 20 - (src[0] + src[3]) * 6 + (src[0] + src[4]) * 3 - (src[1] + src[5])); \ + OP(dst[2], (src[2] + src[3]) * 20 - (src[1] + src[4]) * 6 + (src[0] + src[5]) * 3 - (src[0] + src[6])); \ + OP(dst[3], (src[3] + src[4]) * 20 - (src[2] + src[5]) * 6 + (src[1] + src[6]) * 3 - (src[0] + src[7])); \ + OP(dst[4], (src[4] + src[5]) * 20 - (src[3] + src[6]) * 6 + (src[2] + src[7]) * 3 - (src[1] + src[8])); \ + OP(dst[5], (src[5] + src[6]) * 20 - (src[4] + src[7]) * 6 + (src[3] + src[8]) * 3 - (src[2] + src[9])); \ + OP(dst[6], (src[6] + src[7]) * 20 - (src[5] + src[8]) * 6 + (src[4] + src[9]) * 3 - (src[3] + src[10])); \ + OP(dst[7], (src[7] + src[8]) * 20 - (src[6] + src[9]) * 6 + (src[5] + src[10]) * 3 - (src[4] + src[11])); \ + OP(dst[8], (src[8] + src[9]) * 20 - (src[7] + src[10]) * 6 + (src[6] + src[11]) * 3 - (src[5] + src[12])); \ + OP(dst[9], (src[9] + src[10]) * 20 - (src[8] + src[11]) * 6 + (src[7] + src[12]) * 3 - (src[6] + src[13])); \ + OP(dst[10], (src[10] + src[11]) * 20 - (src[9] + src[12]) * 6 + (src[8] + src[13]) * 3 - (src[7] + src[14])); \ + OP(dst[11], (src[11] + src[12]) * 20 - (src[10] + src[13]) * 6 + (src[9] + src[14]) * 3 - (src[8] + src[15])); \ + OP(dst[12], (src[12] + src[13]) * 20 - (src[11] + src[14]) * 6 + (src[10] + src[15]) * 3 - (src[9] + src[16])); \ + OP(dst[13], (src[13] + src[14]) * 20 - (src[12] + src[15]) * 6 + (src[11] + src[16]) * 3 - (src[10] + src[16])); \ + OP(dst[14], (src[14] + src[15]) * 20 - (src[13] + src[16]) * 6 + (src[12] + src[16]) * 3 - (src[11] + src[15])); \ + OP(dst[15], (src[15] + src[16]) * 20 - (src[14] + src[16]) * 6 + (src[13] + src[15]) * 3 - (src[12] + src[14])); \ + dst += dstStride; \ + src += srcStride; \ + } \ +} \ + \ +static void OPNAME ## mpeg4_qpel16_v_lowpass(uint8_t *dst, \ + const uint8_t *src, \ + int dstStride, int srcStride) \ +{ \ + const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \ + const int w = 16; \ + int i; \ + \ + for (i = 0; i < w; i++) { \ + const int src0 = src[0 * srcStride]; \ + const int src1 = src[1 * srcStride]; \ + const int src2 = src[2 * srcStride]; \ + const int src3 = src[3 * srcStride]; \ + const int src4 = src[4 * srcStride]; \ + const int src5 = src[5 * srcStride]; \ + const int src6 = src[6 * srcStride]; \ + const int src7 = src[7 * srcStride]; \ + const int src8 = src[8 * srcStride]; \ + const int src9 = src[9 * srcStride]; \ + const int src10 = src[10 * srcStride]; \ + const int src11 = src[11 * srcStride]; \ + const int src12 = src[12 * srcStride]; \ + const int src13 = src[13 * srcStride]; \ + const int src14 = src[14 * srcStride]; \ + const int src15 = src[15 * srcStride]; \ + const int src16 = src[16 * srcStride]; \ + OP(dst[0 * dstStride], (src0 + src1) * 20 - (src0 + src2) * 6 + (src1 + src3) * 3 - (src2 + src4)); \ + OP(dst[1 * dstStride], (src1 + src2) * 20 - (src0 + src3) * 6 + (src0 + src4) * 3 - (src1 + src5)); \ + OP(dst[2 * dstStride], (src2 + src3) * 20 - (src1 + src4) * 6 + (src0 + src5) * 3 - (src0 + src6)); \ + OP(dst[3 * dstStride], (src3 + src4) * 20 - (src2 + src5) * 6 + (src1 + src6) * 3 - (src0 + src7)); \ + OP(dst[4 * dstStride], (src4 + src5) * 20 - (src3 + src6) * 6 + (src2 + src7) * 3 - (src1 + src8)); \ + OP(dst[5 * dstStride], (src5 + src6) * 20 - (src4 + src7) * 6 + (src3 + src8) * 3 - (src2 + src9)); \ + OP(dst[6 * dstStride], (src6 + src7) * 20 - (src5 + src8) * 6 + (src4 + src9) * 3 - (src3 + src10)); \ + OP(dst[7 * dstStride], (src7 + src8) * 20 - (src6 + src9) * 6 + (src5 + src10) * 3 - (src4 + src11)); \ + OP(dst[8 * dstStride], (src8 + src9) * 20 - (src7 + src10) * 6 + (src6 + src11) * 3 - (src5 + src12)); \ + OP(dst[9 * dstStride], (src9 + src10) * 20 - (src8 + src11) * 6 + (src7 + src12) * 3 - (src6 + src13)); \ + OP(dst[10 * dstStride], (src10 + src11) * 20 - (src9 + src12) * 6 + (src8 + src13) * 3 - (src7 + src14)); \ + OP(dst[11 * dstStride], (src11 + src12) * 20 - (src10 + src13) * 6 + (src9 + src14) * 3 - (src8 + src15)); \ + OP(dst[12 * dstStride], (src12 + src13) * 20 - (src11 + src14) * 6 + (src10 + src15) * 3 - (src9 + src16)); \ + OP(dst[13 * dstStride], (src13 + src14) * 20 - (src12 + src15) * 6 + (src11 + src16) * 3 - (src10 + src16)); \ + OP(dst[14 * dstStride], (src14 + src15) * 20 - (src13 + src16) * 6 + (src12 + src16) * 3 - (src11 + src15)); \ + OP(dst[15 * dstStride], (src15 + src16) * 20 - (src14 + src16) * 6 + (src13 + src15) * 3 - (src12 + src14)); \ + dst++; \ + src++; \ + } \ +} \ + \ +static void OPNAME ## qpel8_mc10_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t half[64]; \ + \ + put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8); \ + OPNAME ## pixels8_l2_8(dst, src, half, stride, stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc20_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + OPNAME ## mpeg4_qpel8_h_lowpass(dst, src, stride, stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc30_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t half[64]; \ + \ + put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8); \ + OPNAME ## pixels8_l2_8(dst, src + 1, half, stride, stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc01_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t half[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16); \ + OPNAME ## pixels8_l2_8(dst, full, half, stride, 16, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc02_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + OPNAME ## mpeg4_qpel8_v_lowpass(dst, full, stride, 16); \ +} \ + \ +static void OPNAME ## qpel8_mc03_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t half[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16); \ + OPNAME ## pixels8_l2_8(dst, full + 16, half, stride, 16, 8, 8); \ +} \ + \ +void ff_ ## OPNAME ## qpel8_mc11_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfV[64]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfV, full, 8, 16); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l4_8(dst, full, halfH, halfV, halfHV, \ + stride, 16, 8, 8, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc11_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## pixels8_l2_8(halfH, halfH, full, 8, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l2_8(dst, halfH, halfHV, stride, 8, 8, 8); \ +} \ + \ +void ff_ ## OPNAME ## qpel8_mc31_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfV[64]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfV, full + 1, 8, 16); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l4_8(dst, full + 1, halfH, halfV, halfHV, \ + stride, 16, 8, 8, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc31_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## pixels8_l2_8(halfH, halfH, full + 1, 8, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l2_8(dst, halfH, halfHV, stride, 8, 8, 8); \ +} \ + \ +void ff_ ## OPNAME ## qpel8_mc13_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfV[64]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfV, full, 8, 16); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l4_8(dst, full + 16, halfH + 8, halfV, halfHV, \ + stride, 16, 8, 8, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc13_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## pixels8_l2_8(halfH, halfH, full, 8, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l2_8(dst, halfH + 8, halfHV, stride, 8, 8, 8); \ +} \ + \ +void ff_ ## OPNAME ## qpel8_mc33_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfV[64]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfV, full + 1, 8, 16); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l4_8(dst, full + 17, halfH + 8, halfV, halfHV, \ + stride, 16, 8, 8, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc33_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## pixels8_l2_8(halfH, halfH, full + 1, 8, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l2_8(dst, halfH + 8, halfHV, stride, 8, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc21_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t halfH[72]; \ + uint8_t halfHV[64]; \ + \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l2_8(dst, halfH, halfHV, stride, 8, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc23_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t halfH[72]; \ + uint8_t halfHV[64]; \ + \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l2_8(dst, halfH + 8, halfHV, stride, 8, 8, 8); \ +} \ + \ +void ff_ ## OPNAME ## qpel8_mc12_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfV[64]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfV, full, 8, 16); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc12_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## pixels8_l2_8(halfH, halfH, full, 8, 8, 16, 9); \ + OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8); \ +} \ + \ +void ff_ ## OPNAME ## qpel8_mc32_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + uint8_t halfV[64]; \ + uint8_t halfHV[64]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfV, full + 1, 8, 16); \ + put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8); \ + OPNAME ## pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc32_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[16 * 9]; \ + uint8_t halfH[72]; \ + \ + copy_block9(full, src, 16, stride, 9); \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9); \ + put ## RND ## pixels8_l2_8(halfH, halfH, full + 1, 8, 8, 16, 9); \ + OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc22_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t halfH[72]; \ + \ + put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9); \ + OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8); \ +} \ + \ +static void OPNAME ## qpel16_mc10_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t half[256]; \ + \ + put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16); \ + OPNAME ## pixels16_l2_8(dst, src, half, stride, stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc20_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + OPNAME ## mpeg4_qpel16_h_lowpass(dst, src, stride, stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc30_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t half[256]; \ + \ + put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16); \ + OPNAME ## pixels16_l2_8(dst, src + 1, half, stride, stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc01_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t half[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24); \ + OPNAME ## pixels16_l2_8(dst, full, half, stride, 24, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc02_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + OPNAME ## mpeg4_qpel16_v_lowpass(dst, full, stride, 24); \ +} \ + \ +static void OPNAME ## qpel16_mc03_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t half[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24); \ + OPNAME ## pixels16_l2_8(dst, full + 24, half, stride, 24, 16, 16); \ +} \ + \ +void ff_ ## OPNAME ## qpel16_mc11_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfV[256]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfV, full, 16, 24); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l4_8(dst, full, halfH, halfV, halfHV, \ + stride, 24, 16, 16, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc11_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## pixels16_l2_8(halfH, halfH, full, 16, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l2_8(dst, halfH, halfHV, stride, 16, 16, 16); \ +} \ + \ +void ff_ ## OPNAME ## qpel16_mc31_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfV[256]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfV, full + 1, 16, 24); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l4_8(dst, full + 1, halfH, halfV, halfHV, \ + stride, 24, 16, 16, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc31_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## pixels16_l2_8(halfH, halfH, full + 1, 16, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l2_8(dst, halfH, halfHV, stride, 16, 16, 16); \ +} \ + \ +void ff_ ## OPNAME ## qpel16_mc13_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfV[256]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfV, full, 16, 24); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l4_8(dst, full + 24, halfH + 16, halfV, halfHV, \ + stride, 24, 16, 16, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc13_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## pixels16_l2_8(halfH, halfH, full, 16, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l2_8(dst, halfH + 16, halfHV, stride, 16, 16, 16); \ +} \ + \ +void ff_ ## OPNAME ## qpel16_mc33_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfV[256]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfV, full + 1, 16, 24); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l4_8(dst, full + 25, halfH + 16, halfV, halfHV, \ + stride, 24, 16, 16, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc33_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## pixels16_l2_8(halfH, halfH, full + 1, 16, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l2_8(dst, halfH + 16, halfHV, stride, 16, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc21_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t halfH[272]; \ + uint8_t halfHV[256]; \ + \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l2_8(dst, halfH, halfHV, stride, 16, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc23_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t halfH[272]; \ + uint8_t halfHV[256]; \ + \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l2_8(dst, halfH + 16, halfHV, stride, 16, 16, 16); \ +} \ + \ +void ff_ ## OPNAME ## qpel16_mc12_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfV[256]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfV, full, 16, 24); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l2_8(dst, halfV, halfHV, stride, 16, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc12_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## pixels16_l2_8(halfH, halfH, full, 16, 16, 24, 17); \ + OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16); \ +} \ + \ +void ff_ ## OPNAME ## qpel16_mc32_old_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + uint8_t halfV[256]; \ + uint8_t halfHV[256]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfV, full + 1, 16, 24); \ + put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16); \ + OPNAME ## pixels16_l2_8(dst, halfV, halfHV, stride, 16, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc32_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t full[24 * 17]; \ + uint8_t halfH[272]; \ + \ + copy_block17(full, src, 24, stride, 17); \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17); \ + put ## RND ## pixels16_l2_8(halfH, halfH, full + 1, 16, 16, 24, 17); \ + OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc22_c(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint8_t halfH[272]; \ + \ + put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17); \ + OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16); \ +} + +#define op_avg(a, b) a = (((a) + cm[((b) + 16) >> 5] + 1) >> 1) +#define op_put(a, b) a = cm[((b) + 16) >> 5] +#define op_put_no_rnd(a, b) a = cm[((b) + 15) >> 5] + +QPEL_MC(0, put_, _, op_put) +QPEL_MC(1, put_no_rnd_, _no_rnd_, op_put_no_rnd) +QPEL_MC(0, avg_, _, op_avg) + +#undef op_avg +#undef op_put +#undef op_put_no_rnd + +void ff_put_pixels8x8_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) +{ + put_pixels8_8_c(dst, src, stride, 8); +} + +void ff_avg_pixels8x8_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) +{ + avg_pixels8_8_c(dst, src, stride, 8); +} + +void ff_put_pixels16x16_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) +{ + put_pixels16_8_c(dst, src, stride, 16); +} + +void ff_avg_pixels16x16_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) +{ + avg_pixels16_8_c(dst, src, stride, 16); +} + +#define put_qpel8_mc00_c ff_put_pixels8x8_c +#define avg_qpel8_mc00_c ff_avg_pixels8x8_c +#define put_qpel16_mc00_c ff_put_pixels16x16_c +#define avg_qpel16_mc00_c ff_avg_pixels16x16_c +#define put_no_rnd_qpel8_mc00_c ff_put_pixels8x8_c +#define put_no_rnd_qpel16_mc00_c ff_put_pixels16x16_c + +void ff_put_pixels8_l2_8(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dst_stride, int src_stride1, int src_stride2, + int h) +{ + put_pixels8_l2_8(dst, src1, src2, dst_stride, src_stride1, src_stride2, h); + +} + +#if CONFIG_DIRAC_DECODER +#define DIRAC_MC(OPNAME)\ +void ff_ ## OPNAME ## _dirac_pixels8_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_8_c(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_8_c(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_8_c(dst , src[0] , stride, h);\ + OPNAME ## _pixels16_8_c(dst+16, src[0]+16, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels8_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_l2_8(dst, src[0], src[1], stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l2_8(dst, src[0], src[1], stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l2_8(dst , src[0] , src[1] , stride, stride, stride, h);\ + OPNAME ## _pixels16_l2_8(dst+16, src[0]+16, src[1]+16, stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels8_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_l4_8(dst, src[0], src[1], src[2], src[3], stride, stride, stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l4_8(dst, src[0], src[1], src[2], src[3], stride, stride, stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l4_8(dst , src[0] , src[1] , src[2] , src[3] , stride, stride, stride, stride, stride, h);\ + OPNAME ## _pixels16_l4_8(dst+16, src[0]+16, src[1]+16, src[2]+16, src[3]+16, stride, stride, stride, stride, stride, h);\ +} +DIRAC_MC(put) +DIRAC_MC(avg) +#endif + +av_cold void ff_qpeldsp_init(QpelDSPContext *c) +{ +#define dspfunc(PFX, IDX, NUM) \ + c->PFX ## _pixels_tab[IDX][0] = PFX ## NUM ## _mc00_c; \ + c->PFX ## _pixels_tab[IDX][1] = PFX ## NUM ## _mc10_c; \ + c->PFX ## _pixels_tab[IDX][2] = PFX ## NUM ## _mc20_c; \ + c->PFX ## _pixels_tab[IDX][3] = PFX ## NUM ## _mc30_c; \ + c->PFX ## _pixels_tab[IDX][4] = PFX ## NUM ## _mc01_c; \ + c->PFX ## _pixels_tab[IDX][5] = PFX ## NUM ## _mc11_c; \ + c->PFX ## _pixels_tab[IDX][6] = PFX ## NUM ## _mc21_c; \ + c->PFX ## _pixels_tab[IDX][7] = PFX ## NUM ## _mc31_c; \ + c->PFX ## _pixels_tab[IDX][8] = PFX ## NUM ## _mc02_c; \ + c->PFX ## _pixels_tab[IDX][9] = PFX ## NUM ## _mc12_c; \ + c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_c; \ + c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_c; \ + c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_c; \ + c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_c; \ + c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_c; \ + c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_c + + dspfunc(put_qpel, 0, 16); + dspfunc(put_qpel, 1, 8); + + dspfunc(put_no_rnd_qpel, 0, 16); + dspfunc(put_no_rnd_qpel, 1, 8); + + dspfunc(avg_qpel, 0, 16); + dspfunc(avg_qpel, 1, 8); + + if (ARCH_X86) + ff_qpeldsp_init_x86(c); + if (ARCH_MIPS) + ff_qpeldsp_init_mips(c); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qpeldsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qpeldsp.h new file mode 100644 index 000000000..91019eda9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qpeldsp.h @@ -0,0 +1,83 @@ +/* + * quarterpel DSP functions + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * quarterpel DSP functions + */ + +#ifndef AVCODEC_QPELDSP_H +#define AVCODEC_QPELDSP_H + +#include +#include + +void ff_put_pixels8x8_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_pixels8x8_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_put_pixels16x16_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +void ff_avg_pixels16x16_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + +void ff_put_pixels8_l2_8(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dst_stride, int src_stride1, int src_stride2, + int h); + +#define DEF_OLD_QPEL(name) \ +void ff_put_ ## name(uint8_t *dst /* align width (8 or 16) */, \ + const uint8_t *src /* align 1 */, \ + ptrdiff_t stride); \ +void ff_put_no_rnd_ ## name(uint8_t *dst /* align width (8 or 16) */, \ + const uint8_t *src /* align 1 */, \ + ptrdiff_t stride); \ +void ff_avg_ ## name(uint8_t *dst /* align width (8 or 16) */, \ + const uint8_t *src /* align 1 */, \ + ptrdiff_t stride); + +DEF_OLD_QPEL(qpel16_mc11_old_c) +DEF_OLD_QPEL(qpel16_mc31_old_c) +DEF_OLD_QPEL(qpel16_mc12_old_c) +DEF_OLD_QPEL(qpel16_mc32_old_c) +DEF_OLD_QPEL(qpel16_mc13_old_c) +DEF_OLD_QPEL(qpel16_mc33_old_c) +DEF_OLD_QPEL(qpel8_mc11_old_c) +DEF_OLD_QPEL(qpel8_mc31_old_c) +DEF_OLD_QPEL(qpel8_mc12_old_c) +DEF_OLD_QPEL(qpel8_mc32_old_c) +DEF_OLD_QPEL(qpel8_mc13_old_c) +DEF_OLD_QPEL(qpel8_mc33_old_c) + +typedef void (*qpel_mc_func)(uint8_t *dst /* align width (8 or 16) */, + const uint8_t *src /* align 1 */, + ptrdiff_t stride); + +/** + * quarterpel DSP context + */ +typedef struct QpelDSPContext { + qpel_mc_func put_qpel_pixels_tab[2][16]; + qpel_mc_func avg_qpel_pixels_tab[2][16]; + qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16]; +} QpelDSPContext; + +void ff_qpeldsp_init(QpelDSPContext *c); + +void ff_qpeldsp_init_x86(QpelDSPContext *c); +void ff_qpeldsp_init_mips(QpelDSPContext *c); + +#endif /* AVCODEC_QPELDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qsv.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qsv.h new file mode 100644 index 000000000..b77158ec2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qsv.h @@ -0,0 +1,107 @@ +/* + * Intel MediaSDK QSV public API + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_QSV_H +#define AVCODEC_QSV_H + +#include + +#include "libavutil/buffer.h" + +/** + * This struct is used for communicating QSV parameters between libavcodec and + * the caller. It is managed by the caller and must be assigned to + * AVCodecContext.hwaccel_context. + * - decoding: hwaccel_context must be set on return from the get_format() + * callback + * - encoding: hwaccel_context must be set before avcodec_open2() + */ +typedef struct AVQSVContext { + /** + * If non-NULL, the session to use for encoding or decoding. + * Otherwise, libavcodec will try to create an internal session. + */ + mfxSession session; + + /** + * The IO pattern to use. + */ + int iopattern; + + /** + * Extra buffers to pass to encoder or decoder initialization. + */ + mfxExtBuffer **ext_buffers; + int nb_ext_buffers; + + /** + * Encoding only. If this field is set to non-zero by the caller, libavcodec + * will create an mfxExtOpaqueSurfaceAlloc extended buffer and pass it to + * the encoder initialization. This only makes sense if iopattern is also + * set to MFX_IOPATTERN_IN_OPAQUE_MEMORY. + * + * The number of allocated opaque surfaces will be the sum of the number + * required by the encoder and the user-provided value nb_opaque_surfaces. + * The array of the opaque surfaces will be exported to the caller through + * the opaque_surfaces field. + */ + int opaque_alloc; + + /** + * Encoding only, and only if opaque_alloc is set to non-zero. Before + * calling avcodec_open2(), the caller should set this field to the number + * of extra opaque surfaces to allocate beyond what is required by the + * encoder. + * + * On return from avcodec_open2(), this field will be set by libavcodec to + * the total number of allocated opaque surfaces. + */ + int nb_opaque_surfaces; + + /** + * Encoding only, and only if opaque_alloc is set to non-zero. On return + * from avcodec_open2(), this field will be used by libavcodec to export the + * array of the allocated opaque surfaces to the caller, so they can be + * passed to other parts of the pipeline. + * + * The buffer reference exported here is owned and managed by libavcodec, + * the callers should make their own reference with av_buffer_ref() and free + * it with av_buffer_unref() when it is no longer needed. + * + * The buffer data is an nb_opaque_surfaces-sized array of mfxFrameSurface1. + */ + AVBufferRef *opaque_surfaces; + + /** + * Encoding only, and only if opaque_alloc is set to non-zero. On return + * from avcodec_open2(), this field will be set to the surface type used in + * the opaque allocation request. + */ + int opaque_alloc_type; +} AVQSVContext; + +/** + * Allocate a new context. + * + * It must be freed by the caller with av_free(). + */ +AVQSVContext *av_qsv_alloc_context(void); + +#endif /* AVCODEC_QSV_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qsv_api.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qsv_api.c new file mode 100644 index 000000000..327ff7d81 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/qsv_api.c @@ -0,0 +1,42 @@ +/* + * Intel MediaSDK QSV public API functions + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#include "libavutil/mem.h" + +#if CONFIG_QSV +#include "qsv.h" + +AVQSVContext *av_qsv_alloc_context(void) +{ + return av_mallocz(sizeof(AVQSVContext)); +} +#else + +struct AVQSVContext *av_qsv_alloc_context(void); + +struct AVQSVContext *av_qsv_alloc_context(void) +{ + return NULL; +} +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ratecontrol.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ratecontrol.c new file mode 100644 index 000000000..49d169ba2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ratecontrol.c @@ -0,0 +1,1028 @@ +/* + * Rate control for video encoders + * + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Rate control for video encoders. + */ + +#include "libavutil/attributes.h" +#include "libavutil/internal.h" + +#include "avcodec.h" +#include "internal.h" +#include "ratecontrol.h" +#include "mpegutils.h" +#include "mpegvideo.h" +#include "libavutil/eval.h" + +void ff_write_pass1_stats(MpegEncContext *s) +{ + snprintf(s->avctx->stats_out, 256, + "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d " + "fcode:%d bcode:%d mc-var:%"PRId64" var:%"PRId64" icount:%d skipcount:%d hbits:%d;\n", + s->current_picture_ptr->f->display_picture_number, + s->current_picture_ptr->f->coded_picture_number, + s->pict_type, + s->current_picture.f->quality, + s->i_tex_bits, + s->p_tex_bits, + s->mv_bits, + s->misc_bits, + s->f_code, + s->b_code, + s->current_picture.mc_mb_var_sum, + s->current_picture.mb_var_sum, + s->i_count, s->skip_count, + s->header_bits); +} + +static double get_fps(AVCodecContext *avctx) +{ + return 1.0 / av_q2d(avctx->time_base) / FFMAX(avctx->ticks_per_frame, 1); +} + +static inline double qp2bits(RateControlEntry *rce, double qp) +{ + if (qp <= 0.0) { + av_log(NULL, AV_LOG_ERROR, "qp<=0.0\n"); + } + return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + 1) / qp; +} + +static inline double bits2qp(RateControlEntry *rce, double bits) +{ + if (bits < 0.9) { + av_log(NULL, AV_LOG_ERROR, "bits<0.9\n"); + } + return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + 1) / bits; +} + +static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, double q) +{ + RateControlContext *rcc = &s->rc_context; + AVCodecContext *a = s->avctx; + const int pict_type = rce->new_pict_type; + const double last_p_q = rcc->last_qscale_for[AV_PICTURE_TYPE_P]; + const double last_non_b_q = rcc->last_qscale_for[rcc->last_non_b_pict_type]; + + if (pict_type == AV_PICTURE_TYPE_I && + (a->i_quant_factor > 0.0 || rcc->last_non_b_pict_type == AV_PICTURE_TYPE_P)) + q = last_p_q * FFABS(a->i_quant_factor) + a->i_quant_offset; + else if (pict_type == AV_PICTURE_TYPE_B && + a->b_quant_factor > 0.0) + q = last_non_b_q * a->b_quant_factor + a->b_quant_offset; + if (q < 1) + q = 1; + + /* last qscale / qdiff stuff */ + if (rcc->last_non_b_pict_type == pict_type || pict_type != AV_PICTURE_TYPE_I) { + double last_q = rcc->last_qscale_for[pict_type]; + const int maxdiff = FF_QP2LAMBDA * a->max_qdiff; + + if (q > last_q + maxdiff) + q = last_q + maxdiff; + else if (q < last_q - maxdiff) + q = last_q - maxdiff; + } + + rcc->last_qscale_for[pict_type] = q; // Note we cannot do that after blurring + + if (pict_type != AV_PICTURE_TYPE_B) + rcc->last_non_b_pict_type = pict_type; + + return q; +} + +/** + * Get the qmin & qmax for pict_type. + */ +static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type) +{ + int qmin = s->lmin; + int qmax = s->lmax; + + av_assert0(qmin <= qmax); + + switch (pict_type) { + case AV_PICTURE_TYPE_B: + qmin = (int)(qmin * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset + 0.5); + qmax = (int)(qmax * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset + 0.5); + break; + case AV_PICTURE_TYPE_I: + qmin = (int)(qmin * FFABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset + 0.5); + qmax = (int)(qmax * FFABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset + 0.5); + break; + } + + qmin = av_clip(qmin, 1, FF_LAMBDA_MAX); + qmax = av_clip(qmax, 1, FF_LAMBDA_MAX); + + if (qmax < qmin) + qmax = qmin; + + *qmin_ret = qmin; + *qmax_ret = qmax; +} + +static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, + double q, int frame_num) +{ + RateControlContext *rcc = &s->rc_context; + const double buffer_size = s->avctx->rc_buffer_size; + const double fps = get_fps(s->avctx); + const double min_rate = s->avctx->rc_min_rate / fps; + const double max_rate = s->avctx->rc_max_rate / fps; + const int pict_type = rce->new_pict_type; + int qmin, qmax; + + get_qminmax(&qmin, &qmax, s, pict_type); + + /* modulation */ + if (s->rc_qmod_freq && + frame_num % s->rc_qmod_freq == 0 && + pict_type == AV_PICTURE_TYPE_P) + q *= s->rc_qmod_amp; + + /* buffer overflow/underflow protection */ + if (buffer_size) { + double expected_size = rcc->buffer_index; + double q_limit; + + if (min_rate) { + double d = 2 * (buffer_size - expected_size) / buffer_size; + if (d > 1.0) + d = 1.0; + else if (d < 0.0001) + d = 0.0001; + q *= pow(d, 1.0 / s->rc_buffer_aggressivity); + + q_limit = bits2qp(rce, + FFMAX((min_rate - buffer_size + rcc->buffer_index) * + s->avctx->rc_min_vbv_overflow_use, 1)); + + if (q > q_limit) { + if (s->avctx->debug & FF_DEBUG_RC) + av_log(s->avctx, AV_LOG_DEBUG, + "limiting QP %f -> %f\n", q, q_limit); + q = q_limit; + } + } + + if (max_rate) { + double d = 2 * expected_size / buffer_size; + if (d > 1.0) + d = 1.0; + else if (d < 0.0001) + d = 0.0001; + q /= pow(d, 1.0 / s->rc_buffer_aggressivity); + + q_limit = bits2qp(rce, + FFMAX(rcc->buffer_index * + s->avctx->rc_max_available_vbv_use, + 1)); + if (q < q_limit) { + if (s->avctx->debug & FF_DEBUG_RC) + av_log(s->avctx, AV_LOG_DEBUG, + "limiting QP %f -> %f\n", q, q_limit); + q = q_limit; + } + } + } + ff_dlog(s, "q:%f max:%f min:%f size:%f index:%f agr:%f\n", + q, max_rate, min_rate, buffer_size, rcc->buffer_index, + s->rc_buffer_aggressivity); + if (s->rc_qsquish == 0.0 || qmin == qmax) { + if (q < qmin) + q = qmin; + else if (q > qmax) + q = qmax; + } else { + double min2 = log(qmin); + double max2 = log(qmax); + + q = log(q); + q = (q - min2) / (max2 - min2) - 0.5; + q *= -4.0; + q = 1.0 / (1.0 + exp(q)); + q = q * (max2 - min2) + min2; + + q = exp(q); + } + + return q; +} + +/** + * Modify the bitrate curve from pass1 for one frame. + */ +static double get_qscale(MpegEncContext *s, RateControlEntry *rce, + double rate_factor, int frame_num) +{ + RateControlContext *rcc = &s->rc_context; + AVCodecContext *a = s->avctx; + const int pict_type = rce->new_pict_type; + const double mb_num = s->mb_num; + double q, bits; + int i; + + double const_values[] = { + M_PI, + M_E, + rce->i_tex_bits * rce->qscale, + rce->p_tex_bits * rce->qscale, + (rce->i_tex_bits + rce->p_tex_bits) * (double)rce->qscale, + rce->mv_bits / mb_num, + rce->pict_type == AV_PICTURE_TYPE_B ? (rce->f_code + rce->b_code) * 0.5 : rce->f_code, + rce->i_count / mb_num, + rce->mc_mb_var_sum / mb_num, + rce->mb_var_sum / mb_num, + rce->pict_type == AV_PICTURE_TYPE_I, + rce->pict_type == AV_PICTURE_TYPE_P, + rce->pict_type == AV_PICTURE_TYPE_B, + rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type], + a->qcompress, + rcc->i_cplx_sum[AV_PICTURE_TYPE_I] / (double)rcc->frame_count[AV_PICTURE_TYPE_I], + rcc->i_cplx_sum[AV_PICTURE_TYPE_P] / (double)rcc->frame_count[AV_PICTURE_TYPE_P], + rcc->p_cplx_sum[AV_PICTURE_TYPE_P] / (double)rcc->frame_count[AV_PICTURE_TYPE_P], + rcc->p_cplx_sum[AV_PICTURE_TYPE_B] / (double)rcc->frame_count[AV_PICTURE_TYPE_B], + (rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / (double)rcc->frame_count[pict_type], + 0 + }; + + bits = av_expr_eval(rcc->rc_eq_eval, const_values, rce); + if (isnan(bits)) { + av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->rc_eq); + return -1; + } + + rcc->pass1_rc_eq_output_sum += bits; + bits *= rate_factor; + if (bits < 0.0) + bits = 0.0; + bits += 1.0; // avoid 1/0 issues + + /* user override */ + for (i = 0; i < s->avctx->rc_override_count; i++) { + RcOverride *rco = s->avctx->rc_override; + if (rco[i].start_frame > frame_num) + continue; + if (rco[i].end_frame < frame_num) + continue; + + if (rco[i].qscale) + bits = qp2bits(rce, rco[i].qscale); // FIXME move at end to really force it? + else + bits *= rco[i].quality_factor; + } + + q = bits2qp(rce, bits); + + /* I/B difference */ + if (pict_type == AV_PICTURE_TYPE_I && s->avctx->i_quant_factor < 0.0) + q = -q * s->avctx->i_quant_factor + s->avctx->i_quant_offset; + else if (pict_type == AV_PICTURE_TYPE_B && s->avctx->b_quant_factor < 0.0) + q = -q * s->avctx->b_quant_factor + s->avctx->b_quant_offset; + if (q < 1) + q = 1; + + return q; +} + +static int init_pass2(MpegEncContext *s) +{ + RateControlContext *rcc = &s->rc_context; + AVCodecContext *a = s->avctx; + int i, toobig; + double fps = get_fps(s->avctx); + double complexity[5] = { 0 }; // approximate bits at quant=1 + uint64_t const_bits[5] = { 0 }; // quantizer independent bits + uint64_t all_const_bits; + uint64_t all_available_bits = (uint64_t)(s->bit_rate * + (double)rcc->num_entries / fps); + double rate_factor = 0; + double step; + const int filter_size = (int)(a->qblur * 4) | 1; + double expected_bits = 0; // init to silence gcc warning + double *qscale, *blurred_qscale, qscale_sum; + + /* find complexity & const_bits & decide the pict_types */ + for (i = 0; i < rcc->num_entries; i++) { + RateControlEntry *rce = &rcc->entry[i]; + + rce->new_pict_type = rce->pict_type; + rcc->i_cplx_sum[rce->pict_type] += rce->i_tex_bits * rce->qscale; + rcc->p_cplx_sum[rce->pict_type] += rce->p_tex_bits * rce->qscale; + rcc->mv_bits_sum[rce->pict_type] += rce->mv_bits; + rcc->frame_count[rce->pict_type]++; + + complexity[rce->new_pict_type] += (rce->i_tex_bits + rce->p_tex_bits) * + (double)rce->qscale; + const_bits[rce->new_pict_type] += rce->mv_bits + rce->misc_bits; + } + + all_const_bits = const_bits[AV_PICTURE_TYPE_I] + + const_bits[AV_PICTURE_TYPE_P] + + const_bits[AV_PICTURE_TYPE_B]; + + if (all_available_bits < all_const_bits) { + av_log(s->avctx, AV_LOG_ERROR, "requested bitrate is too low\n"); + return -1; + } + + qscale = av_malloc_array(rcc->num_entries, sizeof(double)); + blurred_qscale = av_malloc_array(rcc->num_entries, sizeof(double)); + if (!qscale || !blurred_qscale) { + av_free(qscale); + av_free(blurred_qscale); + return AVERROR(ENOMEM); + } + toobig = 0; + + for (step = 256 * 256; step > 0.0000001; step *= 0.5) { + expected_bits = 0; + rate_factor += step; + + rcc->buffer_index = s->avctx->rc_buffer_size / 2; + + /* find qscale */ + for (i = 0; i < rcc->num_entries; i++) { + RateControlEntry *rce = &rcc->entry[i]; + + qscale[i] = get_qscale(s, &rcc->entry[i], rate_factor, i); + rcc->last_qscale_for[rce->pict_type] = qscale[i]; + } + av_assert0(filter_size % 2 == 1); + + /* fixed I/B QP relative to P mode */ + for (i = FFMAX(0, rcc->num_entries - 300); i < rcc->num_entries; i++) { + RateControlEntry *rce = &rcc->entry[i]; + + qscale[i] = get_diff_limited_q(s, rce, qscale[i]); + } + + for (i = rcc->num_entries - 1; i >= 0; i--) { + RateControlEntry *rce = &rcc->entry[i]; + + qscale[i] = get_diff_limited_q(s, rce, qscale[i]); + } + + /* smooth curve */ + for (i = 0; i < rcc->num_entries; i++) { + RateControlEntry *rce = &rcc->entry[i]; + const int pict_type = rce->new_pict_type; + int j; + double q = 0.0, sum = 0.0; + + for (j = 0; j < filter_size; j++) { + int index = i + j - filter_size / 2; + double d = index - i; + double coeff = a->qblur == 0 ? 1.0 : exp(-d * d / (a->qblur * a->qblur)); + + if (index < 0 || index >= rcc->num_entries) + continue; + if (pict_type != rcc->entry[index].new_pict_type) + continue; + q += qscale[index] * coeff; + sum += coeff; + } + blurred_qscale[i] = q / sum; + } + + /* find expected bits */ + for (i = 0; i < rcc->num_entries; i++) { + RateControlEntry *rce = &rcc->entry[i]; + double bits; + + rce->new_qscale = modify_qscale(s, rce, blurred_qscale[i], i); + + bits = qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits; + bits += 8 * ff_vbv_update(s, bits); + + rce->expected_bits = expected_bits; + expected_bits += bits; + } + + ff_dlog(s->avctx, + "expected_bits: %f all_available_bits: %d rate_factor: %f\n", + expected_bits, (int)all_available_bits, rate_factor); + if (expected_bits > all_available_bits) { + rate_factor -= step; + ++toobig; + } + } + av_free(qscale); + av_free(blurred_qscale); + + /* check bitrate calculations and print info */ + qscale_sum = 0.0; + for (i = 0; i < rcc->num_entries; i++) { + ff_dlog(s, "[lavc rc] entry[%d].new_qscale = %.3f qp = %.3f\n", + i, + rcc->entry[i].new_qscale, + rcc->entry[i].new_qscale / FF_QP2LAMBDA); + qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA, + s->avctx->qmin, s->avctx->qmax); + } + av_assert0(toobig <= 40); + av_log(s->avctx, AV_LOG_DEBUG, + "[lavc rc] requested bitrate: %"PRId64" bps expected bitrate: %"PRId64" bps\n", + s->bit_rate, + (int64_t)(expected_bits / ((double)all_available_bits / s->bit_rate))); + av_log(s->avctx, AV_LOG_DEBUG, + "[lavc rc] estimated target average qp: %.3f\n", + (float)qscale_sum / rcc->num_entries); + if (toobig == 0) { + av_log(s->avctx, AV_LOG_INFO, + "[lavc rc] Using all of requested bitrate is not " + "necessary for this video with these parameters.\n"); + } else if (toobig == 40) { + av_log(s->avctx, AV_LOG_ERROR, + "[lavc rc] Error: bitrate too low for this video " + "with these parameters.\n"); + return -1; + } else if (fabs(expected_bits / all_available_bits - 1.0) > 0.01) { + av_log(s->avctx, AV_LOG_ERROR, + "[lavc rc] Error: 2pass curve failed to converge\n"); + return -1; + } + + return 0; +} + +av_cold int ff_rate_control_init(MpegEncContext *s) +{ + RateControlContext *rcc = &s->rc_context; + int i, res; + static const char * const const_names[] = { + "PI", + "E", + "iTex", + "pTex", + "tex", + "mv", + "fCode", + "iCount", + "mcVar", + "var", + "isI", + "isP", + "isB", + "avgQP", + "qComp", + "avgIITex", + "avgPITex", + "avgPPTex", + "avgBPTex", + "avgTex", + NULL + }; + static double (* const func1[])(void *, double) = { + (double (*)(void *, double)) bits2qp, + (double (*)(void *, double)) qp2bits, + NULL + }; + static const char * const func1_names[] = { + "bits2qp", + "qp2bits", + NULL + }; + emms_c(); + + if (!s->avctx->rc_max_available_vbv_use && s->avctx->rc_buffer_size) { + if (s->avctx->rc_max_rate) { + s->avctx->rc_max_available_vbv_use = av_clipf(s->avctx->rc_max_rate/(s->avctx->rc_buffer_size*get_fps(s->avctx)), 1.0/3, 1.0); + } else + s->avctx->rc_max_available_vbv_use = 1.0; + } + + res = av_expr_parse(&rcc->rc_eq_eval, + s->rc_eq ? s->rc_eq : "tex^qComp", + const_names, func1_names, func1, + NULL, NULL, 0, s->avctx); + if (res < 0) { + av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->rc_eq); + return res; + } + + for (i = 0; i < 5; i++) { + rcc->pred[i].coeff = FF_QP2LAMBDA * 7.0; + rcc->pred[i].count = 1.0; + rcc->pred[i].decay = 0.4; + + rcc->i_cplx_sum [i] = + rcc->p_cplx_sum [i] = + rcc->mv_bits_sum[i] = + rcc->qscale_sum [i] = + rcc->frame_count[i] = 1; // 1 is better because of 1/0 and such + + rcc->last_qscale_for[i] = FF_QP2LAMBDA * 5; + } + rcc->buffer_index = s->avctx->rc_initial_buffer_occupancy; + if (!rcc->buffer_index) + rcc->buffer_index = s->avctx->rc_buffer_size * 3 / 4; + + if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { + int i; + char *p; + + /* find number of pics */ + p = s->avctx->stats_in; + for (i = -1; p; i++) + p = strchr(p + 1, ';'); + i += s->max_b_frames; + if (i <= 0 || i >= INT_MAX / sizeof(RateControlEntry)) + return -1; + rcc->entry = av_mallocz(i * sizeof(RateControlEntry)); + if (!rcc->entry) + return AVERROR(ENOMEM); + rcc->num_entries = i; + + /* init all to skipped P-frames + * (with B-frames we might have a not encoded frame at the end FIXME) */ + for (i = 0; i < rcc->num_entries; i++) { + RateControlEntry *rce = &rcc->entry[i]; + + rce->pict_type = rce->new_pict_type = AV_PICTURE_TYPE_P; + rce->qscale = rce->new_qscale = FF_QP2LAMBDA * 2; + rce->misc_bits = s->mb_num + 10; + rce->mb_var_sum = s->mb_num * 100; + } + + /* read stats */ + p = s->avctx->stats_in; + for (i = 0; i < rcc->num_entries - s->max_b_frames; i++) { + RateControlEntry *rce; + int picture_number; + int e; + char *next; + + next = strchr(p, ';'); + if (next) { + (*next) = 0; // sscanf is unbelievably slow on looong strings // FIXME copy / do not write + next++; + } + e = sscanf(p, " in:%d ", &picture_number); + + av_assert0(picture_number >= 0); + av_assert0(picture_number < rcc->num_entries); + rce = &rcc->entry[picture_number]; + + e += sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%"SCNd64" var:%"SCNd64" icount:%d skipcount:%d hbits:%d", + &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, + &rce->mv_bits, &rce->misc_bits, + &rce->f_code, &rce->b_code, + &rce->mc_mb_var_sum, &rce->mb_var_sum, + &rce->i_count, &rce->skip_count, &rce->header_bits); + if (e != 14) { + av_log(s->avctx, AV_LOG_ERROR, + "statistics are damaged at line %d, parser out=%d\n", + i, e); + return -1; + } + + p = next; + } + + if (init_pass2(s) < 0) { + ff_rate_control_uninit(s); + return -1; + } + } + + if (!(s->avctx->flags & AV_CODEC_FLAG_PASS2)) { + rcc->short_term_qsum = 0.001; + rcc->short_term_qcount = 0.001; + + rcc->pass1_rc_eq_output_sum = 0.001; + rcc->pass1_wanted_bits = 0.001; + + if (s->avctx->qblur > 1.0) { + av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n"); + return -1; + } + /* init stuff with the user specified complexity */ + if (s->rc_initial_cplx) { + for (i = 0; i < 60 * 30; i++) { + double bits = s->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num; + RateControlEntry rce; + + if (i % ((s->gop_size + 3) / 4) == 0) + rce.pict_type = AV_PICTURE_TYPE_I; + else if (i % (s->max_b_frames + 1)) + rce.pict_type = AV_PICTURE_TYPE_B; + else + rce.pict_type = AV_PICTURE_TYPE_P; + + rce.new_pict_type = rce.pict_type; + rce.mc_mb_var_sum = bits * s->mb_num / 100000; + rce.mb_var_sum = s->mb_num; + + rce.qscale = FF_QP2LAMBDA * 2; + rce.f_code = 2; + rce.b_code = 1; + rce.misc_bits = 1; + + if (s->pict_type == AV_PICTURE_TYPE_I) { + rce.i_count = s->mb_num; + rce.i_tex_bits = bits; + rce.p_tex_bits = 0; + rce.mv_bits = 0; + } else { + rce.i_count = 0; // FIXME we do know this approx + rce.i_tex_bits = 0; + rce.p_tex_bits = bits * 0.9; + rce.mv_bits = bits * 0.1; + } + rcc->i_cplx_sum[rce.pict_type] += rce.i_tex_bits * rce.qscale; + rcc->p_cplx_sum[rce.pict_type] += rce.p_tex_bits * rce.qscale; + rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits; + rcc->frame_count[rce.pict_type]++; + + get_qscale(s, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i); + + // FIXME misbehaves a little for variable fps + rcc->pass1_wanted_bits += s->bit_rate / get_fps(s->avctx); + } + } + } + + return 0; +} + +av_cold void ff_rate_control_uninit(MpegEncContext *s) +{ + RateControlContext *rcc = &s->rc_context; + emms_c(); + + av_expr_free(rcc->rc_eq_eval); + av_freep(&rcc->entry); +} + +int ff_vbv_update(MpegEncContext *s, int frame_size) +{ + RateControlContext *rcc = &s->rc_context; + const double fps = get_fps(s->avctx); + const int buffer_size = s->avctx->rc_buffer_size; + const double min_rate = s->avctx->rc_min_rate / fps; + const double max_rate = s->avctx->rc_max_rate / fps; + + ff_dlog(s, "%d %f %d %f %f\n", + buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate); + + if (buffer_size) { + int left; + + rcc->buffer_index -= frame_size; + if (rcc->buffer_index < 0) { + av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n"); + if (frame_size > max_rate && s->qscale == s->avctx->qmax) { + av_log(s->avctx, AV_LOG_ERROR, "max bitrate possibly too small or try trellis with large lmax or increase qmax\n"); + } + rcc->buffer_index = 0; + } + + left = buffer_size - rcc->buffer_index - 1; + rcc->buffer_index += av_clip(left, min_rate, max_rate); + + if (rcc->buffer_index > buffer_size) { + int stuffing = ceil((rcc->buffer_index - buffer_size) / 8); + + if (stuffing < 4 && s->codec_id == AV_CODEC_ID_MPEG4) + stuffing = 4; + rcc->buffer_index -= 8 * stuffing; + + if (s->avctx->debug & FF_DEBUG_RC) + av_log(s->avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing); + + return stuffing; + } + } + return 0; +} + +static double predict_size(Predictor *p, double q, double var) +{ + return p->coeff * var / (q * p->count); +} + +static void update_predictor(Predictor *p, double q, double var, double size) +{ + double new_coeff = size * q / (var + 1); + if (var < 10) + return; + + p->count *= p->decay; + p->coeff *= p->decay; + p->count++; + p->coeff += new_coeff; +} + +static void adaptive_quantization(MpegEncContext *s, double q) +{ + int i; + const float lumi_masking = s->avctx->lumi_masking / (128.0 * 128.0); + const float dark_masking = s->avctx->dark_masking / (128.0 * 128.0); + const float temp_cplx_masking = s->avctx->temporal_cplx_masking; + const float spatial_cplx_masking = s->avctx->spatial_cplx_masking; + const float p_masking = s->avctx->p_masking; + const float border_masking = s->border_masking; + float bits_sum = 0.0; + float cplx_sum = 0.0; + float *cplx_tab = s->cplx_tab; + float *bits_tab = s->bits_tab; + const int qmin = s->avctx->mb_lmin; + const int qmax = s->avctx->mb_lmax; + Picture *const pic = &s->current_picture; + const int mb_width = s->mb_width; + const int mb_height = s->mb_height; + + for (i = 0; i < s->mb_num; i++) { + const int mb_xy = s->mb_index2xy[i]; + float temp_cplx = sqrt(pic->mc_mb_var[mb_xy]); // FIXME merge in pow() + float spat_cplx = sqrt(pic->mb_var[mb_xy]); + const int lumi = pic->mb_mean[mb_xy]; + float bits, cplx, factor; + int mb_x = mb_xy % s->mb_stride; + int mb_y = mb_xy / s->mb_stride; + int mb_distance; + float mb_factor = 0.0; + if (spat_cplx < 4) + spat_cplx = 4; // FIXME fine-tune + if (temp_cplx < 4) + temp_cplx = 4; // FIXME fine-tune + + if ((s->mb_type[mb_xy] & CANDIDATE_MB_TYPE_INTRA)) { // FIXME hq mode + cplx = spat_cplx; + factor = 1.0 + p_masking; + } else { + cplx = temp_cplx; + factor = pow(temp_cplx, -temp_cplx_masking); + } + factor *= pow(spat_cplx, -spatial_cplx_masking); + + if (lumi > 127) + factor *= (1.0 - (lumi - 128) * (lumi - 128) * lumi_masking); + else + factor *= (1.0 - (lumi - 128) * (lumi - 128) * dark_masking); + + if (mb_x < mb_width / 5) { + mb_distance = mb_width / 5 - mb_x; + mb_factor = (float)mb_distance / (float)(mb_width / 5); + } else if (mb_x > 4 * mb_width / 5) { + mb_distance = mb_x - 4 * mb_width / 5; + mb_factor = (float)mb_distance / (float)(mb_width / 5); + } + if (mb_y < mb_height / 5) { + mb_distance = mb_height / 5 - mb_y; + mb_factor = FFMAX(mb_factor, + (float)mb_distance / (float)(mb_height / 5)); + } else if (mb_y > 4 * mb_height / 5) { + mb_distance = mb_y - 4 * mb_height / 5; + mb_factor = FFMAX(mb_factor, + (float)mb_distance / (float)(mb_height / 5)); + } + + factor *= 1.0 - border_masking * mb_factor; + + if (factor < 0.00001) + factor = 0.00001; + + bits = cplx * factor; + cplx_sum += cplx; + bits_sum += bits; + cplx_tab[i] = cplx; + bits_tab[i] = bits; + } + + /* handle qmin/qmax clipping */ + if (s->mpv_flags & FF_MPV_FLAG_NAQ) { + float factor = bits_sum / cplx_sum; + for (i = 0; i < s->mb_num; i++) { + float newq = q * cplx_tab[i] / bits_tab[i]; + newq *= factor; + + if (newq > qmax) { + bits_sum -= bits_tab[i]; + cplx_sum -= cplx_tab[i] * q / qmax; + } else if (newq < qmin) { + bits_sum -= bits_tab[i]; + cplx_sum -= cplx_tab[i] * q / qmin; + } + } + if (bits_sum < 0.001) + bits_sum = 0.001; + if (cplx_sum < 0.001) + cplx_sum = 0.001; + } + + for (i = 0; i < s->mb_num; i++) { + const int mb_xy = s->mb_index2xy[i]; + float newq = q * cplx_tab[i] / bits_tab[i]; + int intq; + + if (s->mpv_flags & FF_MPV_FLAG_NAQ) { + newq *= bits_sum / cplx_sum; + } + + intq = (int)(newq + 0.5); + + if (intq > qmax) + intq = qmax; + else if (intq < qmin) + intq = qmin; + s->lambda_table[mb_xy] = intq; + } +} + +void ff_get_2pass_fcode(MpegEncContext *s) +{ + RateControlContext *rcc = &s->rc_context; + RateControlEntry *rce = &rcc->entry[s->picture_number]; + + s->f_code = rce->f_code; + s->b_code = rce->b_code; +} + +// FIXME rd or at least approx for dquant + +float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) +{ + float q; + int qmin, qmax; + float br_compensation; + double diff; + double short_term_q; + double fps; + int picture_number = s->picture_number; + int64_t wanted_bits; + RateControlContext *rcc = &s->rc_context; + AVCodecContext *a = s->avctx; + RateControlEntry local_rce, *rce; + double bits; + double rate_factor; + int64_t var; + const int pict_type = s->pict_type; + Picture * const pic = &s->current_picture; + emms_c(); + + get_qminmax(&qmin, &qmax, s, pict_type); + + fps = get_fps(s->avctx); + /* update predictors */ + if (picture_number > 2 && !dry_run) { + const int64_t last_var = + s->last_pict_type == AV_PICTURE_TYPE_I ? rcc->last_mb_var_sum + : rcc->last_mc_mb_var_sum; + av_assert1(s->frame_bits >= s->stuffing_bits); + update_predictor(&rcc->pred[s->last_pict_type], + rcc->last_qscale, + sqrt(last_var), + s->frame_bits - s->stuffing_bits); + } + + if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { + av_assert0(picture_number >= 0); + if (picture_number >= rcc->num_entries) { + av_log(s, AV_LOG_ERROR, "Input is longer than 2-pass log file\n"); + return -1; + } + rce = &rcc->entry[picture_number]; + wanted_bits = rce->expected_bits; + } else { + Picture *dts_pic; + rce = &local_rce; + + /* FIXME add a dts field to AVFrame and ensure it is set and use it + * here instead of reordering but the reordering is simpler for now + * until H.264 B-pyramid must be handled. */ + if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) + dts_pic = s->current_picture_ptr; + else + dts_pic = s->last_picture_ptr; + + if (!dts_pic || dts_pic->f->pts == AV_NOPTS_VALUE) + wanted_bits = (uint64_t)(s->bit_rate * (double)picture_number / fps); + else + wanted_bits = (uint64_t)(s->bit_rate * (double)dts_pic->f->pts / fps); + } + + diff = s->total_bits - wanted_bits; + br_compensation = (a->bit_rate_tolerance - diff) / a->bit_rate_tolerance; + if (br_compensation <= 0.0) + br_compensation = 0.001; + + var = pict_type == AV_PICTURE_TYPE_I ? pic->mb_var_sum : pic->mc_mb_var_sum; + + short_term_q = 0; /* avoid warning */ + if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { + if (pict_type != AV_PICTURE_TYPE_I) + av_assert0(pict_type == rce->new_pict_type); + + q = rce->new_qscale / br_compensation; + ff_dlog(s, "%f %f %f last:%d var:%"PRId64" type:%d//\n", q, rce->new_qscale, + br_compensation, s->frame_bits, var, pict_type); + } else { + rce->pict_type = + rce->new_pict_type = pict_type; + rce->mc_mb_var_sum = pic->mc_mb_var_sum; + rce->mb_var_sum = pic->mb_var_sum; + rce->qscale = FF_QP2LAMBDA * 2; + rce->f_code = s->f_code; + rce->b_code = s->b_code; + rce->misc_bits = 1; + + bits = predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var)); + if (pict_type == AV_PICTURE_TYPE_I) { + rce->i_count = s->mb_num; + rce->i_tex_bits = bits; + rce->p_tex_bits = 0; + rce->mv_bits = 0; + } else { + rce->i_count = 0; // FIXME we do know this approx + rce->i_tex_bits = 0; + rce->p_tex_bits = bits * 0.9; + rce->mv_bits = bits * 0.1; + } + rcc->i_cplx_sum[pict_type] += rce->i_tex_bits * rce->qscale; + rcc->p_cplx_sum[pict_type] += rce->p_tex_bits * rce->qscale; + rcc->mv_bits_sum[pict_type] += rce->mv_bits; + rcc->frame_count[pict_type]++; + + rate_factor = rcc->pass1_wanted_bits / + rcc->pass1_rc_eq_output_sum * br_compensation; + + q = get_qscale(s, rce, rate_factor, picture_number); + if (q < 0) + return -1; + + av_assert0(q > 0.0); + q = get_diff_limited_q(s, rce, q); + av_assert0(q > 0.0); + + // FIXME type dependent blur like in 2-pass + if (pict_type == AV_PICTURE_TYPE_P || s->intra_only) { + rcc->short_term_qsum *= a->qblur; + rcc->short_term_qcount *= a->qblur; + + rcc->short_term_qsum += q; + rcc->short_term_qcount++; + q = short_term_q = rcc->short_term_qsum / rcc->short_term_qcount; + } + av_assert0(q > 0.0); + + q = modify_qscale(s, rce, q, picture_number); + + rcc->pass1_wanted_bits += s->bit_rate / fps; + + av_assert0(q > 0.0); + } + + if (s->avctx->debug & FF_DEBUG_RC) { + av_log(s->avctx, AV_LOG_DEBUG, + "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f " + "size:%d var:%"PRId64"/%"PRId64" br:%"PRId64" fps:%d\n", + av_get_picture_type_char(pict_type), + qmin, q, qmax, picture_number, + (int)wanted_bits / 1000, (int)s->total_bits / 1000, + br_compensation, short_term_q, s->frame_bits, + pic->mb_var_sum, pic->mc_mb_var_sum, + s->bit_rate / 1000, (int)fps); + } + + if (q < qmin) + q = qmin; + else if (q > qmax) + q = qmax; + + if (s->adaptive_quant) + adaptive_quantization(s, q); + else + q = (int)(q + 0.5); + + if (!dry_run) { + rcc->last_qscale = q; + rcc->last_mc_mb_var_sum = pic->mc_mb_var_sum; + rcc->last_mb_var_sum = pic->mb_var_sum; + } + return q; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ratecontrol.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ratecontrol.h new file mode 100644 index 000000000..2a7aaec64 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/ratecontrol.h @@ -0,0 +1,99 @@ +/* + * Ratecontrol + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_RATECONTROL_H +#define AVCODEC_RATECONTROL_H + +/** + * @file + * ratecontrol header. + */ + +#include +#include +#include "libavutil/eval.h" + +typedef struct Predictor{ + double coeff; + double count; + double decay; +} Predictor; + +typedef struct RateControlEntry{ + int pict_type; + float qscale; + int mv_bits; + int i_tex_bits; + int p_tex_bits; + int misc_bits; + int header_bits; + uint64_t expected_bits; + int new_pict_type; + float new_qscale; + int64_t mc_mb_var_sum; + int64_t mb_var_sum; + int i_count; + int skip_count; + int f_code; + int b_code; +}RateControlEntry; + +/** + * rate control context. + */ +typedef struct RateControlContext{ + int num_entries; ///< number of RateControlEntries + RateControlEntry *entry; + double buffer_index; ///< amount of bits in the video/audio buffer + Predictor pred[5]; + double short_term_qsum; ///< sum of recent qscales + double short_term_qcount; ///< count of recent qscales + double pass1_rc_eq_output_sum;///< sum of the output of the rc equation, this is used for normalization + double pass1_wanted_bits; ///< bits which should have been output by the pass1 code (including complexity init) + double last_qscale; + double last_qscale_for[5]; ///< last qscale for a specific pict type, used for max_diff & ipb factor stuff + int64_t last_mc_mb_var_sum; + int64_t last_mb_var_sum; + uint64_t i_cplx_sum[5]; + uint64_t p_cplx_sum[5]; + uint64_t mv_bits_sum[5]; + uint64_t qscale_sum[5]; + int frame_count[5]; + int last_non_b_pict_type; + + void *non_lavc_opaque; ///< context for non lavc rc code (for example xvid) + float dry_run_qscale; ///< for xvid rc + int last_picture_number; ///< for xvid rc + AVExpr * rc_eq_eval; +}RateControlContext; + +struct MpegEncContext; + +/* rate control */ +int ff_rate_control_init(struct MpegEncContext *s); +float ff_rate_estimate_qscale(struct MpegEncContext *s, int dry_run); +void ff_write_pass1_stats(struct MpegEncContext *s); +void ff_rate_control_uninit(struct MpegEncContext *s); +int ff_vbv_update(struct MpegEncContext *s, int frame_size); +void ff_get_2pass_fcode(struct MpegEncContext *s); + +#endif /* AVCODEC_RATECONTROL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/raw.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/raw.c new file mode 100644 index 000000000..b6fb91c1c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/raw.c @@ -0,0 +1,338 @@ +/* + * Raw Video Codec + * Copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Raw Video Codec + */ + +#include "avcodec.h" +#include "raw.h" +#include "libavutil/common.h" + +const PixelFormatTag ff_raw_pix_fmt_tags[] = { + { AV_PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */ + { AV_PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') }, + { AV_PIX_FMT_YUV420P, MKTAG('y', 'v', '1', '2') }, + { AV_PIX_FMT_YUV420P, MKTAG('Y', 'V', '1', '2') }, + { AV_PIX_FMT_YUV410P, MKTAG('Y', 'U', 'V', '9') }, + { AV_PIX_FMT_YUV410P, MKTAG('Y', 'V', 'U', '9') }, + { AV_PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') }, + { AV_PIX_FMT_YUV422P, MKTAG('Y', '4', '2', 'B') }, + { AV_PIX_FMT_YUV422P, MKTAG('P', '4', '2', '2') }, + { AV_PIX_FMT_YUV422P, MKTAG('Y', 'V', '1', '6') }, + /* yuvjXXX formats are deprecated hacks specific to libav*, + they are identical to yuvXXX */ + { AV_PIX_FMT_YUVJ420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */ + { AV_PIX_FMT_YUVJ420P, MKTAG('I', 'Y', 'U', 'V') }, + { AV_PIX_FMT_YUVJ420P, MKTAG('Y', 'V', '1', '2') }, + { AV_PIX_FMT_YUVJ422P, MKTAG('Y', '4', '2', 'B') }, + { AV_PIX_FMT_YUVJ422P, MKTAG('P', '4', '2', '2') }, + { AV_PIX_FMT_GRAY8, MKTAG('Y', '8', '0', '0') }, + { AV_PIX_FMT_GRAY8, MKTAG('Y', '8', ' ', ' ') }, + + { AV_PIX_FMT_YUYV422, MKTAG('Y', 'U', 'Y', '2') }, /* Packed formats */ + { AV_PIX_FMT_YUYV422, MKTAG('Y', '4', '2', '2') }, + { AV_PIX_FMT_YUYV422, MKTAG('V', '4', '2', '2') }, + { AV_PIX_FMT_YUYV422, MKTAG('V', 'Y', 'U', 'Y') }, + { AV_PIX_FMT_YUYV422, MKTAG('Y', 'U', 'N', 'V') }, + { AV_PIX_FMT_YUYV422, MKTAG('Y', 'U', 'Y', 'V') }, + { AV_PIX_FMT_YVYU422, MKTAG('Y', 'V', 'Y', 'U') }, /* Philips */ + { AV_PIX_FMT_UYVY422, MKTAG('U', 'Y', 'V', 'Y') }, + { AV_PIX_FMT_UYVY422, MKTAG('H', 'D', 'Y', 'C') }, + { AV_PIX_FMT_UYVY422, MKTAG('U', 'Y', 'N', 'V') }, + { AV_PIX_FMT_UYVY422, MKTAG('U', 'Y', 'N', 'Y') }, + { AV_PIX_FMT_UYVY422, MKTAG('u', 'y', 'v', '1') }, + { AV_PIX_FMT_UYVY422, MKTAG('2', 'V', 'u', '1') }, + { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'R', 'n') }, /* Avid AVI Codec 1:1 */ + { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', '1', 'x') }, /* Avid 1:1x */ + { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'u', 'p') }, + { AV_PIX_FMT_UYVY422, MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */ + { AV_PIX_FMT_UYVY422, MKTAG('a', 'u', 'v', '2') }, + { AV_PIX_FMT_UYVY422, MKTAG('c', 'y', 'u', 'v') }, /* CYUV is also Creative YUV */ + { AV_PIX_FMT_UYYVYY411, MKTAG('Y', '4', '1', '1') }, + { AV_PIX_FMT_GRAY8, MKTAG('G', 'R', 'E', 'Y') }, + { AV_PIX_FMT_NV12, MKTAG('N', 'V', '1', '2') }, + { AV_PIX_FMT_NV21, MKTAG('N', 'V', '2', '1') }, + + /* nut */ + { AV_PIX_FMT_RGB555LE, MKTAG('R', 'G', 'B', 15) }, + { AV_PIX_FMT_BGR555LE, MKTAG('B', 'G', 'R', 15) }, + { AV_PIX_FMT_RGB565LE, MKTAG('R', 'G', 'B', 16) }, + { AV_PIX_FMT_BGR565LE, MKTAG('B', 'G', 'R', 16) }, + { AV_PIX_FMT_RGB555BE, MKTAG(15 , 'B', 'G', 'R') }, + { AV_PIX_FMT_BGR555BE, MKTAG(15 , 'R', 'G', 'B') }, + { AV_PIX_FMT_RGB565BE, MKTAG(16 , 'B', 'G', 'R') }, + { AV_PIX_FMT_BGR565BE, MKTAG(16 , 'R', 'G', 'B') }, + { AV_PIX_FMT_RGB444LE, MKTAG('R', 'G', 'B', 12) }, + { AV_PIX_FMT_BGR444LE, MKTAG('B', 'G', 'R', 12) }, + { AV_PIX_FMT_RGB444BE, MKTAG(12 , 'B', 'G', 'R') }, + { AV_PIX_FMT_BGR444BE, MKTAG(12 , 'R', 'G', 'B') }, + { AV_PIX_FMT_RGBA64LE, MKTAG('R', 'B', 'A', 64 ) }, + { AV_PIX_FMT_BGRA64LE, MKTAG('B', 'R', 'A', 64 ) }, + { AV_PIX_FMT_RGBA64BE, MKTAG(64 , 'R', 'B', 'A') }, + { AV_PIX_FMT_BGRA64BE, MKTAG(64 , 'B', 'R', 'A') }, + { AV_PIX_FMT_RGBA, MKTAG('R', 'G', 'B', 'A') }, + { AV_PIX_FMT_RGB0, MKTAG('R', 'G', 'B', 0 ) }, + { AV_PIX_FMT_BGRA, MKTAG('B', 'G', 'R', 'A') }, + { AV_PIX_FMT_BGR0, MKTAG('B', 'G', 'R', 0 ) }, + { AV_PIX_FMT_ABGR, MKTAG('A', 'B', 'G', 'R') }, + { AV_PIX_FMT_0BGR, MKTAG( 0 , 'B', 'G', 'R') }, + { AV_PIX_FMT_ARGB, MKTAG('A', 'R', 'G', 'B') }, + { AV_PIX_FMT_0RGB, MKTAG( 0 , 'R', 'G', 'B') }, + { AV_PIX_FMT_RGB24, MKTAG('R', 'G', 'B', 24 ) }, + { AV_PIX_FMT_BGR24, MKTAG('B', 'G', 'R', 24 ) }, + { AV_PIX_FMT_YUV411P, MKTAG('4', '1', '1', 'P') }, + { AV_PIX_FMT_YUV422P, MKTAG('4', '2', '2', 'P') }, + { AV_PIX_FMT_YUVJ422P, MKTAG('4', '2', '2', 'P') }, + { AV_PIX_FMT_YUV440P, MKTAG('4', '4', '0', 'P') }, + { AV_PIX_FMT_YUVJ440P, MKTAG('4', '4', '0', 'P') }, + { AV_PIX_FMT_YUV444P, MKTAG('4', '4', '4', 'P') }, + { AV_PIX_FMT_YUVJ444P, MKTAG('4', '4', '4', 'P') }, + { AV_PIX_FMT_MONOWHITE,MKTAG('B', '1', 'W', '0') }, + { AV_PIX_FMT_MONOBLACK,MKTAG('B', '0', 'W', '1') }, + { AV_PIX_FMT_BGR8, MKTAG('B', 'G', 'R', 8 ) }, + { AV_PIX_FMT_RGB8, MKTAG('R', 'G', 'B', 8 ) }, + { AV_PIX_FMT_BGR4, MKTAG('B', 'G', 'R', 4 ) }, + { AV_PIX_FMT_RGB4, MKTAG('R', 'G', 'B', 4 ) }, + { AV_PIX_FMT_RGB4_BYTE,MKTAG('B', '4', 'B', 'Y') }, + { AV_PIX_FMT_BGR4_BYTE,MKTAG('R', '4', 'B', 'Y') }, + { AV_PIX_FMT_RGB48LE, MKTAG('R', 'G', 'B', 48 ) }, + { AV_PIX_FMT_RGB48BE, MKTAG( 48, 'R', 'G', 'B') }, + { AV_PIX_FMT_BGR48LE, MKTAG('B', 'G', 'R', 48 ) }, + { AV_PIX_FMT_BGR48BE, MKTAG( 48, 'B', 'G', 'R') }, + { AV_PIX_FMT_GRAY9LE, MKTAG('Y', '1', 0 , 9 ) }, + { AV_PIX_FMT_GRAY9BE, MKTAG( 9 , 0 , '1', 'Y') }, + { AV_PIX_FMT_GRAY10LE, MKTAG('Y', '1', 0 , 10 ) }, + { AV_PIX_FMT_GRAY10BE, MKTAG(10 , 0 , '1', 'Y') }, + { AV_PIX_FMT_GRAY12LE, MKTAG('Y', '1', 0 , 12 ) }, + { AV_PIX_FMT_GRAY12BE, MKTAG(12 , 0 , '1', 'Y') }, + { AV_PIX_FMT_GRAY14LE, MKTAG('Y', '1', 0 , 14 ) }, + { AV_PIX_FMT_GRAY14BE, MKTAG(14 , 0 , '1', 'Y') }, + { AV_PIX_FMT_GRAY16LE, MKTAG('Y', '1', 0 , 16 ) }, + { AV_PIX_FMT_GRAY16BE, MKTAG(16 , 0 , '1', 'Y') }, + { AV_PIX_FMT_YUV420P9LE, MKTAG('Y', '3', 11 , 9 ) }, + { AV_PIX_FMT_YUV420P9BE, MKTAG( 9 , 11 , '3', 'Y') }, + { AV_PIX_FMT_YUV422P9LE, MKTAG('Y', '3', 10 , 9 ) }, + { AV_PIX_FMT_YUV422P9BE, MKTAG( 9 , 10 , '3', 'Y') }, + { AV_PIX_FMT_YUV444P9LE, MKTAG('Y', '3', 0 , 9 ) }, + { AV_PIX_FMT_YUV444P9BE, MKTAG( 9 , 0 , '3', 'Y') }, + { AV_PIX_FMT_YUV420P10LE, MKTAG('Y', '3', 11 , 10 ) }, + { AV_PIX_FMT_YUV420P10BE, MKTAG(10 , 11 , '3', 'Y') }, + { AV_PIX_FMT_YUV422P10LE, MKTAG('Y', '3', 10 , 10 ) }, + { AV_PIX_FMT_YUV422P10BE, MKTAG(10 , 10 , '3', 'Y') }, + { AV_PIX_FMT_YUV444P10LE, MKTAG('Y', '3', 0 , 10 ) }, + { AV_PIX_FMT_YUV444P10BE, MKTAG(10 , 0 , '3', 'Y') }, + { AV_PIX_FMT_YUV420P12LE, MKTAG('Y', '3', 11 , 12 ) }, + { AV_PIX_FMT_YUV420P12BE, MKTAG(12 , 11 , '3', 'Y') }, + { AV_PIX_FMT_YUV422P12LE, MKTAG('Y', '3', 10 , 12 ) }, + { AV_PIX_FMT_YUV422P12BE, MKTAG(12 , 10 , '3', 'Y') }, + { AV_PIX_FMT_YUV444P12LE, MKTAG('Y', '3', 0 , 12 ) }, + { AV_PIX_FMT_YUV444P12BE, MKTAG(12 , 0 , '3', 'Y') }, + { AV_PIX_FMT_YUV420P14LE, MKTAG('Y', '3', 11 , 14 ) }, + { AV_PIX_FMT_YUV420P14BE, MKTAG(14 , 11 , '3', 'Y') }, + { AV_PIX_FMT_YUV422P14LE, MKTAG('Y', '3', 10 , 14 ) }, + { AV_PIX_FMT_YUV422P14BE, MKTAG(14 , 10 , '3', 'Y') }, + { AV_PIX_FMT_YUV444P14LE, MKTAG('Y', '3', 0 , 14 ) }, + { AV_PIX_FMT_YUV444P14BE, MKTAG(14 , 0 , '3', 'Y') }, + { AV_PIX_FMT_YUV420P16LE, MKTAG('Y', '3', 11 , 16 ) }, + { AV_PIX_FMT_YUV420P16BE, MKTAG(16 , 11 , '3', 'Y') }, + { AV_PIX_FMT_YUV422P16LE, MKTAG('Y', '3', 10 , 16 ) }, + { AV_PIX_FMT_YUV422P16BE, MKTAG(16 , 10 , '3', 'Y') }, + { AV_PIX_FMT_YUV444P16LE, MKTAG('Y', '3', 0 , 16 ) }, + { AV_PIX_FMT_YUV444P16BE, MKTAG(16 , 0 , '3', 'Y') }, + { AV_PIX_FMT_YUVA420P, MKTAG('Y', '4', 11 , 8 ) }, + { AV_PIX_FMT_YUVA422P, MKTAG('Y', '4', 10 , 8 ) }, + { AV_PIX_FMT_YUVA444P, MKTAG('Y', '4', 0 , 8 ) }, + { AV_PIX_FMT_YA8, MKTAG('Y', '2', 0 , 8 ) }, + { AV_PIX_FMT_PAL8, MKTAG('P', 'A', 'L', 8 ) }, + + { AV_PIX_FMT_YUVA420P9LE, MKTAG('Y', '4', 11 , 9 ) }, + { AV_PIX_FMT_YUVA420P9BE, MKTAG( 9 , 11 , '4', 'Y') }, + { AV_PIX_FMT_YUVA422P9LE, MKTAG('Y', '4', 10 , 9 ) }, + { AV_PIX_FMT_YUVA422P9BE, MKTAG( 9 , 10 , '4', 'Y') }, + { AV_PIX_FMT_YUVA444P9LE, MKTAG('Y', '4', 0 , 9 ) }, + { AV_PIX_FMT_YUVA444P9BE, MKTAG( 9 , 0 , '4', 'Y') }, + { AV_PIX_FMT_YUVA420P10LE, MKTAG('Y', '4', 11 , 10 ) }, + { AV_PIX_FMT_YUVA420P10BE, MKTAG(10 , 11 , '4', 'Y') }, + { AV_PIX_FMT_YUVA422P10LE, MKTAG('Y', '4', 10 , 10 ) }, + { AV_PIX_FMT_YUVA422P10BE, MKTAG(10 , 10 , '4', 'Y') }, + { AV_PIX_FMT_YUVA444P10LE, MKTAG('Y', '4', 0 , 10 ) }, + { AV_PIX_FMT_YUVA444P10BE, MKTAG(10 , 0 , '4', 'Y') }, + { AV_PIX_FMT_YUVA422P12LE, MKTAG('Y', '4', 10 , 12 ) }, + { AV_PIX_FMT_YUVA422P12BE, MKTAG(12 , 10 , '4', 'Y') }, + { AV_PIX_FMT_YUVA444P12LE, MKTAG('Y', '4', 0 , 12 ) }, + { AV_PIX_FMT_YUVA444P12BE, MKTAG(12 , 0 , '4', 'Y') }, + { AV_PIX_FMT_YUVA420P16LE, MKTAG('Y', '4', 11 , 16 ) }, + { AV_PIX_FMT_YUVA420P16BE, MKTAG(16 , 11 , '4', 'Y') }, + { AV_PIX_FMT_YUVA422P16LE, MKTAG('Y', '4', 10 , 16 ) }, + { AV_PIX_FMT_YUVA422P16BE, MKTAG(16 , 10 , '4', 'Y') }, + { AV_PIX_FMT_YUVA444P16LE, MKTAG('Y', '4', 0 , 16 ) }, + { AV_PIX_FMT_YUVA444P16BE, MKTAG(16 , 0 , '4', 'Y') }, + + { AV_PIX_FMT_GBRP, MKTAG('G', '3', 00 , 8 ) }, + { AV_PIX_FMT_GBRP9LE, MKTAG('G', '3', 00 , 9 ) }, + { AV_PIX_FMT_GBRP9BE, MKTAG( 9 , 00 , '3', 'G') }, + { AV_PIX_FMT_GBRP10LE, MKTAG('G', '3', 00 , 10 ) }, + { AV_PIX_FMT_GBRP10BE, MKTAG(10 , 00 , '3', 'G') }, + { AV_PIX_FMT_GBRP12LE, MKTAG('G', '3', 00 , 12 ) }, + { AV_PIX_FMT_GBRP12BE, MKTAG(12 , 00 , '3', 'G') }, + { AV_PIX_FMT_GBRP14LE, MKTAG('G', '3', 00 , 14 ) }, + { AV_PIX_FMT_GBRP14BE, MKTAG(14 , 00 , '3', 'G') }, + { AV_PIX_FMT_GBRP16LE, MKTAG('G', '3', 00 , 16 ) }, + { AV_PIX_FMT_GBRP16BE, MKTAG(16 , 00 , '3', 'G') }, + + { AV_PIX_FMT_GBRAP, MKTAG('G', '4', 00 , 8 ) }, + { AV_PIX_FMT_GBRAP10LE, MKTAG('G', '4', 00 , 10 ) }, + { AV_PIX_FMT_GBRAP10BE, MKTAG(10 , 00 , '4', 'G') }, + { AV_PIX_FMT_GBRAP12LE, MKTAG('G', '4', 00 , 12 ) }, + { AV_PIX_FMT_GBRAP12BE, MKTAG(12 , 00 , '4', 'G') }, + { AV_PIX_FMT_GBRAP16LE, MKTAG('G', '4', 00 , 16 ) }, + { AV_PIX_FMT_GBRAP16BE, MKTAG(16 , 00 , '4', 'G') }, + + { AV_PIX_FMT_XYZ12LE, MKTAG('X', 'Y', 'Z' , 36 ) }, + { AV_PIX_FMT_XYZ12BE, MKTAG(36 , 'Z' , 'Y', 'X') }, + + { AV_PIX_FMT_BAYER_BGGR8, MKTAG(0xBA, 'B', 'G', 8 ) }, + { AV_PIX_FMT_BAYER_BGGR16LE, MKTAG(0xBA, 'B', 'G', 16 ) }, + { AV_PIX_FMT_BAYER_BGGR16BE, MKTAG(16 , 'G', 'B', 0xBA) }, + { AV_PIX_FMT_BAYER_RGGB8, MKTAG(0xBA, 'R', 'G', 8 ) }, + { AV_PIX_FMT_BAYER_RGGB16LE, MKTAG(0xBA, 'R', 'G', 16 ) }, + { AV_PIX_FMT_BAYER_RGGB16BE, MKTAG(16 , 'G', 'R', 0xBA) }, + { AV_PIX_FMT_BAYER_GBRG8, MKTAG(0xBA, 'G', 'B', 8 ) }, + { AV_PIX_FMT_BAYER_GBRG16LE, MKTAG(0xBA, 'G', 'B', 16 ) }, + { AV_PIX_FMT_BAYER_GBRG16BE, MKTAG(16, 'B', 'G', 0xBA) }, + { AV_PIX_FMT_BAYER_GRBG8, MKTAG(0xBA, 'G', 'R', 8 ) }, + { AV_PIX_FMT_BAYER_GRBG16LE, MKTAG(0xBA, 'G', 'R', 16 ) }, + { AV_PIX_FMT_BAYER_GRBG16BE, MKTAG(16, 'R', 'G', 0xBA) }, + + /* quicktime */ + { AV_PIX_FMT_YUV420P, MKTAG('R', '4', '2', '0') }, /* Radius DV YUV PAL */ + { AV_PIX_FMT_YUV411P, MKTAG('R', '4', '1', '1') }, /* Radius DV YUV NTSC */ + { AV_PIX_FMT_UYVY422, MKTAG('2', 'v', 'u', 'y') }, + { AV_PIX_FMT_UYVY422, MKTAG('2', 'V', 'u', 'y') }, + { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'U', 'I') }, /* FIXME merge both fields */ + { AV_PIX_FMT_UYVY422, MKTAG('b', 'x', 'y', 'v') }, + { AV_PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', '2') }, + { AV_PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', 's') }, + { AV_PIX_FMT_YUYV422, MKTAG('D', 'V', 'O', 'O') }, /* Digital Voodoo SD 8 Bit */ + { AV_PIX_FMT_RGB555LE,MKTAG('L', '5', '5', '5') }, + { AV_PIX_FMT_RGB565LE,MKTAG('L', '5', '6', '5') }, + { AV_PIX_FMT_RGB565BE,MKTAG('B', '5', '6', '5') }, + { AV_PIX_FMT_BGR24, MKTAG('2', '4', 'B', 'G') }, + { AV_PIX_FMT_BGR24, MKTAG('b', 'x', 'b', 'g') }, + { AV_PIX_FMT_BGRA, MKTAG('B', 'G', 'R', 'A') }, + { AV_PIX_FMT_RGBA, MKTAG('R', 'G', 'B', 'A') }, + { AV_PIX_FMT_RGB24, MKTAG('b', 'x', 'r', 'g') }, + { AV_PIX_FMT_ABGR, MKTAG('A', 'B', 'G', 'R') }, + { AV_PIX_FMT_GRAY16BE,MKTAG('b', '1', '6', 'g') }, + { AV_PIX_FMT_RGB48BE, MKTAG('b', '4', '8', 'r') }, + { AV_PIX_FMT_RGBA64BE,MKTAG('b', '6', '4', 'a') }, + + /* vlc */ + { AV_PIX_FMT_YUV410P, MKTAG('I', '4', '1', '0') }, + { AV_PIX_FMT_YUV411P, MKTAG('I', '4', '1', '1') }, + { AV_PIX_FMT_YUV422P, MKTAG('I', '4', '2', '2') }, + { AV_PIX_FMT_YUV440P, MKTAG('I', '4', '4', '0') }, + { AV_PIX_FMT_YUV444P, MKTAG('I', '4', '4', '4') }, + { AV_PIX_FMT_YUVJ420P, MKTAG('J', '4', '2', '0') }, + { AV_PIX_FMT_YUVJ422P, MKTAG('J', '4', '2', '2') }, + { AV_PIX_FMT_YUVJ440P, MKTAG('J', '4', '4', '0') }, + { AV_PIX_FMT_YUVJ444P, MKTAG('J', '4', '4', '4') }, + { AV_PIX_FMT_YUVA444P, MKTAG('Y', 'U', 'V', 'A') }, + { AV_PIX_FMT_YUVA420P, MKTAG('I', '4', '0', 'A') }, + { AV_PIX_FMT_YUVA422P, MKTAG('I', '4', '2', 'A') }, + { AV_PIX_FMT_RGB8, MKTAG('R', 'G', 'B', '2') }, + { AV_PIX_FMT_RGB555LE, MKTAG('R', 'V', '1', '5') }, + { AV_PIX_FMT_RGB565LE, MKTAG('R', 'V', '1', '6') }, + { AV_PIX_FMT_BGR24, MKTAG('R', 'V', '2', '4') }, + { AV_PIX_FMT_BGR0, MKTAG('R', 'V', '3', '2') }, + { AV_PIX_FMT_RGBA, MKTAG('A', 'V', '3', '2') }, + { AV_PIX_FMT_YUV420P9LE, MKTAG('I', '0', '9', 'L') }, + { AV_PIX_FMT_YUV420P9BE, MKTAG('I', '0', '9', 'B') }, + { AV_PIX_FMT_YUV422P9LE, MKTAG('I', '2', '9', 'L') }, + { AV_PIX_FMT_YUV422P9BE, MKTAG('I', '2', '9', 'B') }, + { AV_PIX_FMT_YUV444P9LE, MKTAG('I', '4', '9', 'L') }, + { AV_PIX_FMT_YUV444P9BE, MKTAG('I', '4', '9', 'B') }, + { AV_PIX_FMT_YUV420P10LE, MKTAG('I', '0', 'A', 'L') }, + { AV_PIX_FMT_YUV420P10BE, MKTAG('I', '0', 'A', 'B') }, + { AV_PIX_FMT_YUV422P10LE, MKTAG('I', '2', 'A', 'L') }, + { AV_PIX_FMT_YUV422P10BE, MKTAG('I', '2', 'A', 'B') }, + { AV_PIX_FMT_YUV444P10LE, MKTAG('I', '4', 'A', 'L') }, + { AV_PIX_FMT_YUV444P10BE, MKTAG('I', '4', 'A', 'B') }, + { AV_PIX_FMT_YUV420P12LE, MKTAG('I', '0', 'C', 'L') }, + { AV_PIX_FMT_YUV420P12BE, MKTAG('I', '0', 'C', 'B') }, + { AV_PIX_FMT_YUV422P12LE, MKTAG('I', '2', 'C', 'L') }, + { AV_PIX_FMT_YUV422P12BE, MKTAG('I', '2', 'C', 'B') }, + { AV_PIX_FMT_YUV444P12LE, MKTAG('I', '4', 'C', 'L') }, + { AV_PIX_FMT_YUV444P12BE, MKTAG('I', '4', 'C', 'B') }, + { AV_PIX_FMT_YUV420P16LE, MKTAG('I', '0', 'F', 'L') }, + { AV_PIX_FMT_YUV420P16BE, MKTAG('I', '0', 'F', 'B') }, + { AV_PIX_FMT_YUV444P16LE, MKTAG('I', '4', 'F', 'L') }, + { AV_PIX_FMT_YUV444P16BE, MKTAG('I', '4', 'F', 'B') }, + + /* special */ + { AV_PIX_FMT_RGB565LE,MKTAG( 3 , 0 , 0 , 0 ) }, /* flipped RGB565LE */ + { AV_PIX_FMT_YUV444P, MKTAG('Y', 'V', '2', '4') }, /* YUV444P, swapped UV */ + + { AV_PIX_FMT_NONE, 0 }, +}; + +const struct PixelFormatTag *avpriv_get_raw_pix_fmt_tags(void) +{ + return ff_raw_pix_fmt_tags; +} + +unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat fmt) +{ + const PixelFormatTag *tags = ff_raw_pix_fmt_tags; + while (tags->pix_fmt >= 0) { + if (tags->pix_fmt == fmt) + return tags->fourcc; + tags++; + } + return 0; +} + +const PixelFormatTag avpriv_pix_fmt_bps_avi[] = { + { AV_PIX_FMT_PAL8, 1 }, + { AV_PIX_FMT_PAL8, 2 }, + { AV_PIX_FMT_PAL8, 4 }, + { AV_PIX_FMT_PAL8, 8 }, + { AV_PIX_FMT_RGB444LE, 12 }, + { AV_PIX_FMT_RGB555LE, 15 }, + { AV_PIX_FMT_RGB555LE, 16 }, + { AV_PIX_FMT_BGR24, 24 }, + { AV_PIX_FMT_BGRA, 32 }, + { AV_PIX_FMT_NONE, 0 }, +}; + +const PixelFormatTag avpriv_pix_fmt_bps_mov[] = { + { AV_PIX_FMT_PAL8, 1 }, + { AV_PIX_FMT_PAL8, 2 }, + { AV_PIX_FMT_PAL8, 4 }, + { AV_PIX_FMT_PAL8, 8 }, + { AV_PIX_FMT_RGB555BE, 16 }, + { AV_PIX_FMT_RGB24, 24 }, + { AV_PIX_FMT_ARGB, 32 }, + { AV_PIX_FMT_PAL8, 33 }, + { AV_PIX_FMT_NONE, 0 }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/raw.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/raw.h new file mode 100644 index 000000000..28a27b1f9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/raw.h @@ -0,0 +1,48 @@ +/* + * Raw Video Codec + * Copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Raw Video Codec + */ + +#ifndef AVCODEC_RAW_H +#define AVCODEC_RAW_H + +#include "avcodec.h" +#include "internal.h" +#include "libavutil/internal.h" + +typedef struct PixelFormatTag { + enum AVPixelFormat pix_fmt; + unsigned int fourcc; +} PixelFormatTag; + +extern const PixelFormatTag ff_raw_pix_fmt_tags[]; // exposed through avpriv_get_raw_pix_fmt_tags() + +const struct PixelFormatTag *avpriv_get_raw_pix_fmt_tags(void); + +enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc); + +extern av_export_avcodec const PixelFormatTag avpriv_pix_fmt_bps_avi[]; +extern av_export_avcodec const PixelFormatTag avpriv_pix_fmt_bps_mov[]; + +#endif /* AVCODEC_RAW_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rdft.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rdft.h new file mode 100644 index 000000000..ffafca7f2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rdft.h @@ -0,0 +1,52 @@ +/* + * (I)RDFT transforms + * Copyright (c) 2009 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(AVCODEC_RDFT_H) && (!defined(FFT_FLOAT) || FFT_FLOAT) +#define AVCODEC_RDFT_H + +#include "config.h" +#include "fft.h" + +struct RDFTContext { + int nbits; + int inverse; + int sign_convention; + + /* pre/post rotation tables */ + const FFTSample *tcos; + const FFTSample *tsin; + int negative_sin; + FFTContext fft; + void (*rdft_calc)(struct RDFTContext *s, FFTSample *z); +}; + +/** + * Set up a real FFT. + * @param nbits log2 of the length of the input array + * @param trans the type of transform + */ +int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans); +void ff_rdft_end(RDFTContext *s); + +void ff_rdft_init_arm(RDFTContext *s); + + +#endif /* AVCODEC_RDFT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.c new file mode 100644 index 000000000..6eac306b8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.c @@ -0,0 +1,147 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/mem.h" + +#include "rl.h" + +void ff_rl_free(RLTable *rl) +{ + int i; + + for (i = 0; i < 2; i++) { + av_freep(&rl->max_run[i]); + av_freep(&rl->max_level[i]); + av_freep(&rl->index_run[i]); + } +} + +av_cold int ff_rl_init(RLTable *rl, + uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3]) +{ + int8_t max_level[MAX_RUN + 1], max_run[MAX_LEVEL + 1]; + uint8_t index_run[MAX_RUN + 1]; + int last, run, level, start, end, i; + + /* If table is static, we can quit if rl->max_level[0] is not NULL */ + if (static_store && rl->max_level[0]) + return 0; + + /* compute max_level[], max_run[] and index_run[] */ + for (last = 0; last < 2; last++) { + if (last == 0) { + start = 0; + end = rl->last; + } else { + start = rl->last; + end = rl->n; + } + + memset(max_level, 0, MAX_RUN + 1); + memset(max_run, 0, MAX_LEVEL + 1); + memset(index_run, rl->n, MAX_RUN + 1); + for (i = start; i < end; i++) { + run = rl->table_run[i]; + level = rl->table_level[i]; + if (index_run[run] == rl->n) + index_run[run] = i; + if (level > max_level[run]) + max_level[run] = level; + if (run > max_run[level]) + max_run[level] = run; + } + if (static_store) + rl->max_level[last] = static_store[last]; + else { + rl->max_level[last] = av_malloc(MAX_RUN + 1); + if (!rl->max_level[last]) + goto fail; + } + memcpy(rl->max_level[last], max_level, MAX_RUN + 1); + if (static_store) + rl->max_run[last] = static_store[last] + MAX_RUN + 1; + else { + rl->max_run[last] = av_malloc(MAX_LEVEL + 1); + if (!rl->max_run[last]) + goto fail; + } + memcpy(rl->max_run[last], max_run, MAX_LEVEL + 1); + if (static_store) + rl->index_run[last] = static_store[last] + MAX_RUN + MAX_LEVEL + 2; + else { + rl->index_run[last] = av_malloc(MAX_RUN + 1); + if (!rl->index_run[last]) + goto fail; + } + memcpy(rl->index_run[last], index_run, MAX_RUN + 1); + } + return 0; + +fail: + ff_rl_free(rl); + return AVERROR(ENOMEM); +} + +av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size) +{ + int i, q; + VLC_TYPE table[1500][2] = {{0}}; + VLC vlc = { .table = table, .table_allocated = static_size }; + av_assert0(static_size <= FF_ARRAY_ELEMS(table)); + init_vlc(&vlc, 9, rl->n + 1, &rl->table_vlc[0][1], 4, 2, &rl->table_vlc[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC); + + for (q = 0; q < 32; q++) { + int qmul = q * 2; + int qadd = (q - 1) | 1; + + if (q == 0) { + qmul = 1; + qadd = 0; + } + for (i = 0; i < vlc.table_size; i++) { + int code = vlc.table[i][0]; + int len = vlc.table[i][1]; + int level, run; + + if (len == 0) { // illegal code + run = 66; + level = MAX_LEVEL; + } else if (len < 0) { // more bits needed + run = 0; + level = code; + } else { + if (code == rl->n) { // esc + run = 66; + level = 0; + } else { + run = rl->table_run[code] + 1; + level = rl->table_level[code] * qmul + qadd; + if (code >= rl->last) run += 192; + } + } + rl->rl_vlc[q][i].len = len; + rl->rl_vlc[q][i].level = level; + rl->rl_vlc[q][i].run = run; + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.h new file mode 100644 index 000000000..9a767bc5f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rl.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2000-2002 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * rl header. + */ + +#ifndef AVCODEC_RL_H +#define AVCODEC_RL_H + +#include + +#include "vlc.h" + +/* run length table */ +#define MAX_RUN 64 +#define MAX_LEVEL 64 + +/** RLTable. */ +typedef struct RLTable { + int n; ///< number of entries of table_vlc minus 1 + int last; ///< number of values for last = 0 + const uint16_t (*table_vlc)[2]; + const int8_t *table_run; + const int8_t *table_level; + uint8_t *index_run[2]; ///< encoding only + int8_t *max_level[2]; ///< encoding & decoding + int8_t *max_run[2]; ///< encoding & decoding + RL_VLC_ELEM *rl_vlc[32]; ///< decoding only +} RLTable; + +/** + * @param static_store static uint8_t array[2][2*MAX_RUN + MAX_LEVEL + 3] which will hold + * the level and run tables, if this is NULL av_malloc() will be used + */ +int ff_rl_init(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]); +void ff_rl_init_vlc(RLTable *rl, unsigned static_size); + +/** + * Free the contents of a dynamically allocated table. + */ +void ff_rl_free(RLTable *rl); + +#define INIT_VLC_RL(rl, static_size)\ +{\ + int q;\ + static RL_VLC_ELEM rl_vlc_table[32][static_size];\ +\ + if(!rl.rl_vlc[0]){\ + for(q=0; q<32; q++)\ + rl.rl_vlc[q]= rl_vlc_table[q];\ +\ + ff_rl_init_vlc(&rl, static_size);\ + }\ +} + +static inline int get_rl_index(const RLTable *rl, int last, int run, int level) +{ + int index; + index = rl->index_run[last][run]; + if (index >= rl->n) + return rl->n; + if (level > rl->max_level[last][run]) + return rl->n; + return index + level - 1; +} + +#endif /* AVCODEC_RL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rle.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rle.h new file mode 100644 index 000000000..a92edf7a2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/rle.h @@ -0,0 +1,51 @@ +/* + * RLE encoder + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_RLE_H +#define AVCODEC_RLE_H + +#include + +/** + * Count up to 127 consecutive pixels which are either all the same or + * all differ from the previous and next pixels. + * @param start Pointer to the first pixel + * @param len Maximum number of pixels + * @param bpp Bytes per pixel + * @param same 1 if searching for identical pixel values, 0 for differing + * @return Number of matching consecutive pixels found + */ +int ff_rle_count_pixels(const uint8_t *start, int len, int bpp, int same); + +/** + * RLE compress the row, with maximum size of out_size. + * Value before repeated bytes is (count ^ xor_rep) + add_rep. + * Value before raw bytes is (count ^ xor_raw) + add_raw. + * @param outbuf Output buffer + * @param out_size Maximum output size + * @param inbuf Input buffer + * @param bpp Bytes per pixel + * @param w Image width + * @return Size of output in bytes, or -1 if larger than out_size + */ +int ff_rle_encode(uint8_t *outbuf, int out_size, const uint8_t *inbuf, int bpp, + int w, int add_rep, int xor_rep, int add_raw, int xor_raw); + +#endif /* AVCODEC_RLE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbr.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbr.h new file mode 100644 index 000000000..eb7d1aec0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbr.h @@ -0,0 +1,217 @@ +/* + * Spectral Band Replication definitions and structures + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Spectral Band Replication definitions and structures + * @author Robert Swain ( rob opendot cl ) + */ + +#ifndef AVCODEC_SBR_H +#define AVCODEC_SBR_H + +#include +#include "fft.h" +#include "aacps.h" +#include "sbrdsp.h" + +typedef struct AACContext AACContext; + +/** + * Spectral Band Replication header - spectrum parameters that invoke a reset if they differ from the previous header. + */ +typedef struct SpectrumParameters { + uint8_t bs_start_freq; + uint8_t bs_stop_freq; + uint8_t bs_xover_band; + + /** + * @name Variables associated with bs_header_extra_1 + * @{ + */ + uint8_t bs_freq_scale; + uint8_t bs_alter_scale; + uint8_t bs_noise_bands; + /** @} */ +} SpectrumParameters; + +#define SBR_SYNTHESIS_BUF_SIZE ((1280-128)*2) + +/** + * Spectral Band Replication per channel data + */ +typedef struct SBRData { + /** + * @name Main bitstream data variables + * @{ + */ + unsigned bs_frame_class; + unsigned bs_add_harmonic_flag; + AAC_SIGNE bs_num_env; + uint8_t bs_freq_res[7]; + AAC_SIGNE bs_num_noise; + uint8_t bs_df_env[5]; + uint8_t bs_df_noise[2]; + uint8_t bs_invf_mode[2][5]; + uint8_t bs_add_harmonic[48]; + unsigned bs_amp_res; + /** @} */ + + /** + * @name State variables + * @{ + */ + DECLARE_ALIGNED(32, INTFLOAT, synthesis_filterbank_samples)[SBR_SYNTHESIS_BUF_SIZE]; + DECLARE_ALIGNED(32, INTFLOAT, analysis_filterbank_samples) [1312]; + int synthesis_filterbank_samples_offset; + ///l_APrev and l_A + int e_a[2]; + ///Chirp factors + INTFLOAT bw_array[5]; + ///QMF values of the original signal + INTFLOAT W[2][32][32][2]; + ///QMF output of the HF adjustor + int Ypos; + DECLARE_ALIGNED(16, INTFLOAT, Y)[2][38][64][2]; + DECLARE_ALIGNED(16, AAC_FLOAT, g_temp)[42][48]; + AAC_FLOAT q_temp[42][48]; + uint8_t s_indexmapped[8][48]; + ///Envelope scalefactors + uint8_t env_facs_q[6][48]; + AAC_FLOAT env_facs[6][48]; + ///Noise scalefactors + uint8_t noise_facs_q[3][5]; + AAC_FLOAT noise_facs[3][5]; + ///Envelope time borders + uint8_t t_env[8]; + ///Envelope time border of the last envelope of the previous frame + uint8_t t_env_num_env_old; + ///Noise time borders + uint8_t t_q[3]; + unsigned f_indexnoise; + unsigned f_indexsine; + /** @} */ +} SBRData; + +typedef struct SpectralBandReplication SpectralBandReplication; + +/** + * aacsbr functions pointers + */ +typedef struct AACSBRContext { + int (*sbr_lf_gen)(AACContext *ac, SpectralBandReplication *sbr, + INTFLOAT X_low[32][40][2], const INTFLOAT W[2][32][32][2], + int buf_idx); + void (*sbr_hf_assemble)(INTFLOAT Y1[38][64][2], + const INTFLOAT X_high[64][40][2], + SpectralBandReplication *sbr, SBRData *ch_data, + const int e_a[2]); + int (*sbr_x_gen)(SpectralBandReplication *sbr, INTFLOAT X[2][38][64], + const INTFLOAT Y0[38][64][2], const INTFLOAT Y1[38][64][2], + const INTFLOAT X_low[32][40][2], int ch); + void (*sbr_hf_inverse_filter)(SBRDSPContext *dsp, + INTFLOAT (*alpha0)[2], INTFLOAT (*alpha1)[2], + const INTFLOAT X_low[32][40][2], int k0); +} AACSBRContext; + +/** + * Spectral Band Replication + */ +struct SpectralBandReplication { + int sample_rate; + int start; + int ready_for_dequant; + int id_aac; + int reset; + SpectrumParameters spectrum_params; + int bs_amp_res_header; + /** + * @name Variables associated with bs_header_extra_2 + * @{ + */ + unsigned bs_limiter_bands; + unsigned bs_limiter_gains; + unsigned bs_interpol_freq; + unsigned bs_smoothing_mode; + /** @} */ + unsigned bs_coupling; + AAC_SIGNE k[5]; ///< k0, k1, k2 + ///kx', and kx respectively, kx is the first QMF subband where SBR is used. + ///kx' is its value from the previous frame + AAC_SIGNE kx[2]; + ///M' and M respectively, M is the number of QMF subbands that use SBR. + AAC_SIGNE m[2]; + unsigned kx_and_m_pushed; + ///The number of frequency bands in f_master + AAC_SIGNE n_master; + SBRData data[2]; + PSContext ps; + ///N_Low and N_High respectively, the number of frequency bands for low and high resolution + AAC_SIGNE n[2]; + ///Number of noise floor bands + AAC_SIGNE n_q; + ///Number of limiter bands + AAC_SIGNE n_lim; + ///The master QMF frequency grouping + uint16_t f_master[49]; + ///Frequency borders for low resolution SBR + uint16_t f_tablelow[25]; + ///Frequency borders for high resolution SBR + uint16_t f_tablehigh[49]; + ///Frequency borders for noise floors + uint16_t f_tablenoise[6]; + ///Frequency borders for the limiter + uint16_t f_tablelim[30]; + AAC_SIGNE num_patches; + uint8_t patch_num_subbands[6]; + uint8_t patch_start_subband[6]; + ///QMF low frequency input to the HF generator + DECLARE_ALIGNED(16, INTFLOAT, X_low)[32][40][2]; + ///QMF output of the HF generator + DECLARE_ALIGNED(16, INTFLOAT, X_high)[64][40][2]; + ///QMF values of the reconstructed signal + DECLARE_ALIGNED(16, INTFLOAT, X)[2][2][38][64]; + ///Zeroth coefficient used to filter the subband signals + DECLARE_ALIGNED(16, INTFLOAT, alpha0)[64][2]; + ///First coefficient used to filter the subband signals + DECLARE_ALIGNED(16, INTFLOAT, alpha1)[64][2]; + ///Dequantized envelope scalefactors, remapped + AAC_FLOAT e_origmapped[7][48]; + ///Dequantized noise scalefactors, remapped + AAC_FLOAT q_mapped[7][48]; + ///Sinusoidal presence, remapped + uint8_t s_mapped[7][48]; + ///Estimated envelope + AAC_FLOAT e_curr[7][48]; + ///Amplitude adjusted noise scalefactors + AAC_FLOAT q_m[7][48]; + ///Sinusoidal levels + AAC_FLOAT s_m[7][48]; + AAC_FLOAT gain[7][48]; + DECLARE_ALIGNED(32, INTFLOAT, qmf_filter_scratch)[5][64]; + FFTContext mdct_ana; + FFTContext mdct; + SBRDSPContext dsp; + AACSBRContext c; +}; + +#endif /* AVCODEC_SBR_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.asm new file mode 100644 index 000000000..62bbe512e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.asm @@ -0,0 +1,548 @@ +;****************************************************************************** +;* AAC Spectral Band Replication decoding functions +;* Copyright (C) 2012 Christophe Gisquet +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA +; mask equivalent for multiply by -1.0 1.0 +ps_mask times 2 dd 1<<31, 0 +ps_mask2 times 2 dd 0, 1<<31 +ps_mask3 dd 0, 0, 0, 1<<31 +ps_noise0 times 2 dd 1.0, 0.0, +ps_noise2 times 2 dd -1.0, 0.0 +ps_noise13 dd 0.0, 1.0, 0.0, -1.0 + dd 0.0, -1.0, 0.0, 1.0 + dd 0.0, 1.0, 0.0, -1.0 +cextern sbr_noise_table +cextern ps_neg + +SECTION .text + +INIT_XMM sse +cglobal sbr_sum_square, 2, 3, 6 + mov r2d, r1d + xorps m0, m0 + xorps m1, m1 + sar r2, 3 + jz .prepare +.loop: + movu m2, [r0 + 0] + movu m3, [r0 + 16] + movu m4, [r0 + 32] + movu m5, [r0 + 48] + mulps m2, m2 + mulps m3, m3 + mulps m4, m4 + mulps m5, m5 + addps m0, m2 + addps m1, m3 + addps m0, m4 + addps m1, m5 + add r0, 64 + dec r2 + jnz .loop +.prepare: + and r1, 7 + sar r1, 1 + jz .end +; len is a multiple of 2, thus there are at least 4 elements to process +.endloop: + movu m2, [r0] + add r0, 16 + mulps m2, m2 + dec r1 + addps m0, m2 + jnz .endloop +.end: + addps m0, m1 + movhlps m2, m0 + addps m0, m2 + movss m1, m0 + shufps m0, m0, 1 + addss m0, m1 +%if ARCH_X86_64 == 0 + movss r0m, m0 + fld dword r0m +%endif + RET + +%define STEP 40*4*2 +cglobal sbr_hf_g_filt, 5, 6, 5 + lea r1, [r1 + 8*r4] ; offset by ixh elements into X_high + mov r5, r3 + and r3, 0xFC + lea r2, [r2 + r3*4] + lea r0, [r0 + r3*8] + neg r3 + jz .loop1 +.loop4: + movlps m0, [r2 + 4*r3 + 0] + movlps m1, [r2 + 4*r3 + 8] + movlps m2, [r1 + 0*STEP] + movlps m3, [r1 + 2*STEP] + movhps m2, [r1 + 1*STEP] + movhps m3, [r1 + 3*STEP] + unpcklps m0, m0 + unpcklps m1, m1 + mulps m0, m2 + mulps m1, m3 + movu [r0 + 8*r3 + 0], m0 + movu [r0 + 8*r3 + 16], m1 + add r1, 4*STEP + add r3, 4 + jnz .loop4 + and r5, 3 ; number of single element loops + jz .end +.loop1: ; element 0 and 1 can be computed at the same time + movss m0, [r2] + movlps m2, [r1] + unpcklps m0, m0 + mulps m2, m0 + movlps [r0], m2 + add r0, 8 + add r2, 4 + add r1, STEP + dec r5 + jnz .loop1 +.end: + RET + +; void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2], +; const float alpha0[2], const float alpha1[2], +; float bw, int start, int end) +; +cglobal sbr_hf_gen, 4,4,8, X_high, X_low, alpha0, alpha1, BW, S, E + ; load alpha factors +%define bw m0 +%if ARCH_X86_64 == 0 || WIN64 + movss bw, BWm +%endif + movlps m2, [alpha1q] + movlps m1, [alpha0q] + shufps bw, bw, 0 + mulps m2, bw ; (a1[0] a1[1])*bw + mulps m1, bw ; (a0[0] a0[1])*bw = (a2 a3) + mulps m2, bw ; (a1[0] a1[1])*bw*bw = (a0 a1) + mova m3, m1 + mova m4, m2 + + ; Set pointers +%if ARCH_X86_64 == 0 || WIN64 + ; start and end 6th and 7th args on stack + mov r2d, Sm + mov r3d, Em + DEFINE_ARGS X_high, X_low, start, end +%else +; BW does not actually occupy a register, so shift by 1 + DEFINE_ARGS X_high, X_low, alpha0, alpha1, start, end + movsxd startq, startd + movsxd endq, endd +%endif + sub startq, endq ; neg num of loops + lea X_highq, [X_highq + endq*2*4] + lea X_lowq, [X_lowq + endq*2*4 - 2*2*4] + shl startq, 3 ; offset from num loops + + mova m0, [X_lowq + startq] + shufps m3, m3, q1111 + shufps m4, m4, q1111 + xorps m3, [ps_mask] + shufps m1, m1, q0000 + shufps m2, m2, q0000 + xorps m4, [ps_mask] +.loop2: + movu m7, [X_lowq + startq + 8] ; BbCc + mova m6, m0 + mova m5, m7 + shufps m0, m0, q2301 ; aAbB + shufps m7, m7, q2301 ; bBcC + mulps m0, m4 + mulps m7, m3 + mulps m6, m2 + mulps m5, m1 + addps m7, m0 + mova m0, [X_lowq + startq + 16] ; CcDd + addps m7, m0 + addps m6, m5 + addps m7, m6 + mova [X_highq + startq], m7 + add startq, 16 + jnz .loop2 + RET + +cglobal sbr_sum64x5, 1,2,4,z + lea r1q, [zq+ 256] +.loop: + mova m0, [zq+ 0] + mova m2, [zq+ 16] + mova m1, [zq+ 256] + mova m3, [zq+ 272] + addps m0, [zq+ 512] + addps m2, [zq+ 528] + addps m1, [zq+ 768] + addps m3, [zq+ 784] + addps m0, [zq+1024] + addps m2, [zq+1040] + addps m0, m1 + addps m2, m3 + mova [zq], m0 + mova [zq+16], m2 + add zq, 32 + cmp zq, r1q + jne .loop + REP_RET + +INIT_XMM sse +cglobal sbr_qmf_post_shuffle, 2,3,4,W,z + lea r2q, [zq + (64-4)*4] + mova m3, [ps_neg] +.loop: + mova m1, [zq] + xorps m0, m3, [r2q] + shufps m0, m0, m0, q0123 + unpcklps m2, m0, m1 + unpckhps m0, m0, m1 + mova [Wq + 0], m2 + mova [Wq + 16], m0 + add Wq, 32 + sub r2q, 16 + add zq, 16 + cmp zq, r2q + jl .loop + REP_RET + +INIT_XMM sse +cglobal sbr_neg_odd_64, 1,2,4,z + lea r1q, [zq+256] +.loop: + mova m0, [zq+ 0] + mova m1, [zq+16] + mova m2, [zq+32] + mova m3, [zq+48] + xorps m0, [ps_mask2] + xorps m1, [ps_mask2] + xorps m2, [ps_mask2] + xorps m3, [ps_mask2] + mova [zq+ 0], m0 + mova [zq+16], m1 + mova [zq+32], m2 + mova [zq+48], m3 + add zq, 64 + cmp zq, r1q + jne .loop + REP_RET + +; void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1) +%macro SBR_QMF_DEINT_BFLY 0 +cglobal sbr_qmf_deint_bfly, 3,5,8, v,src0,src1,vrev,c + mov cq, 64*4-2*mmsize + lea vrevq, [vq + 64*4] +.loop: + mova m0, [src0q+cq] + mova m1, [src1q] + mova m4, [src0q+cq+mmsize] + mova m5, [src1q+mmsize] +%if cpuflag(sse2) + pshufd m2, m0, q0123 + pshufd m3, m1, q0123 + pshufd m6, m4, q0123 + pshufd m7, m5, q0123 +%else + shufps m2, m0, m0, q0123 + shufps m3, m1, m1, q0123 + shufps m6, m4, m4, q0123 + shufps m7, m5, m5, q0123 +%endif + addps m5, m2 + subps m0, m7 + addps m1, m6 + subps m4, m3 + mova [vrevq], m1 + mova [vrevq+mmsize], m5 + mova [vq+cq], m0 + mova [vq+cq+mmsize], m4 + add src1q, 2*mmsize + add vrevq, 2*mmsize + sub cq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +SBR_QMF_DEINT_BFLY + +INIT_XMM sse2 +SBR_QMF_DEINT_BFLY + +INIT_XMM sse2 +cglobal sbr_qmf_pre_shuffle, 1,4,6,z +%define OFFSET (32*4-2*mmsize) + mov r3q, OFFSET + lea r1q, [zq + (32+1)*4] + lea r2q, [zq + 64*4] + mova m5, [ps_neg] +.loop: + movu m0, [r1q] + movu m2, [r1q + mmsize] + movu m1, [zq + r3q + 4 + mmsize] + movu m3, [zq + r3q + 4] + + pxor m2, m5 + pxor m0, m5 + pshufd m2, m2, q0123 + pshufd m0, m0, q0123 + SBUTTERFLY dq, 2, 3, 4 + SBUTTERFLY dq, 0, 1, 4 + mova [r2q + 2*r3q + 0*mmsize], m2 + mova [r2q + 2*r3q + 1*mmsize], m3 + mova [r2q + 2*r3q + 2*mmsize], m0 + mova [r2q + 2*r3q + 3*mmsize], m1 + add r1q, 2*mmsize + sub r3q, 2*mmsize + jge .loop + movq m2, [zq] + movq [r2q], m2 + REP_RET + +%ifdef PIC +%define NREGS 1 +%if UNIX64 +%define NOISE_TABLE r6q ; r5q is m_max +%else +%define NOISE_TABLE r5q +%endif +%else +%define NREGS 0 +%define NOISE_TABLE sbr_noise_table +%endif + +%macro LOAD_NST 1 +%ifdef PIC + lea NOISE_TABLE, [%1] + mova m0, [kxq + NOISE_TABLE] +%else + mova m0, [kxq + %1] +%endif +%endmacro + +INIT_XMM sse2 +; sbr_hf_apply_noise_0(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_0, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + mova m0, [ps_noise0] + jmp apply_noise_main + +; sbr_hf_apply_noise_1(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_1, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + and kxq, 1 + shl kxq, 4 + LOAD_NST ps_noise13 + jmp apply_noise_main + +; sbr_hf_apply_noise_2(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_2, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + mova m0, [ps_noise2] + jmp apply_noise_main + +; sbr_hf_apply_noise_3(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_3, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + and kxq, 1 + shl kxq, 4 + LOAD_NST ps_noise13+16 + +apply_noise_main: +%if ARCH_X86_64 == 0 || WIN64 + mov kxd, m_maxm + DEFINE_ARGS Y, s_m, q_filt, noise, count +%else + DEFINE_ARGS Y, s_m, q_filt, noise, kx, count +%endif + movsxdifnidn noiseq, noised + dec noiseq + shl countd, 2 +%ifdef PIC + lea NOISE_TABLE, [sbr_noise_table] +%endif + lea Yq, [Yq + 2*countq] + add s_mq, countq + add q_filtq, countq + shl noiseq, 3 + pxor m5, m5 + neg countq +.loop: + mova m1, [q_filtq + countq] + movu m3, [noiseq + NOISE_TABLE + 1*mmsize] + movu m4, [noiseq + NOISE_TABLE + 2*mmsize] + add noiseq, 2*mmsize + and noiseq, 0x1ff<<3 + punpckhdq m2, m1, m1 + punpckldq m1, m1 + mulps m1, m3 ; m2 = q_filt[m] * ff_sbr_noise_table[noise] + mulps m2, m4 ; m2 = q_filt[m] * ff_sbr_noise_table[noise] + mova m3, [s_mq + countq] + ; TODO: replace by a vpermd in AVX2 + punpckhdq m4, m3, m3 + punpckldq m3, m3 + pcmpeqd m6, m3, m5 ; m6 == 0 + pcmpeqd m7, m4, m5 ; m7 == 0 + mulps m3, m0 ; s_m[m] * phi_sign + mulps m4, m0 ; s_m[m] * phi_sign + pand m1, m6 + pand m2, m7 + movu m6, [Yq + 2*countq] + movu m7, [Yq + 2*countq + mmsize] + addps m3, m1 + addps m4, m2 + addps m6, m3 + addps m7, m4 + movu [Yq + 2*countq], m6 + movu [Yq + 2*countq + mmsize], m7 + add countq, mmsize + jl .loop + RET + +INIT_XMM sse +cglobal sbr_qmf_deint_neg, 2,4,4,v,src,vrev,c +%define COUNT 32*4 +%define OFFSET 32*4 + mov cq, -COUNT + lea vrevq, [vq + OFFSET + COUNT] + add vq, OFFSET-mmsize + add srcq, 2*COUNT + mova m3, [ps_neg] +.loop: + mova m0, [srcq + 2*cq + 0*mmsize] + mova m1, [srcq + 2*cq + 1*mmsize] + shufps m2, m0, m1, q2020 + shufps m1, m0, q1313 + xorps m2, m3 + mova [vq], m1 + mova [vrevq + cq], m2 + sub vq, mmsize + add cq, mmsize + jl .loop + REP_RET + +%macro SBR_AUTOCORRELATE 0 +cglobal sbr_autocorrelate, 2,3,8,32, x, phi, cnt + mov cntq, 37*8 + add xq, cntq + neg cntq + +%if cpuflag(sse3) +%define MOVH movsd + movddup m5, [xq+cntq] +%else +%define MOVH movlps + movlps m5, [xq+cntq] + movlhps m5, m5 +%endif + MOVH m7, [xq+cntq+8 ] + MOVH m1, [xq+cntq+16] + shufps m7, m7, q0110 + shufps m1, m1, q0110 + mulps m3, m5, m7 ; x[0][0] * x[1][0], x[0][1] * x[1][1], x[0][0] * x[1][1], x[0][1] * x[1][0] + mulps m4, m5, m5 ; x[0][0] * x[0][0], x[0][1] * x[0][1]; + mulps m5, m1 ; real_sum2 = x[0][0] * x[2][0], x[0][1] * x[2][1]; imag_sum2 = x[0][0] * x[2][1], x[0][1] * x[2][0] + movaps [rsp ], m3 + movaps [rsp+16], m4 + add cntq, 8 + + MOVH m2, [xq+cntq+16] + movlhps m7, m7 + shufps m2, m2, q0110 + mulps m6, m7, m1 ; real_sum1 = x[1][0] * x[2][0], x[1][1] * x[2][1]; imag_sum1 += x[1][0] * x[2][1], x[1][1] * x[2][0] + mulps m4, m7, m2 + mulps m7, m7 ; real_sum0 = x[1][0] * x[1][0], x[1][1] * x[1][1]; + addps m5, m4 ; real_sum2 += x[1][0] * x[3][0], x[1][1] * x[3][1]; imag_sum2 += x[1][0] * x[3][1], x[1][1] * x[3][0] + +align 16 +.loop: + add cntq, 8 + MOVH m0, [xq+cntq+16] + movlhps m1, m1 + shufps m0, m0, q0110 + mulps m3, m1, m2 + mulps m4, m1, m0 + mulps m1, m1 + addps m6, m3 ; real_sum1 += x[i][0] * x[i + 1][0], x[i][1] * x[i + 1][1]; imag_sum1 += x[i][0] * x[i + 1][1], x[i][1] * x[i + 1][0]; + addps m5, m4 ; real_sum2 += x[i][0] * x[i + 2][0], x[i][1] * x[i + 2][1]; imag_sum2 += x[i][0] * x[i + 2][1], x[i][1] * x[i + 2][0]; + addps m7, m1 ; real_sum0 += x[i][0] * x[i][0], x[i][1] * x[i][1]; + add cntq, 8 + MOVH m1, [xq+cntq+16] + movlhps m2, m2 + shufps m1, m1, q0110 + mulps m3, m2, m0 + mulps m4, m2, m1 + mulps m2, m2 + addps m6, m3 ; real_sum1 += x[i][0] * x[i + 1][0], x[i][1] * x[i + 1][1]; imag_sum1 += x[i][0] * x[i + 1][1], x[i][1] * x[i + 1][0]; + addps m5, m4 ; real_sum2 += x[i][0] * x[i + 2][0], x[i][1] * x[i + 2][1]; imag_sum2 += x[i][0] * x[i + 2][1], x[i][1] * x[i + 2][0]; + addps m7, m2 ; real_sum0 += x[i][0] * x[i][0], x[i][1] * x[i][1]; + add cntq, 8 + MOVH m2, [xq+cntq+16] + movlhps m0, m0 + shufps m2, m2, q0110 + mulps m3, m0, m1 + mulps m4, m0, m2 + mulps m0, m0 + addps m6, m3 ; real_sum1 += x[i][0] * x[i + 1][0], x[i][1] * x[i + 1][1]; imag_sum1 += x[i][0] * x[i + 1][1], x[i][1] * x[i + 1][0]; + addps m5, m4 ; real_sum2 += x[i][0] * x[i + 2][0], x[i][1] * x[i + 2][1]; imag_sum2 += x[i][0] * x[i + 2][1], x[i][1] * x[i + 2][0]; + addps m7, m0 ; real_sum0 += x[i][0] * x[i][0], x[i][1] * x[i][1]; + jl .loop + + movlhps m1, m1 + mulps m2, m1 + mulps m1, m1 + addps m2, m6 ; real_sum1 + x[38][0] * x[39][0], x[38][1] * x[39][1]; imag_sum1 + x[38][0] * x[39][1], x[38][1] * x[39][0]; + addps m1, m7 ; real_sum0 + x[38][0] * x[38][0], x[38][1] * x[38][1]; + addps m6, [rsp ] ; real_sum1 + x[ 0][0] * x[ 1][0], x[ 0][1] * x[ 1][1]; imag_sum1 + x[ 0][0] * x[ 1][1], x[ 0][1] * x[ 1][0]; + addps m7, [rsp+16] ; real_sum0 + x[ 0][0] * x[ 0][0], x[ 0][1] * x[ 0][1]; + + xorps m2, [ps_mask3] + xorps m5, [ps_mask3] + xorps m6, [ps_mask3] + HADDPS m2, m5, m3 + HADDPS m7, m6, m4 +%if cpuflag(sse3) + movshdup m0, m1 +%else + movss m0, m1 + shufps m1, m1, q0001 +%endif + addss m1, m0 + movaps [phiq ], m2 + movhps [phiq+0x18], m7 + movss [phiq+0x28], m7 + movss [phiq+0x10], m1 + RET +%endmacro + +INIT_XMM sse +SBR_AUTOCORRELATE +INIT_XMM sse3 +SBR_AUTOCORRELATE diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.c new file mode 100644 index 000000000..a93b5f9c1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.c @@ -0,0 +1,225 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2009-2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 0 + +#include "aac.h" +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/intfloat.h" +#include "sbrdsp.h" + +static float sbr_sum_square_c(float (*x)[2], int n) +{ + float sum0 = 0.0f, sum1 = 0.0f; + int i; + + for (i = 0; i < n; i += 2) + { + sum0 += x[i + 0][0] * x[i + 0][0]; + sum1 += x[i + 0][1] * x[i + 0][1]; + sum0 += x[i + 1][0] * x[i + 1][0]; + sum1 += x[i + 1][1] * x[i + 1][1]; + } + + return sum0 + sum1; +} + +static void sbr_neg_odd_64_c(float *x) +{ + union av_intfloat32 *xi = (union av_intfloat32*) x; + int i; + for (i = 1; i < 64; i += 4) { + xi[i + 0].i ^= 1U << 31; + xi[i + 2].i ^= 1U << 31; + } +} + +static void sbr_qmf_pre_shuffle_c(float *z) +{ + union av_intfloat32 *zi = (union av_intfloat32*) z; + int k; + zi[64].i = zi[0].i; + zi[65].i = zi[1].i; + for (k = 1; k < 31; k += 2) { + zi[64 + 2 * k + 0].i = zi[64 - k].i ^ (1U << 31); + zi[64 + 2 * k + 1].i = zi[ k + 1].i; + zi[64 + 2 * k + 2].i = zi[63 - k].i ^ (1U << 31); + zi[64 + 2 * k + 3].i = zi[ k + 2].i; + } + + zi[64 + 2 * 31 + 0].i = zi[64 - 31].i ^ (1U << 31); + zi[64 + 2 * 31 + 1].i = zi[31 + 1].i; +} + +static void sbr_qmf_post_shuffle_c(float W[32][2], const float *z) +{ + const union av_intfloat32 *zi = (const union av_intfloat32*) z; + union av_intfloat32 *Wi = (union av_intfloat32*) W; + int k; + for (k = 0; k < 32; k += 2) { + Wi[2 * k + 0].i = zi[63 - k].i ^ (1U << 31); + Wi[2 * k + 1].i = zi[ k + 0].i; + Wi[2 * k + 2].i = zi[62 - k].i ^ (1U << 31); + Wi[2 * k + 3].i = zi[ k + 1].i; + } +} + +static void sbr_qmf_deint_neg_c(float *v, const float *src) +{ + const union av_intfloat32 *si = (const union av_intfloat32*)src; + union av_intfloat32 *vi = (union av_intfloat32*)v; + int i; + for (i = 0; i < 32; i++) { + vi[ i].i = si[63 - 2 * i ].i; + vi[63 - i].i = si[63 - 2 * i - 1].i ^ (1U << 31); + } +} + +#if 0 + /* This code is slower because it multiplies memory accesses. + * It is left for educational purposes and because it may offer + * a better reference for writing arch-specific DSP functions. */ +static av_always_inline void autocorrelate(const float x[40][2], + float phi[3][2][2], int lag) +{ + int i; + float real_sum = 0.0f; + float imag_sum = 0.0f; + if (lag) { + for (i = 1; i < 38; i++) { + real_sum += x[i][0] * x[i+lag][0] + x[i][1] * x[i+lag][1]; + imag_sum += x[i][0] * x[i+lag][1] - x[i][1] * x[i+lag][0]; + } + phi[2-lag][1][0] = real_sum + x[ 0][0] * x[lag][0] + x[ 0][1] * x[lag][1]; + phi[2-lag][1][1] = imag_sum + x[ 0][0] * x[lag][1] - x[ 0][1] * x[lag][0]; + if (lag == 1) { + phi[0][0][0] = real_sum + x[38][0] * x[39][0] + x[38][1] * x[39][1]; + phi[0][0][1] = imag_sum + x[38][0] * x[39][1] - x[38][1] * x[39][0]; + } + } else { + for (i = 1; i < 38; i++) { + real_sum += x[i][0] * x[i][0] + x[i][1] * x[i][1]; + } + phi[2][1][0] = real_sum + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1]; + phi[1][0][0] = real_sum + x[38][0] * x[38][0] + x[38][1] * x[38][1]; + } +} + +static void sbr_autocorrelate_c(const float x[40][2], float phi[3][2][2]) +{ + autocorrelate(x, phi, 0); + autocorrelate(x, phi, 1); + autocorrelate(x, phi, 2); +} +#else +static void sbr_autocorrelate_c(const float x[40][2], float phi[3][2][2]) +{ + float real_sum2 = x[0][0] * x[2][0] + x[0][1] * x[2][1]; + float imag_sum2 = x[0][0] * x[2][1] - x[0][1] * x[2][0]; + float real_sum1 = 0.0f, imag_sum1 = 0.0f, real_sum0 = 0.0f; + int i; + for (i = 1; i < 38; i++) { + real_sum0 += x[i][0] * x[i ][0] + x[i][1] * x[i ][1]; + real_sum1 += x[i][0] * x[i + 1][0] + x[i][1] * x[i + 1][1]; + imag_sum1 += x[i][0] * x[i + 1][1] - x[i][1] * x[i + 1][0]; + real_sum2 += x[i][0] * x[i + 2][0] + x[i][1] * x[i + 2][1]; + imag_sum2 += x[i][0] * x[i + 2][1] - x[i][1] * x[i + 2][0]; + } + phi[2 - 2][1][0] = real_sum2; + phi[2 - 2][1][1] = imag_sum2; + phi[2 ][1][0] = real_sum0 + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1]; + phi[1 ][0][0] = real_sum0 + x[38][0] * x[38][0] + x[38][1] * x[38][1]; + phi[2 - 1][1][0] = real_sum1 + x[ 0][0] * x[ 1][0] + x[ 0][1] * x[ 1][1]; + phi[2 - 1][1][1] = imag_sum1 + x[ 0][0] * x[ 1][1] - x[ 0][1] * x[ 1][0]; + phi[0 ][0][0] = real_sum1 + x[38][0] * x[39][0] + x[38][1] * x[39][1]; + phi[0 ][0][1] = imag_sum1 + x[38][0] * x[39][1] - x[38][1] * x[39][0]; +} +#endif + +static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2], + const float alpha0[2], const float alpha1[2], + float bw, int start, int end) +{ + float alpha[4]; + int i; + + alpha[0] = alpha1[0] * bw * bw; + alpha[1] = alpha1[1] * bw * bw; + alpha[2] = alpha0[0] * bw; + alpha[3] = alpha0[1] * bw; + + for (i = start; i < end; i++) { + X_high[i][0] = + X_low[i - 2][0] * alpha[0] - + X_low[i - 2][1] * alpha[1] + + X_low[i - 1][0] * alpha[2] - + X_low[i - 1][1] * alpha[3] + + X_low[i][0]; + X_high[i][1] = + X_low[i - 2][1] * alpha[0] + + X_low[i - 2][0] * alpha[1] + + X_low[i - 1][1] * alpha[2] + + X_low[i - 1][0] * alpha[3] + + X_low[i][1]; + } +} + +static void sbr_hf_g_filt_c(float (*Y)[2], const float (*X_high)[40][2], + const float *g_filt, int m_max, intptr_t ixh) +{ + int m; + + for (m = 0; m < m_max; m++) { + Y[m][0] = X_high[m][ixh][0] * g_filt[m]; + Y[m][1] = X_high[m][ixh][1] * g_filt[m]; + } +} + +static av_always_inline void sbr_hf_apply_noise(float (*Y)[2], + const float *s_m, + const float *q_filt, + int noise, + float phi_sign0, + float phi_sign1, + int m_max) +{ + int m; + + for (m = 0; m < m_max; m++) { + float y0 = Y[m][0]; + float y1 = Y[m][1]; + noise = (noise + 1) & 0x1ff; + if (s_m[m]) { + y0 += s_m[m] * phi_sign0; + y1 += s_m[m] * phi_sign1; + } else { + y0 += q_filt[m] * ff_sbr_noise_table[noise][0]; + y1 += q_filt[m] * ff_sbr_noise_table[noise][1]; + } + Y[m][0] = y0; + Y[m][1] = y1; + phi_sign1 = -phi_sign1; + } +} + +#include "sbrdsp_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.h new file mode 100644 index 000000000..e6fd76d8e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_SBRDSP_H +#define AVCODEC_SBRDSP_H + +#include +#include "aac_defines.h" +#include "libavutil/softfloat.h" + +typedef struct SBRDSPContext { + void (*sum64x5)(INTFLOAT *z); + AAC_FLOAT (*sum_square)(INTFLOAT (*x)[2], int n); + void (*neg_odd_64)(INTFLOAT *x); + void (*qmf_pre_shuffle)(INTFLOAT *z); + void (*qmf_post_shuffle)(INTFLOAT W[32][2], const INTFLOAT *z); + void (*qmf_deint_neg)(INTFLOAT *v, const INTFLOAT *src); + void (*qmf_deint_bfly)(INTFLOAT *v, const INTFLOAT *src0, const INTFLOAT *src1); + void (*autocorrelate)(const INTFLOAT x[40][2], AAC_FLOAT phi[3][2][2]); + void (*hf_gen)(INTFLOAT (*X_high)[2], const INTFLOAT (*X_low)[2], + const INTFLOAT alpha0[2], const INTFLOAT alpha1[2], + INTFLOAT bw, int start, int end); + void (*hf_g_filt)(INTFLOAT (*Y)[2], const INTFLOAT (*X_high)[40][2], + const AAC_FLOAT *g_filt, int m_max, intptr_t ixh); + void (*hf_apply_noise[4])(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m, + const AAC_FLOAT *q_filt, int noise, + int kx, int m_max); +} SBRDSPContext; + +extern const INTFLOAT AAC_RENAME(ff_sbr_noise_table)[][2]; + +void AAC_RENAME(ff_sbrdsp_init)(SBRDSPContext *s); +void ff_sbrdsp_init_arm(SBRDSPContext *s); +void ff_sbrdsp_init_aarch64(SBRDSPContext *s); +void ff_sbrdsp_init_x86(SBRDSPContext *s); +void ff_sbrdsp_init_mips(SBRDSPContext *s); + +#endif /* AVCODEC_SBRDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_fixed.c new file mode 100644 index 000000000..91fa664c0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_fixed.c @@ -0,0 +1,315 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2009-2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Note: Rounding-to-nearest used unless otherwise stated + * + */ + +#define USE_FIXED 1 + +#include "aac.h" +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/intfloat.h" +#include "sbrdsp.h" + +static SoftFloat sbr_sum_square_c(int (*x)[2], int n) +{ + SoftFloat ret; + uint64_t accu = 0, round; + uint64_t accu0 = 0, accu1 = 0, accu2 = 0, accu3 = 0; + int i, nz, nz0; + unsigned u; + + nz = 0; + for (i = 0; i < n; i += 2) { + accu0 += (int64_t)x[i + 0][0] * x[i + 0][0]; + accu1 += (int64_t)x[i + 0][1] * x[i + 0][1]; + accu2 += (int64_t)x[i + 1][0] * x[i + 1][0]; + accu3 += (int64_t)x[i + 1][1] * x[i + 1][1]; + if ((accu0|accu1|accu2|accu3) > UINT64_MAX - INT32_MIN*(int64_t)INT32_MIN || i+2>=n) { + accu0 >>= nz; + accu1 >>= nz; + accu2 >>= nz; + accu3 >>= nz; + while ((accu0|accu1|accu2|accu3) > (UINT64_MAX - accu) >> 2) { + accu0 >>= 1; + accu1 >>= 1; + accu2 >>= 1; + accu3 >>= 1; + accu >>= 1; + nz ++; + } + accu += accu0 + accu1 + accu2 + accu3; + accu0 = accu1 = accu2 = accu3 = 0; + } + } + + nz0 = 15 - nz; + + u = accu >> 32; + if (u) { + nz = 33; + while (u < 0x80000000U) { + u <<= 1; + nz--; + } + } else + nz = 1; + + round = 1ULL << (nz-1); + u = ((accu + round) >> nz); + u >>= 1; + ret = av_int2sf(u, nz0 - nz); + + return ret; +} + +static void sbr_neg_odd_64_c(int *x) +{ + int i; + for (i = 1; i < 64; i += 2) + x[i] = -x[i]; +} + +static void sbr_qmf_pre_shuffle_c(int *z) +{ + int k; + z[64] = z[0]; + z[65] = z[1]; + for (k = 1; k < 32; k++) { + z[64+2*k ] = -z[64 - k]; + z[64+2*k+1] = z[ k + 1]; + } +} + +static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z) +{ + int k; + for (k = 0; k < 32; k++) { + W[k][0] = -z[63-k]; + W[k][1] = z[k]; + } +} + +static void sbr_qmf_deint_neg_c(int *v, const int *src) +{ + int i; + for (i = 0; i < 32; i++) { + v[ i] = ( src[63 - 2*i ] + 0x10) >> 5; + v[63 - i] = (-src[63 - 2*i - 1] + 0x10) >> 5; + } +} + +static av_always_inline SoftFloat autocorr_calc(int64_t accu) +{ + int nz, mant, expo; + unsigned round; + int i = (int)(accu >> 32); + if (i == 0) { + nz = 1; + } else { + nz = 0; + while (FFABS(i) < 0x40000000) { + i *= 2; + nz++; + } + nz = 32-nz; + } + + round = 1U << (nz-1); + mant = (int)((accu + round) >> nz); + mant = (mant + 0x40LL)>>7; + mant *= 64; + expo = nz + 15; + return av_int2sf(mant, 30 - expo); +} + +static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag) +{ + int i; + int64_t real_sum, imag_sum; + int64_t accu_re = 0, accu_im = 0; + + if (lag) { + for (i = 1; i < 38; i++) { + accu_re += (uint64_t)x[i][0] * x[i+lag][0]; + accu_re += (uint64_t)x[i][1] * x[i+lag][1]; + accu_im += (uint64_t)x[i][0] * x[i+lag][1]; + accu_im -= (uint64_t)x[i][1] * x[i+lag][0]; + } + + real_sum = accu_re; + imag_sum = accu_im; + + accu_re += (uint64_t)x[ 0][0] * x[lag][0]; + accu_re += (uint64_t)x[ 0][1] * x[lag][1]; + accu_im += (uint64_t)x[ 0][0] * x[lag][1]; + accu_im -= (uint64_t)x[ 0][1] * x[lag][0]; + + phi[2-lag][1][0] = autocorr_calc(accu_re); + phi[2-lag][1][1] = autocorr_calc(accu_im); + + if (lag == 1) { + accu_re = real_sum; + accu_im = imag_sum; + accu_re += (uint64_t)x[38][0] * x[39][0]; + accu_re += (uint64_t)x[38][1] * x[39][1]; + accu_im += (uint64_t)x[38][0] * x[39][1]; + accu_im -= (uint64_t)x[38][1] * x[39][0]; + + phi[0][0][0] = autocorr_calc(accu_re); + phi[0][0][1] = autocorr_calc(accu_im); + } + } else { + for (i = 1; i < 38; i++) { + accu_re += (uint64_t)x[i][0] * x[i][0]; + accu_re += (uint64_t)x[i][1] * x[i][1]; + } + real_sum = accu_re; + accu_re += (uint64_t)x[ 0][0] * x[ 0][0]; + accu_re += (uint64_t)x[ 0][1] * x[ 0][1]; + + phi[2][1][0] = autocorr_calc(accu_re); + + accu_re = real_sum; + accu_re += (uint64_t)x[38][0] * x[38][0]; + accu_re += (uint64_t)x[38][1] * x[38][1]; + + phi[1][0][0] = autocorr_calc(accu_re); + } +} + +static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2]) +{ + autocorrelate(x, phi, 0); + autocorrelate(x, phi, 1); + autocorrelate(x, phi, 2); +} + +static void sbr_hf_gen_c(int (*X_high)[2], const int (*X_low)[2], + const int alpha0[2], const int alpha1[2], + int bw, int start, int end) +{ + int alpha[4]; + int i; + int64_t accu; + + accu = (int64_t)alpha0[0] * bw; + alpha[2] = (int)((accu + 0x40000000) >> 31); + accu = (int64_t)alpha0[1] * bw; + alpha[3] = (int)((accu + 0x40000000) >> 31); + accu = (int64_t)bw * bw; + bw = (int)((accu + 0x40000000) >> 31); + accu = (int64_t)alpha1[0] * bw; + alpha[0] = (int)((accu + 0x40000000) >> 31); + accu = (int64_t)alpha1[1] * bw; + alpha[1] = (int)((accu + 0x40000000) >> 31); + + for (i = start; i < end; i++) { + accu = (int64_t)X_low[i][0] * 0x20000000; + accu += (int64_t)X_low[i - 2][0] * alpha[0]; + accu -= (int64_t)X_low[i - 2][1] * alpha[1]; + accu += (int64_t)X_low[i - 1][0] * alpha[2]; + accu -= (int64_t)X_low[i - 1][1] * alpha[3]; + X_high[i][0] = (int)((accu + 0x10000000) >> 29); + + accu = (int64_t)X_low[i][1] * 0x20000000; + accu += (int64_t)X_low[i - 2][1] * alpha[0]; + accu += (int64_t)X_low[i - 2][0] * alpha[1]; + accu += (int64_t)X_low[i - 1][1] * alpha[2]; + accu += (int64_t)X_low[i - 1][0] * alpha[3]; + X_high[i][1] = (int)((accu + 0x10000000) >> 29); + } +} + +static void sbr_hf_g_filt_c(int (*Y)[2], const int (*X_high)[40][2], + const SoftFloat *g_filt, int m_max, intptr_t ixh) +{ + int m; + int64_t accu; + + for (m = 0; m < m_max; m++) { + if (22 - g_filt[m].exp < 61) { + int64_t r = 1LL << (22-g_filt[m].exp); + accu = (int64_t)X_high[m][ixh][0] * ((g_filt[m].mant + 0x40)>>7); + Y[m][0] = (int)((accu + r) >> (23-g_filt[m].exp)); + + accu = (int64_t)X_high[m][ixh][1] * ((g_filt[m].mant + 0x40)>>7); + Y[m][1] = (int)((accu + r) >> (23-g_filt[m].exp)); + } + } +} + +static av_always_inline int sbr_hf_apply_noise(int (*Y)[2], + const SoftFloat *s_m, + const SoftFloat *q_filt, + int noise, + int phi_sign0, + int phi_sign1, + int m_max) +{ + int m; + + for (m = 0; m < m_max; m++) { + unsigned y0 = Y[m][0]; + unsigned y1 = Y[m][1]; + noise = (noise + 1) & 0x1ff; + if (s_m[m].mant) { + int shift, round; + + shift = 22 - s_m[m].exp; + if (shift < 1) { + av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_apply_noise, shift=%d\n", shift); + return AVERROR(ERANGE); + } else if (shift < 30) { + round = 1 << (shift-1); + y0 += (s_m[m].mant * phi_sign0 + round) >> shift; + y1 += (s_m[m].mant * phi_sign1 + round) >> shift; + } + } else { + int shift, round, tmp; + int64_t accu; + + shift = 22 - q_filt[m].exp; + if (shift < 1) { + av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_apply_noise, shift=%d\n", shift); + return AVERROR(ERANGE); + } else if (shift < 30) { + round = 1 << (shift-1); + + accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][0]; + tmp = (int)((accu + 0x40000000) >> 31); + y0 += (tmp + round) >> shift; + + accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][1]; + tmp = (int)((accu + 0x40000000) >> 31); + y1 += (tmp + round) >> shift; + } + } + Y[m][0] = y0; + Y[m][1] = y1; + phi_sign1 = -phi_sign1; + } + return 0; +} + +#include "sbrdsp_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_init.c new file mode 100644 index 000000000..6911a1a51 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_init.c @@ -0,0 +1,87 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2012 Christophe Gisquet + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/sbrdsp.h" + +float ff_sbr_sum_square_sse(float (*x)[2], int n); +void ff_sbr_sum64x5_sse(float *z); +void ff_sbr_hf_g_filt_sse(float (*Y)[2], const float (*X_high)[40][2], + const float *g_filt, int m_max, intptr_t ixh); +void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2], + const float alpha0[2], const float alpha1[2], + float bw, int start, int end); +void ff_sbr_neg_odd_64_sse(float *z); +void ff_sbr_qmf_post_shuffle_sse(float W[32][2], const float *z); +void ff_sbr_qmf_deint_bfly_sse(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_pre_shuffle_sse2(float *z); + +void ff_sbr_hf_apply_noise_0_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_1_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_2_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_3_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); + +void ff_sbr_qmf_deint_neg_sse(float *v, const float *src); + +void ff_sbr_autocorrelate_sse (const float x[40][2], float phi[3][2][2]); +void ff_sbr_autocorrelate_sse3(const float x[40][2], float phi[3][2][2]); + +av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + s->neg_odd_64 = ff_sbr_neg_odd_64_sse; + s->sum_square = ff_sbr_sum_square_sse; + s->sum64x5 = ff_sbr_sum64x5_sse; + s->hf_g_filt = ff_sbr_hf_g_filt_sse; + s->hf_gen = ff_sbr_hf_gen_sse; + s->qmf_post_shuffle = ff_sbr_qmf_post_shuffle_sse; + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse; + s->qmf_deint_neg = ff_sbr_qmf_deint_neg_sse; + s->autocorrelate = ff_sbr_autocorrelate_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse2; + s->qmf_pre_shuffle = ff_sbr_qmf_pre_shuffle_sse2; + s->hf_apply_noise[0] = ff_sbr_hf_apply_noise_0_sse2; + s->hf_apply_noise[1] = ff_sbr_hf_apply_noise_1_sse2; + s->hf_apply_noise[2] = ff_sbr_hf_apply_noise_2_sse2; + s->hf_apply_noise[3] = ff_sbr_hf_apply_noise_3_sse2; + } + + if (EXTERNAL_SSE3(cpu_flags)) { + s->autocorrelate = ff_sbr_autocorrelate_sse3; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_template.c new file mode 100644 index 000000000..37a3365b9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sbrdsp_template.c @@ -0,0 +1,104 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2009-2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static void sbr_sum64x5_c(INTFLOAT *z) +{ + int k; + for (k = 0; k < 64; k++) { + INTFLOAT f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256]; + z[k] = f; + } +} + +static void sbr_qmf_deint_bfly_c(INTFLOAT *v, const INTFLOAT *src0, const INTFLOAT *src1) +{ + int i; + for (i = 0; i < 64; i++) { +#if USE_FIXED + v[ i] = (int)(0x10U + src0[i] - src1[63 - i]) >> 5; + v[127 - i] = (int)(0x10U + src0[i] + src1[63 - i]) >> 5; +#else + v[ i] = src0[i] - src1[63 - i]; + v[127 - i] = src0[i] + src1[63 - i]; +#endif + } +} + +static void sbr_hf_apply_noise_0(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m, + const AAC_FLOAT *q_filt, int noise, + int kx, int m_max) +{ + sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)1.0, (INTFLOAT)0.0, m_max); +} + +static void sbr_hf_apply_noise_1(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m, + const AAC_FLOAT *q_filt, int noise, + int kx, int m_max) +{ + INTFLOAT phi_sign = 1 - 2 * (kx & 1); + sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)0.0, phi_sign, m_max); +} + +static void sbr_hf_apply_noise_2(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m, + const AAC_FLOAT *q_filt, int noise, + int kx, int m_max) +{ + sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)-1.0, (INTFLOAT)0.0, m_max); +} + +static void sbr_hf_apply_noise_3(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m, + const AAC_FLOAT *q_filt, int noise, + int kx, int m_max) +{ + INTFLOAT phi_sign = 1 - 2 * (kx & 1); + sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)0.0, -phi_sign, m_max); +} + +av_cold void AAC_RENAME(ff_sbrdsp_init)(SBRDSPContext *s) +{ + s->sum64x5 = sbr_sum64x5_c; + s->sum_square = sbr_sum_square_c; + s->neg_odd_64 = sbr_neg_odd_64_c; + s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_c; + s->qmf_post_shuffle = sbr_qmf_post_shuffle_c; + s->qmf_deint_neg = sbr_qmf_deint_neg_c; + s->qmf_deint_bfly = sbr_qmf_deint_bfly_c; + s->autocorrelate = sbr_autocorrelate_c; + s->hf_gen = sbr_hf_gen_c; + s->hf_g_filt = sbr_hf_g_filt_c; + + s->hf_apply_noise[0] = sbr_hf_apply_noise_0; + s->hf_apply_noise[1] = sbr_hf_apply_noise_1; + s->hf_apply_noise[2] = sbr_hf_apply_noise_2; + s->hf_apply_noise[3] = sbr_hf_apply_noise_3; + +#if !USE_FIXED + if (ARCH_ARM) + ff_sbrdsp_init_arm(s); + if (ARCH_AARCH64) + ff_sbrdsp_init_aarch64(s); + if (ARCH_X86) + ff_sbrdsp_init_x86(s); + if (ARCH_MIPS) + ff_sbrdsp_init_mips(s); +#endif /* !USE_FIXED */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin.c new file mode 100644 index 000000000..4532dc735 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin.c @@ -0,0 +1,21 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 0 +#include "sinewin.h" +#include "sinewin_tablegen.h" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin.h new file mode 100644 index 000000000..329e9bb5b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2008 Robert Swain + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_SINEWIN_H +#define AVCODEC_SINEWIN_H + +#include "config.h" +#include "libavutil/mem.h" +#include "libavcodec/aac_defines.h" + +#if CONFIG_HARDCODED_TABLES +# define SINETABLE_CONST const +#else +# define SINETABLE_CONST +#endif + +#ifndef USE_FIXED +#define USE_FIXED 0 +#endif + +#define SINETABLE(size) \ + SINETABLE_CONST DECLARE_ALIGNED(32, INTFLOAT, AAC_RENAME(ff_sine_##size))[size] + +#define SINETABLE120960(size) \ + DECLARE_ALIGNED(32, INTFLOAT, AAC_RENAME(ff_sine_##size))[size] + +/** + * Generate a sine window. + * @param window pointer to half window + * @param n size of half window + */ +void AAC_RENAME(ff_sine_window_init)(INTFLOAT *window, int n); + +/** + * initialize the specified entry of ff_sine_windows + */ +void AAC_RENAME(ff_init_ff_sine_windows)(int index); + +extern SINETABLE( 32); +extern SINETABLE( 64); +extern SINETABLE120960(120); +extern SINETABLE( 128); +extern SINETABLE( 256); +extern SINETABLE( 512); +extern SINETABLE120960(960); +extern SINETABLE(1024); +extern SINETABLE(2048); +extern SINETABLE(4096); +extern SINETABLE(8192); + +extern SINETABLE_CONST INTFLOAT * const AAC_RENAME(ff_sine_windows)[16]; + +#endif /* AVCODEC_SINEWIN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_fixed.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_fixed.c new file mode 100644 index 000000000..27ead29e8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_fixed.c @@ -0,0 +1,21 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 1 +#include "sinewin.h" +#include "sinewin_tablegen.h" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_tablegen.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_tablegen.c new file mode 100644 index 000000000..dd602668e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_tablegen.c @@ -0,0 +1,24 @@ +/* + * Generate a header file for hardcoded sine windows + * + * Copyright (c) 2009 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define USE_FIXED 0 +#include "sinewin_tablegen_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_tablegen.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_tablegen.h new file mode 100644 index 000000000..dc52234ed --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/sinewin_tablegen.h @@ -0,0 +1,83 @@ +/* + * Header file for hardcoded sine windows + * + * Copyright (c) 2009 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_SINEWIN_TABLEGEN_H +#define AVCODEC_SINEWIN_TABLEGEN_H + +#include +// do not use libavutil/libm.h since this is compiled both +// for the host and the target and config.h is only valid for the target +#include +#include "libavcodec/aac_defines.h" +#include "libavutil/attributes.h" +#include "libavutil/common.h" + +#if !USE_FIXED +SINETABLE120960(120); +SINETABLE120960(960); +#endif +#if !CONFIG_HARDCODED_TABLES +SINETABLE( 32); +SINETABLE( 64); +SINETABLE( 128); +SINETABLE( 256); +SINETABLE( 512); +SINETABLE(1024); +SINETABLE(2048); +SINETABLE(4096); +SINETABLE(8192); +#else +#if USE_FIXED +#include "libavcodec/sinewin_fixed_tables.h" +#else +#include "libavcodec/sinewin_tables.h" +#endif +#endif + +#if USE_FIXED +#define SIN_FIX(a) (int)floor((a) * 0x80000000 + 0.5) +#else +#define SIN_FIX(a) a +#endif + +SINETABLE_CONST INTFLOAT * const AAC_RENAME(ff_sine_windows)[] = { + NULL, NULL, NULL, NULL, NULL, // unused + AAC_RENAME(ff_sine_32) , AAC_RENAME(ff_sine_64), AAC_RENAME(ff_sine_128), + AAC_RENAME(ff_sine_256), AAC_RENAME(ff_sine_512), AAC_RENAME(ff_sine_1024), + AAC_RENAME(ff_sine_2048), AAC_RENAME(ff_sine_4096), AAC_RENAME(ff_sine_8192), +}; + +// Generate a sine window. +av_cold void AAC_RENAME(ff_sine_window_init)(INTFLOAT *window, int n) { + int i; + for(i = 0; i < n; i++) + window[i] = SIN_FIX(sinf((i + 0.5) * (M_PI / (2.0 * n)))); +} + +av_cold void AAC_RENAME(ff_init_ff_sine_windows)(int index) { + assert(index >= 0 && index < FF_ARRAY_ELEMS(AAC_RENAME(ff_sine_windows))); +#if !CONFIG_HARDCODED_TABLES + AAC_RENAME(ff_sine_window_init)(AAC_RENAME(ff_sine_windows)[index], 1 << index); +#endif +} + +#endif /* AVCODEC_SINEWIN_TABLEGEN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/thread.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/thread.h new file mode 100644 index 000000000..540135fbc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/thread.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2008 Alexander Strange + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Multithreading support functions + * @author Alexander Strange + */ + +#ifndef AVCODEC_THREAD_H +#define AVCODEC_THREAD_H + +#include "libavutil/buffer.h" + +#include "avcodec.h" + +typedef struct ThreadFrame { + AVFrame *f; + AVCodecContext *owner[2]; + // progress->data is an array of 2 ints holding progress for top/bottom + // fields + AVBufferRef *progress; +} ThreadFrame; + +/** + * Wait for decoding threads to finish and reset internal state. + * Called by avcodec_flush_buffers(). + * + * @param avctx The context. + */ +void ff_thread_flush(AVCodecContext *avctx); + +/** + * Submit a new frame to a decoding thread. + * Returns the next available frame in picture. *got_picture_ptr + * will be 0 if none is available. + * The return value on success is the size of the consumed packet for + * compatibility with avcodec_decode_video2(). This means the decoder + * has to consume the full packet. + * + * Parameters are the same as avcodec_decode_video2(). + */ +int ff_thread_decode_frame(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, AVPacket *avpkt); + +/** + * If the codec defines update_thread_context(), call this + * when they are ready for the next thread to start decoding + * the next frame. After calling it, do not change any variables + * read by the update_thread_context() method, or call ff_thread_get_buffer(). + * + * @param avctx The context. + */ +void ff_thread_finish_setup(AVCodecContext *avctx); + +/** + * Notify later decoding threads when part of their reference picture is ready. + * Call this when some part of the picture is finished decoding. + * Later calls with lower values of progress have no effect. + * + * @param f The picture being decoded. + * @param progress Value, in arbitrary units, of how much of the picture has decoded. + * @param field The field being decoded, for field-picture codecs. + * 0 for top field or frame pictures, 1 for bottom field. + */ +void ff_thread_report_progress(ThreadFrame *f, int progress, int field); + +/** + * Wait for earlier decoding threads to finish reference pictures. + * Call this before accessing some part of a picture, with a given + * value for progress, and it will return after the responsible decoding + * thread calls ff_thread_report_progress() with the same or + * higher value for progress. + * + * @param f The picture being referenced. + * @param progress Value, in arbitrary units, to wait for. + * @param field The field being referenced, for field-picture codecs. + * 0 for top field or frame pictures, 1 for bottom field. + */ +void ff_thread_await_progress(ThreadFrame *f, int progress, int field); + +/** + * Wrapper around get_format() for frame-multithreaded codecs. + * Call this function instead of avctx->get_format(). + * Cannot be called after the codec has called ff_thread_finish_setup(). + * + * @param avctx The current context. + * @param fmt The list of available formats. + */ +enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt); + +/** + * Wrapper around get_buffer() for frame-multithreaded codecs. + * Call this function instead of ff_get_buffer(f). + * Cannot be called after the codec has called ff_thread_finish_setup(). + * + * @param avctx The current context. + * @param f The frame to write into. + */ +int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags); + +/** + * Wrapper around release_buffer() frame-for multithreaded codecs. + * Call this function instead of avctx->release_buffer(f). + * The AVFrame will be copied and the actual release_buffer() call + * will be performed later. The contents of data pointed to by the + * AVFrame should not be changed until ff_thread_get_buffer() is called + * on it. + * + * @param avctx The current context. + * @param f The picture being released. + */ +void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f); + +int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src); + +int ff_thread_init(AVCodecContext *s); +int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, + int (*action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr), + int (*main_func)(AVCodecContext *c), void *arg, int *ret, int job_count); +void ff_thread_free(AVCodecContext *s); +int ff_alloc_entries(AVCodecContext *avctx, int count); +void ff_reset_entries(AVCodecContext *avctx); +void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n); +void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift); + +#endif /* AVCODEC_THREAD_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/utils.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/utils.c new file mode 100644 index 000000000..a6a646636 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/utils.c @@ -0,0 +1,2234 @@ +/* + * utils for libavcodec + * Copyright (c) 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * utils. + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" +#include "libavutil/channel_layout.h" +#include "libavutil/crc.h" +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/internal.h" +#include "libavutil/mathematics.h" +#include "libavutil/mem_internal.h" +#include "libavutil/pixdesc.h" +#include "libavutil/imgutils.h" +#include "libavutil/samplefmt.h" +#include "libavutil/dict.h" +#include "libavutil/thread.h" +#include "avcodec.h" +#include "decode.h" +#include "hwaccel.h" +#include "libavutil/opt.h" +#include "mpegvideo.h" +#include "thread.h" +#include "frame_thread_encoder.h" +#include "internal.h" +#include "raw.h" +#include "bytestream.h" +#include "version.h" +#include +#include +#include +#include +#include +#if CONFIG_ICONV +# include +#endif + +#include "libavutil/ffversion.h" +const char av_codec_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + +static AVMutex codec_mutex = AV_MUTEX_INITIALIZER; + +void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size) +{ + uint8_t **p = ptr; + if (min_size > SIZE_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { + av_freep(p); + *size = 0; + return; + } + if (!ff_fast_malloc(p, size, min_size + AV_INPUT_BUFFER_PADDING_SIZE, 1)) + memset(*p + min_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); +} + +void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size) +{ + uint8_t **p = ptr; + if (min_size > SIZE_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { + av_freep(p); + *size = 0; + return; + } + if (!ff_fast_malloc(p, size, min_size + AV_INPUT_BUFFER_PADDING_SIZE, 1)) + memset(*p, 0, min_size + AV_INPUT_BUFFER_PADDING_SIZE); +} + +int av_codec_is_encoder(const AVCodec *codec) +{ + return codec && (codec->encode_sub || codec->encode2 ||codec->send_frame); +} + +int av_codec_is_decoder(const AVCodec *codec) +{ + return codec && (codec->decode || codec->receive_frame); +} + +int ff_set_dimensions(AVCodecContext *s, int width, int height) +{ + int ret = av_image_check_size2(width, height, s->max_pixels, AV_PIX_FMT_NONE, 0, s); + + if (ret < 0) + width = height = 0; + + s->coded_width = width; + s->coded_height = height; + s->width = AV_CEIL_RSHIFT(width, s->lowres); + s->height = AV_CEIL_RSHIFT(height, s->lowres); + + return ret; +} + +int ff_set_sar(AVCodecContext *avctx, AVRational sar) +{ + int ret = av_image_check_sar(avctx->width, avctx->height, sar); + + if (ret < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %d/%d\n", + sar.num, sar.den); + avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; + return ret; + } else { + avctx->sample_aspect_ratio = sar; + } + return 0; +} + +int ff_side_data_update_matrix_encoding(AVFrame *frame, + enum AVMatrixEncoding matrix_encoding) +{ + AVFrameSideData *side_data; + enum AVMatrixEncoding *data; + + side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_MATRIXENCODING); + if (!side_data) + side_data = av_frame_new_side_data(frame, AV_FRAME_DATA_MATRIXENCODING, + sizeof(enum AVMatrixEncoding)); + + if (!side_data) + return AVERROR(ENOMEM); + + data = (enum AVMatrixEncoding*)side_data->data; + *data = matrix_encoding; + + return 0; +} + +void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, + int linesize_align[AV_NUM_DATA_POINTERS]) +{ + int i; + int w_align = 1; + int h_align = 1; + AVPixFmtDescriptor const *desc = av_pix_fmt_desc_get(s->pix_fmt); + + if (desc) { + w_align = 1 << desc->log2_chroma_w; + h_align = 1 << desc->log2_chroma_h; + } + + switch (s->pix_fmt) { + case AV_PIX_FMT_YUV420P: + case AV_PIX_FMT_YUYV422: + case AV_PIX_FMT_YVYU422: + case AV_PIX_FMT_UYVY422: + case AV_PIX_FMT_YUV422P: + case AV_PIX_FMT_YUV440P: + case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_GBRP: + case AV_PIX_FMT_GBRAP: + case AV_PIX_FMT_GRAY8: + case AV_PIX_FMT_GRAY16BE: + case AV_PIX_FMT_GRAY16LE: + case AV_PIX_FMT_YUVJ420P: + case AV_PIX_FMT_YUVJ422P: + case AV_PIX_FMT_YUVJ440P: + case AV_PIX_FMT_YUVJ444P: + case AV_PIX_FMT_YUVA420P: + case AV_PIX_FMT_YUVA422P: + case AV_PIX_FMT_YUVA444P: + case AV_PIX_FMT_YUV420P9LE: + case AV_PIX_FMT_YUV420P9BE: + case AV_PIX_FMT_YUV420P10LE: + case AV_PIX_FMT_YUV420P10BE: + case AV_PIX_FMT_YUV420P12LE: + case AV_PIX_FMT_YUV420P12BE: + case AV_PIX_FMT_YUV420P14LE: + case AV_PIX_FMT_YUV420P14BE: + case AV_PIX_FMT_YUV420P16LE: + case AV_PIX_FMT_YUV420P16BE: + case AV_PIX_FMT_YUVA420P9LE: + case AV_PIX_FMT_YUVA420P9BE: + case AV_PIX_FMT_YUVA420P10LE: + case AV_PIX_FMT_YUVA420P10BE: + case AV_PIX_FMT_YUVA420P16LE: + case AV_PIX_FMT_YUVA420P16BE: + case AV_PIX_FMT_YUV422P9LE: + case AV_PIX_FMT_YUV422P9BE: + case AV_PIX_FMT_YUV422P10LE: + case AV_PIX_FMT_YUV422P10BE: + case AV_PIX_FMT_YUV422P12LE: + case AV_PIX_FMT_YUV422P12BE: + case AV_PIX_FMT_YUV422P14LE: + case AV_PIX_FMT_YUV422P14BE: + case AV_PIX_FMT_YUV422P16LE: + case AV_PIX_FMT_YUV422P16BE: + case AV_PIX_FMT_YUVA422P9LE: + case AV_PIX_FMT_YUVA422P9BE: + case AV_PIX_FMT_YUVA422P10LE: + case AV_PIX_FMT_YUVA422P10BE: + case AV_PIX_FMT_YUVA422P12LE: + case AV_PIX_FMT_YUVA422P12BE: + case AV_PIX_FMT_YUVA422P16LE: + case AV_PIX_FMT_YUVA422P16BE: + case AV_PIX_FMT_YUV440P10LE: + case AV_PIX_FMT_YUV440P10BE: + case AV_PIX_FMT_YUV440P12LE: + case AV_PIX_FMT_YUV440P12BE: + case AV_PIX_FMT_YUV444P9LE: + case AV_PIX_FMT_YUV444P9BE: + case AV_PIX_FMT_YUV444P10LE: + case AV_PIX_FMT_YUV444P10BE: + case AV_PIX_FMT_YUV444P12LE: + case AV_PIX_FMT_YUV444P12BE: + case AV_PIX_FMT_YUV444P14LE: + case AV_PIX_FMT_YUV444P14BE: + case AV_PIX_FMT_YUV444P16LE: + case AV_PIX_FMT_YUV444P16BE: + case AV_PIX_FMT_YUVA444P9LE: + case AV_PIX_FMT_YUVA444P9BE: + case AV_PIX_FMT_YUVA444P10LE: + case AV_PIX_FMT_YUVA444P10BE: + case AV_PIX_FMT_YUVA444P12LE: + case AV_PIX_FMT_YUVA444P12BE: + case AV_PIX_FMT_YUVA444P16LE: + case AV_PIX_FMT_YUVA444P16BE: + case AV_PIX_FMT_GBRP9LE: + case AV_PIX_FMT_GBRP9BE: + case AV_PIX_FMT_GBRP10LE: + case AV_PIX_FMT_GBRP10BE: + case AV_PIX_FMT_GBRP12LE: + case AV_PIX_FMT_GBRP12BE: + case AV_PIX_FMT_GBRP14LE: + case AV_PIX_FMT_GBRP14BE: + case AV_PIX_FMT_GBRP16LE: + case AV_PIX_FMT_GBRP16BE: + case AV_PIX_FMT_GBRAP12LE: + case AV_PIX_FMT_GBRAP12BE: + case AV_PIX_FMT_GBRAP16LE: + case AV_PIX_FMT_GBRAP16BE: + w_align = 16; //FIXME assume 16 pixel per macroblock + h_align = 16 * 2; // interlaced needs 2 macroblocks height + break; + case AV_PIX_FMT_YUV411P: + case AV_PIX_FMT_YUVJ411P: + case AV_PIX_FMT_UYYVYY411: + w_align = 32; + h_align = 16 * 2; + break; + case AV_PIX_FMT_YUV410P: + if (s->codec_id == AV_CODEC_ID_SVQ1) { + w_align = 64; + h_align = 64; + } + break; + case AV_PIX_FMT_RGB555: + if (s->codec_id == AV_CODEC_ID_RPZA) { + w_align = 4; + h_align = 4; + } + if (s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) { + w_align = 8; + h_align = 8; + } + break; + case AV_PIX_FMT_PAL8: + case AV_PIX_FMT_BGR8: + case AV_PIX_FMT_RGB8: + if (s->codec_id == AV_CODEC_ID_SMC || + s->codec_id == AV_CODEC_ID_CINEPAK) { + w_align = 4; + h_align = 4; + } + if (s->codec_id == AV_CODEC_ID_JV || + s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) { + w_align = 8; + h_align = 8; + } + break; + case AV_PIX_FMT_BGR24: + if ((s->codec_id == AV_CODEC_ID_MSZH) || + (s->codec_id == AV_CODEC_ID_ZLIB)) { + w_align = 4; + h_align = 4; + } + break; + case AV_PIX_FMT_RGB24: + if (s->codec_id == AV_CODEC_ID_CINEPAK) { + w_align = 4; + h_align = 4; + } + break; + default: + break; + } + + if (s->codec_id == AV_CODEC_ID_IFF_ILBM) { + w_align = FFMAX(w_align, 8); + } + + *width = FFALIGN(*width, w_align); + *height = FFALIGN(*height, h_align); + if (s->codec_id == AV_CODEC_ID_H264 || s->lowres || + s->codec_id == AV_CODEC_ID_VP5 || s->codec_id == AV_CODEC_ID_VP6 || + s->codec_id == AV_CODEC_ID_VP6F || s->codec_id == AV_CODEC_ID_VP6A + ) { + // some of the optimized chroma MC reads one line too much + // which is also done in mpeg decoders with lowres > 0 + *height += 2; + + // H.264 uses edge emulation for out of frame motion vectors, for this + // it requires a temporary area large enough to hold a 21x21 block, + // increasing witdth ensure that the temporary area is large enough, + // the next rounded up width is 32 + *width = FFMAX(*width, 32); + } + + for (i = 0; i < 4; i++) + linesize_align[i] = STRIDE_ALIGN; +} + +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt); + int chroma_shift = desc->log2_chroma_w; + int linesize_align[AV_NUM_DATA_POINTERS]; + int align; + + avcodec_align_dimensions2(s, width, height, linesize_align); + align = FFMAX(linesize_align[0], linesize_align[3]); + linesize_align[1] <<= chroma_shift; + linesize_align[2] <<= chroma_shift; + align = FFMAX3(align, linesize_align[1], linesize_align[2]); + *width = FFALIGN(*width, align); +} + +int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos) +{ + if (pos <= AVCHROMA_LOC_UNSPECIFIED || pos >= AVCHROMA_LOC_NB) + return AVERROR(EINVAL); + pos--; + + *xpos = (pos&1) * 128; + *ypos = ((pos>>1)^(pos<4)) * 128; + + return 0; +} + +enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos) +{ + int pos, xout, yout; + + for (pos = AVCHROMA_LOC_UNSPECIFIED + 1; pos < AVCHROMA_LOC_NB; pos++) { + if (avcodec_enum_to_chroma_pos(&xout, &yout, pos) == 0 && xout == xpos && yout == ypos) + return pos; + } + return AVCHROMA_LOC_UNSPECIFIED; +} + +int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, + enum AVSampleFormat sample_fmt, const uint8_t *buf, + int buf_size, int align) +{ + int ch, planar, needed_size, ret = 0; + + needed_size = av_samples_get_buffer_size(NULL, nb_channels, + frame->nb_samples, sample_fmt, + align); + if (buf_size < needed_size) + return AVERROR(EINVAL); + + planar = av_sample_fmt_is_planar(sample_fmt); + if (planar && nb_channels > AV_NUM_DATA_POINTERS) { + if (!(frame->extended_data = av_mallocz_array(nb_channels, + sizeof(*frame->extended_data)))) + return AVERROR(ENOMEM); + } else { + frame->extended_data = frame->data; + } + + if ((ret = av_samples_fill_arrays(frame->extended_data, &frame->linesize[0], + (uint8_t *)(intptr_t)buf, nb_channels, frame->nb_samples, + sample_fmt, align)) < 0) { + if (frame->extended_data != frame->data) + av_freep(&frame->extended_data); + return ret; + } + if (frame->extended_data != frame->data) { + for (ch = 0; ch < AV_NUM_DATA_POINTERS; ch++) + frame->data[ch] = frame->extended_data[ch]; + } + + return ret; +} + +void ff_color_frame(AVFrame *frame, const int c[4]) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + int p, y, x; + + av_assert0(desc->flags & AV_PIX_FMT_FLAG_PLANAR); + + for (p = 0; pnb_components; p++) { + uint8_t *dst = frame->data[p]; + int is_chroma = p == 1 || p == 2; + int bytes = is_chroma ? AV_CEIL_RSHIFT(frame->width, desc->log2_chroma_w) : frame->width; + int height = is_chroma ? AV_CEIL_RSHIFT(frame->height, desc->log2_chroma_h) : frame->height; + for (y = 0; y < height; y++) { + if (desc->comp[0].depth >= 9) { + for (x = 0; xlinesize[p]; + } + } +} + +int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size) +{ + int i; + + for (i = 0; i < count; i++) { + int r = func(c, (char *)arg + i * size); + if (ret) + ret[i] = r; + } + emms_c(); + return 0; +} + +int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int jobnr, int threadnr), void *arg, int *ret, int count) +{ + int i; + + for (i = 0; i < count; i++) { + int r = func(c, arg, i, 0); + if (ret) + ret[i] = r; + } + emms_c(); + return 0; +} + +enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, + unsigned int fourcc) +{ + while (tags->pix_fmt >= 0) { + if (tags->fourcc == fourcc) + return tags->pix_fmt; + tags++; + } + return AV_PIX_FMT_NONE; +} + +#if FF_API_CODEC_GET_SET +MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase) +MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor) +MAKE_ACCESSORS(AVCodecContext, codec, int, lowres) +MAKE_ACCESSORS(AVCodecContext, codec, int, seek_preroll) +MAKE_ACCESSORS(AVCodecContext, codec, uint16_t*, chroma_intra_matrix) + +unsigned av_codec_get_codec_properties(const AVCodecContext *codec) +{ + return codec->properties; +} + +int av_codec_get_max_lowres(const AVCodec *codec) +{ + return codec->max_lowres; +} +#endif + +int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec){ + return !!(codec->caps_internal & FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM); +} + +static int64_t get_bit_rate(AVCodecContext *ctx) +{ + int64_t bit_rate; + int bits_per_sample; + + switch (ctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + case AVMEDIA_TYPE_DATA: + case AVMEDIA_TYPE_SUBTITLE: + case AVMEDIA_TYPE_ATTACHMENT: + bit_rate = ctx->bit_rate; + break; + case AVMEDIA_TYPE_AUDIO: + bits_per_sample = av_get_bits_per_sample(ctx->codec_id); + bit_rate = bits_per_sample ? ctx->sample_rate * (int64_t)ctx->channels * bits_per_sample : ctx->bit_rate; + break; + default: + bit_rate = 0; + break; + } + return bit_rate; +} + + +static void ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec) +{ + if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init) + ff_mutex_lock(&codec_mutex); +} + +static void ff_unlock_avcodec(const AVCodec *codec) +{ + if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init) + ff_mutex_unlock(&codec_mutex); +} + +int attribute_align_arg ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) +{ + int ret = 0; + + ff_unlock_avcodec(codec); + + ret = avcodec_open2(avctx, codec, options); + + ff_lock_avcodec(avctx, codec); + return ret; +} + +int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) +{ + int ret = 0; + int codec_init_ok = 0; + AVDictionary *tmp = NULL; + const AVPixFmtDescriptor *pixdesc; + + if (avcodec_is_open(avctx)) + return 0; + + if ((!codec && !avctx->codec)) { + av_log(avctx, AV_LOG_ERROR, "No codec provided to avcodec_open2()\n"); + return AVERROR(EINVAL); + } + if ((codec && avctx->codec && codec != avctx->codec)) { + av_log(avctx, AV_LOG_ERROR, "This AVCodecContext was allocated for %s, " + "but %s passed to avcodec_open2()\n", avctx->codec->name, codec->name); + return AVERROR(EINVAL); + } + if (!codec) + codec = avctx->codec; + + if (avctx->extradata_size < 0 || avctx->extradata_size >= FF_MAX_EXTRADATA_SIZE) + return AVERROR(EINVAL); + + if (options) + av_dict_copy(&tmp, *options, 0); + + ff_lock_avcodec(avctx, codec); + + avctx->internal = av_mallocz(sizeof(*avctx->internal)); + if (!avctx->internal) { + ret = AVERROR(ENOMEM); + goto end; + } + + avctx->internal->pool = av_mallocz(sizeof(*avctx->internal->pool)); + if (!avctx->internal->pool) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->to_free = av_frame_alloc(); + if (!avctx->internal->to_free) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->compat_decode_frame = av_frame_alloc(); + if (!avctx->internal->compat_decode_frame) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->buffer_frame = av_frame_alloc(); + if (!avctx->internal->buffer_frame) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->buffer_pkt = av_packet_alloc(); + if (!avctx->internal->buffer_pkt) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->ds.in_pkt = av_packet_alloc(); + if (!avctx->internal->ds.in_pkt) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->last_pkt_props = av_packet_alloc(); + if (!avctx->internal->last_pkt_props) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + + avctx->internal->skip_samples_multiplier = 1; + + if (codec->priv_data_size > 0) { + if (!avctx->priv_data) { + avctx->priv_data = av_mallocz(codec->priv_data_size); + if (!avctx->priv_data) { + ret = AVERROR(ENOMEM); + goto end; + } + if (codec->priv_class) { + *(const AVClass **)avctx->priv_data = codec->priv_class; + av_opt_set_defaults(avctx->priv_data); + } + } + if (codec->priv_class && (ret = av_opt_set_dict(avctx->priv_data, &tmp)) < 0) + goto free_and_end; + } else { + avctx->priv_data = NULL; + } + if ((ret = av_opt_set_dict(avctx, &tmp)) < 0) + goto free_and_end; + + if (avctx->codec_whitelist && av_match_list(codec->name, avctx->codec_whitelist, ',') <= 0) { + av_log(avctx, AV_LOG_ERROR, "Codec (%s) not on whitelist \'%s\'\n", codec->name, avctx->codec_whitelist); + ret = AVERROR(EINVAL); + goto free_and_end; + } + + // only call ff_set_dimensions() for non H.264/VP6F/DXV codecs so as not to overwrite previously setup dimensions + if (!(avctx->coded_width && avctx->coded_height && avctx->width && avctx->height && + (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_VP6F || avctx->codec_id == AV_CODEC_ID_DXV))) { + if (avctx->coded_width && avctx->coded_height) + ret = ff_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); + else if (avctx->width && avctx->height) + ret = ff_set_dimensions(avctx, avctx->width, avctx->height); + if (ret < 0) + goto free_and_end; + } + + if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height) + && ( av_image_check_size2(avctx->coded_width, avctx->coded_height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0 + || av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0)) { + av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n"); + ff_set_dimensions(avctx, 0, 0); + } + + if (avctx->width > 0 && avctx->height > 0) { + if (av_image_check_sar(avctx->width, avctx->height, + avctx->sample_aspect_ratio) < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + avctx->sample_aspect_ratio.num, + avctx->sample_aspect_ratio.den); + avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; + } + } + + /* if the decoder init function was already called previously, + * free the already allocated subtitle_header before overwriting it */ + if (av_codec_is_decoder(codec)) + av_freep(&avctx->subtitle_header); + + if (avctx->channels > FF_SANE_NB_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Too many channels: %d\n", avctx->channels); + ret = AVERROR(EINVAL); + goto free_and_end; + } + + avctx->codec = codec; + if ((avctx->codec_type == AVMEDIA_TYPE_UNKNOWN || avctx->codec_type == codec->type) && + avctx->codec_id == AV_CODEC_ID_NONE) { + avctx->codec_type = codec->type; + avctx->codec_id = codec->id; + } + if (avctx->codec_id != codec->id || (avctx->codec_type != codec->type + && avctx->codec_type != AVMEDIA_TYPE_ATTACHMENT)) { + av_log(avctx, AV_LOG_ERROR, "Codec type or id mismatches\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } + avctx->frame_number = 0; + avctx->codec_descriptor = avcodec_descriptor_get(avctx->codec_id); + + if ((avctx->codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) && + avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + const char *codec_string = av_codec_is_encoder(codec) ? "encoder" : "decoder"; + AVCodec *codec2; + av_log(avctx, AV_LOG_ERROR, + "The %s '%s' is experimental but experimental codecs are not enabled, " + "add '-strict %d' if you want to use it.\n", + codec_string, codec->name, FF_COMPLIANCE_EXPERIMENTAL); + codec2 = av_codec_is_encoder(codec) ? avcodec_find_encoder(codec->id) : avcodec_find_decoder(codec->id); + if (!(codec2->capabilities & AV_CODEC_CAP_EXPERIMENTAL)) + av_log(avctx, AV_LOG_ERROR, "Alternatively use the non experimental %s '%s'.\n", + codec_string, codec2->name); + ret = AVERROR_EXPERIMENTAL; + goto free_and_end; + } + + if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && + (!avctx->time_base.num || !avctx->time_base.den)) { + avctx->time_base.num = 1; + avctx->time_base.den = avctx->sample_rate; + } + + if (!HAVE_THREADS) + av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n"); + + if (CONFIG_FRAME_THREAD_ENCODER && av_codec_is_encoder(avctx->codec)) { + ff_unlock_avcodec(codec); //we will instantiate a few encoders thus kick the counter to prevent false detection of a problem + ret = ff_frame_thread_encoder_init(avctx, options ? *options : NULL); + ff_lock_avcodec(avctx, codec); + if (ret < 0) + goto free_and_end; + } + + if (av_codec_is_decoder(avctx->codec)) { + ret = ff_decode_bsfs_init(avctx); + if (ret < 0) + goto free_and_end; + } + + if (HAVE_THREADS + && !(avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) { + ret = ff_thread_init(avctx); + if (ret < 0) { + goto free_and_end; + } + } + if (!HAVE_THREADS && !(codec->capabilities & AV_CODEC_CAP_AUTO_THREADS)) + avctx->thread_count = 1; + + if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) { + av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n", + avctx->codec->max_lowres); + avctx->lowres = avctx->codec->max_lowres; + } + + if (av_codec_is_encoder(avctx->codec)) { + int i; +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + if (avctx->time_base.num <= 0 || avctx->time_base.den <= 0) { + av_log(avctx, AV_LOG_ERROR, "The encoder timebase is not set.\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } + + if (avctx->codec->sample_fmts) { + for (i = 0; avctx->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) { + if (avctx->sample_fmt == avctx->codec->sample_fmts[i]) + break; + if (avctx->channels == 1 && + av_get_planar_sample_fmt(avctx->sample_fmt) == + av_get_planar_sample_fmt(avctx->codec->sample_fmts[i])) { + avctx->sample_fmt = avctx->codec->sample_fmts[i]; + break; + } + } + if (avctx->codec->sample_fmts[i] == AV_SAMPLE_FMT_NONE) { + char buf[128]; + snprintf(buf, sizeof(buf), "%d", avctx->sample_fmt); + av_log(avctx, AV_LOG_ERROR, "Specified sample format %s is invalid or not supported\n", + (char *)av_x_if_null(av_get_sample_fmt_name(avctx->sample_fmt), buf)); + ret = AVERROR(EINVAL); + goto free_and_end; + } + } + if (avctx->codec->pix_fmts) { + for (i = 0; avctx->codec->pix_fmts[i] != AV_PIX_FMT_NONE; i++) + if (avctx->pix_fmt == avctx->codec->pix_fmts[i]) + break; + if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE + && !((avctx->codec_id == AV_CODEC_ID_MJPEG || avctx->codec_id == AV_CODEC_ID_LJPEG) + && avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL)) { + char buf[128]; + snprintf(buf, sizeof(buf), "%d", avctx->pix_fmt); + av_log(avctx, AV_LOG_ERROR, "Specified pixel format %s is invalid or not supported\n", + (char *)av_x_if_null(av_get_pix_fmt_name(avctx->pix_fmt), buf)); + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ420P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ411P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ422P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ440P || + avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ444P) + avctx->color_range = AVCOL_RANGE_JPEG; + } + if (avctx->codec->supported_samplerates) { + for (i = 0; avctx->codec->supported_samplerates[i] != 0; i++) + if (avctx->sample_rate == avctx->codec->supported_samplerates[i]) + break; + if (avctx->codec->supported_samplerates[i] == 0) { + av_log(avctx, AV_LOG_ERROR, "Specified sample rate %d is not supported\n", + avctx->sample_rate); + ret = AVERROR(EINVAL); + goto free_and_end; + } + } + if (avctx->sample_rate < 0) { + av_log(avctx, AV_LOG_ERROR, "Specified sample rate %d is not supported\n", + avctx->sample_rate); + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->codec->channel_layouts) { + if (!avctx->channel_layout) { + av_log(avctx, AV_LOG_WARNING, "Channel layout not specified\n"); + } else { + for (i = 0; avctx->codec->channel_layouts[i] != 0; i++) + if (avctx->channel_layout == avctx->codec->channel_layouts[i]) + break; + if (avctx->codec->channel_layouts[i] == 0) { + char buf[512]; + av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); + av_log(avctx, AV_LOG_ERROR, "Specified channel layout '%s' is not supported\n", buf); + ret = AVERROR(EINVAL); + goto free_and_end; + } + } + } + if (avctx->channel_layout && avctx->channels) { + int channels = av_get_channel_layout_nb_channels(avctx->channel_layout); + if (channels != avctx->channels) { + char buf[512]; + av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); + av_log(avctx, AV_LOG_ERROR, + "Channel layout '%s' with %d channels does not match number of specified channels %d\n", + buf, channels, avctx->channels); + ret = AVERROR(EINVAL); + goto free_and_end; + } + } else if (avctx->channel_layout) { + avctx->channels = av_get_channel_layout_nb_channels(avctx->channel_layout); + } + if (avctx->channels < 0) { + av_log(avctx, AV_LOG_ERROR, "Specified number of channels %d is not supported\n", + avctx->channels); + ret = AVERROR(EINVAL); + goto free_and_end; + } + if(avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + pixdesc = av_pix_fmt_desc_get(avctx->pix_fmt); + if ( avctx->bits_per_raw_sample < 0 + || (avctx->bits_per_raw_sample > 8 && pixdesc->comp[0].depth <= 8)) { + av_log(avctx, AV_LOG_WARNING, "Specified bit depth %d not possible with the specified pixel formats depth %d\n", + avctx->bits_per_raw_sample, pixdesc->comp[0].depth); + avctx->bits_per_raw_sample = pixdesc->comp[0].depth; + } + if (avctx->width <= 0 || avctx->height <= 0) { + av_log(avctx, AV_LOG_ERROR, "dimensions not set\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } + } + if ( (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO) + && avctx->bit_rate>0 && avctx->bit_rate<1000) { + av_log(avctx, AV_LOG_WARNING, "Bitrate %"PRId64" is extremely low, maybe you mean %"PRId64"k\n", avctx->bit_rate, avctx->bit_rate); + } + + if (!avctx->rc_initial_buffer_occupancy) + avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3LL / 4; + + if (avctx->ticks_per_frame && avctx->time_base.num && + avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) { + av_log(avctx, AV_LOG_ERROR, + "ticks_per_frame %d too large for the timebase %d/%d.", + avctx->ticks_per_frame, + avctx->time_base.num, + avctx->time_base.den); + goto free_and_end; + } + + if (avctx->hw_frames_ctx) { + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (frames_ctx->format != avctx->pix_fmt) { + av_log(avctx, AV_LOG_ERROR, + "Mismatching AVCodecContext.pix_fmt and AVHWFramesContext.format\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->sw_pix_fmt != AV_PIX_FMT_NONE && + avctx->sw_pix_fmt != frames_ctx->sw_format) { + av_log(avctx, AV_LOG_ERROR, + "Mismatching AVCodecContext.sw_pix_fmt (%s) " + "and AVHWFramesContext.sw_format (%s)\n", + av_get_pix_fmt_name(avctx->sw_pix_fmt), + av_get_pix_fmt_name(frames_ctx->sw_format)); + ret = AVERROR(EINVAL); + goto free_and_end; + } + avctx->sw_pix_fmt = frames_ctx->sw_format; + } + } + + avctx->pts_correction_num_faulty_pts = + avctx->pts_correction_num_faulty_dts = 0; + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; + + if ( !CONFIG_GRAY && avctx->flags & AV_CODEC_FLAG_GRAY + && avctx->codec_descriptor->type == AVMEDIA_TYPE_VIDEO) + av_log(avctx, AV_LOG_WARNING, + "gray decoding requested but not enabled at configuration time\n"); + + if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME) + || avctx->internal->frame_thread_encoder)) { + ret = avctx->codec->init(avctx); + if (ret < 0) { + goto free_and_end; + } + codec_init_ok = 1; + } + + ret=0; + + if (av_codec_is_decoder(avctx->codec)) { + if (!avctx->bit_rate) + avctx->bit_rate = get_bit_rate(avctx); + /* validate channel layout from the decoder */ + if (avctx->channel_layout) { + int channels = av_get_channel_layout_nb_channels(avctx->channel_layout); + if (!avctx->channels) + avctx->channels = channels; + else if (channels != avctx->channels) { + char buf[512]; + av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout); + av_log(avctx, AV_LOG_WARNING, + "Channel layout '%s' with %d channels does not match specified number of channels %d: " + "ignoring specified channel layout\n", + buf, channels, avctx->channels); + avctx->channel_layout = 0; + } + } + if (avctx->channels && avctx->channels < 0 || + avctx->channels > FF_SANE_NB_CHANNELS) { + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->bits_per_coded_sample < 0) { + ret = AVERROR(EINVAL); + goto free_and_end; + } + if (avctx->sub_charenc) { + if (avctx->codec_type != AVMEDIA_TYPE_SUBTITLE) { + av_log(avctx, AV_LOG_ERROR, "Character encoding is only " + "supported with subtitles codecs\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } else if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) { + av_log(avctx, AV_LOG_WARNING, "Codec '%s' is bitmap-based, " + "subtitles character encoding will be ignored\n", + avctx->codec_descriptor->name); + avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_DO_NOTHING; + } else { + /* input character encoding is set for a text based subtitle + * codec at this point */ + if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_AUTOMATIC) + avctx->sub_charenc_mode = FF_SUB_CHARENC_MODE_PRE_DECODER; + + if (avctx->sub_charenc_mode == FF_SUB_CHARENC_MODE_PRE_DECODER) { +#if CONFIG_ICONV + iconv_t cd = iconv_open("UTF-8", avctx->sub_charenc); + if (cd == (iconv_t)-1) { + ret = AVERROR(errno); + av_log(avctx, AV_LOG_ERROR, "Unable to open iconv context " + "with input character encoding \"%s\"\n", avctx->sub_charenc); + goto free_and_end; + } + iconv_close(cd); +#else + av_log(avctx, AV_LOG_ERROR, "Character encoding subtitles " + "conversion needs a libavcodec built with iconv support " + "for this codec\n"); + ret = AVERROR(ENOSYS); + goto free_and_end; +#endif + } + } + } + +#if FF_API_AVCTX_TIMEBASE + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) + avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); +#endif + } + if (codec->priv_data_size > 0 && avctx->priv_data && codec->priv_class) { + av_assert0(*(const AVClass **)avctx->priv_data == codec->priv_class); + } + +end: + ff_unlock_avcodec(codec); + if (options) { + av_dict_free(options); + *options = tmp; + } + + return ret; +free_and_end: + if (avctx->codec && avctx->codec->close && + (codec_init_ok || + (avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP))) + avctx->codec->close(avctx); + + if (codec->priv_class && codec->priv_data_size) + av_opt_free(avctx->priv_data); + av_opt_free(avctx); + +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + av_frame_free(&avctx->coded_frame); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + av_dict_free(&tmp); + av_freep(&avctx->priv_data); + av_freep(&avctx->subtitle_header); + if (avctx->internal) { + av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->compat_decode_frame); + av_frame_free(&avctx->internal->buffer_frame); + av_packet_free(&avctx->internal->buffer_pkt); + av_packet_free(&avctx->internal->last_pkt_props); + + av_packet_free(&avctx->internal->ds.in_pkt); + ff_decode_bsfs_uninit(avctx); + + av_freep(&avctx->internal->pool); + } + av_freep(&avctx->internal); + avctx->codec = NULL; + goto end; +} + +void avsubtitle_free(AVSubtitle *sub) +{ + int i; + + for (i = 0; i < sub->num_rects; i++) { + av_freep(&sub->rects[i]->data[0]); + av_freep(&sub->rects[i]->data[1]); + av_freep(&sub->rects[i]->data[2]); + av_freep(&sub->rects[i]->data[3]); + av_freep(&sub->rects[i]->text); + av_freep(&sub->rects[i]->ass); + av_freep(&sub->rects[i]); + } + + av_freep(&sub->rects); + + memset(sub, 0, sizeof(*sub)); +} + +av_cold int avcodec_close(AVCodecContext *avctx) +{ + int i; + + if (!avctx) + return 0; + + if (avcodec_is_open(avctx)) { + FramePool *pool = avctx->internal->pool; + if (CONFIG_FRAME_THREAD_ENCODER && + avctx->internal->frame_thread_encoder && avctx->thread_count > 1) { + ff_frame_thread_encoder_free(avctx); + } + if (HAVE_THREADS && avctx->internal->thread_ctx) + ff_thread_free(avctx); + if (avctx->codec && avctx->codec->close) + avctx->codec->close(avctx); + avctx->internal->byte_buffer_size = 0; + av_freep(&avctx->internal->byte_buffer); + av_frame_free(&avctx->internal->to_free); + av_frame_free(&avctx->internal->compat_decode_frame); + av_frame_free(&avctx->internal->buffer_frame); + av_packet_free(&avctx->internal->buffer_pkt); + av_packet_free(&avctx->internal->last_pkt_props); + + av_packet_free(&avctx->internal->ds.in_pkt); + + for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) + av_buffer_pool_uninit(&pool->pools[i]); + av_freep(&avctx->internal->pool); + + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + av_freep(&avctx->internal->hwaccel_priv_data); + + ff_decode_bsfs_uninit(avctx); + + av_freep(&avctx->internal); + } + + for (i = 0; i < avctx->nb_coded_side_data; i++) + av_freep(&avctx->coded_side_data[i].data); + av_freep(&avctx->coded_side_data); + avctx->nb_coded_side_data = 0; + + av_buffer_unref(&avctx->hw_frames_ctx); + av_buffer_unref(&avctx->hw_device_ctx); + + if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) + av_opt_free(avctx->priv_data); + av_opt_free(avctx); + av_freep(&avctx->priv_data); + if (av_codec_is_encoder(avctx->codec)) { + av_freep(&avctx->extradata); +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + av_frame_free(&avctx->coded_frame); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + } + avctx->codec = NULL; + avctx->active_thread_type = 0; + + return 0; +} + +const char *avcodec_get_name(enum AVCodecID id) +{ + const AVCodecDescriptor *cd; + AVCodec *codec; + + if (id == AV_CODEC_ID_NONE) + return "none"; + cd = avcodec_descriptor_get(id); + if (cd) + return cd->name; + av_log(NULL, AV_LOG_WARNING, "Codec 0x%x is not in the full list.\n", id); + codec = avcodec_find_decoder(id); + if (codec) + return codec->name; + codec = avcodec_find_encoder(id); + if (codec) + return codec->name; + return "unknown_codec"; +} + +size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag) +{ + int i, len, ret = 0; + +#define TAG_PRINT(x) \ + (((x) >= '0' && (x) <= '9') || \ + ((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z') || \ + ((x) == '.' || (x) == ' ' || (x) == '-' || (x) == '_')) + + for (i = 0; i < 4; i++) { + len = snprintf(buf, buf_size, + TAG_PRINT(codec_tag & 0xFF) ? "%c" : "[%d]", codec_tag & 0xFF); + buf += len; + buf_size = buf_size > len ? buf_size - len : 0; + ret += len; + codec_tag >>= 8; + } + return ret; +} + +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) +{ + const char *codec_type; + const char *codec_name; + const char *profile = NULL; + int64_t bitrate; + int new_line = 0; + AVRational display_aspect_ratio; + const char *separator = enc->dump_separator ? (const char *)enc->dump_separator : ", "; + + if (!buf || buf_size <= 0) + return; + codec_type = av_get_media_type_string(enc->codec_type); + codec_name = avcodec_get_name(enc->codec_id); + profile = avcodec_profile_name(enc->codec_id, enc->profile); + + snprintf(buf, buf_size, "%s: %s", codec_type ? codec_type : "unknown", + codec_name); + buf[0] ^= 'a' ^ 'A'; /* first letter in uppercase */ + + if (enc->codec && strcmp(enc->codec->name, codec_name)) + snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", enc->codec->name); + + if (profile) + snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile); + if ( enc->codec_type == AVMEDIA_TYPE_VIDEO + && av_log_get_level() >= AV_LOG_VERBOSE + && enc->refs) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %d reference frame%s", + enc->refs, enc->refs > 1 ? "s" : ""); + + if (enc->codec_tag) + snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s / 0x%04X)", + av_fourcc2str(enc->codec_tag), enc->codec_tag); + + switch (enc->codec_type) { + case AVMEDIA_TYPE_VIDEO: + { + char detail[256] = "("; + + av_strlcat(buf, separator, buf_size); + + snprintf(buf + strlen(buf), buf_size - strlen(buf), + "%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" : + av_get_pix_fmt_name(enc->pix_fmt)); + if (enc->bits_per_raw_sample && enc->pix_fmt != AV_PIX_FMT_NONE && + enc->bits_per_raw_sample < av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth) + av_strlcatf(detail, sizeof(detail), "%d bpc, ", enc->bits_per_raw_sample); + if (enc->color_range != AVCOL_RANGE_UNSPECIFIED) + av_strlcatf(detail, sizeof(detail), "%s, ", + av_color_range_name(enc->color_range)); + + if (enc->colorspace != AVCOL_SPC_UNSPECIFIED || + enc->color_primaries != AVCOL_PRI_UNSPECIFIED || + enc->color_trc != AVCOL_TRC_UNSPECIFIED) { + if (enc->colorspace != (int)enc->color_primaries || + enc->colorspace != (int)enc->color_trc) { + new_line = 1; + av_strlcatf(detail, sizeof(detail), "%s/%s/%s, ", + av_color_space_name(enc->colorspace), + av_color_primaries_name(enc->color_primaries), + av_color_transfer_name(enc->color_trc)); + } else + av_strlcatf(detail, sizeof(detail), "%s, ", + av_get_colorspace_name(enc->colorspace)); + } + + if (enc->field_order != AV_FIELD_UNKNOWN) { + const char *field_order = "progressive"; + if (enc->field_order == AV_FIELD_TT) + field_order = "top first"; + else if (enc->field_order == AV_FIELD_BB) + field_order = "bottom first"; + else if (enc->field_order == AV_FIELD_TB) + field_order = "top coded first (swapped)"; + else if (enc->field_order == AV_FIELD_BT) + field_order = "bottom coded first (swapped)"; + + av_strlcatf(detail, sizeof(detail), "%s, ", field_order); + } + + if (av_log_get_level() >= AV_LOG_VERBOSE && + enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) + av_strlcatf(detail, sizeof(detail), "%s, ", + av_chroma_location_name(enc->chroma_sample_location)); + + if (strlen(detail) > 1) { + detail[strlen(detail) - 2] = 0; + av_strlcatf(buf, buf_size, "%s)", detail); + } + } + + if (enc->width) { + av_strlcat(buf, new_line ? separator : ", ", buf_size); + + snprintf(buf + strlen(buf), buf_size - strlen(buf), + "%dx%d", + enc->width, enc->height); + + if (av_log_get_level() >= AV_LOG_VERBOSE && + (enc->width != enc->coded_width || + enc->height != enc->coded_height)) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " (%dx%d)", enc->coded_width, enc->coded_height); + + if (enc->sample_aspect_ratio.num) { + av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, + enc->width * (int64_t)enc->sample_aspect_ratio.num, + enc->height * (int64_t)enc->sample_aspect_ratio.den, + 1024 * 1024); + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " [SAR %d:%d DAR %d:%d]", + enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den, + display_aspect_ratio.num, display_aspect_ratio.den); + } + if (av_log_get_level() >= AV_LOG_DEBUG) { + int g = av_gcd(enc->time_base.num, enc->time_base.den); + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %d/%d", + enc->time_base.num / g, enc->time_base.den / g); + } + } + if (encode) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", q=%d-%d", enc->qmin, enc->qmax); + } else { + if (enc->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", Closed Captions"); + if (enc->properties & FF_CODEC_PROPERTY_LOSSLESS) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", lossless"); + } + break; + case AVMEDIA_TYPE_AUDIO: + av_strlcat(buf, separator, buf_size); + + if (enc->sample_rate) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + "%d Hz, ", enc->sample_rate); + } + av_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout); + if (enc->sample_fmt != AV_SAMPLE_FMT_NONE) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %s", av_get_sample_fmt_name(enc->sample_fmt)); + } + if ( enc->bits_per_raw_sample > 0 + && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " (%d bit)", enc->bits_per_raw_sample); + if (av_log_get_level() >= AV_LOG_VERBOSE) { + if (enc->initial_padding) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", delay %d", enc->initial_padding); + if (enc->trailing_padding) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", padding %d", enc->trailing_padding); + } + break; + case AVMEDIA_TYPE_DATA: + if (av_log_get_level() >= AV_LOG_DEBUG) { + int g = av_gcd(enc->time_base.num, enc->time_base.den); + if (g) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %d/%d", + enc->time_base.num / g, enc->time_base.den / g); + } + break; + case AVMEDIA_TYPE_SUBTITLE: + if (enc->width) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %dx%d", enc->width, enc->height); + break; + default: + return; + } + if (encode) { + if (enc->flags & AV_CODEC_FLAG_PASS1) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", pass 1"); + if (enc->flags & AV_CODEC_FLAG_PASS2) + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", pass 2"); + } + bitrate = get_bit_rate(enc); + if (bitrate != 0) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", %"PRId64" kb/s", bitrate / 1000); + } else if (enc->rc_max_rate > 0) { + snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", max. %"PRId64" kb/s", enc->rc_max_rate / 1000); + } +} + +const char *av_get_profile_name(const AVCodec *codec, int profile) +{ + const AVProfile *p; + if (profile == FF_PROFILE_UNKNOWN || !codec->profiles) + return NULL; + + for (p = codec->profiles; p->profile != FF_PROFILE_UNKNOWN; p++) + if (p->profile == profile) + return p->name; + + return NULL; +} + +const char *avcodec_profile_name(enum AVCodecID codec_id, int profile) +{ + const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id); + const AVProfile *p; + + if (profile == FF_PROFILE_UNKNOWN || !desc || !desc->profiles) + return NULL; + + for (p = desc->profiles; p->profile != FF_PROFILE_UNKNOWN; p++) + if (p->profile == profile) + return p->name; + + return NULL; +} + +unsigned avcodec_version(void) +{ + av_assert0(AV_CODEC_ID_PCM_S8_PLANAR==65563); + av_assert0(AV_CODEC_ID_ADPCM_G722==69660); + av_assert0(AV_CODEC_ID_SRT==94216); + av_assert0(LIBAVCODEC_VERSION_MICRO >= 100); + + return LIBAVCODEC_VERSION_INT; +} + +const char *avcodec_configuration(void) +{ + return FFMPEG_CONFIGURATION; +} + +const char *avcodec_license(void) +{ +#define LICENSE_PREFIX "libavcodec license: " + return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; +} + +int av_get_exact_bits_per_sample(enum AVCodecID codec_id) +{ + switch (codec_id) { + case AV_CODEC_ID_8SVX_EXP: + case AV_CODEC_ID_8SVX_FIB: + case AV_CODEC_ID_ADPCM_CT: + case AV_CODEC_ID_ADPCM_IMA_APC: + case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: + case AV_CODEC_ID_ADPCM_IMA_OKI: + case AV_CODEC_ID_ADPCM_IMA_WS: + case AV_CODEC_ID_ADPCM_G722: + case AV_CODEC_ID_ADPCM_YAMAHA: + case AV_CODEC_ID_ADPCM_AICA: + return 4; + case AV_CODEC_ID_DSD_LSBF: + case AV_CODEC_ID_DSD_MSBF: + case AV_CODEC_ID_DSD_LSBF_PLANAR: + case AV_CODEC_ID_DSD_MSBF_PLANAR: + case AV_CODEC_ID_PCM_ALAW: + case AV_CODEC_ID_PCM_MULAW: + case AV_CODEC_ID_PCM_VIDC: + case AV_CODEC_ID_PCM_S8: + case AV_CODEC_ID_PCM_S8_PLANAR: + case AV_CODEC_ID_PCM_U8: + case AV_CODEC_ID_PCM_ZORK: + case AV_CODEC_ID_SDX2_DPCM: + return 8; + case AV_CODEC_ID_PCM_S16BE: + case AV_CODEC_ID_PCM_S16BE_PLANAR: + case AV_CODEC_ID_PCM_S16LE: + case AV_CODEC_ID_PCM_S16LE_PLANAR: + case AV_CODEC_ID_PCM_U16BE: + case AV_CODEC_ID_PCM_U16LE: + return 16; + case AV_CODEC_ID_PCM_S24DAUD: + case AV_CODEC_ID_PCM_S24BE: + case AV_CODEC_ID_PCM_S24LE: + case AV_CODEC_ID_PCM_S24LE_PLANAR: + case AV_CODEC_ID_PCM_U24BE: + case AV_CODEC_ID_PCM_U24LE: + return 24; + case AV_CODEC_ID_PCM_S32BE: + case AV_CODEC_ID_PCM_S32LE: + case AV_CODEC_ID_PCM_S32LE_PLANAR: + case AV_CODEC_ID_PCM_U32BE: + case AV_CODEC_ID_PCM_U32LE: + case AV_CODEC_ID_PCM_F32BE: + case AV_CODEC_ID_PCM_F32LE: + case AV_CODEC_ID_PCM_F24LE: + case AV_CODEC_ID_PCM_F16LE: + return 32; + case AV_CODEC_ID_PCM_F64BE: + case AV_CODEC_ID_PCM_F64LE: + case AV_CODEC_ID_PCM_S64BE: + case AV_CODEC_ID_PCM_S64LE: + return 64; + default: + return 0; + } +} + +enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be) +{ + static const enum AVCodecID map[AV_SAMPLE_FMT_NB][2] = { + [AV_SAMPLE_FMT_U8 ] = { AV_CODEC_ID_PCM_U8, AV_CODEC_ID_PCM_U8 }, + [AV_SAMPLE_FMT_S16 ] = { AV_CODEC_ID_PCM_S16LE, AV_CODEC_ID_PCM_S16BE }, + [AV_SAMPLE_FMT_S32 ] = { AV_CODEC_ID_PCM_S32LE, AV_CODEC_ID_PCM_S32BE }, + [AV_SAMPLE_FMT_FLT ] = { AV_CODEC_ID_PCM_F32LE, AV_CODEC_ID_PCM_F32BE }, + [AV_SAMPLE_FMT_DBL ] = { AV_CODEC_ID_PCM_F64LE, AV_CODEC_ID_PCM_F64BE }, + [AV_SAMPLE_FMT_U8P ] = { AV_CODEC_ID_PCM_U8, AV_CODEC_ID_PCM_U8 }, + [AV_SAMPLE_FMT_S16P] = { AV_CODEC_ID_PCM_S16LE, AV_CODEC_ID_PCM_S16BE }, + [AV_SAMPLE_FMT_S32P] = { AV_CODEC_ID_PCM_S32LE, AV_CODEC_ID_PCM_S32BE }, + [AV_SAMPLE_FMT_S64P] = { AV_CODEC_ID_PCM_S64LE, AV_CODEC_ID_PCM_S64BE }, + [AV_SAMPLE_FMT_FLTP] = { AV_CODEC_ID_PCM_F32LE, AV_CODEC_ID_PCM_F32BE }, + [AV_SAMPLE_FMT_DBLP] = { AV_CODEC_ID_PCM_F64LE, AV_CODEC_ID_PCM_F64BE }, + }; + if (fmt < 0 || fmt >= AV_SAMPLE_FMT_NB) + return AV_CODEC_ID_NONE; + if (be < 0 || be > 1) + be = AV_NE(1, 0); + return map[fmt][be]; +} + +int av_get_bits_per_sample(enum AVCodecID codec_id) +{ + switch (codec_id) { + case AV_CODEC_ID_ADPCM_SBPRO_2: + return 2; + case AV_CODEC_ID_ADPCM_SBPRO_3: + return 3; + case AV_CODEC_ID_ADPCM_SBPRO_4: + case AV_CODEC_ID_ADPCM_IMA_WAV: + case AV_CODEC_ID_ADPCM_IMA_QT: + case AV_CODEC_ID_ADPCM_SWF: + case AV_CODEC_ID_ADPCM_MS: + return 4; + default: + return av_get_exact_bits_per_sample(codec_id); + } +} + +static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, + uint32_t tag, int bits_per_coded_sample, int64_t bitrate, + uint8_t * extradata, int frame_size, int frame_bytes) +{ + int bps = av_get_exact_bits_per_sample(id); + int framecount = (ba > 0 && frame_bytes / ba > 0) ? frame_bytes / ba : 1; + + /* codecs with an exact constant bits per sample */ + if (bps > 0 && ch > 0 && frame_bytes > 0 && ch < 32768 && bps < 32768) + return (frame_bytes * 8LL) / (bps * ch); + bps = bits_per_coded_sample; + + /* codecs with a fixed packet duration */ + switch (id) { + case AV_CODEC_ID_ADPCM_ADX: return 32; + case AV_CODEC_ID_ADPCM_IMA_QT: return 64; + case AV_CODEC_ID_ADPCM_EA_XAS: return 128; + case AV_CODEC_ID_AMR_NB: + case AV_CODEC_ID_EVRC: + case AV_CODEC_ID_GSM: + case AV_CODEC_ID_QCELP: + case AV_CODEC_ID_RA_288: return 160; + case AV_CODEC_ID_AMR_WB: + case AV_CODEC_ID_GSM_MS: return 320; + case AV_CODEC_ID_MP1: return 384; + case AV_CODEC_ID_ATRAC1: return 512; + case AV_CODEC_ID_ATRAC9: + case AV_CODEC_ID_ATRAC3: return 1024 * framecount; + case AV_CODEC_ID_ATRAC3P: return 2048; + case AV_CODEC_ID_MP2: + case AV_CODEC_ID_MUSEPACK7: return 1152; + case AV_CODEC_ID_AC3: return 1536; + } + + if (sr > 0) { + /* calc from sample rate */ + if (id == AV_CODEC_ID_TTA) + return 256 * sr / 245; + else if (id == AV_CODEC_ID_DST) + return 588 * sr / 44100; + + if (ch > 0) { + /* calc from sample rate and channels */ + if (id == AV_CODEC_ID_BINKAUDIO_DCT) + return (480 << (sr / 22050)) / ch; + } + + if (id == AV_CODEC_ID_MP3) + return sr <= 24000 ? 576 : 1152; + } + + if (ba > 0) { + /* calc from block_align */ + if (id == AV_CODEC_ID_SIPR) { + switch (ba) { + case 20: return 160; + case 19: return 144; + case 29: return 288; + case 37: return 480; + } + } else if (id == AV_CODEC_ID_ILBC) { + switch (ba) { + case 38: return 160; + case 50: return 240; + } + } + } + + if (frame_bytes > 0) { + /* calc from frame_bytes only */ + if (id == AV_CODEC_ID_TRUESPEECH) + return 240 * (frame_bytes / 32); + if (id == AV_CODEC_ID_NELLYMOSER) + return 256 * (frame_bytes / 64); + if (id == AV_CODEC_ID_RA_144) + return 160 * (frame_bytes / 20); + + if (bps > 0) { + /* calc from frame_bytes and bits_per_coded_sample */ + if (id == AV_CODEC_ID_ADPCM_G726 || id == AV_CODEC_ID_ADPCM_G726LE) + return frame_bytes * 8 / bps; + } + + if (ch > 0 && ch < INT_MAX/16) { + /* calc from frame_bytes and channels */ + switch (id) { + case AV_CODEC_ID_ADPCM_AFC: + return frame_bytes / (9 * ch) * 16; + case AV_CODEC_ID_ADPCM_PSX: + case AV_CODEC_ID_ADPCM_DTK: + return frame_bytes / (16 * ch) * 28; + case AV_CODEC_ID_ADPCM_4XM: + case AV_CODEC_ID_ADPCM_IMA_DAT4: + case AV_CODEC_ID_ADPCM_IMA_ISS: + return (frame_bytes - 4 * ch) * 2 / ch; + case AV_CODEC_ID_ADPCM_IMA_SMJPEG: + return (frame_bytes - 4) * 2 / ch; + case AV_CODEC_ID_ADPCM_IMA_AMV: + return (frame_bytes - 8) * 2 / ch; + case AV_CODEC_ID_ADPCM_THP: + case AV_CODEC_ID_ADPCM_THP_LE: + if (extradata) + return frame_bytes * 14 / (8 * ch); + break; + case AV_CODEC_ID_ADPCM_XA: + return (frame_bytes / 128) * 224 / ch; + case AV_CODEC_ID_INTERPLAY_DPCM: + return (frame_bytes - 6 - ch) / ch; + case AV_CODEC_ID_ROQ_DPCM: + return (frame_bytes - 8) / ch; + case AV_CODEC_ID_XAN_DPCM: + return (frame_bytes - 2 * ch) / ch; + case AV_CODEC_ID_MACE3: + return 3 * frame_bytes / ch; + case AV_CODEC_ID_MACE6: + return 6 * frame_bytes / ch; + case AV_CODEC_ID_PCM_LXF: + return 2 * (frame_bytes / (5 * ch)); + case AV_CODEC_ID_IAC: + case AV_CODEC_ID_IMC: + return 4 * frame_bytes / ch; + } + + if (tag) { + /* calc from frame_bytes, channels, and codec_tag */ + if (id == AV_CODEC_ID_SOL_DPCM) { + if (tag == 3) + return frame_bytes / ch; + else + return frame_bytes * 2 / ch; + } + } + + if (ba > 0) { + /* calc from frame_bytes, channels, and block_align */ + int blocks = frame_bytes / ba; + switch (id) { + case AV_CODEC_ID_ADPCM_IMA_WAV: + if (bps < 2 || bps > 5) + return 0; + return blocks * (1 + (ba - 4 * ch) / (bps * ch) * 8); + case AV_CODEC_ID_ADPCM_IMA_DK3: + return blocks * (((ba - 16) * 2 / 3 * 4) / ch); + case AV_CODEC_ID_ADPCM_IMA_DK4: + return blocks * (1 + (ba - 4 * ch) * 2 / ch); + case AV_CODEC_ID_ADPCM_IMA_RAD: + return blocks * ((ba - 4 * ch) * 2 / ch); + case AV_CODEC_ID_ADPCM_MS: + return blocks * (2 + (ba - 7 * ch) * 2 / ch); + case AV_CODEC_ID_ADPCM_MTAF: + return blocks * (ba - 16) * 2 / ch; + } + } + + if (bps > 0) { + /* calc from frame_bytes, channels, and bits_per_coded_sample */ + switch (id) { + case AV_CODEC_ID_PCM_DVD: + if(bps<4 || frame_bytes<3) + return 0; + return 2 * ((frame_bytes - 3) / ((bps * 2 / 8) * ch)); + case AV_CODEC_ID_PCM_BLURAY: + if(bps<4 || frame_bytes<4) + return 0; + return (frame_bytes - 4) / ((FFALIGN(ch, 2) * bps) / 8); + case AV_CODEC_ID_S302M: + return 2 * (frame_bytes / ((bps + 4) / 4)) / ch; + } + } + } + } + + /* Fall back on using frame_size */ + if (frame_size > 1 && frame_bytes) + return frame_size; + + //For WMA we currently have no other means to calculate duration thus we + //do it here by assuming CBR, which is true for all known cases. + if (bitrate > 0 && frame_bytes > 0 && sr > 0 && ba > 1) { + if (id == AV_CODEC_ID_WMAV1 || id == AV_CODEC_ID_WMAV2) + return (frame_bytes * 8LL * sr) / bitrate; + } + + return 0; +} + +int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) +{ + return get_audio_frame_duration(avctx->codec_id, avctx->sample_rate, + avctx->channels, avctx->block_align, + avctx->codec_tag, avctx->bits_per_coded_sample, + avctx->bit_rate, avctx->extradata, avctx->frame_size, + frame_bytes); +} + +int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes) +{ + return get_audio_frame_duration(par->codec_id, par->sample_rate, + par->channels, par->block_align, + par->codec_tag, par->bits_per_coded_sample, + par->bit_rate, par->extradata, par->frame_size, + frame_bytes); +} + +#if !HAVE_THREADS +int ff_thread_init(AVCodecContext *s) +{ + return -1; +} + +#endif + +unsigned int av_xiphlacing(unsigned char *s, unsigned int v) +{ + unsigned int n = 0; + + while (v >= 0xff) { + *s++ = 0xff; + v -= 0xff; + n++; + } + *s = v; + n++; + return n; +} + +int ff_match_2uint16(const uint16_t(*tab)[2], int size, int a, int b) +{ + int i; + for (i = 0; i < size && !(tab[i][0] == a && tab[i][1] == b); i++) ; + return i; +} + +const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index) +{ + int i; + if (!codec->hw_configs || index < 0) + return NULL; + for (i = 0; i <= index; i++) + if (!codec->hw_configs[i]) + return NULL; + return &codec->hw_configs[index]->public; +} + +#if FF_API_USER_VISIBLE_AVHWACCEL +AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel) +{ + return NULL; +} + +void av_register_hwaccel(AVHWAccel *hwaccel) +{ +} +#endif + +#if FF_API_LOCKMGR +int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) +{ + return 0; +} +#endif + +unsigned int avpriv_toupper4(unsigned int x) +{ + return av_toupper(x & 0xFF) + + (av_toupper((x >> 8) & 0xFF) << 8) + + (av_toupper((x >> 16) & 0xFF) << 16) + +((unsigned)av_toupper((x >> 24) & 0xFF) << 24); +} + +int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src) +{ + int ret; + + dst->owner[0] = src->owner[0]; + dst->owner[1] = src->owner[1]; + + ret = av_frame_ref(dst->f, src->f); + if (ret < 0) + return ret; + + av_assert0(!dst->progress); + + if (src->progress && + !(dst->progress = av_buffer_ref(src->progress))) { + ff_thread_release_buffer(dst->owner[0], dst); + return AVERROR(ENOMEM); + } + + return 0; +} + +#if !HAVE_THREADS + +enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) +{ + return ff_get_format(avctx, fmt); +} + +int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) +{ + f->owner[0] = f->owner[1] = avctx; + return ff_get_buffer(avctx, f->f, flags); +} + +void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f) +{ + if (f->f) + av_frame_unref(f->f); +} + +void ff_thread_finish_setup(AVCodecContext *avctx) +{ +} + +void ff_thread_report_progress(ThreadFrame *f, int progress, int field) +{ +} + +void ff_thread_await_progress(ThreadFrame *f, int progress, int field) +{ +} + +int ff_thread_can_start_frame(AVCodecContext *avctx) +{ + return 1; +} + +int ff_alloc_entries(AVCodecContext *avctx, int count) +{ + return 0; +} + +void ff_reset_entries(AVCodecContext *avctx) +{ +} + +void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift) +{ +} + +void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n) +{ +} + +#endif + +int avcodec_is_open(AVCodecContext *s) +{ + return !!s->internal; +} + +int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf) +{ + int ret; + char *str; + + ret = av_bprint_finalize(buf, &str); + if (ret < 0) + return ret; + if (!av_bprint_is_complete(buf)) { + av_free(str); + return AVERROR(ENOMEM); + } + + avctx->extradata = str; + /* Note: the string is NUL terminated (so extradata can be read as a + * string), but the ending character is not accounted in the size (in + * binary formats you are likely not supposed to mux that character). When + * extradata is copied, it is also padded with AV_INPUT_BUFFER_PADDING_SIZE + * zeros. */ + avctx->extradata_size = buf->len; + return 0; +} + +const uint8_t *avpriv_find_start_code(const uint8_t *av_restrict p, + const uint8_t *end, + uint32_t *av_restrict state) +{ + int i; + + av_assert0(p <= end); + if (p >= end) + return end; + + for (i = 0; i < 3; i++) { + uint32_t tmp = *state << 8; + *state = tmp + *(p++); + if (tmp == 0x100 || p == end) + return p; + } + + while (p < end) { + if (p[-1] > 1 ) p += 3; + else if (p[-2] ) p += 2; + else if (p[-3]|(p[-1]-1)) p++; + else { + p++; + break; + } + } + + p = FFMIN(p, end) - 4; + *state = AV_RB32(p); + + return p + 4; +} + +AVCPBProperties *av_cpb_properties_alloc(size_t *size) +{ + AVCPBProperties *props = av_mallocz(sizeof(AVCPBProperties)); + if (!props) + return NULL; + + if (size) + *size = sizeof(*props); + + props->vbv_delay = UINT64_MAX; + + return props; +} + +AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx) +{ + AVPacketSideData *tmp; + AVCPBProperties *props; + size_t size; + + props = av_cpb_properties_alloc(&size); + if (!props) + return NULL; + + tmp = av_realloc_array(avctx->coded_side_data, avctx->nb_coded_side_data + 1, sizeof(*tmp)); + if (!tmp) { + av_freep(&props); + return NULL; + } + + avctx->coded_side_data = tmp; + avctx->nb_coded_side_data++; + + avctx->coded_side_data[avctx->nb_coded_side_data - 1].type = AV_PKT_DATA_CPB_PROPERTIES; + avctx->coded_side_data[avctx->nb_coded_side_data - 1].data = (uint8_t*)props; + avctx->coded_side_data[avctx->nb_coded_side_data - 1].size = size; + + return props; +} + +static void codec_parameters_reset(AVCodecParameters *par) +{ + av_freep(&par->extradata); + + memset(par, 0, sizeof(*par)); + + par->codec_type = AVMEDIA_TYPE_UNKNOWN; + par->codec_id = AV_CODEC_ID_NONE; + par->format = -1; + par->field_order = AV_FIELD_UNKNOWN; + par->color_range = AVCOL_RANGE_UNSPECIFIED; + par->color_primaries = AVCOL_PRI_UNSPECIFIED; + par->color_trc = AVCOL_TRC_UNSPECIFIED; + par->color_space = AVCOL_SPC_UNSPECIFIED; + par->chroma_location = AVCHROMA_LOC_UNSPECIFIED; + par->sample_aspect_ratio = (AVRational){ 0, 1 }; + par->profile = FF_PROFILE_UNKNOWN; + par->level = FF_LEVEL_UNKNOWN; +} + +AVCodecParameters *avcodec_parameters_alloc(void) +{ + AVCodecParameters *par = av_mallocz(sizeof(*par)); + + if (!par) + return NULL; + codec_parameters_reset(par); + return par; +} + +void avcodec_parameters_free(AVCodecParameters **ppar) +{ + AVCodecParameters *par = *ppar; + + if (!par) + return; + codec_parameters_reset(par); + + av_freep(ppar); +} + +int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src) +{ + codec_parameters_reset(dst); + memcpy(dst, src, sizeof(*dst)); + + dst->extradata = NULL; + dst->extradata_size = 0; + if (src->extradata) { + dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!dst->extradata) + return AVERROR(ENOMEM); + memcpy(dst->extradata, src->extradata, src->extradata_size); + dst->extradata_size = src->extradata_size; + } + + return 0; +} + +int avcodec_parameters_from_context(AVCodecParameters *par, + const AVCodecContext *codec) +{ + codec_parameters_reset(par); + + par->codec_type = codec->codec_type; + par->codec_id = codec->codec_id; + par->codec_tag = codec->codec_tag; + + par->bit_rate = codec->bit_rate; + par->bits_per_coded_sample = codec->bits_per_coded_sample; + par->bits_per_raw_sample = codec->bits_per_raw_sample; + par->profile = codec->profile; + par->level = codec->level; + + switch (par->codec_type) { + case AVMEDIA_TYPE_VIDEO: + par->format = codec->pix_fmt; + par->width = codec->width; + par->height = codec->height; + par->field_order = codec->field_order; + par->color_range = codec->color_range; + par->color_primaries = codec->color_primaries; + par->color_trc = codec->color_trc; + par->color_space = codec->colorspace; + par->chroma_location = codec->chroma_sample_location; + par->sample_aspect_ratio = codec->sample_aspect_ratio; + par->video_delay = codec->has_b_frames; + break; + case AVMEDIA_TYPE_AUDIO: + par->format = codec->sample_fmt; + par->channel_layout = codec->channel_layout; + par->channels = codec->channels; + par->sample_rate = codec->sample_rate; + par->block_align = codec->block_align; + par->frame_size = codec->frame_size; + par->initial_padding = codec->initial_padding; + par->trailing_padding = codec->trailing_padding; + par->seek_preroll = codec->seek_preroll; + break; + case AVMEDIA_TYPE_SUBTITLE: + par->width = codec->width; + par->height = codec->height; + break; + } + + if (codec->extradata) { + par->extradata = av_mallocz(codec->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!par->extradata) + return AVERROR(ENOMEM); + memcpy(par->extradata, codec->extradata, codec->extradata_size); + par->extradata_size = codec->extradata_size; + } + + return 0; +} + +int avcodec_parameters_to_context(AVCodecContext *codec, + const AVCodecParameters *par) +{ + codec->codec_type = par->codec_type; + codec->codec_id = par->codec_id; + codec->codec_tag = par->codec_tag; + + codec->bit_rate = par->bit_rate; + codec->bits_per_coded_sample = par->bits_per_coded_sample; + codec->bits_per_raw_sample = par->bits_per_raw_sample; + codec->profile = par->profile; + codec->level = par->level; + + switch (par->codec_type) { + case AVMEDIA_TYPE_VIDEO: + codec->pix_fmt = par->format; + codec->width = par->width; + codec->height = par->height; + codec->field_order = par->field_order; + codec->color_range = par->color_range; + codec->color_primaries = par->color_primaries; + codec->color_trc = par->color_trc; + codec->colorspace = par->color_space; + codec->chroma_sample_location = par->chroma_location; + codec->sample_aspect_ratio = par->sample_aspect_ratio; + codec->has_b_frames = par->video_delay; + break; + case AVMEDIA_TYPE_AUDIO: + codec->sample_fmt = par->format; + codec->channel_layout = par->channel_layout; + codec->channels = par->channels; + codec->sample_rate = par->sample_rate; + codec->block_align = par->block_align; + codec->frame_size = par->frame_size; + codec->delay = + codec->initial_padding = par->initial_padding; + codec->trailing_padding = par->trailing_padding; + codec->seek_preroll = par->seek_preroll; + break; + case AVMEDIA_TYPE_SUBTITLE: + codec->width = par->width; + codec->height = par->height; + break; + } + + if (par->extradata) { + av_freep(&codec->extradata); + codec->extradata = av_mallocz(par->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!codec->extradata) + return AVERROR(ENOMEM); + memcpy(codec->extradata, par->extradata, par->extradata_size); + codec->extradata_size = par->extradata_size; + } + + return 0; +} + +int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, + void **data, size_t *sei_size) +{ + AVFrameSideData *side_data = NULL; + uint8_t *sei_data; + + if (frame) + side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC); + + if (!side_data) { + *data = NULL; + return 0; + } + + *sei_size = side_data->size + 11; + *data = av_mallocz(*sei_size + prefix_len); + if (!*data) + return AVERROR(ENOMEM); + sei_data = (uint8_t*)*data + prefix_len; + + // country code + sei_data[0] = 181; + sei_data[1] = 0; + sei_data[2] = 49; + + /** + * 'GA94' is standard in North America for ATSC, but hard coding + * this style may not be the right thing to do -- other formats + * do exist. This information is not available in the side_data + * so we are going with this right now. + */ + AV_WL32(sei_data + 3, MKTAG('G', 'A', '9', '4')); + sei_data[7] = 3; + sei_data[8] = ((side_data->size/3) & 0x1f) | 0x40; + sei_data[9] = 0; + + memcpy(sei_data + 10, side_data->data, side_data->size); + + sei_data[side_data->size+10] = 255; + + return 0; +} + +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx) +{ + AVRational framerate = avctx->framerate; + int bits_per_coded_sample = avctx->bits_per_coded_sample; + int64_t bitrate; + + if (!(framerate.num && framerate.den)) + framerate = av_inv_q(avctx->time_base); + if (!(framerate.num && framerate.den)) + return 0; + + if (!bits_per_coded_sample) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + bits_per_coded_sample = av_get_bits_per_pixel(desc); + } + bitrate = (int64_t)bits_per_coded_sample * avctx->width * avctx->height * + framerate.num / framerate.den; + + return bitrate; +} + +int ff_int_from_list_or_default(void *ctx, const char * val_name, int val, + const int * array_valid_values, int default_value) +{ + int i = 0, ref_val; + + while (1) { + ref_val = array_valid_values[i]; + if (ref_val == INT_MAX) + break; + if (val == ref_val) + return val; + i++; + } + /* val is not a valid value */ + av_log(ctx, AV_LOG_DEBUG, + "%s %d are not supported. Set to default value : %d\n", val_name, val, default_value); + return default_value; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vaapi.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vaapi.h new file mode 100644 index 000000000..2cf7da588 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vaapi.h @@ -0,0 +1,86 @@ +/* + * Video Acceleration API (shared data between FFmpeg and the video player) + * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 + * + * Copyright (C) 2008-2009 Splitted-Desktop Systems + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VAAPI_H +#define AVCODEC_VAAPI_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_vaapi + * Public libavcodec VA API header. + */ + +#include +#include "libavutil/attributes.h" +#include "version.h" + +#if FF_API_STRUCT_VAAPI_CONTEXT + +/** + * @defgroup lavc_codec_hwaccel_vaapi VA API Decoding + * @ingroup lavc_codec_hwaccel + * @{ + */ + +/** + * This structure is used to share data between the FFmpeg library and + * the client video application. + * This shall be zero-allocated and available as + * AVCodecContext.hwaccel_context. All user members can be set once + * during initialization or through each AVCodecContext.get_buffer() + * function call. In any case, they must be valid prior to calling + * decoding functions. + * + * Deprecated: use AVCodecContext.hw_frames_ctx instead. + */ +struct attribute_deprecated vaapi_context { + /** + * Window system dependent data + * + * - encoding: unused + * - decoding: Set by user + */ + void *display; + + /** + * Configuration ID + * + * - encoding: unused + * - decoding: Set by user + */ + uint32_t config_id; + + /** + * Context ID (video decode pipeline) + * + * - encoding: unused + * - decoding: Set by user + */ + uint32_t context_id; +}; + +/* @} */ + +#endif /* FF_API_STRUCT_VAAPI_CONTEXT */ + +#endif /* AVCODEC_VAAPI_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vdpau.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vdpau.h new file mode 100644 index 000000000..4d9994336 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vdpau.h @@ -0,0 +1,176 @@ +/* + * The Video Decode and Presentation API for UNIX (VDPAU) is used for + * hardware-accelerated decoding of MPEG-1/2, H.264 and VC-1. + * + * Copyright (C) 2008 NVIDIA + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VDPAU_H +#define AVCODEC_VDPAU_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_vdpau + * Public libavcodec VDPAU header. + */ + + +/** + * @defgroup lavc_codec_hwaccel_vdpau VDPAU Decoder and Renderer + * @ingroup lavc_codec_hwaccel + * + * VDPAU hardware acceleration has two modules + * - VDPAU decoding + * - VDPAU presentation + * + * The VDPAU decoding module parses all headers using FFmpeg + * parsing mechanisms and uses VDPAU for the actual decoding. + * + * As per the current implementation, the actual decoding + * and rendering (API calls) are done as part of the VDPAU + * presentation (vo_vdpau.c) module. + * + * @{ + */ + +#include + +#include "libavutil/avconfig.h" +#include "libavutil/attributes.h" + +#include "avcodec.h" +#include "version.h" + +struct AVCodecContext; +struct AVFrame; + +typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *, + const VdpPictureInfo *, uint32_t, + const VdpBitstreamBuffer *); + +/** + * This structure is used to share data between the libavcodec library and + * the client video application. + * The user shall allocate the structure via the av_alloc_vdpau_hwaccel + * function and make it available as + * AVCodecContext.hwaccel_context. Members can be set by the user once + * during initialization or through each AVCodecContext.get_buffer() + * function call. In any case, they must be valid prior to calling + * decoding functions. + * + * The size of this structure is not a part of the public ABI and must not + * be used outside of libavcodec. Use av_vdpau_alloc_context() to allocate an + * AVVDPAUContext. + */ +typedef struct AVVDPAUContext { + /** + * VDPAU decoder handle + * + * Set by user. + */ + VdpDecoder decoder; + + /** + * VDPAU decoder render callback + * + * Set by the user. + */ + VdpDecoderRender *render; + + AVVDPAU_Render2 render2; +} AVVDPAUContext; + +/** + * @brief allocation function for AVVDPAUContext + * + * Allows extending the struct without breaking API/ABI + */ +AVVDPAUContext *av_alloc_vdpaucontext(void); + +AVVDPAU_Render2 av_vdpau_hwaccel_get_render2(const AVVDPAUContext *); +void av_vdpau_hwaccel_set_render2(AVVDPAUContext *, AVVDPAU_Render2); + +/** + * Associate a VDPAU device with a codec context for hardware acceleration. + * This function is meant to be called from the get_format() codec callback, + * or earlier. It can also be called after avcodec_flush_buffers() to change + * the underlying VDPAU device mid-stream (e.g. to recover from non-transparent + * display preemption). + * + * @note get_format() must return AV_PIX_FMT_VDPAU if this function completes + * successfully. + * + * @param avctx decoding context whose get_format() callback is invoked + * @param device VDPAU device handle to use for hardware acceleration + * @param get_proc_address VDPAU device driver + * @param flags zero of more OR'd AV_HWACCEL_FLAG_* flags + * + * @return 0 on success, an AVERROR code on failure. + */ +int av_vdpau_bind_context(AVCodecContext *avctx, VdpDevice device, + VdpGetProcAddress *get_proc_address, unsigned flags); + +/** + * Gets the parameters to create an adequate VDPAU video surface for the codec + * context using VDPAU hardware decoding acceleration. + * + * @note Behavior is undefined if the context was not successfully bound to a + * VDPAU device using av_vdpau_bind_context(). + * + * @param avctx the codec context being used for decoding the stream + * @param type storage space for the VDPAU video surface chroma type + * (or NULL to ignore) + * @param width storage space for the VDPAU video surface pixel width + * (or NULL to ignore) + * @param height storage space for the VDPAU video surface pixel height + * (or NULL to ignore) + * + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_vdpau_get_surface_parameters(AVCodecContext *avctx, VdpChromaType *type, + uint32_t *width, uint32_t *height); + +/** + * Allocate an AVVDPAUContext. + * + * @return Newly-allocated AVVDPAUContext or NULL on failure. + */ +AVVDPAUContext *av_vdpau_alloc_context(void); + +#if FF_API_VDPAU_PROFILE +/** + * Get a decoder profile that should be used for initializing a VDPAU decoder. + * Should be called from the AVCodecContext.get_format() callback. + * + * @deprecated Use av_vdpau_bind_context() instead. + * + * @param avctx the codec context being used for decoding the stream + * @param profile a pointer into which the result will be written on success. + * The contents of profile are undefined if this function returns + * an error. + * + * @return 0 on success (non-negative), a negative AVERROR on failure. + */ +attribute_deprecated +int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile); +#endif + +/* @}*/ + +#endif /* AVCODEC_VDPAU_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/version.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/version.h new file mode 100644 index 000000000..3331d4730 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/version.h @@ -0,0 +1,140 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VERSION_H +#define AVCODEC_VERSION_H + +/** + * @file + * @ingroup libavc + * Libavcodec version macros. + */ + +#include "libavutil/version.h" + +#define LIBAVCODEC_VERSION_MAJOR 58 +#define LIBAVCODEC_VERSION_MINOR 54 +#define LIBAVCODEC_VERSION_MICRO 100 + +#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT + +#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) + +/** + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + * + * @note, when bumping the major version it is recommended to manually + * disable each FF_API_* in its own commit instead of disabling them all + * at once through the bump. This improves the git bisect-ability of the change. + */ + +#ifndef FF_API_LOWRES +#define FF_API_LOWRES (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_DEBUG_MV +#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 58) +#endif +#ifndef FF_API_AVCTX_TIMEBASE +#define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_CODED_FRAME +#define FF_API_CODED_FRAME (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_SIDEDATA_ONLY_PKT +#define FF_API_SIDEDATA_ONLY_PKT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_VDPAU_PROFILE +#define FF_API_VDPAU_PROFILE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_CONVERGENCE_DURATION +#define FF_API_CONVERGENCE_DURATION (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_AVPICTURE +#define FF_API_AVPICTURE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_AVPACKET_OLD_API +#define FF_API_AVPACKET_OLD_API (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_RTP_CALLBACK +#define FF_API_RTP_CALLBACK (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_VBV_DELAY +#define FF_API_VBV_DELAY (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_CODER_TYPE +#define FF_API_CODER_TYPE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_STAT_BITS +#define FF_API_STAT_BITS (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_PRIVATE_OPT +#define FF_API_PRIVATE_OPT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_ASS_TIMING +#define FF_API_ASS_TIMING (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OLD_BSF +#define FF_API_OLD_BSF (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_COPY_CONTEXT +#define FF_API_COPY_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_GET_CONTEXT_DEFAULTS +#define FF_API_GET_CONTEXT_DEFAULTS (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_NVENC_OLD_NAME +#define FF_API_NVENC_OLD_NAME (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_STRUCT_VAAPI_CONTEXT +#define FF_API_STRUCT_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_MERGE_SD_API +#define FF_API_MERGE_SD_API (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_TAG_STRING +#define FF_API_TAG_STRING (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_GETCHROMA +#define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_CODEC_GET_SET +#define FF_API_CODEC_GET_SET (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_USER_VISIBLE_AVHWACCEL +#define FF_API_USER_VISIBLE_AVHWACCEL (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LOCKMGR +#define FF_API_LOCKMGR (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_NEXT +#define FF_API_NEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_UNSANITIZED_BITRATES +#define FF_API_UNSANITIZED_BITRATES (LIBAVCODEC_VERSION_MAJOR < 59) +#endif + + +#endif /* AVCODEC_VERSION_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videodsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videodsp.c new file mode 100644 index 000000000..ce9e9eb14 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videodsp.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2012 Ronald S. Bultje + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "videodsp.h" + +#define BIT_DEPTH 8 +#include "videodsp_template.c" +#undef BIT_DEPTH + +#define BIT_DEPTH 16 +#include "videodsp_template.c" +#undef BIT_DEPTH + +static void just_return(uint8_t *buf, ptrdiff_t stride, int h) +{ +} + +av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc) +{ + ctx->prefetch = just_return; + if (bpc <= 8) { + ctx->emulated_edge_mc = ff_emulated_edge_mc_8; + } else { + ctx->emulated_edge_mc = ff_emulated_edge_mc_16; + } + + if (ARCH_AARCH64) + ff_videodsp_init_aarch64(ctx, bpc); + if (ARCH_ARM) + ff_videodsp_init_arm(ctx, bpc); + if (ARCH_PPC) + ff_videodsp_init_ppc(ctx, bpc); + if (ARCH_X86) + ff_videodsp_init_x86(ctx, bpc); + if (ARCH_MIPS) + ff_videodsp_init_mips(ctx, bpc); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videodsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videodsp.h new file mode 100644 index 000000000..c0545f22b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videodsp.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2012 Ronald S. Bultje + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Core video DSP helper functions + */ + +#ifndef AVCODEC_VIDEODSP_H +#define AVCODEC_VIDEODSP_H + +#include +#include + +#define EMULATED_EDGE(depth) \ +void ff_emulated_edge_mc_ ## depth(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t dst_stride, ptrdiff_t src_stride, \ + int block_w, int block_h,\ + int src_x, int src_y, int w, int h); + +EMULATED_EDGE(8) +EMULATED_EDGE(16) + +typedef struct VideoDSPContext { + /** + * Copy a rectangular area of samples to a temporary buffer and replicate + * the border samples. + * + * @param dst destination buffer + * @param dst_stride number of bytes between 2 vertically adjacent samples + * in destination buffer + * @param src source buffer + * @param dst_linesize number of bytes between 2 vertically adjacent + * samples in the destination buffer + * @param src_linesize number of bytes between 2 vertically adjacent + * samples in both the source buffer + * @param block_w width of block + * @param block_h height of block + * @param src_x x coordinate of the top left sample of the block in the + * source buffer + * @param src_y y coordinate of the top left sample of the block in the + * source buffer + * @param w width of the source buffer + * @param h height of the source buffer + */ + void (*emulated_edge_mc)(uint8_t *dst, const uint8_t *src, + ptrdiff_t dst_linesize, + ptrdiff_t src_linesize, + int block_w, int block_h, + int src_x, int src_y, int w, int h); + + /** + * Prefetch memory into cache (if supported by hardware). + * + * @param buf pointer to buffer to prefetch memory from + * @param stride distance between two lines of buf (in bytes) + * @param h number of lines to prefetch + */ + void (*prefetch)(uint8_t *buf, ptrdiff_t stride, int h); +} VideoDSPContext; + +void ff_videodsp_init(VideoDSPContext *ctx, int bpc); + +/* for internal use only (i.e. called by ff_videodsp_init() */ +void ff_videodsp_init_aarch64(VideoDSPContext *ctx, int bpc); +void ff_videodsp_init_arm(VideoDSPContext *ctx, int bpc); +void ff_videodsp_init_ppc(VideoDSPContext *ctx, int bpc); +void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc); +void ff_videodsp_init_mips(VideoDSPContext *ctx, int bpc); + +#endif /* AVCODEC_VIDEODSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videotoolbox.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videotoolbox.h new file mode 100644 index 000000000..af2db0d58 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/videotoolbox.h @@ -0,0 +1,127 @@ +/* + * Videotoolbox hardware acceleration + * + * copyright (c) 2012 Sebastien Zwickert + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VIDEOTOOLBOX_H +#define AVCODEC_VIDEOTOOLBOX_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_videotoolbox + * Public libavcodec Videotoolbox header. + */ + +#include + +#define Picture QuickdrawPicture +#include +#undef Picture + +#include "libavcodec/avcodec.h" + +/** + * This struct holds all the information that needs to be passed + * between the caller and libavcodec for initializing Videotoolbox decoding. + * Its size is not a part of the public ABI, it must be allocated with + * av_videotoolbox_alloc_context() and freed with av_free(). + */ +typedef struct AVVideotoolboxContext { + /** + * Videotoolbox decompression session object. + * Created and freed the caller. + */ + VTDecompressionSessionRef session; + + /** + * The output callback that must be passed to the session. + * Set by av_videottoolbox_default_init() + */ + VTDecompressionOutputCallback output_callback; + + /** + * CVPixelBuffer Format Type that Videotoolbox will use for decoded frames. + * set by the caller. If this is set to 0, then no specific format is + * requested from the decoder, and its native format is output. + */ + OSType cv_pix_fmt_type; + + /** + * CoreMedia Format Description that Videotoolbox will use to create the decompression session. + * Set by the caller. + */ + CMVideoFormatDescriptionRef cm_fmt_desc; + + /** + * CoreMedia codec type that Videotoolbox will use to create the decompression session. + * Set by the caller. + */ + int cm_codec_type; +} AVVideotoolboxContext; + +/** + * Allocate and initialize a Videotoolbox context. + * + * This function should be called from the get_format() callback when the caller + * selects the AV_PIX_FMT_VIDETOOLBOX format. The caller must then create + * the decoder object (using the output callback provided by libavcodec) that + * will be used for Videotoolbox-accelerated decoding. + * + * When decoding with Videotoolbox is finished, the caller must destroy the decoder + * object and free the Videotoolbox context using av_free(). + * + * @return the newly allocated context or NULL on failure + */ +AVVideotoolboxContext *av_videotoolbox_alloc_context(void); + +/** + * This is a convenience function that creates and sets up the Videotoolbox context using + * an internal implementation. + * + * @param avctx the corresponding codec context + * + * @return >= 0 on success, a negative AVERROR code on failure + */ +int av_videotoolbox_default_init(AVCodecContext *avctx); + +/** + * This is a convenience function that creates and sets up the Videotoolbox context using + * an internal implementation. + * + * @param avctx the corresponding codec context + * @param vtctx the Videotoolbox context to use + * + * @return >= 0 on success, a negative AVERROR code on failure + */ +int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext *vtctx); + +/** + * This function must be called to free the Videotoolbox context initialized with + * av_videotoolbox_default_init(). + * + * @param avctx the corresponding codec context + */ +void av_videotoolbox_default_free(AVCodecContext *avctx); + +/** + * @} + */ + +#endif /* AVCODEC_VIDEOTOOLBOX_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vlc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vlc.h new file mode 100644 index 000000000..42ccddf3f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vlc.h @@ -0,0 +1,81 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VLC_H +#define AVCODEC_VLC_H + +#include + +#define VLC_TYPE int16_t + +typedef struct VLC { + int bits; + VLC_TYPE (*table)[2]; ///< code, bits + int table_size, table_allocated; +} VLC; + +typedef struct RL_VLC_ELEM { + int16_t level; + int8_t len; + uint8_t run; +} RL_VLC_ELEM; + +#define init_vlc(vlc, nb_bits, nb_codes, \ + bits, bits_wrap, bits_size, \ + codes, codes_wrap, codes_size, \ + flags) \ + ff_init_vlc_sparse(vlc, nb_bits, nb_codes, \ + bits, bits_wrap, bits_size, \ + codes, codes_wrap, codes_size, \ + NULL, 0, 0, flags) + +int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + const void *symbols, int symbols_wrap, int symbols_size, + int flags); +void ff_free_vlc(VLC *vlc); + +#define INIT_VLC_LE 2 +#define INIT_VLC_USE_NEW_STATIC 4 + +#define INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ + do { \ + static VLC_TYPE table[static_size][2]; \ + (vlc)->table = table; \ + (vlc)->table_allocated = static_size; \ + ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ + INIT_VLC_USE_NEW_STATIC); \ + } while (0) + +#define INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ + do { \ + static VLC_TYPE table[static_size][2]; \ + (vlc)->table = table; \ + (vlc)->table_allocated = static_size; \ + ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ + INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); \ + } while (0) + +#define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ + INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) + +#define INIT_LE_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ + INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) + +#endif /* AVCODEC_VLC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis.c new file mode 100644 index 000000000..cca2aa7c6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis.c @@ -0,0 +1,218 @@ +/** + * @file + * Common code for Vorbis I encoder and decoder + * @author Denes Balatoni ( dbalatoni programozo hu ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Common code for Vorbis I encoder and decoder + * @author Denes Balatoni ( dbalatoni programozo hu ) + */ + +#include "libavutil/common.h" + +#include "avcodec.h" +#include "vorbis.h" + + +/* Helper functions */ + +// x^(1/n) +unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n) +{ + unsigned int ret = 0, i, j; + + do { + ++ret; + for (i = 0, j = ret; i < n - 1; i++) + j *= ret; + } while (j <= x); + + return ret - 1; +} + +// Generate vlc codes from vorbis huffman code lengths + +// the two bits[p] > 32 checks should be redundant, all calling code should +// already ensure that, but since it allows overwriting the stack it seems +// reasonable to check redundantly. +int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num) +{ + uint32_t exit_at_level[33] = { 404 }; + unsigned i, j, p, code; + + for (p = 0; (p < num) && (bits[p] == 0); ++p) + ; + if (p == num) + return 0; + + codes[p] = 0; + if (bits[p] > 32) + return AVERROR_INVALIDDATA; + for (i = 0; i < bits[p]; ++i) + exit_at_level[i+1] = 1u << i; + + ++p; + + for (i = p; (i < num) && (bits[i] == 0); ++i) + ; + if (i == num) + return 0; + + for (; p < num; ++p) { + if (bits[p] > 32) + return AVERROR_INVALIDDATA; + if (bits[p] == 0) + continue; + // find corresponding exit(node which the tree can grow further from) + for (i = bits[p]; i > 0; --i) + if (exit_at_level[i]) + break; + if (!i) // overspecified tree + return AVERROR_INVALIDDATA; + code = exit_at_level[i]; + exit_at_level[i] = 0; + // construct code (append 0s to end) and introduce new exits + for (j = i + 1 ;j <= bits[p]; ++j) + exit_at_level[j] = code + (1u << (j - 1)); + codes[p] = code; + } + + //no exits should be left (underspecified tree - ie. unused valid vlcs - not allowed by SPEC) + for (p = 1; p < 33; p++) + if (exit_at_level[p]) + return AVERROR_INVALIDDATA; + + return 0; +} + +int ff_vorbis_ready_floor1_list(AVCodecContext *avctx, + vorbis_floor1_entry *list, int values) +{ + int i; + list[0].sort = 0; + list[1].sort = 1; + for (i = 2; i < values; i++) { + int j; + list[i].low = 0; + list[i].high = 1; + list[i].sort = i; + for (j = 2; j < i; j++) { + int tmp = list[j].x; + if (tmp < list[i].x) { + if (tmp > list[list[i].low].x) + list[i].low = j; + } else { + if (tmp < list[list[i].high].x) + list[i].high = j; + } + } + } + for (i = 0; i < values - 1; i++) { + int j; + for (j = i + 1; j < values; j++) { + if (list[i].x == list[j].x) { + av_log(avctx, AV_LOG_ERROR, + "Duplicate value found in floor 1 X coordinates\n"); + return AVERROR_INVALIDDATA; + } + if (list[list[i].sort].x > list[list[j].sort].x) { + int tmp = list[i].sort; + list[i].sort = list[j].sort; + list[j].sort = tmp; + } + } + } + return 0; +} + +static inline void render_line_unrolled(intptr_t x, int y, int x1, + intptr_t sy, int ady, int adx, + float *buf) +{ + int err = -adx; + x -= x1 - 1; + buf += x1 - 1; + while (++x < 0) { + err += ady; + if (err >= 0) { + err += ady - adx; + y += sy; + buf[x++] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; + } + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; + } + if (x <= 0) { + if (err + ady >= 0) + y += sy; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; + } +} + +static void render_line(int x0, int y0, int x1, int y1, float *buf) +{ + int dy = y1 - y0; + int adx = x1 - x0; + int ady = FFABS(dy); + int sy = dy < 0 ? -1 : 1; + buf[x0] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y0)]; + if (ady*2 <= adx) { // optimized common case + render_line_unrolled(x0, y0, x1, sy, ady, adx, buf); + } else { + int base = dy / adx; + int x = x0; + int y = y0; + int err = -adx; + ady -= FFABS(base) * adx; + while (++x < x1) { + y += base; + err += ady; + if (err >= 0) { + err -= adx; + y += sy; + } + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; + } + } +} + +void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, + uint16_t *y_list, int *flag, + int multiplier, float *out, int samples) +{ + int lx, ly, i; + lx = 0; + ly = y_list[0] * multiplier; + for (i = 1; i < values; i++) { + int pos = list[i].sort; + if (flag[pos]) { + int x1 = list[pos].x; + int y1 = y_list[pos] * multiplier; + if (lx < samples) + render_line(lx, ly, FFMIN(x1,samples), y1, out); + lx = x1; + ly = y1; + } + if (lx >= samples) + break; + } + if (lx < samples) + render_line(lx, ly, samples, ly, out); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis.h new file mode 100644 index 000000000..98dd14f9d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis.h @@ -0,0 +1,50 @@ +/* + * copyright (c) 2006 Oded Shimon + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VORBIS_H +#define AVCODEC_VORBIS_H + +#include "avcodec.h" + +extern const float ff_vorbis_floor1_inverse_db_table[256]; +extern const float * const ff_vorbis_vwin[8]; +extern const uint8_t ff_vorbis_channel_layout_offsets[8][8]; +extern const uint8_t ff_vorbis_encoding_channel_layout_offsets[8][8]; +extern const uint64_t ff_vorbis_channel_layouts[9]; + +typedef struct vorbis_floor1_entry { + uint16_t x; + uint16_t sort; + uint16_t low; + uint16_t high; +} vorbis_floor1_entry; + +int ff_vorbis_ready_floor1_list(AVCodecContext *avctx, + vorbis_floor1_entry *list, int values); +unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n); // x^(1/n) +int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num); +void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, + uint16_t *y_list, int *flag, + int multiplier, float * out, int samples); +void ff_vorbis_inverse_coupling(float *mag, float *ang, intptr_t blocksize); + +#define ilog(i) av_log2(2*(i)) + +#endif /* AVCODEC_VORBIS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_data.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_data.c new file mode 100644 index 000000000..063a075ce --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_data.c @@ -0,0 +1,2193 @@ +/* + * copyright (c) 2005 Denes Balatoni ( dbalatoni programozo hu ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/channel_layout.h" +#include "libavutil/mem.h" +#include "vorbis.h" + +const uint8_t ff_vorbis_channel_layout_offsets[8][8] = { + { 0 }, + { 0, 1 }, + { 0, 2, 1 }, + { 0, 1, 2, 3 }, + { 0, 2, 1, 3, 4 }, + { 0, 2, 1, 5, 3, 4 }, + { 0, 2, 1, 6, 5, 3, 4 }, + { 0, 2, 1, 7, 5, 6, 3, 4 }, +}; + +const uint8_t ff_vorbis_encoding_channel_layout_offsets[8][8] = { + { 0 }, + { 0, 1 }, + { 0, 2, 1 }, + { 0, 1, 2, 3 }, + { 0, 2, 1, 3, 4 }, + { 0, 2, 1, 4, 5, 3 }, + { 0, 2, 1, 5, 6, 4, 3 }, + { 0, 2, 1, 6, 7, 4, 5, 3 }, +}; + +const uint64_t ff_vorbis_channel_layouts[9] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_QUAD, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER, + AV_CH_LAYOUT_7POINT1, + 0 +}; + +DECLARE_ALIGNED(16, static const float, vwin64)[32] = { + 0.0009460463F, 0.0085006468F, 0.0235352254F, 0.0458950567F, + 0.0753351908F, 0.1115073077F, 0.1539457973F, 0.2020557475F, + 0.2551056759F, 0.3122276645F, 0.3724270287F, 0.4346027792F, + 0.4975789974F, 0.5601459521F, 0.6211085051F, 0.6793382689F, + 0.7338252629F, 0.7837245849F, 0.8283939355F, 0.8674186656F, + 0.9006222429F, 0.9280614787F, 0.9500073081F, 0.9669131782F, + 0.9793740220F, 0.9880792941F, 0.9937636139F, 0.9971582668F, + 0.9989462667F, 0.9997230082F, 0.9999638688F, 0.9999995525F, +}; + +DECLARE_ALIGNED(16, static const float, vwin128)[64] = { + 0.0002365472F, 0.0021280687F, 0.0059065254F, 0.0115626550F, + 0.0190823442F, 0.0284463735F, 0.0396300935F, 0.0526030430F, + 0.0673285281F, 0.0837631763F, 0.1018564887F, 0.1215504095F, + 0.1427789367F, 0.1654677960F, 0.1895342001F, 0.2148867160F, + 0.2414252576F, 0.2690412240F, 0.2976177952F, 0.3270303960F, + 0.3571473350F, 0.3878306189F, 0.4189369387F, 0.4503188188F, + 0.4818259135F, 0.5133064334F, 0.5446086751F, 0.5755826278F, + 0.6060816248F, 0.6359640047F, 0.6650947483F, 0.6933470543F, + 0.7206038179F, 0.7467589810F, 0.7717187213F, 0.7954024542F, + 0.8177436264F, 0.8386902831F, 0.8582053981F, 0.8762669622F, + 0.8928678298F, 0.9080153310F, 0.9217306608F, 0.9340480615F, + 0.9450138200F, 0.9546851041F, 0.9631286621F, 0.9704194171F, + 0.9766389810F, 0.9818741197F, 0.9862151938F, 0.9897546035F, + 0.9925852598F, 0.9947991032F, 0.9964856900F, 0.9977308602F, + 0.9986155015F, 0.9992144193F, 0.9995953200F, 0.9998179155F, + 0.9999331503F, 0.9999825563F, 0.9999977357F, 0.9999999720F, +}; + +DECLARE_ALIGNED(16, static const float, vwin256)[128] = { + 0.0000591390F, 0.0005321979F, 0.0014780301F, 0.0028960636F, + 0.0047854363F, 0.0071449926F, 0.0099732775F, 0.0132685298F, + 0.0170286741F, 0.0212513119F, 0.0259337111F, 0.0310727950F, + 0.0366651302F, 0.0427069140F, 0.0491939614F, 0.0561216907F, + 0.0634851102F, 0.0712788035F, 0.0794969160F, 0.0881331402F, + 0.0971807028F, 0.1066323515F, 0.1164803426F, 0.1267164297F, + 0.1373318534F, 0.1483173323F, 0.1596630553F, 0.1713586755F, + 0.1833933062F, 0.1957555184F, 0.2084333404F, 0.2214142599F, + 0.2346852280F, 0.2482326664F, 0.2620424757F, 0.2761000481F, + 0.2903902813F, 0.3048975959F, 0.3196059553F, 0.3344988887F, + 0.3495595160F, 0.3647705766F, 0.3801144597F, 0.3955732382F, + 0.4111287047F, 0.4267624093F, 0.4424557009F, 0.4581897696F, + 0.4739456913F, 0.4897044744F, 0.5054471075F, 0.5211546088F, + 0.5368080763F, 0.5523887395F, 0.5678780103F, 0.5832575361F, + 0.5985092508F, 0.6136154277F, 0.6285587300F, 0.6433222619F, + 0.6578896175F, 0.6722449294F, 0.6863729144F, 0.7002589187F, + 0.7138889597F, 0.7272497662F, 0.7403288154F, 0.7531143679F, + 0.7655954985F, 0.7777621249F, 0.7896050322F, 0.8011158947F, + 0.8122872932F, 0.8231127294F, 0.8335866365F, 0.8437043850F, + 0.8534622861F, 0.8628575905F, 0.8718884835F, 0.8805540765F, + 0.8888543947F, 0.8967903616F, 0.9043637797F, 0.9115773078F, + 0.9184344360F, 0.9249394562F, 0.9310974312F, 0.9369141608F, + 0.9423961446F, 0.9475505439F, 0.9523851406F, 0.9569082947F, + 0.9611289005F, 0.9650563408F, 0.9687004405F, 0.9720714191F, + 0.9751798427F, 0.9780365753F, 0.9806527301F, 0.9830396204F, + 0.9852087111F, 0.9871715701F, 0.9889398207F, 0.9905250941F, + 0.9919389832F, 0.9931929973F, 0.9942985174F, 0.9952667537F, + 0.9961087037F, 0.9968351119F, 0.9974564312F, 0.9979827858F, + 0.9984239359F, 0.9987892441F, 0.9990876435F, 0.9993276081F, + 0.9995171241F, 0.9996636648F, 0.9997741654F, 0.9998550016F, + 0.9999119692F, 0.9999502656F, 0.9999744742F, 0.9999885497F, + 0.9999958064F, 0.9999989077F, 0.9999998584F, 0.9999999983F, +}; + +DECLARE_ALIGNED(16, static const float, vwin512)[256] = { + 0.0000147849F, 0.0001330607F, 0.0003695946F, 0.0007243509F, + 0.0011972759F, 0.0017882983F, 0.0024973285F, 0.0033242588F, + 0.0042689632F, 0.0053312973F, 0.0065110982F, 0.0078081841F, + 0.0092223540F, 0.0107533880F, 0.0124010466F, 0.0141650703F, + 0.0160451800F, 0.0180410758F, 0.0201524373F, 0.0223789233F, + 0.0247201710F, 0.0271757958F, 0.0297453914F, 0.0324285286F, + 0.0352247556F, 0.0381335972F, 0.0411545545F, 0.0442871045F, + 0.0475306997F, 0.0508847676F, 0.0543487103F, 0.0579219038F, + 0.0616036982F, 0.0653934164F, 0.0692903546F, 0.0732937809F, + 0.0774029356F, 0.0816170305F, 0.0859352485F, 0.0903567428F, + 0.0948806375F, 0.0995060259F, 0.1042319712F, 0.1090575056F, + 0.1139816300F, 0.1190033137F, 0.1241214941F, 0.1293350764F, + 0.1346429333F, 0.1400439046F, 0.1455367974F, 0.1511203852F, + 0.1567934083F, 0.1625545735F, 0.1684025537F, 0.1743359881F, + 0.1803534820F, 0.1864536069F, 0.1926349000F, 0.1988958650F, + 0.2052349715F, 0.2116506555F, 0.2181413191F, 0.2247053313F, + 0.2313410275F, 0.2380467105F, 0.2448206500F, 0.2516610835F, + 0.2585662164F, 0.2655342226F, 0.2725632448F, 0.2796513950F, + 0.2867967551F, 0.2939973773F, 0.3012512852F, 0.3085564739F, + 0.3159109111F, 0.3233125375F, 0.3307592680F, 0.3382489922F, + 0.3457795756F, 0.3533488602F, 0.3609546657F, 0.3685947904F, + 0.3762670121F, 0.3839690896F, 0.3916987634F, 0.3994537572F, + 0.4072317788F, 0.4150305215F, 0.4228476653F, 0.4306808783F, + 0.4385278181F, 0.4463861329F, 0.4542534630F, 0.4621274424F, + 0.4700057001F, 0.4778858615F, 0.4857655502F, 0.4936423891F, + 0.5015140023F, 0.5093780165F, 0.5172320626F, 0.5250737772F, + 0.5329008043F, 0.5407107971F, 0.5485014192F, 0.5562703465F, + 0.5640152688F, 0.5717338914F, 0.5794239366F, 0.5870831457F, + 0.5947092801F, 0.6023001235F, 0.6098534829F, 0.6173671907F, + 0.6248391059F, 0.6322671161F, 0.6396491384F, 0.6469831217F, + 0.6542670475F, 0.6614989319F, 0.6686768267F, 0.6757988210F, + 0.6828630426F, 0.6898676592F, 0.6968108799F, 0.7036909564F, + 0.7105061843F, 0.7172549043F, 0.7239355032F, 0.7305464154F, + 0.7370861235F, 0.7435531598F, 0.7499461068F, 0.7562635986F, + 0.7625043214F, 0.7686670148F, 0.7747504721F, 0.7807535410F, + 0.7866751247F, 0.7925141825F, 0.7982697296F, 0.8039408387F, + 0.8095266395F, 0.8150263196F, 0.8204391248F, 0.8257643590F, + 0.8310013848F, 0.8361496236F, 0.8412085555F, 0.8461777194F, + 0.8510567129F, 0.8558451924F, 0.8605428730F, 0.8651495278F, + 0.8696649882F, 0.8740891432F, 0.8784219392F, 0.8826633797F, + 0.8868135244F, 0.8908724888F, 0.8948404441F, 0.8987176157F, + 0.9025042831F, 0.9062007791F, 0.9098074886F, 0.9133248482F, + 0.9167533451F, 0.9200935163F, 0.9233459472F, 0.9265112712F, + 0.9295901680F, 0.9325833632F, 0.9354916263F, 0.9383157705F, + 0.9410566504F, 0.9437151618F, 0.9462922398F, 0.9487888576F, + 0.9512060252F, 0.9535447882F, 0.9558062262F, 0.9579914516F, + 0.9601016078F, 0.9621378683F, 0.9641014348F, 0.9659935361F, + 0.9678154261F, 0.9695683830F, 0.9712537071F, 0.9728727198F, + 0.9744267618F, 0.9759171916F, 0.9773453842F, 0.9787127293F, + 0.9800206298F, 0.9812705006F, 0.9824637665F, 0.9836018613F, + 0.9846862258F, 0.9857183066F, 0.9866995544F, 0.9876314227F, + 0.9885153662F, 0.9893528393F, 0.9901452948F, 0.9908941823F, + 0.9916009470F, 0.9922670279F, 0.9928938570F, 0.9934828574F, + 0.9940354423F, 0.9945530133F, 0.9950369595F, 0.9954886562F, + 0.9959094633F, 0.9963007242F, 0.9966637649F, 0.9969998925F, + 0.9973103939F, 0.9975965351F, 0.9978595598F, 0.9981006885F, + 0.9983211172F, 0.9985220166F, 0.9987045311F, 0.9988697776F, + 0.9990188449F, 0.9991527924F, 0.9992726499F, 0.9993794157F, + 0.9994740570F, 0.9995575079F, 0.9996306699F, 0.9996944099F, + 0.9997495605F, 0.9997969190F, 0.9998372465F, 0.9998712678F, + 0.9998996704F, 0.9999231041F, 0.9999421807F, 0.9999574732F, + 0.9999695157F, 0.9999788026F, 0.9999857885F, 0.9999908879F, + 0.9999944746F, 0.9999968817F, 0.9999984010F, 0.9999992833F, + 0.9999997377F, 0.9999999317F, 0.9999999911F, 0.9999999999F, +}; + +DECLARE_ALIGNED(16, static const float, vwin1024)[512] = { + 0.0000036962F, 0.0000332659F, 0.0000924041F, 0.0001811086F, + 0.0002993761F, 0.0004472021F, 0.0006245811F, 0.0008315063F, + 0.0010679699F, 0.0013339631F, 0.0016294757F, 0.0019544965F, + 0.0023090133F, 0.0026930125F, 0.0031064797F, 0.0035493989F, + 0.0040217533F, 0.0045235250F, 0.0050546946F, 0.0056152418F, + 0.0062051451F, 0.0068243817F, 0.0074729278F, 0.0081507582F, + 0.0088578466F, 0.0095941655F, 0.0103596863F, 0.0111543789F, + 0.0119782122F, 0.0128311538F, 0.0137131701F, 0.0146242260F, + 0.0155642855F, 0.0165333111F, 0.0175312640F, 0.0185581042F, + 0.0196137903F, 0.0206982797F, 0.0218115284F, 0.0229534910F, + 0.0241241208F, 0.0253233698F, 0.0265511886F, 0.0278075263F, + 0.0290923308F, 0.0304055484F, 0.0317471241F, 0.0331170013F, + 0.0345151222F, 0.0359414274F, 0.0373958560F, 0.0388783456F, + 0.0403888325F, 0.0419272511F, 0.0434935347F, 0.0450876148F, + 0.0467094213F, 0.0483588828F, 0.0500359261F, 0.0517404765F, + 0.0534724575F, 0.0552317913F, 0.0570183983F, 0.0588321971F, + 0.0606731048F, 0.0625410369F, 0.0644359070F, 0.0663576272F, + 0.0683061077F, 0.0702812571F, 0.0722829821F, 0.0743111878F, + 0.0763657775F, 0.0784466526F, 0.0805537129F, 0.0826868561F, + 0.0848459782F, 0.0870309736F, 0.0892417345F, 0.0914781514F, + 0.0937401128F, 0.0960275056F, 0.0983402145F, 0.1006781223F, + 0.1030411101F, 0.1054290568F, 0.1078418397F, 0.1102793336F, + 0.1127414119F, 0.1152279457F, 0.1177388042F, 0.1202738544F, + 0.1228329618F, 0.1254159892F, 0.1280227980F, 0.1306532471F, + 0.1333071937F, 0.1359844927F, 0.1386849970F, 0.1414085575F, + 0.1441550230F, 0.1469242403F, 0.1497160539F, 0.1525303063F, + 0.1553668381F, 0.1582254875F, 0.1611060909F, 0.1640084822F, + 0.1669324936F, 0.1698779549F, 0.1728446939F, 0.1758325362F, + 0.1788413055F, 0.1818708232F, 0.1849209084F, 0.1879913785F, + 0.1910820485F, 0.1941927312F, 0.1973232376F, 0.2004733764F, + 0.2036429541F, 0.2068317752F, 0.2100396421F, 0.2132663552F, + 0.2165117125F, 0.2197755102F, 0.2230575422F, 0.2263576007F, + 0.2296754753F, 0.2330109540F, 0.2363638225F, 0.2397338646F, + 0.2431208619F, 0.2465245941F, 0.2499448389F, 0.2533813719F, + 0.2568339669F, 0.2603023956F, 0.2637864277F, 0.2672858312F, + 0.2708003718F, 0.2743298135F, 0.2778739186F, 0.2814324472F, + 0.2850051576F, 0.2885918065F, 0.2921921485F, 0.2958059366F, + 0.2994329219F, 0.3030728538F, 0.3067254799F, 0.3103905462F, + 0.3140677969F, 0.3177569747F, 0.3214578205F, 0.3251700736F, + 0.3288934718F, 0.3326277513F, 0.3363726468F, 0.3401278914F, + 0.3438932168F, 0.3476683533F, 0.3514530297F, 0.3552469734F, + 0.3590499106F, 0.3628615659F, 0.3666816630F, 0.3705099239F, + 0.3743460698F, 0.3781898204F, 0.3820408945F, 0.3858990095F, + 0.3897638820F, 0.3936352274F, 0.3975127601F, 0.4013961936F, + 0.4052852405F, 0.4091796123F, 0.4130790198F, 0.4169831732F, + 0.4208917815F, 0.4248045534F, 0.4287211965F, 0.4326414181F, + 0.4365649248F, 0.4404914225F, 0.4444206167F, 0.4483522125F, + 0.4522859146F, 0.4562214270F, 0.4601584538F, 0.4640966984F, + 0.4680358644F, 0.4719756548F, 0.4759157726F, 0.4798559209F, + 0.4837958024F, 0.4877351199F, 0.4916735765F, 0.4956108751F, + 0.4995467188F, 0.5034808109F, 0.5074128550F, 0.5113425550F, + 0.5152696149F, 0.5191937395F, 0.5231146336F, 0.5270320028F, + 0.5309455530F, 0.5348549910F, 0.5387600239F, 0.5426603597F, + 0.5465557070F, 0.5504457754F, 0.5543302752F, 0.5582089175F, + 0.5620814145F, 0.5659474793F, 0.5698068262F, 0.5736591704F, + 0.5775042283F, 0.5813417176F, 0.5851713571F, 0.5889928670F, + 0.5928059689F, 0.5966103856F, 0.6004058415F, 0.6041920626F, + 0.6079687761F, 0.6117357113F, 0.6154925986F, 0.6192391705F, + 0.6229751612F, 0.6267003064F, 0.6304143441F, 0.6341170137F, + 0.6378080569F, 0.6414872173F, 0.6451542405F, 0.6488088741F, + 0.6524508681F, 0.6560799742F, 0.6596959469F, 0.6632985424F, + 0.6668875197F, 0.6704626398F, 0.6740236662F, 0.6775703649F, + 0.6811025043F, 0.6846198554F, 0.6881221916F, 0.6916092892F, + 0.6950809269F, 0.6985368861F, 0.7019769510F, 0.7054009085F, + 0.7088085484F, 0.7121996632F, 0.7155740484F, 0.7189315023F, + 0.7222718263F, 0.7255948245F, 0.7289003043F, 0.7321880760F, + 0.7354579530F, 0.7387097518F, 0.7419432921F, 0.7451583966F, + 0.7483548915F, 0.7515326059F, 0.7546913723F, 0.7578310265F, + 0.7609514077F, 0.7640523581F, 0.7671337237F, 0.7701953535F, + 0.7732371001F, 0.7762588195F, 0.7792603711F, 0.7822416178F, + 0.7852024259F, 0.7881426654F, 0.7910622097F, 0.7939609356F, + 0.7968387237F, 0.7996954579F, 0.8025310261F, 0.8053453193F, + 0.8081382324F, 0.8109096638F, 0.8136595156F, 0.8163876936F, + 0.8190941071F, 0.8217786690F, 0.8244412960F, 0.8270819086F, + 0.8297004305F, 0.8322967896F, 0.8348709171F, 0.8374227481F, + 0.8399522213F, 0.8424592789F, 0.8449438672F, 0.8474059356F, + 0.8498454378F, 0.8522623306F, 0.8546565748F, 0.8570281348F, + 0.8593769787F, 0.8617030779F, 0.8640064080F, 0.8662869477F, + 0.8685446796F, 0.8707795899F, 0.8729916682F, 0.8751809079F, + 0.8773473059F, 0.8794908626F, 0.8816115819F, 0.8837094713F, + 0.8857845418F, 0.8878368079F, 0.8898662874F, 0.8918730019F, + 0.8938569760F, 0.8958182380F, 0.8977568194F, 0.8996727552F, + 0.9015660837F, 0.9034368465F, 0.9052850885F, 0.9071108577F, + 0.9089142057F, 0.9106951869F, 0.9124538591F, 0.9141902832F, + 0.9159045233F, 0.9175966464F, 0.9192667228F, 0.9209148257F, + 0.9225410313F, 0.9241454187F, 0.9257280701F, 0.9272890704F, + 0.9288285075F, 0.9303464720F, 0.9318430576F, 0.9333183603F, + 0.9347724792F, 0.9362055158F, 0.9376175745F, 0.9390087622F, + 0.9403791881F, 0.9417289644F, 0.9430582055F, 0.9443670283F, + 0.9456555521F, 0.9469238986F, 0.9481721917F, 0.9494005577F, + 0.9506091252F, 0.9517980248F, 0.9529673894F, 0.9541173540F, + 0.9552480557F, 0.9563596334F, 0.9574522282F, 0.9585259830F, + 0.9595810428F, 0.9606175542F, 0.9616356656F, 0.9626355274F, + 0.9636172915F, 0.9645811114F, 0.9655271425F, 0.9664555414F, + 0.9673664664F, 0.9682600774F, 0.9691365355F, 0.9699960034F, + 0.9708386448F, 0.9716646250F, 0.9724741103F, 0.9732672685F, + 0.9740442683F, 0.9748052795F, 0.9755504729F, 0.9762800205F, + 0.9769940950F, 0.9776928703F, 0.9783765210F, 0.9790452223F, + 0.9796991504F, 0.9803384823F, 0.9809633954F, 0.9815740679F, + 0.9821706784F, 0.9827534063F, 0.9833224312F, 0.9838779332F, + 0.9844200928F, 0.9849490910F, 0.9854651087F, 0.9859683274F, + 0.9864589286F, 0.9869370940F, 0.9874030054F, 0.9878568447F, + 0.9882987937F, 0.9887290343F, 0.9891477481F, 0.9895551169F, + 0.9899513220F, 0.9903365446F, 0.9907109658F, 0.9910747662F, + 0.9914281260F, 0.9917712252F, 0.9921042433F, 0.9924273593F, + 0.9927407516F, 0.9930445982F, 0.9933390763F, 0.9936243626F, + 0.9939006331F, 0.9941680631F, 0.9944268269F, 0.9946770982F, + 0.9949190498F, 0.9951528537F, 0.9953786808F, 0.9955967011F, + 0.9958070836F, 0.9960099963F, 0.9962056061F, 0.9963940787F, + 0.9965755786F, 0.9967502693F, 0.9969183129F, 0.9970798704F, + 0.9972351013F, 0.9973841640F, 0.9975272151F, 0.9976644103F, + 0.9977959036F, 0.9979218476F, 0.9980423932F, 0.9981576901F, + 0.9982678862F, 0.9983731278F, 0.9984735596F, 0.9985693247F, + 0.9986605645F, 0.9987474186F, 0.9988300248F, 0.9989085193F, + 0.9989830364F, 0.9990537085F, 0.9991206662F, 0.9991840382F, + 0.9992439513F, 0.9993005303F, 0.9993538982F, 0.9994041757F, + 0.9994514817F, 0.9994959330F, 0.9995376444F, 0.9995767286F, + 0.9996132960F, 0.9996474550F, 0.9996793121F, 0.9997089710F, + 0.9997365339F, 0.9997621003F, 0.9997857677F, 0.9998076311F, + 0.9998277836F, 0.9998463156F, 0.9998633155F, 0.9998788692F, + 0.9998930603F, 0.9999059701F, 0.9999176774F, 0.9999282586F, + 0.9999377880F, 0.9999463370F, 0.9999539749F, 0.9999607685F, + 0.9999667820F, 0.9999720773F, 0.9999767136F, 0.9999807479F, + 0.9999842344F, 0.9999872249F, 0.9999897688F, 0.9999919127F, + 0.9999937009F, 0.9999951749F, 0.9999963738F, 0.9999973342F, + 0.9999980900F, 0.9999986724F, 0.9999991103F, 0.9999994297F, + 0.9999996543F, 0.9999998049F, 0.9999999000F, 0.9999999552F, + 0.9999999836F, 0.9999999957F, 0.9999999994F, 1.0000000000F, +}; + +DECLARE_ALIGNED(16, static const float, vwin2048)[1024] = { + 0.0000009241F, 0.0000083165F, 0.0000231014F, 0.0000452785F, + 0.0000748476F, 0.0001118085F, 0.0001561608F, 0.0002079041F, + 0.0002670379F, 0.0003335617F, 0.0004074748F, 0.0004887765F, + 0.0005774661F, 0.0006735427F, 0.0007770054F, 0.0008878533F, + 0.0010060853F, 0.0011317002F, 0.0012646969F, 0.0014050742F, + 0.0015528307F, 0.0017079650F, 0.0018704756F, 0.0020403610F, + 0.0022176196F, 0.0024022497F, 0.0025942495F, 0.0027936173F, + 0.0030003511F, 0.0032144490F, 0.0034359088F, 0.0036647286F, + 0.0039009061F, 0.0041444391F, 0.0043953253F, 0.0046535621F, + 0.0049191472F, 0.0051920781F, 0.0054723520F, 0.0057599664F, + 0.0060549184F, 0.0063572052F, 0.0066668239F, 0.0069837715F, + 0.0073080449F, 0.0076396410F, 0.0079785566F, 0.0083247884F, + 0.0086783330F, 0.0090391871F, 0.0094073470F, 0.0097828092F, + 0.0101655700F, 0.0105556258F, 0.0109529726F, 0.0113576065F, + 0.0117695237F, 0.0121887200F, 0.0126151913F, 0.0130489335F, + 0.0134899422F, 0.0139382130F, 0.0143937415F, 0.0148565233F, + 0.0153265536F, 0.0158038279F, 0.0162883413F, 0.0167800889F, + 0.0172790660F, 0.0177852675F, 0.0182986882F, 0.0188193231F, + 0.0193471668F, 0.0198822141F, 0.0204244594F, 0.0209738974F, + 0.0215305225F, 0.0220943289F, 0.0226653109F, 0.0232434627F, + 0.0238287784F, 0.0244212519F, 0.0250208772F, 0.0256276481F, + 0.0262415582F, 0.0268626014F, 0.0274907711F, 0.0281260608F, + 0.0287684638F, 0.0294179736F, 0.0300745833F, 0.0307382859F, + 0.0314090747F, 0.0320869424F, 0.0327718819F, 0.0334638860F, + 0.0341629474F, 0.0348690586F, 0.0355822122F, 0.0363024004F, + 0.0370296157F, 0.0377638502F, 0.0385050960F, 0.0392533451F, + 0.0400085896F, 0.0407708211F, 0.0415400315F, 0.0423162123F, + 0.0430993552F, 0.0438894515F, 0.0446864926F, 0.0454904698F, + 0.0463013742F, 0.0471191969F, 0.0479439288F, 0.0487755607F, + 0.0496140836F, 0.0504594879F, 0.0513117642F, 0.0521709031F, + 0.0530368949F, 0.0539097297F, 0.0547893979F, 0.0556758894F, + 0.0565691941F, 0.0574693019F, 0.0583762026F, 0.0592898858F, + 0.0602103410F, 0.0611375576F, 0.0620715250F, 0.0630122324F, + 0.0639596688F, 0.0649138234F, 0.0658746848F, 0.0668422421F, + 0.0678164838F, 0.0687973985F, 0.0697849746F, 0.0707792005F, + 0.0717800645F, 0.0727875547F, 0.0738016591F, 0.0748223656F, + 0.0758496620F, 0.0768835359F, 0.0779239751F, 0.0789709668F, + 0.0800244985F, 0.0810845574F, 0.0821511306F, 0.0832242052F, + 0.0843037679F, 0.0853898056F, 0.0864823050F, 0.0875812525F, + 0.0886866347F, 0.0897984378F, 0.0909166480F, 0.0920412513F, + 0.0931722338F, 0.0943095813F, 0.0954532795F, 0.0966033140F, + 0.0977596702F, 0.0989223336F, 0.1000912894F, 0.1012665227F, + 0.1024480185F, 0.1036357616F, 0.1048297369F, 0.1060299290F, + 0.1072363224F, 0.1084489014F, 0.1096676504F, 0.1108925534F, + 0.1121235946F, 0.1133607577F, 0.1146040267F, 0.1158533850F, + 0.1171088163F, 0.1183703040F, 0.1196378312F, 0.1209113812F, + 0.1221909370F, 0.1234764815F, 0.1247679974F, 0.1260654674F, + 0.1273688740F, 0.1286781995F, 0.1299934263F, 0.1313145365F, + 0.1326415121F, 0.1339743349F, 0.1353129866F, 0.1366574490F, + 0.1380077035F, 0.1393637315F, 0.1407255141F, 0.1420930325F, + 0.1434662677F, 0.1448452004F, 0.1462298115F, 0.1476200814F, + 0.1490159906F, 0.1504175195F, 0.1518246482F, 0.1532373569F, + 0.1546556253F, 0.1560794333F, 0.1575087606F, 0.1589435866F, + 0.1603838909F, 0.1618296526F, 0.1632808509F, 0.1647374648F, + 0.1661994731F, 0.1676668546F, 0.1691395880F, 0.1706176516F, + 0.1721010238F, 0.1735896829F, 0.1750836068F, 0.1765827736F, + 0.1780871610F, 0.1795967468F, 0.1811115084F, 0.1826314234F, + 0.1841564689F, 0.1856866221F, 0.1872218600F, 0.1887621595F, + 0.1903074974F, 0.1918578503F, 0.1934131947F, 0.1949735068F, + 0.1965387630F, 0.1981089393F, 0.1996840117F, 0.2012639560F, + 0.2028487479F, 0.2044383630F, 0.2060327766F, 0.2076319642F, + 0.2092359007F, 0.2108445614F, 0.2124579211F, 0.2140759545F, + 0.2156986364F, 0.2173259411F, 0.2189578432F, 0.2205943168F, + 0.2222353361F, 0.2238808751F, 0.2255309076F, 0.2271854073F, + 0.2288443480F, 0.2305077030F, 0.2321754457F, 0.2338475493F, + 0.2355239869F, 0.2372047315F, 0.2388897560F, 0.2405790329F, + 0.2422725350F, 0.2439702347F, 0.2456721043F, 0.2473781159F, + 0.2490882418F, 0.2508024539F, 0.2525207240F, 0.2542430237F, + 0.2559693248F, 0.2576995986F, 0.2594338166F, 0.2611719498F, + 0.2629139695F, 0.2646598466F, 0.2664095520F, 0.2681630564F, + 0.2699203304F, 0.2716813445F, 0.2734460691F, 0.2752144744F, + 0.2769865307F, 0.2787622079F, 0.2805414760F, 0.2823243047F, + 0.2841106637F, 0.2859005227F, 0.2876938509F, 0.2894906179F, + 0.2912907928F, 0.2930943447F, 0.2949012426F, 0.2967114554F, + 0.2985249520F, 0.3003417009F, 0.3021616708F, 0.3039848301F, + 0.3058111471F, 0.3076405901F, 0.3094731273F, 0.3113087266F, + 0.3131473560F, 0.3149889833F, 0.3168335762F, 0.3186811024F, + 0.3205315294F, 0.3223848245F, 0.3242409552F, 0.3260998886F, + 0.3279615918F, 0.3298260319F, 0.3316931758F, 0.3335629903F, + 0.3354354423F, 0.3373104982F, 0.3391881247F, 0.3410682882F, + 0.3429509551F, 0.3448360917F, 0.3467236642F, 0.3486136387F, + 0.3505059811F, 0.3524006575F, 0.3542976336F, 0.3561968753F, + 0.3580983482F, 0.3600020179F, 0.3619078499F, 0.3638158096F, + 0.3657258625F, 0.3676379737F, 0.3695521086F, 0.3714682321F, + 0.3733863094F, 0.3753063055F, 0.3772281852F, 0.3791519134F, + 0.3810774548F, 0.3830047742F, 0.3849338362F, 0.3868646053F, + 0.3887970459F, 0.3907311227F, 0.3926667998F, 0.3946040417F, + 0.3965428125F, 0.3984830765F, 0.4004247978F, 0.4023679403F, + 0.4043124683F, 0.4062583455F, 0.4082055359F, 0.4101540034F, + 0.4121037117F, 0.4140546246F, 0.4160067058F, 0.4179599190F, + 0.4199142277F, 0.4218695956F, 0.4238259861F, 0.4257833627F, + 0.4277416888F, 0.4297009279F, 0.4316610433F, 0.4336219983F, + 0.4355837562F, 0.4375462803F, 0.4395095337F, 0.4414734797F, + 0.4434380815F, 0.4454033021F, 0.4473691046F, 0.4493354521F, + 0.4513023078F, 0.4532696345F, 0.4552373954F, 0.4572055533F, + 0.4591740713F, 0.4611429123F, 0.4631120393F, 0.4650814151F, + 0.4670510028F, 0.4690207650F, 0.4709906649F, 0.4729606651F, + 0.4749307287F, 0.4769008185F, 0.4788708972F, 0.4808409279F, + 0.4828108732F, 0.4847806962F, 0.4867503597F, 0.4887198264F, + 0.4906890593F, 0.4926580213F, 0.4946266753F, 0.4965949840F, + 0.4985629105F, 0.5005304176F, 0.5024974683F, 0.5044640255F, + 0.5064300522F, 0.5083955114F, 0.5103603659F, 0.5123245790F, + 0.5142881136F, 0.5162509328F, 0.5182129997F, 0.5201742774F, + 0.5221347290F, 0.5240943178F, 0.5260530070F, 0.5280107598F, + 0.5299675395F, 0.5319233095F, 0.5338780330F, 0.5358316736F, + 0.5377841946F, 0.5397355596F, 0.5416857320F, 0.5436346755F, + 0.5455823538F, 0.5475287304F, 0.5494737691F, 0.5514174337F, + 0.5533596881F, 0.5553004962F, 0.5572398218F, 0.5591776291F, + 0.5611138821F, 0.5630485449F, 0.5649815818F, 0.5669129570F, + 0.5688426349F, 0.5707705799F, 0.5726967564F, 0.5746211290F, + 0.5765436624F, 0.5784643212F, 0.5803830702F, 0.5822998743F, + 0.5842146984F, 0.5861275076F, 0.5880382669F, 0.5899469416F, + 0.5918534968F, 0.5937578981F, 0.5956601107F, 0.5975601004F, + 0.5994578326F, 0.6013532732F, 0.6032463880F, 0.6051371429F, + 0.6070255039F, 0.6089114372F, 0.6107949090F, 0.6126758856F, + 0.6145543334F, 0.6164302191F, 0.6183035092F, 0.6201741706F, + 0.6220421700F, 0.6239074745F, 0.6257700513F, 0.6276298674F, + 0.6294868903F, 0.6313410873F, 0.6331924262F, 0.6350408745F, + 0.6368864001F, 0.6387289710F, 0.6405685552F, 0.6424051209F, + 0.6442386364F, 0.6460690702F, 0.6478963910F, 0.6497205673F, + 0.6515415682F, 0.6533593625F, 0.6551739194F, 0.6569852082F, + 0.6587931984F, 0.6605978593F, 0.6623991609F, 0.6641970728F, + 0.6659915652F, 0.6677826081F, 0.6695701718F, 0.6713542268F, + 0.6731347437F, 0.6749116932F, 0.6766850461F, 0.6784547736F, + 0.6802208469F, 0.6819832374F, 0.6837419164F, 0.6854968559F, + 0.6872480275F, 0.6889954034F, 0.6907389556F, 0.6924786566F, + 0.6942144788F, 0.6959463950F, 0.6976743780F, 0.6993984008F, + 0.7011184365F, 0.7028344587F, 0.7045464407F, 0.7062543564F, + 0.7079581796F, 0.7096578844F, 0.7113534450F, 0.7130448359F, + 0.7147320316F, 0.7164150070F, 0.7180937371F, 0.7197681970F, + 0.7214383620F, 0.7231042077F, 0.7247657098F, 0.7264228443F, + 0.7280755871F, 0.7297239147F, 0.7313678035F, 0.7330072301F, + 0.7346421715F, 0.7362726046F, 0.7378985069F, 0.7395198556F, + 0.7411366285F, 0.7427488034F, 0.7443563584F, 0.7459592717F, + 0.7475575218F, 0.7491510873F, 0.7507399471F, 0.7523240803F, + 0.7539034661F, 0.7554780839F, 0.7570479136F, 0.7586129349F, + 0.7601731279F, 0.7617284730F, 0.7632789506F, 0.7648245416F, + 0.7663652267F, 0.7679009872F, 0.7694318044F, 0.7709576599F, + 0.7724785354F, 0.7739944130F, 0.7755052749F, 0.7770111035F, + 0.7785118815F, 0.7800075916F, 0.7814982170F, 0.7829837410F, + 0.7844641472F, 0.7859394191F, 0.7874095408F, 0.7888744965F, + 0.7903342706F, 0.7917888476F, 0.7932382124F, 0.7946823501F, + 0.7961212460F, 0.7975548855F, 0.7989832544F, 0.8004063386F, + 0.8018241244F, 0.8032365981F, 0.8046437463F, 0.8060455560F, + 0.8074420141F, 0.8088331080F, 0.8102188253F, 0.8115991536F, + 0.8129740810F, 0.8143435957F, 0.8157076861F, 0.8170663409F, + 0.8184195489F, 0.8197672994F, 0.8211095817F, 0.8224463853F, + 0.8237777001F, 0.8251035161F, 0.8264238235F, 0.8277386129F, + 0.8290478750F, 0.8303516008F, 0.8316497814F, 0.8329424083F, + 0.8342294731F, 0.8355109677F, 0.8367868841F, 0.8380572148F, + 0.8393219523F, 0.8405810893F, 0.8418346190F, 0.8430825345F, + 0.8443248294F, 0.8455614974F, 0.8467925323F, 0.8480179285F, + 0.8492376802F, 0.8504517822F, 0.8516602292F, 0.8528630164F, + 0.8540601391F, 0.8552515928F, 0.8564373733F, 0.8576174766F, + 0.8587918990F, 0.8599606368F, 0.8611236868F, 0.8622810460F, + 0.8634327113F, 0.8645786802F, 0.8657189504F, 0.8668535195F, + 0.8679823857F, 0.8691055472F, 0.8702230025F, 0.8713347503F, + 0.8724407896F, 0.8735411194F, 0.8746357394F, 0.8757246489F, + 0.8768078479F, 0.8778853364F, 0.8789571146F, 0.8800231832F, + 0.8810835427F, 0.8821381942F, 0.8831871387F, 0.8842303777F, + 0.8852679127F, 0.8862997456F, 0.8873258784F, 0.8883463132F, + 0.8893610527F, 0.8903700994F, 0.8913734562F, 0.8923711263F, + 0.8933631129F, 0.8943494196F, 0.8953300500F, 0.8963050083F, + 0.8972742985F, 0.8982379249F, 0.8991958922F, 0.9001482052F, + 0.9010948688F, 0.9020358883F, 0.9029712690F, 0.9039010165F, + 0.9048251367F, 0.9057436357F, 0.9066565195F, 0.9075637946F, + 0.9084654678F, 0.9093615456F, 0.9102520353F, 0.9111369440F, + 0.9120162792F, 0.9128900484F, 0.9137582595F, 0.9146209204F, + 0.9154780394F, 0.9163296248F, 0.9171756853F, 0.9180162296F, + 0.9188512667F, 0.9196808057F, 0.9205048559F, 0.9213234270F, + 0.9221365285F, 0.9229441704F, 0.9237463629F, 0.9245431160F, + 0.9253344404F, 0.9261203465F, 0.9269008453F, 0.9276759477F, + 0.9284456648F, 0.9292100080F, 0.9299689889F, 0.9307226190F, + 0.9314709103F, 0.9322138747F, 0.9329515245F, 0.9336838721F, + 0.9344109300F, 0.9351327108F, 0.9358492275F, 0.9365604931F, + 0.9372665208F, 0.9379673239F, 0.9386629160F, 0.9393533107F, + 0.9400385220F, 0.9407185637F, 0.9413934501F, 0.9420631954F, + 0.9427278141F, 0.9433873208F, 0.9440417304F, 0.9446910576F, + 0.9453353176F, 0.9459745255F, 0.9466086968F, 0.9472378469F, + 0.9478619915F, 0.9484811463F, 0.9490953274F, 0.9497045506F, + 0.9503088323F, 0.9509081888F, 0.9515026365F, 0.9520921921F, + 0.9526768723F, 0.9532566940F, 0.9538316742F, 0.9544018300F, + 0.9549671786F, 0.9555277375F, 0.9560835241F, 0.9566345562F, + 0.9571808513F, 0.9577224275F, 0.9582593027F, 0.9587914949F, + 0.9593190225F, 0.9598419038F, 0.9603601571F, 0.9608738012F, + 0.9613828546F, 0.9618873361F, 0.9623872646F, 0.9628826591F, + 0.9633735388F, 0.9638599227F, 0.9643418303F, 0.9648192808F, + 0.9652922939F, 0.9657608890F, 0.9662250860F, 0.9666849046F, + 0.9671403646F, 0.9675914861F, 0.9680382891F, 0.9684807937F, + 0.9689190202F, 0.9693529890F, 0.9697827203F, 0.9702082347F, + 0.9706295529F, 0.9710466953F, 0.9714596828F, 0.9718685362F, + 0.9722732762F, 0.9726739240F, 0.9730705005F, 0.9734630267F, + 0.9738515239F, 0.9742360134F, 0.9746165163F, 0.9749930540F, + 0.9753656481F, 0.9757343198F, 0.9760990909F, 0.9764599829F, + 0.9768170175F, 0.9771702164F, 0.9775196013F, 0.9778651941F, + 0.9782070167F, 0.9785450909F, 0.9788794388F, 0.9792100824F, + 0.9795370437F, 0.9798603449F, 0.9801800080F, 0.9804960554F, + 0.9808085092F, 0.9811173916F, 0.9814227251F, 0.9817245318F, + 0.9820228343F, 0.9823176549F, 0.9826090160F, 0.9828969402F, + 0.9831814498F, 0.9834625674F, 0.9837403156F, 0.9840147169F, + 0.9842857939F, 0.9845535692F, 0.9848180654F, 0.9850793052F, + 0.9853373113F, 0.9855921062F, 0.9858437127F, 0.9860921535F, + 0.9863374512F, 0.9865796287F, 0.9868187085F, 0.9870547136F, + 0.9872876664F, 0.9875175899F, 0.9877445067F, 0.9879684396F, + 0.9881894112F, 0.9884074444F, 0.9886225619F, 0.9888347863F, + 0.9890441404F, 0.9892506468F, 0.9894543284F, 0.9896552077F, + 0.9898533074F, 0.9900486502F, 0.9902412587F, 0.9904311555F, + 0.9906183633F, 0.9908029045F, 0.9909848019F, 0.9911640779F, + 0.9913407550F, 0.9915148557F, 0.9916864025F, 0.9918554179F, + 0.9920219241F, 0.9921859437F, 0.9923474989F, 0.9925066120F, + 0.9926633054F, 0.9928176012F, 0.9929695218F, 0.9931190891F, + 0.9932663254F, 0.9934112527F, 0.9935538932F, 0.9936942686F, + 0.9938324012F, 0.9939683126F, 0.9941020248F, 0.9942335597F, + 0.9943629388F, 0.9944901841F, 0.9946153170F, 0.9947383593F, + 0.9948593325F, 0.9949782579F, 0.9950951572F, 0.9952100516F, + 0.9953229625F, 0.9954339111F, 0.9955429186F, 0.9956500062F, + 0.9957551948F, 0.9958585056F, 0.9959599593F, 0.9960595769F, + 0.9961573792F, 0.9962533869F, 0.9963476206F, 0.9964401009F, + 0.9965308483F, 0.9966198833F, 0.9967072261F, 0.9967928971F, + 0.9968769164F, 0.9969593041F, 0.9970400804F, 0.9971192651F, + 0.9971968781F, 0.9972729391F, 0.9973474680F, 0.9974204842F, + 0.9974920074F, 0.9975620569F, 0.9976306521F, 0.9976978122F, + 0.9977635565F, 0.9978279039F, 0.9978908736F, 0.9979524842F, + 0.9980127547F, 0.9980717037F, 0.9981293499F, 0.9981857116F, + 0.9982408073F, 0.9982946554F, 0.9983472739F, 0.9983986810F, + 0.9984488947F, 0.9984979328F, 0.9985458132F, 0.9985925534F, + 0.9986381711F, 0.9986826838F, 0.9987261086F, 0.9987684630F, + 0.9988097640F, 0.9988500286F, 0.9988892738F, 0.9989275163F, + 0.9989647727F, 0.9990010597F, 0.9990363938F, 0.9990707911F, + 0.9991042679F, 0.9991368404F, 0.9991685244F, 0.9991993358F, + 0.9992292905F, 0.9992584038F, 0.9992866914F, 0.9993141686F, + 0.9993408506F, 0.9993667526F, 0.9993918895F, 0.9994162761F, + 0.9994399273F, 0.9994628576F, 0.9994850815F, 0.9995066133F, + 0.9995274672F, 0.9995476574F, 0.9995671978F, 0.9995861021F, + 0.9996043841F, 0.9996220573F, 0.9996391352F, 0.9996556310F, + 0.9996715579F, 0.9996869288F, 0.9997017568F, 0.9997160543F, + 0.9997298342F, 0.9997431088F, 0.9997558905F, 0.9997681914F, + 0.9997800236F, 0.9997913990F, 0.9998023292F, 0.9998128261F, + 0.9998229009F, 0.9998325650F, 0.9998418296F, 0.9998507058F, + 0.9998592044F, 0.9998673362F, 0.9998751117F, 0.9998825415F, + 0.9998896358F, 0.9998964047F, 0.9999028584F, 0.9999090066F, + 0.9999148590F, 0.9999204253F, 0.9999257148F, 0.9999307368F, + 0.9999355003F, 0.9999400144F, 0.9999442878F, 0.9999483293F, + 0.9999521472F, 0.9999557499F, 0.9999591457F, 0.9999623426F, + 0.9999653483F, 0.9999681708F, 0.9999708175F, 0.9999732959F, + 0.9999756132F, 0.9999777765F, 0.9999797928F, 0.9999816688F, + 0.9999834113F, 0.9999850266F, 0.9999865211F, 0.9999879009F, + 0.9999891721F, 0.9999903405F, 0.9999914118F, 0.9999923914F, + 0.9999932849F, 0.9999940972F, 0.9999948336F, 0.9999954989F, + 0.9999960978F, 0.9999966349F, 0.9999971146F, 0.9999975411F, + 0.9999979185F, 0.9999982507F, 0.9999985414F, 0.9999987944F, + 0.9999990129F, 0.9999992003F, 0.9999993596F, 0.9999994939F, + 0.9999996059F, 0.9999996981F, 0.9999997732F, 0.9999998333F, + 0.9999998805F, 0.9999999170F, 0.9999999444F, 0.9999999643F, + 0.9999999784F, 0.9999999878F, 0.9999999937F, 0.9999999972F, + 0.9999999990F, 0.9999999997F, 1.0000000000F, 1.0000000000F, +}; + +DECLARE_ALIGNED(16, static const float, vwin4096)[2048] = { + 0.0000002310F, 0.0000020791F, 0.0000057754F, 0.0000113197F, + 0.0000187121F, 0.0000279526F, 0.0000390412F, 0.0000519777F, + 0.0000667623F, 0.0000833949F, 0.0001018753F, 0.0001222036F, + 0.0001443798F, 0.0001684037F, 0.0001942754F, 0.0002219947F, + 0.0002515616F, 0.0002829761F, 0.0003162380F, 0.0003513472F, + 0.0003883038F, 0.0004271076F, 0.0004677584F, 0.0005102563F, + 0.0005546011F, 0.0006007928F, 0.0006488311F, 0.0006987160F, + 0.0007504474F, 0.0008040251F, 0.0008594490F, 0.0009167191F, + 0.0009758351F, 0.0010367969F, 0.0010996044F, 0.0011642574F, + 0.0012307558F, 0.0012990994F, 0.0013692880F, 0.0014413216F, + 0.0015151998F, 0.0015909226F, 0.0016684898F, 0.0017479011F, + 0.0018291565F, 0.0019122556F, 0.0019971983F, 0.0020839845F, + 0.0021726138F, 0.0022630861F, 0.0023554012F, 0.0024495588F, + 0.0025455588F, 0.0026434008F, 0.0027430847F, 0.0028446103F, + 0.0029479772F, 0.0030531853F, 0.0031602342F, 0.0032691238F, + 0.0033798538F, 0.0034924239F, 0.0036068338F, 0.0037230833F, + 0.0038411721F, 0.0039610999F, 0.0040828664F, 0.0042064714F, + 0.0043319145F, 0.0044591954F, 0.0045883139F, 0.0047192696F, + 0.0048520622F, 0.0049866914F, 0.0051231569F, 0.0052614583F, + 0.0054015953F, 0.0055435676F, 0.0056873748F, 0.0058330166F, + 0.0059804926F, 0.0061298026F, 0.0062809460F, 0.0064339226F, + 0.0065887320F, 0.0067453738F, 0.0069038476F, 0.0070641531F, + 0.0072262899F, 0.0073902575F, 0.0075560556F, 0.0077236838F, + 0.0078931417F, 0.0080644288F, 0.0082375447F, 0.0084124891F, + 0.0085892615F, 0.0087678614F, 0.0089482885F, 0.0091305422F, + 0.0093146223F, 0.0095005281F, 0.0096882592F, 0.0098778153F, + 0.0100691958F, 0.0102624002F, 0.0104574281F, 0.0106542791F, + 0.0108529525F, 0.0110534480F, 0.0112557651F, 0.0114599032F, + 0.0116658618F, 0.0118736405F, 0.0120832387F, 0.0122946560F, + 0.0125078917F, 0.0127229454F, 0.0129398166F, 0.0131585046F, + 0.0133790090F, 0.0136013292F, 0.0138254647F, 0.0140514149F, + 0.0142791792F, 0.0145087572F, 0.0147401481F, 0.0149733515F, + 0.0152083667F, 0.0154451932F, 0.0156838304F, 0.0159242777F, + 0.0161665345F, 0.0164106001F, 0.0166564741F, 0.0169041557F, + 0.0171536443F, 0.0174049393F, 0.0176580401F, 0.0179129461F, + 0.0181696565F, 0.0184281708F, 0.0186884883F, 0.0189506084F, + 0.0192145303F, 0.0194802535F, 0.0197477772F, 0.0200171008F, + 0.0202882236F, 0.0205611449F, 0.0208358639F, 0.0211123801F, + 0.0213906927F, 0.0216708011F, 0.0219527043F, 0.0222364019F, + 0.0225218930F, 0.0228091769F, 0.0230982529F, 0.0233891203F, + 0.0236817782F, 0.0239762259F, 0.0242724628F, 0.0245704880F, + 0.0248703007F, 0.0251719002F, 0.0254752858F, 0.0257804565F, + 0.0260874117F, 0.0263961506F, 0.0267066722F, 0.0270189760F, + 0.0273330609F, 0.0276489263F, 0.0279665712F, 0.0282859949F, + 0.0286071966F, 0.0289301753F, 0.0292549303F, 0.0295814607F, + 0.0299097656F, 0.0302398442F, 0.0305716957F, 0.0309053191F, + 0.0312407135F, 0.0315778782F, 0.0319168122F, 0.0322575145F, + 0.0325999844F, 0.0329442209F, 0.0332902231F, 0.0336379900F, + 0.0339875208F, 0.0343388146F, 0.0346918703F, 0.0350466871F, + 0.0354032640F, 0.0357616000F, 0.0361216943F, 0.0364835458F, + 0.0368471535F, 0.0372125166F, 0.0375796339F, 0.0379485046F, + 0.0383191276F, 0.0386915020F, 0.0390656267F, 0.0394415008F, + 0.0398191231F, 0.0401984927F, 0.0405796086F, 0.0409624698F, + 0.0413470751F, 0.0417334235F, 0.0421215141F, 0.0425113457F, + 0.0429029172F, 0.0432962277F, 0.0436912760F, 0.0440880610F, + 0.0444865817F, 0.0448868370F, 0.0452888257F, 0.0456925468F, + 0.0460979992F, 0.0465051816F, 0.0469140931F, 0.0473247325F, + 0.0477370986F, 0.0481511902F, 0.0485670064F, 0.0489845458F, + 0.0494038074F, 0.0498247899F, 0.0502474922F, 0.0506719131F, + 0.0510980514F, 0.0515259060F, 0.0519554756F, 0.0523867590F, + 0.0528197550F, 0.0532544624F, 0.0536908800F, 0.0541290066F, + 0.0545688408F, 0.0550103815F, 0.0554536274F, 0.0558985772F, + 0.0563452297F, 0.0567935837F, 0.0572436377F, 0.0576953907F, + 0.0581488412F, 0.0586039880F, 0.0590608297F, 0.0595193651F, + 0.0599795929F, 0.0604415117F, 0.0609051202F, 0.0613704170F, + 0.0618374009F, 0.0623060704F, 0.0627764243F, 0.0632484611F, + 0.0637221795F, 0.0641975781F, 0.0646746555F, 0.0651534104F, + 0.0656338413F, 0.0661159469F, 0.0665997257F, 0.0670851763F, + 0.0675722973F, 0.0680610873F, 0.0685515448F, 0.0690436684F, + 0.0695374567F, 0.0700329081F, 0.0705300213F, 0.0710287947F, + 0.0715292269F, 0.0720313163F, 0.0725350616F, 0.0730404612F, + 0.0735475136F, 0.0740562172F, 0.0745665707F, 0.0750785723F, + 0.0755922207F, 0.0761075143F, 0.0766244515F, 0.0771430307F, + 0.0776632505F, 0.0781851092F, 0.0787086052F, 0.0792337371F, + 0.0797605032F, 0.0802889018F, 0.0808189315F, 0.0813505905F, + 0.0818838773F, 0.0824187903F, 0.0829553277F, 0.0834934881F, + 0.0840332697F, 0.0845746708F, 0.0851176899F, 0.0856623252F, + 0.0862085751F, 0.0867564379F, 0.0873059119F, 0.0878569954F, + 0.0884096867F, 0.0889639840F, 0.0895198858F, 0.0900773902F, + 0.0906364955F, 0.0911972000F, 0.0917595019F, 0.0923233995F, + 0.0928888909F, 0.0934559745F, 0.0940246485F, 0.0945949110F, + 0.0951667604F, 0.0957401946F, 0.0963152121F, 0.0968918109F, + 0.0974699893F, 0.0980497454F, 0.0986310773F, 0.0992139832F, + 0.0997984614F, 0.1003845098F, 0.1009721267F, 0.1015613101F, + 0.1021520582F, 0.1027443692F, 0.1033382410F, 0.1039336718F, + 0.1045306597F, 0.1051292027F, 0.1057292990F, 0.1063309466F, + 0.1069341435F, 0.1075388878F, 0.1081451776F, 0.1087530108F, + 0.1093623856F, 0.1099732998F, 0.1105857516F, 0.1111997389F, + 0.1118152597F, 0.1124323121F, 0.1130508939F, 0.1136710032F, + 0.1142926379F, 0.1149157960F, 0.1155404755F, 0.1161666742F, + 0.1167943901F, 0.1174236211F, 0.1180543652F, 0.1186866202F, + 0.1193203841F, 0.1199556548F, 0.1205924300F, 0.1212307078F, + 0.1218704860F, 0.1225117624F, 0.1231545349F, 0.1237988013F, + 0.1244445596F, 0.1250918074F, 0.1257405427F, 0.1263907632F, + 0.1270424667F, 0.1276956512F, 0.1283503142F, 0.1290064537F, + 0.1296640674F, 0.1303231530F, 0.1309837084F, 0.1316457312F, + 0.1323092193F, 0.1329741703F, 0.1336405820F, 0.1343084520F, + 0.1349777782F, 0.1356485582F, 0.1363207897F, 0.1369944704F, + 0.1376695979F, 0.1383461700F, 0.1390241842F, 0.1397036384F, + 0.1403845300F, 0.1410668567F, 0.1417506162F, 0.1424358061F, + 0.1431224240F, 0.1438104674F, 0.1444999341F, 0.1451908216F, + 0.1458831274F, 0.1465768492F, 0.1472719844F, 0.1479685308F, + 0.1486664857F, 0.1493658468F, 0.1500666115F, 0.1507687775F, + 0.1514723422F, 0.1521773031F, 0.1528836577F, 0.1535914035F, + 0.1543005380F, 0.1550110587F, 0.1557229631F, 0.1564362485F, + 0.1571509124F, 0.1578669524F, 0.1585843657F, 0.1593031499F, + 0.1600233024F, 0.1607448205F, 0.1614677017F, 0.1621919433F, + 0.1629175428F, 0.1636444975F, 0.1643728047F, 0.1651024619F, + 0.1658334665F, 0.1665658156F, 0.1672995067F, 0.1680345371F, + 0.1687709041F, 0.1695086050F, 0.1702476372F, 0.1709879978F, + 0.1717296843F, 0.1724726938F, 0.1732170237F, 0.1739626711F, + 0.1747096335F, 0.1754579079F, 0.1762074916F, 0.1769583819F, + 0.1777105760F, 0.1784640710F, 0.1792188642F, 0.1799749529F, + 0.1807323340F, 0.1814910049F, 0.1822509628F, 0.1830122046F, + 0.1837747277F, 0.1845385292F, 0.1853036062F, 0.1860699558F, + 0.1868375751F, 0.1876064613F, 0.1883766114F, 0.1891480226F, + 0.1899206919F, 0.1906946164F, 0.1914697932F, 0.1922462194F, + 0.1930238919F, 0.1938028079F, 0.1945829643F, 0.1953643583F, + 0.1961469868F, 0.1969308468F, 0.1977159353F, 0.1985022494F, + 0.1992897859F, 0.2000785420F, 0.2008685145F, 0.2016597005F, + 0.2024520968F, 0.2032457005F, 0.2040405084F, 0.2048365175F, + 0.2056337247F, 0.2064321269F, 0.2072317211F, 0.2080325041F, + 0.2088344727F, 0.2096376240F, 0.2104419547F, 0.2112474618F, + 0.2120541420F, 0.2128619923F, 0.2136710094F, 0.2144811902F, + 0.2152925315F, 0.2161050301F, 0.2169186829F, 0.2177334866F, + 0.2185494381F, 0.2193665340F, 0.2201847712F, 0.2210041465F, + 0.2218246565F, 0.2226462981F, 0.2234690680F, 0.2242929629F, + 0.2251179796F, 0.2259441147F, 0.2267713650F, 0.2275997272F, + 0.2284291979F, 0.2292597739F, 0.2300914518F, 0.2309242283F, + 0.2317581001F, 0.2325930638F, 0.2334291160F, 0.2342662534F, + 0.2351044727F, 0.2359437703F, 0.2367841431F, 0.2376255875F, + 0.2384681001F, 0.2393116776F, 0.2401563165F, 0.2410020134F, + 0.2418487649F, 0.2426965675F, 0.2435454178F, 0.2443953122F, + 0.2452462474F, 0.2460982199F, 0.2469512262F, 0.2478052628F, + 0.2486603262F, 0.2495164129F, 0.2503735194F, 0.2512316421F, + 0.2520907776F, 0.2529509222F, 0.2538120726F, 0.2546742250F, + 0.2555373760F, 0.2564015219F, 0.2572666593F, 0.2581327845F, + 0.2589998939F, 0.2598679840F, 0.2607370510F, 0.2616070916F, + 0.2624781019F, 0.2633500783F, 0.2642230173F, 0.2650969152F, + 0.2659717684F, 0.2668475731F, 0.2677243257F, 0.2686020226F, + 0.2694806601F, 0.2703602344F, 0.2712407419F, 0.2721221789F, + 0.2730045417F, 0.2738878265F, 0.2747720297F, 0.2756571474F, + 0.2765431760F, 0.2774301117F, 0.2783179508F, 0.2792066895F, + 0.2800963240F, 0.2809868505F, 0.2818782654F, 0.2827705647F, + 0.2836637447F, 0.2845578016F, 0.2854527315F, 0.2863485307F, + 0.2872451953F, 0.2881427215F, 0.2890411055F, 0.2899403433F, + 0.2908404312F, 0.2917413654F, 0.2926431418F, 0.2935457567F, + 0.2944492061F, 0.2953534863F, 0.2962585932F, 0.2971645230F, + 0.2980712717F, 0.2989788356F, 0.2998872105F, 0.3007963927F, + 0.3017063781F, 0.3026171629F, 0.3035287430F, 0.3044411145F, + 0.3053542736F, 0.3062682161F, 0.3071829381F, 0.3080984356F, + 0.3090147047F, 0.3099317413F, 0.3108495414F, 0.3117681011F, + 0.3126874163F, 0.3136074830F, 0.3145282972F, 0.3154498548F, + 0.3163721517F, 0.3172951841F, 0.3182189477F, 0.3191434385F, + 0.3200686525F, 0.3209945856F, 0.3219212336F, 0.3228485927F, + 0.3237766585F, 0.3247054271F, 0.3256348943F, 0.3265650560F, + 0.3274959081F, 0.3284274465F, 0.3293596671F, 0.3302925657F, + 0.3312261382F, 0.3321603804F, 0.3330952882F, 0.3340308574F, + 0.3349670838F, 0.3359039634F, 0.3368414919F, 0.3377796651F, + 0.3387184789F, 0.3396579290F, 0.3405980113F, 0.3415387216F, + 0.3424800556F, 0.3434220091F, 0.3443645779F, 0.3453077578F, + 0.3462515446F, 0.3471959340F, 0.3481409217F, 0.3490865036F, + 0.3500326754F, 0.3509794328F, 0.3519267715F, 0.3528746873F, + 0.3538231759F, 0.3547722330F, 0.3557218544F, 0.3566720357F, + 0.3576227727F, 0.3585740610F, 0.3595258964F, 0.3604782745F, + 0.3614311910F, 0.3623846417F, 0.3633386221F, 0.3642931280F, + 0.3652481549F, 0.3662036987F, 0.3671597548F, 0.3681163191F, + 0.3690733870F, 0.3700309544F, 0.3709890167F, 0.3719475696F, + 0.3729066089F, 0.3738661299F, 0.3748261285F, 0.3757866002F, + 0.3767475406F, 0.3777089453F, 0.3786708100F, 0.3796331302F, + 0.3805959014F, 0.3815591194F, 0.3825227796F, 0.3834868777F, + 0.3844514093F, 0.3854163698F, 0.3863817549F, 0.3873475601F, + 0.3883137810F, 0.3892804131F, 0.3902474521F, 0.3912148933F, + 0.3921827325F, 0.3931509650F, 0.3941195865F, 0.3950885925F, + 0.3960579785F, 0.3970277400F, 0.3979978725F, 0.3989683716F, + 0.3999392328F, 0.4009104516F, 0.4018820234F, 0.4028539438F, + 0.4038262084F, 0.4047988125F, 0.4057717516F, 0.4067450214F, + 0.4077186172F, 0.4086925345F, 0.4096667688F, 0.4106413155F, + 0.4116161703F, 0.4125913284F, 0.4135667854F, 0.4145425368F, + 0.4155185780F, 0.4164949044F, 0.4174715116F, 0.4184483949F, + 0.4194255498F, 0.4204029718F, 0.4213806563F, 0.4223585987F, + 0.4233367946F, 0.4243152392F, 0.4252939281F, 0.4262728566F, + 0.4272520202F, 0.4282314144F, 0.4292110345F, 0.4301908760F, + 0.4311709343F, 0.4321512047F, 0.4331316828F, 0.4341123639F, + 0.4350932435F, 0.4360743168F, 0.4370555794F, 0.4380370267F, + 0.4390186540F, 0.4400004567F, 0.4409824303F, 0.4419645701F, + 0.4429468716F, 0.4439293300F, 0.4449119409F, 0.4458946996F, + 0.4468776014F, 0.4478606418F, 0.4488438162F, 0.4498271199F, + 0.4508105483F, 0.4517940967F, 0.4527777607F, 0.4537615355F, + 0.4547454165F, 0.4557293991F, 0.4567134786F, 0.4576976505F, + 0.4586819101F, 0.4596662527F, 0.4606506738F, 0.4616351687F, + 0.4626197328F, 0.4636043614F, 0.4645890499F, 0.4655737936F, + 0.4665585880F, 0.4675434284F, 0.4685283101F, 0.4695132286F, + 0.4704981791F, 0.4714831570F, 0.4724681577F, 0.4734531766F, + 0.4744382089F, 0.4754232501F, 0.4764082956F, 0.4773933406F, + 0.4783783806F, 0.4793634108F, 0.4803484267F, 0.4813334237F, + 0.4823183969F, 0.4833033419F, 0.4842882540F, 0.4852731285F, + 0.4862579608F, 0.4872427462F, 0.4882274802F, 0.4892121580F, + 0.4901967751F, 0.4911813267F, 0.4921658083F, 0.4931502151F, + 0.4941345427F, 0.4951187863F, 0.4961029412F, 0.4970870029F, + 0.4980709667F, 0.4990548280F, 0.5000385822F, 0.5010222245F, + 0.5020057505F, 0.5029891553F, 0.5039724345F, 0.5049555834F, + 0.5059385973F, 0.5069214716F, 0.5079042018F, 0.5088867831F, + 0.5098692110F, 0.5108514808F, 0.5118335879F, 0.5128155277F, + 0.5137972956F, 0.5147788869F, 0.5157602971F, 0.5167415215F, + 0.5177225555F, 0.5187033945F, 0.5196840339F, 0.5206644692F, + 0.5216446956F, 0.5226247086F, 0.5236045035F, 0.5245840759F, + 0.5255634211F, 0.5265425344F, 0.5275214114F, 0.5285000474F, + 0.5294784378F, 0.5304565781F, 0.5314344637F, 0.5324120899F, + 0.5333894522F, 0.5343665461F, 0.5353433670F, 0.5363199102F, + 0.5372961713F, 0.5382721457F, 0.5392478287F, 0.5402232159F, + 0.5411983027F, 0.5421730845F, 0.5431475569F, 0.5441217151F, + 0.5450955548F, 0.5460690714F, 0.5470422602F, 0.5480151169F, + 0.5489876368F, 0.5499598155F, 0.5509316484F, 0.5519031310F, + 0.5528742587F, 0.5538450271F, 0.5548154317F, 0.5557854680F, + 0.5567551314F, 0.5577244174F, 0.5586933216F, 0.5596618395F, + 0.5606299665F, 0.5615976983F, 0.5625650302F, 0.5635319580F, + 0.5644984770F, 0.5654645828F, 0.5664302709F, 0.5673955370F, + 0.5683603765F, 0.5693247850F, 0.5702887580F, 0.5712522912F, + 0.5722153800F, 0.5731780200F, 0.5741402069F, 0.5751019362F, + 0.5760632034F, 0.5770240042F, 0.5779843341F, 0.5789441889F, + 0.5799035639F, 0.5808624549F, 0.5818208575F, 0.5827787673F, + 0.5837361800F, 0.5846930910F, 0.5856494961F, 0.5866053910F, + 0.5875607712F, 0.5885156324F, 0.5894699703F, 0.5904237804F, + 0.5913770586F, 0.5923298004F, 0.5932820016F, 0.5942336578F, + 0.5951847646F, 0.5961353179F, 0.5970853132F, 0.5980347464F, + 0.5989836131F, 0.5999319090F, 0.6008796298F, 0.6018267713F, + 0.6027733292F, 0.6037192993F, 0.6046646773F, 0.6056094589F, + 0.6065536400F, 0.6074972162F, 0.6084401833F, 0.6093825372F, + 0.6103242736F, 0.6112653884F, 0.6122058772F, 0.6131457359F, + 0.6140849604F, 0.6150235464F, 0.6159614897F, 0.6168987862F, + 0.6178354318F, 0.6187714223F, 0.6197067535F, 0.6206414213F, + 0.6215754215F, 0.6225087501F, 0.6234414028F, 0.6243733757F, + 0.6253046646F, 0.6262352654F, 0.6271651739F, 0.6280943862F, + 0.6290228982F, 0.6299507057F, 0.6308778048F, 0.6318041913F, + 0.6327298612F, 0.6336548105F, 0.6345790352F, 0.6355025312F, + 0.6364252945F, 0.6373473211F, 0.6382686070F, 0.6391891483F, + 0.6401089409F, 0.6410279808F, 0.6419462642F, 0.6428637869F, + 0.6437805452F, 0.6446965350F, 0.6456117524F, 0.6465261935F, + 0.6474398544F, 0.6483527311F, 0.6492648197F, 0.6501761165F, + 0.6510866174F, 0.6519963186F, 0.6529052162F, 0.6538133064F, + 0.6547205854F, 0.6556270492F, 0.6565326941F, 0.6574375162F, + 0.6583415117F, 0.6592446769F, 0.6601470079F, 0.6610485009F, + 0.6619491521F, 0.6628489578F, 0.6637479143F, 0.6646460177F, + 0.6655432643F, 0.6664396505F, 0.6673351724F, 0.6682298264F, + 0.6691236087F, 0.6700165157F, 0.6709085436F, 0.6717996889F, + 0.6726899478F, 0.6735793167F, 0.6744677918F, 0.6753553697F, + 0.6762420466F, 0.6771278190F, 0.6780126832F, 0.6788966357F, + 0.6797796728F, 0.6806617909F, 0.6815429866F, 0.6824232562F, + 0.6833025961F, 0.6841810030F, 0.6850584731F, 0.6859350031F, + 0.6868105894F, 0.6876852284F, 0.6885589168F, 0.6894316510F, + 0.6903034275F, 0.6911742430F, 0.6920440939F, 0.6929129769F, + 0.6937808884F, 0.6946478251F, 0.6955137837F, 0.6963787606F, + 0.6972427525F, 0.6981057560F, 0.6989677678F, 0.6998287845F, + 0.7006888028F, 0.7015478194F, 0.7024058309F, 0.7032628340F, + 0.7041188254F, 0.7049738019F, 0.7058277601F, 0.7066806969F, + 0.7075326089F, 0.7083834929F, 0.7092333457F, 0.7100821640F, + 0.7109299447F, 0.7117766846F, 0.7126223804F, 0.7134670291F, + 0.7143106273F, 0.7151531721F, 0.7159946602F, 0.7168350885F, + 0.7176744539F, 0.7185127534F, 0.7193499837F, 0.7201861418F, + 0.7210212247F, 0.7218552293F, 0.7226881526F, 0.7235199914F, + 0.7243507428F, 0.7251804039F, 0.7260089715F, 0.7268364426F, + 0.7276628144F, 0.7284880839F, 0.7293122481F, 0.7301353040F, + 0.7309572487F, 0.7317780794F, 0.7325977930F, 0.7334163868F, + 0.7342338579F, 0.7350502033F, 0.7358654202F, 0.7366795059F, + 0.7374924573F, 0.7383042718F, 0.7391149465F, 0.7399244787F, + 0.7407328655F, 0.7415401041F, 0.7423461920F, 0.7431511261F, + 0.7439549040F, 0.7447575227F, 0.7455589797F, 0.7463592723F, + 0.7471583976F, 0.7479563532F, 0.7487531363F, 0.7495487443F, + 0.7503431745F, 0.7511364244F, 0.7519284913F, 0.7527193726F, + 0.7535090658F, 0.7542975683F, 0.7550848776F, 0.7558709910F, + 0.7566559062F, 0.7574396205F, 0.7582221314F, 0.7590034366F, + 0.7597835334F, 0.7605624194F, 0.7613400923F, 0.7621165495F, + 0.7628917886F, 0.7636658072F, 0.7644386030F, 0.7652101735F, + 0.7659805164F, 0.7667496292F, 0.7675175098F, 0.7682841556F, + 0.7690495645F, 0.7698137341F, 0.7705766622F, 0.7713383463F, + 0.7720987844F, 0.7728579741F, 0.7736159132F, 0.7743725994F, + 0.7751280306F, 0.7758822046F, 0.7766351192F, 0.7773867722F, + 0.7781371614F, 0.7788862848F, 0.7796341401F, 0.7803807253F, + 0.7811260383F, 0.7818700769F, 0.7826128392F, 0.7833543230F, + 0.7840945263F, 0.7848334471F, 0.7855710833F, 0.7863074330F, + 0.7870424941F, 0.7877762647F, 0.7885087428F, 0.7892399264F, + 0.7899698137F, 0.7906984026F, 0.7914256914F, 0.7921516780F, + 0.7928763607F, 0.7935997375F, 0.7943218065F, 0.7950425661F, + 0.7957620142F, 0.7964801492F, 0.7971969692F, 0.7979124724F, + 0.7986266570F, 0.7993395214F, 0.8000510638F, 0.8007612823F, + 0.8014701754F, 0.8021777413F, 0.8028839784F, 0.8035888849F, + 0.8042924592F, 0.8049946997F, 0.8056956048F, 0.8063951727F, + 0.8070934020F, 0.8077902910F, 0.8084858381F, 0.8091800419F, + 0.8098729007F, 0.8105644130F, 0.8112545774F, 0.8119433922F, + 0.8126308561F, 0.8133169676F, 0.8140017251F, 0.8146851272F, + 0.8153671726F, 0.8160478598F, 0.8167271874F, 0.8174051539F, + 0.8180817582F, 0.8187569986F, 0.8194308741F, 0.8201033831F, + 0.8207745244F, 0.8214442966F, 0.8221126986F, 0.8227797290F, + 0.8234453865F, 0.8241096700F, 0.8247725781F, 0.8254341097F, + 0.8260942636F, 0.8267530385F, 0.8274104334F, 0.8280664470F, + 0.8287210782F, 0.8293743259F, 0.8300261889F, 0.8306766662F, + 0.8313257566F, 0.8319734591F, 0.8326197727F, 0.8332646963F, + 0.8339082288F, 0.8345503692F, 0.8351911167F, 0.8358304700F, + 0.8364684284F, 0.8371049907F, 0.8377401562F, 0.8383739238F, + 0.8390062927F, 0.8396372618F, 0.8402668305F, 0.8408949977F, + 0.8415217626F, 0.8421471245F, 0.8427710823F, 0.8433936354F, + 0.8440147830F, 0.8446345242F, 0.8452528582F, 0.8458697844F, + 0.8464853020F, 0.8470994102F, 0.8477121084F, 0.8483233958F, + 0.8489332718F, 0.8495417356F, 0.8501487866F, 0.8507544243F, + 0.8513586479F, 0.8519614568F, 0.8525628505F, 0.8531628283F, + 0.8537613897F, 0.8543585341F, 0.8549542611F, 0.8555485699F, + 0.8561414603F, 0.8567329315F, 0.8573229832F, 0.8579116149F, + 0.8584988262F, 0.8590846165F, 0.8596689855F, 0.8602519327F, + 0.8608334577F, 0.8614135603F, 0.8619922399F, 0.8625694962F, + 0.8631453289F, 0.8637197377F, 0.8642927222F, 0.8648642821F, + 0.8654344172F, 0.8660031272F, 0.8665704118F, 0.8671362708F, + 0.8677007039F, 0.8682637109F, 0.8688252917F, 0.8693854460F, + 0.8699441737F, 0.8705014745F, 0.8710573485F, 0.8716117953F, + 0.8721648150F, 0.8727164073F, 0.8732665723F, 0.8738153098F, + 0.8743626197F, 0.8749085021F, 0.8754529569F, 0.8759959840F, + 0.8765375835F, 0.8770777553F, 0.8776164996F, 0.8781538162F, + 0.8786897054F, 0.8792241670F, 0.8797572013F, 0.8802888082F, + 0.8808189880F, 0.8813477407F, 0.8818750664F, 0.8824009653F, + 0.8829254375F, 0.8834484833F, 0.8839701028F, 0.8844902961F, + 0.8850090636F, 0.8855264054F, 0.8860423218F, 0.8865568131F, + 0.8870698794F, 0.8875815212F, 0.8880917386F, 0.8886005319F, + 0.8891079016F, 0.8896138479F, 0.8901183712F, 0.8906214719F, + 0.8911231503F, 0.8916234067F, 0.8921222417F, 0.8926196556F, + 0.8931156489F, 0.8936102219F, 0.8941033752F, 0.8945951092F, + 0.8950854244F, 0.8955743212F, 0.8960618003F, 0.8965478621F, + 0.8970325071F, 0.8975157359F, 0.8979975490F, 0.8984779471F, + 0.8989569307F, 0.8994345004F, 0.8999106568F, 0.9003854005F, + 0.9008587323F, 0.9013306526F, 0.9018011623F, 0.9022702619F, + 0.9027379521F, 0.9032042337F, 0.9036691074F, 0.9041325739F, + 0.9045946339F, 0.9050552882F, 0.9055145376F, 0.9059723828F, + 0.9064288246F, 0.9068838638F, 0.9073375013F, 0.9077897379F, + 0.9082405743F, 0.9086900115F, 0.9091380503F, 0.9095846917F, + 0.9100299364F, 0.9104737854F, 0.9109162397F, 0.9113573001F, + 0.9117969675F, 0.9122352430F, 0.9126721275F, 0.9131076219F, + 0.9135417273F, 0.9139744447F, 0.9144057750F, 0.9148357194F, + 0.9152642787F, 0.9156914542F, 0.9161172468F, 0.9165416576F, + 0.9169646877F, 0.9173863382F, 0.9178066102F, 0.9182255048F, + 0.9186430232F, 0.9190591665F, 0.9194739359F, 0.9198873324F, + 0.9202993574F, 0.9207100120F, 0.9211192973F, 0.9215272147F, + 0.9219337653F, 0.9223389504F, 0.9227427713F, 0.9231452290F, + 0.9235463251F, 0.9239460607F, 0.9243444371F, 0.9247414557F, + 0.9251371177F, 0.9255314245F, 0.9259243774F, 0.9263159778F, + 0.9267062270F, 0.9270951264F, 0.9274826774F, 0.9278688814F, + 0.9282537398F, 0.9286372540F, 0.9290194254F, 0.9294002555F, + 0.9297797458F, 0.9301578976F, 0.9305347125F, 0.9309101919F, + 0.9312843373F, 0.9316571503F, 0.9320286323F, 0.9323987849F, + 0.9327676097F, 0.9331351080F, 0.9335012816F, 0.9338661320F, + 0.9342296607F, 0.9345918694F, 0.9349527596F, 0.9353123330F, + 0.9356705911F, 0.9360275357F, 0.9363831683F, 0.9367374905F, + 0.9370905042F, 0.9374422108F, 0.9377926122F, 0.9381417099F, + 0.9384895057F, 0.9388360014F, 0.9391811985F, 0.9395250989F, + 0.9398677043F, 0.9402090165F, 0.9405490371F, 0.9408877680F, + 0.9412252110F, 0.9415613678F, 0.9418962402F, 0.9422298301F, + 0.9425621392F, 0.9428931695F, 0.9432229226F, 0.9435514005F, + 0.9438786050F, 0.9442045381F, 0.9445292014F, 0.9448525971F, + 0.9451747268F, 0.9454955926F, 0.9458151963F, 0.9461335399F, + 0.9464506253F, 0.9467664545F, 0.9470810293F, 0.9473943517F, + 0.9477064238F, 0.9480172474F, 0.9483268246F, 0.9486351573F, + 0.9489422475F, 0.9492480973F, 0.9495527087F, 0.9498560837F, + 0.9501582243F, 0.9504591325F, 0.9507588105F, 0.9510572603F, + 0.9513544839F, 0.9516504834F, 0.9519452609F, 0.9522388186F, + 0.9525311584F, 0.9528222826F, 0.9531121932F, 0.9534008923F, + 0.9536883821F, 0.9539746647F, 0.9542597424F, 0.9545436171F, + 0.9548262912F, 0.9551077667F, 0.9553880459F, 0.9556671309F, + 0.9559450239F, 0.9562217272F, 0.9564972429F, 0.9567715733F, + 0.9570447206F, 0.9573166871F, 0.9575874749F, 0.9578570863F, + 0.9581255236F, 0.9583927890F, 0.9586588849F, 0.9589238134F, + 0.9591875769F, 0.9594501777F, 0.9597116180F, 0.9599719003F, + 0.9602310267F, 0.9604889995F, 0.9607458213F, 0.9610014942F, + 0.9612560206F, 0.9615094028F, 0.9617616433F, 0.9620127443F, + 0.9622627083F, 0.9625115376F, 0.9627592345F, 0.9630058016F, + 0.9632512411F, 0.9634955555F, 0.9637387471F, 0.9639808185F, + 0.9642217720F, 0.9644616100F, 0.9647003349F, 0.9649379493F, + 0.9651744556F, 0.9654098561F, 0.9656441534F, 0.9658773499F, + 0.9661094480F, 0.9663404504F, 0.9665703593F, 0.9667991774F, + 0.9670269071F, 0.9672535509F, 0.9674791114F, 0.9677035909F, + 0.9679269921F, 0.9681493174F, 0.9683705694F, 0.9685907506F, + 0.9688098636F, 0.9690279108F, 0.9692448948F, 0.9694608182F, + 0.9696756836F, 0.9698894934F, 0.9701022503F, 0.9703139569F, + 0.9705246156F, 0.9707342291F, 0.9709428000F, 0.9711503309F, + 0.9713568243F, 0.9715622829F, 0.9717667093F, 0.9719701060F, + 0.9721724757F, 0.9723738210F, 0.9725741446F, 0.9727734490F, + 0.9729717369F, 0.9731690109F, 0.9733652737F, 0.9735605279F, + 0.9737547762F, 0.9739480212F, 0.9741402656F, 0.9743315120F, + 0.9745217631F, 0.9747110216F, 0.9748992901F, 0.9750865714F, + 0.9752728681F, 0.9754581829F, 0.9756425184F, 0.9758258775F, + 0.9760082627F, 0.9761896768F, 0.9763701224F, 0.9765496024F, + 0.9767281193F, 0.9769056760F, 0.9770822751F, 0.9772579193F, + 0.9774326114F, 0.9776063542F, 0.9777791502F, 0.9779510023F, + 0.9781219133F, 0.9782918858F, 0.9784609226F, 0.9786290264F, + 0.9787962000F, 0.9789624461F, 0.9791277676F, 0.9792921671F, + 0.9794556474F, 0.9796182113F, 0.9797798615F, 0.9799406009F, + 0.9801004321F, 0.9802593580F, 0.9804173813F, 0.9805745049F, + 0.9807307314F, 0.9808860637F, 0.9810405046F, 0.9811940568F, + 0.9813467232F, 0.9814985065F, 0.9816494095F, 0.9817994351F, + 0.9819485860F, 0.9820968650F, 0.9822442750F, 0.9823908186F, + 0.9825364988F, 0.9826813184F, 0.9828252801F, 0.9829683868F, + 0.9831106413F, 0.9832520463F, 0.9833926048F, 0.9835323195F, + 0.9836711932F, 0.9838092288F, 0.9839464291F, 0.9840827969F, + 0.9842183351F, 0.9843530464F, 0.9844869337F, 0.9846199998F, + 0.9847522475F, 0.9848836798F, 0.9850142993F, 0.9851441090F, + 0.9852731117F, 0.9854013101F, 0.9855287073F, 0.9856553058F, + 0.9857811087F, 0.9859061188F, 0.9860303388F, 0.9861537717F, + 0.9862764202F, 0.9863982872F, 0.9865193756F, 0.9866396882F, + 0.9867592277F, 0.9868779972F, 0.9869959993F, 0.9871132370F, + 0.9872297131F, 0.9873454304F, 0.9874603918F, 0.9875746001F, + 0.9876880581F, 0.9878007688F, 0.9879127348F, 0.9880239592F, + 0.9881344447F, 0.9882441941F, 0.9883532104F, 0.9884614962F, + 0.9885690546F, 0.9886758883F, 0.9887820001F, 0.9888873930F, + 0.9889920697F, 0.9890960331F, 0.9891992859F, 0.9893018312F, + 0.9894036716F, 0.9895048100F, 0.9896052493F, 0.9897049923F, + 0.9898040418F, 0.9899024006F, 0.9900000717F, 0.9900970577F, + 0.9901933616F, 0.9902889862F, 0.9903839343F, 0.9904782087F, + 0.9905718122F, 0.9906647477F, 0.9907570180F, 0.9908486259F, + 0.9909395742F, 0.9910298658F, 0.9911195034F, 0.9912084899F, + 0.9912968281F, 0.9913845208F, 0.9914715708F, 0.9915579810F, + 0.9916437540F, 0.9917288928F, 0.9918134001F, 0.9918972788F, + 0.9919805316F, 0.9920631613F, 0.9921451707F, 0.9922265626F, + 0.9923073399F, 0.9923875052F, 0.9924670615F, 0.9925460114F, + 0.9926243577F, 0.9927021033F, 0.9927792508F, 0.9928558032F, + 0.9929317631F, 0.9930071333F, 0.9930819167F, 0.9931561158F, + 0.9932297337F, 0.9933027728F, 0.9933752362F, 0.9934471264F, + 0.9935184462F, 0.9935891985F, 0.9936593859F, 0.9937290112F, + 0.9937980771F, 0.9938665864F, 0.9939345418F, 0.9940019460F, + 0.9940688018F, 0.9941351118F, 0.9942008789F, 0.9942661057F, + 0.9943307950F, 0.9943949494F, 0.9944585717F, 0.9945216645F, + 0.9945842307F, 0.9946462728F, 0.9947077936F, 0.9947687957F, + 0.9948292820F, 0.9948892550F, 0.9949487174F, 0.9950076719F, + 0.9950661212F, 0.9951240679F, 0.9951815148F, 0.9952384645F, + 0.9952949196F, 0.9953508828F, 0.9954063568F, 0.9954613442F, + 0.9955158476F, 0.9955698697F, 0.9956234132F, 0.9956764806F, + 0.9957290746F, 0.9957811978F, 0.9958328528F, 0.9958840423F, + 0.9959347688F, 0.9959850351F, 0.9960348435F, 0.9960841969F, + 0.9961330977F, 0.9961815486F, 0.9962295521F, 0.9962771108F, + 0.9963242274F, 0.9963709043F, 0.9964171441F, 0.9964629494F, + 0.9965083228F, 0.9965532668F, 0.9965977840F, 0.9966418768F, + 0.9966855479F, 0.9967287998F, 0.9967716350F, 0.9968140559F, + 0.9968560653F, 0.9968976655F, 0.9969388591F, 0.9969796485F, + 0.9970200363F, 0.9970600250F, 0.9970996170F, 0.9971388149F, + 0.9971776211F, 0.9972160380F, 0.9972540683F, 0.9972917142F, + 0.9973289783F, 0.9973658631F, 0.9974023709F, 0.9974385042F, + 0.9974742655F, 0.9975096571F, 0.9975446816F, 0.9975793413F, + 0.9976136386F, 0.9976475759F, 0.9976811557F, 0.9977143803F, + 0.9977472521F, 0.9977797736F, 0.9978119470F, 0.9978437748F, + 0.9978752593F, 0.9979064029F, 0.9979372079F, 0.9979676768F, + 0.9979978117F, 0.9980276151F, 0.9980570893F, 0.9980862367F, + 0.9981150595F, 0.9981435600F, 0.9981717406F, 0.9981996035F, + 0.9982271511F, 0.9982543856F, 0.9982813093F, 0.9983079246F, + 0.9983342336F, 0.9983602386F, 0.9983859418F, 0.9984113456F, + 0.9984364522F, 0.9984612638F, 0.9984857825F, 0.9985100108F, + 0.9985339507F, 0.9985576044F, 0.9985809743F, 0.9986040624F, + 0.9986268710F, 0.9986494022F, 0.9986716583F, 0.9986936413F, + 0.9987153535F, 0.9987367969F, 0.9987579738F, 0.9987788864F, + 0.9987995366F, 0.9988199267F, 0.9988400587F, 0.9988599348F, + 0.9988795572F, 0.9988989278F, 0.9989180487F, 0.9989369222F, + 0.9989555501F, 0.9989739347F, 0.9989920780F, 0.9990099820F, + 0.9990276487F, 0.9990450803F, 0.9990622787F, 0.9990792460F, + 0.9990959841F, 0.9991124952F, 0.9991287812F, 0.9991448440F, + 0.9991606858F, 0.9991763084F, 0.9991917139F, 0.9992069042F, + 0.9992218813F, 0.9992366471F, 0.9992512035F, 0.9992655525F, + 0.9992796961F, 0.9992936361F, 0.9993073744F, 0.9993209131F, + 0.9993342538F, 0.9993473987F, 0.9993603494F, 0.9993731080F, + 0.9993856762F, 0.9993980559F, 0.9994102490F, 0.9994222573F, + 0.9994340827F, 0.9994457269F, 0.9994571918F, 0.9994684793F, + 0.9994795910F, 0.9994905288F, 0.9995012945F, 0.9995118898F, + 0.9995223165F, 0.9995325765F, 0.9995426713F, 0.9995526029F, + 0.9995623728F, 0.9995719829F, 0.9995814349F, 0.9995907304F, + 0.9995998712F, 0.9996088590F, 0.9996176954F, 0.9996263821F, + 0.9996349208F, 0.9996433132F, 0.9996515609F, 0.9996596656F, + 0.9996676288F, 0.9996754522F, 0.9996831375F, 0.9996906862F, + 0.9996981000F, 0.9997053804F, 0.9997125290F, 0.9997195474F, + 0.9997264371F, 0.9997331998F, 0.9997398369F, 0.9997463500F, + 0.9997527406F, 0.9997590103F, 0.9997651606F, 0.9997711930F, + 0.9997771089F, 0.9997829098F, 0.9997885973F, 0.9997941728F, + 0.9997996378F, 0.9998049936F, 0.9998102419F, 0.9998153839F, + 0.9998204211F, 0.9998253550F, 0.9998301868F, 0.9998349182F, + 0.9998395503F, 0.9998440847F, 0.9998485226F, 0.9998528654F, + 0.9998571146F, 0.9998612713F, 0.9998653370F, 0.9998693130F, + 0.9998732007F, 0.9998770012F, 0.9998807159F, 0.9998843461F, + 0.9998878931F, 0.9998913581F, 0.9998947424F, 0.9998980473F, + 0.9999012740F, 0.9999044237F, 0.9999074976F, 0.9999104971F, + 0.9999134231F, 0.9999162771F, 0.9999190601F, 0.9999217733F, + 0.9999244179F, 0.9999269950F, 0.9999295058F, 0.9999319515F, + 0.9999343332F, 0.9999366519F, 0.9999389088F, 0.9999411050F, + 0.9999432416F, 0.9999453196F, 0.9999473402F, 0.9999493044F, + 0.9999512132F, 0.9999530677F, 0.9999548690F, 0.9999566180F, + 0.9999583157F, 0.9999599633F, 0.9999615616F, 0.9999631116F, + 0.9999646144F, 0.9999660709F, 0.9999674820F, 0.9999688487F, + 0.9999701719F, 0.9999714526F, 0.9999726917F, 0.9999738900F, + 0.9999750486F, 0.9999761682F, 0.9999772497F, 0.9999782941F, + 0.9999793021F, 0.9999802747F, 0.9999812126F, 0.9999821167F, + 0.9999829878F, 0.9999838268F, 0.9999846343F, 0.9999854113F, + 0.9999861584F, 0.9999868765F, 0.9999875664F, 0.9999882287F, + 0.9999888642F, 0.9999894736F, 0.9999900577F, 0.9999906172F, + 0.9999911528F, 0.9999916651F, 0.9999921548F, 0.9999926227F, + 0.9999930693F, 0.9999934954F, 0.9999939015F, 0.9999942883F, + 0.9999946564F, 0.9999950064F, 0.9999953390F, 0.9999956547F, + 0.9999959541F, 0.9999962377F, 0.9999965062F, 0.9999967601F, + 0.9999969998F, 0.9999972260F, 0.9999974392F, 0.9999976399F, + 0.9999978285F, 0.9999980056F, 0.9999981716F, 0.9999983271F, + 0.9999984724F, 0.9999986081F, 0.9999987345F, 0.9999988521F, + 0.9999989613F, 0.9999990625F, 0.9999991562F, 0.9999992426F, + 0.9999993223F, 0.9999993954F, 0.9999994625F, 0.9999995239F, + 0.9999995798F, 0.9999996307F, 0.9999996768F, 0.9999997184F, + 0.9999997559F, 0.9999997895F, 0.9999998195F, 0.9999998462F, + 0.9999998698F, 0.9999998906F, 0.9999999088F, 0.9999999246F, + 0.9999999383F, 0.9999999500F, 0.9999999600F, 0.9999999684F, + 0.9999999754F, 0.9999999811F, 0.9999999858F, 0.9999999896F, + 0.9999999925F, 0.9999999948F, 0.9999999965F, 0.9999999978F, + 0.9999999986F, 0.9999999992F, 0.9999999996F, 0.9999999998F, + 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, +}; + +DECLARE_ALIGNED(16, static const float, vwin8192)[4096] = { + 0.0000000578F, 0.0000005198F, 0.0000014438F, 0.0000028299F, + 0.0000046780F, 0.0000069882F, 0.0000097604F, 0.0000129945F, + 0.0000166908F, 0.0000208490F, 0.0000254692F, 0.0000305515F, + 0.0000360958F, 0.0000421021F, 0.0000485704F, 0.0000555006F, + 0.0000628929F, 0.0000707472F, 0.0000790635F, 0.0000878417F, + 0.0000970820F, 0.0001067842F, 0.0001169483F, 0.0001275744F, + 0.0001386625F, 0.0001502126F, 0.0001622245F, 0.0001746984F, + 0.0001876343F, 0.0002010320F, 0.0002148917F, 0.0002292132F, + 0.0002439967F, 0.0002592421F, 0.0002749493F, 0.0002911184F, + 0.0003077493F, 0.0003248421F, 0.0003423967F, 0.0003604132F, + 0.0003788915F, 0.0003978316F, 0.0004172335F, 0.0004370971F, + 0.0004574226F, 0.0004782098F, 0.0004994587F, 0.0005211694F, + 0.0005433418F, 0.0005659759F, 0.0005890717F, 0.0006126292F, + 0.0006366484F, 0.0006611292F, 0.0006860716F, 0.0007114757F, + 0.0007373414F, 0.0007636687F, 0.0007904576F, 0.0008177080F, + 0.0008454200F, 0.0008735935F, 0.0009022285F, 0.0009313250F, + 0.0009608830F, 0.0009909025F, 0.0010213834F, 0.0010523257F, + 0.0010837295F, 0.0011155946F, 0.0011479211F, 0.0011807090F, + 0.0012139582F, 0.0012476687F, 0.0012818405F, 0.0013164736F, + 0.0013515679F, 0.0013871235F, 0.0014231402F, 0.0014596182F, + 0.0014965573F, 0.0015339576F, 0.0015718190F, 0.0016101415F, + 0.0016489251F, 0.0016881698F, 0.0017278754F, 0.0017680421F, + 0.0018086698F, 0.0018497584F, 0.0018913080F, 0.0019333185F, + 0.0019757898F, 0.0020187221F, 0.0020621151F, 0.0021059690F, + 0.0021502837F, 0.0021950591F, 0.0022402953F, 0.0022859921F, + 0.0023321497F, 0.0023787679F, 0.0024258467F, 0.0024733861F, + 0.0025213861F, 0.0025698466F, 0.0026187676F, 0.0026681491F, + 0.0027179911F, 0.0027682935F, 0.0028190562F, 0.0028702794F, + 0.0029219628F, 0.0029741066F, 0.0030267107F, 0.0030797749F, + 0.0031332994F, 0.0031872841F, 0.0032417289F, 0.0032966338F, + 0.0033519988F, 0.0034078238F, 0.0034641089F, 0.0035208539F, + 0.0035780589F, 0.0036357237F, 0.0036938485F, 0.0037524331F, + 0.0038114775F, 0.0038709817F, 0.0039309456F, 0.0039913692F, + 0.0040522524F, 0.0041135953F, 0.0041753978F, 0.0042376599F, + 0.0043003814F, 0.0043635624F, 0.0044272029F, 0.0044913028F, + 0.0045558620F, 0.0046208806F, 0.0046863585F, 0.0047522955F, + 0.0048186919F, 0.0048855473F, 0.0049528619F, 0.0050206356F, + 0.0050888684F, 0.0051575601F, 0.0052267108F, 0.0052963204F, + 0.0053663890F, 0.0054369163F, 0.0055079025F, 0.0055793474F, + 0.0056512510F, 0.0057236133F, 0.0057964342F, 0.0058697137F, + 0.0059434517F, 0.0060176482F, 0.0060923032F, 0.0061674166F, + 0.0062429883F, 0.0063190183F, 0.0063955066F, 0.0064724532F, + 0.0065498579F, 0.0066277207F, 0.0067060416F, 0.0067848205F, + 0.0068640575F, 0.0069437523F, 0.0070239051F, 0.0071045157F, + 0.0071855840F, 0.0072671102F, 0.0073490940F, 0.0074315355F, + 0.0075144345F, 0.0075977911F, 0.0076816052F, 0.0077658768F, + 0.0078506057F, 0.0079357920F, 0.0080214355F, 0.0081075363F, + 0.0081940943F, 0.0082811094F, 0.0083685816F, 0.0084565108F, + 0.0085448970F, 0.0086337401F, 0.0087230401F, 0.0088127969F, + 0.0089030104F, 0.0089936807F, 0.0090848076F, 0.0091763911F, + 0.0092684311F, 0.0093609276F, 0.0094538805F, 0.0095472898F, + 0.0096411554F, 0.0097354772F, 0.0098302552F, 0.0099254894F, + 0.0100211796F, 0.0101173259F, 0.0102139281F, 0.0103109863F, + 0.0104085002F, 0.0105064700F, 0.0106048955F, 0.0107037766F, + 0.0108031133F, 0.0109029056F, 0.0110031534F, 0.0111038565F, + 0.0112050151F, 0.0113066289F, 0.0114086980F, 0.0115112222F, + 0.0116142015F, 0.0117176359F, 0.0118215252F, 0.0119258695F, + 0.0120306686F, 0.0121359225F, 0.0122416312F, 0.0123477944F, + 0.0124544123F, 0.0125614847F, 0.0126690116F, 0.0127769928F, + 0.0128854284F, 0.0129943182F, 0.0131036623F, 0.0132134604F, + 0.0133237126F, 0.0134344188F, 0.0135455790F, 0.0136571929F, + 0.0137692607F, 0.0138817821F, 0.0139947572F, 0.0141081859F, + 0.0142220681F, 0.0143364037F, 0.0144511927F, 0.0145664350F, + 0.0146821304F, 0.0147982791F, 0.0149148808F, 0.0150319355F, + 0.0151494431F, 0.0152674036F, 0.0153858168F, 0.0155046828F, + 0.0156240014F, 0.0157437726F, 0.0158639962F, 0.0159846723F, + 0.0161058007F, 0.0162273814F, 0.0163494142F, 0.0164718991F, + 0.0165948361F, 0.0167182250F, 0.0168420658F, 0.0169663584F, + 0.0170911027F, 0.0172162987F, 0.0173419462F, 0.0174680452F, + 0.0175945956F, 0.0177215974F, 0.0178490504F, 0.0179769545F, + 0.0181053098F, 0.0182341160F, 0.0183633732F, 0.0184930812F, + 0.0186232399F, 0.0187538494F, 0.0188849094F, 0.0190164200F, + 0.0191483809F, 0.0192807923F, 0.0194136539F, 0.0195469656F, + 0.0196807275F, 0.0198149394F, 0.0199496012F, 0.0200847128F, + 0.0202202742F, 0.0203562853F, 0.0204927460F, 0.0206296561F, + 0.0207670157F, 0.0209048245F, 0.0210430826F, 0.0211817899F, + 0.0213209462F, 0.0214605515F, 0.0216006057F, 0.0217411086F, + 0.0218820603F, 0.0220234605F, 0.0221653093F, 0.0223076066F, + 0.0224503521F, 0.0225935459F, 0.0227371879F, 0.0228812779F, + 0.0230258160F, 0.0231708018F, 0.0233162355F, 0.0234621169F, + 0.0236084459F, 0.0237552224F, 0.0239024462F, 0.0240501175F, + 0.0241982359F, 0.0243468015F, 0.0244958141F, 0.0246452736F, + 0.0247951800F, 0.0249455331F, 0.0250963329F, 0.0252475792F, + 0.0253992720F, 0.0255514111F, 0.0257039965F, 0.0258570281F, + 0.0260105057F, 0.0261644293F, 0.0263187987F, 0.0264736139F, + 0.0266288747F, 0.0267845811F, 0.0269407330F, 0.0270973302F, + 0.0272543727F, 0.0274118604F, 0.0275697930F, 0.0277281707F, + 0.0278869932F, 0.0280462604F, 0.0282059723F, 0.0283661287F, + 0.0285267295F, 0.0286877747F, 0.0288492641F, 0.0290111976F, + 0.0291735751F, 0.0293363965F, 0.0294996617F, 0.0296633706F, + 0.0298275231F, 0.0299921190F, 0.0301571583F, 0.0303226409F, + 0.0304885667F, 0.0306549354F, 0.0308217472F, 0.0309890017F, + 0.0311566989F, 0.0313248388F, 0.0314934211F, 0.0316624459F, + 0.0318319128F, 0.0320018220F, 0.0321721732F, 0.0323429663F, + 0.0325142013F, 0.0326858779F, 0.0328579962F, 0.0330305559F, + 0.0332035570F, 0.0333769994F, 0.0335508829F, 0.0337252074F, + 0.0338999728F, 0.0340751790F, 0.0342508259F, 0.0344269134F, + 0.0346034412F, 0.0347804094F, 0.0349578178F, 0.0351356663F, + 0.0353139548F, 0.0354926831F, 0.0356718511F, 0.0358514588F, + 0.0360315059F, 0.0362119924F, 0.0363929182F, 0.0365742831F, + 0.0367560870F, 0.0369383297F, 0.0371210113F, 0.0373041315F, + 0.0374876902F, 0.0376716873F, 0.0378561226F, 0.0380409961F, + 0.0382263077F, 0.0384120571F, 0.0385982443F, 0.0387848691F, + 0.0389719315F, 0.0391594313F, 0.0393473683F, 0.0395357425F, + 0.0397245537F, 0.0399138017F, 0.0401034866F, 0.0402936080F, + 0.0404841660F, 0.0406751603F, 0.0408665909F, 0.0410584576F, + 0.0412507603F, 0.0414434988F, 0.0416366731F, 0.0418302829F, + 0.0420243282F, 0.0422188088F, 0.0424137246F, 0.0426090755F, + 0.0428048613F, 0.0430010819F, 0.0431977371F, 0.0433948269F, + 0.0435923511F, 0.0437903095F, 0.0439887020F, 0.0441875285F, + 0.0443867889F, 0.0445864830F, 0.0447866106F, 0.0449871717F, + 0.0451881661F, 0.0453895936F, 0.0455914542F, 0.0457937477F, + 0.0459964738F, 0.0461996326F, 0.0464032239F, 0.0466072475F, + 0.0468117032F, 0.0470165910F, 0.0472219107F, 0.0474276622F, + 0.0476338452F, 0.0478404597F, 0.0480475056F, 0.0482549827F, + 0.0484628907F, 0.0486712297F, 0.0488799994F, 0.0490891998F, + 0.0492988306F, 0.0495088917F, 0.0497193830F, 0.0499303043F, + 0.0501416554F, 0.0503534363F, 0.0505656468F, 0.0507782867F, + 0.0509913559F, 0.0512048542F, 0.0514187815F, 0.0516331376F, + 0.0518479225F, 0.0520631358F, 0.0522787775F, 0.0524948475F, + 0.0527113455F, 0.0529282715F, 0.0531456252F, 0.0533634066F, + 0.0535816154F, 0.0538002515F, 0.0540193148F, 0.0542388051F, + 0.0544587222F, 0.0546790660F, 0.0548998364F, 0.0551210331F, + 0.0553426561F, 0.0555647051F, 0.0557871801F, 0.0560100807F, + 0.0562334070F, 0.0564571587F, 0.0566813357F, 0.0569059378F, + 0.0571309649F, 0.0573564168F, 0.0575822933F, 0.0578085942F, + 0.0580353195F, 0.0582624689F, 0.0584900423F, 0.0587180396F, + 0.0589464605F, 0.0591753049F, 0.0594045726F, 0.0596342635F, + 0.0598643774F, 0.0600949141F, 0.0603258735F, 0.0605572555F, + 0.0607890597F, 0.0610212862F, 0.0612539346F, 0.0614870049F, + 0.0617204968F, 0.0619544103F, 0.0621887451F, 0.0624235010F, + 0.0626586780F, 0.0628942758F, 0.0631302942F, 0.0633667331F, + 0.0636035923F, 0.0638408717F, 0.0640785710F, 0.0643166901F, + 0.0645552288F, 0.0647941870F, 0.0650335645F, 0.0652733610F, + 0.0655135765F, 0.0657542108F, 0.0659952636F, 0.0662367348F, + 0.0664786242F, 0.0667209316F, 0.0669636570F, 0.0672068000F, + 0.0674503605F, 0.0676943384F, 0.0679387334F, 0.0681835454F, + 0.0684287742F, 0.0686744196F, 0.0689204814F, 0.0691669595F, + 0.0694138536F, 0.0696611637F, 0.0699088894F, 0.0701570307F, + 0.0704055873F, 0.0706545590F, 0.0709039458F, 0.0711537473F, + 0.0714039634F, 0.0716545939F, 0.0719056387F, 0.0721570975F, + 0.0724089702F, 0.0726612565F, 0.0729139563F, 0.0731670694F, + 0.0734205956F, 0.0736745347F, 0.0739288866F, 0.0741836510F, + 0.0744388277F, 0.0746944166F, 0.0749504175F, 0.0752068301F, + 0.0754636543F, 0.0757208899F, 0.0759785367F, 0.0762365946F, + 0.0764950632F, 0.0767539424F, 0.0770132320F, 0.0772729319F, + 0.0775330418F, 0.0777935616F, 0.0780544909F, 0.0783158298F, + 0.0785775778F, 0.0788397349F, 0.0791023009F, 0.0793652755F, + 0.0796286585F, 0.0798924498F, 0.0801566492F, 0.0804212564F, + 0.0806862712F, 0.0809516935F, 0.0812175231F, 0.0814837597F, + 0.0817504031F, 0.0820174532F, 0.0822849097F, 0.0825527724F, + 0.0828210412F, 0.0830897158F, 0.0833587960F, 0.0836282816F, + 0.0838981724F, 0.0841684682F, 0.0844391688F, 0.0847102740F, + 0.0849817835F, 0.0852536973F, 0.0855260150F, 0.0857987364F, + 0.0860718614F, 0.0863453897F, 0.0866193211F, 0.0868936554F, + 0.0871683924F, 0.0874435319F, 0.0877190737F, 0.0879950175F, + 0.0882713632F, 0.0885481105F, 0.0888252592F, 0.0891028091F, + 0.0893807600F, 0.0896591117F, 0.0899378639F, 0.0902170165F, + 0.0904965692F, 0.0907765218F, 0.0910568740F, 0.0913376258F, + 0.0916187767F, 0.0919003268F, 0.0921822756F, 0.0924646230F, + 0.0927473687F, 0.0930305126F, 0.0933140545F, 0.0935979940F, + 0.0938823310F, 0.0941670653F, 0.0944521966F, 0.0947377247F, + 0.0950236494F, 0.0953099704F, 0.0955966876F, 0.0958838007F, + 0.0961713094F, 0.0964592136F, 0.0967475131F, 0.0970362075F, + 0.0973252967F, 0.0976147805F, 0.0979046585F, 0.0981949307F, + 0.0984855967F, 0.0987766563F, 0.0990681093F, 0.0993599555F, + 0.0996521945F, 0.0999448263F, 0.1002378506F, 0.1005312671F, + 0.1008250755F, 0.1011192757F, 0.1014138675F, 0.1017088505F, + 0.1020042246F, 0.1022999895F, 0.1025961450F, 0.1028926909F, + 0.1031896268F, 0.1034869526F, 0.1037846680F, 0.1040827729F, + 0.1043812668F, 0.1046801497F, 0.1049794213F, 0.1052790813F, + 0.1055791294F, 0.1058795656F, 0.1061803894F, 0.1064816006F, + 0.1067831991F, 0.1070851846F, 0.1073875568F, 0.1076903155F, + 0.1079934604F, 0.1082969913F, 0.1086009079F, 0.1089052101F, + 0.1092098975F, 0.1095149699F, 0.1098204270F, 0.1101262687F, + 0.1104324946F, 0.1107391045F, 0.1110460982F, 0.1113534754F, + 0.1116612359F, 0.1119693793F, 0.1122779055F, 0.1125868142F, + 0.1128961052F, 0.1132057781F, 0.1135158328F, 0.1138262690F, + 0.1141370863F, 0.1144482847F, 0.1147598638F, 0.1150718233F, + 0.1153841631F, 0.1156968828F, 0.1160099822F, 0.1163234610F, + 0.1166373190F, 0.1169515559F, 0.1172661714F, 0.1175811654F, + 0.1178965374F, 0.1182122874F, 0.1185284149F, 0.1188449198F, + 0.1191618018F, 0.1194790606F, 0.1197966960F, 0.1201147076F, + 0.1204330953F, 0.1207518587F, 0.1210709976F, 0.1213905118F, + 0.1217104009F, 0.1220306647F, 0.1223513029F, 0.1226723153F, + 0.1229937016F, 0.1233154615F, 0.1236375948F, 0.1239601011F, + 0.1242829803F, 0.1246062319F, 0.1249298559F, 0.1252538518F, + 0.1255782195F, 0.1259029586F, 0.1262280689F, 0.1265535501F, + 0.1268794019F, 0.1272056241F, 0.1275322163F, 0.1278591784F, + 0.1281865099F, 0.1285142108F, 0.1288422805F, 0.1291707190F, + 0.1294995259F, 0.1298287009F, 0.1301582437F, 0.1304881542F, + 0.1308184319F, 0.1311490766F, 0.1314800881F, 0.1318114660F, + 0.1321432100F, 0.1324753200F, 0.1328077955F, 0.1331406364F, + 0.1334738422F, 0.1338074129F, 0.1341413479F, 0.1344756472F, + 0.1348103103F, 0.1351453370F, 0.1354807270F, 0.1358164801F, + 0.1361525959F, 0.1364890741F, 0.1368259145F, 0.1371631167F, + 0.1375006805F, 0.1378386056F, 0.1381768917F, 0.1385155384F, + 0.1388545456F, 0.1391939129F, 0.1395336400F, 0.1398737266F, + 0.1402141724F, 0.1405549772F, 0.1408961406F, 0.1412376623F, + 0.1415795421F, 0.1419217797F, 0.1422643746F, 0.1426073268F, + 0.1429506358F, 0.1432943013F, 0.1436383231F, 0.1439827008F, + 0.1443274342F, 0.1446725229F, 0.1450179667F, 0.1453637652F, + 0.1457099181F, 0.1460564252F, 0.1464032861F, 0.1467505006F, + 0.1470980682F, 0.1474459888F, 0.1477942620F, 0.1481428875F, + 0.1484918651F, 0.1488411942F, 0.1491908748F, 0.1495409065F, + 0.1498912889F, 0.1502420218F, 0.1505931048F, 0.1509445376F, + 0.1512963200F, 0.1516484516F, 0.1520009321F, 0.1523537612F, + 0.1527069385F, 0.1530604638F, 0.1534143368F, 0.1537685571F, + 0.1541231244F, 0.1544780384F, 0.1548332987F, 0.1551889052F, + 0.1555448574F, 0.1559011550F, 0.1562577978F, 0.1566147853F, + 0.1569721173F, 0.1573297935F, 0.1576878135F, 0.1580461771F, + 0.1584048838F, 0.1587639334F, 0.1591233255F, 0.1594830599F, + 0.1598431361F, 0.1602035540F, 0.1605643131F, 0.1609254131F, + 0.1612868537F, 0.1616486346F, 0.1620107555F, 0.1623732160F, + 0.1627360158F, 0.1630991545F, 0.1634626319F, 0.1638264476F, + 0.1641906013F, 0.1645550926F, 0.1649199212F, 0.1652850869F, + 0.1656505892F, 0.1660164278F, 0.1663826024F, 0.1667491127F, + 0.1671159583F, 0.1674831388F, 0.1678506541F, 0.1682185036F, + 0.1685866872F, 0.1689552044F, 0.1693240549F, 0.1696932384F, + 0.1700627545F, 0.1704326029F, 0.1708027833F, 0.1711732952F, + 0.1715441385F, 0.1719153127F, 0.1722868175F, 0.1726586526F, + 0.1730308176F, 0.1734033121F, 0.1737761359F, 0.1741492886F, + 0.1745227698F, 0.1748965792F, 0.1752707164F, 0.1756451812F, + 0.1760199731F, 0.1763950918F, 0.1767705370F, 0.1771463083F, + 0.1775224054F, 0.1778988279F, 0.1782755754F, 0.1786526477F, + 0.1790300444F, 0.1794077651F, 0.1797858094F, 0.1801641771F, + 0.1805428677F, 0.1809218810F, 0.1813012165F, 0.1816808739F, + 0.1820608528F, 0.1824411530F, 0.1828217739F, 0.1832027154F, + 0.1835839770F, 0.1839655584F, 0.1843474592F, 0.1847296790F, + 0.1851122175F, 0.1854950744F, 0.1858782492F, 0.1862617417F, + 0.1866455514F, 0.1870296780F, 0.1874141211F, 0.1877988804F, + 0.1881839555F, 0.1885693461F, 0.1889550517F, 0.1893410721F, + 0.1897274068F, 0.1901140555F, 0.1905010178F, 0.1908882933F, + 0.1912758818F, 0.1916637828F, 0.1920519959F, 0.1924405208F, + 0.1928293571F, 0.1932185044F, 0.1936079625F, 0.1939977308F, + 0.1943878091F, 0.1947781969F, 0.1951688939F, 0.1955598998F, + 0.1959512141F, 0.1963428364F, 0.1967347665F, 0.1971270038F, + 0.1975195482F, 0.1979123990F, 0.1983055561F, 0.1986990190F, + 0.1990927873F, 0.1994868607F, 0.1998812388F, 0.2002759212F, + 0.2006709075F, 0.2010661974F, 0.2014617904F, 0.2018576862F, + 0.2022538844F, 0.2026503847F, 0.2030471865F, 0.2034442897F, + 0.2038416937F, 0.2042393982F, 0.2046374028F, 0.2050357071F, + 0.2054343107F, 0.2058332133F, 0.2062324145F, 0.2066319138F, + 0.2070317110F, 0.2074318055F, 0.2078321970F, 0.2082328852F, + 0.2086338696F, 0.2090351498F, 0.2094367255F, 0.2098385962F, + 0.2102407617F, 0.2106432213F, 0.2110459749F, 0.2114490220F, + 0.2118523621F, 0.2122559950F, 0.2126599202F, 0.2130641373F, + 0.2134686459F, 0.2138734456F, 0.2142785361F, 0.2146839168F, + 0.2150895875F, 0.2154955478F, 0.2159017972F, 0.2163083353F, + 0.2167151617F, 0.2171222761F, 0.2175296780F, 0.2179373670F, + 0.2183453428F, 0.2187536049F, 0.2191621529F, 0.2195709864F, + 0.2199801051F, 0.2203895085F, 0.2207991961F, 0.2212091677F, + 0.2216194228F, 0.2220299610F, 0.2224407818F, 0.2228518850F, + 0.2232632699F, 0.2236749364F, 0.2240868839F, 0.2244991121F, + 0.2249116204F, 0.2253244086F, 0.2257374763F, 0.2261508229F, + 0.2265644481F, 0.2269783514F, 0.2273925326F, 0.2278069911F, + 0.2282217265F, 0.2286367384F, 0.2290520265F, 0.2294675902F, + 0.2298834292F, 0.2302995431F, 0.2307159314F, 0.2311325937F, + 0.2315495297F, 0.2319667388F, 0.2323842207F, 0.2328019749F, + 0.2332200011F, 0.2336382988F, 0.2340568675F, 0.2344757070F, + 0.2348948166F, 0.2353141961F, 0.2357338450F, 0.2361537629F, + 0.2365739493F, 0.2369944038F, 0.2374151261F, 0.2378361156F, + 0.2382573720F, 0.2386788948F, 0.2391006836F, 0.2395227380F, + 0.2399450575F, 0.2403676417F, 0.2407904902F, 0.2412136026F, + 0.2416369783F, 0.2420606171F, 0.2424845185F, 0.2429086820F, + 0.2433331072F, 0.2437577936F, 0.2441827409F, 0.2446079486F, + 0.2450334163F, 0.2454591435F, 0.2458851298F, 0.2463113747F, + 0.2467378779F, 0.2471646389F, 0.2475916573F, 0.2480189325F, + 0.2484464643F, 0.2488742521F, 0.2493022955F, 0.2497305940F, + 0.2501591473F, 0.2505879549F, 0.2510170163F, 0.2514463311F, + 0.2518758989F, 0.2523057193F, 0.2527357916F, 0.2531661157F, + 0.2535966909F, 0.2540275169F, 0.2544585931F, 0.2548899193F, + 0.2553214948F, 0.2557533193F, 0.2561853924F, 0.2566177135F, + 0.2570502822F, 0.2574830981F, 0.2579161608F, 0.2583494697F, + 0.2587830245F, 0.2592168246F, 0.2596508697F, 0.2600851593F, + 0.2605196929F, 0.2609544701F, 0.2613894904F, 0.2618247534F, + 0.2622602586F, 0.2626960055F, 0.2631319938F, 0.2635682230F, + 0.2640046925F, 0.2644414021F, 0.2648783511F, 0.2653155391F, + 0.2657529657F, 0.2661906305F, 0.2666285329F, 0.2670666725F, + 0.2675050489F, 0.2679436616F, 0.2683825101F, 0.2688215940F, + 0.2692609127F, 0.2697004660F, 0.2701402532F, 0.2705802739F, + 0.2710205278F, 0.2714610142F, 0.2719017327F, 0.2723426830F, + 0.2727838644F, 0.2732252766F, 0.2736669191F, 0.2741087914F, + 0.2745508930F, 0.2749932235F, 0.2754357824F, 0.2758785693F, + 0.2763215837F, 0.2767648251F, 0.2772082930F, 0.2776519870F, + 0.2780959066F, 0.2785400513F, 0.2789844207F, 0.2794290143F, + 0.2798738316F, 0.2803188722F, 0.2807641355F, 0.2812096211F, + 0.2816553286F, 0.2821012574F, 0.2825474071F, 0.2829937773F, + 0.2834403673F, 0.2838871768F, 0.2843342053F, 0.2847814523F, + 0.2852289174F, 0.2856765999F, 0.2861244996F, 0.2865726159F, + 0.2870209482F, 0.2874694962F, 0.2879182594F, 0.2883672372F, + 0.2888164293F, 0.2892658350F, 0.2897154540F, 0.2901652858F, + 0.2906153298F, 0.2910655856F, 0.2915160527F, 0.2919667306F, + 0.2924176189F, 0.2928687171F, 0.2933200246F, 0.2937715409F, + 0.2942232657F, 0.2946751984F, 0.2951273386F, 0.2955796856F, + 0.2960322391F, 0.2964849986F, 0.2969379636F, 0.2973911335F, + 0.2978445080F, 0.2982980864F, 0.2987518684F, 0.2992058534F, + 0.2996600409F, 0.3001144305F, 0.3005690217F, 0.3010238139F, + 0.3014788067F, 0.3019339995F, 0.3023893920F, 0.3028449835F, + 0.3033007736F, 0.3037567618F, 0.3042129477F, 0.3046693306F, + 0.3051259102F, 0.3055826859F, 0.3060396572F, 0.3064968236F, + 0.3069541847F, 0.3074117399F, 0.3078694887F, 0.3083274307F, + 0.3087855653F, 0.3092438920F, 0.3097024104F, 0.3101611199F, + 0.3106200200F, 0.3110791103F, 0.3115383902F, 0.3119978592F, + 0.3124575169F, 0.3129173627F, 0.3133773961F, 0.3138376166F, + 0.3142980238F, 0.3147586170F, 0.3152193959F, 0.3156803598F, + 0.3161415084F, 0.3166028410F, 0.3170643573F, 0.3175260566F, + 0.3179879384F, 0.3184500023F, 0.3189122478F, 0.3193746743F, + 0.3198372814F, 0.3203000685F, 0.3207630351F, 0.3212261807F, + 0.3216895048F, 0.3221530069F, 0.3226166865F, 0.3230805430F, + 0.3235445760F, 0.3240087849F, 0.3244731693F, 0.3249377285F, + 0.3254024622F, 0.3258673698F, 0.3263324507F, 0.3267977045F, + 0.3272631306F, 0.3277287286F, 0.3281944978F, 0.3286604379F, + 0.3291265482F, 0.3295928284F, 0.3300592777F, 0.3305258958F, + 0.3309926821F, 0.3314596361F, 0.3319267573F, 0.3323940451F, + 0.3328614990F, 0.3333291186F, 0.3337969033F, 0.3342648525F, + 0.3347329658F, 0.3352012427F, 0.3356696825F, 0.3361382849F, + 0.3366070492F, 0.3370759749F, 0.3375450616F, 0.3380143087F, + 0.3384837156F, 0.3389532819F, 0.3394230071F, 0.3398928905F, + 0.3403629317F, 0.3408331302F, 0.3413034854F, 0.3417739967F, + 0.3422446638F, 0.3427154860F, 0.3431864628F, 0.3436575938F, + 0.3441288782F, 0.3446003158F, 0.3450719058F, 0.3455436478F, + 0.3460155412F, 0.3464875856F, 0.3469597804F, 0.3474321250F, + 0.3479046189F, 0.3483772617F, 0.3488500527F, 0.3493229914F, + 0.3497960774F, 0.3502693100F, 0.3507426887F, 0.3512162131F, + 0.3516898825F, 0.3521636965F, 0.3526376545F, 0.3531117559F, + 0.3535860003F, 0.3540603870F, 0.3545349157F, 0.3550095856F, + 0.3554843964F, 0.3559593474F, 0.3564344381F, 0.3569096680F, + 0.3573850366F, 0.3578605432F, 0.3583361875F, 0.3588119687F, + 0.3592878865F, 0.3597639402F, 0.3602401293F, 0.3607164533F, + 0.3611929117F, 0.3616695038F, 0.3621462292F, 0.3626230873F, + 0.3631000776F, 0.3635771995F, 0.3640544525F, 0.3645318360F, + 0.3650093496F, 0.3654869926F, 0.3659647645F, 0.3664426648F, + 0.3669206930F, 0.3673988484F, 0.3678771306F, 0.3683555390F, + 0.3688340731F, 0.3693127322F, 0.3697915160F, 0.3702704237F, + 0.3707494549F, 0.3712286091F, 0.3717078857F, 0.3721872840F, + 0.3726668037F, 0.3731464441F, 0.3736262047F, 0.3741060850F, + 0.3745860843F, 0.3750662023F, 0.3755464382F, 0.3760267915F, + 0.3765072618F, 0.3769878484F, 0.3774685509F, 0.3779493686F, + 0.3784303010F, 0.3789113475F, 0.3793925076F, 0.3798737809F, + 0.3803551666F, 0.3808366642F, 0.3813182733F, 0.3817999932F, + 0.3822818234F, 0.3827637633F, 0.3832458124F, 0.3837279702F, + 0.3842102360F, 0.3846926093F, 0.3851750897F, 0.3856576764F, + 0.3861403690F, 0.3866231670F, 0.3871060696F, 0.3875890765F, + 0.3880721870F, 0.3885554007F, 0.3890387168F, 0.3895221349F, + 0.3900056544F, 0.3904892748F, 0.3909729955F, 0.3914568160F, + 0.3919407356F, 0.3924247539F, 0.3929088702F, 0.3933930841F, + 0.3938773949F, 0.3943618021F, 0.3948463052F, 0.3953309035F, + 0.3958155966F, 0.3963003838F, 0.3967852646F, 0.3972702385F, + 0.3977553048F, 0.3982404631F, 0.3987257127F, 0.3992110531F, + 0.3996964838F, 0.4001820041F, 0.4006676136F, 0.4011533116F, + 0.4016390976F, 0.4021249710F, 0.4026109313F, 0.4030969779F, + 0.4035831102F, 0.4040693277F, 0.4045556299F, 0.4050420160F, + 0.4055284857F, 0.4060150383F, 0.4065016732F, 0.4069883899F, + 0.4074751879F, 0.4079620665F, 0.4084490252F, 0.4089360635F, + 0.4094231807F, 0.4099103763F, 0.4103976498F, 0.4108850005F, + 0.4113724280F, 0.4118599315F, 0.4123475107F, 0.4128351648F, + 0.4133228934F, 0.4138106959F, 0.4142985716F, 0.4147865201F, + 0.4152745408F, 0.4157626330F, 0.4162507963F, 0.4167390301F, + 0.4172273337F, 0.4177157067F, 0.4182041484F, 0.4186926583F, + 0.4191812359F, 0.4196698805F, 0.4201585915F, 0.4206473685F, + 0.4211362108F, 0.4216251179F, 0.4221140892F, 0.4226031241F, + 0.4230922221F, 0.4235813826F, 0.4240706050F, 0.4245598887F, + 0.4250492332F, 0.4255386379F, 0.4260281022F, 0.4265176256F, + 0.4270072075F, 0.4274968473F, 0.4279865445F, 0.4284762984F, + 0.4289661086F, 0.4294559743F, 0.4299458951F, 0.4304358704F, + 0.4309258996F, 0.4314159822F, 0.4319061175F, 0.4323963050F, + 0.4328865441F, 0.4333768342F, 0.4338671749F, 0.4343575654F, + 0.4348480052F, 0.4353384938F, 0.4358290306F, 0.4363196149F, + 0.4368102463F, 0.4373009241F, 0.4377916478F, 0.4382824168F, + 0.4387732305F, 0.4392640884F, 0.4397549899F, 0.4402459343F, + 0.4407369212F, 0.4412279499F, 0.4417190198F, 0.4422101305F, + 0.4427012813F, 0.4431924717F, 0.4436837010F, 0.4441749686F, + 0.4446662742F, 0.4451576169F, 0.4456489963F, 0.4461404118F, + 0.4466318628F, 0.4471233487F, 0.4476148690F, 0.4481064230F, + 0.4485980103F, 0.4490896302F, 0.4495812821F, 0.4500729654F, + 0.4505646797F, 0.4510564243F, 0.4515481986F, 0.4520400021F, + 0.4525318341F, 0.4530236942F, 0.4535155816F, 0.4540074959F, + 0.4544994365F, 0.4549914028F, 0.4554833941F, 0.4559754100F, + 0.4564674499F, 0.4569595131F, 0.4574515991F, 0.4579437074F, + 0.4584358372F, 0.4589279881F, 0.4594201595F, 0.4599123508F, + 0.4604045615F, 0.4608967908F, 0.4613890383F, 0.4618813034F, + 0.4623735855F, 0.4628658841F, 0.4633581984F, 0.4638505281F, + 0.4643428724F, 0.4648352308F, 0.4653276028F, 0.4658199877F, + 0.4663123849F, 0.4668047940F, 0.4672972143F, 0.4677896451F, + 0.4682820861F, 0.4687745365F, 0.4692669958F, 0.4697594634F, + 0.4702519387F, 0.4707444211F, 0.4712369102F, 0.4717294052F, + 0.4722219056F, 0.4727144109F, 0.4732069204F, 0.4736994336F, + 0.4741919498F, 0.4746844686F, 0.4751769893F, 0.4756695113F, + 0.4761620341F, 0.4766545571F, 0.4771470797F, 0.4776396013F, + 0.4781321213F, 0.4786246392F, 0.4791171544F, 0.4796096663F, + 0.4801021744F, 0.4805946779F, 0.4810871765F, 0.4815796694F, + 0.4820721561F, 0.4825646360F, 0.4830571086F, 0.4835495732F, + 0.4840420293F, 0.4845344763F, 0.4850269136F, 0.4855193407F, + 0.4860117569F, 0.4865041617F, 0.4869965545F, 0.4874889347F, + 0.4879813018F, 0.4884736551F, 0.4889659941F, 0.4894583182F, + 0.4899506268F, 0.4904429193F, 0.4909351952F, 0.4914274538F, + 0.4919196947F, 0.4924119172F, 0.4929041207F, 0.4933963046F, + 0.4938884685F, 0.4943806116F, 0.4948727335F, 0.4953648335F, + 0.4958569110F, 0.4963489656F, 0.4968409965F, 0.4973330032F, + 0.4978249852F, 0.4983169419F, 0.4988088726F, 0.4993007768F, + 0.4997926539F, 0.5002845034F, 0.5007763247F, 0.5012681171F, + 0.5017598801F, 0.5022516132F, 0.5027433157F, 0.5032349871F, + 0.5037266268F, 0.5042182341F, 0.5047098086F, 0.5052013497F, + 0.5056928567F, 0.5061843292F, 0.5066757664F, 0.5071671679F, + 0.5076585330F, 0.5081498613F, 0.5086411520F, 0.5091324047F, + 0.5096236187F, 0.5101147934F, 0.5106059284F, 0.5110970230F, + 0.5115880766F, 0.5120790887F, 0.5125700587F, 0.5130609860F, + 0.5135518700F, 0.5140427102F, 0.5145335059F, 0.5150242566F, + 0.5155149618F, 0.5160056208F, 0.5164962331F, 0.5169867980F, + 0.5174773151F, 0.5179677837F, 0.5184582033F, 0.5189485733F, + 0.5194388931F, 0.5199291621F, 0.5204193798F, 0.5209095455F, + 0.5213996588F, 0.5218897190F, 0.5223797256F, 0.5228696779F, + 0.5233595755F, 0.5238494177F, 0.5243392039F, 0.5248289337F, + 0.5253186063F, 0.5258082213F, 0.5262977781F, 0.5267872760F, + 0.5272767146F, 0.5277660932F, 0.5282554112F, 0.5287446682F, + 0.5292338635F, 0.5297229965F, 0.5302120667F, 0.5307010736F, + 0.5311900164F, 0.5316788947F, 0.5321677079F, 0.5326564554F, + 0.5331451366F, 0.5336337511F, 0.5341222981F, 0.5346107771F, + 0.5350991876F, 0.5355875290F, 0.5360758007F, 0.5365640021F, + 0.5370521327F, 0.5375401920F, 0.5380281792F, 0.5385160939F, + 0.5390039355F, 0.5394917034F, 0.5399793971F, 0.5404670159F, + 0.5409545594F, 0.5414420269F, 0.5419294179F, 0.5424167318F, + 0.5429039680F, 0.5433911261F, 0.5438782053F, 0.5443652051F, + 0.5448521250F, 0.5453389644F, 0.5458257228F, 0.5463123995F, + 0.5467989940F, 0.5472855057F, 0.5477719341F, 0.5482582786F, + 0.5487445387F, 0.5492307137F, 0.5497168031F, 0.5502028063F, + 0.5506887228F, 0.5511745520F, 0.5516602934F, 0.5521459463F, + 0.5526315103F, 0.5531169847F, 0.5536023690F, 0.5540876626F, + 0.5545728649F, 0.5550579755F, 0.5555429937F, 0.5560279189F, + 0.5565127507F, 0.5569974884F, 0.5574821315F, 0.5579666794F, + 0.5584511316F, 0.5589354875F, 0.5594197465F, 0.5599039080F, + 0.5603879716F, 0.5608719367F, 0.5613558026F, 0.5618395689F, + 0.5623232350F, 0.5628068002F, 0.5632902642F, 0.5637736262F, + 0.5642568858F, 0.5647400423F, 0.5652230953F, 0.5657060442F, + 0.5661888883F, 0.5666716272F, 0.5671542603F, 0.5676367870F, + 0.5681192069F, 0.5686015192F, 0.5690837235F, 0.5695658192F, + 0.5700478058F, 0.5705296827F, 0.5710114494F, 0.5714931052F, + 0.5719746497F, 0.5724560822F, 0.5729374023F, 0.5734186094F, + 0.5738997029F, 0.5743806823F, 0.5748615470F, 0.5753422965F, + 0.5758229301F, 0.5763034475F, 0.5767838480F, 0.5772641310F, + 0.5777442960F, 0.5782243426F, 0.5787042700F, 0.5791840778F, + 0.5796637654F, 0.5801433322F, 0.5806227778F, 0.5811021016F, + 0.5815813029F, 0.5820603814F, 0.5825393363F, 0.5830181673F, + 0.5834968737F, 0.5839754549F, 0.5844539105F, 0.5849322399F, + 0.5854104425F, 0.5858885179F, 0.5863664653F, 0.5868442844F, + 0.5873219746F, 0.5877995353F, 0.5882769660F, 0.5887542661F, + 0.5892314351F, 0.5897084724F, 0.5901853776F, 0.5906621500F, + 0.5911387892F, 0.5916152945F, 0.5920916655F, 0.5925679016F, + 0.5930440022F, 0.5935199669F, 0.5939957950F, 0.5944714861F, + 0.5949470396F, 0.5954224550F, 0.5958977317F, 0.5963728692F, + 0.5968478669F, 0.5973227244F, 0.5977974411F, 0.5982720163F, + 0.5987464497F, 0.5992207407F, 0.5996948887F, 0.6001688932F, + 0.6006427537F, 0.6011164696F, 0.6015900405F, 0.6020634657F, + 0.6025367447F, 0.6030098770F, 0.6034828621F, 0.6039556995F, + 0.6044283885F, 0.6049009288F, 0.6053733196F, 0.6058455606F, + 0.6063176512F, 0.6067895909F, 0.6072613790F, 0.6077330152F, + 0.6082044989F, 0.6086758295F, 0.6091470065F, 0.6096180294F, + 0.6100888977F, 0.6105596108F, 0.6110301682F, 0.6115005694F, + 0.6119708139F, 0.6124409011F, 0.6129108305F, 0.6133806017F, + 0.6138502139F, 0.6143196669F, 0.6147889599F, 0.6152580926F, + 0.6157270643F, 0.6161958746F, 0.6166645230F, 0.6171330088F, + 0.6176013317F, 0.6180694910F, 0.6185374863F, 0.6190053171F, + 0.6194729827F, 0.6199404828F, 0.6204078167F, 0.6208749841F, + 0.6213419842F, 0.6218088168F, 0.6222754811F, 0.6227419768F, + 0.6232083032F, 0.6236744600F, 0.6241404465F, 0.6246062622F, + 0.6250719067F, 0.6255373795F, 0.6260026799F, 0.6264678076F, + 0.6269327619F, 0.6273975425F, 0.6278621487F, 0.6283265800F, + 0.6287908361F, 0.6292549163F, 0.6297188201F, 0.6301825471F, + 0.6306460966F, 0.6311094683F, 0.6315726617F, 0.6320356761F, + 0.6324985111F, 0.6329611662F, 0.6334236410F, 0.6338859348F, + 0.6343480472F, 0.6348099777F, 0.6352717257F, 0.6357332909F, + 0.6361946726F, 0.6366558704F, 0.6371168837F, 0.6375777122F, + 0.6380383552F, 0.6384988123F, 0.6389590830F, 0.6394191668F, + 0.6398790631F, 0.6403387716F, 0.6407982916F, 0.6412576228F, + 0.6417167645F, 0.6421757163F, 0.6426344778F, 0.6430930483F, + 0.6435514275F, 0.6440096149F, 0.6444676098F, 0.6449254119F, + 0.6453830207F, 0.6458404356F, 0.6462976562F, 0.6467546820F, + 0.6472115125F, 0.6476681472F, 0.6481245856F, 0.6485808273F, + 0.6490368717F, 0.6494927183F, 0.6499483667F, 0.6504038164F, + 0.6508590670F, 0.6513141178F, 0.6517689684F, 0.6522236185F, + 0.6526780673F, 0.6531323146F, 0.6535863598F, 0.6540402024F, + 0.6544938419F, 0.6549472779F, 0.6554005099F, 0.6558535373F, + 0.6563063598F, 0.6567589769F, 0.6572113880F, 0.6576635927F, + 0.6581155906F, 0.6585673810F, 0.6590189637F, 0.6594703380F, + 0.6599215035F, 0.6603724598F, 0.6608232064F, 0.6612737427F, + 0.6617240684F, 0.6621741829F, 0.6626240859F, 0.6630737767F, + 0.6635232550F, 0.6639725202F, 0.6644215720F, 0.6648704098F, + 0.6653190332F, 0.6657674417F, 0.6662156348F, 0.6666636121F, + 0.6671113731F, 0.6675589174F, 0.6680062445F, 0.6684533538F, + 0.6689002450F, 0.6693469177F, 0.6697933712F, 0.6702396052F, + 0.6706856193F, 0.6711314129F, 0.6715769855F, 0.6720223369F, + 0.6724674664F, 0.6729123736F, 0.6733570581F, 0.6738015194F, + 0.6742457570F, 0.6746897706F, 0.6751335596F, 0.6755771236F, + 0.6760204621F, 0.6764635747F, 0.6769064609F, 0.6773491204F, + 0.6777915525F, 0.6782337570F, 0.6786757332F, 0.6791174809F, + 0.6795589995F, 0.6800002886F, 0.6804413477F, 0.6808821765F, + 0.6813227743F, 0.6817631409F, 0.6822032758F, 0.6826431785F, + 0.6830828485F, 0.6835222855F, 0.6839614890F, 0.6844004585F, + 0.6848391936F, 0.6852776939F, 0.6857159589F, 0.6861539883F, + 0.6865917815F, 0.6870293381F, 0.6874666576F, 0.6879037398F, + 0.6883405840F, 0.6887771899F, 0.6892135571F, 0.6896496850F, + 0.6900855733F, 0.6905212216F, 0.6909566294F, 0.6913917963F, + 0.6918267218F, 0.6922614055F, 0.6926958471F, 0.6931300459F, + 0.6935640018F, 0.6939977141F, 0.6944311825F, 0.6948644066F, + 0.6952973859F, 0.6957301200F, 0.6961626085F, 0.6965948510F, + 0.6970268470F, 0.6974585961F, 0.6978900980F, 0.6983213521F, + 0.6987523580F, 0.6991831154F, 0.6996136238F, 0.7000438828F, + 0.7004738921F, 0.7009036510F, 0.7013331594F, 0.7017624166F, + 0.7021914224F, 0.7026201763F, 0.7030486779F, 0.7034769268F, + 0.7039049226F, 0.7043326648F, 0.7047601531F, 0.7051873870F, + 0.7056143662F, 0.7060410902F, 0.7064675586F, 0.7068937711F, + 0.7073197271F, 0.7077454264F, 0.7081708684F, 0.7085960529F, + 0.7090209793F, 0.7094456474F, 0.7098700566F, 0.7102942066F, + 0.7107180970F, 0.7111417274F, 0.7115650974F, 0.7119882066F, + 0.7124110545F, 0.7128336409F, 0.7132559653F, 0.7136780272F, + 0.7140998264F, 0.7145213624F, 0.7149426348F, 0.7153636433F, + 0.7157843874F, 0.7162048668F, 0.7166250810F, 0.7170450296F, + 0.7174647124F, 0.7178841289F, 0.7183032786F, 0.7187221613F, + 0.7191407765F, 0.7195591239F, 0.7199772030F, 0.7203950135F, + 0.7208125550F, 0.7212298271F, 0.7216468294F, 0.7220635616F, + 0.7224800233F, 0.7228962140F, 0.7233121335F, 0.7237277813F, + 0.7241431571F, 0.7245582604F, 0.7249730910F, 0.7253876484F, + 0.7258019322F, 0.7262159422F, 0.7266296778F, 0.7270431388F, + 0.7274563247F, 0.7278692353F, 0.7282818700F, 0.7286942287F, + 0.7291063108F, 0.7295181160F, 0.7299296440F, 0.7303408944F, + 0.7307518669F, 0.7311625609F, 0.7315729763F, 0.7319831126F, + 0.7323929695F, 0.7328025466F, 0.7332118435F, 0.7336208600F, + 0.7340295955F, 0.7344380499F, 0.7348462226F, 0.7352541134F, + 0.7356617220F, 0.7360690478F, 0.7364760907F, 0.7368828502F, + 0.7372893259F, 0.7376955176F, 0.7381014249F, 0.7385070475F, + 0.7389123849F, 0.7393174368F, 0.7397222029F, 0.7401266829F, + 0.7405308763F, 0.7409347829F, 0.7413384023F, 0.7417417341F, + 0.7421447780F, 0.7425475338F, 0.7429500009F, 0.7433521791F, + 0.7437540681F, 0.7441556674F, 0.7445569769F, 0.7449579960F, + 0.7453587245F, 0.7457591621F, 0.7461593084F, 0.7465591631F, + 0.7469587259F, 0.7473579963F, 0.7477569741F, 0.7481556590F, + 0.7485540506F, 0.7489521486F, 0.7493499526F, 0.7497474623F, + 0.7501446775F, 0.7505415977F, 0.7509382227F, 0.7513345521F, + 0.7517305856F, 0.7521263229F, 0.7525217636F, 0.7529169074F, + 0.7533117541F, 0.7537063032F, 0.7541005545F, 0.7544945076F, + 0.7548881623F, 0.7552815182F, 0.7556745749F, 0.7560673323F, + 0.7564597899F, 0.7568519474F, 0.7572438046F, 0.7576353611F, + 0.7580266166F, 0.7584175708F, 0.7588082235F, 0.7591985741F, + 0.7595886226F, 0.7599783685F, 0.7603678116F, 0.7607569515F, + 0.7611457879F, 0.7615343206F, 0.7619225493F, 0.7623104735F, + 0.7626980931F, 0.7630854078F, 0.7634724171F, 0.7638591209F, + 0.7642455188F, 0.7646316106F, 0.7650173959F, 0.7654028744F, + 0.7657880459F, 0.7661729100F, 0.7665574664F, 0.7669417150F, + 0.7673256553F, 0.7677092871F, 0.7680926100F, 0.7684756239F, + 0.7688583284F, 0.7692407232F, 0.7696228080F, 0.7700045826F, + 0.7703860467F, 0.7707671999F, 0.7711480420F, 0.7715285728F, + 0.7719087918F, 0.7722886989F, 0.7726682938F, 0.7730475762F, + 0.7734265458F, 0.7738052023F, 0.7741835454F, 0.7745615750F, + 0.7749392906F, 0.7753166921F, 0.7756937791F, 0.7760705514F, + 0.7764470087F, 0.7768231508F, 0.7771989773F, 0.7775744880F, + 0.7779496827F, 0.7783245610F, 0.7786991227F, 0.7790733676F, + 0.7794472953F, 0.7798209056F, 0.7801941982F, 0.7805671729F, + 0.7809398294F, 0.7813121675F, 0.7816841869F, 0.7820558873F, + 0.7824272684F, 0.7827983301F, 0.7831690720F, 0.7835394940F, + 0.7839095957F, 0.7842793768F, 0.7846488373F, 0.7850179767F, + 0.7853867948F, 0.7857552914F, 0.7861234663F, 0.7864913191F, + 0.7868588497F, 0.7872260578F, 0.7875929431F, 0.7879595055F, + 0.7883257445F, 0.7886916601F, 0.7890572520F, 0.7894225198F, + 0.7897874635F, 0.7901520827F, 0.7905163772F, 0.7908803468F, + 0.7912439912F, 0.7916073102F, 0.7919703035F, 0.7923329710F, + 0.7926953124F, 0.7930573274F, 0.7934190158F, 0.7937803774F, + 0.7941414120F, 0.7945021193F, 0.7948624991F, 0.7952225511F, + 0.7955822752F, 0.7959416711F, 0.7963007387F, 0.7966594775F, + 0.7970178875F, 0.7973759685F, 0.7977337201F, 0.7980911422F, + 0.7984482346F, 0.7988049970F, 0.7991614292F, 0.7995175310F, + 0.7998733022F, 0.8002287426F, 0.8005838519F, 0.8009386299F, + 0.8012930765F, 0.8016471914F, 0.8020009744F, 0.8023544253F, + 0.8027075438F, 0.8030603298F, 0.8034127831F, 0.8037649035F, + 0.8041166906F, 0.8044681445F, 0.8048192647F, 0.8051700512F, + 0.8055205038F, 0.8058706222F, 0.8062204062F, 0.8065698556F, + 0.8069189702F, 0.8072677499F, 0.8076161944F, 0.8079643036F, + 0.8083120772F, 0.8086595151F, 0.8090066170F, 0.8093533827F, + 0.8096998122F, 0.8100459051F, 0.8103916613F, 0.8107370806F, + 0.8110821628F, 0.8114269077F, 0.8117713151F, 0.8121153849F, + 0.8124591169F, 0.8128025108F, 0.8131455666F, 0.8134882839F, + 0.8138306627F, 0.8141727027F, 0.8145144038F, 0.8148557658F, + 0.8151967886F, 0.8155374718F, 0.8158778154F, 0.8162178192F, + 0.8165574830F, 0.8168968067F, 0.8172357900F, 0.8175744328F, + 0.8179127349F, 0.8182506962F, 0.8185883164F, 0.8189255955F, + 0.8192625332F, 0.8195991295F, 0.8199353840F, 0.8202712967F, + 0.8206068673F, 0.8209420958F, 0.8212769820F, 0.8216115256F, + 0.8219457266F, 0.8222795848F, 0.8226131000F, 0.8229462721F, + 0.8232791009F, 0.8236115863F, 0.8239437280F, 0.8242755260F, + 0.8246069801F, 0.8249380901F, 0.8252688559F, 0.8255992774F, + 0.8259293544F, 0.8262590867F, 0.8265884741F, 0.8269175167F, + 0.8272462141F, 0.8275745663F, 0.8279025732F, 0.8282302344F, + 0.8285575501F, 0.8288845199F, 0.8292111437F, 0.8295374215F, + 0.8298633530F, 0.8301889382F, 0.8305141768F, 0.8308390688F, + 0.8311636141F, 0.8314878124F, 0.8318116637F, 0.8321351678F, + 0.8324583246F, 0.8327811340F, 0.8331035957F, 0.8334257098F, + 0.8337474761F, 0.8340688944F, 0.8343899647F, 0.8347106867F, + 0.8350310605F, 0.8353510857F, 0.8356707624F, 0.8359900904F, + 0.8363090696F, 0.8366276999F, 0.8369459811F, 0.8372639131F, + 0.8375814958F, 0.8378987292F, 0.8382156130F, 0.8385321472F, + 0.8388483316F, 0.8391641662F, 0.8394796508F, 0.8397947853F, + 0.8401095697F, 0.8404240037F, 0.8407380873F, 0.8410518204F, + 0.8413652029F, 0.8416782347F, 0.8419909156F, 0.8423032456F, + 0.8426152245F, 0.8429268523F, 0.8432381289F, 0.8435490541F, + 0.8438596279F, 0.8441698502F, 0.8444797208F, 0.8447892396F, + 0.8450984067F, 0.8454072218F, 0.8457156849F, 0.8460237959F, + 0.8463315547F, 0.8466389612F, 0.8469460154F, 0.8472527170F, + 0.8475590661F, 0.8478650625F, 0.8481707063F, 0.8484759971F, + 0.8487809351F, 0.8490855201F, 0.8493897521F, 0.8496936308F, + 0.8499971564F, 0.8503003286F, 0.8506031474F, 0.8509056128F, + 0.8512077246F, 0.8515094828F, 0.8518108872F, 0.8521119379F, + 0.8524126348F, 0.8527129777F, 0.8530129666F, 0.8533126015F, + 0.8536118822F, 0.8539108087F, 0.8542093809F, 0.8545075988F, + 0.8548054623F, 0.8551029712F, 0.8554001257F, 0.8556969255F, + 0.8559933707F, 0.8562894611F, 0.8565851968F, 0.8568805775F, + 0.8571756034F, 0.8574702743F, 0.8577645902F, 0.8580585509F, + 0.8583521566F, 0.8586454070F, 0.8589383021F, 0.8592308420F, + 0.8595230265F, 0.8598148556F, 0.8601063292F, 0.8603974473F, + 0.8606882098F, 0.8609786167F, 0.8612686680F, 0.8615583636F, + 0.8618477034F, 0.8621366874F, 0.8624253156F, 0.8627135878F, + 0.8630015042F, 0.8632890646F, 0.8635762690F, 0.8638631173F, + 0.8641496096F, 0.8644357457F, 0.8647215257F, 0.8650069495F, + 0.8652920171F, 0.8655767283F, 0.8658610833F, 0.8661450820F, + 0.8664287243F, 0.8667120102F, 0.8669949397F, 0.8672775127F, + 0.8675597293F, 0.8678415894F, 0.8681230929F, 0.8684042398F, + 0.8686850302F, 0.8689654640F, 0.8692455412F, 0.8695252617F, + 0.8698046255F, 0.8700836327F, 0.8703622831F, 0.8706405768F, + 0.8709185138F, 0.8711960940F, 0.8714733174F, 0.8717501840F, + 0.8720266939F, 0.8723028469F, 0.8725786430F, 0.8728540824F, + 0.8731291648F, 0.8734038905F, 0.8736782592F, 0.8739522711F, + 0.8742259261F, 0.8744992242F, 0.8747721653F, 0.8750447496F, + 0.8753169770F, 0.8755888475F, 0.8758603611F, 0.8761315177F, + 0.8764023175F, 0.8766727603F, 0.8769428462F, 0.8772125752F, + 0.8774819474F, 0.8777509626F, 0.8780196209F, 0.8782879224F, + 0.8785558669F, 0.8788234546F, 0.8790906854F, 0.8793575594F, + 0.8796240765F, 0.8798902368F, 0.8801560403F, 0.8804214870F, + 0.8806865768F, 0.8809513099F, 0.8812156863F, 0.8814797059F, + 0.8817433687F, 0.8820066749F, 0.8822696243F, 0.8825322171F, + 0.8827944532F, 0.8830563327F, 0.8833178556F, 0.8835790219F, + 0.8838398316F, 0.8841002848F, 0.8843603815F, 0.8846201217F, + 0.8848795054F, 0.8851385327F, 0.8853972036F, 0.8856555182F, + 0.8859134764F, 0.8861710783F, 0.8864283239F, 0.8866852133F, + 0.8869417464F, 0.8871979234F, 0.8874537443F, 0.8877092090F, + 0.8879643177F, 0.8882190704F, 0.8884734671F, 0.8887275078F, + 0.8889811927F, 0.8892345216F, 0.8894874948F, 0.8897401122F, + 0.8899923738F, 0.8902442798F, 0.8904958301F, 0.8907470248F, + 0.8909978640F, 0.8912483477F, 0.8914984759F, 0.8917482487F, + 0.8919976662F, 0.8922467284F, 0.8924954353F, 0.8927437871F, + 0.8929917837F, 0.8932394252F, 0.8934867118F, 0.8937336433F, + 0.8939802199F, 0.8942264417F, 0.8944723087F, 0.8947178210F, + 0.8949629785F, 0.8952077815F, 0.8954522299F, 0.8956963239F, + 0.8959400634F, 0.8961834486F, 0.8964264795F, 0.8966691561F, + 0.8969114786F, 0.8971534470F, 0.8973950614F, 0.8976363219F, + 0.8978772284F, 0.8981177812F, 0.8983579802F, 0.8985978256F, + 0.8988373174F, 0.8990764556F, 0.8993152405F, 0.8995536720F, + 0.8997917502F, 0.9000294751F, 0.9002668470F, 0.9005038658F, + 0.9007405317F, 0.9009768446F, 0.9012128048F, 0.9014484123F, + 0.9016836671F, 0.9019185693F, 0.9021531191F, 0.9023873165F, + 0.9026211616F, 0.9028546546F, 0.9030877954F, 0.9033205841F, + 0.9035530210F, 0.9037851059F, 0.9040168392F, 0.9042482207F, + 0.9044792507F, 0.9047099293F, 0.9049402564F, 0.9051702323F, + 0.9053998569F, 0.9056291305F, 0.9058580531F, 0.9060866248F, + 0.9063148457F, 0.9065427159F, 0.9067702355F, 0.9069974046F, + 0.9072242233F, 0.9074506917F, 0.9076768100F, 0.9079025782F, + 0.9081279964F, 0.9083530647F, 0.9085777833F, 0.9088021523F, + 0.9090261717F, 0.9092498417F, 0.9094731623F, 0.9096961338F, + 0.9099187561F, 0.9101410295F, 0.9103629540F, 0.9105845297F, + 0.9108057568F, 0.9110266354F, 0.9112471656F, 0.9114673475F, + 0.9116871812F, 0.9119066668F, 0.9121258046F, 0.9123445945F, + 0.9125630367F, 0.9127811314F, 0.9129988786F, 0.9132162785F, + 0.9134333312F, 0.9136500368F, 0.9138663954F, 0.9140824073F, + 0.9142980724F, 0.9145133910F, 0.9147283632F, 0.9149429890F, + 0.9151572687F, 0.9153712023F, 0.9155847900F, 0.9157980319F, + 0.9160109282F, 0.9162234790F, 0.9164356844F, 0.9166475445F, + 0.9168590595F, 0.9170702296F, 0.9172810548F, 0.9174915354F, + 0.9177016714F, 0.9179114629F, 0.9181209102F, 0.9183300134F, + 0.9185387726F, 0.9187471879F, 0.9189552595F, 0.9191629876F, + 0.9193703723F, 0.9195774136F, 0.9197841119F, 0.9199904672F, + 0.9201964797F, 0.9204021495F, 0.9206074767F, 0.9208124616F, + 0.9210171043F, 0.9212214049F, 0.9214253636F, 0.9216289805F, + 0.9218322558F, 0.9220351896F, 0.9222377821F, 0.9224400335F, + 0.9226419439F, 0.9228435134F, 0.9230447423F, 0.9232456307F, + 0.9234461787F, 0.9236463865F, 0.9238462543F, 0.9240457822F, + 0.9242449704F, 0.9244438190F, 0.9246423282F, 0.9248404983F, + 0.9250383293F, 0.9252358214F, 0.9254329747F, 0.9256297896F, + 0.9258262660F, 0.9260224042F, 0.9262182044F, 0.9264136667F, + 0.9266087913F, 0.9268035783F, 0.9269980280F, 0.9271921405F, + 0.9273859160F, 0.9275793546F, 0.9277724566F, 0.9279652221F, + 0.9281576513F, 0.9283497443F, 0.9285415014F, 0.9287329227F, + 0.9289240084F, 0.9291147586F, 0.9293051737F, 0.9294952536F, + 0.9296849987F, 0.9298744091F, 0.9300634850F, 0.9302522266F, + 0.9304406340F, 0.9306287074F, 0.9308164471F, 0.9310038532F, + 0.9311909259F, 0.9313776654F, 0.9315640719F, 0.9317501455F, + 0.9319358865F, 0.9321212951F, 0.9323063713F, 0.9324911155F, + 0.9326755279F, 0.9328596085F, 0.9330433577F, 0.9332267756F, + 0.9334098623F, 0.9335926182F, 0.9337750434F, 0.9339571380F, + 0.9341389023F, 0.9343203366F, 0.9345014409F, 0.9346822155F, + 0.9348626606F, 0.9350427763F, 0.9352225630F, 0.9354020207F, + 0.9355811498F, 0.9357599503F, 0.9359384226F, 0.9361165667F, + 0.9362943830F, 0.9364718716F, 0.9366490327F, 0.9368258666F, + 0.9370023733F, 0.9371785533F, 0.9373544066F, 0.9375299335F, + 0.9377051341F, 0.9378800087F, 0.9380545576F, 0.9382287809F, + 0.9384026787F, 0.9385762515F, 0.9387494993F, 0.9389224223F, + 0.9390950209F, 0.9392672951F, 0.9394392453F, 0.9396108716F, + 0.9397821743F, 0.9399531536F, 0.9401238096F, 0.9402941427F, + 0.9404641530F, 0.9406338407F, 0.9408032061F, 0.9409722495F, + 0.9411409709F, 0.9413093707F, 0.9414774491F, 0.9416452062F, + 0.9418126424F, 0.9419797579F, 0.9421465528F, 0.9423130274F, + 0.9424791819F, 0.9426450166F, 0.9428105317F, 0.9429757274F, + 0.9431406039F, 0.9433051616F, 0.9434694005F, 0.9436333209F, + 0.9437969232F, 0.9439602074F, 0.9441231739F, 0.9442858229F, + 0.9444481545F, 0.9446101691F, 0.9447718669F, 0.9449332481F, + 0.9450943129F, 0.9452550617F, 0.9454154945F, 0.9455756118F, + 0.9457354136F, 0.9458949003F, 0.9460540721F, 0.9462129292F, + 0.9463714719F, 0.9465297003F, 0.9466876149F, 0.9468452157F, + 0.9470025031F, 0.9471594772F, 0.9473161384F, 0.9474724869F, + 0.9476285229F, 0.9477842466F, 0.9479396584F, 0.9480947585F, + 0.9482495470F, 0.9484040243F, 0.9485581906F, 0.9487120462F, + 0.9488655913F, 0.9490188262F, 0.9491717511F, 0.9493243662F, + 0.9494766718F, 0.9496286683F, 0.9497803557F, 0.9499317345F, + 0.9500828047F, 0.9502335668F, 0.9503840209F, 0.9505341673F, + 0.9506840062F, 0.9508335380F, 0.9509827629F, 0.9511316810F, + 0.9512802928F, 0.9514285984F, 0.9515765982F, 0.9517242923F, + 0.9518716810F, 0.9520187646F, 0.9521655434F, 0.9523120176F, + 0.9524581875F, 0.9526040534F, 0.9527496154F, 0.9528948739F, + 0.9530398292F, 0.9531844814F, 0.9533288310F, 0.9534728780F, + 0.9536166229F, 0.9537600659F, 0.9539032071F, 0.9540460470F, + 0.9541885858F, 0.9543308237F, 0.9544727611F, 0.9546143981F, + 0.9547557351F, 0.9548967723F, 0.9550375100F, 0.9551779485F, + 0.9553180881F, 0.9554579290F, 0.9555974714F, 0.9557367158F, + 0.9558756623F, 0.9560143112F, 0.9561526628F, 0.9562907174F, + 0.9564284752F, 0.9565659366F, 0.9567031017F, 0.9568399710F, + 0.9569765446F, 0.9571128229F, 0.9572488061F, 0.9573844944F, + 0.9575198883F, 0.9576549879F, 0.9577897936F, 0.9579243056F, + 0.9580585242F, 0.9581924497F, 0.9583260824F, 0.9584594226F, + 0.9585924705F, 0.9587252264F, 0.9588576906F, 0.9589898634F, + 0.9591217452F, 0.9592533360F, 0.9593846364F, 0.9595156465F, + 0.9596463666F, 0.9597767971F, 0.9599069382F, 0.9600367901F, + 0.9601663533F, 0.9602956279F, 0.9604246143F, 0.9605533128F, + 0.9606817236F, 0.9608098471F, 0.9609376835F, 0.9610652332F, + 0.9611924963F, 0.9613194733F, 0.9614461644F, 0.9615725699F, + 0.9616986901F, 0.9618245253F, 0.9619500757F, 0.9620753418F, + 0.9622003238F, 0.9623250219F, 0.9624494365F, 0.9625735679F, + 0.9626974163F, 0.9628209821F, 0.9629442656F, 0.9630672671F, + 0.9631899868F, 0.9633124251F, 0.9634345822F, 0.9635564585F, + 0.9636780543F, 0.9637993699F, 0.9639204056F, 0.9640411616F, + 0.9641616383F, 0.9642818359F, 0.9644017549F, 0.9645213955F, + 0.9646407579F, 0.9647598426F, 0.9648786497F, 0.9649971797F, + 0.9651154328F, 0.9652334092F, 0.9653511095F, 0.9654685337F, + 0.9655856823F, 0.9657025556F, 0.9658191538F, 0.9659354773F, + 0.9660515263F, 0.9661673013F, 0.9662828024F, 0.9663980300F, + 0.9665129845F, 0.9666276660F, 0.9667420750F, 0.9668562118F, + 0.9669700766F, 0.9670836698F, 0.9671969917F, 0.9673100425F, + 0.9674228227F, 0.9675353325F, 0.9676475722F, 0.9677595422F, + 0.9678712428F, 0.9679826742F, 0.9680938368F, 0.9682047309F, + 0.9683153569F, 0.9684257150F, 0.9685358056F, 0.9686456289F, + 0.9687551853F, 0.9688644752F, 0.9689734987F, 0.9690822564F, + 0.9691907483F, 0.9692989750F, 0.9694069367F, 0.9695146337F, + 0.9696220663F, 0.9697292349F, 0.9698361398F, 0.9699427813F, + 0.9700491597F, 0.9701552754F, 0.9702611286F, 0.9703667197F, + 0.9704720490F, 0.9705771169F, 0.9706819236F, 0.9707864695F, + 0.9708907549F, 0.9709947802F, 0.9710985456F, 0.9712020514F, + 0.9713052981F, 0.9714082859F, 0.9715110151F, 0.9716134862F, + 0.9717156993F, 0.9718176549F, 0.9719193532F, 0.9720207946F, + 0.9721219794F, 0.9722229080F, 0.9723235806F, 0.9724239976F, + 0.9725241593F, 0.9726240661F, 0.9727237183F, 0.9728231161F, + 0.9729222601F, 0.9730211503F, 0.9731197873F, 0.9732181713F, + 0.9733163027F, 0.9734141817F, 0.9735118088F, 0.9736091842F, + 0.9737063083F, 0.9738031814F, 0.9738998039F, 0.9739961760F, + 0.9740922981F, 0.9741881706F, 0.9742837938F, 0.9743791680F, + 0.9744742935F, 0.9745691707F, 0.9746637999F, 0.9747581814F, + 0.9748523157F, 0.9749462029F, 0.9750398435F, 0.9751332378F, + 0.9752263861F, 0.9753192887F, 0.9754119461F, 0.9755043585F, + 0.9755965262F, 0.9756884496F, 0.9757801291F, 0.9758715650F, + 0.9759627575F, 0.9760537071F, 0.9761444141F, 0.9762348789F, + 0.9763251016F, 0.9764150828F, 0.9765048228F, 0.9765943218F, + 0.9766835802F, 0.9767725984F, 0.9768613767F, 0.9769499154F, + 0.9770382149F, 0.9771262755F, 0.9772140976F, 0.9773016815F, + 0.9773890275F, 0.9774761360F, 0.9775630073F, 0.9776496418F, + 0.9777360398F, 0.9778222016F, 0.9779081277F, 0.9779938182F, + 0.9780792736F, 0.9781644943F, 0.9782494805F, 0.9783342326F, + 0.9784187509F, 0.9785030359F, 0.9785870877F, 0.9786709069F, + 0.9787544936F, 0.9788378484F, 0.9789209714F, 0.9790038631F, + 0.9790865238F, 0.9791689538F, 0.9792511535F, 0.9793331232F, + 0.9794148633F, 0.9794963742F, 0.9795776561F, 0.9796587094F, + 0.9797395345F, 0.9798201316F, 0.9799005013F, 0.9799806437F, + 0.9800605593F, 0.9801402483F, 0.9802197112F, 0.9802989483F, + 0.9803779600F, 0.9804567465F, 0.9805353082F, 0.9806136455F, + 0.9806917587F, 0.9807696482F, 0.9808473143F, 0.9809247574F, + 0.9810019778F, 0.9810789759F, 0.9811557519F, 0.9812323064F, + 0.9813086395F, 0.9813847517F, 0.9814606433F, 0.9815363147F, + 0.9816117662F, 0.9816869981F, 0.9817620108F, 0.9818368047F, + 0.9819113801F, 0.9819857374F, 0.9820598769F, 0.9821337989F, + 0.9822075038F, 0.9822809920F, 0.9823542638F, 0.9824273195F, + 0.9825001596F, 0.9825727843F, 0.9826451940F, 0.9827173891F, + 0.9827893700F, 0.9828611368F, 0.9829326901F, 0.9830040302F, + 0.9830751574F, 0.9831460720F, 0.9832167745F, 0.9832872652F, + 0.9833575444F, 0.9834276124F, 0.9834974697F, 0.9835671166F, + 0.9836365535F, 0.9837057806F, 0.9837747983F, 0.9838436071F, + 0.9839122072F, 0.9839805990F, 0.9840487829F, 0.9841167591F, + 0.9841845282F, 0.9842520903F, 0.9843194459F, 0.9843865953F, + 0.9844535389F, 0.9845202771F, 0.9845868101F, 0.9846531383F, + 0.9847192622F, 0.9847851820F, 0.9848508980F, 0.9849164108F, + 0.9849817205F, 0.9850468276F, 0.9851117324F, 0.9851764352F, + 0.9852409365F, 0.9853052366F, 0.9853693358F, 0.9854332344F, + 0.9854969330F, 0.9855604317F, 0.9856237309F, 0.9856868310F, + 0.9857497325F, 0.9858124355F, 0.9858749404F, 0.9859372477F, + 0.9859993577F, 0.9860612707F, 0.9861229871F, 0.9861845072F, + 0.9862458315F, 0.9863069601F, 0.9863678936F, 0.9864286322F, + 0.9864891764F, 0.9865495264F, 0.9866096826F, 0.9866696454F, + 0.9867294152F, 0.9867889922F, 0.9868483769F, 0.9869075695F, + 0.9869665706F, 0.9870253803F, 0.9870839991F, 0.9871424273F, + 0.9872006653F, 0.9872587135F, 0.9873165721F, 0.9873742415F, + 0.9874317222F, 0.9874890144F, 0.9875461185F, 0.9876030348F, + 0.9876597638F, 0.9877163057F, 0.9877726610F, 0.9878288300F, + 0.9878848130F, 0.9879406104F, 0.9879962225F, 0.9880516497F, + 0.9881068924F, 0.9881619509F, 0.9882168256F, 0.9882715168F, + 0.9883260249F, 0.9883803502F, 0.9884344931F, 0.9884884539F, + 0.9885422331F, 0.9885958309F, 0.9886492477F, 0.9887024838F, + 0.9887555397F, 0.9888084157F, 0.9888611120F, 0.9889136292F, + 0.9889659675F, 0.9890181273F, 0.9890701089F, 0.9891219128F, + 0.9891735392F, 0.9892249885F, 0.9892762610F, 0.9893273572F, + 0.9893782774F, 0.9894290219F, 0.9894795911F, 0.9895299853F, + 0.9895802049F, 0.9896302502F, 0.9896801217F, 0.9897298196F, + 0.9897793443F, 0.9898286961F, 0.9898778755F, 0.9899268828F, + 0.9899757183F, 0.9900243823F, 0.9900728753F, 0.9901211976F, + 0.9901693495F, 0.9902173314F, 0.9902651436F, 0.9903127865F, + 0.9903602605F, 0.9904075659F, 0.9904547031F, 0.9905016723F, + 0.9905484740F, 0.9905951086F, 0.9906415763F, 0.9906878775F, + 0.9907340126F, 0.9907799819F, 0.9908257858F, 0.9908714247F, + 0.9909168988F, 0.9909622086F, 0.9910073543F, 0.9910523364F, + 0.9910971552F, 0.9911418110F, 0.9911863042F, 0.9912306351F, + 0.9912748042F, 0.9913188117F, 0.9913626580F, 0.9914063435F, + 0.9914498684F, 0.9914932333F, 0.9915364383F, 0.9915794839F, + 0.9916223703F, 0.9916650981F, 0.9917076674F, 0.9917500787F, + 0.9917923323F, 0.9918344286F, 0.9918763679F, 0.9919181505F, + 0.9919597769F, 0.9920012473F, 0.9920425621F, 0.9920837217F, + 0.9921247263F, 0.9921655765F, 0.9922062724F, 0.9922468145F, + 0.9922872030F, 0.9923274385F, 0.9923675211F, 0.9924074513F, + 0.9924472294F, 0.9924868557F, 0.9925263306F, 0.9925656544F, + 0.9926048275F, 0.9926438503F, 0.9926827230F, 0.9927214461F, + 0.9927600199F, 0.9927984446F, 0.9928367208F, 0.9928748486F, + 0.9929128285F, 0.9929506608F, 0.9929883459F, 0.9930258841F, + 0.9930632757F, 0.9931005211F, 0.9931376207F, 0.9931745747F, + 0.9932113836F, 0.9932480476F, 0.9932845671F, 0.9933209425F, + 0.9933571742F, 0.9933932623F, 0.9934292074F, 0.9934650097F, + 0.9935006696F, 0.9935361874F, 0.9935715635F, 0.9936067982F, + 0.9936418919F, 0.9936768448F, 0.9937116574F, 0.9937463300F, + 0.9937808629F, 0.9938152565F, 0.9938495111F, 0.9938836271F, + 0.9939176047F, 0.9939514444F, 0.9939851465F, 0.9940187112F, + 0.9940521391F, 0.9940854303F, 0.9941185853F, 0.9941516044F, + 0.9941844879F, 0.9942172361F, 0.9942498495F, 0.9942823283F, + 0.9943146729F, 0.9943468836F, 0.9943789608F, 0.9944109047F, + 0.9944427158F, 0.9944743944F, 0.9945059408F, 0.9945373553F, + 0.9945686384F, 0.9945997902F, 0.9946308112F, 0.9946617017F, + 0.9946924621F, 0.9947230926F, 0.9947535937F, 0.9947839656F, + 0.9948142086F, 0.9948443232F, 0.9948743097F, 0.9949041683F, + 0.9949338995F, 0.9949635035F, 0.9949929807F, 0.9950223315F, + 0.9950515561F, 0.9950806549F, 0.9951096282F, 0.9951384764F, + 0.9951671998F, 0.9951957987F, 0.9952242735F, 0.9952526245F, + 0.9952808520F, 0.9953089564F, 0.9953369380F, 0.9953647971F, + 0.9953925340F, 0.9954201491F, 0.9954476428F, 0.9954750153F, + 0.9955022670F, 0.9955293981F, 0.9955564092F, 0.9955833003F, + 0.9956100720F, 0.9956367245F, 0.9956632582F, 0.9956896733F, + 0.9957159703F, 0.9957421494F, 0.9957682110F, 0.9957941553F, + 0.9958199828F, 0.9958456937F, 0.9958712884F, 0.9958967672F, + 0.9959221305F, 0.9959473784F, 0.9959725115F, 0.9959975300F, + 0.9960224342F, 0.9960472244F, 0.9960719011F, 0.9960964644F, + 0.9961209148F, 0.9961452525F, 0.9961694779F, 0.9961935913F, + 0.9962175930F, 0.9962414834F, 0.9962652627F, 0.9962889313F, + 0.9963124895F, 0.9963359377F, 0.9963592761F, 0.9963825051F, + 0.9964056250F, 0.9964286361F, 0.9964515387F, 0.9964743332F, + 0.9964970198F, 0.9965195990F, 0.9965420709F, 0.9965644360F, + 0.9965866946F, 0.9966088469F, 0.9966308932F, 0.9966528340F, + 0.9966746695F, 0.9966964001F, 0.9967180260F, 0.9967395475F, + 0.9967609651F, 0.9967822789F, 0.9968034894F, 0.9968245968F, + 0.9968456014F, 0.9968665036F, 0.9968873037F, 0.9969080019F, + 0.9969285987F, 0.9969490942F, 0.9969694889F, 0.9969897830F, + 0.9970099769F, 0.9970300708F, 0.9970500651F, 0.9970699601F, + 0.9970897561F, 0.9971094533F, 0.9971290522F, 0.9971485531F, + 0.9971679561F, 0.9971872617F, 0.9972064702F, 0.9972255818F, + 0.9972445968F, 0.9972635157F, 0.9972823386F, 0.9973010659F, + 0.9973196980F, 0.9973382350F, 0.9973566773F, 0.9973750253F, + 0.9973932791F, 0.9974114392F, 0.9974295059F, 0.9974474793F, + 0.9974653599F, 0.9974831480F, 0.9975008438F, 0.9975184476F, + 0.9975359598F, 0.9975533806F, 0.9975707104F, 0.9975879495F, + 0.9976050981F, 0.9976221566F, 0.9976391252F, 0.9976560043F, + 0.9976727941F, 0.9976894950F, 0.9977061073F, 0.9977226312F, + 0.9977390671F, 0.9977554152F, 0.9977716759F, 0.9977878495F, + 0.9978039361F, 0.9978199363F, 0.9978358501F, 0.9978516780F, + 0.9978674202F, 0.9978830771F, 0.9978986488F, 0.9979141358F, + 0.9979295383F, 0.9979448566F, 0.9979600909F, 0.9979752417F, + 0.9979903091F, 0.9980052936F, 0.9980201952F, 0.9980350145F, + 0.9980497515F, 0.9980644067F, 0.9980789804F, 0.9980934727F, + 0.9981078841F, 0.9981222147F, 0.9981364649F, 0.9981506350F, + 0.9981647253F, 0.9981787360F, 0.9981926674F, 0.9982065199F, + 0.9982202936F, 0.9982339890F, 0.9982476062F, 0.9982611456F, + 0.9982746074F, 0.9982879920F, 0.9983012996F, 0.9983145304F, + 0.9983276849F, 0.9983407632F, 0.9983537657F, 0.9983666926F, + 0.9983795442F, 0.9983923208F, 0.9984050226F, 0.9984176501F, + 0.9984302033F, 0.9984426827F, 0.9984550884F, 0.9984674208F, + 0.9984796802F, 0.9984918667F, 0.9985039808F, 0.9985160227F, + 0.9985279926F, 0.9985398909F, 0.9985517177F, 0.9985634734F, + 0.9985751583F, 0.9985867727F, 0.9985983167F, 0.9986097907F, + 0.9986211949F, 0.9986325297F, 0.9986437953F, 0.9986549919F, + 0.9986661199F, 0.9986771795F, 0.9986881710F, 0.9986990946F, + 0.9987099507F, 0.9987207394F, 0.9987314611F, 0.9987421161F, + 0.9987527045F, 0.9987632267F, 0.9987736829F, 0.9987840734F, + 0.9987943985F, 0.9988046584F, 0.9988148534F, 0.9988249838F, + 0.9988350498F, 0.9988450516F, 0.9988549897F, 0.9988648641F, + 0.9988746753F, 0.9988844233F, 0.9988941086F, 0.9989037313F, + 0.9989132918F, 0.9989227902F, 0.9989322269F, 0.9989416021F, + 0.9989509160F, 0.9989601690F, 0.9989693613F, 0.9989784931F, + 0.9989875647F, 0.9989965763F, 0.9990055283F, 0.9990144208F, + 0.9990232541F, 0.9990320286F, 0.9990407443F, 0.9990494016F, + 0.9990580008F, 0.9990665421F, 0.9990750257F, 0.9990834519F, + 0.9990918209F, 0.9991001331F, 0.9991083886F, 0.9991165877F, + 0.9991247307F, 0.9991328177F, 0.9991408491F, 0.9991488251F, + 0.9991567460F, 0.9991646119F, 0.9991724232F, 0.9991801801F, + 0.9991878828F, 0.9991955316F, 0.9992031267F, 0.9992106684F, + 0.9992181569F, 0.9992255925F, 0.9992329753F, 0.9992403057F, + 0.9992475839F, 0.9992548101F, 0.9992619846F, 0.9992691076F, + 0.9992761793F, 0.9992832001F, 0.9992901701F, 0.9992970895F, + 0.9993039587F, 0.9993107777F, 0.9993175470F, 0.9993242667F, + 0.9993309371F, 0.9993375583F, 0.9993441307F, 0.9993506545F, + 0.9993571298F, 0.9993635570F, 0.9993699362F, 0.9993762678F, + 0.9993825519F, 0.9993887887F, 0.9993949785F, 0.9994011216F, + 0.9994072181F, 0.9994132683F, 0.9994192725F, 0.9994252307F, + 0.9994311434F, 0.9994370107F, 0.9994428327F, 0.9994486099F, + 0.9994543423F, 0.9994600303F, 0.9994656739F, 0.9994712736F, + 0.9994768294F, 0.9994823417F, 0.9994878105F, 0.9994932363F, + 0.9994986191F, 0.9995039592F, 0.9995092568F, 0.9995145122F, + 0.9995197256F, 0.9995248971F, 0.9995300270F, 0.9995351156F, + 0.9995401630F, 0.9995451695F, 0.9995501352F, 0.9995550604F, + 0.9995599454F, 0.9995647903F, 0.9995695953F, 0.9995743607F, + 0.9995790866F, 0.9995837734F, 0.9995884211F, 0.9995930300F, + 0.9995976004F, 0.9996021324F, 0.9996066263F, 0.9996110822F, + 0.9996155004F, 0.9996198810F, 0.9996242244F, 0.9996285306F, + 0.9996327999F, 0.9996370326F, 0.9996412287F, 0.9996453886F, + 0.9996495125F, 0.9996536004F, 0.9996576527F, 0.9996616696F, + 0.9996656512F, 0.9996695977F, 0.9996735094F, 0.9996773865F, + 0.9996812291F, 0.9996850374F, 0.9996888118F, 0.9996925523F, + 0.9996962591F, 0.9996999325F, 0.9997035727F, 0.9997071798F, + 0.9997107541F, 0.9997142957F, 0.9997178049F, 0.9997212818F, + 0.9997247266F, 0.9997281396F, 0.9997315209F, 0.9997348708F, + 0.9997381893F, 0.9997414767F, 0.9997447333F, 0.9997479591F, + 0.9997511544F, 0.9997543194F, 0.9997574542F, 0.9997605591F, + 0.9997636342F, 0.9997666797F, 0.9997696958F, 0.9997726828F, + 0.9997756407F, 0.9997785698F, 0.9997814703F, 0.9997843423F, + 0.9997871860F, 0.9997900016F, 0.9997927894F, 0.9997955494F, + 0.9997982818F, 0.9998009869F, 0.9998036648F, 0.9998063157F, + 0.9998089398F, 0.9998115373F, 0.9998141082F, 0.9998166529F, + 0.9998191715F, 0.9998216642F, 0.9998241311F, 0.9998265724F, + 0.9998289884F, 0.9998313790F, 0.9998337447F, 0.9998360854F, + 0.9998384015F, 0.9998406930F, 0.9998429602F, 0.9998452031F, + 0.9998474221F, 0.9998496171F, 0.9998517885F, 0.9998539364F, + 0.9998560610F, 0.9998581624F, 0.9998602407F, 0.9998622962F, + 0.9998643291F, 0.9998663394F, 0.9998683274F, 0.9998702932F, + 0.9998722370F, 0.9998741589F, 0.9998760591F, 0.9998779378F, + 0.9998797952F, 0.9998816313F, 0.9998834464F, 0.9998852406F, + 0.9998870141F, 0.9998887670F, 0.9998904995F, 0.9998922117F, + 0.9998939039F, 0.9998955761F, 0.9998972285F, 0.9998988613F, + 0.9999004746F, 0.9999020686F, 0.9999036434F, 0.9999051992F, + 0.9999067362F, 0.9999082544F, 0.9999097541F, 0.9999112354F, + 0.9999126984F, 0.9999141433F, 0.9999155703F, 0.9999169794F, + 0.9999183709F, 0.9999197449F, 0.9999211014F, 0.9999224408F, + 0.9999237631F, 0.9999250684F, 0.9999263570F, 0.9999276289F, + 0.9999288843F, 0.9999301233F, 0.9999313461F, 0.9999325529F, + 0.9999337437F, 0.9999349187F, 0.9999360780F, 0.9999372218F, + 0.9999383503F, 0.9999394635F, 0.9999405616F, 0.9999416447F, + 0.9999427129F, 0.9999437665F, 0.9999448055F, 0.9999458301F, + 0.9999468404F, 0.9999478365F, 0.9999488185F, 0.9999497867F, + 0.9999507411F, 0.9999516819F, 0.9999526091F, 0.9999535230F, + 0.9999544236F, 0.9999553111F, 0.9999561856F, 0.9999570472F, + 0.9999578960F, 0.9999587323F, 0.9999595560F, 0.9999603674F, + 0.9999611666F, 0.9999619536F, 0.9999627286F, 0.9999634917F, + 0.9999642431F, 0.9999649828F, 0.9999657110F, 0.9999664278F, + 0.9999671334F, 0.9999678278F, 0.9999685111F, 0.9999691835F, + 0.9999698451F, 0.9999704960F, 0.9999711364F, 0.9999717662F, + 0.9999723858F, 0.9999729950F, 0.9999735942F, 0.9999741834F, + 0.9999747626F, 0.9999753321F, 0.9999758919F, 0.9999764421F, + 0.9999769828F, 0.9999775143F, 0.9999780364F, 0.9999785495F, + 0.9999790535F, 0.9999795485F, 0.9999800348F, 0.9999805124F, + 0.9999809813F, 0.9999814417F, 0.9999818938F, 0.9999823375F, + 0.9999827731F, 0.9999832005F, 0.9999836200F, 0.9999840316F, + 0.9999844353F, 0.9999848314F, 0.9999852199F, 0.9999856008F, + 0.9999859744F, 0.9999863407F, 0.9999866997F, 0.9999870516F, + 0.9999873965F, 0.9999877345F, 0.9999880656F, 0.9999883900F, + 0.9999887078F, 0.9999890190F, 0.9999893237F, 0.9999896220F, + 0.9999899140F, 0.9999901999F, 0.9999904796F, 0.9999907533F, + 0.9999910211F, 0.9999912830F, 0.9999915391F, 0.9999917896F, + 0.9999920345F, 0.9999922738F, 0.9999925077F, 0.9999927363F, + 0.9999929596F, 0.9999931777F, 0.9999933907F, 0.9999935987F, + 0.9999938018F, 0.9999940000F, 0.9999941934F, 0.9999943820F, + 0.9999945661F, 0.9999947456F, 0.9999949206F, 0.9999950912F, + 0.9999952575F, 0.9999954195F, 0.9999955773F, 0.9999957311F, + 0.9999958807F, 0.9999960265F, 0.9999961683F, 0.9999963063F, + 0.9999964405F, 0.9999965710F, 0.9999966979F, 0.9999968213F, + 0.9999969412F, 0.9999970576F, 0.9999971707F, 0.9999972805F, + 0.9999973871F, 0.9999974905F, 0.9999975909F, 0.9999976881F, + 0.9999977824F, 0.9999978738F, 0.9999979624F, 0.9999980481F, + 0.9999981311F, 0.9999982115F, 0.9999982892F, 0.9999983644F, + 0.9999984370F, 0.9999985072F, 0.9999985750F, 0.9999986405F, + 0.9999987037F, 0.9999987647F, 0.9999988235F, 0.9999988802F, + 0.9999989348F, 0.9999989873F, 0.9999990379F, 0.9999990866F, + 0.9999991334F, 0.9999991784F, 0.9999992217F, 0.9999992632F, + 0.9999993030F, 0.9999993411F, 0.9999993777F, 0.9999994128F, + 0.9999994463F, 0.9999994784F, 0.9999995091F, 0.9999995384F, + 0.9999995663F, 0.9999995930F, 0.9999996184F, 0.9999996426F, + 0.9999996657F, 0.9999996876F, 0.9999997084F, 0.9999997282F, + 0.9999997469F, 0.9999997647F, 0.9999997815F, 0.9999997973F, + 0.9999998123F, 0.9999998265F, 0.9999998398F, 0.9999998524F, + 0.9999998642F, 0.9999998753F, 0.9999998857F, 0.9999998954F, + 0.9999999045F, 0.9999999130F, 0.9999999209F, 0.9999999282F, + 0.9999999351F, 0.9999999414F, 0.9999999472F, 0.9999999526F, + 0.9999999576F, 0.9999999622F, 0.9999999664F, 0.9999999702F, + 0.9999999737F, 0.9999999769F, 0.9999999798F, 0.9999999824F, + 0.9999999847F, 0.9999999868F, 0.9999999887F, 0.9999999904F, + 0.9999999919F, 0.9999999932F, 0.9999999943F, 0.9999999953F, + 0.9999999961F, 0.9999999969F, 0.9999999975F, 0.9999999980F, + 0.9999999985F, 0.9999999988F, 0.9999999991F, 0.9999999993F, + 0.9999999995F, 0.9999999997F, 0.9999999998F, 0.9999999999F, + 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, + 1.0000000000F, 1.0000000000F, 1.0000000000F, 1.0000000000F, +}; + +const float ff_vorbis_floor1_inverse_db_table[256]={ + 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, + 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, + 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, + 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, + 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, + 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, + 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, + 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, + 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, + 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, + 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, + 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, + 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, + 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, + 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, + 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, + 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, + 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, + 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, + 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, + 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, + 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, + 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, + 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, + 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, + 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, + 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, + 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, + 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, + 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, + 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, + 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, + 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, + 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, + 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, + 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, + 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, + 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, + 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, + 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, + 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, + 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, + 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, + 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, + 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, + 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, + 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, + 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, + 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, + 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, + 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, + 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, + 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, + 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, + 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, + 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, + 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, + 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, + 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, + 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, + 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, + 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, + 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, + 0.82788260F, 0.88168307F, 0.9389798F, 1.F, +}; + +const float * const ff_vorbis_vwin[8] = { + vwin64, vwin128, vwin256, vwin512, + vwin1024, vwin2048, vwin4096, vwin8192 +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_enc_data.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_enc_data.h new file mode 100644 index 000000000..a51aaec97 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_enc_data.h @@ -0,0 +1,504 @@ +/* + * copyright (c) 2006 Oded Shimon + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VORBIS_ENC_DATA_H +#define AVCODEC_VORBIS_ENC_DATA_H + +#include + +static const uint8_t codebook0[] = { + 2, 10, 8, 14, 7, 12, 11, 14, 1, 5, 3, 7, 4, 9, 7, 13, +}; + +static const uint8_t codebook1[] = { + 1, 4, 2, 6, 3, 7, 5, 7, +}; + +static const uint8_t codebook2[] = { + 1, 5, 7, 21, 5, 8, 9, 21, 10, 9, 12, 20, 20, 16, 20, + 20, 4, 8, 9, 20, 6, 8, 9, 20, 11, 11, 13, 20, 20, 15, + 17, 20, 9, 11, 14, 20, 8, 10, 15, 20, 11, 13, 15, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 13, 20, 20, 20, 18, 18, 20, 20, + 20, 20, 20, 20, 3, 6, 8, 20, 6, 7, 9, 20, 10, 9, 12, + 20, 20, 20, 20, 20, 5, 7, 9, 20, 6, 6, 9, 20, 10, 9, + 12, 20, 20, 20, 20, 20, 8, 10, 13, 20, 8, 9, 12, 20, 11, + 10, 12, 20, 20, 20, 20, 20, 18, 20, 20, 20, 15, 17, 18, 20, + 18, 17, 18, 20, 20, 20, 20, 20, 7, 10, 12, 20, 8, 9, 11, + 20, 14, 13, 14, 20, 20, 20, 20, 20, 6, 9, 12, 20, 7, 8, + 11, 20, 12, 11, 13, 20, 20, 20, 20, 20, 9, 11, 15, 20, 8, + 10, 14, 20, 12, 11, 14, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 11, 16, 18, + 20, 15, 15, 17, 20, 20, 17, 20, 20, 20, 20, 20, 20, 9, 14, + 16, 20, 12, 12, 15, 20, 17, 15, 18, 20, 20, 20, 20, 20, 16, + 19, 18, 20, 15, 16, 20, 20, 17, 17, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, +}; + +static const uint8_t codebook3[] = { + 2, 3, 7, 13, 4, 4, 7, 15, 8, 6, 9, 17, 21, 16, 15, + 21, 2, 5, 7, 11, 5, 5, 7, 14, 9, 7, 10, 16, 17, 15, + 16, 21, 4, 7, 10, 17, 7, 7, 9, 15, 11, 9, 11, 16, 21, + 18, 15, 21, 18, 21, 21, 21, 15, 17, 17, 19, 21, 19, 18, 20, + 21, 21, 21, 20, +}; + +static const uint8_t codebook4[] = { + 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, + 5, 6, 5, 6, 5, 6, 5, 6, 5, 7, 5, 7, 5, 7, 5, + 7, 5, 8, 6, 8, 6, 8, 6, 9, 6, 9, 6, 10, 6, 10, + 6, 11, 6, 11, 7, 11, 7, 12, 7, 12, 7, 12, 7, 12, 7, + 12, 7, 12, 7, 12, 7, 12, 8, 13, 8, 12, 8, 12, 8, 13, + 8, 13, 9, 13, 9, 13, 9, 13, 9, 12, 10, 12, 10, 13, 10, + 14, 11, 14, 12, 14, 13, 14, 13, 14, 14, 15, 16, 15, 15, 15, + 14, 15, 17, 21, 22, 22, 21, 22, 22, 22, 22, 22, 22, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, +}; + +static const uint8_t codebook5[] = { + 2, 5, 5, 4, 5, 4, 5, 4, 5, 4, 6, 5, 6, 5, 6, + 5, 6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 6, 9, 6, + 9, 6, +}; + +static const uint8_t codebook6[] = { + 8, 5, 8, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, + 4, 9, 4, 9, 4, 9, 4, 8, 4, 8, 4, 9, 5, 9, 5, + 9, 5, 9, 5, 9, 6, 10, 6, 10, 7, 10, 8, 11, 9, 11, + 11, 12, 13, 12, 14, 13, 15, 13, 15, 14, 16, 14, 17, 15, 17, + 15, 15, 16, 16, 15, 16, 16, 16, 15, 18, 16, 15, 17, 17, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, +}; + +static const uint8_t codebook7[] = { + 1, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, + 5, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 9, 8, 10, 9, + 10, 9, +}; + +static const uint8_t codebook8[] = { + 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 5, 5, 6, 5, 6, + 5, 7, 5, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 9, 8, + 9, 9, 9, 9, 10, 10, 10, 11, 9, 12, 9, 12, 9, 15, 10, + 14, 9, 13, 10, 13, 10, 12, 10, 12, 10, 13, 10, 12, 11, 13, + 11, 14, 12, 13, 13, 14, 14, 13, 14, 15, 14, 16, 13, 13, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 15, 15, +}; + +static const uint8_t codebook9[] = { + 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4, 4, 5, + 5, 5, +}; + +static const uint8_t codebook10[] = { + 3, 3, 4, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 5, + 7, 5, 8, 6, 8, 6, 9, 7, 10, 7, 10, 8, 10, 8, 11, + 9, 11, +}; + +static const uint8_t codebook11[] = { + 3, 7, 3, 8, 3, 10, 3, 8, 3, 9, 3, 8, 4, 9, 4, + 9, 5, 9, 6, 10, 6, 9, 7, 11, 7, 12, 9, 13, 10, 13, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, +}; + +static const uint8_t codebook12[] = { + 4, 5, 4, 5, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, + 5, 4, +}; + +static const uint8_t codebook13[] = { + 4, 2, 4, 2, 5, 3, 5, 4, 6, 6, 6, 7, 7, 8, 7, + 8, 7, 8, 7, 9, 8, 9, 8, 9, 8, 10, 8, 11, 9, 12, + 9, 12, +}; + +static const uint8_t codebook14[] = { + 2, 5, 2, 6, 3, 6, 4, 7, 4, 7, 5, 9, 5, 11, 6, + 11, 6, 11, 7, 11, 6, 11, 6, 11, 9, 11, 8, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, + 10, 10, 10, +}; + +static const uint8_t codebook15[] = { + 5, 6, 11, 11, 11, 11, 10, 10, 12, 11, 5, 2, 11, 5, 6, + 6, 7, 9, 11, 13, 13, 10, 7, 11, 6, 7, 8, 9, 10, 12, + 11, 5, 11, 6, 8, 7, 9, 11, 14, 15, 11, 6, 6, 8, 4, + 5, 7, 8, 10, 13, 10, 5, 7, 7, 5, 5, 6, 8, 10, 11, + 10, 7, 7, 8, 6, 5, 5, 7, 9, 9, 11, 8, 8, 11, 8, + 7, 6, 6, 7, 9, 12, 11, 10, 13, 9, 9, 7, 7, 7, 9, + 11, 13, 12, 15, 12, 11, 9, 8, 8, 8, +}; + +static const uint8_t codebook16[] = { + 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, + 0, 0, 0, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, + 7, 8, 8, 0, 0, 0, 0, 0, 0, 6, 7, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, + 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0, 0, 0, 0, 0, + 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, + 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, + 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, + 7, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, + 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, 0, + 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 7, 8, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, + 0, 0, 0, 8, 9, 8, +}; + +static const uint8_t codebook17[] = { + 2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, + 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, + 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 10, 10, 0, 0, + 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, + 0, 7, 7, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, + 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, + 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 10, 0, 0, + 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0, 10, 10, 0, 0, + 0, 0, 0, 0, 0, 8, 10, 10, 0, 0, 0, 9, 9, 0, 0, + 0, 9, 9, 0, 0, 0, 10, 10, +}; + +static const uint8_t codebook18[] = { + 2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 6, 6, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 7, 9, 9, +}; + +static const uint8_t codebook19[] = { + 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, + 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, + 6, 6, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, + 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, + 0, 0, 0, 0, 0, 0, 9, 9, +}; + +static const uint8_t codebook20[] = { + 1, 3, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 7, + 8, 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, + 8, 8, 8, 8, 10, 10, 0, 0, 0, 8, 8, 8, 8, 10, 10, + 0, 0, 0, 9, 9, 9, 9, 10, 10, 0, 0, 0, 9, 9, 9, + 9, 10, 10, 0, 0, 0, 10, 10, 10, 10, 11, 11, 0, 0, 0, + 0, 0, 10, 10, 11, 11, +}; + +static const uint8_t codebook21[] = { + 2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, + 11, 10, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9, 10, 10, + 10, 10, 11, 11, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9, + 10, 10, 10, 10, 11, 11, 0, 6, 6, 7, 7, 8, 8, 9, 9, + 9, 9, 10, 10, 11, 11, 11, 11, 0, 0, 0, 7, 7, 8, 8, + 9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 0, 0, 0, 8, 8, + 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 0, 0, 0, + 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 0, + 0, 0, 9, 9, 9, 9, 10, 10, 10, 10, 11, 10, 11, 11, 12, + 12, 0, 0, 0, 0, 0, 9, 9, 10, 10, 10, 10, 11, 11, 11, + 11, 12, 12, 0, 0, 0, 0, 0, 9, 8, 9, 9, 10, 10, 11, + 11, 12, 12, 12, 12, 0, 0, 0, 0, 0, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 11, 12, 12, 0, 0, 0, 0, 0, 9, 10, 10, + 10, 11, 11, 11, 11, 12, 12, 13, 13, 0, 0, 0, 0, 0, 0, + 0, 10, 10, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0, 0, 0, + 0, 0, 0, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 0, 0, + 0, 0, 0, 0, 0, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, + 0, 0, 0, 0, 0, 0, 0, 11, 11, 12, 12, 12, 12, 13, 13, + 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 12, + 13, 13, 13, 13, +}; + +static const uint8_t codebook22[] = { + 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7, 10, 9, 9, + 11, 9, 9, 4, 7, 7, 10, 9, 9, 11, 9, 9, 7, 10, 10, + 11, 11, 10, 12, 11, 11, 6, 9, 9, 11, 10, 10, 11, 10, 10, + 6, 9, 9, 11, 10, 10, 11, 10, 10, 7, 11, 11, 11, 11, 11, + 12, 11, 11, 6, 9, 9, 11, 10, 10, 11, 10, 10, 6, 9, 9, + 11, 10, 10, 11, 10, 10, +}; + +static const uint8_t codebook23[] = { + 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 10, 5, 5, 6, + 6, 7, 7, 8, 8, 8, 8, 10, 5, 5, 6, 6, 7, 7, 8, + 8, 8, 8, 10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 10, + 10, 10, 7, 7, 8, 7, 8, 8, 8, 8, 10, 10, 10, 8, 8, + 8, 8, 8, 8, 8, 8, 10, 10, 10, 7, 8, 8, 8, 8, 8, + 8, 8, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, + 10, 10, 10, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 9, + 9, 8, 8, 9, 8, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, + 8, +}; + +static const uint8_t codebook24[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 6, 5, + 5, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, 7, 5, 5, 7, + 7, 8, 8, 8, 8, 9, 9, 11, 10, 0, 8, 8, 8, 8, 9, + 9, 9, 9, 10, 10, 11, 11, 0, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 11, 11, 0, 12, 12, 9, 9, 10, 10, 10, 10, 11, + 11, 11, 12, 0, 13, 13, 9, 9, 10, 10, 10, 10, 11, 11, 12, + 12, 0, 0, 0, 10, 10, 10, 10, 11, 11, 12, 12, 12, 12, 0, + 0, 0, 10, 10, 10, 10, 11, 11, 12, 12, 12, 12, 0, 0, 0, + 14, 14, 11, 11, 11, 11, 12, 12, 13, 13, 0, 0, 0, 14, 14, + 11, 11, 11, 11, 12, 12, 13, 13, 0, 0, 0, 0, 0, 12, 12, + 12, 12, 13, 13, 14, 13, 0, 0, 0, 0, 0, 13, 13, 12, 12, + 13, 12, 14, 13, +}; + +static const uint8_t codebook25[] = { + 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, + 6, 5, 5, 5, 5, 6, 6, 6, 5, 5, +}; + +static const uint8_t codebook26[] = { + 1, 4, 4, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 9, + 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 9, 7, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, +}; + +static const uint8_t codebook27[] = { + 1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 9, 10, 10, 10, 10, + 6, 5, 5, 7, 7, 8, 8, 10, 8, 11, 10, 12, 12, 13, 13, + 6, 5, 5, 7, 7, 8, 8, 10, 9, 11, 11, 12, 12, 13, 12, + 18, 8, 8, 8, 8, 9, 9, 10, 9, 11, 10, 12, 12, 13, 13, + 18, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 13, 12, 14, 13, + 18, 11, 11, 9, 9, 10, 10, 11, 11, 11, 12, 13, 12, 13, 14, + 18, 11, 11, 9, 8, 11, 10, 11, 11, 11, 11, 12, 12, 14, 13, + 18, 18, 18, 10, 11, 10, 11, 12, 12, 12, 12, 13, 12, 14, 13, + 18, 18, 18, 10, 11, 11, 9, 12, 11, 12, 12, 12, 13, 13, 13, + 18, 18, 17, 14, 14, 11, 11, 12, 12, 13, 12, 14, 12, 14, 13, + 18, 18, 18, 14, 14, 11, 10, 12, 9, 12, 13, 13, 13, 13, 13, + 18, 18, 17, 16, 18, 13, 13, 12, 12, 13, 11, 14, 12, 14, 14, + 17, 18, 18, 17, 18, 13, 12, 13, 10, 12, 11, 14, 14, 14, 14, + 17, 18, 18, 18, 18, 15, 16, 12, 12, 13, 10, 14, 12, 14, 15, + 18, 18, 18, 16, 17, 16, 14, 12, 11, 13, 10, 13, 13, 14, 15, +}; + +static const uint8_t codebook28[] = { + 2, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 10, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 8, 9, + 9, 9, 9, 9, 10, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 10, 7, 7, 7, 7, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 7, 7, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, + 10, 10, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, + 9, 10, 10, 10, 11, 11, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 11, 10, 11, 11, 11, 9, 9, 9, 9, 9, 9, 10, + 10, 9, 9, 10, 9, 11, 10, 11, 11, 11, 9, 9, 9, 9, 9, + 9, 9, 9, 10, 10, 10, 9, 11, 11, 11, 11, 11, 9, 9, 9, + 9, 10, 10, 9, 9, 9, 9, 10, 9, 11, 11, 11, 11, 11, 11, + 11, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, + 11, 11, 11, 10, 9, 10, 10, 9, 10, 9, 9, 10, 9, 11, 10, + 10, 11, 11, 11, 11, 9, 10, 9, 9, 9, 9, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 10, 10, 10, 9, 9, 10, 9, 10, 9, + 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 9, 9, 9, 9, + 9, 10, 10, 10, +}; + +static const struct { + int dim; + int len; + int real_len; + const uint8_t *clens; + int lookup; + float min; + float delta; + const uint8_t *quant; +} cvectors[] = { + { 2, 16, 16, codebook0, 0 }, + { 2, 8, 8, codebook1, 0 }, + { 2, 256, 256, codebook2, 0 }, + { 2, 64, 64, codebook3, 0 }, + { 2, 128, 128, codebook4, 0 }, + { 2, 32, 32, codebook5, 0 }, + { 2, 96, 96, codebook6, 0 }, + { 2, 32, 32, codebook7, 0 }, + { 2, 96, 96, codebook8, 0 }, + { 2, 17, 17, codebook9, 0 }, + { 2, 32, 32, codebook10, 0 }, + { 2, 78, 78, codebook11, 0 }, + { 2, 17, 17, codebook12, 0 }, + { 2, 32, 32, codebook13, 0 }, + { 2, 78, 78, codebook14, 0 }, + { 2, 100, 100, codebook15, 0 }, + { 8, 1641, 6561, codebook16, 1, -1.0, 1.0, (const uint8_t[]){ 1, 0, 2, } }, + { 4, 443, 625, codebook17, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, + { 4, 105, 625, codebook18, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, + { 2, 68, 81, codebook19, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } }, + { 2, 81, 81, codebook20, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } }, + { 2, 289, 289, codebook21, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } }, + { 4, 81, 81, codebook22, 1, -11.0, 11.0, (const uint8_t[]){ 1, 0, 2, } }, + { 2, 121, 121, codebook23, 1, -5.0, 1.0, (const uint8_t[]){ 5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10, } }, + { 2, 169, 169, codebook24, 1, -30.0, 5.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } }, + { 2, 25, 25, codebook25, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, + { 2, 169, 169, codebook26, 1, -1530.0, 255.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } }, + { 2, 225, 225, codebook27, 1, -119.0, 17.0, (const uint8_t[]){ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13, 0, 14, } }, + { 2, 289, 289, codebook28, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } }, +}; + +static const struct { + int dim; + int subclass; + int masterbook; + const int nbooks[4]; +} floor_classes[] = { + { 3, 0, 0, { 4 } }, + { 4, 1, 0, { 5, 6 } }, + { 3, 1, 1, { 7, 8 } }, + { 4, 2, 2, { -1, 9, 10, 11 } }, + { 3, 2, 3, { -1, 12, 13, 14 } }, +}; + +#endif /* AVCODEC_VORBIS_ENC_DATA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser.c new file mode 100644 index 000000000..0b2c97cde --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Vorbis audio parser + * + * Determines the duration for each packet. + */ + +#include "libavutil/log.h" + +#include "get_bits.h" +#include "parser.h" +#include "xiph.h" +#include "vorbis_parser_internal.h" + +static const AVClass vorbis_parser_class = { + .class_name = "Vorbis parser", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +static int parse_id_header(AVVorbisParseContext *s, + const uint8_t *buf, int buf_size) +{ + /* Id header should be 30 bytes */ + if (buf_size < 30) { + av_log(s, AV_LOG_ERROR, "Id header is too short\n"); + return AVERROR_INVALIDDATA; + } + + /* make sure this is the Id header */ + if (buf[0] != 1) { + av_log(s, AV_LOG_ERROR, "Wrong packet type in Id header\n"); + return AVERROR_INVALIDDATA; + } + + /* check for header signature */ + if (memcmp(&buf[1], "vorbis", 6)) { + av_log(s, AV_LOG_ERROR, "Invalid packet signature in Id header\n"); + return AVERROR_INVALIDDATA; + } + + if (!(buf[29] & 0x1)) { + av_log(s, AV_LOG_ERROR, "Invalid framing bit in Id header\n"); + return AVERROR_INVALIDDATA; + } + + s->blocksize[0] = 1 << (buf[28] & 0xF); + s->blocksize[1] = 1 << (buf[28] >> 4); + + return 0; +} + +static int parse_setup_header(AVVorbisParseContext *s, + const uint8_t *buf, int buf_size) +{ + GetBitContext gb, gb0; + uint8_t *rev_buf; + int i, ret = 0; + int got_framing_bit, mode_count, got_mode_header, last_mode_count = 0; + + /* avoid overread */ + if (buf_size < 7) { + av_log(s, AV_LOG_ERROR, "Setup header is too short\n"); + return AVERROR_INVALIDDATA; + } + + /* make sure this is the Setup header */ + if (buf[0] != 5) { + av_log(s, AV_LOG_ERROR, "Wrong packet type in Setup header\n"); + return AVERROR_INVALIDDATA; + } + + /* check for header signature */ + if (memcmp(&buf[1], "vorbis", 6)) { + av_log(s, AV_LOG_ERROR, "Invalid packet signature in Setup header\n"); + return AVERROR_INVALIDDATA; + } + + /* reverse bytes so we can easily read backwards with get_bits() */ + if (!(rev_buf = av_malloc(buf_size))) { + av_log(s, AV_LOG_ERROR, "Out of memory\n"); + return AVERROR(ENOMEM); + } + for (i = 0; i < buf_size; i++) + rev_buf[i] = buf[buf_size - 1 - i]; + init_get_bits(&gb, rev_buf, buf_size * 8); + + got_framing_bit = 0; + while (get_bits_left(&gb) > 97) { + if (get_bits1(&gb)) { + got_framing_bit = get_bits_count(&gb); + break; + } + } + if (!got_framing_bit) { + av_log(s, AV_LOG_ERROR, "Invalid Setup header\n"); + ret = AVERROR_INVALIDDATA; + goto bad_header; + } + + /* Now we search backwards to find possible valid mode counts. This is not + * fool-proof because we could have false positive matches and read too + * far, but there isn't really any way to be sure without parsing through + * all the many variable-sized fields before the modes. This approach seems + * to work well in testing, and it is similar to how it is handled in + * liboggz. */ + mode_count = 0; + got_mode_header = 0; + while (get_bits_left(&gb) >= 97) { + if (get_bits(&gb, 8) > 63 || get_bits(&gb, 16) || get_bits(&gb, 16)) + break; + skip_bits(&gb, 1); + mode_count++; + if (mode_count > 64) + break; + gb0 = gb; + if (get_bits(&gb0, 6) + 1 == mode_count) { + got_mode_header = 1; + last_mode_count = mode_count; + } + } + if (!got_mode_header) { + av_log(s, AV_LOG_ERROR, "Invalid Setup header\n"); + ret = AVERROR_INVALIDDATA; + goto bad_header; + } + /* All samples I've seen use <= 2 modes, so ask for a sample if we find + * more than that, as it is most likely a false positive. If we get any + * we may need to approach this the long way and parse the whole Setup + * header, but I hope very much that it never comes to that. */ + if (last_mode_count > 2) { + avpriv_request_sample(s, + "%d modes (either a false positive or a " + "sample from an unknown encoder)", + last_mode_count); + } + /* We're limiting the mode count to 63 so that we know that the previous + * block flag will be in the first packet byte. */ + if (last_mode_count > 63) { + av_log(s, AV_LOG_ERROR, "Unsupported mode count: %d\n", + last_mode_count); + ret = AVERROR_INVALIDDATA; + goto bad_header; + } + s->mode_count = mode_count = last_mode_count; + /* Determine the number of bits required to code the mode and turn that + * into a bitmask to directly access the mode from the first frame byte. */ + s->mode_mask = ((1 << (av_log2(mode_count - 1) + 1)) - 1) << 1; + /* The previous window flag is the next bit after the mode */ + s->prev_mask = (s->mode_mask | 0x1) + 1; + + init_get_bits(&gb, rev_buf, buf_size * 8); + skip_bits_long(&gb, got_framing_bit); + for (i = mode_count - 1; i >= 0; i--) { + skip_bits_long(&gb, 40); + s->mode_blocksize[i] = get_bits1(&gb); + } + +bad_header: + av_free(rev_buf); + return ret; +} + +static int vorbis_parse_init(AVVorbisParseContext *s, + const uint8_t *extradata, int extradata_size) +{ + const uint8_t *header_start[3]; + int header_len[3]; + int ret; + + s->class = &vorbis_parser_class; + s->extradata_parsed = 1; + + if ((ret = avpriv_split_xiph_headers(extradata, + extradata_size, 30, + header_start, header_len)) < 0) { + av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n"); + return ret; + } + + if ((ret = parse_id_header(s, header_start[0], header_len[0])) < 0) + return ret; + + if ((ret = parse_setup_header(s, header_start[2], header_len[2])) < 0) + return ret; + + s->valid_extradata = 1; + s->previous_blocksize = s->blocksize[s->mode_blocksize[0]]; + + return 0; +} + +int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf, + int buf_size, int *flags) +{ + int duration = 0; + + if (s->valid_extradata && buf_size > 0) { + int mode, current_blocksize; + int previous_blocksize = s->previous_blocksize; + + if (buf[0] & 1) { + /* If the user doesn't care about special packets, it's a bad one. */ + if (!flags) + goto bad_packet; + + /* Set the flag for which kind of special packet it is. */ + if (buf[0] == 1) + *flags |= VORBIS_FLAG_HEADER; + else if (buf[0] == 3) + *flags |= VORBIS_FLAG_COMMENT; + else if (buf[0] == 5) + *flags |= VORBIS_FLAG_SETUP; + else + goto bad_packet; + + /* Special packets have no duration. */ + return 0; + +bad_packet: + av_log(s, AV_LOG_ERROR, "Invalid packet\n"); + return AVERROR_INVALIDDATA; + } + if (s->mode_count == 1) + mode = 0; + else + mode = (buf[0] & s->mode_mask) >> 1; + if (mode >= s->mode_count) { + av_log(s, AV_LOG_ERROR, "Invalid mode in packet\n"); + return AVERROR_INVALIDDATA; + } + if(s->mode_blocksize[mode]){ + int flag = !!(buf[0] & s->prev_mask); + previous_blocksize = s->blocksize[flag]; + } + current_blocksize = s->blocksize[s->mode_blocksize[mode]]; + duration = (previous_blocksize + current_blocksize) >> 2; + s->previous_blocksize = current_blocksize; + } + + return duration; +} + +int av_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf, + int buf_size) +{ + return av_vorbis_parse_frame_flags(s, buf, buf_size, NULL); +} + +void av_vorbis_parse_reset(AVVorbisParseContext *s) +{ + if (s->valid_extradata) + s->previous_blocksize = s->blocksize[0]; +} + +void av_vorbis_parse_free(AVVorbisParseContext **s) +{ + av_freep(s); +} + +AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata, + int extradata_size) +{ + AVVorbisParseContext *s = av_mallocz(sizeof(*s)); + int ret; + + if (!s) + return NULL; + + ret = vorbis_parse_init(s, extradata, extradata_size); + if (ret < 0) { + av_vorbis_parse_free(&s); + return NULL; + } + + return s; +} + +#if CONFIG_VORBIS_PARSER + +typedef struct VorbisParseContext { + AVVorbisParseContext *vp; +} VorbisParseContext; + +static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + VorbisParseContext *s = s1->priv_data; + int duration; + + if (!s->vp && avctx->extradata && avctx->extradata_size) { + s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size); + } + if (!s->vp) + goto end; + + if ((duration = av_vorbis_parse_frame(s->vp, buf, buf_size)) >= 0) + s1->duration = duration; + +end: + /* always return the full packet. this parser isn't doing any splitting or + combining, only packet analysis */ + *poutbuf = buf; + *poutbuf_size = buf_size; + return buf_size; +} + +static void vorbis_parser_close(AVCodecParserContext *ctx) +{ + VorbisParseContext *s = ctx->priv_data; + av_vorbis_parse_free(&s->vp); +} + +AVCodecParser ff_vorbis_parser = { + .codec_ids = { AV_CODEC_ID_VORBIS }, + .priv_data_size = sizeof(VorbisParseContext), + .parser_parse = vorbis_parse, + .parser_close = vorbis_parser_close, +}; +#endif /* CONFIG_VORBIS_PARSER */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser.h new file mode 100644 index 000000000..789932ac4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser.h @@ -0,0 +1,74 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * A public API for Vorbis parsing + * + * Determines the duration for each packet. + */ + +#ifndef AVCODEC_VORBIS_PARSER_H +#define AVCODEC_VORBIS_PARSER_H + +#include + +typedef struct AVVorbisParseContext AVVorbisParseContext; + +/** + * Allocate and initialize the Vorbis parser using headers in the extradata. + */ +AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata, + int extradata_size); + +/** + * Free the parser and everything associated with it. + */ +void av_vorbis_parse_free(AVVorbisParseContext **s); + +#define VORBIS_FLAG_HEADER 0x00000001 +#define VORBIS_FLAG_COMMENT 0x00000002 +#define VORBIS_FLAG_SETUP 0x00000004 + +/** + * Get the duration for a Vorbis packet. + * + * If @p flags is @c NULL, + * special frames are considered invalid. + * + * @param s Vorbis parser context + * @param buf buffer containing a Vorbis frame + * @param buf_size size of the buffer + * @param flags flags for special frames + */ +int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf, + int buf_size, int *flags); + +/** + * Get the duration for a Vorbis packet. + * + * @param s Vorbis parser context + * @param buf buffer containing a Vorbis frame + * @param buf_size size of the buffer + */ +int av_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf, + int buf_size); + +void av_vorbis_parse_reset(AVVorbisParseContext *s); + +#endif /* AVCODEC_VORBIS_PARSER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser_internal.h new file mode 100644 index 000000000..691a84238 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbis_parser_internal.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Vorbis audio parser + * + * Determines the duration for each packet. + */ + +#ifndef AVCODEC_VORBIS_PARSER_INTERNAL_H +#define AVCODEC_VORBIS_PARSER_INTERNAL_H + +#include "avcodec.h" +#include "vorbis_parser.h" + +struct AVVorbisParseContext { + const AVClass *class; + int extradata_parsed; ///< we have attempted to parse extradata + int valid_extradata; ///< extradata is valid, so we can calculate duration + int blocksize[2]; ///< short and long window sizes + int previous_blocksize; ///< previous window size + int mode_blocksize[64]; ///< window size mapping for each mode + int mode_count; ///< number of modes + int mode_mask; ///< bitmask used to get the mode in each packet + int prev_mask; ///< bitmask used to get the previous mode flag in each packet +}; + +#endif /* AVCODEC_VORBIS_PARSER_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbisdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbisdsp.h new file mode 100644 index 000000000..7abec4e4b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/vorbisdsp.h @@ -0,0 +1,38 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VORBISDSP_H +#define AVCODEC_VORBISDSP_H + +#include + +typedef struct VorbisDSPContext { + /* assume len is a multiple of 4, and arrays are 16-byte aligned */ + void (*vorbis_inverse_coupling)(float *mag, float *ang, + intptr_t blocksize); +} VorbisDSPContext; + +void ff_vorbisdsp_init(VorbisDSPContext *dsp); + +/* for internal use only */ +void ff_vorbisdsp_init_aarch64(VorbisDSPContext *dsp); +void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp); +void ff_vorbisdsp_init_arm(VorbisDSPContext *dsp); +void ff_vorbisdsp_init_ppc(VorbisDSPContext *dsp); + +#endif /* AVCODEC_VORBISDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacencdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacencdsp_init.c new file mode 100644 index 000000000..d761c3c5e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacencdsp_init.c @@ -0,0 +1,43 @@ +/* + * AAC encoder assembly optimizations + * Copyright (C) 2016 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/float_dsp.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/aacenc.h" + +void ff_abs_pow34_sse(float *out, const float *in, const int size); + +void ff_aac_quantize_bands_sse2(int *out, const float *in, const float *scaled, + int size, int is_signed, int maxval, const float Q34, + const float rounding); + +av_cold void ff_aac_dsp_init_x86(AACEncContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) + s->abs_pow34 = ff_abs_pow34_sse; + + if (EXTERNAL_SSE2(cpu_flags)) + s->quant_bands = ff_aac_quantize_bands_sse2; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacpsdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacpsdsp_init.c new file mode 100644 index 000000000..21f00efa2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacpsdsp_init.c @@ -0,0 +1,72 @@ +/* + * SIMD optimized MPEG-4 Parametric Stereo decoding functions + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" + +#include "libavutil/x86/cpu.h" +#include "libavutil/attributes.h" +#include "libavcodec/aacpsdsp.h" + +void ff_ps_add_squares_sse (float *dst, const float (*src)[2], int n); +void ff_ps_add_squares_sse3 (float *dst, const float (*src)[2], int n); +void ff_ps_mul_pair_single_sse (float (*dst)[2], float (*src0)[2], + float *src1, int n); +void ff_ps_hybrid_analysis_sse (float (*out)[2], float (*in)[2], + const float (*filter)[8][2], + ptrdiff_t stride, int n); +void ff_ps_hybrid_analysis_sse3(float (*out)[2], float (*in)[2], + const float (*filter)[8][2], + ptrdiff_t stride, int n); +void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len); +void ff_ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len); +void ff_ps_hybrid_synthesis_deint_sse(float out[2][38][64], float (*in)[32][2], + int i, int len); +void ff_ps_hybrid_synthesis_deint_sse4(float out[2][38][64], float (*in)[32][2], + int i, int len); +void ff_ps_hybrid_analysis_ileave_sse(float (*out)[32][2], float L[2][38][64], + int i, int len); + +av_cold void ff_psdsp_init_x86(PSDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + s->add_squares = ff_ps_add_squares_sse; + s->mul_pair_single = ff_ps_mul_pair_single_sse; + s->hybrid_analysis_ileave = ff_ps_hybrid_analysis_ileave_sse; + s->hybrid_synthesis_deint = ff_ps_hybrid_synthesis_deint_sse; + s->hybrid_analysis = ff_ps_hybrid_analysis_sse; + } + if (EXTERNAL_SSE3(cpu_flags)) { + s->add_squares = ff_ps_add_squares_sse3; + s->stereo_interpolate[0] = ff_ps_stereo_interpolate_sse3; + s->stereo_interpolate[1] = ff_ps_stereo_interpolate_ipdopd_sse3; + s->hybrid_analysis = ff_ps_hybrid_analysis_sse3; + } + if (EXTERNAL_SSE4(cpu_flags)) { + s->hybrid_synthesis_deint = ff_ps_hybrid_synthesis_deint_sse4; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ac3dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ac3dsp_init.c new file mode 100644 index 000000000..2e7e2fb6d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ac3dsp_init.c @@ -0,0 +1,164 @@ +/* + * x86-optimized AC-3 DSP functions + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/ac3.h" +#include "libavcodec/ac3dsp.h" + +void ff_ac3_exponent_min_mmx (uint8_t *exp, int num_reuse_blocks, int nb_coefs); +void ff_ac3_exponent_min_mmxext(uint8_t *exp, int num_reuse_blocks, int nb_coefs); +void ff_ac3_exponent_min_sse2 (uint8_t *exp, int num_reuse_blocks, int nb_coefs); + +int ff_ac3_max_msb_abs_int16_mmx (const int16_t *src, int len); +int ff_ac3_max_msb_abs_int16_mmxext(const int16_t *src, int len); +int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len); +int ff_ac3_max_msb_abs_int16_ssse3(const int16_t *src, int len); + +void ff_ac3_lshift_int16_mmx (int16_t *src, unsigned int len, unsigned int shift); +void ff_ac3_lshift_int16_sse2(int16_t *src, unsigned int len, unsigned int shift); + +void ff_ac3_rshift_int32_mmx (int32_t *src, unsigned int len, unsigned int shift); +void ff_ac3_rshift_int32_sse2(int32_t *src, unsigned int len, unsigned int shift); + +void ff_float_to_fixed24_3dnow(int32_t *dst, const float *src, unsigned int len); +void ff_float_to_fixed24_sse (int32_t *dst, const float *src, unsigned int len); +void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned int len); + +int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]); + +void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs); +void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs); + +void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); +void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); + +av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->ac3_exponent_min = ff_ac3_exponent_min_mmx; + c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmx; + c->ac3_lshift_int16 = ff_ac3_lshift_int16_mmx; + c->ac3_rshift_int32 = ff_ac3_rshift_int32_mmx; + } + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + if (!bit_exact) { + c->float_to_fixed24 = ff_float_to_fixed24_3dnow; + } + } + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->ac3_exponent_min = ff_ac3_exponent_min_mmxext; + c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmxext; + if (bit_exact) { + c->apply_window_int16 = ff_apply_window_int16_mmxext; + } else { + c->apply_window_int16 = ff_apply_window_int16_round_mmxext; + } + } + if (EXTERNAL_SSE(cpu_flags)) { + c->float_to_fixed24 = ff_float_to_fixed24_sse; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->ac3_exponent_min = ff_ac3_exponent_min_sse2; + c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_sse2; + c->float_to_fixed24 = ff_float_to_fixed24_sse2; + c->compute_mantissa_size = ff_ac3_compute_mantissa_size_sse2; + c->extract_exponents = ff_ac3_extract_exponents_sse2; + if (bit_exact) { + c->apply_window_int16 = ff_apply_window_int16_sse2; + } + } + + if (EXTERNAL_SSE2_FAST(cpu_flags)) { + c->ac3_lshift_int16 = ff_ac3_lshift_int16_sse2; + c->ac3_rshift_int32 = ff_ac3_rshift_int32_sse2; + if (!bit_exact) { + c->apply_window_int16 = ff_apply_window_int16_round_sse2; + } + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_ssse3; + if (cpu_flags & AV_CPU_FLAG_ATOM) { + c->apply_window_int16 = ff_apply_window_int16_ssse3_atom; + } else { + c->extract_exponents = ff_ac3_extract_exponents_ssse3; + c->apply_window_int16 = ff_apply_window_int16_ssse3; + } + } +} + +#define DOWNMIX_FUNC_OPT(ch, opt) \ +void ff_ac3_downmix_ ## ch ## _to_1_ ## opt(float **samples, \ + float **matrix, int len); \ +void ff_ac3_downmix_ ## ch ## _to_2_ ## opt(float **samples, \ + float **matrix, int len); + +#define DOWNMIX_FUNCS(opt) \ + DOWNMIX_FUNC_OPT(3, opt) \ + DOWNMIX_FUNC_OPT(4, opt) \ + DOWNMIX_FUNC_OPT(5, opt) \ + DOWNMIX_FUNC_OPT(6, opt) + +DOWNMIX_FUNCS(sse) +DOWNMIX_FUNCS(avx) +DOWNMIX_FUNCS(fma3) + +void ff_ac3dsp_set_downmix_x86(AC3DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + +#define SET_DOWNMIX(ch, suf, SUF) \ + if (ch == c->in_channels) { \ + if (EXTERNAL_ ## SUF (cpu_flags)) { \ + if (c->out_channels == 1) \ + c->downmix = ff_ac3_downmix_ ## ch ## _to_1_ ## suf; \ + else \ + c->downmix = ff_ac3_downmix_ ## ch ## _to_2_ ## suf; \ + } \ + } + +#define SET_DOWNMIX_ALL(suf, SUF) \ + SET_DOWNMIX(3, suf, SUF) \ + SET_DOWNMIX(4, suf, SUF) \ + SET_DOWNMIX(5, suf, SUF) \ + SET_DOWNMIX(6, suf, SUF) + + SET_DOWNMIX_ALL(sse, SSE) + if (!(cpu_flags & AV_CPU_FLAG_AVXSLOW)) { + SET_DOWNMIX_ALL(avx, AVX) + SET_DOWNMIX_ALL(fma3, FMA3) + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/alacdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/alacdsp_init.c new file mode 100644 index 000000000..18f7308a1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/alacdsp_init.c @@ -0,0 +1,44 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/alacdsp.h" +#include "config.h" + +void ff_alac_decorrelate_stereo_sse4(int32_t *buffer[2], int nb_samples, + int decorr_shift, int decorr_left_weight); +void ff_alac_append_extra_bits_stereo_sse2(int32_t *buffer[2], int32_t *extra_bits_buffer[2], + int extra_bits, int channels, int nb_samples); +void ff_alac_append_extra_bits_mono_sse2(int32_t *buffer[2], int32_t *extra_bits_buffer[2], + int extra_bits, int channels, int nb_samples); + +av_cold void ff_alacdsp_init_x86(ALACDSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + c->append_extra_bits[0] = ff_alac_append_extra_bits_mono_sse2; + c->append_extra_bits[1] = ff_alac_append_extra_bits_stereo_sse2; + } + if (EXTERNAL_SSE4(cpu_flags)) { + c->decorrelate_stereo = ff_alac_decorrelate_stereo_sse4; + } +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/audiodsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/audiodsp_init.c new file mode 100644 index 000000000..98e296c26 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/audiodsp_init.c @@ -0,0 +1,66 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/audiodsp.h" + +int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2, + int order); +int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2, + int order); + +void ff_vector_clip_int32_mmx(int32_t *dst, const int32_t *src, + int32_t min, int32_t max, unsigned int len); +void ff_vector_clip_int32_sse2(int32_t *dst, const int32_t *src, + int32_t min, int32_t max, unsigned int len); +void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src, + int32_t min, int32_t max, unsigned int len); +void ff_vector_clip_int32_sse4(int32_t *dst, const int32_t *src, + int32_t min, int32_t max, unsigned int len); +void ff_vector_clipf_sse(float *dst, const float *src, + int len, float min, float max); + +av_cold void ff_audiodsp_init_x86(AudioDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) + c->vector_clip_int32 = ff_vector_clip_int32_mmx; + + if (EXTERNAL_MMXEXT(cpu_flags)) + c->scalarproduct_int16 = ff_scalarproduct_int16_mmxext; + + if (EXTERNAL_SSE(cpu_flags)) + c->vector_clipf = ff_vector_clipf_sse; + + if (EXTERNAL_SSE2(cpu_flags)) { + c->scalarproduct_int16 = ff_scalarproduct_int16_sse2; + if (cpu_flags & AV_CPU_FLAG_ATOM) + c->vector_clip_int32 = ff_vector_clip_int32_int_sse2; + else + c->vector_clip_int32 = ff_vector_clip_int32_sse2; + } + + if (EXTERNAL_SSE4(cpu_flags)) + c->vector_clip_int32 = ff_vector_clip_int32_sse4; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/blockdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/blockdsp_init.c new file mode 100644 index 000000000..8b01a447c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/blockdsp_init.c @@ -0,0 +1,60 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/internal.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/blockdsp.h" +#include "libavcodec/version.h" + +void ff_clear_block_mmx(int16_t *block); +void ff_clear_block_sse(int16_t *block); +void ff_clear_block_avx(int16_t *block); +void ff_clear_blocks_mmx(int16_t *blocks); +void ff_clear_blocks_sse(int16_t *blocks); +void ff_clear_blocks_avx(int16_t *blocks); + +av_cold void ff_blockdsp_init_x86(BlockDSPContext *c, + AVCodecContext *avctx) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->clear_block = ff_clear_block_mmx; + c->clear_blocks = ff_clear_blocks_mmx; + } + + /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */ + if (CONFIG_XVMC && avctx->hwaccel && avctx->hwaccel->decode_mb) + return; + + if (EXTERNAL_SSE(cpu_flags)) { + c->clear_block = ff_clear_block_sse; + c->clear_blocks = ff_clear_blocks_sse; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + c->clear_block = ff_clear_block_avx; + c->clear_blocks = ff_clear_blocks_avx; + } +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/bswapdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/bswapdsp_init.c new file mode 100644 index 000000000..877bab1a2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/bswapdsp_init.c @@ -0,0 +1,40 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/bswapdsp.h" + +void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w); +void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w); +void ff_bswap32_buf_avx2(uint32_t *dst, const uint32_t *src, int w); + +av_cold void ff_bswapdsp_init_x86(BswapDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) + c->bswap_buf = ff_bswap32_buf_sse2; + if (EXTERNAL_SSSE3(cpu_flags)) + c->bswap_buf = ff_bswap32_buf_ssse3; + if (EXTERNAL_AVX2_FAST(cpu_flags)) + c->bswap_buf = ff_bswap32_buf_avx2; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/cabac.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/cabac.h new file mode 100644 index 000000000..cfd3b759c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/cabac.h @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_CABAC_H +#define AVCODEC_X86_CABAC_H + +#include "libavcodec/cabac.h" +#include "libavutil/attributes.h" +#include "libavutil/macros.h" +#include "libavutil/x86/asm.h" +#include "config.h" + +#if (defined(__i386) && defined(__clang__) && (__clang_major__<2 || (__clang_major__==2 && __clang_minor__<10)))\ + || ( !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1)\ + || (defined(__INTEL_COMPILER) && defined(_MSC_VER)) +# define BROKEN_COMPILER 1 +#else +# define BROKEN_COMPILER 0 +#endif + +#if HAVE_INLINE_ASM + +#ifndef UNCHECKED_BITSTREAM_READER +#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER +#endif + +#if UNCHECKED_BITSTREAM_READER +#define END_CHECK(end) "" +#else +#define END_CHECK(end) \ + "cmp "end" , %%"FF_REG_c" \n\t"\ + "jge 1f \n\t" +#endif + +#ifdef BROKEN_RELOCATIONS +#define TABLES_ARG , "r"(tables) + +#if HAVE_FAST_CMOV +#define BRANCHLESS_GET_CABAC_UPDATE(ret, retq, low, range, tmp) \ + "cmp "low" , "tmp" \n\t"\ + "cmova %%ecx , "range" \n\t"\ + "sbb %%rcx , %%rcx \n\t"\ + "and %%ecx , "tmp" \n\t"\ + "xor %%rcx , "retq" \n\t"\ + "sub "tmp" , "low" \n\t" +#else /* HAVE_FAST_CMOV */ +#define BRANCHLESS_GET_CABAC_UPDATE(ret, retq, low, range, tmp) \ +/* P4 Prescott has crappy cmov,sbb,64-bit shift so avoid them */ \ + "sub "low" , "tmp" \n\t"\ + "sar $31 , "tmp" \n\t"\ + "sub %%ecx , "range" \n\t"\ + "and "tmp" , "range" \n\t"\ + "add %%ecx , "range" \n\t"\ + "shl $17 , %%ecx \n\t"\ + "and "tmp" , %%ecx \n\t"\ + "sub %%ecx , "low" \n\t"\ + "xor "tmp" , "ret" \n\t"\ + "movslq "ret" , "retq" \n\t" +#endif /* HAVE_FAST_CMOV */ + +#define BRANCHLESS_GET_CABAC(ret, retq, statep, low, lowword, range, rangeq, tmp, tmpbyte, byte, end, norm_off, lps_off, mlps_off, tables) \ + "movzbl "statep" , "ret" \n\t"\ + "mov "range" , "tmp" \n\t"\ + "and $0xC0 , "range" \n\t"\ + "lea ("ret", "range", 2), %%ecx \n\t"\ + "movzbl "lps_off"("tables", %%rcx), "range" \n\t"\ + "sub "range" , "tmp" \n\t"\ + "mov "tmp" , %%ecx \n\t"\ + "shl $17 , "tmp" \n\t"\ + BRANCHLESS_GET_CABAC_UPDATE(ret, retq, low, range, tmp) \ + "movzbl "norm_off"("tables", "rangeq"), %%ecx \n\t"\ + "shl %%cl , "range" \n\t"\ + "movzbl "mlps_off"+128("tables", "retq"), "tmp" \n\t"\ + "shl %%cl , "low" \n\t"\ + "mov "tmpbyte" , "statep" \n\t"\ + "test "lowword" , "lowword" \n\t"\ + "jnz 2f \n\t"\ + "mov "byte" , %%"FF_REG_c" \n\t"\ + END_CHECK(end)\ + "add"FF_OPSIZE" $2 , "byte" \n\t"\ + "1: \n\t"\ + "movzwl (%%"FF_REG_c") , "tmp" \n\t"\ + "lea -1("low") , %%ecx \n\t"\ + "xor "low" , %%ecx \n\t"\ + "shr $15 , %%ecx \n\t"\ + "bswap "tmp" \n\t"\ + "shr $15 , "tmp" \n\t"\ + "movzbl "norm_off"("tables", %%rcx), %%ecx \n\t"\ + "sub $0xFFFF , "tmp" \n\t"\ + "neg %%ecx \n\t"\ + "add $7 , %%ecx \n\t"\ + "shl %%cl , "tmp" \n\t"\ + "add "tmp" , "low" \n\t"\ + "2: \n\t" + +#else /* BROKEN_RELOCATIONS */ +#define TABLES_ARG NAMED_CONSTRAINTS_ARRAY_ADD(ff_h264_cabac_tables) +#define RIP_ARG + +#if HAVE_FAST_CMOV +#define BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp)\ + "mov "tmp" , %%ecx \n\t"\ + "shl $17 , "tmp" \n\t"\ + "cmp "low" , "tmp" \n\t"\ + "cmova %%ecx , "range" \n\t"\ + "sbb %%ecx , %%ecx \n\t"\ + "and %%ecx , "tmp" \n\t"\ + "xor %%ecx , "ret" \n\t"\ + "sub "tmp" , "low" \n\t" +#else /* HAVE_FAST_CMOV */ +#define BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp)\ + "mov "tmp" , %%ecx \n\t"\ + "shl $17 , "tmp" \n\t"\ + "sub "low" , "tmp" \n\t"\ + "sar $31 , "tmp" \n\t" /*lps_mask*/\ + "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\ + "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\ + "add %%ecx , "range" \n\t" /*new range*/\ + "shl $17 , %%ecx \n\t"\ + "and "tmp" , %%ecx \n\t"\ + "sub %%ecx , "low" \n\t"\ + "xor "tmp" , "ret" \n\t" +#endif /* HAVE_FAST_CMOV */ + +#define BRANCHLESS_GET_CABAC(ret, retq, statep, low, lowword, range, rangeq, tmp, tmpbyte, byte, end, norm_off, lps_off, mlps_off, tables) \ + "movzbl "statep" , "ret" \n\t"\ + "mov "range" , "tmp" \n\t"\ + "and $0xC0 , "range" \n\t"\ + "movzbl "MANGLE(ff_h264_cabac_tables)"+"lps_off"("ret", "range", 2), "range" \n\t"\ + "sub "range" , "tmp" \n\t"\ + BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp) \ + "movzbl "MANGLE(ff_h264_cabac_tables)"+"norm_off"("range"), %%ecx \n\t"\ + "shl %%cl , "range" \n\t"\ + "movzbl "MANGLE(ff_h264_cabac_tables)"+"mlps_off"+128("ret"), "tmp" \n\t"\ + "shl %%cl , "low" \n\t"\ + "mov "tmpbyte" , "statep" \n\t"\ + "test "lowword" , "lowword" \n\t"\ + " jnz 2f \n\t"\ + "mov "byte" , %%"FF_REG_c" \n\t"\ + END_CHECK(end)\ + "add"FF_OPSIZE" $2 , "byte" \n\t"\ + "1: \n\t"\ + "movzwl (%%"FF_REG_c") , "tmp" \n\t"\ + "lea -1("low") , %%ecx \n\t"\ + "xor "low" , %%ecx \n\t"\ + "shr $15 , %%ecx \n\t"\ + "bswap "tmp" \n\t"\ + "shr $15 , "tmp" \n\t"\ + "movzbl "MANGLE(ff_h264_cabac_tables)"+"norm_off"(%%ecx), %%ecx \n\t"\ + "sub $0xFFFF , "tmp" \n\t"\ + "neg %%ecx \n\t"\ + "add $7 , %%ecx \n\t"\ + "shl %%cl , "tmp" \n\t"\ + "add "tmp" , "low" \n\t"\ + "2: \n\t" + +#endif /* BROKEN_RELOCATIONS */ + +#if HAVE_7REGS && !BROKEN_COMPILER +#define get_cabac_inline get_cabac_inline_x86 +static av_always_inline int get_cabac_inline_x86(CABACContext *c, + uint8_t *const state) +{ + int bit, tmp; +#ifdef BROKEN_RELOCATIONS + void *tables; + + __asm__ volatile( + "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" + : "=&r"(tables) + : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) + ); +#endif + + __asm__ volatile( + BRANCHLESS_GET_CABAC("%0", "%q0", "(%4)", "%1", "%w1", + "%2", "%q2", "%3", "%b3", + "%c6(%5)", "%c7(%5)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%8") + : "=&r"(bit), "=&r"(c->low), "=&r"(c->range), "=&q"(tmp) + : "r"(state), "r"(c), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)) + TABLES_ARG + ,"1"(c->low), "2"(c->range) + : "%"FF_REG_c, "memory" + ); + return bit & 1; +} +#endif /* HAVE_7REGS && !BROKEN_COMPILER */ + +#if !BROKEN_COMPILER +#define get_cabac_bypass_sign get_cabac_bypass_sign_x86 +static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val) +{ + x86_reg tmp; + __asm__ volatile( + "movl %c6(%2), %k1 \n\t" + "movl %c3(%2), %%eax \n\t" + "shl $17, %k1 \n\t" + "add %%eax, %%eax \n\t" + "sub %k1, %%eax \n\t" + "cdq \n\t" + "and %%edx, %k1 \n\t" + "add %k1, %%eax \n\t" + "xor %%edx, %%ecx \n\t" + "sub %%edx, %%ecx \n\t" + "test %%ax, %%ax \n\t" + "jnz 1f \n\t" + "mov %c4(%2), %1 \n\t" + "subl $0xFFFF, %%eax \n\t" + "movzwl (%1), %%edx \n\t" + "bswap %%edx \n\t" + "shrl $15, %%edx \n\t" +#if UNCHECKED_BITSTREAM_READER + "add $2, %1 \n\t" + "addl %%edx, %%eax \n\t" + "mov %1, %c4(%2) \n\t" +#else + "addl %%edx, %%eax \n\t" + "cmp %c5(%2), %1 \n\t" + "jge 1f \n\t" + "add"FF_OPSIZE" $2, %c4(%2) \n\t" +#endif + "1: \n\t" + "movl %%eax, %c3(%2) \n\t" + + : "+c"(val), "=&r"(tmp) + : "r"(c), + "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)), + "i"(offsetof(CABACContext, range)) + : "%eax", "%edx", "memory" + ); + return val; +} + +#define get_cabac_bypass get_cabac_bypass_x86 +static av_always_inline int get_cabac_bypass_x86(CABACContext *c) +{ + x86_reg tmp; + int res; + __asm__ volatile( + "movl %c6(%2), %k1 \n\t" + "movl %c3(%2), %%eax \n\t" + "shl $17, %k1 \n\t" + "add %%eax, %%eax \n\t" + "sub %k1, %%eax \n\t" + "cdq \n\t" + "and %%edx, %k1 \n\t" + "add %k1, %%eax \n\t" + "inc %%edx \n\t" + "test %%ax, %%ax \n\t" + "jnz 1f \n\t" + "mov %c4(%2), %1 \n\t" + "subl $0xFFFF, %%eax \n\t" + "movzwl (%1), %%ecx \n\t" + "bswap %%ecx \n\t" + "shrl $15, %%ecx \n\t" + "addl %%ecx, %%eax \n\t" + "cmp %c5(%2), %1 \n\t" + "jge 1f \n\t" + "add"FF_OPSIZE" $2, %c4(%2) \n\t" + "1: \n\t" + "movl %%eax, %c3(%2) \n\t" + + : "=&d"(res), "=&r"(tmp) + : "r"(c), + "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)), + "i"(offsetof(CABACContext, range)) + : "%eax", "%ecx", "memory" + ); + return res; +} +#endif /* !BROKEN_COMPILER */ + +#endif /* HAVE_INLINE_ASM */ +#endif /* AVCODEC_X86_CABAC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/cavsdsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/cavsdsp.c new file mode 100644 index 000000000..becb3a480 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/cavsdsp.c @@ -0,0 +1,463 @@ +/* + * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. + * Copyright (c) 2006 Stefan Gehrer + * + * MMX-optimized DSP functions, based on H.264 optimizations by + * Michael Niedermayer and Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/common.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/cavsdsp.h" +#include "libavcodec/idctdsp.h" +#include "constants.h" +#include "fpel.h" +#include "idctdsp.h" +#include "config.h" + + +#if HAVE_MMX_EXTERNAL + +void ff_cavs_idct8_mmx(int16_t *out, const int16_t *in); + +static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, ptrdiff_t stride) +{ + LOCAL_ALIGNED(16, int16_t, b2, [64]); + ff_cavs_idct8_mmx(b2, block); + ff_add_pixels_clamped_mmx(b2, dst, stride); +} + +void ff_cavs_idct8_sse2(int16_t *out, const int16_t *in); + +static void cavs_idct8_add_sse2(uint8_t *dst, int16_t *block, ptrdiff_t stride) +{ + LOCAL_ALIGNED(16, int16_t, b2, [64]); + ff_cavs_idct8_sse2(b2, block); + ff_add_pixels_clamped_sse2(b2, dst, stride); +} + +#endif /* HAVE_MMX_EXTERNAL */ + +#if (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE) + +/***************************************************************************** + * + * motion compensation + * + ****************************************************************************/ + +/* vertical filter [-1 -2 96 42 -7 0] */ +#define QPEL_CAVSV1(A,B,C,D,E,F,OP,ADD, MUL1, MUL2) \ + "movd (%0), "#F" \n\t"\ + "movq "#C", %%mm6 \n\t"\ + "pmullw "MANGLE(MUL1)", %%mm6\n\t"\ + "movq "#D", %%mm7 \n\t"\ + "pmullw "MANGLE(MUL2)", %%mm7\n\t"\ + "psllw $3, "#E" \n\t"\ + "psubw "#E", %%mm6 \n\t"\ + "psraw $3, "#E" \n\t"\ + "paddw %%mm7, %%mm6 \n\t"\ + "paddw "#E", %%mm6 \n\t"\ + "paddw "#B", "#B" \n\t"\ + "pxor %%mm7, %%mm7 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, "#F" \n\t"\ + "psubw "#B", %%mm6 \n\t"\ + "psraw $1, "#B" \n\t"\ + "psubw "#A", %%mm6 \n\t"\ + "paddw "MANGLE(ADD)", %%mm6 \n\t"\ + "psraw $7, %%mm6 \n\t"\ + "packuswb %%mm6, %%mm6 \n\t"\ + OP(%%mm6, (%1), A, d) \ + "add %3, %1 \n\t" + +/* vertical filter [ 0 -1 5 5 -1 0] */ +#define QPEL_CAVSV2(A,B,C,D,E,F,OP,ADD, MUL1, MUL2) \ + "movd (%0), "#F" \n\t"\ + "movq "#C", %%mm6 \n\t"\ + "paddw "#D", %%mm6 \n\t"\ + "pmullw "MANGLE(MUL1)", %%mm6\n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, "#F" \n\t"\ + "psubw "#B", %%mm6 \n\t"\ + "psubw "#E", %%mm6 \n\t"\ + "paddw "MANGLE(ADD)", %%mm6 \n\t"\ + "psraw $3, %%mm6 \n\t"\ + "packuswb %%mm6, %%mm6 \n\t"\ + OP(%%mm6, (%1), A, d) \ + "add %3, %1 \n\t" + +/* vertical filter [ 0 -7 42 96 -2 -1] */ +#define QPEL_CAVSV3(A,B,C,D,E,F,OP,ADD, MUL1, MUL2) \ + "movd (%0), "#F" \n\t"\ + "movq "#C", %%mm6 \n\t"\ + "pmullw "MANGLE(MUL2)", %%mm6\n\t"\ + "movq "#D", %%mm7 \n\t"\ + "pmullw "MANGLE(MUL1)", %%mm7\n\t"\ + "psllw $3, "#B" \n\t"\ + "psubw "#B", %%mm6 \n\t"\ + "psraw $3, "#B" \n\t"\ + "paddw %%mm7, %%mm6 \n\t"\ + "paddw "#B", %%mm6 \n\t"\ + "paddw "#E", "#E" \n\t"\ + "pxor %%mm7, %%mm7 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, "#F" \n\t"\ + "psubw "#E", %%mm6 \n\t"\ + "psraw $1, "#E" \n\t"\ + "psubw "#F", %%mm6 \n\t"\ + "paddw "MANGLE(ADD)", %%mm6 \n\t"\ + "psraw $7, %%mm6 \n\t"\ + "packuswb %%mm6, %%mm6 \n\t"\ + OP(%%mm6, (%1), A, d) \ + "add %3, %1 \n\t" + + +#define QPEL_CAVSVNUM(VOP,OP,ADD,MUL1,MUL2)\ + int w= 2;\ + src -= 2*srcStride;\ + \ + while(w--){\ + __asm__ volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movd (%0), %%mm0 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm1 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm2 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm3 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm4 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + VOP(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP, ADD, MUL1, MUL2)\ + VOP(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP, ADD, MUL1, MUL2)\ + VOP(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP, ADD, MUL1, MUL2)\ + VOP(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP, ADD, MUL1, MUL2)\ + VOP(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, OP, ADD, MUL1, MUL2)\ + VOP(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, OP, ADD, MUL1, MUL2)\ + VOP(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP, ADD, MUL1, MUL2)\ + VOP(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP, ADD, MUL1, MUL2)\ + \ + : "+a"(src), "+c"(dst)\ + : "S"((x86_reg)srcStride), "r"((x86_reg)dstStride)\ + NAMED_CONSTRAINTS_ADD(ADD,MUL1,MUL2)\ + : "memory"\ + );\ + if(h==16){\ + __asm__ volatile(\ + VOP(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP, ADD, MUL1, MUL2)\ + VOP(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP, ADD, MUL1, MUL2)\ + VOP(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, OP, ADD, MUL1, MUL2)\ + VOP(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, OP, ADD, MUL1, MUL2)\ + VOP(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP, ADD, MUL1, MUL2)\ + VOP(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP, ADD, MUL1, MUL2)\ + VOP(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP, ADD, MUL1, MUL2)\ + VOP(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP, ADD, MUL1, MUL2)\ + \ + : "+a"(src), "+c"(dst)\ + : "S"((x86_reg)srcStride), "r"((x86_reg)dstStride)\ + NAMED_CONSTRAINTS_ADD(ADD,MUL1,MUL2)\ + : "memory"\ + );\ + }\ + src += 4-(h+5)*srcStride;\ + dst += 4-h*dstStride;\ + } + +#define QPEL_CAVS(OPNAME, OP, MMX)\ +static void OPNAME ## cavs_qpel8_h_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{\ + int h=8;\ + __asm__ volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movq "MANGLE(ff_pw_5)", %%mm6\n\t"\ + "1: \n\t"\ + "movq (%0), %%mm0 \n\t"\ + "movq 1(%0), %%mm2 \n\t"\ + "movq %%mm0, %%mm1 \n\t"\ + "movq %%mm2, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpckhbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpckhbw %%mm7, %%mm3 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"\ + "paddw %%mm3, %%mm1 \n\t"\ + "pmullw %%mm6, %%mm0 \n\t"\ + "pmullw %%mm6, %%mm1 \n\t"\ + "movq -1(%0), %%mm2 \n\t"\ + "movq 2(%0), %%mm4 \n\t"\ + "movq %%mm2, %%mm3 \n\t"\ + "movq %%mm4, %%mm5 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpckhbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + "punpckhbw %%mm7, %%mm5 \n\t"\ + "paddw %%mm4, %%mm2 \n\t"\ + "paddw %%mm3, %%mm5 \n\t"\ + "psubw %%mm2, %%mm0 \n\t"\ + "psubw %%mm5, %%mm1 \n\t"\ + "movq "MANGLE(ff_pw_4)", %%mm5\n\t"\ + "paddw %%mm5, %%mm0 \n\t"\ + "paddw %%mm5, %%mm1 \n\t"\ + "psraw $3, %%mm0 \n\t"\ + "psraw $3, %%mm1 \n\t"\ + "packuswb %%mm1, %%mm0 \n\t"\ + OP(%%mm0, (%1),%%mm5, q) \ + "add %3, %0 \n\t"\ + "add %4, %1 \n\t"\ + "decl %2 \n\t"\ + " jnz 1b \n\t"\ + : "+a"(src), "+c"(dst), "+m"(h)\ + : "d"((x86_reg)srcStride), "S"((x86_reg)dstStride)\ + NAMED_CONSTRAINTS_ADD(ff_pw_4,ff_pw_5)\ + : "memory"\ + );\ +}\ +\ +static inline void OPNAME ## cavs_qpel8or16_v1_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)\ +{ \ + QPEL_CAVSVNUM(QPEL_CAVSV1,OP,ff_pw_64,ff_pw_96,ff_pw_42) \ +}\ +\ +static inline void OPNAME ## cavs_qpel8or16_v2_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)\ +{ \ + QPEL_CAVSVNUM(QPEL_CAVSV2,OP,ff_pw_4,ff_pw_5,ff_pw_42) \ +}\ +\ +static inline void OPNAME ## cavs_qpel8or16_v3_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)\ +{ \ + QPEL_CAVSVNUM(QPEL_CAVSV3,OP,ff_pw_64,ff_pw_96,ff_pw_42) \ +}\ +\ +static void OPNAME ## cavs_qpel8_v1_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static void OPNAME ## cavs_qpel16_v1_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst , src , dstStride, srcStride, 16);\ + OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +}\ +\ +static void OPNAME ## cavs_qpel8_v2_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static void OPNAME ## cavs_qpel16_v2_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst , src , dstStride, srcStride, 16);\ + OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +}\ +\ +static void OPNAME ## cavs_qpel8_v3_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static void OPNAME ## cavs_qpel16_v3_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst , src , dstStride, srcStride, 16);\ + OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +}\ +\ +static void OPNAME ## cavs_qpel16_h_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8_h_ ## MMX(dst , src , dstStride, srcStride);\ + OPNAME ## cavs_qpel8_h_ ## MMX(dst+8, src+8, dstStride, srcStride);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + OPNAME ## cavs_qpel8_h_ ## MMX(dst , src , dstStride, srcStride);\ + OPNAME ## cavs_qpel8_h_ ## MMX(dst+8, src+8, dstStride, srcStride);\ +}\ + +#define CAVS_MC(OPNAME, SIZE, MMX) \ +static void OPNAME ## cavs_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + OPNAME ## cavs_qpel ## SIZE ## _h_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + OPNAME ## cavs_qpel ## SIZE ## _v1_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + OPNAME ## cavs_qpel ## SIZE ## _v2_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + OPNAME ## cavs_qpel ## SIZE ## _v3_ ## MMX(dst, src, stride, stride);\ +}\ + +#define PUT_OP(a,b,temp, size) "mov" #size " " #a ", " #b " \n\t" +#define AVG_3DNOW_OP(a,b,temp, size) \ +"mov" #size " " #b ", " #temp " \n\t"\ +"pavgusb " #temp ", " #a " \n\t"\ +"mov" #size " " #a ", " #b " \n\t" +#define AVG_MMXEXT_OP(a, b, temp, size) \ +"mov" #size " " #b ", " #temp " \n\t"\ +"pavgb " #temp ", " #a " \n\t"\ +"mov" #size " " #a ", " #b " \n\t" + +#endif /* (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE) */ + +#if HAVE_MMX_EXTERNAL +static void put_cavs_qpel8_mc00_mmx(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels8_mmx(dst, src, stride, 8); +} + +static void avg_cavs_qpel8_mc00_mmx(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels8_mmx(dst, src, stride, 8); +} + +static void avg_cavs_qpel8_mc00_mmxext(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels8_mmxext(dst, src, stride, 8); +} + +static void put_cavs_qpel16_mc00_mmx(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels16_mmx(dst, src, stride, 16); +} + +static void avg_cavs_qpel16_mc00_mmx(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_mmx(dst, src, stride, 16); +} + +static void avg_cavs_qpel16_mc00_mmxext(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_mmxext(dst, src, stride, 16); +} + +static void put_cavs_qpel16_mc00_sse2(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels16_sse2(dst, src, stride, 16); +} + +static void avg_cavs_qpel16_mc00_sse2(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_sse2(dst, src, stride, 16); +} +#endif + +static av_cold void cavsdsp_init_mmx(CAVSDSPContext *c, + AVCodecContext *avctx) +{ +#if HAVE_MMX_EXTERNAL + c->put_cavs_qpel_pixels_tab[0][0] = put_cavs_qpel16_mc00_mmx; + c->put_cavs_qpel_pixels_tab[1][0] = put_cavs_qpel8_mc00_mmx; + c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_mmx; + c->avg_cavs_qpel_pixels_tab[1][0] = avg_cavs_qpel8_mc00_mmx; + + c->cavs_idct8_add = cavs_idct8_add_mmx; + c->idct_perm = FF_IDCT_PERM_TRANSPOSE; +#endif /* HAVE_MMX_EXTERNAL */ +} + +#define DSPFUNC(PFX, IDX, NUM, EXT) \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][ 2] = PFX ## _cavs_qpel ## NUM ## _mc20_ ## EXT; \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][ 4] = PFX ## _cavs_qpel ## NUM ## _mc01_ ## EXT; \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][ 8] = PFX ## _cavs_qpel ## NUM ## _mc02_ ## EXT; \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][12] = PFX ## _cavs_qpel ## NUM ## _mc03_ ## EXT; \ + +#if HAVE_MMXEXT_INLINE +QPEL_CAVS(put_, PUT_OP, mmxext) +QPEL_CAVS(avg_, AVG_MMXEXT_OP, mmxext) + +CAVS_MC(put_, 8, mmxext) +CAVS_MC(put_, 16, mmxext) +CAVS_MC(avg_, 8, mmxext) +CAVS_MC(avg_, 16, mmxext) +#endif /* HAVE_MMXEXT_INLINE */ + +#if HAVE_AMD3DNOW_INLINE +QPEL_CAVS(put_, PUT_OP, 3dnow) +QPEL_CAVS(avg_, AVG_3DNOW_OP, 3dnow) + +CAVS_MC(put_, 8, 3dnow) +CAVS_MC(put_, 16,3dnow) +CAVS_MC(avg_, 8, 3dnow) +CAVS_MC(avg_, 16,3dnow) + +static av_cold void cavsdsp_init_3dnow(CAVSDSPContext *c, + AVCodecContext *avctx) +{ + DSPFUNC(put, 0, 16, 3dnow); + DSPFUNC(put, 1, 8, 3dnow); + DSPFUNC(avg, 0, 16, 3dnow); + DSPFUNC(avg, 1, 8, 3dnow); +} +#endif /* HAVE_AMD3DNOW_INLINE */ + +av_cold void ff_cavsdsp_init_x86(CAVSDSPContext *c, AVCodecContext *avctx) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + + if (X86_MMX(cpu_flags)) + cavsdsp_init_mmx(c, avctx); + +#if HAVE_AMD3DNOW_INLINE + if (INLINE_AMD3DNOW(cpu_flags)) + cavsdsp_init_3dnow(c, avctx); +#endif /* HAVE_AMD3DNOW_INLINE */ +#if HAVE_MMXEXT_INLINE + if (INLINE_MMXEXT(cpu_flags)) { + DSPFUNC(put, 0, 16, mmxext); + DSPFUNC(put, 1, 8, mmxext); + DSPFUNC(avg, 0, 16, mmxext); + DSPFUNC(avg, 1, 8, mmxext); + } +#endif +#if HAVE_MMX_EXTERNAL + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_mmxext; + c->avg_cavs_qpel_pixels_tab[1][0] = avg_cavs_qpel8_mc00_mmxext; + } +#endif +#if HAVE_SSE2_EXTERNAL + if (EXTERNAL_SSE2(cpu_flags)) { + c->put_cavs_qpel_pixels_tab[0][0] = put_cavs_qpel16_mc00_sse2; + c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_sse2; + + c->cavs_idct8_add = cavs_idct8_add_sse2; + c->idct_perm = FF_IDCT_PERM_TRANSPOSE; + } +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/celt_pvq_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/celt_pvq_init.c new file mode 100644 index 000000000..13724c356 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/celt_pvq_init.c @@ -0,0 +1,43 @@ +/* + * Opus encoder assembly optimizations + * Copyright (C) 2017 Ivan Kalvachev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/x86/cpu.h" +#include "libavcodec/opus_pvq.h" + +extern float ff_pvq_search_approx_sse2(float *X, int *y, int K, int N); +extern float ff_pvq_search_approx_sse4(float *X, int *y, int K, int N); +extern float ff_pvq_search_exact_avx (float *X, int *y, int K, int N); + +av_cold void ff_celt_pvq_init_x86(CeltPVQ *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) + s->pvq_search = ff_pvq_search_approx_sse2; + + if (EXTERNAL_SSE4(cpu_flags)) + s->pvq_search = ff_pvq_search_approx_sse4; + + if (EXTERNAL_AVX_FAST(cpu_flags)) + s->pvq_search = ff_pvq_search_exact_avx; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/constants.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/constants.c new file mode 100644 index 000000000..4bfb78cc3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/constants.c @@ -0,0 +1,94 @@ +/* + * MMX/SSE/AVX constants used across x86 dsp optimizations. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" // for xmm_reg +#include "constants.h" + +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_1) = { 0x0001000100010001ULL, 0x0001000100010001ULL, + 0x0001000100010001ULL, 0x0001000100010001ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_2) = { 0x0002000200020002ULL, 0x0002000200020002ULL, + 0x0002000200020002ULL, 0x0002000200020002ULL }; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_3) = { 0x0003000300030003ULL, 0x0003000300030003ULL }; +DECLARE_ASM_ALIGNED(32, const ymm_reg, ff_pw_4) = { 0x0004000400040004ULL, 0x0004000400040004ULL, + 0x0004000400040004ULL, 0x0004000400040004ULL }; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_5) = { 0x0005000500050005ULL, 0x0005000500050005ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_8) = { 0x0008000800080008ULL, 0x0008000800080008ULL }; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_9) = { 0x0009000900090009ULL, 0x0009000900090009ULL }; +DECLARE_ALIGNED(8, const uint64_t, ff_pw_15) = 0x000F000F000F000FULL; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_16) = { 0x0010001000100010ULL, 0x0010001000100010ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_17) = { 0x0011001100110011ULL, 0x0011001100110011ULL }; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_18) = { 0x0012001200120012ULL, 0x0012001200120012ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_20) = { 0x0014001400140014ULL, 0x0014001400140014ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_32) = { 0x0020002000200020ULL, 0x0020002000200020ULL }; +DECLARE_ASM_ALIGNED(8, const uint64_t, ff_pw_42) = 0x002A002A002A002AULL; +DECLARE_ASM_ALIGNED(8, const uint64_t, ff_pw_53) = 0x0035003500350035ULL; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_64) = { 0x0040004000400040ULL, 0x0040004000400040ULL }; +DECLARE_ASM_ALIGNED(8, const uint64_t, ff_pw_96) = 0x0060006000600060ULL; +DECLARE_ASM_ALIGNED(8, const uint64_t, ff_pw_128) = 0x0080008000800080ULL; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_255) = { 0x00ff00ff00ff00ffULL, 0x00ff00ff00ff00ffULL, + 0x00ff00ff00ff00ffULL, 0x00ff00ff00ff00ffULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_256) = { 0x0100010001000100ULL, 0x0100010001000100ULL, + 0x0100010001000100ULL, 0x0100010001000100ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_512) = { 0x0200020002000200ULL, 0x0200020002000200ULL, + 0x0200020002000200ULL, 0x0200020002000200ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1019) = { 0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_1023) = { 0x03ff03ff03ff03ffULL, 0x03ff03ff03ff03ffULL, + 0x03ff03ff03ff03ffULL, 0x03ff03ff03ff03ffULL}; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_1024) = { 0x0400040004000400ULL, 0x0400040004000400ULL, + 0x0400040004000400ULL, 0x0400040004000400ULL}; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_2048) = { 0x0800080008000800ULL, 0x0800080008000800ULL, + 0x0800080008000800ULL, 0x0800080008000800ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_4095) = { 0x0fff0fff0fff0fffULL, 0x0fff0fff0fff0fffULL, + 0x0fff0fff0fff0fffULL, 0x0fff0fff0fff0fffULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_4096) = { 0x1000100010001000ULL, 0x1000100010001000ULL, + 0x1000100010001000ULL, 0x1000100010001000ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_8192) = { 0x2000200020002000ULL, 0x2000200020002000ULL, + 0x2000200020002000ULL, 0x2000200020002000ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_m1) = { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL }; + +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_0) = { 0x0000000000000000ULL, 0x0000000000000000ULL, + 0x0000000000000000ULL, 0x0000000000000000ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_1) = { 0x0101010101010101ULL, 0x0101010101010101ULL, + 0x0101010101010101ULL, 0x0101010101010101ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_2) = { 0x0202020202020202ULL, 0x0202020202020202ULL, + 0x0202020202020202ULL, 0x0202020202020202ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_3) = { 0x0303030303030303ULL, 0x0303030303030303ULL, + 0x0303030303030303ULL, 0x0303030303030303ULL }; +DECLARE_ALIGNED(32, const xmm_reg, ff_pb_15) = { 0x0F0F0F0F0F0F0F0FULL, 0x0F0F0F0F0F0F0F0FULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_80) = { 0x8080808080808080ULL, 0x8080808080808080ULL, + 0x8080808080808080ULL, 0x8080808080808080ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_FE) = { 0xFEFEFEFEFEFEFEFEULL, 0xFEFEFEFEFEFEFEFEULL, + 0xFEFEFEFEFEFEFEFEULL, 0xFEFEFEFEFEFEFEFEULL }; +DECLARE_ALIGNED(8, const uint64_t, ff_pb_FC) = 0xFCFCFCFCFCFCFCFCULL; + +DECLARE_ALIGNED(16, const xmm_reg, ff_ps_neg) = { 0x8000000080000000ULL, 0x8000000080000000ULL }; + +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_1) = { 0x0000000100000001ULL, 0x0000000100000001ULL, + 0x0000000100000001ULL, 0x0000000100000001ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_16) = { 0x0000001000000010ULL, 0x0000001000000010ULL, + 0x0000001000000010ULL, 0x0000001000000010ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_32) = { 0x0000002000000020ULL, 0x0000002000000020ULL, + 0x0000002000000020ULL, 0x0000002000000020ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_8192) = { 0x0000200000002000ULL, 0x0000200000002000ULL, + 0x0000200000002000ULL, 0x0000200000002000ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_65535)= { 0x0000ffff0000ffffULL, 0x0000ffff0000ffffULL, + 0x0000ffff0000ffffULL, 0x0000ffff0000ffffULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/constants.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/constants.h new file mode 100644 index 000000000..85da38b7b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/constants.h @@ -0,0 +1,72 @@ +/* + * MMX/SSE constants used across x86 dsp optimizations. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_CONSTANTS_H +#define AVCODEC_X86_CONSTANTS_H + +#include + +#include "libavutil/x86/asm.h" + +extern const ymm_reg ff_pw_1; +extern const ymm_reg ff_pw_2; +extern const xmm_reg ff_pw_3; +extern const ymm_reg ff_pw_4; +extern const xmm_reg ff_pw_5; +extern const xmm_reg ff_pw_8; +extern const xmm_reg ff_pw_9; +extern const uint64_t ff_pw_15; +extern const xmm_reg ff_pw_16; +extern const xmm_reg ff_pw_18; +extern const xmm_reg ff_pw_20; +extern const xmm_reg ff_pw_32; +extern const uint64_t ff_pw_42; +extern const uint64_t ff_pw_53; +extern const xmm_reg ff_pw_64; +extern const uint64_t ff_pw_96; +extern const uint64_t ff_pw_128; +extern const ymm_reg ff_pw_255; +extern const ymm_reg ff_pw_256; +extern const ymm_reg ff_pw_512; +extern const ymm_reg ff_pw_1023; +extern const ymm_reg ff_pw_1024; +extern const ymm_reg ff_pw_2048; +extern const ymm_reg ff_pw_4095; +extern const ymm_reg ff_pw_4096; +extern const ymm_reg ff_pw_8192; +extern const ymm_reg ff_pw_m1; + +extern const ymm_reg ff_pb_0; +extern const ymm_reg ff_pb_1; +extern const ymm_reg ff_pb_2; +extern const ymm_reg ff_pb_3; +extern const ymm_reg ff_pb_80; +extern const ymm_reg ff_pb_FE; +extern const uint64_t ff_pb_FC; + +extern const xmm_reg ff_ps_neg; + +extern const ymm_reg ff_pd_1; +extern const ymm_reg ff_pd_16; +extern const ymm_reg ff_pd_32; +extern const ymm_reg ff_pd_8192; +extern const ymm_reg ff_pd_65535; + +#endif /* AVCODEC_X86_CONSTANTS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dcadsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dcadsp_init.c new file mode 100644 index 000000000..fc10fb8bc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dcadsp_init.c @@ -0,0 +1,52 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/dcadsp.h" + +#define LFE_FIR_FLOAT_FUNC(opt) \ +void ff_lfe_fir0_float_##opt(float *pcm_samples, int32_t *lfe_samples, \ + const float *filter_coeff, ptrdiff_t npcmblocks); \ +void ff_lfe_fir1_float_##opt(float *pcm_samples, int32_t *lfe_samples, \ + const float *filter_coeff, ptrdiff_t npcmblocks); + +LFE_FIR_FLOAT_FUNC(sse) +LFE_FIR_FLOAT_FUNC(sse2) +LFE_FIR_FLOAT_FUNC(sse3) +LFE_FIR_FLOAT_FUNC(avx) +LFE_FIR_FLOAT_FUNC(fma3) + +av_cold void ff_dcadsp_init_x86(DCADSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (ARCH_X86_32 && EXTERNAL_SSE(cpu_flags)) + s->lfe_fir_float[0] = ff_lfe_fir0_float_sse; + if (EXTERNAL_SSE2(cpu_flags)) + s->lfe_fir_float[0] = ff_lfe_fir0_float_sse2; + if (EXTERNAL_SSE3(cpu_flags)) + s->lfe_fir_float[1] = ff_lfe_fir1_float_sse3; + if (EXTERNAL_AVX(cpu_flags)) { + s->lfe_fir_float[0] = ff_lfe_fir0_float_avx; + s->lfe_fir_float[1] = ff_lfe_fir1_float_avx; + } + if (EXTERNAL_FMA3(cpu_flags)) + s->lfe_fir_float[0] = ff_lfe_fir0_float_fma3; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dct_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dct_init.c new file mode 100644 index 000000000..c31ef9223 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dct_init.c @@ -0,0 +1,41 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/dct.h" + +void ff_dct32_float_sse(FFTSample *out, const FFTSample *in); +void ff_dct32_float_sse2(FFTSample *out, const FFTSample *in); +void ff_dct32_float_avx(FFTSample *out, const FFTSample *in); + +av_cold void ff_dct_init_x86(DCTContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags)) + s->dct32 = ff_dct32_float_sse; +#endif + if (EXTERNAL_SSE2(cpu_flags)) + s->dct32 = ff_dct32_float_sse2; + if (EXTERNAL_AVX_FAST(cpu_flags)) + s->dct32 = ff_dct32_float_avx; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dirac_dwt_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dirac_dwt_init.c new file mode 100644 index 000000000..49a6380ad --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dirac_dwt_init.c @@ -0,0 +1,229 @@ +/* + * x86 optimized discrete wavelet transform + * Copyright (c) 2002-2004 Michael Niedermayer + * Copyright (c) 2010 David Conrad + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/dirac_dwt.h" + +#define COMPOSE_VERTICAL(ext, align) \ +void ff_vertical_compose53iL0##ext(int16_t *b0, int16_t *b1, int16_t *b2, int width); \ +void ff_vertical_compose_dirac53iH0##ext(int16_t *b0, int16_t *b1, int16_t *b2, int width); \ +void ff_vertical_compose_dd137iL0##ext(int16_t *b0, int16_t *b1, int16_t *b2, int16_t *b3, int16_t *b4, int width); \ +void ff_vertical_compose_dd97iH0##ext(int16_t *b0, int16_t *b1, int16_t *b2, int16_t *b3, int16_t *b4, int width); \ +void ff_vertical_compose_haar##ext(int16_t *b0, int16_t *b1, int width); \ +void ff_horizontal_compose_haar0i##ext(int16_t *b, int16_t *tmp, int w);\ +void ff_horizontal_compose_haar1i##ext(int16_t *b, int16_t *tmp, int w);\ +\ +static void vertical_compose53iL0##ext(uint8_t *_b0, uint8_t *_b1, uint8_t *_b2, int width) \ +{ \ + int i, width_align = width&~(align-1); \ + int16_t *b0 = (int16_t *)_b0; \ + int16_t *b1 = (int16_t *)_b1; \ + int16_t *b2 = (int16_t *)_b2; \ +\ + for(i=width_align; i>1;\ + int x= w2 - (w2&(align-1));\ + int16_t *b = (int16_t *)_b; \ + int16_t *tmp = (int16_t *)_tmp; \ +\ + ff_horizontal_compose_haar0i##ext(b, tmp, w);\ +\ + for (; x < w2; x++) {\ + b[2*x ] = tmp[x];\ + b[2*x+1] = COMPOSE_HAARiH0(b[x+w2], tmp[x]);\ + }\ +}\ +static void horizontal_compose_haar1i##ext(uint8_t *_b, uint8_t *_tmp, int w)\ +{\ + int w2= w>>1;\ + int x= w2 - (w2&(align-1));\ + int16_t *b = (int16_t *)_b; \ + int16_t *tmp = (int16_t *)_tmp; \ +\ + ff_horizontal_compose_haar1i##ext(b, tmp, w);\ +\ + for (; x < w2; x++) {\ + b[2*x ] = (tmp[x] + 1)>>1;\ + b[2*x+1] = (COMPOSE_HAARiH0(b[x+w2], tmp[x]) + 1)>>1;\ + }\ +}\ +\ + +#if HAVE_X86ASM +#if !ARCH_X86_64 +COMPOSE_VERTICAL(_mmx, 4) +#endif +COMPOSE_VERTICAL(_sse2, 8) + + +void ff_horizontal_compose_dd97i_ssse3(int16_t *_b, int16_t *_tmp, int w); + +static void horizontal_compose_dd97i_ssse3(uint8_t *_b, uint8_t *_tmp, int w) +{ + int w2= w>>1; + int x= w2 - (w2&7); + int16_t *b = (int16_t *)_b; + int16_t *tmp = (int16_t *)_tmp; + + ff_horizontal_compose_dd97i_ssse3(b, tmp, w); + + for (; x < w2; x++) { + b[2*x ] = (tmp[x] + 1)>>1; + b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1; + } +} +#endif + +void ff_spatial_idwt_init_x86(DWTContext *d, enum dwt_type type) +{ +#if HAVE_X86ASM + int mm_flags = av_get_cpu_flags(); + +#if !ARCH_X86_64 + if (!(mm_flags & AV_CPU_FLAG_MMX)) + return; + + switch (type) { + case DWT_DIRAC_DD9_7: + d->vertical_compose_l0 = (void*)vertical_compose53iL0_mmx; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_mmx; + break; + case DWT_DIRAC_LEGALL5_3: + d->vertical_compose_l0 = (void*)vertical_compose53iL0_mmx; + d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0_mmx; + break; + case DWT_DIRAC_DD13_7: + d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0_mmx; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_mmx; + break; + case DWT_DIRAC_HAAR0: + d->vertical_compose = (void*)vertical_compose_haar_mmx; + d->horizontal_compose = horizontal_compose_haar0i_mmx; + break; + case DWT_DIRAC_HAAR1: + d->vertical_compose = (void*)vertical_compose_haar_mmx; + d->horizontal_compose = horizontal_compose_haar1i_mmx; + break; + } +#endif + + if (!(mm_flags & AV_CPU_FLAG_SSE2)) + return; + + switch (type) { + case DWT_DIRAC_DD9_7: + d->vertical_compose_l0 = (void*)vertical_compose53iL0_sse2; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_sse2; + break; + case DWT_DIRAC_LEGALL5_3: + d->vertical_compose_l0 = (void*)vertical_compose53iL0_sse2; + d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0_sse2; + break; + case DWT_DIRAC_DD13_7: + d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0_sse2; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_sse2; + break; + case DWT_DIRAC_HAAR0: + d->vertical_compose = (void*)vertical_compose_haar_sse2; + d->horizontal_compose = horizontal_compose_haar0i_sse2; + break; + case DWT_DIRAC_HAAR1: + d->vertical_compose = (void*)vertical_compose_haar_sse2; + d->horizontal_compose = horizontal_compose_haar1i_sse2; + break; + } + + if (!(mm_flags & AV_CPU_FLAG_SSSE3)) + return; + + switch (type) { + case DWT_DIRAC_DD9_7: + d->horizontal_compose = horizontal_compose_dd97i_ssse3; + break; + } +#endif // HAVE_X86ASM +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/diracdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/diracdsp_init.c new file mode 100644 index 000000000..8cb84eb74 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/diracdsp_init.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2010 David Conrad + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/x86/cpu.h" +#include "libavcodec/diracdsp.h" +#include "fpel.h" + +DECL_DIRAC_PIXOP(put, mmx); +DECL_DIRAC_PIXOP(avg, mmx); +DECL_DIRAC_PIXOP(avg, mmxext); + +void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); +void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); +void ff_put_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); +void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); + +void ff_add_rect_clamped_mmx(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int); +void ff_add_rect_clamped_sse2(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int); + +void ff_add_dirac_obmc8_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); +void ff_add_dirac_obmc16_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); +void ff_add_dirac_obmc32_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); + +void ff_add_dirac_obmc16_sse2(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); +void ff_add_dirac_obmc32_sse2(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); + +void ff_put_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_rect_clamped_sse2(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_signed_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_signed_rect_clamped_sse2(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_signed_rect_clamped_10_sse4(uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int width, int height); + +void ff_dequant_subband_32_sse4(uint8_t *src, uint8_t *dst, ptrdiff_t stride, const int qf, const int qs, int tot_v, int tot_h); + +#if HAVE_X86ASM + +#define HPEL_FILTER(MMSIZE, EXT) \ + void ff_dirac_hpel_filter_v_ ## EXT(uint8_t *, const uint8_t *, int, int); \ + void ff_dirac_hpel_filter_h_ ## EXT(uint8_t *, const uint8_t *, int); \ + \ + static void dirac_hpel_filter_ ## EXT(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, \ + const uint8_t *src, int stride, int width, int height) \ + { \ + while( height-- ) \ + { \ + ff_dirac_hpel_filter_v_ ## EXT(dstv-MMSIZE, src-MMSIZE, stride, width+MMSIZE+5); \ + ff_dirac_hpel_filter_h_ ## EXT(dsth, src, width); \ + ff_dirac_hpel_filter_h_ ## EXT(dstc, dstv, width); \ + \ + dsth += stride; \ + dstv += stride; \ + dstc += stride; \ + src += stride; \ + } \ + } + +#define PIXFUNC(PFX, IDX, EXT) \ + /*MMXDISABLEDc->PFX ## _dirac_pixels_tab[0][IDX] = ff_ ## PFX ## _dirac_pixels8_ ## EXT;*/ \ + c->PFX ## _dirac_pixels_tab[1][IDX] = ff_ ## PFX ## _dirac_pixels16_ ## EXT; \ + c->PFX ## _dirac_pixels_tab[2][IDX] = ff_ ## PFX ## _dirac_pixels32_ ## EXT + +#define DIRAC_PIXOP(OPNAME2, OPNAME, EXT)\ +void ff_ ## OPNAME2 ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + if (h&3)\ + ff_ ## OPNAME2 ## _dirac_pixels8_c(dst, src, stride, h);\ + else\ + OPNAME ## _pixels8_ ## EXT(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME2 ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + if (h&3)\ + ff_ ## OPNAME2 ## _dirac_pixels16_c(dst, src, stride, h);\ + else\ + OPNAME ## _pixels16_ ## EXT(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME2 ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + if (h&3) {\ + ff_ ## OPNAME2 ## _dirac_pixels32_c(dst, src, stride, h);\ + } else {\ + OPNAME ## _pixels16_ ## EXT(dst , src[0] , stride, h);\ + OPNAME ## _pixels16_ ## EXT(dst+16, src[0]+16, stride, h);\ + }\ +} + +DIRAC_PIXOP(put, ff_put, mmx) +DIRAC_PIXOP(avg, ff_avg, mmx) +DIRAC_PIXOP(avg, ff_avg, mmxext) + +void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) +{ + if (h&3) + ff_put_dirac_pixels16_c(dst, src, stride, h); + else + ff_put_pixels16_sse2(dst, src[0], stride, h); +} +void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) +{ + if (h&3) + ff_avg_dirac_pixels16_c(dst, src, stride, h); + else + ff_avg_pixels16_sse2(dst, src[0], stride, h); +} +void ff_put_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) +{ + if (h&3) { + ff_put_dirac_pixels32_c(dst, src, stride, h); + } else { + ff_put_pixels16_sse2(dst , src[0] , stride, h); + ff_put_pixels16_sse2(dst+16, src[0]+16, stride, h); + } +} +void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) +{ + if (h&3) { + ff_avg_dirac_pixels32_c(dst, src, stride, h); + } else { + ff_avg_pixels16_sse2(dst , src[0] , stride, h); + ff_avg_pixels16_sse2(dst+16, src[0]+16, stride, h); + } +} + +#else // HAVE_X86ASM + +#define HPEL_FILTER(MMSIZE, EXT) \ + void dirac_hpel_filter_ ## EXT(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, \ + const uint8_t *src, int stride, int width, int height); + +#define PIXFUNC(PFX, IDX, EXT) do {} while (0) + +#endif // HAVE_X86ASM + +#if !ARCH_X86_64 +HPEL_FILTER(8, mmx) +#endif +HPEL_FILTER(16, sse2) + +void ff_diracdsp_init_x86(DiracDSPContext* c) +{ + int mm_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(mm_flags)) { + c->add_dirac_obmc[0] = ff_add_dirac_obmc8_mmx; +#if !ARCH_X86_64 + c->add_dirac_obmc[1] = ff_add_dirac_obmc16_mmx; + c->add_dirac_obmc[2] = ff_add_dirac_obmc32_mmx; + c->dirac_hpel_filter = dirac_hpel_filter_mmx; + c->add_rect_clamped = ff_add_rect_clamped_mmx; + c->put_signed_rect_clamped[0] = (void *)ff_put_signed_rect_clamped_mmx; +#endif + PIXFUNC(put, 0, mmx); + PIXFUNC(avg, 0, mmx); + } + + if (EXTERNAL_MMXEXT(mm_flags)) { + PIXFUNC(avg, 0, mmxext); + } + + if (EXTERNAL_SSE2(mm_flags)) { + c->dirac_hpel_filter = dirac_hpel_filter_sse2; + c->add_rect_clamped = ff_add_rect_clamped_sse2; + c->put_signed_rect_clamped[0] = (void *)ff_put_signed_rect_clamped_sse2; + + c->add_dirac_obmc[1] = ff_add_dirac_obmc16_sse2; + c->add_dirac_obmc[2] = ff_add_dirac_obmc32_sse2; + + c->put_dirac_pixels_tab[1][0] = ff_put_dirac_pixels16_sse2; + c->avg_dirac_pixels_tab[1][0] = ff_avg_dirac_pixels16_sse2; + c->put_dirac_pixels_tab[2][0] = ff_put_dirac_pixels32_sse2; + c->avg_dirac_pixels_tab[2][0] = ff_avg_dirac_pixels32_sse2; + } + + if (EXTERNAL_SSE4(mm_flags)) { + c->dequant_subband[1] = ff_dequant_subband_32_sse4; + c->put_signed_rect_clamped[1] = ff_put_signed_rect_clamped_10_sse4; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dnxhdenc_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dnxhdenc_init.c new file mode 100644 index 000000000..fd6f15005 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/dnxhdenc_init.c @@ -0,0 +1,37 @@ +/* + * VC3/DNxHD SIMD functions + * Copyright (c) 2007 Baptiste Coudurier + * + * VC-3 encoder funded by the British Broadcasting Corporation + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/dnxhdenc.h" + +void ff_get_pixels_8x4_sym_sse2(int16_t *block, const uint8_t *pixels, + ptrdiff_t line_size); + +av_cold void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx) +{ + if (EXTERNAL_SSE2(av_get_cpu_flags())) { + if (ctx->cid_table->bit_depth == 8) + ctx->get_pixels_8x4_sym = ff_get_pixels_8x4_sym_sse2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/exrdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/exrdsp_init.c new file mode 100644 index 000000000..63b3480d8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/exrdsp_init.c @@ -0,0 +1,52 @@ +/* + * OpenEXR (.exr) image decoder + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/exrdsp.h" + +void ff_reorder_pixels_sse2(uint8_t *dst, const uint8_t *src, ptrdiff_t size); + +void ff_reorder_pixels_avx2(uint8_t *dst, const uint8_t *src, ptrdiff_t size); + +void ff_predictor_ssse3(uint8_t *src, ptrdiff_t size); + +void ff_predictor_avx(uint8_t *src, ptrdiff_t size); + +void ff_predictor_avx2(uint8_t *src, ptrdiff_t size); + +av_cold void ff_exrdsp_init_x86(ExrDSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + dsp->reorder_pixels = ff_reorder_pixels_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + dsp->predictor = ff_predictor_ssse3; + } + if (EXTERNAL_AVX(cpu_flags)) { + dsp->predictor = ff_predictor_avx; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + dsp->reorder_pixels = ff_reorder_pixels_avx2; + dsp->predictor = ff_predictor_avx2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdct.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdct.c new file mode 100644 index 000000000..112566ded --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdct.c @@ -0,0 +1,594 @@ +/* + * SIMD-optimized forward DCT + * The gcc porting is Copyright (c) 2001 Fabrice Bellard. + * cleanup/optimizations are Copyright (c) 2002-2004 Michael Niedermayer + * SSE2 optimization is Copyright (c) 2004 Denes Balatoni. + * + * from fdctam32.c - AP922 MMX(3D-Now) forward-DCT + * + * Intel Application Note AP-922 - fast, precise implementation of DCT + * http://developer.intel.com/vtune/cbts/appnotes.htm + * + * Also of inspiration: + * a page about fdct at http://www.geocities.com/ssavekar/dct.htm + * Skal's fdct at http://skal.planet-d.net/coding/dct.html + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/common.h" +#include "libavutil/x86/asm.h" +#include "fdct.h" + +#if HAVE_MMX_INLINE + +////////////////////////////////////////////////////////////////////// +// +// constants for the forward DCT +// ----------------------------- +// +// Be sure to check that your compiler is aligning all constants to QWORD +// (8-byte) memory boundaries! Otherwise the unaligned memory access will +// severely stall MMX execution. +// +////////////////////////////////////////////////////////////////////// + +#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 - 3) +#define RND_FRW_ROW (1 << (SHIFT_FRW_ROW-1)) +//#define RND_FRW_COL (1 << (SHIFT_FRW_COL-1)) + +#define X8(x) x,x,x,x,x,x,x,x + +//concatenated table, for forward DCT transformation +DECLARE_ALIGNED(16, static const int16_t, fdct_tg_all_16)[24] = { + X8(13036), // tg * (2<<16) + 0.5 + X8(27146), // tg * (2<<16) + 0.5 + X8(-21746) // tg * (2<<16) + 0.5 +}; + +DECLARE_ALIGNED(16, static const int16_t, ocos_4_16)[8] = { + X8(23170) //cos * (2<<15) + 0.5 +}; + +DECLARE_ALIGNED(16, static const int16_t, fdct_one_corr)[8] = { X8(1) }; + +DECLARE_ALIGNED(8, static const int32_t, fdct_r_row)[2] = {RND_FRW_ROW, RND_FRW_ROW }; + +static const struct +{ + DECLARE_ALIGNED(16, const int32_t, fdct_r_row_sse2)[4]; +} fdct_r_row_sse2 = +{{ + RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW +}}; +//DECLARE_ALIGNED(16, static const long, fdct_r_row_sse2)[4] = {RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW}; + +DECLARE_ALIGNED(8, static const int16_t, tab_frw_01234567)[] = { // forward_dct coeff table + 16384, 16384, 22725, 19266, + 16384, 16384, 12873, 4520, + 21407, 8867, 19266, -4520, + -8867, -21407, -22725, -12873, + 16384, -16384, 12873, -22725, + -16384, 16384, 4520, 19266, + 8867, -21407, 4520, -12873, + 21407, -8867, 19266, -22725, + + 22725, 22725, 31521, 26722, + 22725, 22725, 17855, 6270, + 29692, 12299, 26722, -6270, + -12299, -29692, -31521, -17855, + 22725, -22725, 17855, -31521, + -22725, 22725, 6270, 26722, + 12299, -29692, 6270, -17855, + 29692, -12299, 26722, -31521, + + 21407, 21407, 29692, 25172, + 21407, 21407, 16819, 5906, + 27969, 11585, 25172, -5906, + -11585, -27969, -29692, -16819, + 21407, -21407, 16819, -29692, + -21407, 21407, 5906, 25172, + 11585, -27969, 5906, -16819, + 27969, -11585, 25172, -29692, + + 19266, 19266, 26722, 22654, + 19266, 19266, 15137, 5315, + 25172, 10426, 22654, -5315, + -10426, -25172, -26722, -15137, + 19266, -19266, 15137, -26722, + -19266, 19266, 5315, 22654, + 10426, -25172, 5315, -15137, + 25172, -10426, 22654, -26722, + + 16384, 16384, 22725, 19266, + 16384, 16384, 12873, 4520, + 21407, 8867, 19266, -4520, + -8867, -21407, -22725, -12873, + 16384, -16384, 12873, -22725, + -16384, 16384, 4520, 19266, + 8867, -21407, 4520, -12873, + 21407, -8867, 19266, -22725, + + 19266, 19266, 26722, 22654, + 19266, 19266, 15137, 5315, + 25172, 10426, 22654, -5315, + -10426, -25172, -26722, -15137, + 19266, -19266, 15137, -26722, + -19266, 19266, 5315, 22654, + 10426, -25172, 5315, -15137, + 25172, -10426, 22654, -26722, + + 21407, 21407, 29692, 25172, + 21407, 21407, 16819, 5906, + 27969, 11585, 25172, -5906, + -11585, -27969, -29692, -16819, + 21407, -21407, 16819, -29692, + -21407, 21407, 5906, 25172, + 11585, -27969, 5906, -16819, + 27969, -11585, 25172, -29692, + + 22725, 22725, 31521, 26722, + 22725, 22725, 17855, 6270, + 29692, 12299, 26722, -6270, + -12299, -29692, -31521, -17855, + 22725, -22725, 17855, -31521, + -22725, 22725, 6270, 26722, + 12299, -29692, 6270, -17855, + 29692, -12299, 26722, -31521, +}; + +static const struct +{ + DECLARE_ALIGNED(16, const int16_t, tab_frw_01234567_sse2)[256]; +} tab_frw_01234567_sse2 = +{{ +//DECLARE_ALIGNED(16, static const int16_t, tab_frw_01234567_sse2)[] = { // forward_dct coeff table +#define TABLE_SSE2 C4, C4, C1, C3, -C6, -C2, -C1, -C5, \ + C4, C4, C5, C7, C2, C6, C3, -C7, \ + -C4, C4, C7, C3, C6, -C2, C7, -C5, \ + C4, -C4, C5, -C1, C2, -C6, C3, -C1, +// c1..c7 * cos(pi/4) * 2^15 +#define C1 22725 +#define C2 21407 +#define C3 19266 +#define C4 16384 +#define C5 12873 +#define C6 8867 +#define C7 4520 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 31521 +#define C2 29692 +#define C3 26722 +#define C4 22725 +#define C5 17855 +#define C6 12299 +#define C7 6270 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 29692 +#define C2 27969 +#define C3 25172 +#define C4 21407 +#define C5 16819 +#define C6 11585 +#define C7 5906 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 26722 +#define C2 25172 +#define C3 22654 +#define C4 19266 +#define C5 15137 +#define C6 10426 +#define C7 5315 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 22725 +#define C2 21407 +#define C3 19266 +#define C4 16384 +#define C5 12873 +#define C6 8867 +#define C7 4520 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 26722 +#define C2 25172 +#define C3 22654 +#define C4 19266 +#define C5 15137 +#define C6 10426 +#define C7 5315 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 29692 +#define C2 27969 +#define C3 25172 +#define C4 21407 +#define C5 16819 +#define C6 11585 +#define C7 5906 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 31521 +#define C2 29692 +#define C3 26722 +#define C4 22725 +#define C5 17855 +#define C6 12299 +#define C7 6270 +TABLE_SSE2 +}}; + +#define S(s) AV_TOSTRING(s) //AV_STRINGIFY is too long + +#define FDCT_COL(cpu, mm, mov)\ +static av_always_inline void fdct_col_##cpu(const int16_t *in, int16_t *out, int offset)\ +{\ + __asm__ volatile (\ + #mov" 16(%0), %%"#mm"0 \n\t" \ + #mov" 96(%0), %%"#mm"1 \n\t" \ + #mov" %%"#mm"0, %%"#mm"2 \n\t" \ + #mov" 32(%0), %%"#mm"3 \n\t" \ + "paddsw %%"#mm"1, %%"#mm"0 \n\t" \ + #mov" 80(%0), %%"#mm"4 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"0 \n\t" \ + #mov" (%0), %%"#mm"5 \n\t" \ + "paddsw %%"#mm"3, %%"#mm"4 \n\t" \ + "paddsw 112(%0), %%"#mm"5 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"4 \n\t" \ + #mov" %%"#mm"0, %%"#mm"6 \n\t" \ + "psubsw %%"#mm"1, %%"#mm"2 \n\t" \ + #mov" 16(%1), %%"#mm"1 \n\t" \ + "psubsw %%"#mm"4, %%"#mm"0 \n\t" \ + #mov" 48(%0), %%"#mm"7 \n\t" \ + "pmulhw %%"#mm"0, %%"#mm"1 \n\t" \ + "paddsw 64(%0), %%"#mm"7 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"5 \n\t" \ + "paddsw %%"#mm"4, %%"#mm"6 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"7 \n\t" \ + #mov" %%"#mm"5, %%"#mm"4 \n\t" \ + "psubsw %%"#mm"7, %%"#mm"5 \n\t" \ + "paddsw %%"#mm"5, %%"#mm"1 \n\t" \ + "paddsw %%"#mm"7, %%"#mm"4 \n\t" \ + "por (%2), %%"#mm"1 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)"+1, %%"#mm"2 \n\t" \ + "pmulhw 16(%1), %%"#mm"5 \n\t" \ + #mov" %%"#mm"4, %%"#mm"7 \n\t" \ + "psubsw 80(%0), %%"#mm"3 \n\t" \ + "psubsw %%"#mm"6, %%"#mm"4 \n\t" \ + #mov" %%"#mm"1, 32(%3) \n\t" \ + "paddsw %%"#mm"6, %%"#mm"7 \n\t" \ + #mov" 48(%0), %%"#mm"1 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)"+1, %%"#mm"3 \n\t" \ + "psubsw 64(%0), %%"#mm"1 \n\t" \ + #mov" %%"#mm"2, %%"#mm"6 \n\t" \ + #mov" %%"#mm"4, 64(%3) \n\t" \ + "paddsw %%"#mm"3, %%"#mm"2 \n\t" \ + "pmulhw (%4), %%"#mm"2 \n\t" \ + "psubsw %%"#mm"3, %%"#mm"6 \n\t" \ + "pmulhw (%4), %%"#mm"6 \n\t" \ + "psubsw %%"#mm"0, %%"#mm"5 \n\t" \ + "por (%2), %%"#mm"5 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"1 \n\t" \ + "por (%2), %%"#mm"2 \n\t" \ + #mov" %%"#mm"1, %%"#mm"4 \n\t" \ + #mov" (%0), %%"#mm"3 \n\t" \ + "paddsw %%"#mm"6, %%"#mm"1 \n\t" \ + "psubsw 112(%0), %%"#mm"3 \n\t" \ + "psubsw %%"#mm"6, %%"#mm"4 \n\t" \ + #mov" (%1), %%"#mm"0 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"3 \n\t" \ + #mov" 32(%1), %%"#mm"6 \n\t" \ + "pmulhw %%"#mm"1, %%"#mm"0 \n\t" \ + #mov" %%"#mm"7, (%3) \n\t" \ + "pmulhw %%"#mm"4, %%"#mm"6 \n\t" \ + #mov" %%"#mm"5, 96(%3) \n\t" \ + #mov" %%"#mm"3, %%"#mm"7 \n\t" \ + #mov" 32(%1), %%"#mm"5 \n\t" \ + "psubsw %%"#mm"2, %%"#mm"7 \n\t" \ + "paddsw %%"#mm"2, %%"#mm"3 \n\t" \ + "pmulhw %%"#mm"7, %%"#mm"5 \n\t" \ + "paddsw %%"#mm"3, %%"#mm"0 \n\t" \ + "paddsw %%"#mm"4, %%"#mm"6 \n\t" \ + "pmulhw (%1), %%"#mm"3 \n\t" \ + "por (%2), %%"#mm"0 \n\t" \ + "paddsw %%"#mm"7, %%"#mm"5 \n\t" \ + "psubsw %%"#mm"6, %%"#mm"7 \n\t" \ + #mov" %%"#mm"0, 16(%3) \n\t" \ + "paddsw %%"#mm"4, %%"#mm"5 \n\t" \ + #mov" %%"#mm"7, 48(%3) \n\t" \ + "psubsw %%"#mm"1, %%"#mm"3 \n\t" \ + #mov" %%"#mm"5, 80(%3) \n\t" \ + #mov" %%"#mm"3, 112(%3) \n\t" \ + : \ + : "r" (in + offset), "r" (fdct_tg_all_16), "r" (fdct_one_corr), \ + "r" (out + offset), "r" (ocos_4_16)); \ +} + +FDCT_COL(mmx, mm, movq) +FDCT_COL(sse2, xmm, movdqa) + +static av_always_inline void fdct_row_sse2(const int16_t *in, int16_t *out) +{ + __asm__ volatile( +#define FDCT_ROW_SSE2_H1(i,t) \ + "movq " #i "(%0), %%xmm2 \n\t" \ + "movq " #i "+8(%0), %%xmm0 \n\t" \ + "movdqa " #t "+32(%1), %%xmm3 \n\t" \ + "movdqa " #t "+48(%1), %%xmm7 \n\t" \ + "movdqa " #t "(%1), %%xmm4 \n\t" \ + "movdqa " #t "+16(%1), %%xmm5 \n\t" + +#define FDCT_ROW_SSE2_H2(i,t) \ + "movq " #i "(%0), %%xmm2 \n\t" \ + "movq " #i "+8(%0), %%xmm0 \n\t" \ + "movdqa " #t "+32(%1), %%xmm3 \n\t" \ + "movdqa " #t "+48(%1), %%xmm7 \n\t" + +#define FDCT_ROW_SSE2(i) \ + "movq %%xmm2, %%xmm1 \n\t" \ + "pshuflw $27, %%xmm0, %%xmm0 \n\t" \ + "paddsw %%xmm0, %%xmm1 \n\t" \ + "psubsw %%xmm0, %%xmm2 \n\t" \ + "punpckldq %%xmm2, %%xmm1 \n\t" \ + "pshufd $78, %%xmm1, %%xmm2 \n\t" \ + "pmaddwd %%xmm2, %%xmm3 \n\t" \ + "pmaddwd %%xmm1, %%xmm7 \n\t" \ + "pmaddwd %%xmm5, %%xmm2 \n\t" \ + "pmaddwd %%xmm4, %%xmm1 \n\t" \ + "paddd %%xmm7, %%xmm3 \n\t" \ + "paddd %%xmm2, %%xmm1 \n\t" \ + "paddd %%xmm6, %%xmm3 \n\t" \ + "paddd %%xmm6, %%xmm1 \n\t" \ + "psrad %3, %%xmm3 \n\t" \ + "psrad %3, %%xmm1 \n\t" \ + "packssdw %%xmm3, %%xmm1 \n\t" \ + "movdqa %%xmm1, " #i "(%4) \n\t" + + "movdqa (%2), %%xmm6 \n\t" + FDCT_ROW_SSE2_H1(0,0) + FDCT_ROW_SSE2(0) + FDCT_ROW_SSE2_H2(64,0) + FDCT_ROW_SSE2(64) + + FDCT_ROW_SSE2_H1(16,64) + FDCT_ROW_SSE2(16) + FDCT_ROW_SSE2_H2(112,64) + FDCT_ROW_SSE2(112) + + FDCT_ROW_SSE2_H1(32,128) + FDCT_ROW_SSE2(32) + FDCT_ROW_SSE2_H2(96,128) + FDCT_ROW_SSE2(96) + + FDCT_ROW_SSE2_H1(48,192) + FDCT_ROW_SSE2(48) + FDCT_ROW_SSE2_H2(80,192) + FDCT_ROW_SSE2(80) + : + : "r" (in), "r" (tab_frw_01234567_sse2.tab_frw_01234567_sse2), + "r" (fdct_r_row_sse2.fdct_r_row_sse2), "i" (SHIFT_FRW_ROW), "r" (out) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7") + ); +} + +static av_always_inline void fdct_row_mmxext(const int16_t *in, int16_t *out, + const int16_t *table) +{ + __asm__ volatile ( + "pshufw $0x1B, 8(%0), %%mm5 \n\t" + "movq (%0), %%mm0 \n\t" + "movq %%mm0, %%mm1 \n\t" + "paddsw %%mm5, %%mm0 \n\t" + "psubsw %%mm5, %%mm1 \n\t" + "movq %%mm0, %%mm2 \n\t" + "punpckldq %%mm1, %%mm0 \n\t" + "punpckhdq %%mm1, %%mm2 \n\t" + "movq (%1), %%mm1 \n\t" + "movq 8(%1), %%mm3 \n\t" + "movq 16(%1), %%mm4 \n\t" + "movq 24(%1), %%mm5 \n\t" + "movq 32(%1), %%mm6 \n\t" + "movq 40(%1), %%mm7 \n\t" + "pmaddwd %%mm0, %%mm1 \n\t" + "pmaddwd %%mm2, %%mm3 \n\t" + "pmaddwd %%mm0, %%mm4 \n\t" + "pmaddwd %%mm2, %%mm5 \n\t" + "pmaddwd %%mm0, %%mm6 \n\t" + "pmaddwd %%mm2, %%mm7 \n\t" + "pmaddwd 48(%1), %%mm0 \n\t" + "pmaddwd 56(%1), %%mm2 \n\t" + "paddd %%mm1, %%mm3 \n\t" + "paddd %%mm4, %%mm5 \n\t" + "paddd %%mm6, %%mm7 \n\t" + "paddd %%mm0, %%mm2 \n\t" + "movq (%2), %%mm0 \n\t" + "paddd %%mm0, %%mm3 \n\t" + "paddd %%mm0, %%mm5 \n\t" + "paddd %%mm0, %%mm7 \n\t" + "paddd %%mm0, %%mm2 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm3 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm5 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm7 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm2 \n\t" + "packssdw %%mm5, %%mm3 \n\t" + "packssdw %%mm2, %%mm7 \n\t" + "movq %%mm3, (%3) \n\t" + "movq %%mm7, 8(%3) \n\t" + : + : "r" (in), "r" (table), "r" (fdct_r_row), "r" (out)); +} + +static av_always_inline void fdct_row_mmx(const int16_t *in, int16_t *out, const int16_t *table) +{ + //FIXME reorder (I do not have an old MMX-only CPU here to benchmark ...) + __asm__ volatile( + "movd 12(%0), %%mm1 \n\t" + "punpcklwd 8(%0), %%mm1 \n\t" + "movq %%mm1, %%mm2 \n\t" + "psrlq $0x20, %%mm1 \n\t" + "movq 0(%0), %%mm0 \n\t" + "punpcklwd %%mm2, %%mm1 \n\t" + "movq %%mm0, %%mm5 \n\t" + "paddsw %%mm1, %%mm0 \n\t" + "psubsw %%mm1, %%mm5 \n\t" + "movq %%mm0, %%mm2 \n\t" + "punpckldq %%mm5, %%mm0 \n\t" + "punpckhdq %%mm5, %%mm2 \n\t" + "movq 0(%1), %%mm1 \n\t" + "movq 8(%1), %%mm3 \n\t" + "movq 16(%1), %%mm4 \n\t" + "movq 24(%1), %%mm5 \n\t" + "movq 32(%1), %%mm6 \n\t" + "movq 40(%1), %%mm7 \n\t" + "pmaddwd %%mm0, %%mm1 \n\t" + "pmaddwd %%mm2, %%mm3 \n\t" + "pmaddwd %%mm0, %%mm4 \n\t" + "pmaddwd %%mm2, %%mm5 \n\t" + "pmaddwd %%mm0, %%mm6 \n\t" + "pmaddwd %%mm2, %%mm7 \n\t" + "pmaddwd 48(%1), %%mm0 \n\t" + "pmaddwd 56(%1), %%mm2 \n\t" + "paddd %%mm1, %%mm3 \n\t" + "paddd %%mm4, %%mm5 \n\t" + "paddd %%mm6, %%mm7 \n\t" + "paddd %%mm0, %%mm2 \n\t" + "movq (%2), %%mm0 \n\t" + "paddd %%mm0, %%mm3 \n\t" + "paddd %%mm0, %%mm5 \n\t" + "paddd %%mm0, %%mm7 \n\t" + "paddd %%mm0, %%mm2 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm3 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm5 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm7 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm2 \n\t" + "packssdw %%mm5, %%mm3 \n\t" + "packssdw %%mm2, %%mm7 \n\t" + "movq %%mm3, 0(%3) \n\t" + "movq %%mm7, 8(%3) \n\t" + : + : "r" (in), "r" (table), "r" (fdct_r_row), "r" (out)); +} + +void ff_fdct_mmx(int16_t *block) +{ + DECLARE_ALIGNED(8, int64_t, align_tmp)[16]; + int16_t * block1= (int16_t*)align_tmp; + const int16_t *table= tab_frw_01234567; + int i; + + fdct_col_mmx(block, block1, 0); + fdct_col_mmx(block, block1, 4); + + for(i=8;i>0;i--) { + fdct_row_mmx(block1, block, table); + block1 += 8; + table += 32; + block += 8; + } +} + +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_MMXEXT_INLINE + +void ff_fdct_mmxext(int16_t *block) +{ + DECLARE_ALIGNED(8, int64_t, align_tmp)[16]; + int16_t *block1= (int16_t*)align_tmp; + const int16_t *table= tab_frw_01234567; + int i; + + fdct_col_mmx(block, block1, 0); + fdct_col_mmx(block, block1, 4); + + for(i=8;i>0;i--) { + fdct_row_mmxext(block1, block, table); + block1 += 8; + table += 32; + block += 8; + } +} + +#endif /* HAVE_MMXEXT_INLINE */ + +#if HAVE_SSE2_INLINE + +void ff_fdct_sse2(int16_t *block) +{ + DECLARE_ALIGNED(16, int64_t, align_tmp)[16]; + int16_t * const block1= (int16_t*)align_tmp; + + fdct_col_sse2(block, block1, 0); + fdct_row_sse2(block1, block); +} + +#endif /* HAVE_SSE2_INLINE */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdct.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdct.h new file mode 100644 index 000000000..648cdc535 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdct.h @@ -0,0 +1,28 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_FDCT_H +#define AVCODEC_X86_FDCT_H + +#include + +void ff_fdct_mmx(int16_t *block); +void ff_fdct_mmxext(int16_t *block); +void ff_fdct_sse2(int16_t *block); + +#endif /* AVCODEC_X86_FDCT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdctdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdctdsp_init.c new file mode 100644 index 000000000..0cb5fd625 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fdctdsp_init.c @@ -0,0 +1,44 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/fdctdsp.h" +#include "fdct.h" + +av_cold void ff_fdctdsp_init_x86(FDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + const int dct_algo = avctx->dct_algo; + + if (!high_bit_depth) { + if ((dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX)) { + if (INLINE_MMX(cpu_flags)) + c->fdct = ff_fdct_mmx; + + if (INLINE_MMXEXT(cpu_flags)) + c->fdct = ff_fdct_mmxext; + + if (INLINE_SSE2(cpu_flags)) + c->fdct = ff_fdct_sse2; + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft.h new file mode 100644 index 000000000..398091eb1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft.h @@ -0,0 +1,38 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_FFT_H +#define AVCODEC_X86_FFT_H + +#include "libavcodec/fft.h" + +void ff_fft_permute_sse(FFTContext *s, FFTComplex *z); +void ff_fft_calc_avx(FFTContext *s, FFTComplex *z); +void ff_fft_calc_sse(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dnow(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dnowext(FFTContext *s, FFTComplex *z); + +void ff_imdct_calc_3dnow(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_3dnow(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_3dnowext(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_3dnowext(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_avx(FFTContext *s, FFTSample *output, const FFTSample *input); + +#endif /* AVCODEC_X86_FFT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft_init.c new file mode 100644 index 000000000..928f1dcda --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft_init.c @@ -0,0 +1,61 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" + +#include "fft.h" + +av_cold void ff_fft_init_x86(FFTContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (s->nbits > 16) + return; + +#if ARCH_X86_32 + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + s->imdct_calc = ff_imdct_calc_3dnow; + s->imdct_half = ff_imdct_half_3dnow; + s->fft_calc = ff_fft_calc_3dnow; + } + + if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) { + s->imdct_calc = ff_imdct_calc_3dnowext; + s->imdct_half = ff_imdct_half_3dnowext; + s->fft_calc = ff_fft_calc_3dnowext; + } +#endif /* ARCH_X86_32 */ + + if (EXTERNAL_SSE(cpu_flags)) { + s->imdct_calc = ff_imdct_calc_sse; + s->imdct_half = ff_imdct_half_sse; + s->fft_permute = ff_fft_permute_sse; + s->fft_calc = ff_fft_calc_sse; + s->fft_permutation = FF_FFT_PERM_SWAP_LSBS; + } + + if (EXTERNAL_AVX_FAST(cpu_flags) && s->nbits >= 5) { + s->imdct_half = ff_imdct_half_avx; + s->fft_calc = ff_fft_calc_avx; + s->fft_permutation = FF_FFT_PERM_AVX; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/flacdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/flacdsp_init.c new file mode 100644 index 000000000..1971f81b8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/flacdsp_init.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavcodec/flacdsp.h" +#include "libavutil/x86/cpu.h" +#include "config.h" + +void ff_flac_lpc_32_sse4(int32_t *samples, const int coeffs[32], int order, + int qlevel, int len); +void ff_flac_lpc_32_xop(int32_t *samples, const int coeffs[32], int order, + int qlevel, int len); + +void ff_flac_enc_lpc_16_sse4(int32_t *, const int32_t *, int, int, const int32_t *,int); + +#define DECORRELATE_FUNCS(fmt, opt) \ +void ff_flac_decorrelate_ls_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_rs_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_ms_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_indep2_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_indep4_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_indep6_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_indep8_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift) + +DECORRELATE_FUNCS(16, sse2); +DECORRELATE_FUNCS(16, avx); +DECORRELATE_FUNCS(32, sse2); +DECORRELATE_FUNCS(32, avx); + +av_cold void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, + int bps) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + +#if CONFIG_FLAC_DECODER + if (EXTERNAL_SSE2(cpu_flags)) { + if (fmt == AV_SAMPLE_FMT_S16) { + if (channels == 2) + c->decorrelate[0] = ff_flac_decorrelate_indep2_16_sse2; + else if (channels == 4) + c->decorrelate[0] = ff_flac_decorrelate_indep4_16_sse2; + else if (channels == 6) + c->decorrelate[0] = ff_flac_decorrelate_indep6_16_sse2; + else if (ARCH_X86_64 && channels == 8) + c->decorrelate[0] = ff_flac_decorrelate_indep8_16_sse2; + c->decorrelate[1] = ff_flac_decorrelate_ls_16_sse2; + c->decorrelate[2] = ff_flac_decorrelate_rs_16_sse2; + c->decorrelate[3] = ff_flac_decorrelate_ms_16_sse2; + } else if (fmt == AV_SAMPLE_FMT_S32) { + if (channels == 2) + c->decorrelate[0] = ff_flac_decorrelate_indep2_32_sse2; + else if (channels == 4) + c->decorrelate[0] = ff_flac_decorrelate_indep4_32_sse2; + else if (channels == 6) + c->decorrelate[0] = ff_flac_decorrelate_indep6_32_sse2; + else if (ARCH_X86_64 && channels == 8) + c->decorrelate[0] = ff_flac_decorrelate_indep8_32_sse2; + c->decorrelate[1] = ff_flac_decorrelate_ls_32_sse2; + c->decorrelate[2] = ff_flac_decorrelate_rs_32_sse2; + c->decorrelate[3] = ff_flac_decorrelate_ms_32_sse2; + } + } + if (EXTERNAL_SSE4(cpu_flags)) { + c->lpc32 = ff_flac_lpc_32_sse4; + } + if (EXTERNAL_AVX(cpu_flags)) { + if (fmt == AV_SAMPLE_FMT_S16) { + if (ARCH_X86_64 && channels == 8) + c->decorrelate[0] = ff_flac_decorrelate_indep8_16_avx; + } else if (fmt == AV_SAMPLE_FMT_S32) { + if (channels == 4) + c->decorrelate[0] = ff_flac_decorrelate_indep4_32_avx; + else if (channels == 6) + c->decorrelate[0] = ff_flac_decorrelate_indep6_32_avx; + else if (ARCH_X86_64 && channels == 8) + c->decorrelate[0] = ff_flac_decorrelate_indep8_32_avx; + } + } + if (EXTERNAL_XOP(cpu_flags)) { + c->lpc32 = ff_flac_lpc_32_xop; + } +#endif + +#if CONFIG_FLAC_ENCODER + if (EXTERNAL_SSE4(cpu_flags)) { + if (CONFIG_GPL) + c->lpc16_encode = ff_flac_enc_lpc_16_sse4; + } +#endif +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fmtconvert_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fmtconvert_init.c new file mode 100644 index 000000000..df097054e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fmtconvert_init.c @@ -0,0 +1,55 @@ +/* + * Format Conversion Utils + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/fmtconvert.h" + +#if HAVE_X86ASM + +void ff_int32_to_float_fmul_scalar_sse (float *dst, const int32_t *src, float mul, int len); +void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int32_t *src, float mul, int len); +void ff_int32_to_float_fmul_array8_sse (FmtConvertContext *c, float *dst, const int32_t *src, + const float *mul, int len); +void ff_int32_to_float_fmul_array8_sse2(FmtConvertContext *c, float *dst, const int32_t *src, + const float *mul, int len); + +#endif /* HAVE_X86ASM */ + +av_cold void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse; + c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_sse; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2; + c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_sse2; + } +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fpel.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fpel.h new file mode 100644 index 000000000..4e83cf71c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fpel.h @@ -0,0 +1,49 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_FPEL_H +#define AVCODEC_X86_FPEL_H + +#include +#include + +void ff_avg_pixels4_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels4_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + + +#endif /* AVCODEC_X86_FPEL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/g722dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/g722dsp_init.c new file mode 100644 index 000000000..614695193 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/g722dsp_init.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/g722dsp.h" + +void ff_g722_apply_qmf_sse2(const int16_t *prev_samples, int xout[2]); + +av_cold void ff_g722dsp_init_x86(G722DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) + dsp->apply_qmf = ff_g722_apply_qmf_sse2; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h263dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h263dsp_init.c new file mode 100644 index 000000000..ab8106323 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h263dsp_init.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 Diego Biurrun + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/h263dsp.h" + +void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale); +void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale); + +av_cold void ff_h263dsp_init_x86(H263DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx; + c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_cabac.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_cabac.c new file mode 100644 index 000000000..2edc6d7e7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_cabac.c @@ -0,0 +1,208 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * H.264 / AVC / MPEG-4 part10 codec. + * non-SIMD x86-specific optimizations for H.264 + * @author Michael Niedermayer + */ + +#include + +#include "libavcodec/cabac.h" +#include "cabac.h" + +#if HAVE_INLINE_ASM + +#if ARCH_X86_64 +#define REG64 "r" +#else +#define REG64 "m" +#endif + +//FIXME use some macros to avoid duplicating get_cabac (cannot be done yet +//as that would make optimization work hard) +#if HAVE_7REGS && !BROKEN_COMPILER +#define decode_significance decode_significance_x86 +static int decode_significance_x86(CABACContext *c, int max_coeff, + uint8_t *significant_coeff_ctx_base, + int *index, x86_reg last_off){ + void *end= significant_coeff_ctx_base + max_coeff - 1; + int minusstart= -(intptr_t)significant_coeff_ctx_base; + int minusindex= 4-(intptr_t)index; + int bit; + x86_reg coeff_count; + +#ifdef BROKEN_RELOCATIONS + void *tables; + + __asm__ volatile( + "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" + : "=&r"(tables) + : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) + ); +#endif + + __asm__ volatile( + "3: \n\t" + + BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%c11(%6)", "%c12(%6)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%13") + + "test $1, %4 \n\t" + " jz 4f \n\t" + "add %10, %1 \n\t" + + BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%c11(%6)", "%c12(%6)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%13") + + "sub %10, %1 \n\t" + "mov %2, %0 \n\t" + "movl %7, %%ecx \n\t" + "add %1, %%"FF_REG_c" \n\t" + "movl %%ecx, (%0) \n\t" + + "test $1, %4 \n\t" + " jnz 5f \n\t" + + "add"FF_OPSIZE" $4, %2 \n\t" + + "4: \n\t" + "add $1, %1 \n\t" + "cmp %8, %1 \n\t" + " jb 3b \n\t" + "mov %2, %0 \n\t" + "movl %7, %%ecx \n\t" + "add %1, %%"FF_REG_c" \n\t" + "movl %%ecx, (%0) \n\t" + "5: \n\t" + "add %9, %k0 \n\t" + "shr $2, %k0 \n\t" + : "=&q"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), + "+&r"(c->low), "=&r"(bit), "+&r"(c->range) + : "r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)) + TABLES_ARG + : "%"FF_REG_c, "memory" + ); + return coeff_count; +} + +#define decode_significance_8x8 decode_significance_8x8_x86 +static int decode_significance_8x8_x86(CABACContext *c, + uint8_t *significant_coeff_ctx_base, + int *index, uint8_t *last_coeff_ctx_base, const uint8_t *sig_off){ + int minusindex= 4-(intptr_t)index; + int bit; + x86_reg coeff_count; + x86_reg last=0; + x86_reg state; + +#ifdef BROKEN_RELOCATIONS + void *tables; + + __asm__ volatile( + "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" + : "=&r"(tables) + : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) + ); +#endif + + __asm__ volatile( + "mov %1, %6 \n\t" + "3: \n\t" + + "mov %10, %0 \n\t" + "movzb (%0, %6), %6 \n\t" + "add %9, %6 \n\t" + + BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%c12(%7)", "%c13(%7)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%15") + + "mov %1, %6 \n\t" + "test $1, %4 \n\t" + " jz 4f \n\t" + +#ifdef BROKEN_RELOCATIONS + "movzb %c14(%15, %q6), %6\n\t" +#else + "movzb "MANGLE(ff_h264_cabac_tables)"+%c14(%6), %6\n\t" +#endif + "add %11, %6 \n\t" + + BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%c12(%7)", "%c13(%7)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%15") + + "mov %2, %0 \n\t" + "mov %1, %6 \n\t" + "mov %k6, (%0) \n\t" + + "test $1, %4 \n\t" + " jnz 5f \n\t" + + "add"FF_OPSIZE" $4, %2 \n\t" + + "4: \n\t" + "add $1, %6 \n\t" + "mov %6, %1 \n\t" + "cmp $63, %6 \n\t" + " jb 3b \n\t" + "mov %2, %0 \n\t" + "mov %k6, (%0) \n\t" + "5: \n\t" + "addl %8, %k0 \n\t" + "shr $2, %k0 \n\t" + : "=&q"(coeff_count), "+"REG64(last), "+"REG64(index), "+&r"(c->low), + "=&r"(bit), "+&r"(c->range), "=&r"(state) + : "r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), + REG64(sig_off), REG64(last_coeff_ctx_base), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)), + "i"(H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET) TABLES_ARG + : "%"FF_REG_c, "memory" + ); + return coeff_count; +} +#endif /* HAVE_7REGS && BROKEN_COMPILER */ + +#endif /* HAVE_INLINE_ASM */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_intrapred_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_intrapred_init.c new file mode 100644 index 000000000..bdd5125d6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_intrapred_init.c @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2010 Fiona Glaser + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/h264pred.h" + +#define PRED4x4(TYPE, DEPTH, OPT) \ +void ff_pred4x4_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, \ + const uint8_t *topright, \ + ptrdiff_t stride); + +PRED4x4(dc, 10, mmxext) +PRED4x4(down_left, 10, sse2) +PRED4x4(down_left, 10, avx) +PRED4x4(down_right, 10, sse2) +PRED4x4(down_right, 10, ssse3) +PRED4x4(down_right, 10, avx) +PRED4x4(vertical_left, 10, sse2) +PRED4x4(vertical_left, 10, avx) +PRED4x4(vertical_right, 10, sse2) +PRED4x4(vertical_right, 10, ssse3) +PRED4x4(vertical_right, 10, avx) +PRED4x4(horizontal_up, 10, mmxext) +PRED4x4(horizontal_down, 10, sse2) +PRED4x4(horizontal_down, 10, ssse3) +PRED4x4(horizontal_down, 10, avx) + +#define PRED8x8(TYPE, DEPTH, OPT) \ +void ff_pred8x8_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, \ + ptrdiff_t stride); + +PRED8x8(dc, 10, mmxext) +PRED8x8(dc, 10, sse2) +PRED8x8(top_dc, 10, sse2) +PRED8x8(plane, 10, sse2) +PRED8x8(vertical, 10, sse2) +PRED8x8(horizontal, 10, sse2) + +#define PRED8x8L(TYPE, DEPTH, OPT)\ +void ff_pred8x8l_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, \ + int has_topleft, \ + int has_topright, \ + ptrdiff_t stride); + +PRED8x8L(dc, 10, sse2) +PRED8x8L(dc, 10, avx) +PRED8x8L(128_dc, 10, mmxext) +PRED8x8L(128_dc, 10, sse2) +PRED8x8L(top_dc, 10, sse2) +PRED8x8L(top_dc, 10, avx) +PRED8x8L(vertical, 10, sse2) +PRED8x8L(vertical, 10, avx) +PRED8x8L(horizontal, 10, sse2) +PRED8x8L(horizontal, 10, ssse3) +PRED8x8L(horizontal, 10, avx) +PRED8x8L(down_left, 10, sse2) +PRED8x8L(down_left, 10, ssse3) +PRED8x8L(down_left, 10, avx) +PRED8x8L(down_right, 10, sse2) +PRED8x8L(down_right, 10, ssse3) +PRED8x8L(down_right, 10, avx) +PRED8x8L(vertical_right, 10, sse2) +PRED8x8L(vertical_right, 10, ssse3) +PRED8x8L(vertical_right, 10, avx) +PRED8x8L(horizontal_up, 10, sse2) +PRED8x8L(horizontal_up, 10, ssse3) +PRED8x8L(horizontal_up, 10, avx) + +#define PRED16x16(TYPE, DEPTH, OPT)\ +void ff_pred16x16_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, \ + ptrdiff_t stride); + +PRED16x16(dc, 10, mmxext) +PRED16x16(dc, 10, sse2) +PRED16x16(top_dc, 10, mmxext) +PRED16x16(top_dc, 10, sse2) +PRED16x16(128_dc, 10, mmxext) +PRED16x16(128_dc, 10, sse2) +PRED16x16(left_dc, 10, mmxext) +PRED16x16(left_dc, 10, sse2) +PRED16x16(vertical, 10, mmxext) +PRED16x16(vertical, 10, sse2) +PRED16x16(horizontal, 10, mmxext) +PRED16x16(horizontal, 10, sse2) + +/* 8-bit versions */ +PRED16x16(vertical, 8, mmx) +PRED16x16(vertical, 8, sse) +PRED16x16(horizontal, 8, mmx) +PRED16x16(horizontal, 8, mmxext) +PRED16x16(horizontal, 8, ssse3) +PRED16x16(dc, 8, mmxext) +PRED16x16(dc, 8, sse2) +PRED16x16(dc, 8, ssse3) +PRED16x16(plane_h264, 8, mmx) +PRED16x16(plane_h264, 8, mmxext) +PRED16x16(plane_h264, 8, sse2) +PRED16x16(plane_h264, 8, ssse3) +PRED16x16(plane_rv40, 8, mmx) +PRED16x16(plane_rv40, 8, mmxext) +PRED16x16(plane_rv40, 8, sse2) +PRED16x16(plane_rv40, 8, ssse3) +PRED16x16(plane_svq3, 8, mmx) +PRED16x16(plane_svq3, 8, mmxext) +PRED16x16(plane_svq3, 8, sse2) +PRED16x16(plane_svq3, 8, ssse3) +PRED16x16(tm_vp8, 8, mmx) +PRED16x16(tm_vp8, 8, mmxext) +PRED16x16(tm_vp8, 8, sse2) +PRED16x16(tm_vp8, 8, avx2) + +PRED8x8(top_dc, 8, mmxext) +PRED8x8(dc_rv40, 8, mmxext) +PRED8x8(dc, 8, mmxext) +PRED8x8(vertical, 8, mmx) +PRED8x8(horizontal, 8, mmx) +PRED8x8(horizontal, 8, mmxext) +PRED8x8(horizontal, 8, ssse3) +PRED8x8(plane, 8, mmx) +PRED8x8(plane, 8, mmxext) +PRED8x8(plane, 8, sse2) +PRED8x8(plane, 8, ssse3) +PRED8x8(tm_vp8, 8, mmx) +PRED8x8(tm_vp8, 8, mmxext) +PRED8x8(tm_vp8, 8, sse2) +PRED8x8(tm_vp8, 8, ssse3) + +PRED8x8L(top_dc, 8, mmxext) +PRED8x8L(top_dc, 8, ssse3) +PRED8x8L(dc, 8, mmxext) +PRED8x8L(dc, 8, ssse3) +PRED8x8L(horizontal, 8, mmxext) +PRED8x8L(horizontal, 8, ssse3) +PRED8x8L(vertical, 8, mmxext) +PRED8x8L(vertical, 8, ssse3) +PRED8x8L(down_left, 8, mmxext) +PRED8x8L(down_left, 8, sse2) +PRED8x8L(down_left, 8, ssse3) +PRED8x8L(down_right, 8, mmxext) +PRED8x8L(down_right, 8, sse2) +PRED8x8L(down_right, 8, ssse3) +PRED8x8L(vertical_right, 8, mmxext) +PRED8x8L(vertical_right, 8, sse2) +PRED8x8L(vertical_right, 8, ssse3) +PRED8x8L(vertical_left, 8, sse2) +PRED8x8L(vertical_left, 8, ssse3) +PRED8x8L(horizontal_up, 8, mmxext) +PRED8x8L(horizontal_up, 8, ssse3) +PRED8x8L(horizontal_down, 8, mmxext) +PRED8x8L(horizontal_down, 8, sse2) +PRED8x8L(horizontal_down, 8, ssse3) + +PRED4x4(dc, 8, mmxext) +PRED4x4(down_left, 8, mmxext) +PRED4x4(down_right, 8, mmxext) +PRED4x4(vertical_left, 8, mmxext) +PRED4x4(vertical_right, 8, mmxext) +PRED4x4(horizontal_up, 8, mmxext) +PRED4x4(horizontal_down, 8, mmxext) +PRED4x4(tm_vp8, 8, mmx) +PRED4x4(tm_vp8, 8, mmxext) +PRED4x4(tm_vp8, 8, ssse3) +PRED4x4(vertical_vp8, 8, mmxext) + +av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, + const int bit_depth, + const int chroma_format_idc) +{ + int cpu_flags = av_get_cpu_flags(); + + if (bit_depth == 8) { + if (EXTERNAL_MMX(cpu_flags)) { + h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_8_mmx; + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmx; + if (chroma_format_idc <= 1) { + h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x8_vertical_8_mmx; + h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_mmx; + } + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_mmx; + h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_mmx; + h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_8_mmx; + } else { + if (chroma_format_idc <= 1) + h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_mmx; + if (codec_id == AV_CODEC_ID_SVQ3) { + if (cpu_flags & AV_CPU_FLAG_CMOV) + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_mmx; + } else if (codec_id == AV_CODEC_ID_RV40) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_8_mmx; + } else { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_h264_8_mmx; + } + } + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmxext; + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_mmxext; + if (chroma_format_idc <= 1) + h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_mmxext; + h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_8_mmxext; + h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_8_mmxext; + h->pred8x8l [HOR_PRED ] = ff_pred8x8l_horizontal_8_mmxext; + h->pred8x8l [VERT_PRED ] = ff_pred8x8l_vertical_8_mmxext; + h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_mmxext; + h->pred8x8l [VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_8_mmxext; + h->pred8x8l [HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_8_mmxext; + h->pred8x8l [DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_8_mmxext; + h->pred8x8l [HOR_DOWN_PRED ] = ff_pred8x8l_horizontal_down_8_mmxext; + h->pred4x4 [DIAG_DOWN_RIGHT_PRED ] = ff_pred4x4_down_right_8_mmxext; + h->pred4x4 [VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_8_mmxext; + h->pred4x4 [HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_8_mmxext; + h->pred4x4 [DC_PRED ] = ff_pred4x4_dc_8_mmxext; + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8 || + codec_id == AV_CODEC_ID_H264) { + h->pred4x4 [DIAG_DOWN_LEFT_PRED] = ff_pred4x4_down_left_8_mmxext; + } + if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) { + h->pred4x4 [VERT_LEFT_PRED ] = ff_pred4x4_vertical_left_8_mmxext; + } + if (codec_id != AV_CODEC_ID_RV40) { + h->pred4x4 [HOR_UP_PRED ] = ff_pred4x4_horizontal_up_8_mmxext; + } + if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) { + if (chroma_format_idc <= 1) { + h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_8_mmxext; + h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_8_mmxext; + } + } + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_mmxext; + h->pred8x8 [DC_PRED8x8 ] = ff_pred8x8_dc_rv40_8_mmxext; + h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_mmxext; + h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_8_mmxext; + h->pred4x4 [VERT_PRED ] = ff_pred4x4_vertical_vp8_8_mmxext; + } else { + if (chroma_format_idc <= 1) + h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_mmxext; + if (codec_id == AV_CODEC_ID_SVQ3) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_svq3_8_mmxext; + } else if (codec_id == AV_CODEC_ID_RV40) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_rv40_8_mmxext; + } else { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_h264_8_mmxext; + } + } + } + + if (EXTERNAL_SSE(cpu_flags)) { + h->pred16x16[VERT_PRED8x8] = ff_pred16x16_vertical_8_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_sse2; + h->pred8x8l [DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_8_sse2; + h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_sse2; + h->pred8x8l [VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_8_sse2; + h->pred8x8l [VERT_LEFT_PRED ] = ff_pred8x8l_vertical_left_8_sse2; + h->pred8x8l [HOR_DOWN_PRED ] = ff_pred8x8l_horizontal_down_8_sse2; + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_sse2; + h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_sse2; + } else { + if (chroma_format_idc <= 1) + h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_sse2; + if (codec_id == AV_CODEC_ID_SVQ3) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_sse2; + } else if (codec_id == AV_CODEC_ID_RV40) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_8_sse2; + } else { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_h264_8_sse2; + } + } + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_ssse3; + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_ssse3; + if (chroma_format_idc <= 1) + h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_ssse3; + h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_8_ssse3; + h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_8_ssse3; + h->pred8x8l [HOR_PRED ] = ff_pred8x8l_horizontal_8_ssse3; + h->pred8x8l [VERT_PRED ] = ff_pred8x8l_vertical_8_ssse3; + h->pred8x8l [DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_8_ssse3; + h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_ssse3; + h->pred8x8l [VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_8_ssse3; + h->pred8x8l [VERT_LEFT_PRED ] = ff_pred8x8l_vertical_left_8_ssse3; + h->pred8x8l [HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_8_ssse3; + h->pred8x8l [HOR_DOWN_PRED ] = ff_pred8x8l_horizontal_down_8_ssse3; + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { + h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_ssse3; + h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_8_ssse3; + } else { + if (chroma_format_idc <= 1) + h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_ssse3; + if (codec_id == AV_CODEC_ID_SVQ3) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_ssse3; + } else if (codec_id == AV_CODEC_ID_RV40) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_8_ssse3; + } else { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_h264_8_ssse3; + } + } + } + + if(EXTERNAL_AVX2(cpu_flags)){ + if (codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_avx2; + } + } + } else if (bit_depth == 10) { + if (EXTERNAL_MMXEXT(cpu_flags)) { + h->pred4x4[DC_PRED ] = ff_pred4x4_dc_10_mmxext; + h->pred4x4[HOR_UP_PRED ] = ff_pred4x4_horizontal_up_10_mmxext; + + if (chroma_format_idc <= 1) + h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_10_mmxext; + + h->pred8x8l[DC_128_PRED ] = ff_pred8x8l_128_dc_10_mmxext; + + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_10_mmxext; + h->pred16x16[TOP_DC_PRED8x8 ] = ff_pred16x16_top_dc_10_mmxext; + h->pred16x16[DC_128_PRED8x8 ] = ff_pred16x16_128_dc_10_mmxext; + h->pred16x16[LEFT_DC_PRED8x8 ] = ff_pred16x16_left_dc_10_mmxext; + h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_10_mmxext; + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_10_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_sse2; + h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_sse2; + h->pred4x4[VERT_LEFT_PRED ] = ff_pred4x4_vertical_left_10_sse2; + h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_sse2; + h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_sse2; + + if (chroma_format_idc <= 1) { + h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_10_sse2; + h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_10_sse2; + h->pred8x8[PLANE_PRED8x8 ] = ff_pred8x8_plane_10_sse2; + h->pred8x8[VERT_PRED8x8 ] = ff_pred8x8_vertical_10_sse2; + h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_10_sse2; + } + + h->pred8x8l[VERT_PRED ] = ff_pred8x8l_vertical_10_sse2; + h->pred8x8l[HOR_PRED ] = ff_pred8x8l_horizontal_10_sse2; + h->pred8x8l[DC_PRED ] = ff_pred8x8l_dc_10_sse2; + h->pred8x8l[DC_128_PRED ] = ff_pred8x8l_128_dc_10_sse2; + h->pred8x8l[TOP_DC_PRED ] = ff_pred8x8l_top_dc_10_sse2; + h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_sse2; + h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_sse2; + h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_sse2; + h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_sse2; + + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_10_sse2; + h->pred16x16[TOP_DC_PRED8x8 ] = ff_pred16x16_top_dc_10_sse2; + h->pred16x16[DC_128_PRED8x8 ] = ff_pred16x16_128_dc_10_sse2; + h->pred16x16[LEFT_DC_PRED8x8 ] = ff_pred16x16_left_dc_10_sse2; + h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_10_sse2; + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_10_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_ssse3; + h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_ssse3; + h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_ssse3; + + h->pred8x8l[HOR_PRED ] = ff_pred8x8l_horizontal_10_ssse3; + h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_ssse3; + h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_ssse3; + h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_ssse3; + h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_ssse3; + } + if (EXTERNAL_AVX(cpu_flags)) { + h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_avx; + h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_avx; + h->pred4x4[VERT_LEFT_PRED ] = ff_pred4x4_vertical_left_10_avx; + h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_avx; + h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_avx; + + h->pred8x8l[VERT_PRED ] = ff_pred8x8l_vertical_10_avx; + h->pred8x8l[HOR_PRED ] = ff_pred8x8l_horizontal_10_avx; + h->pred8x8l[DC_PRED ] = ff_pred8x8l_dc_10_avx; + h->pred8x8l[TOP_DC_PRED ] = ff_pred8x8l_top_dc_10_avx; + h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_avx; + h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_avx; + h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_avx; + h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_avx; + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_qpel.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_qpel.c new file mode 100644 index 000000000..0d3dbbadb --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264_qpel.c @@ -0,0 +1,634 @@ +/* + * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt + * Copyright (c) 2011 Daniel Kang + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/h264dec.h" +#include "libavcodec/h264qpel.h" +#include "libavcodec/pixels.h" +#include "fpel.h" + +#if HAVE_X86ASM +void ff_put_pixels4_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels4_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_pixels8_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels8_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_pixels16_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels16_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +#define ff_put_pixels8_l2_sse2 ff_put_pixels8_l2_mmxext +#define ff_avg_pixels8_l2_sse2 ff_avg_pixels8_l2_mmxext +#define ff_put_pixels16_l2_sse2 ff_put_pixels16_l2_mmxext +#define ff_avg_pixels16_l2_sse2 ff_avg_pixels16_l2_mmxext +#define ff_put_pixels16_mmxext ff_put_pixels16_mmx +#define ff_put_pixels8_mmxext ff_put_pixels8_mmx +#define ff_put_pixels4_mmxext ff_put_pixels4_mmx + +#define DEF_QPEL(OPNAME)\ +void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_ssse3(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_l2_mmxext(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride);\ +void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_l2_mmxext(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride);\ +void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_l2_ssse3(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride);\ +void ff_ ## OPNAME ## _h264_qpel4_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel8or16_v_lowpass_op_mmxext(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h);\ +void ff_ ## OPNAME ## _h264_qpel8or16_v_lowpass_sse2(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h);\ +void ff_ ## OPNAME ## _h264_qpel4_hv_lowpass_v_mmxext(const uint8_t *src, int16_t *tmp, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel4_hv_lowpass_h_mmxext(int16_t *tmp, uint8_t *dst, int dstStride);\ +void ff_ ## OPNAME ## _h264_qpel8or16_hv1_lowpass_op_mmxext(const uint8_t *src, int16_t *tmp, int srcStride, int size);\ +void ff_ ## OPNAME ## _h264_qpel8or16_hv1_lowpass_op_sse2(const uint8_t *src, int16_t *tmp, int srcStride, int size);\ +void ff_ ## OPNAME ## _h264_qpel8or16_hv2_lowpass_op_mmxext(uint8_t *dst, int16_t *tmp, int dstStride, int unused, int h);\ +void ff_ ## OPNAME ## _h264_qpel8or16_hv2_lowpass_ssse3(uint8_t *dst, int16_t *tmp, int dstStride, int tmpStride, int size);\ +void ff_ ## OPNAME ## _pixels4_l2_shift5_mmxext(uint8_t *dst, const int16_t *src16, const uint8_t *src8, int dstStride, int src8Stride, int h);\ +void ff_ ## OPNAME ## _pixels8_l2_shift5_mmxext(uint8_t *dst, const int16_t *src16, const uint8_t *src8, int dstStride, int src8Stride, int h); + +DEF_QPEL(avg) +DEF_QPEL(put) + +static av_always_inline void ff_put_h264_qpel8or16_hv1_lowpass_mmxext(int16_t *tmp, const uint8_t *src, int tmpStride, int srcStride, int size) +{ + int w = (size + 8) >> 2; + src -= 2 * srcStride + 2; + while (w--) { + ff_put_h264_qpel8or16_hv1_lowpass_op_mmxext(src, tmp, srcStride, size); + tmp += 4; + src += 4; + } +} + +#define QPEL_H264(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel4_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + int w=3;\ + src -= 2*srcStride+2;\ + while(w--){\ + ff_ ## OPNAME ## h264_qpel4_hv_lowpass_v_mmxext(src, tmp, srcStride);\ + tmp += 4;\ + src += 4;\ + }\ + tmp -= 3*4;\ + ff_ ## OPNAME ## h264_qpel4_hv_lowpass_h_mmxext(tmp, dst, dstStride);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h){\ + src -= 2*srcStride;\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_op_mmxext(dst, src, dstStride, srcStride, h);\ + src += 4;\ + dst += 4;\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_op_mmxext(dst, src, dstStride, srcStride, h);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, int dstStride, int tmpStride, int size){\ + int w = size>>4;\ + do{\ + ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_op_mmxext(dst, tmp, dstStride, 0, size);\ + tmp += 8;\ + dst += 8;\ + }while(w--);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 16);\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_h_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_h_lowpass_l2_ ## MMX(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride){\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ + src += 8*dstStride;\ + dst += 8*dstStride;\ + src2 += 8*src2Stride;\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ + ff_put_h264_qpel8or16_hv1_lowpass_ ## MMX(tmp, src, tmpStride, srcStride, size);\ + ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst , tmp , src , dstStride, tmpStride, srcStride, 8);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst , tmp , src , dstStride, tmpStride, srcStride, 16);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## pixels16_l2_shift5_ ## MMX(uint8_t *dst, const int16_t *src16, const uint8_t *src8, int dstStride, int src8Stride, int h)\ +{\ + ff_ ## OPNAME ## pixels8_l2_shift5_ ## MMX(dst , src16 , src8 , dstStride, src8Stride, h);\ + ff_ ## OPNAME ## pixels8_l2_shift5_ ## MMX(dst+8, src16+8, src8+8, dstStride, src8Stride, h);\ +}\ + + +#if ARCH_X86_64 +#define QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ + +void ff_avg_h264_qpel16_h_lowpass_l2_ssse3(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride); +void ff_put_h264_qpel16_h_lowpass_l2_ssse3(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride); + +#else // ARCH_X86_64 +#define QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_h_lowpass_l2_ ## MMX(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride){\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ + src += 8*dstStride;\ + dst += 8*dstStride;\ + src2 += 8*src2Stride;\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ +} +#endif // ARCH_X86_64 + +#define QPEL_H264_H_XMM(OPNAME, OP, MMX)\ +QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_h_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ +}\ + +#define QPEL_H264_V_XMM(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 16);\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +} + +static av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, + const uint8_t *src, + int tmpStride, + int srcStride, + int size) +{ + int w = (size+8)>>3; + src -= 2*srcStride+2; + while(w--){ + ff_put_h264_qpel8or16_hv1_lowpass_op_sse2(src, tmp, srcStride, size); + tmp += 8; + src += 8; + } +} + +#define QPEL_H264_HV_XMM(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ + put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\ + ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst, tmp, src, dstStride, tmpStride, srcStride, 8);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst, tmp, src, dstStride, tmpStride, srcStride, 16);\ +}\ + +#define ff_put_h264_qpel8_h_lowpass_l2_sse2 ff_put_h264_qpel8_h_lowpass_l2_mmxext +#define ff_avg_h264_qpel8_h_lowpass_l2_sse2 ff_avg_h264_qpel8_h_lowpass_l2_mmxext +#define ff_put_h264_qpel16_h_lowpass_l2_sse2 ff_put_h264_qpel16_h_lowpass_l2_mmxext +#define ff_avg_h264_qpel16_h_lowpass_l2_sse2 ff_avg_h264_qpel16_h_lowpass_l2_mmxext + +#define ff_put_h264_qpel8_v_lowpass_ssse3 ff_put_h264_qpel8_v_lowpass_sse2 +#define ff_avg_h264_qpel8_v_lowpass_ssse3 ff_avg_h264_qpel8_v_lowpass_sse2 +#define ff_put_h264_qpel16_v_lowpass_ssse3 ff_put_h264_qpel16_v_lowpass_sse2 +#define ff_avg_h264_qpel16_v_lowpass_ssse3 ff_avg_h264_qpel16_v_lowpass_sse2 + +#define ff_put_h264_qpel8or16_hv2_lowpass_sse2 ff_put_h264_qpel8or16_hv2_lowpass_mmxext +#define ff_avg_h264_qpel8or16_hv2_lowpass_sse2 ff_avg_h264_qpel8or16_hv2_lowpass_mmxext + +#define H264_MC(OPNAME, SIZE, MMX, ALIGN) \ +H264_MC_C(OPNAME, SIZE, MMX, ALIGN)\ +H264_MC_V(OPNAME, SIZE, MMX, ALIGN)\ +H264_MC_H(OPNAME, SIZE, MMX, ALIGN)\ +H264_MC_HV(OPNAME, SIZE, MMX, ALIGN)\ + +static void put_h264_qpel16_mc00_sse2 (uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels16_sse2(dst, src, stride, 16); +} +static void avg_h264_qpel16_mc00_sse2 (uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_sse2(dst, src, stride, 16); +} +#define put_h264_qpel8_mc00_sse2 put_h264_qpel8_mc00_mmxext +#define avg_h264_qpel8_mc00_sse2 avg_h264_qpel8_mc00_mmxext + +#define H264_MC_C(OPNAME, SIZE, MMX, ALIGN) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## MMX (uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## pixels ## SIZE ## _ ## MMX(dst, src, stride, SIZE);\ +}\ + +#define H264_MC_H(OPNAME, SIZE, MMX, ALIGN) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src+1, stride, stride);\ +}\ + +#define H264_MC_V(OPNAME, SIZE, MMX, ALIGN) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + ff_ ## OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src, temp, stride, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + ff_ ## OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src+stride, temp, stride, stride, SIZE);\ +}\ + +#define H264_MC_HV(OPNAME, SIZE, MMX, ALIGN) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint16_t, temp, [SIZE*(SIZE<8?12:24)]);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(dst, temp, src, stride, SIZE, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + av_assert2(((int)temp & 7) == 0);\ + ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfHV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + av_assert2(((int)temp & 7) == 0);\ + ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfHV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + av_assert2(((int)temp & 7) == 0);\ + ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + ff_ ## OPNAME ## pixels ## SIZE ## _l2_shift5_mmxext(dst, halfV+2, halfHV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + av_assert2(((int)temp & 7) == 0);\ + ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + ff_ ## OPNAME ## pixels ## SIZE ## _l2_shift5_mmxext(dst, halfV+3, halfHV, stride, SIZE, SIZE);\ +}\ + +#define H264_MC_4816(MMX)\ +H264_MC(put_, 4, MMX, 8)\ +H264_MC(put_, 8, MMX, 8)\ +H264_MC(put_, 16,MMX, 8)\ +H264_MC(avg_, 4, MMX, 8)\ +H264_MC(avg_, 8, MMX, 8)\ +H264_MC(avg_, 16,MMX, 8)\ + +#define H264_MC_816(QPEL, XMM)\ +QPEL(put_, 8, XMM, 16)\ +QPEL(put_, 16,XMM, 16)\ +QPEL(avg_, 8, XMM, 16)\ +QPEL(avg_, 16,XMM, 16)\ + +QPEL_H264(put_, PUT_OP, mmxext) +QPEL_H264(avg_, AVG_MMXEXT_OP, mmxext) +QPEL_H264_V_XMM(put_, PUT_OP, sse2) +QPEL_H264_V_XMM(avg_,AVG_MMXEXT_OP, sse2) +QPEL_H264_HV_XMM(put_, PUT_OP, sse2) +QPEL_H264_HV_XMM(avg_,AVG_MMXEXT_OP, sse2) +QPEL_H264_H_XMM(put_, PUT_OP, ssse3) +QPEL_H264_H_XMM(avg_,AVG_MMXEXT_OP, ssse3) +QPEL_H264_HV_XMM(put_, PUT_OP, ssse3) +QPEL_H264_HV_XMM(avg_,AVG_MMXEXT_OP, ssse3) + +H264_MC_4816(mmxext) +H264_MC_816(H264_MC_V, sse2) +H264_MC_816(H264_MC_HV, sse2) +H264_MC_816(H264_MC_H, ssse3) +H264_MC_816(H264_MC_HV, ssse3) + + +//10bit +#define LUMA_MC_OP(OP, NUM, DEPTH, TYPE, OPT) \ +void ff_ ## OP ## _h264_qpel ## NUM ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT \ + (uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + +#define LUMA_MC_ALL(DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 4, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 4, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 8, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 8, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 16, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 16, DEPTH, TYPE, OPT) + +#define LUMA_MC_816(DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 8, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 8, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 16, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 16, DEPTH, TYPE, OPT) + +LUMA_MC_ALL(10, mc00, mmxext) +LUMA_MC_ALL(10, mc10, mmxext) +LUMA_MC_ALL(10, mc20, mmxext) +LUMA_MC_ALL(10, mc30, mmxext) +LUMA_MC_ALL(10, mc01, mmxext) +LUMA_MC_ALL(10, mc11, mmxext) +LUMA_MC_ALL(10, mc21, mmxext) +LUMA_MC_ALL(10, mc31, mmxext) +LUMA_MC_ALL(10, mc02, mmxext) +LUMA_MC_ALL(10, mc12, mmxext) +LUMA_MC_ALL(10, mc22, mmxext) +LUMA_MC_ALL(10, mc32, mmxext) +LUMA_MC_ALL(10, mc03, mmxext) +LUMA_MC_ALL(10, mc13, mmxext) +LUMA_MC_ALL(10, mc23, mmxext) +LUMA_MC_ALL(10, mc33, mmxext) + +LUMA_MC_816(10, mc00, sse2) +LUMA_MC_816(10, mc10, sse2) +LUMA_MC_816(10, mc10, sse2_cache64) +LUMA_MC_816(10, mc10, ssse3_cache64) +LUMA_MC_816(10, mc20, sse2) +LUMA_MC_816(10, mc20, sse2_cache64) +LUMA_MC_816(10, mc20, ssse3_cache64) +LUMA_MC_816(10, mc30, sse2) +LUMA_MC_816(10, mc30, sse2_cache64) +LUMA_MC_816(10, mc30, ssse3_cache64) +LUMA_MC_816(10, mc01, sse2) +LUMA_MC_816(10, mc11, sse2) +LUMA_MC_816(10, mc21, sse2) +LUMA_MC_816(10, mc31, sse2) +LUMA_MC_816(10, mc02, sse2) +LUMA_MC_816(10, mc12, sse2) +LUMA_MC_816(10, mc22, sse2) +LUMA_MC_816(10, mc32, sse2) +LUMA_MC_816(10, mc03, sse2) +LUMA_MC_816(10, mc13, sse2) +LUMA_MC_816(10, mc23, sse2) +LUMA_MC_816(10, mc33, sse2) + +#define QPEL16_OPMC(OP, MC, MMX)\ +void ff_ ## OP ## _h264_qpel16_ ## MC ## _10_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride){\ + ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst , src , stride);\ + ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst+16, src+16, stride);\ + src += 8*stride;\ + dst += 8*stride;\ + ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst , src , stride);\ + ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst+16, src+16, stride);\ +} + +#define QPEL16_OP(MC, MMX)\ +QPEL16_OPMC(put, MC, MMX)\ +QPEL16_OPMC(avg, MC, MMX) + +#define QPEL16(MMX)\ +QPEL16_OP(mc00, MMX)\ +QPEL16_OP(mc01, MMX)\ +QPEL16_OP(mc02, MMX)\ +QPEL16_OP(mc03, MMX)\ +QPEL16_OP(mc10, MMX)\ +QPEL16_OP(mc11, MMX)\ +QPEL16_OP(mc12, MMX)\ +QPEL16_OP(mc13, MMX)\ +QPEL16_OP(mc20, MMX)\ +QPEL16_OP(mc21, MMX)\ +QPEL16_OP(mc22, MMX)\ +QPEL16_OP(mc23, MMX)\ +QPEL16_OP(mc30, MMX)\ +QPEL16_OP(mc31, MMX)\ +QPEL16_OP(mc32, MMX)\ +QPEL16_OP(mc33, MMX) + +#if ARCH_X86_32 // ARCH_X86_64 implies SSE2+ +QPEL16(mmxext) +#endif + +#endif /* HAVE_X86ASM */ + +#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX) \ + do { \ + c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \ + } while (0) + +#define H264_QPEL_FUNCS(x, y, CPU) \ + do { \ + c->put_h264_qpel_pixels_tab[0][x + y * 4] = put_h264_qpel16_mc ## x ## y ## _ ## CPU; \ + c->put_h264_qpel_pixels_tab[1][x + y * 4] = put_h264_qpel8_mc ## x ## y ## _ ## CPU; \ + c->avg_h264_qpel_pixels_tab[0][x + y * 4] = avg_h264_qpel16_mc ## x ## y ## _ ## CPU; \ + c->avg_h264_qpel_pixels_tab[1][x + y * 4] = avg_h264_qpel8_mc ## x ## y ## _ ## CPU; \ + } while (0) + +#define H264_QPEL_FUNCS_10(x, y, CPU) \ + do { \ + c->put_h264_qpel_pixels_tab[0][x + y * 4] = ff_put_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \ + c->put_h264_qpel_pixels_tab[1][x + y * 4] = ff_put_h264_qpel8_mc ## x ## y ## _10_ ## CPU; \ + c->avg_h264_qpel_pixels_tab[0][x + y * 4] = ff_avg_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \ + c->avg_h264_qpel_pixels_tab[1][x + y * 4] = ff_avg_h264_qpel8_mc ## x ## y ## _10_ ## CPU; \ + } while (0) + +av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth) +{ +#if HAVE_X86ASM + int high_bit_depth = bit_depth > 8; + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMXEXT(cpu_flags)) { + if (!high_bit_depth) { + SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(put_h264_qpel, 1, 8, mmxext, ); + SET_QPEL_FUNCS(put_h264_qpel, 2, 4, mmxext, ); + SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, mmxext, ); + SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, mmxext, ); + } else if (bit_depth == 10) { +#if ARCH_X86_32 + SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_mmxext, ff_); + SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_mmxext, ff_); + SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 10_mmxext, ff_); + SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 10_mmxext, ff_); +#endif + SET_QPEL_FUNCS(put_h264_qpel, 2, 4, 10_mmxext, ff_); + SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, 10_mmxext, ff_); + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + if (!high_bit_depth) { + H264_QPEL_FUNCS(0, 1, sse2); + H264_QPEL_FUNCS(0, 2, sse2); + H264_QPEL_FUNCS(0, 3, sse2); + H264_QPEL_FUNCS(1, 1, sse2); + H264_QPEL_FUNCS(1, 2, sse2); + H264_QPEL_FUNCS(1, 3, sse2); + H264_QPEL_FUNCS(2, 1, sse2); + H264_QPEL_FUNCS(2, 2, sse2); + H264_QPEL_FUNCS(2, 3, sse2); + H264_QPEL_FUNCS(3, 1, sse2); + H264_QPEL_FUNCS(3, 2, sse2); + H264_QPEL_FUNCS(3, 3, sse2); + } + + if (bit_depth == 10) { + SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_sse2, ff_); + SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 10_sse2, ff_); + SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_sse2, ff_); + SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 10_sse2, ff_); + H264_QPEL_FUNCS_10(1, 0, sse2_cache64); + H264_QPEL_FUNCS_10(2, 0, sse2_cache64); + H264_QPEL_FUNCS_10(3, 0, sse2_cache64); + } + } + + if (EXTERNAL_SSE2_FAST(cpu_flags)) { + if (!high_bit_depth) { + H264_QPEL_FUNCS(0, 0, sse2); + } + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + if (!high_bit_depth) { + H264_QPEL_FUNCS(1, 0, ssse3); + H264_QPEL_FUNCS(1, 1, ssse3); + H264_QPEL_FUNCS(1, 2, ssse3); + H264_QPEL_FUNCS(1, 3, ssse3); + H264_QPEL_FUNCS(2, 0, ssse3); + H264_QPEL_FUNCS(2, 1, ssse3); + H264_QPEL_FUNCS(2, 2, ssse3); + H264_QPEL_FUNCS(2, 3, ssse3); + H264_QPEL_FUNCS(3, 0, ssse3); + H264_QPEL_FUNCS(3, 1, ssse3); + H264_QPEL_FUNCS(3, 2, ssse3); + H264_QPEL_FUNCS(3, 3, ssse3); + } + + if (bit_depth == 10) { + H264_QPEL_FUNCS_10(1, 0, ssse3_cache64); + H264_QPEL_FUNCS_10(2, 0, ssse3_cache64); + H264_QPEL_FUNCS_10(3, 0, ssse3_cache64); + } + } + + if (EXTERNAL_AVX(cpu_flags)) { + /* AVX implies 64 byte cache lines without the need to avoid unaligned + * memory accesses that cross the boundary between two cache lines. + * TODO: Port X264_CPU_CACHELINE_32/64 detection from x264 to avoid + * having to treat SSE2 functions with such properties as AVX. */ + if (bit_depth == 10) { + H264_QPEL_FUNCS_10(1, 0, sse2); + H264_QPEL_FUNCS_10(2, 0, sse2); + H264_QPEL_FUNCS_10(3, 0, sse2); + } + } +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264chroma_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264chroma_init.c new file mode 100644 index 000000000..36bf29df0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264chroma_init.c @@ -0,0 +1,117 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/h264chroma.h" + +void ff_put_h264_chroma_mc8_rnd_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc8_rnd_mmxext(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc8_rnd_3dnow(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_put_h264_chroma_mc4_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc4_mmxext (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc4_3dnow (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_put_h264_chroma_mc2_mmxext (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc2_mmxext (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_put_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_put_h264_chroma_mc4_ssse3 (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_avg_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc4_ssse3 (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +#define CHROMA_MC(OP, NUM, DEPTH, OPT) \ +void ff_ ## OP ## _h264_chroma_mc ## NUM ## _ ## DEPTH ## _ ## OPT \ + (uint8_t *dst, uint8_t *src, \ + ptrdiff_t stride, int h, int x, int y); + +CHROMA_MC(put, 2, 10, mmxext) +CHROMA_MC(avg, 2, 10, mmxext) +CHROMA_MC(put, 4, 10, mmxext) +CHROMA_MC(avg, 4, 10, mmxext) +CHROMA_MC(put, 8, 10, sse2) +CHROMA_MC(avg, 8, 10, sse2) +CHROMA_MC(put, 8, 10, avx) +CHROMA_MC(avg, 8, 10, avx) + +av_cold void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth) +{ + int high_bit_depth = bit_depth > 8; + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags) && !high_bit_depth) { + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_mmx; + c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_mmx; + } + + if (EXTERNAL_AMD3DNOW(cpu_flags) && !high_bit_depth) { + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_3dnow; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_3dnow; + } + + if (EXTERNAL_MMXEXT(cpu_flags) && !high_bit_depth) { + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_mmxext; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_mmxext; + c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_mmxext; + c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_mmxext; + } + + if (EXTERNAL_MMXEXT(cpu_flags) && bit_depth > 8 && bit_depth <= 10) { + c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_10_mmxext; + c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_10_mmxext; + c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_10_mmxext; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_10_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags) && bit_depth > 8 && bit_depth <= 10) { + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_sse2; + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_sse2; + } + + if (EXTERNAL_SSSE3(cpu_flags) && !high_bit_depth) { + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_ssse3; + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_ssse3; + c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_ssse3; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_ssse3; + } + + if (EXTERNAL_AVX(cpu_flags) && bit_depth > 8 && bit_depth <= 10) { + // AVX implies !cache64. + // TODO: Port cache(32|64) detection from x264. + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_avx; + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_avx; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264dsp_init.c new file mode 100644 index 000000000..08eb7ead4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/h264dsp_init.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/h264dsp.h" + +/***********************************/ +/* IDCT */ +#define IDCT_ADD_FUNC(NUM, DEPTH, OPT) \ +void ff_h264_idct ## NUM ## _add_ ## DEPTH ## _ ## OPT(uint8_t *dst, \ + int16_t *block, \ + int stride); + +IDCT_ADD_FUNC(, 8, mmx) +IDCT_ADD_FUNC(, 8, sse2) +IDCT_ADD_FUNC(, 8, avx) +IDCT_ADD_FUNC(, 10, sse2) +IDCT_ADD_FUNC(_dc, 8, mmxext) +IDCT_ADD_FUNC(_dc, 8, sse2) +IDCT_ADD_FUNC(_dc, 8, avx) +IDCT_ADD_FUNC(_dc, 10, mmxext) +IDCT_ADD_FUNC(8_dc, 8, mmxext) +IDCT_ADD_FUNC(8_dc, 10, sse2) +IDCT_ADD_FUNC(8, 8, mmx) +IDCT_ADD_FUNC(8, 8, sse2) +IDCT_ADD_FUNC(8, 10, sse2) +IDCT_ADD_FUNC(, 10, avx) +IDCT_ADD_FUNC(8_dc, 10, avx) +IDCT_ADD_FUNC(8, 10, avx) + + +#define IDCT_ADD_REP_FUNC(NUM, REP, DEPTH, OPT) \ +void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT \ + (uint8_t *dst, const int *block_offset, \ + int16_t *block, int stride, const uint8_t nnzc[6 * 8]); + +IDCT_ADD_REP_FUNC(8, 4, 8, mmx) +IDCT_ADD_REP_FUNC(8, 4, 8, mmxext) +IDCT_ADD_REP_FUNC(8, 4, 8, sse2) +IDCT_ADD_REP_FUNC(8, 4, 10, sse2) +IDCT_ADD_REP_FUNC(8, 4, 10, avx) +IDCT_ADD_REP_FUNC(, 16, 8, mmx) +IDCT_ADD_REP_FUNC(, 16, 8, mmxext) +IDCT_ADD_REP_FUNC(, 16, 8, sse2) +IDCT_ADD_REP_FUNC(, 16, 10, sse2) +IDCT_ADD_REP_FUNC(, 16intra, 8, mmx) +IDCT_ADD_REP_FUNC(, 16intra, 8, mmxext) +IDCT_ADD_REP_FUNC(, 16intra, 8, sse2) +IDCT_ADD_REP_FUNC(, 16intra, 10, sse2) +IDCT_ADD_REP_FUNC(, 16, 10, avx) +IDCT_ADD_REP_FUNC(, 16intra, 10, avx) + + +#define IDCT_ADD_REP_FUNC2(NUM, REP, DEPTH, OPT) \ +void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT \ + (uint8_t **dst, const int *block_offset, \ + int16_t *block, int stride, const uint8_t nnzc[6 * 8]); + +IDCT_ADD_REP_FUNC2(, 8, 8, mmx) +IDCT_ADD_REP_FUNC2(, 8, 8, mmxext) +IDCT_ADD_REP_FUNC2(, 8, 8, sse2) +IDCT_ADD_REP_FUNC2(, 8, 10, sse2) +IDCT_ADD_REP_FUNC2(, 8, 10, avx) + +IDCT_ADD_REP_FUNC2(, 8_422, 8, mmx) + +IDCT_ADD_REP_FUNC2(, 8_422, 10, sse2) +IDCT_ADD_REP_FUNC2(, 8_422, 10, avx) + +void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul); +void ff_h264_luma_dc_dequant_idct_sse2(int16_t *output, int16_t *input, int qmul); + +/***********************************/ +/* deblocking */ + +void ff_h264_loop_filter_strength_mmxext(int16_t bS[2][4][4], uint8_t nnz[40], + int8_t ref[2][40], + int16_t mv[2][40][2], + int bidir, int edges, int step, + int mask_mv0, int mask_mv1, int field); + +#define LF_FUNC(DIR, TYPE, DEPTH, OPT) \ +void ff_deblock_ ## DIR ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT(uint8_t *pix, \ + ptrdiff_t stride, \ + int alpha, \ + int beta, \ + int8_t *tc0); +#define LF_IFUNC(DIR, TYPE, DEPTH, OPT) \ +void ff_deblock_ ## DIR ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT(uint8_t *pix, \ + ptrdiff_t stride, \ + int alpha, \ + int beta); + +#define LF_FUNCS(type, depth) \ +LF_FUNC(h, chroma, depth, mmxext) \ +LF_IFUNC(h, chroma_intra, depth, mmxext) \ +LF_FUNC(h, chroma422, depth, mmxext) \ +LF_IFUNC(h, chroma422_intra, depth, mmxext) \ +LF_FUNC(v, chroma, depth, mmxext) \ +LF_IFUNC(v, chroma_intra, depth, mmxext) \ +LF_FUNC(h, luma, depth, mmxext) \ +LF_IFUNC(h, luma_intra, depth, mmxext) \ +LF_FUNC(h, luma, depth, sse2) \ +LF_IFUNC(h, luma_intra, depth, sse2) \ +LF_FUNC(v, luma, depth, sse2) \ +LF_IFUNC(v, luma_intra, depth, sse2) \ +LF_FUNC(h, chroma, depth, sse2) \ +LF_IFUNC(h, chroma_intra, depth, sse2) \ +LF_FUNC(h, chroma422, depth, sse2) \ +LF_IFUNC(h, chroma422_intra, depth, sse2) \ +LF_FUNC(v, chroma, depth, sse2) \ +LF_IFUNC(v, chroma_intra, depth, sse2) \ +LF_FUNC(h, luma, depth, avx) \ +LF_IFUNC(h, luma_intra, depth, avx) \ +LF_FUNC(v, luma, depth, avx) \ +LF_IFUNC(v, luma_intra, depth, avx) \ +LF_FUNC(h, chroma, depth, avx) \ +LF_IFUNC(h, chroma_intra, depth, avx) \ +LF_FUNC(h, chroma422, depth, avx) \ +LF_IFUNC(h, chroma422_intra, depth, avx) \ +LF_FUNC(v, chroma, depth, avx) \ +LF_IFUNC(v, chroma_intra, depth, avx) + +LF_FUNC(h, luma_mbaff, 8, sse2) +LF_FUNC(h, luma_mbaff, 8, avx) + +LF_FUNCS(uint8_t, 8) +LF_FUNCS(uint16_t, 10) + +#if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL +LF_FUNC(v8, luma, 8, mmxext) +static void deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha, + int beta, int8_t *tc0) +{ + if ((tc0[0] & tc0[1]) >= 0) + ff_deblock_v8_luma_8_mmxext(pix + 0, stride, alpha, beta, tc0); + if ((tc0[2] & tc0[3]) >= 0) + ff_deblock_v8_luma_8_mmxext(pix + 8, stride, alpha, beta, tc0 + 2); +} +LF_IFUNC(v8, luma_intra, 8, mmxext) +static void deblock_v_luma_intra_8_mmxext(uint8_t *pix, int stride, + int alpha, int beta) +{ + ff_deblock_v8_luma_intra_8_mmxext(pix + 0, stride, alpha, beta); + ff_deblock_v8_luma_intra_8_mmxext(pix + 8, stride, alpha, beta); +} +#endif /* ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL */ + +LF_FUNC(v, luma, 10, mmxext) +LF_IFUNC(v, luma_intra, 10, mmxext) + +/***********************************/ +/* weighted prediction */ + +#define H264_WEIGHT(W, OPT) \ +void ff_h264_weight_ ## W ## _ ## OPT(uint8_t *dst, ptrdiff_t stride, \ + int height, int log2_denom, \ + int weight, int offset); + +#define H264_BIWEIGHT(W, OPT) \ +void ff_h264_biweight_ ## W ## _ ## OPT(uint8_t *dst, uint8_t *src, \ + ptrdiff_t stride, int height, \ + int log2_denom, int weightd, \ + int weights, int offset); + +#define H264_BIWEIGHT_MMX(W) \ + H264_WEIGHT(W, mmxext) \ + H264_BIWEIGHT(W, mmxext) + +#define H264_BIWEIGHT_MMX_SSE(W) \ + H264_BIWEIGHT_MMX(W) \ + H264_WEIGHT(W, sse2) \ + H264_BIWEIGHT(W, sse2) \ + H264_BIWEIGHT(W, ssse3) + +H264_BIWEIGHT_MMX_SSE(16) +H264_BIWEIGHT_MMX_SSE(8) +H264_BIWEIGHT_MMX(4) + +#define H264_WEIGHT_10(W, DEPTH, OPT) \ +void ff_h264_weight_ ## W ## _ ## DEPTH ## _ ## OPT(uint8_t *dst, \ + ptrdiff_t stride, \ + int height, \ + int log2_denom, \ + int weight, \ + int offset); + +#define H264_BIWEIGHT_10(W, DEPTH, OPT) \ +void ff_h264_biweight_ ## W ## _ ## DEPTH ## _ ## OPT(uint8_t *dst, \ + uint8_t *src, \ + ptrdiff_t stride, \ + int height, \ + int log2_denom, \ + int weightd, \ + int weights, \ + int offset); + +#define H264_BIWEIGHT_10_SSE(W, DEPTH) \ + H264_WEIGHT_10(W, DEPTH, sse2) \ + H264_WEIGHT_10(W, DEPTH, sse4) \ + H264_BIWEIGHT_10(W, DEPTH, sse2) \ + H264_BIWEIGHT_10(W, DEPTH, sse4) + +H264_BIWEIGHT_10_SSE(16, 10) +H264_BIWEIGHT_10_SSE(8, 10) +H264_BIWEIGHT_10_SSE(4, 10) + +av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, + const int chroma_format_idc) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMXEXT(cpu_flags) && chroma_format_idc <= 1) + c->h264_loop_filter_strength = ff_h264_loop_filter_strength_mmxext; + + if (bit_depth == 8) { + if (EXTERNAL_MMX(cpu_flags)) { + c->h264_idct_dc_add = + c->h264_idct_add = ff_h264_idct_add_8_mmx; + c->h264_idct8_dc_add = + c->h264_idct8_add = ff_h264_idct8_add_8_mmx; + + c->h264_idct_add16 = ff_h264_idct_add16_8_mmx; + c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmx; + if (chroma_format_idc <= 1) { + c->h264_idct_add8 = ff_h264_idct_add8_8_mmx; + } else { + c->h264_idct_add8 = ff_h264_idct_add8_422_8_mmx; + } + c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmx; + if (cpu_flags & AV_CPU_FLAG_CMOV) + c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_mmx; + } + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmxext; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext; + c->h264_idct_add16 = ff_h264_idct_add16_8_mmxext; + c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmxext; + if (chroma_format_idc <= 1) + c->h264_idct_add8 = ff_h264_idct_add8_8_mmxext; + c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmxext; + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_mmxext; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_mmxext; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_8_mmxext; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_mmxext; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_8_mmxext; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma422_intra_8_mmxext; + } +#if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL + c->h264_v_loop_filter_luma = deblock_v_luma_8_mmxext; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_mmxext; + c->h264_v_loop_filter_luma_intra = deblock_v_luma_intra_8_mmxext; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmxext; +#endif /* ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL */ + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_mmxext; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_mmxext; + c->weight_h264_pixels_tab[2] = ff_h264_weight_4_mmxext; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_mmxext; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_mmxext; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->h264_idct8_add = ff_h264_idct8_add_8_sse2; + + c->h264_idct_add16 = ff_h264_idct_add16_8_sse2; + c->h264_idct8_add4 = ff_h264_idct8_add4_8_sse2; + if (chroma_format_idc <= 1) + c->h264_idct_add8 = ff_h264_idct_add8_8_sse2; + c->h264_idct_add16intra = ff_h264_idct_add16intra_8_sse2; + c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_sse2; + + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_sse2; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_sse2; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_sse2; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_sse2; + + c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_sse2; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_sse2; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_sse2; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_sse2; + +#if ARCH_X86_64 + c->h264_h_loop_filter_luma_mbaff = ff_deblock_h_luma_mbaff_8_sse2; +#endif + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_sse2; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_sse2; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_8_sse2; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_sse2; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_8_sse2; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma422_intra_8_sse2; + } + + c->h264_idct_add = ff_h264_idct_add_8_sse2; + c->h264_idct_dc_add = ff_h264_idct_dc_add_8_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_ssse3; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_ssse3; + } + if (EXTERNAL_AVX(cpu_flags)) { + c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_avx; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_avx; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_avx; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_avx; +#if ARCH_X86_64 + c->h264_h_loop_filter_luma_mbaff = ff_deblock_h_luma_mbaff_8_avx; +#endif + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_avx; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_avx; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_8_avx; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_avx; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_8_avx; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma422_intra_8_avx; + } + + c->h264_idct_add = ff_h264_idct_add_8_avx; + c->h264_idct_dc_add = ff_h264_idct_dc_add_8_avx; + } + } else if (bit_depth == 10) { + if (EXTERNAL_MMXEXT(cpu_flags)) { +#if ARCH_X86_32 + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_mmxext; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_mmxext; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_10_mmxext; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_10_mmxext; + } + c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_mmxext; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_mmxext; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_mmxext; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_mmxext; +#endif /* ARCH_X86_32 */ + c->h264_idct_dc_add = ff_h264_idct_dc_add_10_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->h264_idct_add = ff_h264_idct_add_10_sse2; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2; + + c->h264_idct_add16 = ff_h264_idct_add16_10_sse2; + if (chroma_format_idc <= 1) { + c->h264_idct_add8 = ff_h264_idct_add8_10_sse2; + } else { + c->h264_idct_add8 = ff_h264_idct_add8_422_10_sse2; + } + c->h264_idct_add16intra = ff_h264_idct_add16intra_10_sse2; +#if HAVE_ALIGNED_STACK + c->h264_idct8_add = ff_h264_idct8_add_10_sse2; + c->h264_idct8_add4 = ff_h264_idct8_add4_10_sse2; +#endif /* HAVE_ALIGNED_STACK */ + + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse2; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse2; + c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse2; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse2; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse2; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse2; + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_sse2; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_sse2; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_10_sse2; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_10_sse2; + } +#if HAVE_ALIGNED_STACK + c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_sse2; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_sse2; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_sse2; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_sse2; +#endif /* HAVE_ALIGNED_STACK */ + } + if (EXTERNAL_SSE4(cpu_flags)) { + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse4; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse4; + c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse4; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse4; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse4; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse4; + } + if (EXTERNAL_AVX(cpu_flags)) { + c->h264_idct_dc_add = + c->h264_idct_add = ff_h264_idct_add_10_avx; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx; + + c->h264_idct_add16 = ff_h264_idct_add16_10_avx; + if (chroma_format_idc <= 1) { + c->h264_idct_add8 = ff_h264_idct_add8_10_avx; + } else { + c->h264_idct_add8 = ff_h264_idct_add8_422_10_avx; + } + c->h264_idct_add16intra = ff_h264_idct_add16intra_10_avx; +#if HAVE_ALIGNED_STACK + c->h264_idct8_add = ff_h264_idct8_add_10_avx; + c->h264_idct8_add4 = ff_h264_idct8_add4_10_avx; +#endif /* HAVE_ALIGNED_STACK */ + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_avx; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_avx; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_10_avx; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_10_avx; + } +#if HAVE_ALIGNED_STACK + c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_avx; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_avx; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_avx; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_avx; +#endif /* HAVE_ALIGNED_STACK */ + } + } +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hevcdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hevcdsp.h new file mode 100644 index 000000000..67be0a905 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hevcdsp.h @@ -0,0 +1,259 @@ +/* + * HEVC video decoder + * + * Copyright (C) 2012 - 2013 Guillaume Martres + * Copyright (C) 2013 - 2014 Pierre-Edouard Lepere + * + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_HEVCDSP_H +#define AVCODEC_X86_HEVCDSP_H + +#include +#include + + +#define PEL_LINK(dst, idx1, idx2, idx3, name, D, opt) \ +dst[idx1][idx2][idx3] = ff_hevc_put_hevc_ ## name ## _ ## D ## _##opt; \ +dst ## _bi[idx1][idx2][idx3] = ff_hevc_put_hevc_bi_ ## name ## _ ## D ## _##opt; \ +dst ## _uni[idx1][idx2][idx3] = ff_hevc_put_hevc_uni_ ## name ## _ ## D ## _##opt; \ +dst ## _uni_w[idx1][idx2][idx3] = ff_hevc_put_hevc_uni_w_ ## name ## _ ## D ## _##opt; \ +dst ## _bi_w[idx1][idx2][idx3] = ff_hevc_put_hevc_bi_w_ ## name ## _ ## D ## _##opt + + +#define PEL_PROTOTYPE(name, D, opt) \ +void ff_hevc_put_hevc_ ## name ## _ ## D ## _##opt(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); \ +void ff_hevc_put_hevc_bi_ ## name ## _ ## D ## _##opt(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); \ +void ff_hevc_put_hevc_uni_ ## name ## _ ## D ## _##opt(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my, int width); \ +void ff_hevc_put_hevc_uni_w_ ## name ## _ ## D ## _##opt(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width); \ +void ff_hevc_put_hevc_bi_w_ ## name ## _ ## D ## _##opt(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, int denom, int wx0, int wx1, int ox0, int ox1, intptr_t mx, intptr_t my, int width) + + +/////////////////////////////////////////////////////////////////////////////// +// MC functions +/////////////////////////////////////////////////////////////////////////////// + +#define EPEL_PROTOTYPES(fname, bitd, opt) \ + PEL_PROTOTYPE(fname##4, bitd, opt); \ + PEL_PROTOTYPE(fname##6, bitd, opt); \ + PEL_PROTOTYPE(fname##8, bitd, opt); \ + PEL_PROTOTYPE(fname##12, bitd, opt); \ + PEL_PROTOTYPE(fname##16, bitd, opt); \ + PEL_PROTOTYPE(fname##24, bitd, opt); \ + PEL_PROTOTYPE(fname##32, bitd, opt); \ + PEL_PROTOTYPE(fname##48, bitd, opt); \ + PEL_PROTOTYPE(fname##64, bitd, opt) + +#define QPEL_PROTOTYPES(fname, bitd, opt) \ + PEL_PROTOTYPE(fname##4, bitd, opt); \ + PEL_PROTOTYPE(fname##8, bitd, opt); \ + PEL_PROTOTYPE(fname##12, bitd, opt); \ + PEL_PROTOTYPE(fname##16, bitd, opt); \ + PEL_PROTOTYPE(fname##24, bitd, opt); \ + PEL_PROTOTYPE(fname##32, bitd, opt); \ + PEL_PROTOTYPE(fname##48, bitd, opt); \ + PEL_PROTOTYPE(fname##64, bitd, opt) + +#define WEIGHTING_PROTOTYPE(width, bitd, opt) \ +void ff_hevc_put_hevc_uni_w##width##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, int16_t *_src, int height, int denom, int _wx, int _ox); \ +void ff_hevc_put_hevc_bi_w##width##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, int16_t *_src, int16_t *_src2, int height, int denom, int _wx0, int _wx1, int _ox0, int _ox1) + +#define WEIGHTING_PROTOTYPES(bitd, opt) \ + WEIGHTING_PROTOTYPE(2, bitd, opt); \ + WEIGHTING_PROTOTYPE(4, bitd, opt); \ + WEIGHTING_PROTOTYPE(6, bitd, opt); \ + WEIGHTING_PROTOTYPE(8, bitd, opt); \ + WEIGHTING_PROTOTYPE(12, bitd, opt); \ + WEIGHTING_PROTOTYPE(16, bitd, opt); \ + WEIGHTING_PROTOTYPE(24, bitd, opt); \ + WEIGHTING_PROTOTYPE(32, bitd, opt); \ + WEIGHTING_PROTOTYPE(48, bitd, opt); \ + WEIGHTING_PROTOTYPE(64, bitd, opt) + + +/////////////////////////////////////////////////////////////////////////////// +// QPEL_PIXELS EPEL_PIXELS +/////////////////////////////////////////////////////////////////////////////// +EPEL_PROTOTYPES(pel_pixels , 8, sse4); +EPEL_PROTOTYPES(pel_pixels , 10, sse4); +EPEL_PROTOTYPES(pel_pixels , 12, sse4); + +void ff_hevc_put_hevc_pel_pixels16_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels24_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels32_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels48_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels64_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); + +void ff_hevc_put_hevc_pel_pixels16_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels24_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels32_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels48_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels64_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); + + + +void ff_hevc_put_hevc_uni_pel_pixels32_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_uni_pel_pixels48_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_uni_pel_pixels64_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_uni_pel_pixels96_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); //used for 10bit +void ff_hevc_put_hevc_uni_pel_pixels128_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width);//used for 10bit + + +void ff_hevc_put_hevc_bi_pel_pixels16_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels24_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels32_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels48_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels64_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); + +void ff_hevc_put_hevc_bi_pel_pixels16_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels24_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels32_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels48_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels64_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); + +/////////////////////////////////////////////////////////////////////////////// +// EPEL +/////////////////////////////////////////////////////////////////////////////// +EPEL_PROTOTYPES(epel_h , 8, sse4); +EPEL_PROTOTYPES(epel_h , 10, sse4); +EPEL_PROTOTYPES(epel_h , 12, sse4); + +EPEL_PROTOTYPES(epel_v , 8, sse4); +EPEL_PROTOTYPES(epel_v , 10, sse4); +EPEL_PROTOTYPES(epel_v , 12, sse4); + +EPEL_PROTOTYPES(epel_hv , 8, sse4); +EPEL_PROTOTYPES(epel_hv , 10, sse4); +EPEL_PROTOTYPES(epel_hv , 12, sse4); + +PEL_PROTOTYPE(epel_h16, 8, avx2); +PEL_PROTOTYPE(epel_h24, 8, avx2); +PEL_PROTOTYPE(epel_h32, 8, avx2); +PEL_PROTOTYPE(epel_h48, 8, avx2); +PEL_PROTOTYPE(epel_h64, 8, avx2); + +PEL_PROTOTYPE(epel_h16,10, avx2); +PEL_PROTOTYPE(epel_h24,10, avx2); +PEL_PROTOTYPE(epel_h32,10, avx2); +PEL_PROTOTYPE(epel_h48,10, avx2); +PEL_PROTOTYPE(epel_h64,10, avx2); + +PEL_PROTOTYPE(epel_v16, 8, avx2); +PEL_PROTOTYPE(epel_v24, 8, avx2); +PEL_PROTOTYPE(epel_v32, 8, avx2); +PEL_PROTOTYPE(epel_v48, 8, avx2); +PEL_PROTOTYPE(epel_v64, 8, avx2); + +PEL_PROTOTYPE(epel_v16,10, avx2); +PEL_PROTOTYPE(epel_v24,10, avx2); +PEL_PROTOTYPE(epel_v32,10, avx2); +PEL_PROTOTYPE(epel_v48,10, avx2); +PEL_PROTOTYPE(epel_v64,10, avx2); + +PEL_PROTOTYPE(epel_hv16, 8, avx2); +PEL_PROTOTYPE(epel_hv24, 8, avx2); +PEL_PROTOTYPE(epel_hv32, 8, avx2); +PEL_PROTOTYPE(epel_hv48, 8, avx2); +PEL_PROTOTYPE(epel_hv64, 8, avx2); + +PEL_PROTOTYPE(epel_hv16,10, avx2); +PEL_PROTOTYPE(epel_hv24,10, avx2); +PEL_PROTOTYPE(epel_hv32,10, avx2); +PEL_PROTOTYPE(epel_hv48,10, avx2); +PEL_PROTOTYPE(epel_hv64,10, avx2); + +/////////////////////////////////////////////////////////////////////////////// +// QPEL +/////////////////////////////////////////////////////////////////////////////// +QPEL_PROTOTYPES(qpel_h , 8, sse4); +QPEL_PROTOTYPES(qpel_h , 10, sse4); +QPEL_PROTOTYPES(qpel_h , 12, sse4); + +QPEL_PROTOTYPES(qpel_v, 8, sse4); +QPEL_PROTOTYPES(qpel_v, 10, sse4); +QPEL_PROTOTYPES(qpel_v, 12, sse4); + +QPEL_PROTOTYPES(qpel_hv, 8, sse4); +QPEL_PROTOTYPES(qpel_hv, 10, sse4); +QPEL_PROTOTYPES(qpel_hv, 12, sse4); + +PEL_PROTOTYPE(qpel_h16, 8, avx2); +PEL_PROTOTYPE(qpel_h24, 8, avx2); +PEL_PROTOTYPE(qpel_h32, 8, avx2); +PEL_PROTOTYPE(qpel_h48, 8, avx2); +PEL_PROTOTYPE(qpel_h64, 8, avx2); + +PEL_PROTOTYPE(qpel_h16,10, avx2); +PEL_PROTOTYPE(qpel_h24,10, avx2); +PEL_PROTOTYPE(qpel_h32,10, avx2); +PEL_PROTOTYPE(qpel_h48,10, avx2); +PEL_PROTOTYPE(qpel_h64,10, avx2); + +PEL_PROTOTYPE(qpel_v16, 8, avx2); +PEL_PROTOTYPE(qpel_v24, 8, avx2); +PEL_PROTOTYPE(qpel_v32, 8, avx2); +PEL_PROTOTYPE(qpel_v48, 8, avx2); +PEL_PROTOTYPE(qpel_v64, 8, avx2); + +PEL_PROTOTYPE(qpel_v16,10, avx2); +PEL_PROTOTYPE(qpel_v24,10, avx2); +PEL_PROTOTYPE(qpel_v32,10, avx2); +PEL_PROTOTYPE(qpel_v48,10, avx2); +PEL_PROTOTYPE(qpel_v64,10, avx2); + +PEL_PROTOTYPE(qpel_hv16, 8, avx2); +PEL_PROTOTYPE(qpel_hv24, 8, avx2); +PEL_PROTOTYPE(qpel_hv32, 8, avx2); +PEL_PROTOTYPE(qpel_hv48, 8, avx2); +PEL_PROTOTYPE(qpel_hv64, 8, avx2); + +PEL_PROTOTYPE(qpel_hv16,10, avx2); +PEL_PROTOTYPE(qpel_hv24,10, avx2); +PEL_PROTOTYPE(qpel_hv32,10, avx2); +PEL_PROTOTYPE(qpel_hv48,10, avx2); +PEL_PROTOTYPE(qpel_hv64,10, avx2); + +WEIGHTING_PROTOTYPES(8, sse4); +WEIGHTING_PROTOTYPES(10, sse4); +WEIGHTING_PROTOTYPES(12, sse4); + +/////////////////////////////////////////////////////////////////////////////// +// TRANSFORM_ADD +/////////////////////////////////////////////////////////////////////////////// + +void ff_hevc_add_residual_4_8_mmxext(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_8_8_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_16_8_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_8_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_8_8_avx(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_16_8_avx(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_8_avx(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_32_8_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_4_10_mmxext(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_8_10_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_16_10_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_10_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_16_10_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_10_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +#endif // AVCODEC_X86_HEVCDSP_H diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hevcdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hevcdsp_init.c new file mode 100644 index 000000000..17cd2332a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hevcdsp_init.c @@ -0,0 +1,1151 @@ +/* + * Copyright (c) 2013 Seppo Tomperi + * Copyright (c) 2013 - 2014 Pierre-Edouard Lepere + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/get_bits.h" /* required for hevcdsp.h GetBitContext */ +#include "libavcodec/hevcdsp.h" +#include "libavcodec/x86/hevcdsp.h" + +#define LFC_FUNC(DIR, DEPTH, OPT) \ +void ff_hevc_ ## DIR ## _loop_filter_chroma_ ## DEPTH ## _ ## OPT(uint8_t *pix, ptrdiff_t stride, int *tc, uint8_t *no_p, uint8_t *no_q); + +#define LFL_FUNC(DIR, DEPTH, OPT) \ +void ff_hevc_ ## DIR ## _loop_filter_luma_ ## DEPTH ## _ ## OPT(uint8_t *pix, ptrdiff_t stride, int beta, int *tc, uint8_t *no_p, uint8_t *no_q); + +#define LFC_FUNCS(type, depth, opt) \ + LFC_FUNC(h, depth, opt) \ + LFC_FUNC(v, depth, opt) + +#define LFL_FUNCS(type, depth, opt) \ + LFL_FUNC(h, depth, opt) \ + LFL_FUNC(v, depth, opt) + +LFC_FUNCS(uint8_t, 8, sse2) +LFC_FUNCS(uint8_t, 10, sse2) +LFC_FUNCS(uint8_t, 12, sse2) +LFC_FUNCS(uint8_t, 8, avx) +LFC_FUNCS(uint8_t, 10, avx) +LFC_FUNCS(uint8_t, 12, avx) +LFL_FUNCS(uint8_t, 8, sse2) +LFL_FUNCS(uint8_t, 10, sse2) +LFL_FUNCS(uint8_t, 12, sse2) +LFL_FUNCS(uint8_t, 8, ssse3) +LFL_FUNCS(uint8_t, 10, ssse3) +LFL_FUNCS(uint8_t, 12, ssse3) +LFL_FUNCS(uint8_t, 8, avx) +LFL_FUNCS(uint8_t, 10, avx) +LFL_FUNCS(uint8_t, 12, avx) + +#define IDCT_DC_FUNCS(W, opt) \ +void ff_hevc_idct_ ## W ## _dc_8_ ## opt(int16_t *coeffs); \ +void ff_hevc_idct_ ## W ## _dc_10_ ## opt(int16_t *coeffs); \ +void ff_hevc_idct_ ## W ## _dc_12_ ## opt(int16_t *coeffs) + +IDCT_DC_FUNCS(4x4, mmxext); +IDCT_DC_FUNCS(8x8, mmxext); +IDCT_DC_FUNCS(8x8, sse2); +IDCT_DC_FUNCS(16x16, sse2); +IDCT_DC_FUNCS(32x32, sse2); +IDCT_DC_FUNCS(16x16, avx2); +IDCT_DC_FUNCS(32x32, avx2); + +#define IDCT_FUNCS(opt) \ +void ff_hevc_idct_4x4_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_4x4_10_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_8x8_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_8x8_10_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_16x16_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_16x16_10_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_32x32_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_32x32_10_ ## opt(int16_t *coeffs, int col_limit); + +IDCT_FUNCS(sse2) +IDCT_FUNCS(avx) + +#define mc_rep_func(name, bitd, step, W, opt) \ +void ff_hevc_put_hevc_##name##W##_##bitd##_##opt(int16_t *_dst, \ + uint8_t *_src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + int i; \ + uint8_t *src; \ + int16_t *dst; \ + for (i = 0; i < W; i += step) { \ + src = _src + (i * ((bitd + 7) / 8)); \ + dst = _dst + i; \ + ff_hevc_put_hevc_##name##step##_##bitd##_##opt(dst, src, _srcstride, height, mx, my, width); \ + } \ +} +#define mc_rep_uni_func(name, bitd, step, W, opt) \ +void ff_hevc_put_hevc_uni_##name##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t dststride, \ + uint8_t *_src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + int i; \ + uint8_t *src; \ + uint8_t *dst; \ + for (i = 0; i < W; i += step) { \ + src = _src + (i * ((bitd + 7) / 8)); \ + dst = _dst + (i * ((bitd + 7) / 8)); \ + ff_hevc_put_hevc_uni_##name##step##_##bitd##_##opt(dst, dststride, src, _srcstride, \ + height, mx, my, width); \ + } \ +} +#define mc_rep_bi_func(name, bitd, step, W, opt) \ +void ff_hevc_put_hevc_bi_##name##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t dststride, uint8_t *_src, \ + ptrdiff_t _srcstride, int16_t* _src2, \ + int height, intptr_t mx, intptr_t my, int width) \ +{ \ + int i; \ + uint8_t *src; \ + uint8_t *dst; \ + int16_t *src2; \ + for (i = 0; i < W ; i += step) { \ + src = _src + (i * ((bitd + 7) / 8)); \ + dst = _dst + (i * ((bitd + 7) / 8)); \ + src2 = _src2 + i; \ + ff_hevc_put_hevc_bi_##name##step##_##bitd##_##opt(dst, dststride, src, _srcstride, src2, \ + height, mx, my, width); \ + } \ +} + +#define mc_rep_funcs(name, bitd, step, W, opt) \ + mc_rep_func(name, bitd, step, W, opt) \ + mc_rep_uni_func(name, bitd, step, W, opt) \ + mc_rep_bi_func(name, bitd, step, W, opt) + +#define mc_rep_func2(name, bitd, step1, step2, W, opt) \ +void ff_hevc_put_hevc_##name##W##_##bitd##_##opt(int16_t *dst, \ + uint8_t *src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_##name##step1##_##bitd##_##opt(dst, src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_##name##step2##_##bitd##_##opt(dst + step1, src + (step1 * ((bitd + 7) / 8)), \ + _srcstride, height, mx, my, width); \ +} +#define mc_rep_uni_func2(name, bitd, step1, step2, W, opt) \ +void ff_hevc_put_hevc_uni_##name##W##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, \ + uint8_t *src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_uni_##name##step1##_##bitd##_##opt(dst, dststride, src, _srcstride, height, mx, my, width);\ + ff_hevc_put_hevc_uni_##name##step2##_##bitd##_##opt(dst + (step1 * ((bitd + 7) / 8)), dststride, \ + src + (step1 * ((bitd + 7) / 8)), _srcstride, \ + height, mx, my, width); \ +} +#define mc_rep_bi_func2(name, bitd, step1, step2, W, opt) \ +void ff_hevc_put_hevc_bi_##name##W##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t _srcstride, int16_t* src2, \ + int height, intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_bi_##name##step1##_##bitd##_##opt(dst, dststride, src, _srcstride, src2, height, mx, my, width);\ + ff_hevc_put_hevc_bi_##name##step2##_##bitd##_##opt(dst + (step1 * ((bitd + 7) / 8)), dststride, \ + src + (step1 * ((bitd + 7) / 8)), _srcstride, \ + src2 + step1, height, mx, my, width); \ +} + +#define mc_rep_funcs2(name, bitd, step1, step2, W, opt) \ + mc_rep_func2(name, bitd, step1, step2, W, opt) \ + mc_rep_uni_func2(name, bitd, step1, step2, W, opt) \ + mc_rep_bi_func2(name, bitd, step1, step2, W, opt) + +#if ARCH_X86_64 && HAVE_SSE4_EXTERNAL + +#define mc_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +void ff_hevc_put_hevc_##name##width1##_10_##opt1(int16_t *dst, uint8_t *src, ptrdiff_t _srcstride, \ + int height, intptr_t mx, intptr_t my, int width) \ + \ +{ \ + ff_hevc_put_hevc_##name##width2##_10_##opt1(dst, src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_##name##width3##_10_##opt2(dst+ width2, src+ width4, _srcstride, height, mx, my, width); \ +} + +#define mc_bi_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +void ff_hevc_put_hevc_bi_##name##width1##_10_##opt1(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t _srcstride, int16_t *src2, \ + int height, intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_bi_##name##width2##_10_##opt1(dst, dststride, src, _srcstride, src2, \ + height, mx, my, width); \ + ff_hevc_put_hevc_bi_##name##width3##_10_##opt2(dst+width4, dststride, src+width4, _srcstride, src2+width2,\ + height, mx, my, width); \ +} + +#define mc_uni_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +void ff_hevc_put_hevc_uni_##name##width1##_10_##opt1(uint8_t *dst, ptrdiff_t dststride, \ + uint8_t *src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_uni_##name##width2##_10_##opt1(dst, dststride, src, _srcstride, \ + height, mx, my, width); \ + ff_hevc_put_hevc_uni_##name##width3##_10_##opt2(dst+width4, dststride, src+width4, _srcstride, \ + height, mx, my, width); \ +} + +#define mc_rep_mixs_10(name, width1, width2, width3, opt1, opt2, width4) \ +mc_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +mc_bi_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +mc_uni_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) + +#define mc_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +void ff_hevc_put_hevc_##name##width1##_8_##opt1(int16_t *dst, uint8_t *src, ptrdiff_t _srcstride, \ + int height, intptr_t mx, intptr_t my, int width) \ + \ +{ \ + ff_hevc_put_hevc_##name##width2##_8_##opt1(dst, src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_##name##width3##_8_##opt2(dst+ width2, src+ width2, _srcstride, height, mx, my, width); \ +} + +#define mc_bi_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +void ff_hevc_put_hevc_bi_##name##width1##_8_##opt1(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t _srcstride, int16_t* src2, \ + int height, intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_bi_##name##width2##_8_##opt1(dst, dststride, src, _srcstride, \ + src2, height, mx, my, width); \ + ff_hevc_put_hevc_bi_##name##width3##_8_##opt2(dst+width2, dststride, src+width2, _srcstride, \ + src2+width2, height, mx, my, width); \ +} + +#define mc_uni_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +void ff_hevc_put_hevc_uni_##name##width1##_8_##opt1(uint8_t *dst, ptrdiff_t dststride, \ + uint8_t *src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_uni_##name##width2##_8_##opt1(dst, dststride, src, _srcstride, \ + height, mx, my, width); \ + ff_hevc_put_hevc_uni_##name##width3##_8_##opt2(dst+width2, dststride, src+width2, _srcstride, \ + height, mx, my, width); \ +} + +#define mc_rep_mixs_8(name, width1, width2, width3, opt1, opt2) \ +mc_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +mc_bi_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +mc_uni_rep_mix_8(name, width1, width2, width3, opt1, opt2) + +#if HAVE_AVX2_EXTERNAL + +mc_rep_mixs_8(pel_pixels, 48, 32, 16, avx2, sse4) +mc_rep_mixs_8(epel_hv, 48, 32, 16, avx2, sse4) +mc_rep_mixs_8(epel_h , 48, 32, 16, avx2, sse4) +mc_rep_mixs_8(epel_v , 48, 32, 16, avx2, sse4) + +mc_rep_mix_10(pel_pixels, 24, 16, 8, avx2, sse4, 32) +mc_bi_rep_mix_10(pel_pixels,24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(epel_hv, 24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(epel_h , 24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(epel_v , 24, 16, 8, avx2, sse4, 32) + + +mc_rep_mixs_10(qpel_h , 24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(qpel_v , 24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(qpel_hv, 24, 16, 8, avx2, sse4, 32) + + +mc_rep_uni_func(pel_pixels, 8, 64, 128, avx2)//used for 10bit +mc_rep_uni_func(pel_pixels, 8, 32, 96, avx2) //used for 10bit + +mc_rep_funcs(pel_pixels, 8, 32, 64, avx2) + +mc_rep_func(pel_pixels, 10, 16, 32, avx2) +mc_rep_func(pel_pixels, 10, 16, 48, avx2) +mc_rep_func(pel_pixels, 10, 32, 64, avx2) + +mc_rep_bi_func(pel_pixels, 10, 16, 32, avx2) +mc_rep_bi_func(pel_pixels, 10, 16, 48, avx2) +mc_rep_bi_func(pel_pixels, 10, 32, 64, avx2) + +mc_rep_funcs(epel_h, 8, 32, 64, avx2) + +mc_rep_funcs(epel_v, 8, 32, 64, avx2) + +mc_rep_funcs(epel_h, 10, 16, 32, avx2) +mc_rep_funcs(epel_h, 10, 16, 48, avx2) +mc_rep_funcs(epel_h, 10, 32, 64, avx2) + +mc_rep_funcs(epel_v, 10, 16, 32, avx2) +mc_rep_funcs(epel_v, 10, 16, 48, avx2) +mc_rep_funcs(epel_v, 10, 32, 64, avx2) + + +mc_rep_funcs(epel_hv, 8, 32, 64, avx2) + +mc_rep_funcs(epel_hv, 10, 16, 32, avx2) +mc_rep_funcs(epel_hv, 10, 16, 48, avx2) +mc_rep_funcs(epel_hv, 10, 32, 64, avx2) + +mc_rep_funcs(qpel_h, 8, 32, 64, avx2) +mc_rep_mixs_8(qpel_h , 48, 32, 16, avx2, sse4) + +mc_rep_funcs(qpel_v, 8, 32, 64, avx2) +mc_rep_mixs_8(qpel_v, 48, 32, 16, avx2, sse4) + +mc_rep_funcs(qpel_h, 10, 16, 32, avx2) +mc_rep_funcs(qpel_h, 10, 16, 48, avx2) +mc_rep_funcs(qpel_h, 10, 32, 64, avx2) + +mc_rep_funcs(qpel_v, 10, 16, 32, avx2) +mc_rep_funcs(qpel_v, 10, 16, 48, avx2) +mc_rep_funcs(qpel_v, 10, 32, 64, avx2) + +mc_rep_funcs(qpel_hv, 10, 16, 32, avx2) +mc_rep_funcs(qpel_hv, 10, 16, 48, avx2) +mc_rep_funcs(qpel_hv, 10, 32, 64, avx2) + +#endif //AVX2 + +mc_rep_funcs(pel_pixels, 8, 16, 64, sse4) +mc_rep_funcs(pel_pixels, 8, 16, 48, sse4) +mc_rep_funcs(pel_pixels, 8, 16, 32, sse4) +mc_rep_funcs(pel_pixels, 8, 8, 24, sse4) +mc_rep_funcs(pel_pixels,10, 8, 64, sse4) +mc_rep_funcs(pel_pixels,10, 8, 48, sse4) +mc_rep_funcs(pel_pixels,10, 8, 32, sse4) +mc_rep_funcs(pel_pixels,10, 8, 24, sse4) +mc_rep_funcs(pel_pixels,10, 8, 16, sse4) +mc_rep_funcs(pel_pixels,10, 4, 12, sse4) +mc_rep_funcs(pel_pixels,12, 8, 64, sse4) +mc_rep_funcs(pel_pixels,12, 8, 48, sse4) +mc_rep_funcs(pel_pixels,12, 8, 32, sse4) +mc_rep_funcs(pel_pixels,12, 8, 24, sse4) +mc_rep_funcs(pel_pixels,12, 8, 16, sse4) +mc_rep_funcs(pel_pixels,12, 4, 12, sse4) + +mc_rep_funcs(epel_h, 8, 16, 64, sse4) +mc_rep_funcs(epel_h, 8, 16, 48, sse4) +mc_rep_funcs(epel_h, 8, 16, 32, sse4) +mc_rep_funcs(epel_h, 8, 8, 24, sse4) +mc_rep_funcs(epel_h,10, 8, 64, sse4) +mc_rep_funcs(epel_h,10, 8, 48, sse4) +mc_rep_funcs(epel_h,10, 8, 32, sse4) +mc_rep_funcs(epel_h,10, 8, 24, sse4) +mc_rep_funcs(epel_h,10, 8, 16, sse4) +mc_rep_funcs(epel_h,10, 4, 12, sse4) +mc_rep_funcs(epel_h,12, 8, 64, sse4) +mc_rep_funcs(epel_h,12, 8, 48, sse4) +mc_rep_funcs(epel_h,12, 8, 32, sse4) +mc_rep_funcs(epel_h,12, 8, 24, sse4) +mc_rep_funcs(epel_h,12, 8, 16, sse4) +mc_rep_funcs(epel_h,12, 4, 12, sse4) +mc_rep_funcs(epel_v, 8, 16, 64, sse4) +mc_rep_funcs(epel_v, 8, 16, 48, sse4) +mc_rep_funcs(epel_v, 8, 16, 32, sse4) +mc_rep_funcs(epel_v, 8, 8, 24, sse4) +mc_rep_funcs(epel_v,10, 8, 64, sse4) +mc_rep_funcs(epel_v,10, 8, 48, sse4) +mc_rep_funcs(epel_v,10, 8, 32, sse4) +mc_rep_funcs(epel_v,10, 8, 24, sse4) +mc_rep_funcs(epel_v,10, 8, 16, sse4) +mc_rep_funcs(epel_v,10, 4, 12, sse4) +mc_rep_funcs(epel_v,12, 8, 64, sse4) +mc_rep_funcs(epel_v,12, 8, 48, sse4) +mc_rep_funcs(epel_v,12, 8, 32, sse4) +mc_rep_funcs(epel_v,12, 8, 24, sse4) +mc_rep_funcs(epel_v,12, 8, 16, sse4) +mc_rep_funcs(epel_v,12, 4, 12, sse4) +mc_rep_funcs(epel_hv, 8, 16, 64, sse4) +mc_rep_funcs(epel_hv, 8, 16, 48, sse4) +mc_rep_funcs(epel_hv, 8, 16, 32, sse4) +mc_rep_funcs(epel_hv, 8, 8, 24, sse4) +mc_rep_funcs2(epel_hv,8, 8, 4, 12, sse4) +mc_rep_funcs(epel_hv,10, 8, 64, sse4) +mc_rep_funcs(epel_hv,10, 8, 48, sse4) +mc_rep_funcs(epel_hv,10, 8, 32, sse4) +mc_rep_funcs(epel_hv,10, 8, 24, sse4) +mc_rep_funcs(epel_hv,10, 8, 16, sse4) +mc_rep_funcs(epel_hv,10, 4, 12, sse4) +mc_rep_funcs(epel_hv,12, 8, 64, sse4) +mc_rep_funcs(epel_hv,12, 8, 48, sse4) +mc_rep_funcs(epel_hv,12, 8, 32, sse4) +mc_rep_funcs(epel_hv,12, 8, 24, sse4) +mc_rep_funcs(epel_hv,12, 8, 16, sse4) +mc_rep_funcs(epel_hv,12, 4, 12, sse4) + +mc_rep_funcs(qpel_h, 8, 16, 64, sse4) +mc_rep_funcs(qpel_h, 8, 16, 48, sse4) +mc_rep_funcs(qpel_h, 8, 16, 32, sse4) +mc_rep_funcs(qpel_h, 8, 8, 24, sse4) +mc_rep_funcs(qpel_h,10, 8, 64, sse4) +mc_rep_funcs(qpel_h,10, 8, 48, sse4) +mc_rep_funcs(qpel_h,10, 8, 32, sse4) +mc_rep_funcs(qpel_h,10, 8, 24, sse4) +mc_rep_funcs(qpel_h,10, 8, 16, sse4) +mc_rep_funcs(qpel_h,10, 4, 12, sse4) +mc_rep_funcs(qpel_h,12, 8, 64, sse4) +mc_rep_funcs(qpel_h,12, 8, 48, sse4) +mc_rep_funcs(qpel_h,12, 8, 32, sse4) +mc_rep_funcs(qpel_h,12, 8, 24, sse4) +mc_rep_funcs(qpel_h,12, 8, 16, sse4) +mc_rep_funcs(qpel_h,12, 4, 12, sse4) +mc_rep_funcs(qpel_v, 8, 16, 64, sse4) +mc_rep_funcs(qpel_v, 8, 16, 48, sse4) +mc_rep_funcs(qpel_v, 8, 16, 32, sse4) +mc_rep_funcs(qpel_v, 8, 8, 24, sse4) +mc_rep_funcs(qpel_v,10, 8, 64, sse4) +mc_rep_funcs(qpel_v,10, 8, 48, sse4) +mc_rep_funcs(qpel_v,10, 8, 32, sse4) +mc_rep_funcs(qpel_v,10, 8, 24, sse4) +mc_rep_funcs(qpel_v,10, 8, 16, sse4) +mc_rep_funcs(qpel_v,10, 4, 12, sse4) +mc_rep_funcs(qpel_v,12, 8, 64, sse4) +mc_rep_funcs(qpel_v,12, 8, 48, sse4) +mc_rep_funcs(qpel_v,12, 8, 32, sse4) +mc_rep_funcs(qpel_v,12, 8, 24, sse4) +mc_rep_funcs(qpel_v,12, 8, 16, sse4) +mc_rep_funcs(qpel_v,12, 4, 12, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 64, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 48, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 32, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 24, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 16, sse4) +mc_rep_funcs2(qpel_hv,8, 8, 4, 12, sse4) +mc_rep_funcs(qpel_hv,10, 8, 64, sse4) +mc_rep_funcs(qpel_hv,10, 8, 48, sse4) +mc_rep_funcs(qpel_hv,10, 8, 32, sse4) +mc_rep_funcs(qpel_hv,10, 8, 24, sse4) +mc_rep_funcs(qpel_hv,10, 8, 16, sse4) +mc_rep_funcs(qpel_hv,10, 4, 12, sse4) +mc_rep_funcs(qpel_hv,12, 8, 64, sse4) +mc_rep_funcs(qpel_hv,12, 8, 48, sse4) +mc_rep_funcs(qpel_hv,12, 8, 32, sse4) +mc_rep_funcs(qpel_hv,12, 8, 24, sse4) +mc_rep_funcs(qpel_hv,12, 8, 16, sse4) +mc_rep_funcs(qpel_hv,12, 4, 12, sse4) + +#define mc_rep_uni_w(bitd, step, W, opt) \ +void ff_hevc_put_hevc_uni_w##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t dststride, int16_t *_src, \ + int height, int denom, int _wx, int _ox) \ +{ \ + int i; \ + int16_t *src; \ + uint8_t *dst; \ + for (i = 0; i < W; i += step) { \ + src= _src + i; \ + dst= _dst + (i * ((bitd + 7) / 8)); \ + ff_hevc_put_hevc_uni_w##step##_##bitd##_##opt(dst, dststride, src, \ + height, denom, _wx, _ox); \ + } \ +} + +mc_rep_uni_w(8, 6, 12, sse4) +mc_rep_uni_w(8, 8, 16, sse4) +mc_rep_uni_w(8, 8, 24, sse4) +mc_rep_uni_w(8, 8, 32, sse4) +mc_rep_uni_w(8, 8, 48, sse4) +mc_rep_uni_w(8, 8, 64, sse4) + +mc_rep_uni_w(10, 6, 12, sse4) +mc_rep_uni_w(10, 8, 16, sse4) +mc_rep_uni_w(10, 8, 24, sse4) +mc_rep_uni_w(10, 8, 32, sse4) +mc_rep_uni_w(10, 8, 48, sse4) +mc_rep_uni_w(10, 8, 64, sse4) + +mc_rep_uni_w(12, 6, 12, sse4) +mc_rep_uni_w(12, 8, 16, sse4) +mc_rep_uni_w(12, 8, 24, sse4) +mc_rep_uni_w(12, 8, 32, sse4) +mc_rep_uni_w(12, 8, 48, sse4) +mc_rep_uni_w(12, 8, 64, sse4) + +#define mc_rep_bi_w(bitd, step, W, opt) \ +void ff_hevc_put_hevc_bi_w##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t dststride, int16_t *_src, \ + int16_t *_src2, int height, \ + int denom, int _wx0, int _wx1, int _ox0, int _ox1) \ +{ \ + int i; \ + int16_t *src; \ + int16_t *src2; \ + uint8_t *dst; \ + for (i = 0; i < W; i += step) { \ + src = _src + i; \ + src2 = _src2 + i; \ + dst = _dst + (i * ((bitd + 7) / 8)); \ + ff_hevc_put_hevc_bi_w##step##_##bitd##_##opt(dst, dststride, src, src2, \ + height, denom, _wx0, _wx1, _ox0, _ox1); \ + } \ +} + +mc_rep_bi_w(8, 6, 12, sse4) +mc_rep_bi_w(8, 8, 16, sse4) +mc_rep_bi_w(8, 8, 24, sse4) +mc_rep_bi_w(8, 8, 32, sse4) +mc_rep_bi_w(8, 8, 48, sse4) +mc_rep_bi_w(8, 8, 64, sse4) + +mc_rep_bi_w(10, 6, 12, sse4) +mc_rep_bi_w(10, 8, 16, sse4) +mc_rep_bi_w(10, 8, 24, sse4) +mc_rep_bi_w(10, 8, 32, sse4) +mc_rep_bi_w(10, 8, 48, sse4) +mc_rep_bi_w(10, 8, 64, sse4) + +mc_rep_bi_w(12, 6, 12, sse4) +mc_rep_bi_w(12, 8, 16, sse4) +mc_rep_bi_w(12, 8, 24, sse4) +mc_rep_bi_w(12, 8, 32, sse4) +mc_rep_bi_w(12, 8, 48, sse4) +mc_rep_bi_w(12, 8, 64, sse4) + +#define mc_uni_w_func(name, bitd, W, opt) \ +void ff_hevc_put_hevc_uni_w_##name##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t _dststride, \ + uint8_t *_src, ptrdiff_t _srcstride, \ + int height, int denom, \ + int _wx, int _ox, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + LOCAL_ALIGNED_16(int16_t, temp, [71 * MAX_PB_SIZE]); \ + ff_hevc_put_hevc_##name##W##_##bitd##_##opt(temp, _src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_uni_w##W##_##bitd##_##opt(_dst, _dststride, temp, height, denom, _wx, _ox);\ +} + +#define mc_uni_w_funcs(name, bitd, opt) \ + mc_uni_w_func(name, bitd, 4, opt) \ + mc_uni_w_func(name, bitd, 8, opt) \ + mc_uni_w_func(name, bitd, 12, opt) \ + mc_uni_w_func(name, bitd, 16, opt) \ + mc_uni_w_func(name, bitd, 24, opt) \ + mc_uni_w_func(name, bitd, 32, opt) \ + mc_uni_w_func(name, bitd, 48, opt) \ + mc_uni_w_func(name, bitd, 64, opt) + +mc_uni_w_funcs(pel_pixels, 8, sse4) +mc_uni_w_func(pel_pixels, 8, 6, sse4) +mc_uni_w_funcs(epel_h, 8, sse4) +mc_uni_w_func(epel_h, 8, 6, sse4) +mc_uni_w_funcs(epel_v, 8, sse4) +mc_uni_w_func(epel_v, 8, 6, sse4) +mc_uni_w_funcs(epel_hv, 8, sse4) +mc_uni_w_func(epel_hv, 8, 6, sse4) +mc_uni_w_funcs(qpel_h, 8, sse4) +mc_uni_w_funcs(qpel_v, 8, sse4) +mc_uni_w_funcs(qpel_hv, 8, sse4) + +mc_uni_w_funcs(pel_pixels, 10, sse4) +mc_uni_w_func(pel_pixels, 10, 6, sse4) +mc_uni_w_funcs(epel_h, 10, sse4) +mc_uni_w_func(epel_h, 10, 6, sse4) +mc_uni_w_funcs(epel_v, 10, sse4) +mc_uni_w_func(epel_v, 10, 6, sse4) +mc_uni_w_funcs(epel_hv, 10, sse4) +mc_uni_w_func(epel_hv, 10, 6, sse4) +mc_uni_w_funcs(qpel_h, 10, sse4) +mc_uni_w_funcs(qpel_v, 10, sse4) +mc_uni_w_funcs(qpel_hv, 10, sse4) + +mc_uni_w_funcs(pel_pixels, 12, sse4) +mc_uni_w_func(pel_pixels, 12, 6, sse4) +mc_uni_w_funcs(epel_h, 12, sse4) +mc_uni_w_func(epel_h, 12, 6, sse4) +mc_uni_w_funcs(epel_v, 12, sse4) +mc_uni_w_func(epel_v, 12, 6, sse4) +mc_uni_w_funcs(epel_hv, 12, sse4) +mc_uni_w_func(epel_hv, 12, 6, sse4) +mc_uni_w_funcs(qpel_h, 12, sse4) +mc_uni_w_funcs(qpel_v, 12, sse4) +mc_uni_w_funcs(qpel_hv, 12, sse4) + +#define mc_bi_w_func(name, bitd, W, opt) \ +void ff_hevc_put_hevc_bi_w_##name##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t _dststride, \ + uint8_t *_src, ptrdiff_t _srcstride, \ + int16_t *_src2, \ + int height, int denom, \ + int _wx0, int _wx1, int _ox0, int _ox1, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + LOCAL_ALIGNED_16(int16_t, temp, [71 * MAX_PB_SIZE]); \ + ff_hevc_put_hevc_##name##W##_##bitd##_##opt(temp, _src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_bi_w##W##_##bitd##_##opt(_dst, _dststride, temp, _src2, \ + height, denom, _wx0, _wx1, _ox0, _ox1); \ +} + +#define mc_bi_w_funcs(name, bitd, opt) \ + mc_bi_w_func(name, bitd, 4, opt) \ + mc_bi_w_func(name, bitd, 8, opt) \ + mc_bi_w_func(name, bitd, 12, opt) \ + mc_bi_w_func(name, bitd, 16, opt) \ + mc_bi_w_func(name, bitd, 24, opt) \ + mc_bi_w_func(name, bitd, 32, opt) \ + mc_bi_w_func(name, bitd, 48, opt) \ + mc_bi_w_func(name, bitd, 64, opt) + +mc_bi_w_funcs(pel_pixels, 8, sse4) +mc_bi_w_func(pel_pixels, 8, 6, sse4) +mc_bi_w_funcs(epel_h, 8, sse4) +mc_bi_w_func(epel_h, 8, 6, sse4) +mc_bi_w_funcs(epel_v, 8, sse4) +mc_bi_w_func(epel_v, 8, 6, sse4) +mc_bi_w_funcs(epel_hv, 8, sse4) +mc_bi_w_func(epel_hv, 8, 6, sse4) +mc_bi_w_funcs(qpel_h, 8, sse4) +mc_bi_w_funcs(qpel_v, 8, sse4) +mc_bi_w_funcs(qpel_hv, 8, sse4) + +mc_bi_w_funcs(pel_pixels, 10, sse4) +mc_bi_w_func(pel_pixels, 10, 6, sse4) +mc_bi_w_funcs(epel_h, 10, sse4) +mc_bi_w_func(epel_h, 10, 6, sse4) +mc_bi_w_funcs(epel_v, 10, sse4) +mc_bi_w_func(epel_v, 10, 6, sse4) +mc_bi_w_funcs(epel_hv, 10, sse4) +mc_bi_w_func(epel_hv, 10, 6, sse4) +mc_bi_w_funcs(qpel_h, 10, sse4) +mc_bi_w_funcs(qpel_v, 10, sse4) +mc_bi_w_funcs(qpel_hv, 10, sse4) + +mc_bi_w_funcs(pel_pixels, 12, sse4) +mc_bi_w_func(pel_pixels, 12, 6, sse4) +mc_bi_w_funcs(epel_h, 12, sse4) +mc_bi_w_func(epel_h, 12, 6, sse4) +mc_bi_w_funcs(epel_v, 12, sse4) +mc_bi_w_func(epel_v, 12, 6, sse4) +mc_bi_w_funcs(epel_hv, 12, sse4) +mc_bi_w_func(epel_hv, 12, 6, sse4) +mc_bi_w_funcs(qpel_h, 12, sse4) +mc_bi_w_funcs(qpel_v, 12, sse4) +mc_bi_w_funcs(qpel_hv, 12, sse4) +#endif //ARCH_X86_64 && HAVE_SSE4_EXTERNAL + +#define SAO_BAND_FILTER_FUNCS(bitd, opt) \ +void ff_hevc_sao_band_filter_8_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); \ +void ff_hevc_sao_band_filter_16_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); \ +void ff_hevc_sao_band_filter_32_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); \ +void ff_hevc_sao_band_filter_48_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); \ +void ff_hevc_sao_band_filter_64_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); + +SAO_BAND_FILTER_FUNCS(8, sse2) +SAO_BAND_FILTER_FUNCS(10, sse2) +SAO_BAND_FILTER_FUNCS(12, sse2) +SAO_BAND_FILTER_FUNCS(8, avx) +SAO_BAND_FILTER_FUNCS(10, avx) +SAO_BAND_FILTER_FUNCS(12, avx) +SAO_BAND_FILTER_FUNCS(8, avx2) +SAO_BAND_FILTER_FUNCS(10, avx2) +SAO_BAND_FILTER_FUNCS(12, avx2) + +#define SAO_BAND_INIT(bitd, opt) do { \ + c->sao_band_filter[0] = ff_hevc_sao_band_filter_8_##bitd##_##opt; \ + c->sao_band_filter[1] = ff_hevc_sao_band_filter_16_##bitd##_##opt; \ + c->sao_band_filter[2] = ff_hevc_sao_band_filter_32_##bitd##_##opt; \ + c->sao_band_filter[3] = ff_hevc_sao_band_filter_48_##bitd##_##opt; \ + c->sao_band_filter[4] = ff_hevc_sao_band_filter_64_##bitd##_##opt; \ +} while (0) + +#define SAO_EDGE_FILTER_FUNCS(bitd, opt) \ +void ff_hevc_sao_edge_filter_8_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ +void ff_hevc_sao_edge_filter_16_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ +void ff_hevc_sao_edge_filter_32_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ +void ff_hevc_sao_edge_filter_48_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ +void ff_hevc_sao_edge_filter_64_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ + +SAO_EDGE_FILTER_FUNCS(8, ssse3) +SAO_EDGE_FILTER_FUNCS(8, avx2) +SAO_EDGE_FILTER_FUNCS(10, sse2) +SAO_EDGE_FILTER_FUNCS(10, avx2) +SAO_EDGE_FILTER_FUNCS(12, sse2) +SAO_EDGE_FILTER_FUNCS(12, avx2) + +#define SAO_EDGE_INIT(bitd, opt) do { \ + c->sao_edge_filter[0] = ff_hevc_sao_edge_filter_8_##bitd##_##opt; \ + c->sao_edge_filter[1] = ff_hevc_sao_edge_filter_16_##bitd##_##opt; \ + c->sao_edge_filter[2] = ff_hevc_sao_edge_filter_32_##bitd##_##opt; \ + c->sao_edge_filter[3] = ff_hevc_sao_edge_filter_48_##bitd##_##opt; \ + c->sao_edge_filter[4] = ff_hevc_sao_edge_filter_64_##bitd##_##opt; \ +} while (0) + +#define EPEL_LINKS(pointer, my, mx, fname, bitd, opt ) \ + PEL_LINK(pointer, 1, my , mx , fname##4 , bitd, opt ); \ + PEL_LINK(pointer, 2, my , mx , fname##6 , bitd, opt ); \ + PEL_LINK(pointer, 3, my , mx , fname##8 , bitd, opt ); \ + PEL_LINK(pointer, 4, my , mx , fname##12, bitd, opt ); \ + PEL_LINK(pointer, 5, my , mx , fname##16, bitd, opt ); \ + PEL_LINK(pointer, 6, my , mx , fname##24, bitd, opt ); \ + PEL_LINK(pointer, 7, my , mx , fname##32, bitd, opt ); \ + PEL_LINK(pointer, 8, my , mx , fname##48, bitd, opt ); \ + PEL_LINK(pointer, 9, my , mx , fname##64, bitd, opt ) +#define QPEL_LINKS(pointer, my, mx, fname, bitd, opt) \ + PEL_LINK(pointer, 1, my , mx , fname##4 , bitd, opt ); \ + PEL_LINK(pointer, 3, my , mx , fname##8 , bitd, opt ); \ + PEL_LINK(pointer, 4, my , mx , fname##12, bitd, opt ); \ + PEL_LINK(pointer, 5, my , mx , fname##16, bitd, opt ); \ + PEL_LINK(pointer, 6, my , mx , fname##24, bitd, opt ); \ + PEL_LINK(pointer, 7, my , mx , fname##32, bitd, opt ); \ + PEL_LINK(pointer, 8, my , mx , fname##48, bitd, opt ); \ + PEL_LINK(pointer, 9, my , mx , fname##64, bitd, opt ) + +void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + + if (bit_depth == 8) { + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->idct_dc[0] = ff_hevc_idct_4x4_dc_8_mmxext; + c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_mmxext; + + c->add_residual[0] = ff_hevc_add_residual_4_8_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_8_sse2; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_8_sse2; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_8_sse2; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_8_sse2; + + c->idct[2] = ff_hevc_idct_16x16_8_sse2; + c->idct[3] = ff_hevc_idct_32x32_8_sse2; + } + SAO_BAND_INIT(8, sse2); + + c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_sse2; + c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_sse2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_sse2; + + c->idct[0] = ff_hevc_idct_4x4_8_sse2; + c->idct[1] = ff_hevc_idct_8x8_8_sse2; + + c->add_residual[1] = ff_hevc_add_residual_8_8_sse2; + c->add_residual[2] = ff_hevc_add_residual_16_8_sse2; + c->add_residual[3] = ff_hevc_add_residual_32_8_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + if(ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_8_ssse3; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_8_ssse3; + } + SAO_EDGE_INIT(8, ssse3); + } + if (EXTERNAL_SSE4(cpu_flags) && ARCH_X86_64) { + + EPEL_LINKS(c->put_hevc_epel, 0, 0, pel_pixels, 8, sse4); + EPEL_LINKS(c->put_hevc_epel, 0, 1, epel_h, 8, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 0, epel_v, 8, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 1, epel_hv, 8, sse4); + + QPEL_LINKS(c->put_hevc_qpel, 0, 0, pel_pixels, 8, sse4); + QPEL_LINKS(c->put_hevc_qpel, 0, 1, qpel_h, 8, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 0, qpel_v, 8, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 1, qpel_hv, 8, sse4); + } + if (EXTERNAL_AVX(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_8_avx; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_8_avx; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_8_avx; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_8_avx; + + c->idct[2] = ff_hevc_idct_16x16_8_avx; + c->idct[3] = ff_hevc_idct_32x32_8_avx; + } + SAO_BAND_INIT(8, avx); + + c->idct[0] = ff_hevc_idct_4x4_8_avx; + c->idct[1] = ff_hevc_idct_8x8_8_avx; + + c->add_residual[1] = ff_hevc_add_residual_8_8_avx; + c->add_residual[2] = ff_hevc_add_residual_16_8_avx; + c->add_residual[3] = ff_hevc_add_residual_32_8_avx; + } + if (EXTERNAL_AVX2(cpu_flags)) { + c->sao_band_filter[0] = ff_hevc_sao_band_filter_8_8_avx2; + c->sao_band_filter[1] = ff_hevc_sao_band_filter_16_8_avx2; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_avx2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_avx2; + if (ARCH_X86_64) { + c->put_hevc_epel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_avx2; + c->put_hevc_epel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_8_avx2; + c->put_hevc_epel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_8_avx2; + + c->put_hevc_qpel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_avx2; + c->put_hevc_qpel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_8_avx2; + c->put_hevc_qpel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_8_avx2; + + c->put_hevc_epel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_avx2; + c->put_hevc_epel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_avx2; + c->put_hevc_epel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_avx2; + + c->put_hevc_qpel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_avx2; + c->put_hevc_qpel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_avx2; + c->put_hevc_qpel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_avx2; + + c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_avx2; + c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_8_avx2; + c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_8_avx2; + + c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_avx2; + c->put_hevc_epel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_8_avx2; + c->put_hevc_epel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_8_avx2; + + c->put_hevc_epel[7][0][1] = ff_hevc_put_hevc_epel_h32_8_avx2; + c->put_hevc_epel[8][0][1] = ff_hevc_put_hevc_epel_h48_8_avx2; + c->put_hevc_epel[9][0][1] = ff_hevc_put_hevc_epel_h64_8_avx2; + + c->put_hevc_epel_uni[7][0][1] = ff_hevc_put_hevc_uni_epel_h32_8_avx2; + c->put_hevc_epel_uni[8][0][1] = ff_hevc_put_hevc_uni_epel_h48_8_avx2; + c->put_hevc_epel_uni[9][0][1] = ff_hevc_put_hevc_uni_epel_h64_8_avx2; + + c->put_hevc_epel_bi[7][0][1] = ff_hevc_put_hevc_bi_epel_h32_8_avx2; + c->put_hevc_epel_bi[8][0][1] = ff_hevc_put_hevc_bi_epel_h48_8_avx2; + c->put_hevc_epel_bi[9][0][1] = ff_hevc_put_hevc_bi_epel_h64_8_avx2; + + c->put_hevc_epel[7][1][0] = ff_hevc_put_hevc_epel_v32_8_avx2; + c->put_hevc_epel[8][1][0] = ff_hevc_put_hevc_epel_v48_8_avx2; + c->put_hevc_epel[9][1][0] = ff_hevc_put_hevc_epel_v64_8_avx2; + + c->put_hevc_epel_uni[7][1][0] = ff_hevc_put_hevc_uni_epel_v32_8_avx2; + c->put_hevc_epel_uni[8][1][0] = ff_hevc_put_hevc_uni_epel_v48_8_avx2; + c->put_hevc_epel_uni[9][1][0] = ff_hevc_put_hevc_uni_epel_v64_8_avx2; + + c->put_hevc_epel_bi[7][1][0] = ff_hevc_put_hevc_bi_epel_v32_8_avx2; + c->put_hevc_epel_bi[8][1][0] = ff_hevc_put_hevc_bi_epel_v48_8_avx2; + c->put_hevc_epel_bi[9][1][0] = ff_hevc_put_hevc_bi_epel_v64_8_avx2; + + c->put_hevc_epel[7][1][1] = ff_hevc_put_hevc_epel_hv32_8_avx2; + c->put_hevc_epel[8][1][1] = ff_hevc_put_hevc_epel_hv48_8_avx2; + c->put_hevc_epel[9][1][1] = ff_hevc_put_hevc_epel_hv64_8_avx2; + + c->put_hevc_epel_uni[7][1][1] = ff_hevc_put_hevc_uni_epel_hv32_8_avx2; + c->put_hevc_epel_uni[8][1][1] = ff_hevc_put_hevc_uni_epel_hv48_8_avx2; + c->put_hevc_epel_uni[9][1][1] = ff_hevc_put_hevc_uni_epel_hv64_8_avx2; + + c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_bi_epel_hv32_8_avx2; + c->put_hevc_epel_bi[8][1][1] = ff_hevc_put_hevc_bi_epel_hv48_8_avx2; + c->put_hevc_epel_bi[9][1][1] = ff_hevc_put_hevc_bi_epel_hv64_8_avx2; + + c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_8_avx2; + c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_8_avx2; + c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_8_avx2; + + c->put_hevc_qpel[7][1][0] = ff_hevc_put_hevc_qpel_v32_8_avx2; + c->put_hevc_qpel[8][1][0] = ff_hevc_put_hevc_qpel_v48_8_avx2; + c->put_hevc_qpel[9][1][0] = ff_hevc_put_hevc_qpel_v64_8_avx2; + + c->put_hevc_qpel_uni[7][0][1] = ff_hevc_put_hevc_uni_qpel_h32_8_avx2; + c->put_hevc_qpel_uni[8][0][1] = ff_hevc_put_hevc_uni_qpel_h48_8_avx2; + c->put_hevc_qpel_uni[9][0][1] = ff_hevc_put_hevc_uni_qpel_h64_8_avx2; + + c->put_hevc_qpel_uni[7][1][0] = ff_hevc_put_hevc_uni_qpel_v32_8_avx2; + c->put_hevc_qpel_uni[8][1][0] = ff_hevc_put_hevc_uni_qpel_v48_8_avx2; + c->put_hevc_qpel_uni[9][1][0] = ff_hevc_put_hevc_uni_qpel_v64_8_avx2; + + c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_bi_qpel_h32_8_avx2; + c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_bi_qpel_h48_8_avx2; + c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_bi_qpel_h64_8_avx2; + + c->put_hevc_qpel_bi[7][1][0] = ff_hevc_put_hevc_bi_qpel_v32_8_avx2; + c->put_hevc_qpel_bi[8][1][0] = ff_hevc_put_hevc_bi_qpel_v48_8_avx2; + c->put_hevc_qpel_bi[9][1][0] = ff_hevc_put_hevc_bi_qpel_v64_8_avx2; + } + SAO_BAND_INIT(8, avx2); + + c->sao_edge_filter[2] = ff_hevc_sao_edge_filter_32_8_avx2; + c->sao_edge_filter[3] = ff_hevc_sao_edge_filter_48_8_avx2; + c->sao_edge_filter[4] = ff_hevc_sao_edge_filter_64_8_avx2; + + c->add_residual[3] = ff_hevc_add_residual_32_8_avx2; + } + } else if (bit_depth == 10) { + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->add_residual[0] = ff_hevc_add_residual_4_10_mmxext; + c->idct_dc[0] = ff_hevc_idct_4x4_dc_10_mmxext; + c->idct_dc[1] = ff_hevc_idct_8x8_dc_10_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_10_sse2; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_10_sse2; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_10_sse2; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_10_sse2; + + c->idct[2] = ff_hevc_idct_16x16_10_sse2; + c->idct[3] = ff_hevc_idct_32x32_10_sse2; + } + SAO_BAND_INIT(10, sse2); + SAO_EDGE_INIT(10, sse2); + + c->idct_dc[1] = ff_hevc_idct_8x8_dc_10_sse2; + c->idct_dc[2] = ff_hevc_idct_16x16_dc_10_sse2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_10_sse2; + + c->idct[0] = ff_hevc_idct_4x4_10_sse2; + c->idct[1] = ff_hevc_idct_8x8_10_sse2; + + c->add_residual[1] = ff_hevc_add_residual_8_10_sse2; + c->add_residual[2] = ff_hevc_add_residual_16_10_sse2; + c->add_residual[3] = ff_hevc_add_residual_32_10_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags) && ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_10_ssse3; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_10_ssse3; + } + if (EXTERNAL_SSE4(cpu_flags) && ARCH_X86_64) { + EPEL_LINKS(c->put_hevc_epel, 0, 0, pel_pixels, 10, sse4); + EPEL_LINKS(c->put_hevc_epel, 0, 1, epel_h, 10, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 0, epel_v, 10, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 1, epel_hv, 10, sse4); + + QPEL_LINKS(c->put_hevc_qpel, 0, 0, pel_pixels, 10, sse4); + QPEL_LINKS(c->put_hevc_qpel, 0, 1, qpel_h, 10, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 0, qpel_v, 10, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 1, qpel_hv, 10, sse4); + } + if (EXTERNAL_AVX(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_10_avx; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_10_avx; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_10_avx; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_10_avx; + + c->idct[2] = ff_hevc_idct_16x16_10_avx; + c->idct[3] = ff_hevc_idct_32x32_10_avx; + } + + c->idct[0] = ff_hevc_idct_4x4_10_avx; + c->idct[1] = ff_hevc_idct_8x8_10_avx; + + SAO_BAND_INIT(10, avx); + } + if (EXTERNAL_AVX2(cpu_flags)) { + c->sao_band_filter[0] = ff_hevc_sao_band_filter_8_10_avx2; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->idct_dc[2] = ff_hevc_idct_16x16_dc_10_avx2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_10_avx2; + if (ARCH_X86_64) { + c->put_hevc_epel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_10_avx2; + c->put_hevc_epel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_10_avx2; + c->put_hevc_epel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_10_avx2; + c->put_hevc_epel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_10_avx2; + c->put_hevc_epel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_10_avx2; + + c->put_hevc_qpel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_10_avx2; + c->put_hevc_qpel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_10_avx2; + c->put_hevc_qpel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_10_avx2; + c->put_hevc_qpel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_10_avx2; + c->put_hevc_qpel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_10_avx2; + + c->put_hevc_epel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_avx2; + c->put_hevc_epel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_avx2; + c->put_hevc_epel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_avx2; + c->put_hevc_epel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels96_8_avx2; + c->put_hevc_epel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels128_8_avx2; + + c->put_hevc_qpel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_avx2; + c->put_hevc_qpel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_avx2; + c->put_hevc_qpel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_avx2; + c->put_hevc_qpel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels96_8_avx2; + c->put_hevc_qpel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels128_8_avx2; + + c->put_hevc_epel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_10_avx2; + c->put_hevc_epel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_10_avx2; + c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_10_avx2; + c->put_hevc_epel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_10_avx2; + c->put_hevc_epel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_10_avx2; + c->put_hevc_qpel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_10_avx2; + c->put_hevc_qpel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_10_avx2; + c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_10_avx2; + c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_10_avx2; + c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_10_avx2; + + c->put_hevc_epel[5][0][1] = ff_hevc_put_hevc_epel_h16_10_avx2; + c->put_hevc_epel[6][0][1] = ff_hevc_put_hevc_epel_h24_10_avx2; + c->put_hevc_epel[7][0][1] = ff_hevc_put_hevc_epel_h32_10_avx2; + c->put_hevc_epel[8][0][1] = ff_hevc_put_hevc_epel_h48_10_avx2; + c->put_hevc_epel[9][0][1] = ff_hevc_put_hevc_epel_h64_10_avx2; + + c->put_hevc_epel_uni[5][0][1] = ff_hevc_put_hevc_uni_epel_h16_10_avx2; + c->put_hevc_epel_uni[6][0][1] = ff_hevc_put_hevc_uni_epel_h24_10_avx2; + c->put_hevc_epel_uni[7][0][1] = ff_hevc_put_hevc_uni_epel_h32_10_avx2; + c->put_hevc_epel_uni[8][0][1] = ff_hevc_put_hevc_uni_epel_h48_10_avx2; + c->put_hevc_epel_uni[9][0][1] = ff_hevc_put_hevc_uni_epel_h64_10_avx2; + + c->put_hevc_epel_bi[5][0][1] = ff_hevc_put_hevc_bi_epel_h16_10_avx2; + c->put_hevc_epel_bi[6][0][1] = ff_hevc_put_hevc_bi_epel_h24_10_avx2; + c->put_hevc_epel_bi[7][0][1] = ff_hevc_put_hevc_bi_epel_h32_10_avx2; + c->put_hevc_epel_bi[8][0][1] = ff_hevc_put_hevc_bi_epel_h48_10_avx2; + c->put_hevc_epel_bi[9][0][1] = ff_hevc_put_hevc_bi_epel_h64_10_avx2; + + c->put_hevc_epel[5][1][0] = ff_hevc_put_hevc_epel_v16_10_avx2; + c->put_hevc_epel[6][1][0] = ff_hevc_put_hevc_epel_v24_10_avx2; + c->put_hevc_epel[7][1][0] = ff_hevc_put_hevc_epel_v32_10_avx2; + c->put_hevc_epel[8][1][0] = ff_hevc_put_hevc_epel_v48_10_avx2; + c->put_hevc_epel[9][1][0] = ff_hevc_put_hevc_epel_v64_10_avx2; + + c->put_hevc_epel_uni[5][1][0] = ff_hevc_put_hevc_uni_epel_v16_10_avx2; + c->put_hevc_epel_uni[6][1][0] = ff_hevc_put_hevc_uni_epel_v24_10_avx2; + c->put_hevc_epel_uni[7][1][0] = ff_hevc_put_hevc_uni_epel_v32_10_avx2; + c->put_hevc_epel_uni[8][1][0] = ff_hevc_put_hevc_uni_epel_v48_10_avx2; + c->put_hevc_epel_uni[9][1][0] = ff_hevc_put_hevc_uni_epel_v64_10_avx2; + + c->put_hevc_epel_bi[5][1][0] = ff_hevc_put_hevc_bi_epel_v16_10_avx2; + c->put_hevc_epel_bi[6][1][0] = ff_hevc_put_hevc_bi_epel_v24_10_avx2; + c->put_hevc_epel_bi[7][1][0] = ff_hevc_put_hevc_bi_epel_v32_10_avx2; + c->put_hevc_epel_bi[8][1][0] = ff_hevc_put_hevc_bi_epel_v48_10_avx2; + c->put_hevc_epel_bi[9][1][0] = ff_hevc_put_hevc_bi_epel_v64_10_avx2; + + c->put_hevc_epel[5][1][1] = ff_hevc_put_hevc_epel_hv16_10_avx2; + c->put_hevc_epel[6][1][1] = ff_hevc_put_hevc_epel_hv24_10_avx2; + c->put_hevc_epel[7][1][1] = ff_hevc_put_hevc_epel_hv32_10_avx2; + c->put_hevc_epel[8][1][1] = ff_hevc_put_hevc_epel_hv48_10_avx2; + c->put_hevc_epel[9][1][1] = ff_hevc_put_hevc_epel_hv64_10_avx2; + + c->put_hevc_epel_uni[5][1][1] = ff_hevc_put_hevc_uni_epel_hv16_10_avx2; + c->put_hevc_epel_uni[6][1][1] = ff_hevc_put_hevc_uni_epel_hv24_10_avx2; + c->put_hevc_epel_uni[7][1][1] = ff_hevc_put_hevc_uni_epel_hv32_10_avx2; + c->put_hevc_epel_uni[8][1][1] = ff_hevc_put_hevc_uni_epel_hv48_10_avx2; + c->put_hevc_epel_uni[9][1][1] = ff_hevc_put_hevc_uni_epel_hv64_10_avx2; + + c->put_hevc_epel_bi[5][1][1] = ff_hevc_put_hevc_bi_epel_hv16_10_avx2; + c->put_hevc_epel_bi[6][1][1] = ff_hevc_put_hevc_bi_epel_hv24_10_avx2; + c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_bi_epel_hv32_10_avx2; + c->put_hevc_epel_bi[8][1][1] = ff_hevc_put_hevc_bi_epel_hv48_10_avx2; + c->put_hevc_epel_bi[9][1][1] = ff_hevc_put_hevc_bi_epel_hv64_10_avx2; + + c->put_hevc_qpel[5][0][1] = ff_hevc_put_hevc_qpel_h16_10_avx2; + c->put_hevc_qpel[6][0][1] = ff_hevc_put_hevc_qpel_h24_10_avx2; + c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_10_avx2; + c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_10_avx2; + c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_10_avx2; + + c->put_hevc_qpel_uni[5][0][1] = ff_hevc_put_hevc_uni_qpel_h16_10_avx2; + c->put_hevc_qpel_uni[6][0][1] = ff_hevc_put_hevc_uni_qpel_h24_10_avx2; + c->put_hevc_qpel_uni[7][0][1] = ff_hevc_put_hevc_uni_qpel_h32_10_avx2; + c->put_hevc_qpel_uni[8][0][1] = ff_hevc_put_hevc_uni_qpel_h48_10_avx2; + c->put_hevc_qpel_uni[9][0][1] = ff_hevc_put_hevc_uni_qpel_h64_10_avx2; + + c->put_hevc_qpel_bi[5][0][1] = ff_hevc_put_hevc_bi_qpel_h16_10_avx2; + c->put_hevc_qpel_bi[6][0][1] = ff_hevc_put_hevc_bi_qpel_h24_10_avx2; + c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_bi_qpel_h32_10_avx2; + c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_bi_qpel_h48_10_avx2; + c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_bi_qpel_h64_10_avx2; + + c->put_hevc_qpel[5][1][0] = ff_hevc_put_hevc_qpel_v16_10_avx2; + c->put_hevc_qpel[6][1][0] = ff_hevc_put_hevc_qpel_v24_10_avx2; + c->put_hevc_qpel[7][1][0] = ff_hevc_put_hevc_qpel_v32_10_avx2; + c->put_hevc_qpel[8][1][0] = ff_hevc_put_hevc_qpel_v48_10_avx2; + c->put_hevc_qpel[9][1][0] = ff_hevc_put_hevc_qpel_v64_10_avx2; + + c->put_hevc_qpel_uni[5][1][0] = ff_hevc_put_hevc_uni_qpel_v16_10_avx2; + c->put_hevc_qpel_uni[6][1][0] = ff_hevc_put_hevc_uni_qpel_v24_10_avx2; + c->put_hevc_qpel_uni[7][1][0] = ff_hevc_put_hevc_uni_qpel_v32_10_avx2; + c->put_hevc_qpel_uni[8][1][0] = ff_hevc_put_hevc_uni_qpel_v48_10_avx2; + c->put_hevc_qpel_uni[9][1][0] = ff_hevc_put_hevc_uni_qpel_v64_10_avx2; + + c->put_hevc_qpel_bi[5][1][0] = ff_hevc_put_hevc_bi_qpel_v16_10_avx2; + c->put_hevc_qpel_bi[6][1][0] = ff_hevc_put_hevc_bi_qpel_v24_10_avx2; + c->put_hevc_qpel_bi[7][1][0] = ff_hevc_put_hevc_bi_qpel_v32_10_avx2; + c->put_hevc_qpel_bi[8][1][0] = ff_hevc_put_hevc_bi_qpel_v48_10_avx2; + c->put_hevc_qpel_bi[9][1][0] = ff_hevc_put_hevc_bi_qpel_v64_10_avx2; + + c->put_hevc_qpel[5][1][1] = ff_hevc_put_hevc_qpel_hv16_10_avx2; + c->put_hevc_qpel[6][1][1] = ff_hevc_put_hevc_qpel_hv24_10_avx2; + c->put_hevc_qpel[7][1][1] = ff_hevc_put_hevc_qpel_hv32_10_avx2; + c->put_hevc_qpel[8][1][1] = ff_hevc_put_hevc_qpel_hv48_10_avx2; + c->put_hevc_qpel[9][1][1] = ff_hevc_put_hevc_qpel_hv64_10_avx2; + + c->put_hevc_qpel_uni[5][1][1] = ff_hevc_put_hevc_uni_qpel_hv16_10_avx2; + c->put_hevc_qpel_uni[6][1][1] = ff_hevc_put_hevc_uni_qpel_hv24_10_avx2; + c->put_hevc_qpel_uni[7][1][1] = ff_hevc_put_hevc_uni_qpel_hv32_10_avx2; + c->put_hevc_qpel_uni[8][1][1] = ff_hevc_put_hevc_uni_qpel_hv48_10_avx2; + c->put_hevc_qpel_uni[9][1][1] = ff_hevc_put_hevc_uni_qpel_hv64_10_avx2; + + c->put_hevc_qpel_bi[5][1][1] = ff_hevc_put_hevc_bi_qpel_hv16_10_avx2; + c->put_hevc_qpel_bi[6][1][1] = ff_hevc_put_hevc_bi_qpel_hv24_10_avx2; + c->put_hevc_qpel_bi[7][1][1] = ff_hevc_put_hevc_bi_qpel_hv32_10_avx2; + c->put_hevc_qpel_bi[8][1][1] = ff_hevc_put_hevc_bi_qpel_hv48_10_avx2; + c->put_hevc_qpel_bi[9][1][1] = ff_hevc_put_hevc_bi_qpel_hv64_10_avx2; + } + SAO_BAND_INIT(10, avx2); + SAO_EDGE_INIT(10, avx2); + + c->add_residual[2] = ff_hevc_add_residual_16_10_avx2; + c->add_residual[3] = ff_hevc_add_residual_32_10_avx2; + } + } else if (bit_depth == 12) { + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->idct_dc[0] = ff_hevc_idct_4x4_dc_12_mmxext; + c->idct_dc[1] = ff_hevc_idct_8x8_dc_12_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_12_sse2; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_12_sse2; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_12_sse2; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_12_sse2; + } + SAO_BAND_INIT(12, sse2); + SAO_EDGE_INIT(12, sse2); + + c->idct_dc[1] = ff_hevc_idct_8x8_dc_12_sse2; + c->idct_dc[2] = ff_hevc_idct_16x16_dc_12_sse2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_12_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags) && ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_12_ssse3; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_12_ssse3; + } + if (EXTERNAL_SSE4(cpu_flags) && ARCH_X86_64) { + EPEL_LINKS(c->put_hevc_epel, 0, 0, pel_pixels, 12, sse4); + EPEL_LINKS(c->put_hevc_epel, 0, 1, epel_h, 12, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 0, epel_v, 12, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 1, epel_hv, 12, sse4); + + QPEL_LINKS(c->put_hevc_qpel, 0, 0, pel_pixels, 12, sse4); + QPEL_LINKS(c->put_hevc_qpel, 0, 1, qpel_h, 12, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 0, qpel_v, 12, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 1, qpel_hv, 12, sse4); + } + if (EXTERNAL_AVX(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_12_avx; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_12_avx; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_12_avx; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_12_avx; + } + SAO_BAND_INIT(12, avx); + } + if (EXTERNAL_AVX2(cpu_flags)) { + c->sao_band_filter[0] = ff_hevc_sao_band_filter_8_12_avx2; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->idct_dc[2] = ff_hevc_idct_16x16_dc_12_avx2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_12_avx2; + + SAO_BAND_INIT(12, avx2); + SAO_EDGE_INIT(12, avx2); + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp.h new file mode 100644 index 000000000..bf97029b5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp.h @@ -0,0 +1,57 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_HPELDSP_H +#define AVCODEC_X86_HPELDSP_H + +#include +#include + +#include "libavcodec/hpeldsp.h" + +void ff_avg_pixels8_x2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_avg_pixels8_xy2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_xy2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_xy2_ssse3(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_avg_pixels16_xy2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_xy2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_xy2_ssse3(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_put_pixels8_xy2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_xy2_ssse3(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_xy2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_xy2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_xy2_ssse3(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_hpeldsp_vp3_init_x86(HpelDSPContext *c, int cpu_flags, int flags); + +#endif /* AVCODEC_X86_HPELDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_init.c new file mode 100644 index 000000000..d89928cec --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_init.c @@ -0,0 +1,313 @@ +/* + * SIMD-optimized halfpel functions + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * MMX optimization by Nick Kurshev + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/hpeldsp.h" +#include "libavcodec/pixels.h" +#include "fpel.h" +#include "hpeldsp.h" + +void ff_put_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_x2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_x2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_x2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_x2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_y2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_y2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_xy2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_approx_pixels8_xy2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_approx_pixels8_xy2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +#define avg_pixels8_mmx ff_avg_pixels8_mmx +#define avg_pixels8_x2_mmx ff_avg_pixels8_x2_mmx +#define avg_pixels16_mmx ff_avg_pixels16_mmx +#define avg_pixels8_xy2_mmx ff_avg_pixels8_xy2_mmx +#define avg_pixels16_xy2_mmx ff_avg_pixels16_xy2_mmx +#define put_pixels8_mmx ff_put_pixels8_mmx +#define put_pixels16_mmx ff_put_pixels16_mmx +#define put_pixels8_xy2_mmx ff_put_pixels8_xy2_mmx +#define put_pixels16_xy2_mmx ff_put_pixels16_xy2_mmx +#define avg_no_rnd_pixels16_mmx ff_avg_pixels16_mmx +#define put_no_rnd_pixels8_mmx ff_put_pixels8_mmx +#define put_no_rnd_pixels16_mmx ff_put_pixels16_mmx + +#if HAVE_INLINE_ASM + +/***********************************/ +/* MMX no rounding */ +#define DEF(x, y) x ## _no_rnd_ ## y ## _mmx +#define SET_RND MOVQ_WONE +#define PAVGBP(a, b, c, d, e, f) PAVGBP_MMX_NO_RND(a, b, c, d, e, f) +#define PAVGB(a, b, c, e) PAVGB_MMX_NO_RND(a, b, c, e) +#define STATIC static + +#include "rnd_template.c" +#include "hpeldsp_rnd_template.c" + +#undef DEF +#undef SET_RND +#undef PAVGBP +#undef PAVGB +#undef STATIC + +#if HAVE_MMX +CALL_2X_PIXELS(avg_no_rnd_pixels16_y2_mmx, avg_no_rnd_pixels8_y2_mmx, 8) +CALL_2X_PIXELS(put_no_rnd_pixels16_y2_mmx, put_no_rnd_pixels8_y2_mmx, 8) + +CALL_2X_PIXELS(avg_no_rnd_pixels16_xy2_mmx, avg_no_rnd_pixels8_xy2_mmx, 8) +CALL_2X_PIXELS(put_no_rnd_pixels16_xy2_mmx, put_no_rnd_pixels8_xy2_mmx, 8) +#endif + +/***********************************/ +/* MMX rounding */ + +#define DEF(x, y) x ## _ ## y ## _mmx +#define SET_RND MOVQ_WTWO +#define PAVGBP(a, b, c, d, e, f) PAVGBP_MMX(a, b, c, d, e, f) +#define PAVGB(a, b, c, e) PAVGB_MMX(a, b, c, e) + +#include "hpeldsp_rnd_template.c" + +#undef DEF +#define DEF(x, y) ff_ ## x ## _ ## y ## _mmx +#define STATIC + +#include "rnd_template.c" + +#undef DEF +#undef SET_RND +#undef PAVGBP +#undef PAVGB + +#if HAVE_MMX +CALL_2X_PIXELS(avg_pixels16_y2_mmx, avg_pixels8_y2_mmx, 8) +CALL_2X_PIXELS(put_pixels16_y2_mmx, put_pixels8_y2_mmx, 8) + +CALL_2X_PIXELS_EXPORT(ff_avg_pixels16_xy2_mmx, ff_avg_pixels8_xy2_mmx, 8) +CALL_2X_PIXELS_EXPORT(ff_put_pixels16_xy2_mmx, ff_put_pixels8_xy2_mmx, 8) +#endif + +#endif /* HAVE_INLINE_ASM */ + + +#if HAVE_X86ASM + +#define HPELDSP_AVG_PIXELS16(CPUEXT) \ + CALL_2X_PIXELS(put_no_rnd_pixels16_x2 ## CPUEXT, ff_put_no_rnd_pixels8_x2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(put_pixels16_y2 ## CPUEXT, ff_put_pixels8_y2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(put_no_rnd_pixels16_y2 ## CPUEXT, ff_put_no_rnd_pixels8_y2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_pixels16 ## CPUEXT, ff_avg_pixels8 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_pixels16_x2 ## CPUEXT, ff_avg_pixels8_x2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_pixels16_y2 ## CPUEXT, ff_avg_pixels8_y2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_pixels16_xy2 ## CPUEXT, ff_avg_pixels8_xy2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_approx_pixels16_xy2## CPUEXT, ff_avg_approx_pixels8_xy2## CPUEXT, 8) + +HPELDSP_AVG_PIXELS16(_3dnow) +HPELDSP_AVG_PIXELS16(_mmxext) + +#endif /* HAVE_X86ASM */ + +#define SET_HPEL_FUNCS_EXT(PFX, IDX, SIZE, CPU) \ + if (HAVE_MMX_EXTERNAL) \ + c->PFX ## _pixels_tab IDX [0] = PFX ## _pixels ## SIZE ## _ ## CPU; + +#if HAVE_MMX_INLINE +#define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU) \ + do { \ + SET_HPEL_FUNCS_EXT(PFX, IDX, SIZE, CPU) \ + c->PFX ## _pixels_tab IDX [1] = PFX ## _pixels ## SIZE ## _x2_ ## CPU; \ + c->PFX ## _pixels_tab IDX [2] = PFX ## _pixels ## SIZE ## _y2_ ## CPU; \ + c->PFX ## _pixels_tab IDX [3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU; \ + } while (0) +#else +#define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU) \ + do { \ + SET_HPEL_FUNCS_EXT(PFX, IDX, SIZE, CPU) \ + } while (0) +#endif + +static void hpeldsp_init_mmx(HpelDSPContext *c, int flags) +{ + SET_HPEL_FUNCS(put, [0], 16, mmx); + SET_HPEL_FUNCS(put_no_rnd, [0], 16, mmx); + SET_HPEL_FUNCS(avg, [0], 16, mmx); + SET_HPEL_FUNCS(avg_no_rnd, , 16, mmx); + SET_HPEL_FUNCS(put, [1], 8, mmx); + SET_HPEL_FUNCS(put_no_rnd, [1], 8, mmx); + if (HAVE_MMX_EXTERNAL) { + c->avg_pixels_tab[1][0] = ff_avg_pixels8_mmx; + c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_mmx; + } +#if HAVE_MMX_INLINE + c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmx; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_mmx; +#endif +} + +static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags) +{ +#if HAVE_MMXEXT_EXTERNAL + c->put_pixels_tab[0][1] = ff_put_pixels16_x2_mmxext; + c->put_pixels_tab[0][2] = put_pixels16_y2_mmxext; + + c->avg_pixels_tab[0][0] = avg_pixels16_mmxext; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmxext; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmxext; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmxext; + + c->put_pixels_tab[1][1] = ff_put_pixels8_x2_mmxext; + c->put_pixels_tab[1][2] = ff_put_pixels8_y2_mmxext; + + c->avg_pixels_tab[1][0] = ff_avg_pixels8_mmxext; + c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_mmxext; + c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_mmxext; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_mmxext; + + if (!(flags & AV_CODEC_FLAG_BITEXACT)) { + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmxext; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmxext; + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_mmxext; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_mmxext; + + c->avg_pixels_tab[0][3] = avg_approx_pixels16_xy2_mmxext; + c->avg_pixels_tab[1][3] = ff_avg_approx_pixels8_xy2_mmxext; + } +#endif /* HAVE_MMXEXT_EXTERNAL */ +} + +static void hpeldsp_init_3dnow(HpelDSPContext *c, int flags) +{ +#if HAVE_AMD3DNOW_EXTERNAL + c->put_pixels_tab[0][1] = ff_put_pixels16_x2_3dnow; + c->put_pixels_tab[0][2] = put_pixels16_y2_3dnow; + + c->avg_pixels_tab[0][0] = avg_pixels16_3dnow; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_3dnow; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_3dnow; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_3dnow; + + c->put_pixels_tab[1][1] = ff_put_pixels8_x2_3dnow; + c->put_pixels_tab[1][2] = ff_put_pixels8_y2_3dnow; + + c->avg_pixels_tab[1][0] = ff_avg_pixels8_3dnow; + c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_3dnow; + c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_3dnow; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_3dnow; + + if (!(flags & AV_CODEC_FLAG_BITEXACT)){ + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_3dnow; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_3dnow; + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_3dnow; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_3dnow; + + c->avg_pixels_tab[0][3] = avg_approx_pixels16_xy2_3dnow; + c->avg_pixels_tab[1][3] = ff_avg_approx_pixels8_xy2_3dnow; + } +#endif /* HAVE_AMD3DNOW_EXTERNAL */ +} + +static void hpeldsp_init_sse2_fast(HpelDSPContext *c, int flags) +{ +#if HAVE_SSE2_EXTERNAL + c->put_pixels_tab[0][0] = ff_put_pixels16_sse2; + c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_sse2; + c->put_pixels_tab[0][1] = ff_put_pixels16_x2_sse2; + c->put_pixels_tab[0][2] = ff_put_pixels16_y2_sse2; + c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_sse2; + c->avg_pixels_tab[0][0] = ff_avg_pixels16_sse2; + c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_sse2; + c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_sse2; + c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_sse2; +#endif /* HAVE_SSE2_EXTERNAL */ +} + +static void hpeldsp_init_ssse3(HpelDSPContext *c, int flags) +{ +#if HAVE_SSSE3_EXTERNAL + c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_ssse3; + c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_ssse3; + c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_ssse3; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_ssse3; +#endif +} + +av_cold void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags) +{ + int cpu_flags = av_get_cpu_flags(); + + if (INLINE_MMX(cpu_flags)) + hpeldsp_init_mmx(c, flags); + + if (EXTERNAL_AMD3DNOW(cpu_flags)) + hpeldsp_init_3dnow(c, flags); + + if (EXTERNAL_MMXEXT(cpu_flags)) + hpeldsp_init_mmxext(c, flags); + + if (EXTERNAL_SSE2_FAST(cpu_flags)) + hpeldsp_init_sse2_fast(c, flags); + + if (EXTERNAL_SSSE3(cpu_flags)) + hpeldsp_init_ssse3(c, flags); + + if (CONFIG_VP3_DECODER) + ff_hpeldsp_vp3_init_x86(c, cpu_flags, flags); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_rnd_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_rnd_template.c new file mode 100644 index 000000000..2bff2d276 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_rnd_template.c @@ -0,0 +1,202 @@ +/* + * SIMD-optimized halfpel functions are compiled twice for rnd/no_rnd + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2003-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * mostly rewritten by Michael Niedermayer + * and improved by Zdenek Kabelac + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +// put_pixels +av_unused static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +av_unused static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%1, %3), %%mm2 \n\t" + "movq 9(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, 8(%2) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%1, %3), %%mm2 \n\t" + "movq 9(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, 8(%2) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +av_unused static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"),%%mm2\n\t" + PAVGBP(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"),%%mm0\n\t" + PAVGBP(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +av_unused static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%2), %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, (%2) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%2), %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, 8(%2) \n\t" + "add %3, %1 \n\t" + "add %3, %2 \n\t" + "subl $1, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :"memory"); +} + +av_unused static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" + PAVGBP(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) + "movq (%2), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm4, %%mm0, %%mm6) + "movq (%2, %3), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + PAVGBP(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) + "movq (%2), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm4, %%mm2, %%mm6) + "movq (%2, %3), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) + "movq %%mm2, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_vp3_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_vp3_init.c new file mode 100644 index 000000000..5979f4123 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/hpeldsp_vp3_init.c @@ -0,0 +1,56 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" + +#include "libavcodec/avcodec.h" +#include "libavcodec/hpeldsp.h" + +#include "hpeldsp.h" + +void ff_put_no_rnd_pixels8_x2_exact_mmxext(uint8_t *block, + const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_x2_exact_3dnow(uint8_t *block, + const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_y2_exact_mmxext(uint8_t *block, + const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_y2_exact_3dnow(uint8_t *block, + const uint8_t *pixels, + ptrdiff_t line_size, int h); + +av_cold void ff_hpeldsp_vp3_init_x86(HpelDSPContext *c, int cpu_flags, int flags) +{ + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + if (flags & AV_CODEC_FLAG_BITEXACT) { + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_3dnow; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_3dnow; + } + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + if (flags & AV_CODEC_FLAG_BITEXACT) { + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_mmxext; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_mmxext; + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/huffyuvdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/huffyuvdsp_init.c new file mode 100644 index 000000000..eb10de383 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/huffyuvdsp_init.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2009 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/pixdesc.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/huffyuvdsp.h" + +void ff_add_int16_mmx(uint16_t *dst, const uint16_t *src, unsigned mask, int w); +void ff_add_int16_sse2(uint16_t *dst, const uint16_t *src, unsigned mask, int w); +void ff_add_int16_avx2(uint16_t *dst, const uint16_t *src, unsigned mask, int w); + +void ff_add_hfyu_left_pred_bgr32_mmx(uint8_t *dst, const uint8_t *src, + intptr_t w, uint8_t *left); +void ff_add_hfyu_left_pred_bgr32_sse2(uint8_t *dst, const uint8_t *src, + intptr_t w, uint8_t *left); +void ff_add_hfyu_median_pred_int16_mmxext(uint16_t *dst, const uint16_t *top, const uint16_t *diff, unsigned mask, int w, int *left, int *left_top); + +av_cold void ff_huffyuvdsp_init_x86(HuffYUVDSPContext *c, enum AVPixelFormat pix_fmt) +{ + int cpu_flags = av_get_cpu_flags(); + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(pix_fmt); + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { + c->add_hfyu_left_pred_bgr32 = ff_add_hfyu_left_pred_bgr32_mmx; + c->add_int16 = ff_add_int16_mmx; + } + + if (EXTERNAL_MMXEXT(cpu_flags) && pix_desc && pix_desc->comp[0].depth<16) { + c->add_hfyu_median_pred_int16 = ff_add_hfyu_median_pred_int16_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->add_int16 = ff_add_int16_sse2; + c->add_hfyu_left_pred_bgr32 = ff_add_hfyu_left_pred_bgr32_sse2; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->add_int16 = ff_add_int16_avx2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/huffyuvencdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/huffyuvencdsp_init.c new file mode 100644 index 000000000..6c6e068cf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/huffyuvencdsp_init.c @@ -0,0 +1,60 @@ +/* + * SIMD-optimized HuffYUV encoding functions + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/pixdesc.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/huffyuvencdsp.h" + +void ff_diff_int16_mmx (uint16_t *dst, const uint16_t *src1, const uint16_t *src2, + unsigned mask, int w); +void ff_diff_int16_sse2(uint16_t *dst, const uint16_t *src1, const uint16_t *src2, + unsigned mask, int w); +void ff_diff_int16_avx2(uint16_t *dst, const uint16_t *src1, const uint16_t *src2, + unsigned mask, int w); +void ff_sub_hfyu_median_pred_int16_mmxext(uint16_t *dst, const uint16_t *src1, const uint16_t *src2, + unsigned mask, int w, int *left, int *left_top); + +av_cold void ff_huffyuvencdsp_init_x86(HuffYUVEncDSPContext *c, AVCodecContext *avctx) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(avctx->pix_fmt); + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { + c->diff_int16 = ff_diff_int16_mmx; + } + + if (EXTERNAL_MMXEXT(cpu_flags) && pix_desc && pix_desc->comp[0].depth<16) { + c->sub_hfyu_median_pred_int16 = ff_sub_hfyu_median_pred_int16_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->diff_int16 = ff_diff_int16_sse2; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->diff_int16 = ff_diff_int16_avx2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/idctdsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/idctdsp.h new file mode 100644 index 000000000..0d0bdb5f5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/idctdsp.h @@ -0,0 +1,39 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_IDCTDSP_H +#define AVCODEC_X86_IDCTDSP_H + +#include +#include + +void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_add_pixels_clamped_sse2(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_put_pixels_clamped_sse2(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_put_signed_pixels_clamped_sse2(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); + + +#endif /* AVCODEC_X86_IDCTDSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/idctdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/idctdsp_init.c new file mode 100644 index 000000000..9103b92ce --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/idctdsp_init.c @@ -0,0 +1,162 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/idctdsp.h" +#include "idctdsp.h" +#include "simple_idct.h" + +/* Input permutation for the simple_idct_mmx */ +static const uint8_t simple_mmx_permutation[64] = { + 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, + 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, + 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, + 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, + 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, + 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, + 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, + 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, +}; + +static const uint8_t idct_sse2_row_perm[8] = { 0, 4, 1, 5, 2, 6, 3, 7 }; + +av_cold int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, + enum idct_permutation_type perm_type) +{ + int i; + + switch (perm_type) { + case FF_IDCT_PERM_SIMPLE: + for (i = 0; i < 64; i++) + idct_permutation[i] = simple_mmx_permutation[i]; + return 1; + case FF_IDCT_PERM_SSE2: + for (i = 0; i < 64; i++) + idct_permutation[i] = (i & 0x38) | idct_sse2_row_perm[i & 7]; + return 1; + } + + return 0; +} + +av_cold void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx; + c->put_pixels_clamped = ff_put_pixels_clamped_mmx; + c->add_pixels_clamped = ff_add_pixels_clamped_mmx; + + if (!high_bit_depth && + avctx->lowres == 0 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX)) { + c->idct_put = ff_simple_idct_put_mmx; + c->idct_add = ff_simple_idct_add_mmx; + c->idct = ff_simple_idct_mmx; + c->perm_type = FF_IDCT_PERM_SIMPLE; + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_sse2; + c->put_pixels_clamped = ff_put_pixels_clamped_sse2; + c->add_pixels_clamped = ff_add_pixels_clamped_sse2; + + if (!high_bit_depth && + avctx->lowres == 0 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX)) { + c->idct_put = ff_simple_idct_put_sse2; + c->idct_add = ff_simple_idct_add_sse2; + c->perm_type = FF_IDCT_PERM_SIMPLE; + } + + if (ARCH_X86_64 && + !high_bit_depth && + avctx->lowres == 0 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX || + avctx->idct_algo == FF_IDCT_SIMPLE)) { + c->idct = ff_simple_idct8_sse2; + c->idct_put = ff_simple_idct8_put_sse2; + c->idct_add = ff_simple_idct8_add_sse2; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + } + + if (ARCH_X86_64 && avctx->lowres == 0) { + if (EXTERNAL_AVX(cpu_flags) && + !high_bit_depth && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX || + avctx->idct_algo == FF_IDCT_SIMPLE)) { + c->idct = ff_simple_idct8_avx; + c->idct_put = ff_simple_idct8_put_avx; + c->idct_add = ff_simple_idct8_add_avx; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + + if (avctx->bits_per_raw_sample == 10 && + avctx->codec_id != AV_CODEC_ID_MPEG4 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLE)) { + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct_put = ff_simple_idct10_put_sse2; + c->idct_add = NULL; + c->idct = ff_simple_idct10_sse2; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + + } + if (EXTERNAL_AVX(cpu_flags)) { + c->idct_put = ff_simple_idct10_put_avx; + c->idct_add = NULL; + c->idct = ff_simple_idct10_avx; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + } + + if (avctx->bits_per_raw_sample == 12 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX)) { + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct_put = ff_simple_idct12_put_sse2; + c->idct_add = NULL; + c->idct = ff_simple_idct12_sse2; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + if (EXTERNAL_AVX(cpu_flags)) { + c->idct_put = ff_simple_idct12_put_avx; + c->idct_add = NULL; + c->idct = ff_simple_idct12_avx; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/inline_asm.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/inline_asm.h new file mode 100644 index 000000000..019874671 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/inline_asm.h @@ -0,0 +1,100 @@ +/* + * inline assembly helper macros + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_INLINE_ASM_H +#define AVCODEC_X86_INLINE_ASM_H + +#include "constants.h" + +#define MOVQ_WONE(regd) \ + __asm__ volatile ( \ + "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ + "psrlw $15, %%" #regd ::) + +#define JUMPALIGN() __asm__ volatile (".p2align 3"::) +#define MOVQ_ZERO(regd) __asm__ volatile ("pxor %%"#regd", %%"#regd ::) + +#define MOVQ_BFE(regd) \ + __asm__ volatile ( \ + "pcmpeqd %%"#regd", %%"#regd" \n\t" \ + "paddb %%"#regd", %%"#regd" \n\t" ::) + +#ifndef PIC +#define MOVQ_WTWO(regd) __asm__ volatile ("movq %0, %%"#regd" \n\t" :: "m"(ff_pw_2)) +#else +// for shared library it's better to use this way for accessing constants +// pcmpeqd -> -1 +#define MOVQ_WTWO(regd) \ + __asm__ volatile ( \ + "pcmpeqd %%"#regd", %%"#regd" \n\t" \ + "psrlw $15, %%"#regd" \n\t" \ + "psllw $1, %%"#regd" \n\t"::) + +#endif + +// using regr as temporary and for the output result +// first argument is unmodified and second is trashed +// regfe is supposed to contain 0xfefefefefefefefe +#define PAVGB_MMX_NO_RND(rega, regb, regr, regfe) \ + "movq "#rega", "#regr" \n\t" \ + "pand "#regb", "#regr" \n\t" \ + "pxor "#rega", "#regb" \n\t" \ + "pand "#regfe", "#regb" \n\t" \ + "psrlq $1, "#regb" \n\t" \ + "paddb "#regb", "#regr" \n\t" + +#define PAVGB_MMX(rega, regb, regr, regfe) \ + "movq "#rega", "#regr" \n\t" \ + "por "#regb", "#regr" \n\t" \ + "pxor "#rega", "#regb" \n\t" \ + "pand "#regfe", "#regb" \n\t" \ + "psrlq $1, "#regb" \n\t" \ + "psubb "#regb", "#regr" \n\t" + +// mm6 is supposed to contain 0xfefefefefefefefe +#define PAVGBP_MMX_NO_RND(rega, regb, regr, regc, regd, regp) \ + "movq "#rega", "#regr" \n\t" \ + "movq "#regc", "#regp" \n\t" \ + "pand "#regb", "#regr" \n\t" \ + "pand "#regd", "#regp" \n\t" \ + "pxor "#rega", "#regb" \n\t" \ + "pxor "#regc", "#regd" \n\t" \ + "pand %%mm6, "#regb" \n\t" \ + "pand %%mm6, "#regd" \n\t" \ + "psrlq $1, "#regb" \n\t" \ + "psrlq $1, "#regd" \n\t" \ + "paddb "#regb", "#regr" \n\t" \ + "paddb "#regd", "#regp" \n\t" + +#define PAVGBP_MMX(rega, regb, regr, regc, regd, regp) \ + "movq "#rega", "#regr" \n\t" \ + "movq "#regc", "#regp" \n\t" \ + "por "#regb", "#regr" \n\t" \ + "por "#regd", "#regp" \n\t" \ + "pxor "#rega", "#regb" \n\t" \ + "pxor "#regc", "#regd" \n\t" \ + "pand %%mm6, "#regb" \n\t" \ + "pand %%mm6, "#regd" \n\t" \ + "psrlq $1, "#regd" \n\t" \ + "psrlq $1, "#regb" \n\t" \ + "psubb "#regb", "#regr" \n\t" \ + "psubb "#regd", "#regp" \n\t" + +#endif /* AVCODEC_X86_INLINE_ASM_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/jpeg2000dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/jpeg2000dsp_init.c new file mode 100644 index 000000000..7310a1d0e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/jpeg2000dsp_init.c @@ -0,0 +1,60 @@ +/* + * SIMD optimized JPEG 2000 DSP functions + * Copyright (c) 2015 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/jpeg2000dsp.h" + +void ff_ict_float_sse(void *src0, void *src1, void *src2, int csize); +void ff_ict_float_avx(void *src0, void *src1, void *src2, int csize); +void ff_ict_float_fma3(void *src0, void *src1, void *src2, int csize); +void ff_ict_float_fma4(void *src0, void *src1, void *src2, int csize); +void ff_rct_int_sse2 (void *src0, void *src1, void *src2, int csize); +void ff_rct_int_avx2 (void *src0, void *src1, void *src2, int csize); + +av_cold void ff_jpeg2000dsp_init_x86(Jpeg2000DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + if (EXTERNAL_SSE(cpu_flags)) { + c->mct_decode[FF_DWT97] = ff_ict_float_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->mct_decode[FF_DWT53] = ff_rct_int_sse2; + } + + if (EXTERNAL_AVX_FAST(cpu_flags)) { + c->mct_decode[FF_DWT97] = ff_ict_float_avx; + } + + if (EXTERNAL_FMA4(cpu_flags)) { + c->mct_decode[FF_DWT97] = ff_ict_float_fma4; + } + + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + c->mct_decode[FF_DWT97] = ff_ict_float_fma3; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->mct_decode[FF_DWT53] = ff_rct_int_avx2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_audiodsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_audiodsp_init.c new file mode 100644 index 000000000..f74c7e436 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_audiodsp_init.c @@ -0,0 +1,56 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/lossless_audiodsp.h" + +int32_t ff_scalarproduct_and_madd_int16_mmxext(int16_t *v1, const int16_t *v2, + const int16_t *v3, + int order, int mul); +int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2, + const int16_t *v3, + int order, int mul); +int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2, + const int16_t *v3, + int order, int mul); + +int32_t ff_scalarproduct_and_madd_int32_sse4(int16_t *v1, const int32_t *v2, + const int16_t *v3, + int order, int mul); + +av_cold void ff_llauddsp_init_x86(LLAudDSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMXEXT(cpu_flags)) + c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext; + + if (EXTERNAL_SSE2(cpu_flags)) + c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2; + + if (EXTERNAL_SSSE3(cpu_flags) && + !(cpu_flags & (AV_CPU_FLAG_SSE42 | AV_CPU_FLAG_3DNOW))) // cachesplit + c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3; + + if (EXTERNAL_SSE4(cpu_flags)) + c->scalarproduct_and_madd_int32 = ff_scalarproduct_and_madd_int32_sse4; +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_videodsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_videodsp_init.c new file mode 100644 index 000000000..6d71f14e7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_videodsp_init.c @@ -0,0 +1,128 @@ +/* + * Lossless video DSP utils + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/x86/asm.h" +#include "../lossless_videodsp.h" +#include "libavutil/x86/cpu.h" + +void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t w); +void ff_add_bytes_sse2(uint8_t *dst, uint8_t *src, ptrdiff_t w); +void ff_add_bytes_avx2(uint8_t *dst, uint8_t *src, ptrdiff_t w); + +void ff_add_median_pred_mmxext(uint8_t *dst, const uint8_t *top, + const uint8_t *diff, ptrdiff_t w, + int *left, int *left_top); +void ff_add_median_pred_sse2(uint8_t *dst, const uint8_t *top, + const uint8_t *diff, ptrdiff_t w, + int *left, int *left_top); + +int ff_add_left_pred_ssse3(uint8_t *dst, const uint8_t *src, + ptrdiff_t w, int left); +int ff_add_left_pred_unaligned_ssse3(uint8_t *dst, const uint8_t *src, + ptrdiff_t w, int left); +int ff_add_left_pred_unaligned_avx2(uint8_t *dst, const uint8_t *src, + ptrdiff_t w, int left); + +int ff_add_left_pred_int16_ssse3(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc); +int ff_add_left_pred_int16_unaligned_ssse3(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc); + +void ff_add_gradient_pred_ssse3(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width); +void ff_add_gradient_pred_avx2(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width); + +#if HAVE_INLINE_ASM && HAVE_7REGS && ARCH_X86_32 +static void add_median_pred_cmov(uint8_t *dst, const uint8_t *top, + const uint8_t *diff, ptrdiff_t w, + int *left, int *left_top) +{ + x86_reg w2 = -w; + x86_reg x; + int l = *left & 0xff; + int tl = *left_top & 0xff; + int t; + __asm__ volatile ( + "mov %7, %3 \n" + "1: \n" + "movzbl (%3, %4), %2 \n" + "mov %2, %k3 \n" + "sub %b1, %b3 \n" + "add %b0, %b3 \n" + "mov %2, %1 \n" + "cmp %0, %2 \n" + "cmovg %0, %2 \n" + "cmovg %1, %0 \n" + "cmp %k3, %0 \n" + "cmovg %k3, %0 \n" + "mov %7, %3 \n" + "cmp %2, %0 \n" + "cmovl %2, %0 \n" + "add (%6, %4), %b0 \n" + "mov %b0, (%5, %4) \n" + "inc %4 \n" + "jl 1b \n" + : "+&q"(l), "+&q"(tl), "=&r"(t), "=&q"(x), "+&r"(w2) + : "r"(dst + w), "r"(diff + w), "rm"(top + w) + ); + *left = l; + *left_top = tl; +} +#endif + +void ff_llviddsp_init_x86(LLVidDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + +#if HAVE_INLINE_ASM && HAVE_7REGS && ARCH_X86_32 + if (cpu_flags & AV_CPU_FLAG_CMOV) + c->add_median_pred = add_median_pred_cmov; +#endif + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { + c->add_bytes = ff_add_bytes_mmx; + } + + if (ARCH_X86_32 && EXTERNAL_MMXEXT(cpu_flags)) { + /* slower than cmov version on AMD */ + if (!(cpu_flags & AV_CPU_FLAG_3DNOW)) + c->add_median_pred = ff_add_median_pred_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->add_bytes = ff_add_bytes_sse2; + c->add_median_pred = ff_add_median_pred_sse2; + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + c->add_left_pred = ff_add_left_pred_ssse3; + c->add_left_pred_int16 = ff_add_left_pred_int16_ssse3; + c->add_gradient_pred = ff_add_gradient_pred_ssse3; + } + + if (EXTERNAL_SSSE3_FAST(cpu_flags)) { + c->add_left_pred = ff_add_left_pred_unaligned_ssse3; + c->add_left_pred_int16 = ff_add_left_pred_int16_unaligned_ssse3; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->add_bytes = ff_add_bytes_avx2; + c->add_left_pred = ff_add_left_pred_unaligned_avx2; + c->add_gradient_pred = ff_add_gradient_pred_avx2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_videoencdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_videoencdsp_init.c new file mode 100644 index 000000000..40407add5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lossless_videoencdsp_init.c @@ -0,0 +1,111 @@ +/* + * SIMD-optimized lossless video encoding functions + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/lossless_videoencdsp.h" +#include "libavcodec/mathops.h" + +void ff_diff_bytes_mmx(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + intptr_t w); +void ff_diff_bytes_sse2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + intptr_t w); +void ff_diff_bytes_avx2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + intptr_t w); + +void ff_sub_left_predict_avx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, ptrdiff_t width, int height); + +#if HAVE_INLINE_ASM + +static void sub_median_pred_mmxext(uint8_t *dst, const uint8_t *src1, + const uint8_t *src2, intptr_t w, + int *left, int *left_top) +{ + x86_reg i = 0; + uint8_t l, lt; + + __asm__ volatile ( + "movq (%1, %0), %%mm0 \n\t" // LT + "psllq $8, %%mm0 \n\t" + "1: \n\t" + "movq (%1, %0), %%mm1 \n\t" // T + "movq -1(%2, %0), %%mm2 \n\t" // L + "movq (%2, %0), %%mm3 \n\t" // X + "movq %%mm2, %%mm4 \n\t" // L + "psubb %%mm0, %%mm2 \n\t" + "paddb %%mm1, %%mm2 \n\t" // L + T - LT + "movq %%mm4, %%mm5 \n\t" // L + "pmaxub %%mm1, %%mm4 \n\t" // max(T, L) + "pminub %%mm5, %%mm1 \n\t" // min(T, L) + "pminub %%mm2, %%mm4 \n\t" + "pmaxub %%mm1, %%mm4 \n\t" + "psubb %%mm4, %%mm3 \n\t" // dst - pred + "movq %%mm3, (%3, %0) \n\t" + "add $8, %0 \n\t" + "movq -1(%1, %0), %%mm0 \n\t" // LT + "cmp %4, %0 \n\t" + " jb 1b \n\t" + : "+r" (i) + : "r" (src1), "r" (src2), "r" (dst), "r" ((x86_reg) w)); + + l = *left; + lt = *left_top; + + dst[0] = src2[0] - mid_pred(l, src1[0], (l + src1[0] - lt) & 0xFF); + + *left_top = src1[w - 1]; + *left = src2[w - 1]; +} + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_llvidencdsp_init_x86(LLVidEncDSPContext *c) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { + c->diff_bytes = ff_diff_bytes_mmx; + } + +#if HAVE_INLINE_ASM + if (INLINE_MMXEXT(cpu_flags)) { + c->sub_median_pred = sub_median_pred_mmxext; + } +#endif /* HAVE_INLINE_ASM */ + + if (EXTERNAL_SSE2(cpu_flags)) { + c->diff_bytes = ff_diff_bytes_sse2; + } + + if (EXTERNAL_AVX(cpu_flags)) { + c->sub_left_predict = ff_sub_left_predict_avx; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->diff_bytes = ff_diff_bytes_avx2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lpc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lpc.c new file mode 100644 index 000000000..6c72e21ba --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/lpc.c @@ -0,0 +1,162 @@ +/* + * SIMD-optimized LPC functions + * Copyright (c) 2007 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/lpc.h" + +DECLARE_ASM_CONST(16, double, pd_1)[2] = { 1.0, 1.0 }; +DECLARE_ASM_CONST(16, double, pd_2)[2] = { 2.0, 2.0 }; + +#if HAVE_SSE2_INLINE + +static void lpc_apply_welch_window_sse2(const int32_t *data, int len, + double *w_data) +{ + double c = 2.0 / (len-1.0); + int n2 = len>>1; + x86_reg i = -n2*sizeof(int32_t); + x86_reg j = n2*sizeof(int32_t); + __asm__ volatile( + "movsd %4, %%xmm7 \n\t" + "movapd "MANGLE(pd_1)", %%xmm6 \n\t" + "movapd "MANGLE(pd_2)", %%xmm5 \n\t" + "movlhps %%xmm7, %%xmm7 \n\t" + "subpd %%xmm5, %%xmm7 \n\t" + "addsd %%xmm6, %%xmm7 \n\t" + "test $1, %5 \n\t" + "jz 2f \n\t" +#define WELCH(MOVPD, offset)\ + "1: \n\t"\ + "movapd %%xmm7, %%xmm1 \n\t"\ + "mulpd %%xmm1, %%xmm1 \n\t"\ + "movapd %%xmm6, %%xmm0 \n\t"\ + "subpd %%xmm1, %%xmm0 \n\t"\ + "pshufd $0x4e, %%xmm0, %%xmm1 \n\t"\ + "cvtpi2pd (%3,%0), %%xmm2 \n\t"\ + "cvtpi2pd "#offset"*4(%3,%1), %%xmm3 \n\t"\ + "mulpd %%xmm0, %%xmm2 \n\t"\ + "mulpd %%xmm1, %%xmm3 \n\t"\ + "movapd %%xmm2, (%2,%0,2) \n\t"\ + MOVPD" %%xmm3, "#offset"*8(%2,%1,2) \n\t"\ + "subpd %%xmm5, %%xmm7 \n\t"\ + "sub $8, %1 \n\t"\ + "add $8, %0 \n\t"\ + "jl 1b \n\t"\ + + WELCH("movupd", -1) + "jmp 3f \n\t" + "2: \n\t" + WELCH("movapd", -2) + "3: \n\t" + :"+&r"(i), "+&r"(j) + :"r"(w_data+n2), "r"(data+n2), "m"(c), "r"(len) + NAMED_CONSTRAINTS_ARRAY_ADD(pd_1,pd_2) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm5", "%xmm6", "%xmm7") + ); +#undef WELCH +} + +static void lpc_compute_autocorr_sse2(const double *data, int len, int lag, + double *autoc) +{ + int j; + + if((x86_reg)data & 15) + data++; + + for(j=0; jlpc_apply_welch_window = lpc_apply_welch_window_sse2; + c->lpc_compute_autocorr = lpc_compute_autocorr_sse2; + } +#endif /* HAVE_SSE2_INLINE */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mathops.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mathops.h new file mode 100644 index 000000000..6298f5ed1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mathops.h @@ -0,0 +1,133 @@ +/* + * simple math operations + * Copyright (c) 2006 Michael Niedermayer et al + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_MATHOPS_H +#define AVCODEC_X86_MATHOPS_H + +#include "config.h" + +#include "libavutil/common.h" +#include "libavutil/x86/asm.h" + +#if HAVE_INLINE_ASM + +#if ARCH_X86_32 + +#define MULL MULL +static av_always_inline av_const int MULL(int a, int b, unsigned shift) +{ + int rt, dummy; + __asm__ ( + "imull %3 \n\t" + "shrdl %4, %%edx, %%eax \n\t" + :"=a"(rt), "=d"(dummy) + :"a"(a), "rm"(b), "ci"((uint8_t)shift) + ); + return rt; +} + +#define MULH MULH +static av_always_inline av_const int MULH(int a, int b) +{ + int rt, dummy; + __asm__ ( + "imull %3" + :"=d"(rt), "=a"(dummy) + :"a"(a), "rm"(b) + ); + return rt; +} + +#define MUL64 MUL64 +static av_always_inline av_const int64_t MUL64(int a, int b) +{ + int64_t rt; + __asm__ ( + "imull %2" + :"=A"(rt) + :"a"(a), "rm"(b) + ); + return rt; +} + +#endif /* ARCH_X86_32 */ + +#if HAVE_I686 +/* median of 3 */ +#define mid_pred mid_pred +static inline av_const int mid_pred(int a, int b, int c) +{ + int i=b; + __asm__ ( + "cmp %2, %1 \n\t" + "cmovg %1, %0 \n\t" + "cmovg %2, %1 \n\t" + "cmp %3, %1 \n\t" + "cmovl %3, %1 \n\t" + "cmp %1, %0 \n\t" + "cmovg %1, %0 \n\t" + :"+&r"(i), "+&r"(a) + :"r"(b), "r"(c) + ); + return i; +} + +#if HAVE_6REGS +#define COPY3_IF_LT(x, y, a, b, c, d)\ +__asm__ volatile(\ + "cmpl %0, %3 \n\t"\ + "cmovl %3, %0 \n\t"\ + "cmovl %4, %1 \n\t"\ + "cmovl %5, %2 \n\t"\ + : "+&r" (x), "+&r" (a), "+r" (c)\ + : "r" (y), "r" (b), "r" (d)\ +); +#endif /* HAVE_6REGS */ + +#endif /* HAVE_I686 */ + +#define MASK_ABS(mask, level) \ + __asm__ ("cdq \n\t" \ + "xorl %1, %0 \n\t" \ + "subl %1, %0 \n\t" \ + : "+a"(level), "=&d"(mask)) + +// avoid +32 for shift optimization (gcc should do that ...) +#define NEG_SSR32 NEG_SSR32 +static inline int32_t NEG_SSR32( int32_t a, int8_t s){ + __asm__ ("sarl %1, %0\n\t" + : "+r" (a) + : "ic" ((uint8_t)(-s)) + ); + return a; +} + +#define NEG_USR32 NEG_USR32 +static inline uint32_t NEG_USR32(uint32_t a, int8_t s){ + __asm__ ("shrl %1, %0\n\t" + : "+r" (a) + : "ic" ((uint8_t)(-s)) + ); + return a; +} + +#endif /* HAVE_INLINE_ASM */ +#endif /* AVCODEC_X86_MATHOPS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mdct15_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mdct15_init.c new file mode 100644 index 000000000..444801d9c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mdct15_init.c @@ -0,0 +1,99 @@ +/* + * SIMD optimized non-power-of-two MDCT functions + * + * Copyright (C) 2017 Rostislav Pehlivanov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/x86/cpu.h" +#include "libavcodec/mdct15.h" + +void ff_mdct15_postreindex_sse3(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); +void ff_mdct15_postreindex_avx2(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); + +void ff_fft15_avx(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); + +static void perm_twiddles(MDCT15Context *s) +{ + int k; + FFTComplex tmp[30]; + + /* 5-point FFT twiddles */ + s->exptab[60].re = s->exptab[60].im = s->exptab[19].re; + s->exptab[61].re = s->exptab[61].im = s->exptab[19].im; + s->exptab[62].re = s->exptab[62].im = s->exptab[20].re; + s->exptab[63].re = s->exptab[63].im = s->exptab[20].im; + + /* 15-point FFT twiddles */ + for (k = 0; k < 5; k++) { + tmp[6*k + 0] = s->exptab[k + 0]; + tmp[6*k + 2] = s->exptab[k + 5]; + tmp[6*k + 4] = s->exptab[k + 10]; + + tmp[6*k + 1] = s->exptab[2 * (k + 0)]; + tmp[6*k + 3] = s->exptab[2 * (k + 5)]; + tmp[6*k + 5] = s->exptab[2 * k + 5 ]; + } + + for (k = 0; k < 6; k++) { + FFTComplex ac_exp[] = { + { tmp[6*1 + k].re, tmp[6*1 + k].re }, + { tmp[6*2 + k].re, tmp[6*2 + k].re }, + { tmp[6*3 + k].re, tmp[6*3 + k].re }, + { tmp[6*4 + k].re, tmp[6*4 + k].re }, + { tmp[6*1 + k].im, -tmp[6*1 + k].im }, + { tmp[6*2 + k].im, -tmp[6*2 + k].im }, + { tmp[6*3 + k].im, -tmp[6*3 + k].im }, + { tmp[6*4 + k].im, -tmp[6*4 + k].im }, + }; + memcpy(s->exptab + 8*k, ac_exp, 8*sizeof(FFTComplex)); + } + + /* Specialcase when k = 0 */ + for (k = 0; k < 3; k++) { + FFTComplex dc_exp[] = { + { tmp[2*k + 0].re, -tmp[2*k + 0].im }, + { tmp[2*k + 0].im, tmp[2*k + 0].re }, + { tmp[2*k + 1].re, -tmp[2*k + 1].im }, + { tmp[2*k + 1].im, tmp[2*k + 1].re }, + }; + memcpy(s->exptab + 8*6 + 4*k, dc_exp, 4*sizeof(FFTComplex)); + } +} + +av_cold void ff_mdct15_init_x86(MDCT15Context *s) +{ + int adjust_twiddles = 0; + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE3(cpu_flags)) + s->postreindex = ff_mdct15_postreindex_sse3; + + if (ARCH_X86_64 && EXTERNAL_AVX(cpu_flags)) { + s->fft15 = ff_fft15_avx; + adjust_twiddles = 1; + } + + if (ARCH_X86_64 && EXTERNAL_AVX2_FAST(cpu_flags)) + s->postreindex = ff_mdct15_postreindex_avx2; + + if (adjust_twiddles) + perm_twiddles(s); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/me_cmp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/me_cmp_init.c new file mode 100644 index 000000000..6aec93e55 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/me_cmp_init.c @@ -0,0 +1,651 @@ +/* + * SIMD-optimized motion estimation + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/me_cmp.h" +#include "libavcodec/mpegvideo.h" + +int ff_sum_abs_dctelem_mmx(int16_t *block); +int ff_sum_abs_dctelem_mmxext(int16_t *block); +int ff_sum_abs_dctelem_sse2(int16_t *block); +int ff_sum_abs_dctelem_ssse3(int16_t *block); +int ff_sse8_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sse16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sse16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_hf_noise8_mmx(uint8_t *pix1, ptrdiff_t stride, int h); +int ff_hf_noise16_mmx(uint8_t *pix1, ptrdiff_t stride, int h); +int ff_sad8_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad8_x2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_x2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_x2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad8_y2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_y2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_y2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad8_approx_xy2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_approx_xy2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_approx_xy2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad_intra8_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad_intra16_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad_intra16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad8_approx_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad16_approx_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad16_approx_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); + +#define hadamard_func(cpu) \ + int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, uint8_t *src1, \ + uint8_t *src2, ptrdiff_t stride, int h); \ + int ff_hadamard8_diff16_ ## cpu(MpegEncContext *s, uint8_t *src1, \ + uint8_t *src2, ptrdiff_t stride, int h); + +hadamard_func(mmx) +hadamard_func(mmxext) +hadamard_func(sse2) +hadamard_func(ssse3) + +#if HAVE_X86ASM +static int nsse16_mmx(MpegEncContext *c, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int score1, score2; + + if (c) + score1 = c->mecc.sse[0](c, pix1, pix2, stride, h); + else + score1 = ff_sse16_mmx(c, pix1, pix2, stride, h); + score2 = ff_hf_noise16_mmx(pix1, stride, h) + ff_hf_noise8_mmx(pix1+8, stride, h) + - ff_hf_noise16_mmx(pix2, stride, h) - ff_hf_noise8_mmx(pix2+8, stride, h); + + if (c) + return score1 + FFABS(score2) * c->avctx->nsse_weight; + else + return score1 + FFABS(score2) * 8; +} + +static int nsse8_mmx(MpegEncContext *c, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int score1 = ff_sse8_mmx(c, pix1, pix2, stride, h); + int score2 = ff_hf_noise8_mmx(pix1, stride, h) - + ff_hf_noise8_mmx(pix2, stride, h); + + if (c) + return score1 + FFABS(score2) * c->avctx->nsse_weight; + else + return score1 + FFABS(score2) * 8; +} + +#endif /* HAVE_X86ASM */ + +#if HAVE_INLINE_ASM + +static int vsad_intra16_mmx(MpegEncContext *v, uint8_t *pix, uint8_t *dummy, + ptrdiff_t stride, int h) +{ + int tmp; + + av_assert2((((int) pix) & 7) == 0); + av_assert2((stride & 7) == 0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0), %%mm2\n" \ + "movq 8(%0), %%mm3\n" \ + "add %2,%0\n" \ + "movq %%mm2, " #out0 "\n" \ + "movq %%mm3, " #out1 "\n" \ + "psubusb " #in0 ", %%mm2\n" \ + "psubusb " #in1 ", %%mm3\n" \ + "psubusb " #out0 ", " #in0 "\n" \ + "psubusb " #out1 ", " #in1 "\n" \ + "por %%mm2, " #in0 "\n" \ + "por %%mm3, " #in1 "\n" \ + "movq " #in0 ", %%mm2\n" \ + "movq " #in1 ", %%mm3\n" \ + "punpcklbw %%mm7, " #in0 "\n" \ + "punpcklbw %%mm7, " #in1 "\n" \ + "punpckhbw %%mm7, %%mm2\n" \ + "punpckhbw %%mm7, %%mm3\n" \ + "paddw " #in1 ", " #in0 "\n" \ + "paddw %%mm3, %%mm2\n" \ + "paddw %%mm2, " #in0 "\n" \ + "paddw " #in0 ", %%mm6\n" + + + __asm__ volatile ( + "movl %3, %%ecx\n" + "pxor %%mm6, %%mm6\n" + "pxor %%mm7, %%mm7\n" + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "add %2, %0\n" + "jmp 2f\n" + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + "2:\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movq %%mm6, %%mm0\n" + "psrlq $32, %%mm6\n" + "paddw %%mm6, %%mm0\n" + "movq %%mm0, %%mm6\n" + "psrlq $16, %%mm0\n" + "paddw %%mm6, %%mm0\n" + "movd %%mm0, %1\n" + : "+r" (pix), "=r" (tmp) + : "r" (stride), "m" (h) + : "%ecx"); + + return tmp & 0xFFFF; +} +#undef SUM + +static int vsad16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int tmp; + + av_assert2((((int) pix1) & 7) == 0); + av_assert2((((int) pix2) & 7) == 0); + av_assert2((stride & 7) == 0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0), %%mm2\n" \ + "movq (%1), " #out0 "\n" \ + "movq 8(%0), %%mm3\n" \ + "movq 8(%1), " #out1 "\n" \ + "add %3, %0\n" \ + "add %3, %1\n" \ + "psubb " #out0 ", %%mm2\n" \ + "psubb " #out1 ", %%mm3\n" \ + "pxor %%mm7, %%mm2\n" \ + "pxor %%mm7, %%mm3\n" \ + "movq %%mm2, " #out0 "\n" \ + "movq %%mm3, " #out1 "\n" \ + "psubusb " #in0 ", %%mm2\n" \ + "psubusb " #in1 ", %%mm3\n" \ + "psubusb " #out0 ", " #in0 "\n" \ + "psubusb " #out1 ", " #in1 "\n" \ + "por %%mm2, " #in0 "\n" \ + "por %%mm3, " #in1 "\n" \ + "movq " #in0 ", %%mm2\n" \ + "movq " #in1 ", %%mm3\n" \ + "punpcklbw %%mm7, " #in0 "\n" \ + "punpcklbw %%mm7, " #in1 "\n" \ + "punpckhbw %%mm7, %%mm2\n" \ + "punpckhbw %%mm7, %%mm3\n" \ + "paddw " #in1 ", " #in0 "\n" \ + "paddw %%mm3, %%mm2\n" \ + "paddw %%mm2, " #in0 "\n" \ + "paddw " #in0 ", %%mm6\n" + + + __asm__ volatile ( + "movl %4, %%ecx\n" + "pxor %%mm6, %%mm6\n" + "pcmpeqw %%mm7, %%mm7\n" + "psllw $15, %%mm7\n" + "packsswb %%mm7, %%mm7\n" + "movq (%0), %%mm0\n" + "movq (%1), %%mm2\n" + "movq 8(%0), %%mm1\n" + "movq 8(%1), %%mm3\n" + "add %3, %0\n" + "add %3, %1\n" + "psubb %%mm2, %%mm0\n" + "psubb %%mm3, %%mm1\n" + "pxor %%mm7, %%mm0\n" + "pxor %%mm7, %%mm1\n" + "jmp 2f\n" + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + "2:\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movq %%mm6, %%mm0\n" + "psrlq $32, %%mm6\n" + "paddw %%mm6, %%mm0\n" + "movq %%mm0, %%mm6\n" + "psrlq $16, %%mm0\n" + "paddw %%mm6, %%mm0\n" + "movd %%mm0, %2\n" + : "+r" (pix1), "+r" (pix2), "=r" (tmp) + : "r" (stride), "m" (h) + : "%ecx"); + + return tmp & 0x7FFF; +} +#undef SUM + +DECLARE_ASM_CONST(8, uint64_t, round_tab)[3] = { + 0x0000000000000000ULL, + 0x0001000100010001ULL, + 0x0002000200020002ULL, +}; + +static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + x86_reg len = -stride * h; + __asm__ volatile ( + ".p2align 4 \n\t" + "1: \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm2 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm4 \n\t" + "add %3, %%"FF_REG_a" \n\t" + "psubusb %%mm0, %%mm2 \n\t" + "psubusb %%mm4, %%mm0 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm1 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm5 \n\t" + "psubusb %%mm1, %%mm3 \n\t" + "psubusb %%mm5, %%mm1 \n\t" + "por %%mm2, %%mm0 \n\t" + "por %%mm1, %%mm3 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm3, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm2 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm3, %%mm2 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %3, %%"FF_REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1 - len), "r" (blk2 - len), "r" (stride)); +} + +static inline void sad8_2_mmx(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + x86_reg len = -stride * h; + __asm__ volatile ( + ".p2align 4 \n\t" + "1: \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddw %%mm0, %%mm1 \n\t" + "paddw %%mm2, %%mm3 \n\t" + "movq (%3, %%"FF_REG_a"), %%mm4 \n\t" + "movq (%3, %%"FF_REG_a"), %%mm2 \n\t" + "paddw %%mm5, %%mm1 \n\t" + "paddw %%mm5, %%mm3 \n\t" + "psrlw $1, %%mm1 \n\t" + "psrlw $1, %%mm3 \n\t" + "packuswb %%mm3, %%mm1 \n\t" + "psubusb %%mm1, %%mm4 \n\t" + "psubusb %%mm2, %%mm1 \n\t" + "por %%mm4, %%mm1 \n\t" + "movq %%mm1, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %4, %%"FF_REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1a - len), "r" (blk1b - len), "r" (blk2 - len), + "r" (stride)); +} + +static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + x86_reg len = -stride * h; + __asm__ volatile ( + "movq (%1, %%"FF_REG_a"), %%mm0\n\t" + "movq 1(%1, %%"FF_REG_a"), %%mm2\n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm3, %%mm1 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%2, %%"FF_REG_a"), %%mm2\n\t" + "movq 1(%2, %%"FF_REG_a"), %%mm4\n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddw %%mm4, %%mm2 \n\t" + "paddw %%mm5, %%mm3 \n\t" + "movq %5, %%mm5 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm3, %%mm1 \n\t" + "paddw %%mm5, %%mm0 \n\t" + "paddw %%mm5, %%mm1 \n\t" + "movq (%3, %%"FF_REG_a"), %%mm4 \n\t" + "movq (%3, %%"FF_REG_a"), %%mm5 \n\t" + "psrlw $2, %%mm0 \n\t" + "psrlw $2, %%mm1 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "psubusb %%mm0, %%mm4 \n\t" + "psubusb %%mm5, %%mm0 \n\t" + "por %%mm4, %%mm0 \n\t" + "movq %%mm0, %%mm4 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm4 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "paddw %%mm4, %%mm6 \n\t" + "movq %%mm2, %%mm0 \n\t" + "movq %%mm3, %%mm1 \n\t" + "add %4, %%"FF_REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1 - len), "r" (blk1 - len + stride), "r" (blk2 - len), + "r" (stride), "m" (round_tab[2])); +} + +static inline int sum_mmx(void) +{ + int ret; + __asm__ volatile ( + "movq %%mm6, %%mm0 \n\t" + "psrlq $32, %%mm6 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "movq %%mm6, %%mm0 \n\t" + "psrlq $16, %%mm6 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "movd %%mm6, %0 \n\t" + : "=r" (ret)); + return ret & 0xFFFF; +} + +static inline void sad8_x2a_mmx(uint8_t *blk1, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + sad8_2_mmx(blk1, blk1 + 1, blk2, stride, h); +} + +static inline void sad8_y2a_mmx(uint8_t *blk1, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + sad8_2_mmx(blk1, blk1 + stride, blk2, stride, h); +} + +#define PIX_SAD(suf) \ +static int sad8_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + av_assert2(h == 8); \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + :); \ + \ + sad8_1_ ## suf(blk1, blk2, stride, 8); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad8_x2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + av_assert2(h == 8); \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + "movq %0, %%mm5 \n\t" \ + :: "m" (round_tab[1])); \ + \ + sad8_x2a_ ## suf(blk1, blk2, stride, 8); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad8_y2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + av_assert2(h == 8); \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + "movq %0, %%mm5 \n\t" \ + :: "m" (round_tab[1])); \ + \ + sad8_y2a_ ## suf(blk1, blk2, stride, 8); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad8_xy2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + av_assert2(h == 8); \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + ::); \ + \ + sad8_4_ ## suf(blk1, blk2, stride, 8); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad16_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + :); \ + \ + sad8_1_ ## suf(blk1, blk2, stride, h); \ + sad8_1_ ## suf(blk1 + 8, blk2 + 8, stride, h); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad16_x2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + "movq %0, %%mm5 \n\t" \ + :: "m" (round_tab[1])); \ + \ + sad8_x2a_ ## suf(blk1, blk2, stride, h); \ + sad8_x2a_ ## suf(blk1 + 8, blk2 + 8, stride, h); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad16_y2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + "movq %0, %%mm5 \n\t" \ + :: "m" (round_tab[1])); \ + \ + sad8_y2a_ ## suf(blk1, blk2, stride, h); \ + sad8_y2a_ ## suf(blk1 + 8, blk2 + 8, stride, h); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad16_xy2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + ::); \ + \ + sad8_4_ ## suf(blk1, blk2, stride, h); \ + sad8_4_ ## suf(blk1 + 8, blk2 + 8, stride, h); \ + \ + return sum_ ## suf(); \ +} \ + +PIX_SAD(mmx) + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx) +{ + int cpu_flags = av_get_cpu_flags(); + +#if HAVE_INLINE_ASM + if (INLINE_MMX(cpu_flags)) { + c->pix_abs[0][0] = sad16_mmx; + c->pix_abs[0][1] = sad16_x2_mmx; + c->pix_abs[0][2] = sad16_y2_mmx; + c->pix_abs[0][3] = sad16_xy2_mmx; + c->pix_abs[1][0] = sad8_mmx; + c->pix_abs[1][1] = sad8_x2_mmx; + c->pix_abs[1][2] = sad8_y2_mmx; + c->pix_abs[1][3] = sad8_xy2_mmx; + + c->sad[0] = sad16_mmx; + c->sad[1] = sad8_mmx; + + c->vsad[4] = vsad_intra16_mmx; + + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->vsad[0] = vsad16_mmx; + } + } + +#endif /* HAVE_INLINE_ASM */ + + if (EXTERNAL_MMX(cpu_flags)) { + c->hadamard8_diff[0] = ff_hadamard8_diff16_mmx; + c->hadamard8_diff[1] = ff_hadamard8_diff_mmx; + c->sum_abs_dctelem = ff_sum_abs_dctelem_mmx; + c->sse[0] = ff_sse16_mmx; + c->sse[1] = ff_sse8_mmx; +#if HAVE_X86ASM + c->nsse[0] = nsse16_mmx; + c->nsse[1] = nsse8_mmx; +#endif + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->hadamard8_diff[0] = ff_hadamard8_diff16_mmxext; + c->hadamard8_diff[1] = ff_hadamard8_diff_mmxext; + c->sum_abs_dctelem = ff_sum_abs_dctelem_mmxext; + + c->sad[0] = ff_sad16_mmxext; + c->sad[1] = ff_sad8_mmxext; + + c->pix_abs[0][0] = ff_sad16_mmxext; + c->pix_abs[0][1] = ff_sad16_x2_mmxext; + c->pix_abs[0][2] = ff_sad16_y2_mmxext; + c->pix_abs[1][0] = ff_sad8_mmxext; + c->pix_abs[1][1] = ff_sad8_x2_mmxext; + c->pix_abs[1][2] = ff_sad8_y2_mmxext; + + c->vsad[4] = ff_vsad_intra16_mmxext; + c->vsad[5] = ff_vsad_intra8_mmxext; + + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->pix_abs[0][3] = ff_sad16_approx_xy2_mmxext; + c->pix_abs[1][3] = ff_sad8_approx_xy2_mmxext; + + c->vsad[0] = ff_vsad16_approx_mmxext; + c->vsad[1] = ff_vsad8_approx_mmxext; + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->sse[0] = ff_sse16_sse2; + c->sum_abs_dctelem = ff_sum_abs_dctelem_sse2; + +#if HAVE_ALIGNED_STACK + c->hadamard8_diff[0] = ff_hadamard8_diff16_sse2; + c->hadamard8_diff[1] = ff_hadamard8_diff_sse2; +#endif + if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW) && avctx->codec_id != AV_CODEC_ID_SNOW) { + c->sad[0] = ff_sad16_sse2; + c->pix_abs[0][0] = ff_sad16_sse2; + c->pix_abs[0][1] = ff_sad16_x2_sse2; + c->pix_abs[0][2] = ff_sad16_y2_sse2; + + c->vsad[4] = ff_vsad_intra16_sse2; + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->pix_abs[0][3] = ff_sad16_approx_xy2_sse2; + c->vsad[0] = ff_vsad16_approx_sse2; + } + } + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + c->sum_abs_dctelem = ff_sum_abs_dctelem_ssse3; +#if HAVE_ALIGNED_STACK + c->hadamard8_diff[0] = ff_hadamard8_diff16_ssse3; + c->hadamard8_diff[1] = ff_hadamard8_diff_ssse3; +#endif + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mlpdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mlpdsp_init.c new file mode 100644 index 000000000..cb90ca24f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mlpdsp_init.c @@ -0,0 +1,204 @@ +/* + * MLP DSP functions x86-optimized + * Copyright (c) 2009 Ramiro Polla + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/mlpdsp.h" +#include "libavcodec/mlp.h" + +#define REMATRIX_CHANNEL_FUNC(opt) \ +void ff_mlp_rematrix_channel_##opt(int32_t *samples, \ + const int32_t *coeffs, \ + const uint8_t *bypassed_lsbs, \ + const int8_t *noise_buffer, \ + int index, \ + unsigned int dest_ch, \ + uint16_t blockpos, \ + unsigned int maxchan, \ + int matrix_noise_shift, \ + int access_unit_size_pow2, \ + int32_t mask); + +REMATRIX_CHANNEL_FUNC(sse4) +REMATRIX_CHANNEL_FUNC(avx2_bmi2) + +#if HAVE_7REGS && HAVE_INLINE_ASM && HAVE_INLINE_ASM_NONLOCAL_LABELS + +extern char ff_mlp_firorder_8; +extern char ff_mlp_firorder_7; +extern char ff_mlp_firorder_6; +extern char ff_mlp_firorder_5; +extern char ff_mlp_firorder_4; +extern char ff_mlp_firorder_3; +extern char ff_mlp_firorder_2; +extern char ff_mlp_firorder_1; +extern char ff_mlp_firorder_0; + +extern char ff_mlp_iirorder_4; +extern char ff_mlp_iirorder_3; +extern char ff_mlp_iirorder_2; +extern char ff_mlp_iirorder_1; +extern char ff_mlp_iirorder_0; + +static const void * const firtable[9] = { &ff_mlp_firorder_0, &ff_mlp_firorder_1, + &ff_mlp_firorder_2, &ff_mlp_firorder_3, + &ff_mlp_firorder_4, &ff_mlp_firorder_5, + &ff_mlp_firorder_6, &ff_mlp_firorder_7, + &ff_mlp_firorder_8 }; +static const void * const iirtable[5] = { &ff_mlp_iirorder_0, &ff_mlp_iirorder_1, + &ff_mlp_iirorder_2, &ff_mlp_iirorder_3, + &ff_mlp_iirorder_4 }; + +#if ARCH_X86_64 + +#define MLPMUL(label, offset, offs, offc) \ + LABEL_MANGLE(label)": \n\t" \ + "movslq "offset"+"offs"(%0), %%rax\n\t" \ + "movslq "offset"+"offc"(%1), %%rdx\n\t" \ + "imul %%rdx, %%rax\n\t" \ + "add %%rax, %%rsi\n\t" + +#define FIRMULREG(label, offset, firc)\ + LABEL_MANGLE(label)": \n\t" \ + "movslq "#offset"(%0), %%rax\n\t" \ + "imul %"#firc", %%rax\n\t" \ + "add %%rax, %%rsi\n\t" + +#define CLEAR_ACCUM \ + "xor %%rsi, %%rsi\n\t" + +#define SHIFT_ACCUM \ + "shr %%cl, %%rsi\n\t" + +#define ACCUM "%%rdx" +#define RESULT "%%rsi" +#define RESULT32 "%%esi" + +#else /* if ARCH_X86_32 */ + +#define MLPMUL(label, offset, offs, offc) \ + LABEL_MANGLE(label)": \n\t" \ + "mov "offset"+"offs"(%0), %%eax\n\t" \ + "imull "offset"+"offc"(%1) \n\t" \ + "add %%eax , %%esi\n\t" \ + "adc %%edx , %%ecx\n\t" + +#define FIRMULREG(label, offset, firc) \ + MLPMUL(label, #offset, "0", "0") + +#define CLEAR_ACCUM \ + "xor %%esi, %%esi\n\t" \ + "xor %%ecx, %%ecx\n\t" + +#define SHIFT_ACCUM \ + "mov %%ecx, %%edx\n\t" \ + "mov %%esi, %%eax\n\t" \ + "movzbl %7 , %%ecx\n\t" \ + "shrd %%cl, %%edx, %%eax\n\t" \ + +#define ACCUM "%%edx" +#define RESULT "%%eax" +#define RESULT32 "%%eax" + +#endif /* !ARCH_X86_64 */ + +#define BINC AV_STRINGIFY(4* MAX_CHANNELS) +#define IOFFS AV_STRINGIFY(4*(MAX_FIR_ORDER + MAX_BLOCKSIZE)) +#define IOFFC AV_STRINGIFY(4* MAX_FIR_ORDER) + +#define FIRMUL(label, offset) MLPMUL(label, #offset, "0", "0") +#define IIRMUL(label, offset) MLPMUL(label, #offset, IOFFS, IOFFC) + +static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff, + int firorder, int iirorder, + unsigned int filter_shift, int32_t mask, + int blocksize, int32_t *sample_buffer) +{ + const void *firjump = firtable[firorder]; + const void *iirjump = iirtable[iirorder]; + + blocksize = -blocksize; + + __asm__ volatile( + "1: \n\t" + CLEAR_ACCUM + "jmp *%5 \n\t" + FIRMUL (ff_mlp_firorder_8, 0x1c ) + FIRMUL (ff_mlp_firorder_7, 0x18 ) + FIRMUL (ff_mlp_firorder_6, 0x14 ) + FIRMUL (ff_mlp_firorder_5, 0x10 ) + FIRMUL (ff_mlp_firorder_4, 0x0c ) + FIRMUL (ff_mlp_firorder_3, 0x08 ) + FIRMUL (ff_mlp_firorder_2, 0x04 ) + FIRMULREG(ff_mlp_firorder_1, 0x00, 8) + LABEL_MANGLE(ff_mlp_firorder_0)":\n\t" + "jmp *%6 \n\t" + IIRMUL (ff_mlp_iirorder_4, 0x0c ) + IIRMUL (ff_mlp_iirorder_3, 0x08 ) + IIRMUL (ff_mlp_iirorder_2, 0x04 ) + IIRMUL (ff_mlp_iirorder_1, 0x00 ) + LABEL_MANGLE(ff_mlp_iirorder_0)":\n\t" + SHIFT_ACCUM + "mov "RESULT" ,"ACCUM" \n\t" + "add (%2) ,"RESULT" \n\t" + "and %4 ,"RESULT" \n\t" + "sub $4 , %0 \n\t" + "mov "RESULT32", (%0) \n\t" + "mov "RESULT32", (%2) \n\t" + "add $"BINC" , %2 \n\t" + "sub "ACCUM" ,"RESULT" \n\t" + "mov "RESULT32","IOFFS"(%0) \n\t" + "incl %3 \n\t" + "js 1b \n\t" + : /* 0*/"+r"(state), + /* 1*/"+r"(coeff), + /* 2*/"+r"(sample_buffer), +#if ARCH_X86_64 + /* 3*/"+r"(blocksize) + : /* 4*/"r"((x86_reg)mask), /* 5*/"r"(firjump), + /* 6*/"r"(iirjump) , /* 7*/"c"(filter_shift) + , /* 8*/"r"((int64_t)coeff[0]) + : "rax", "rdx", "rsi" +#else /* ARCH_X86_32 */ + /* 3*/"+m"(blocksize) + : /* 4*/"m"( mask), /* 5*/"m"(firjump), + /* 6*/"m"(iirjump) , /* 7*/"m"(filter_shift) + : "eax", "edx", "esi", "ecx" +#endif /* !ARCH_X86_64 */ + ); +} + +#endif /* HAVE_7REGS && HAVE_INLINE_ASM */ + +av_cold void ff_mlpdsp_init_x86(MLPDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); +#if HAVE_7REGS && HAVE_INLINE_ASM && HAVE_INLINE_ASM_NONLOCAL_LABELS + if (INLINE_MMX(cpu_flags)) + c->mlp_filter_channel = mlp_filter_channel_x86; +#endif + if (ARCH_X86_64 && EXTERNAL_SSE4(cpu_flags)) + c->mlp_rematrix_channel = ff_mlp_rematrix_channel_sse4; + if (ARCH_X86_64 && EXTERNAL_AVX2_FAST(cpu_flags) && cpu_flags & AV_CPU_FLAG_BMI2) + c->mlp_rematrix_channel = ff_mlp_rematrix_channel_avx2_bmi2; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegaudiodsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegaudiodsp.c new file mode 100644 index 000000000..f46a5c4f3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegaudiodsp.c @@ -0,0 +1,289 @@ +/* + * SIMD-optimized MP3 decoding functions + * Copyright (c) 2010 Vitor Sessak + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/internal.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/mpegaudiodsp.h" + +#define DECL(CPU)\ +static void imdct36_blocks_ ## CPU(float *out, float *buf, float *in, int count, int switch_point, int block_type);\ +void ff_imdct36_float_ ## CPU(float *out, float *buf, float *in, float *win); + +#if HAVE_X86ASM +#if ARCH_X86_32 +DECL(sse) +#endif +DECL(sse2) +DECL(sse3) +DECL(ssse3) +DECL(avx) +#endif /* HAVE_X86ASM */ + +void ff_four_imdct36_float_sse(float *out, float *buf, float *in, float *win, + float *tmpbuf); +void ff_four_imdct36_float_avx(float *out, float *buf, float *in, float *win, + float *tmpbuf); + +DECLARE_ALIGNED(16, static float, mdct_win_sse)[2][4][4*40]; + +#if HAVE_6REGS && HAVE_SSE_INLINE + +#define MACS(rt, ra, rb) rt+=(ra)*(rb) +#define MLSS(rt, ra, rb) rt-=(ra)*(rb) + +#define SUM8(op, sum, w, p) \ +{ \ + op(sum, (w)[0 * 64], (p)[0 * 64]); \ + op(sum, (w)[1 * 64], (p)[1 * 64]); \ + op(sum, (w)[2 * 64], (p)[2 * 64]); \ + op(sum, (w)[3 * 64], (p)[3 * 64]); \ + op(sum, (w)[4 * 64], (p)[4 * 64]); \ + op(sum, (w)[5 * 64], (p)[5 * 64]); \ + op(sum, (w)[6 * 64], (p)[6 * 64]); \ + op(sum, (w)[7 * 64], (p)[7 * 64]); \ +} + +static void apply_window(const float *buf, const float *win1, + const float *win2, float *sum1, float *sum2, int len) +{ + x86_reg count = - 4*len; + const float *win1a = win1+len; + const float *win2a = win2+len; + const float *bufa = buf+len; + float *sum1a = sum1+len; + float *sum2a = sum2+len; + + +#define MULT(a, b) \ + "movaps " #a "(%1,%0), %%xmm1 \n\t" \ + "movaps " #a "(%3,%0), %%xmm2 \n\t" \ + "mulps %%xmm2, %%xmm1 \n\t" \ + "subps %%xmm1, %%xmm0 \n\t" \ + "mulps " #b "(%2,%0), %%xmm2 \n\t" \ + "subps %%xmm2, %%xmm4 \n\t" \ + + __asm__ volatile( + "1: \n\t" + "xorps %%xmm0, %%xmm0 \n\t" + "xorps %%xmm4, %%xmm4 \n\t" + + MULT( 0, 0) + MULT( 256, 64) + MULT( 512, 128) + MULT( 768, 192) + MULT(1024, 256) + MULT(1280, 320) + MULT(1536, 384) + MULT(1792, 448) + + "movaps %%xmm0, (%4,%0) \n\t" + "movaps %%xmm4, (%5,%0) \n\t" + "add $16, %0 \n\t" + "jl 1b \n\t" + :"+&r"(count) + :"r"(win1a), "r"(win2a), "r"(bufa), "r"(sum1a), "r"(sum2a) + ); + +#undef MULT +} + +static void apply_window_mp3(float *in, float *win, int *unused, float *out, + ptrdiff_t incr) +{ + LOCAL_ALIGNED_16(float, suma, [17]); + LOCAL_ALIGNED_16(float, sumb, [17]); + LOCAL_ALIGNED_16(float, sumc, [17]); + LOCAL_ALIGNED_16(float, sumd, [17]); + + float sum; + + /* copy to avoid wrap */ + __asm__ volatile( + "movaps 0(%0), %%xmm0 \n\t" \ + "movaps 16(%0), %%xmm1 \n\t" \ + "movaps 32(%0), %%xmm2 \n\t" \ + "movaps 48(%0), %%xmm3 \n\t" \ + "movaps %%xmm0, 0(%1) \n\t" \ + "movaps %%xmm1, 16(%1) \n\t" \ + "movaps %%xmm2, 32(%1) \n\t" \ + "movaps %%xmm3, 48(%1) \n\t" \ + "movaps 64(%0), %%xmm0 \n\t" \ + "movaps 80(%0), %%xmm1 \n\t" \ + "movaps 96(%0), %%xmm2 \n\t" \ + "movaps 112(%0), %%xmm3 \n\t" \ + "movaps %%xmm0, 64(%1) \n\t" \ + "movaps %%xmm1, 80(%1) \n\t" \ + "movaps %%xmm2, 96(%1) \n\t" \ + "movaps %%xmm3, 112(%1) \n\t" + ::"r"(in), "r"(in+512) + :"memory" + ); + + apply_window(in + 16, win , win + 512, suma, sumc, 16); + apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16); + + SUM8(MACS, suma[0], win + 32, in + 48); + + sumc[ 0] = 0; + sumb[16] = 0; + sumd[16] = 0; + +#define SUMS(suma, sumb, sumc, sumd, out1, out2) \ + "movups " #sumd "(%4), %%xmm0 \n\t" \ + "shufps $0x1b, %%xmm0, %%xmm0 \n\t" \ + "subps " #suma "(%1), %%xmm0 \n\t" \ + "movaps %%xmm0," #out1 "(%0) \n\t" \ +\ + "movups " #sumc "(%3), %%xmm0 \n\t" \ + "shufps $0x1b, %%xmm0, %%xmm0 \n\t" \ + "addps " #sumb "(%2), %%xmm0 \n\t" \ + "movaps %%xmm0," #out2 "(%0) \n\t" + + if (incr == 1) { + __asm__ volatile( + SUMS( 0, 48, 4, 52, 0, 112) + SUMS(16, 32, 20, 36, 16, 96) + SUMS(32, 16, 36, 20, 32, 80) + SUMS(48, 0, 52, 4, 48, 64) + + :"+&r"(out) + :"r"(&suma[0]), "r"(&sumb[0]), "r"(&sumc[0]), "r"(&sumd[0]) + :"memory" + ); + out += 16*incr; + } else { + int j; + float *out2 = out + 32 * incr; + out[0 ] = -suma[ 0]; + out += incr; + out2 -= incr; + for(j=1;j<16;j++) { + *out = -suma[ j] + sumd[16-j]; + *out2 = sumb[16-j] + sumc[ j]; + out += incr; + out2 -= incr; + } + } + + sum = 0; + SUM8(MLSS, sum, win + 16 + 32, in + 32); + *out = sum; +} + +#endif /* HAVE_6REGS && HAVE_SSE_INLINE */ + +#if HAVE_X86ASM +#define DECL_IMDCT_BLOCKS(CPU1, CPU2) \ +static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in, \ + int count, int switch_point, int block_type) \ +{ \ + int align_end = count - (count & 3); \ + int j; \ + for (j = 0; j < align_end; j+= 4) { \ + LOCAL_ALIGNED_16(float, tmpbuf, [1024]); \ + float *win = mdct_win_sse[switch_point && j < 4][block_type]; \ + /* apply window & overlap with previous buffer */ \ + \ + /* select window */ \ + ff_four_imdct36_float_ ## CPU2(out, buf, in, win, tmpbuf); \ + in += 4*18; \ + buf += 4*18; \ + out += 4; \ + } \ + for (; j < count; j++) { \ + /* apply window & overlap with previous buffer */ \ + \ + /* select window */ \ + int win_idx = (switch_point && j < 2) ? 0 : block_type; \ + float *win = ff_mdct_win_float[win_idx + (4 & -(j & 1))]; \ + \ + ff_imdct36_float_ ## CPU1(out, buf, in, win); \ + \ + in += 18; \ + buf++; \ + out++; \ + } \ +} + +#if HAVE_SSE +#if ARCH_X86_32 +DECL_IMDCT_BLOCKS(sse,sse) +#endif +DECL_IMDCT_BLOCKS(sse2,sse) +DECL_IMDCT_BLOCKS(sse3,sse) +DECL_IMDCT_BLOCKS(ssse3,sse) +#endif +#if HAVE_AVX_EXTERNAL +DECL_IMDCT_BLOCKS(avx,avx) +#endif +#endif /* HAVE_X86ASM */ + +av_cold void ff_mpadsp_init_x86(MPADSPContext *s) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + + int i, j; + for (j = 0; j < 4; j++) { + for (i = 0; i < 40; i ++) { + mdct_win_sse[0][j][4*i ] = ff_mdct_win_float[j ][i]; + mdct_win_sse[0][j][4*i + 1] = ff_mdct_win_float[j + 4][i]; + mdct_win_sse[0][j][4*i + 2] = ff_mdct_win_float[j ][i]; + mdct_win_sse[0][j][4*i + 3] = ff_mdct_win_float[j + 4][i]; + mdct_win_sse[1][j][4*i ] = ff_mdct_win_float[0 ][i]; + mdct_win_sse[1][j][4*i + 1] = ff_mdct_win_float[4 ][i]; + mdct_win_sse[1][j][4*i + 2] = ff_mdct_win_float[j ][i]; + mdct_win_sse[1][j][4*i + 3] = ff_mdct_win_float[j + 4][i]; + } + } + +#if HAVE_6REGS && HAVE_SSE_INLINE + if (INLINE_SSE(cpu_flags)) { + s->apply_window_float = apply_window_mp3; + } +#endif /* HAVE_SSE_INLINE */ + +#if HAVE_X86ASM +#if HAVE_SSE +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_sse; + } +#endif + if (EXTERNAL_SSE2(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_sse2; + } + if (EXTERNAL_SSE3(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_sse3; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_ssse3; + } +#endif +#if HAVE_AVX_EXTERNAL + if (EXTERNAL_AVX(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_avx; + } +#endif +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideo.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideo.c new file mode 100644 index 000000000..73967cafd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideo.c @@ -0,0 +1,469 @@ +/* + * Optimized for ia32 CPUs by Nick Kurshev + * H.263, MPEG-1, MPEG-2 dequantizer & draw_edges by Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/mpegvideo.h" +#include "libavcodec/mpegvideodata.h" + +#if HAVE_MMX_INLINE + +static void dct_unquantize_h263_intra_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg level, qmul, qadd, nCoeffs; + + qmul = qscale << 1; + + av_assert2(s->block_last_index[n]>=0 || s->h263_aic); + + if (!s->h263_aic) { + if (n < 4) + level = block[0] * s->y_dc_scale; + else + level = block[0] * s->c_dc_scale; + qadd = (qscale - 1) | 1; + }else{ + qadd = 0; + level= block[0]; + } + if(s->ac_pred) + nCoeffs=63; + else + nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; + +__asm__ volatile( + "movd %1, %%mm6 \n\t" //qmul + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "movd %2, %%mm5 \n\t" //qadd + "pxor %%mm7, %%mm7 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "psubw %%mm5, %%mm7 \n\t" + "pxor %%mm4, %%mm4 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %3), %%mm0 \n\t" + "movq 8(%0, %3), %%mm1 \n\t" + + "pmullw %%mm6, %%mm0 \n\t" + "pmullw %%mm6, %%mm1 \n\t" + + "movq (%0, %3), %%mm2 \n\t" + "movq 8(%0, %3), %%mm3 \n\t" + + "pcmpgtw %%mm4, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm4, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + + "paddw %%mm7, %%mm0 \n\t" + "paddw %%mm7, %%mm1 \n\t" + + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + + "pcmpeqw %%mm7, %%mm0 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw %%mm7, %%mm1 \n\t" // block[i] == 0 ? -1 : 0 + + "pandn %%mm2, %%mm0 \n\t" + "pandn %%mm3, %%mm1 \n\t" + + "movq %%mm0, (%0, %3) \n\t" + "movq %%mm1, 8(%0, %3) \n\t" + + "add $16, %3 \n\t" + "jng 1b \n\t" + ::"r" (block+nCoeffs), "rm"(qmul), "rm" (qadd), "r" (2*(-nCoeffs)) + : "memory" + ); + block[0]= level; +} + + +static void dct_unquantize_h263_inter_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg qmul, qadd, nCoeffs; + + qmul = qscale << 1; + qadd = (qscale - 1) | 1; + + av_assert2(s->block_last_index[n]>=0 || s->h263_aic); + + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; + +__asm__ volatile( + "movd %1, %%mm6 \n\t" //qmul + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "movd %2, %%mm5 \n\t" //qadd + "pxor %%mm7, %%mm7 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "psubw %%mm5, %%mm7 \n\t" + "pxor %%mm4, %%mm4 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %3), %%mm0 \n\t" + "movq 8(%0, %3), %%mm1 \n\t" + + "pmullw %%mm6, %%mm0 \n\t" + "pmullw %%mm6, %%mm1 \n\t" + + "movq (%0, %3), %%mm2 \n\t" + "movq 8(%0, %3), %%mm3 \n\t" + + "pcmpgtw %%mm4, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm4, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + + "paddw %%mm7, %%mm0 \n\t" + "paddw %%mm7, %%mm1 \n\t" + + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + + "pcmpeqw %%mm7, %%mm0 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw %%mm7, %%mm1 \n\t" // block[i] == 0 ? -1 : 0 + + "pandn %%mm2, %%mm0 \n\t" + "pandn %%mm3, %%mm1 \n\t" + + "movq %%mm0, (%0, %3) \n\t" + "movq %%mm1, 8(%0, %3) \n\t" + + "add $16, %3 \n\t" + "jng 1b \n\t" + ::"r" (block+nCoeffs), "rm"(qmul), "rm" (qadd), "r" (2*(-nCoeffs)) + : "memory" + ); +} + +static void dct_unquantize_mpeg1_intra_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg nCoeffs; + const uint16_t *quant_matrix; + int block0; + + av_assert2(s->block_last_index[n]>=0); + + nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1; + + if (n < 4) + block0 = block[0] * s->y_dc_scale; + else + block0 = block[0] * s->c_dc_scale; + /* XXX: only MPEG-1 */ + quant_matrix = s->intra_matrix; +__asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlw $15, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %%"FF_REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"FF_REG_a"), %%mm1\n\t" + "movq (%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"FF_REG_a"), %%mm5\n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*q + "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"FF_REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"FF_REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psraw $3, %%mm0 \n\t" + "psraw $3, %%mm1 \n\t" + "psubw %%mm7, %%mm0 \n\t" + "psubw %%mm7, %%mm1 \n\t" + "por %%mm7, %%mm0 \n\t" + "por %%mm7, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "movq %%mm4, (%0, %%"FF_REG_a") \n\t" + "movq %%mm5, 8(%0, %%"FF_REG_a")\n\t" + + "add $16, %%"FF_REG_a" \n\t" + "js 1b \n\t" + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "rm" (qscale), "g" (-2*nCoeffs) + : "%"FF_REG_a, "memory" + ); + block[0]= block0; +} + +static void dct_unquantize_mpeg1_inter_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg nCoeffs; + const uint16_t *quant_matrix; + + av_assert2(s->block_last_index[n]>=0); + + nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1; + + quant_matrix = s->inter_matrix; +__asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlw $15, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %%"FF_REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"FF_REG_a"), %%mm1\n\t" + "movq (%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"FF_REG_a"), %%mm5\n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "paddw %%mm0, %%mm0 \n\t" // abs(block[i])*2 + "paddw %%mm1, %%mm1 \n\t" // abs(block[i])*2 + "paddw %%mm7, %%mm0 \n\t" // abs(block[i])*2 + 1 + "paddw %%mm7, %%mm1 \n\t" // abs(block[i])*2 + 1 + "pmullw %%mm4, %%mm0 \n\t" // (abs(block[i])*2 + 1)*q + "pmullw %%mm5, %%mm1 \n\t" // (abs(block[i])*2 + 1)*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"FF_REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"FF_REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psraw $4, %%mm0 \n\t" + "psraw $4, %%mm1 \n\t" + "psubw %%mm7, %%mm0 \n\t" + "psubw %%mm7, %%mm1 \n\t" + "por %%mm7, %%mm0 \n\t" + "por %%mm7, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "movq %%mm4, (%0, %%"FF_REG_a") \n\t" + "movq %%mm5, 8(%0, %%"FF_REG_a")\n\t" + + "add $16, %%"FF_REG_a" \n\t" + "js 1b \n\t" + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "rm" (qscale), "g" (-2*nCoeffs) + : "%"FF_REG_a, "memory" + ); +} + +static void dct_unquantize_mpeg2_intra_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg nCoeffs; + const uint16_t *quant_matrix; + int block0; + + av_assert2(s->block_last_index[n]>=0); + + if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale]; + else qscale <<= 1; + + if(s->alternate_scan) nCoeffs= 63; //FIXME + else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; + + if (n < 4) + block0 = block[0] * s->y_dc_scale; + else + block0 = block[0] * s->c_dc_scale; + quant_matrix = s->intra_matrix; +__asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlw $15, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %%"FF_REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"FF_REG_a"), %%mm1\n\t" + "movq (%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"FF_REG_a"), %%mm5\n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*q + "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"FF_REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"FF_REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psraw $4, %%mm0 \n\t" + "psraw $4, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "movq %%mm4, (%0, %%"FF_REG_a") \n\t" + "movq %%mm5, 8(%0, %%"FF_REG_a")\n\t" + + "add $16, %%"FF_REG_a" \n\t" + "jng 1b \n\t" + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "rm" (qscale), "g" (-2*nCoeffs) + : "%"FF_REG_a, "memory" + ); + block[0]= block0; + //Note, we do not do mismatch control for intra as errors cannot accumulate +} + +static void dct_unquantize_mpeg2_inter_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg nCoeffs; + const uint16_t *quant_matrix; + + av_assert2(s->block_last_index[n]>=0); + + if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale]; + else qscale <<= 1; + + if(s->alternate_scan) nCoeffs= 63; //FIXME + else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; + + quant_matrix = s->inter_matrix; +__asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlq $48, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %%"FF_REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"FF_REG_a"), %%mm1\n\t" + "movq (%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"FF_REG_a"), %%mm5\n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "paddw %%mm0, %%mm0 \n\t" // abs(block[i])*2 + "paddw %%mm1, %%mm1 \n\t" // abs(block[i])*2 + "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*2*q + "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*2*q + "paddw %%mm4, %%mm0 \n\t" // (abs(block[i])*2 + 1)*q + "paddw %%mm5, %%mm1 \n\t" // (abs(block[i])*2 + 1)*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"FF_REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"FF_REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psrlw $5, %%mm0 \n\t" + "psrlw $5, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "pxor %%mm4, %%mm7 \n\t" + "pxor %%mm5, %%mm7 \n\t" + "movq %%mm4, (%0, %%"FF_REG_a") \n\t" + "movq %%mm5, 8(%0, %%"FF_REG_a")\n\t" + + "add $16, %%"FF_REG_a" \n\t" + "jng 1b \n\t" + "movd 124(%0, %3), %%mm0 \n\t" + "movq %%mm7, %%mm6 \n\t" + "psrlq $32, %%mm7 \n\t" + "pxor %%mm6, %%mm7 \n\t" + "movq %%mm7, %%mm6 \n\t" + "psrlq $16, %%mm7 \n\t" + "pxor %%mm6, %%mm7 \n\t" + "pslld $31, %%mm7 \n\t" + "psrlq $15, %%mm7 \n\t" + "pxor %%mm7, %%mm0 \n\t" + "movd %%mm0, 124(%0, %3) \n\t" + + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "rm" (qscale), "r" (-2*nCoeffs) + : "%"FF_REG_a, "memory" + ); +} + +#endif /* HAVE_MMX_INLINE */ + +av_cold void ff_mpv_common_init_x86(MpegEncContext *s) +{ +#if HAVE_MMX_INLINE + int cpu_flags = av_get_cpu_flags(); + + if (INLINE_MMX(cpu_flags)) { + s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_mmx; + s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_mmx; + s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_mmx; + s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_mmx; + if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT)) + s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx; + s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx; + } +#endif /* HAVE_MMX_INLINE */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideodsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideodsp.c new file mode 100644 index 000000000..6009b64e0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideodsp.c @@ -0,0 +1,161 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/mpegvideodsp.h" +#include "libavcodec/videodsp.h" + +#if HAVE_INLINE_ASM + +static void gmc_mmx(uint8_t *dst, uint8_t *src, + int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, + int shift, int r, int width, int height) +{ + const int w = 8; + const int ix = ox >> (16 + shift); + const int iy = oy >> (16 + shift); + const int oxs = ox >> 4; + const int oys = oy >> 4; + const int dxxs = dxx >> 4; + const int dxys = dxy >> 4; + const int dyxs = dyx >> 4; + const int dyys = dyy >> 4; + const uint16_t r4[4] = { r, r, r, r }; + const uint16_t dxy4[4] = { dxys, dxys, dxys, dxys }; + const uint16_t dyy4[4] = { dyys, dyys, dyys, dyys }; + const uint64_t shift2 = 2 * shift; +#define MAX_STRIDE 4096U +#define MAX_H 8U + uint8_t edge_buf[(MAX_H + 1) * MAX_STRIDE]; + int x, y; + + const int dxw = (dxx - (1 << (16 + shift))) * (w - 1); + const int dyh = (dyy - (1 << (16 + shift))) * (h - 1); + const int dxh = dxy * (h - 1); + const int dyw = dyx * (w - 1); + int need_emu = (unsigned) ix >= width - w || width < w || + (unsigned) iy >= height - h || height< h + ; + + if ( // non-constant fullpel offset (3% of blocks) + ((ox ^ (ox + dxw)) | (ox ^ (ox + dxh)) | (ox ^ (ox + dxw + dxh)) | + (oy ^ (oy + dyw)) | (oy ^ (oy + dyh)) | (oy ^ (oy + dyw + dyh))) >> (16 + shift) || + // uses more than 16 bits of subpel mv (only at huge resolution) + (dxx | dxy | dyx | dyy) & 15 || + (need_emu && (h > MAX_H || stride > MAX_STRIDE))) { + // FIXME could still use mmx for some of the rows + ff_gmc_c(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, + shift, r, width, height); + return; + } + + src += ix + iy * stride; + if (need_emu) { + ff_emulated_edge_mc_8(edge_buf, src, stride, stride, w + 1, h + 1, ix, iy, width, height); + src = edge_buf; + } + + __asm__ volatile ( + "movd %0, %%mm6 \n\t" + "pxor %%mm7, %%mm7 \n\t" + "punpcklwd %%mm6, %%mm6 \n\t" + "punpcklwd %%mm6, %%mm6 \n\t" + :: "r" (1 << shift)); + + for (x = 0; x < w; x += 4) { + uint16_t dx4[4] = { oxs - dxys + dxxs * (x + 0), + oxs - dxys + dxxs * (x + 1), + oxs - dxys + dxxs * (x + 2), + oxs - dxys + dxxs * (x + 3) }; + uint16_t dy4[4] = { oys - dyys + dyxs * (x + 0), + oys - dyys + dyxs * (x + 1), + oys - dyys + dyxs * (x + 2), + oys - dyys + dyxs * (x + 3) }; + + for (y = 0; y < h; y++) { + __asm__ volatile ( + "movq %0, %%mm4 \n\t" + "movq %1, %%mm5 \n\t" + "paddw %2, %%mm4 \n\t" + "paddw %3, %%mm5 \n\t" + "movq %%mm4, %0 \n\t" + "movq %%mm5, %1 \n\t" + "psrlw $12, %%mm4 \n\t" + "psrlw $12, %%mm5 \n\t" + : "+m" (*dx4), "+m" (*dy4) + : "m" (*dxy4), "m" (*dyy4)); + + __asm__ volatile ( + "movq %%mm6, %%mm2 \n\t" + "movq %%mm6, %%mm1 \n\t" + "psubw %%mm4, %%mm2 \n\t" + "psubw %%mm5, %%mm1 \n\t" + "movq %%mm2, %%mm0 \n\t" + "movq %%mm4, %%mm3 \n\t" + "pmullw %%mm1, %%mm0 \n\t" // (s - dx) * (s - dy) + "pmullw %%mm5, %%mm3 \n\t" // dx * dy + "pmullw %%mm5, %%mm2 \n\t" // (s - dx) * dy + "pmullw %%mm4, %%mm1 \n\t" // dx * (s - dy) + + "movd %4, %%mm5 \n\t" + "movd %3, %%mm4 \n\t" + "punpcklbw %%mm7, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "pmullw %%mm5, %%mm3 \n\t" // src[1, 1] * dx * dy + "pmullw %%mm4, %%mm2 \n\t" // src[0, 1] * (s - dx) * dy + + "movd %2, %%mm5 \n\t" + "movd %1, %%mm4 \n\t" + "punpcklbw %%mm7, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "pmullw %%mm5, %%mm1 \n\t" // src[1, 0] * dx * (s - dy) + "pmullw %%mm4, %%mm0 \n\t" // src[0, 0] * (s - dx) * (s - dy) + "paddw %5, %%mm1 \n\t" + "paddw %%mm3, %%mm2 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm2, %%mm0 \n\t" + + "psrlw %6, %%mm0 \n\t" + "packuswb %%mm0, %%mm0 \n\t" + "movd %%mm0, %0 \n\t" + + : "=m" (dst[x + y * stride]) + : "m" (src[0]), "m" (src[1]), + "m" (src[stride]), "m" (src[stride + 1]), + "m" (*r4), "m" (shift2)); + src += stride; + } + src += 4 - h * stride; + } +} + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_mpegvideodsp_init_x86(MpegVideoDSPContext *c) +{ +#if HAVE_INLINE_ASM + int cpu_flags = av_get_cpu_flags(); + + if (INLINE_MMX(cpu_flags)) + c->gmc = gmc_mmx; +#endif /* HAVE_INLINE_ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc.c new file mode 100644 index 000000000..c884cf121 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc.c @@ -0,0 +1,244 @@ +/* + * The simplest mpeg encoder (well, it was the simplest!) + * Copyright (c) 2000,2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/dct.h" +#include "libavcodec/mpegvideo.h" + +/* not permutated inverse zigzag_direct + 1 for MMX quantizer */ +DECLARE_ALIGNED(16, static const uint16_t, inv_zigzag_direct16)[64] = { + 1, 2, 6, 7, 15, 16, 28, 29, + 3, 5, 8, 14, 17, 27, 30, 43, + 4, 9, 13, 18, 26, 31, 42, 44, + 10, 12, 19, 25, 32, 41, 45, 54, + 11, 20, 24, 33, 40, 46, 53, 55, + 21, 23, 34, 39, 47, 52, 56, 61, + 22, 35, 38, 48, 51, 57, 60, 62, + 36, 37, 49, 50, 58, 59, 63, 64, +}; + +#if HAVE_6REGS + +#if HAVE_MMX_INLINE +#define COMPILE_TEMPLATE_MMXEXT 0 +#define COMPILE_TEMPLATE_SSE2 0 +#define COMPILE_TEMPLATE_SSSE3 0 +#define RENAME(a) a ## _mmx +#define RENAME_FDCT(a) a ## _mmx +#include "mpegvideoenc_template.c" +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_MMXEXT_INLINE +#undef COMPILE_TEMPLATE_SSSE3 +#undef COMPILE_TEMPLATE_SSE2 +#undef COMPILE_TEMPLATE_MMXEXT +#define COMPILE_TEMPLATE_MMXEXT 1 +#define COMPILE_TEMPLATE_SSE2 0 +#define COMPILE_TEMPLATE_SSSE3 0 +#undef RENAME +#undef RENAME_FDCT +#define RENAME(a) a ## _mmxext +#define RENAME_FDCT(a) a ## _mmxext +#include "mpegvideoenc_template.c" +#endif /* HAVE_MMXEXT_INLINE */ + +#if HAVE_SSE2_INLINE +#undef COMPILE_TEMPLATE_MMXEXT +#undef COMPILE_TEMPLATE_SSE2 +#undef COMPILE_TEMPLATE_SSSE3 +#define COMPILE_TEMPLATE_MMXEXT 0 +#define COMPILE_TEMPLATE_SSE2 1 +#define COMPILE_TEMPLATE_SSSE3 0 +#undef RENAME +#undef RENAME_FDCT +#define RENAME(a) a ## _sse2 +#define RENAME_FDCT(a) a ## _sse2 +#include "mpegvideoenc_template.c" +#endif /* HAVE_SSE2_INLINE */ + +#if HAVE_SSSE3_INLINE +#undef COMPILE_TEMPLATE_MMXEXT +#undef COMPILE_TEMPLATE_SSE2 +#undef COMPILE_TEMPLATE_SSSE3 +#define COMPILE_TEMPLATE_MMXEXT 0 +#define COMPILE_TEMPLATE_SSE2 1 +#define COMPILE_TEMPLATE_SSSE3 1 +#undef RENAME +#undef RENAME_FDCT +#define RENAME(a) a ## _ssse3 +#define RENAME_FDCT(a) a ## _sse2 +#include "mpegvideoenc_template.c" +#endif /* HAVE_SSSE3_INLINE */ + +#endif /* HAVE_6REGS */ + +#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE +static void denoise_dct_mmx(MpegEncContext *s, int16_t *block){ + const int intra= s->mb_intra; + int *sum= s->dct_error_sum[intra]; + uint16_t *offset= s->dct_offset[intra]; + + s->dct_count[intra]++; + + __asm__ volatile( + "pxor %%mm7, %%mm7 \n\t" + "1: \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "movq (%0), %%mm2 \n\t" + "movq 8(%0), %%mm3 \n\t" + "pcmpgtw %%mm2, %%mm0 \n\t" + "pcmpgtw %%mm3, %%mm1 \n\t" + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + "psubw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq %%mm3, %%mm5 \n\t" + "psubusw (%2), %%mm2 \n\t" + "psubusw 8(%2), %%mm3 \n\t" + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + "psubw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" + "movq %%mm2, (%0) \n\t" + "movq %%mm3, 8(%0) \n\t" + "movq %%mm4, %%mm2 \n\t" + "movq %%mm5, %%mm3 \n\t" + "punpcklwd %%mm7, %%mm4 \n\t" + "punpckhwd %%mm7, %%mm2 \n\t" + "punpcklwd %%mm7, %%mm5 \n\t" + "punpckhwd %%mm7, %%mm3 \n\t" + "paddd (%1), %%mm4 \n\t" + "paddd 8(%1), %%mm2 \n\t" + "paddd 16(%1), %%mm5 \n\t" + "paddd 24(%1), %%mm3 \n\t" + "movq %%mm4, (%1) \n\t" + "movq %%mm2, 8(%1) \n\t" + "movq %%mm5, 16(%1) \n\t" + "movq %%mm3, 24(%1) \n\t" + "add $16, %0 \n\t" + "add $32, %1 \n\t" + "add $16, %2 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (block), "+r" (sum), "+r" (offset) + : "r"(block+64) + ); +} +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_SSE2_INLINE +static void denoise_dct_sse2(MpegEncContext *s, int16_t *block){ + const int intra= s->mb_intra; + int *sum= s->dct_error_sum[intra]; + uint16_t *offset= s->dct_offset[intra]; + + s->dct_count[intra]++; + + __asm__ volatile( + "pxor %%xmm7, %%xmm7 \n\t" + "1: \n\t" + "pxor %%xmm0, %%xmm0 \n\t" + "pxor %%xmm1, %%xmm1 \n\t" + "movdqa (%0), %%xmm2 \n\t" + "movdqa 16(%0), %%xmm3 \n\t" + "pcmpgtw %%xmm2, %%xmm0 \n\t" + "pcmpgtw %%xmm3, %%xmm1 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm3 \n\t" + "psubw %%xmm0, %%xmm2 \n\t" + "psubw %%xmm1, %%xmm3 \n\t" + "movdqa %%xmm2, %%xmm4 \n\t" + "movdqa %%xmm3, %%xmm5 \n\t" + "psubusw (%2), %%xmm2 \n\t" + "psubusw 16(%2), %%xmm3 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm3 \n\t" + "psubw %%xmm0, %%xmm2 \n\t" + "psubw %%xmm1, %%xmm3 \n\t" + "movdqa %%xmm2, (%0) \n\t" + "movdqa %%xmm3, 16(%0) \n\t" + "movdqa %%xmm4, %%xmm6 \n\t" + "movdqa %%xmm5, %%xmm0 \n\t" + "punpcklwd %%xmm7, %%xmm4 \n\t" + "punpckhwd %%xmm7, %%xmm6 \n\t" + "punpcklwd %%xmm7, %%xmm5 \n\t" + "punpckhwd %%xmm7, %%xmm0 \n\t" + "paddd (%1), %%xmm4 \n\t" + "paddd 16(%1), %%xmm6 \n\t" + "paddd 32(%1), %%xmm5 \n\t" + "paddd 48(%1), %%xmm0 \n\t" + "movdqa %%xmm4, (%1) \n\t" + "movdqa %%xmm6, 16(%1) \n\t" + "movdqa %%xmm5, 32(%1) \n\t" + "movdqa %%xmm0, 48(%1) \n\t" + "add $32, %0 \n\t" + "add $64, %1 \n\t" + "add $32, %2 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (block), "+r" (sum), "+r" (offset) + : "r"(block+64) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7") + ); +} +#endif /* HAVE_SSE2_INLINE */ +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_dct_encode_init_x86(MpegEncContext *s) +{ + const int dct_algo = s->avctx->dct_algo; + + if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) { +#if HAVE_MMX_INLINE + int cpu_flags = av_get_cpu_flags(); + if (INLINE_MMX(cpu_flags)) { +#if HAVE_6REGS + s->dct_quantize = dct_quantize_mmx; +#endif + s->denoise_dct = denoise_dct_mmx; + } +#endif +#if HAVE_6REGS && HAVE_MMXEXT_INLINE + if (INLINE_MMXEXT(cpu_flags)) + s->dct_quantize = dct_quantize_mmxext; +#endif +#if HAVE_SSE2_INLINE + if (INLINE_SSE2(cpu_flags)) { +#if HAVE_6REGS + s->dct_quantize = dct_quantize_sse2; +#endif + s->denoise_dct = denoise_dct_sse2; + } +#endif +#if HAVE_6REGS && HAVE_SSSE3_INLINE + if (INLINE_SSSE3(cpu_flags)) + s->dct_quantize = dct_quantize_ssse3; +#endif + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc_qns_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc_qns_template.c new file mode 100644 index 000000000..882d48620 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc_qns_template.c @@ -0,0 +1,109 @@ +/* + * QNS functions are compiled 3 times for MMX/3DNOW/SSSE3 + * Copyright (c) 2004 Michael Niedermayer + * + * MMX optimization by Michael Niedermayer + * 3DNow! and SSSE3 optimization by Zuxy Meng + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/x86/asm.h" + +#include "inline_asm.h" + +#define MAX_ABS (512 >> (SCALE_OFFSET>0 ? SCALE_OFFSET : 0)) + +static int DEF(try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale) +{ + x86_reg i=0; + + av_assert2(FFABS(scale) < MAX_ABS); + scale<<= 16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT; + + SET_RND(mm6); + __asm__ volatile( + "pxor %%mm7, %%mm7 \n\t" + "movd %4, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq 8(%1, %0), %%mm1 \n\t" + PMULHRW(%%mm0, %%mm1, %%mm5, %%mm6) + "paddw (%2, %0), %%mm0 \n\t" + "paddw 8(%2, %0), %%mm1 \n\t" + "psraw $6, %%mm0 \n\t" + "psraw $6, %%mm1 \n\t" + "pmullw (%3, %0), %%mm0 \n\t" + "pmullw 8(%3, %0), %%mm1 \n\t" + "pmaddwd %%mm0, %%mm0 \n\t" + "pmaddwd %%mm1, %%mm1 \n\t" + "paddd %%mm1, %%mm0 \n\t" + "psrld $4, %%mm0 \n\t" + "paddd %%mm0, %%mm7 \n\t" + "add $16, %0 \n\t" + "cmp $128, %0 \n\t" //FIXME optimize & bench + " jb 1b \n\t" + PHADDD(%%mm7, %%mm6) + "psrld $2, %%mm7 \n\t" + "movd %%mm7, %0 \n\t" + + : "+r" (i) + : "r"(basis), "r"(rem), "r"(weight), "g"(scale) + ); + return i; +} + +static void DEF(add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale) +{ + x86_reg i=0; + + if(FFABS(scale) < MAX_ABS){ + scale<<= 16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT; + SET_RND(mm6); + __asm__ volatile( + "movd %3, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq 8(%1, %0), %%mm1 \n\t" + PMULHRW(%%mm0, %%mm1, %%mm5, %%mm6) + "paddw (%2, %0), %%mm0 \n\t" + "paddw 8(%2, %0), %%mm1 \n\t" + "movq %%mm0, (%2, %0) \n\t" + "movq %%mm1, 8(%2, %0) \n\t" + "add $16, %0 \n\t" + "cmp $128, %0 \n\t" // FIXME optimize & bench + " jb 1b \n\t" + + : "+r" (i) + : "r"(basis), "r"(rem), "g"(scale) + ); + }else{ + for(i=0; i<8*8; i++){ + rem[i] += (basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT); + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc_template.c new file mode 100644 index 000000000..1201be514 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoenc_template.c @@ -0,0 +1,423 @@ +/* + * MPEG video MMX templates + * + * Copyright (c) 2002 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/internal.h" +#include "libavutil/x86/asm.h" +#include "libavcodec/mpegutils.h" +#include "libavcodec/mpegvideo.h" +#include "fdct.h" + +#undef MMREG_WIDTH +#undef MM +#undef MOVQ +#undef SPREADW +#undef PMAXW +#undef PMAX +#undef SAVE_SIGN +#undef RESTORE_SIGN + +#if COMPILE_TEMPLATE_SSE2 +#define MMREG_WIDTH "16" +#define MM "%%xmm" +#define MOVQ "movdqa" +#define SPREADW(a) \ + "pshuflw $0, "a", "a" \n\t"\ + "punpcklwd "a", "a" \n\t" +#define PMAXW(a,b) "pmaxsw "a", "b" \n\t" +#define PMAX(a,b) \ + "movhlps "a", "b" \n\t"\ + PMAXW(b, a)\ + "pshuflw $0x0E, "a", "b" \n\t"\ + PMAXW(b, a)\ + "pshuflw $0x01, "a", "b" \n\t"\ + PMAXW(b, a) +#else +#define MMREG_WIDTH "8" +#define MM "%%mm" +#define MOVQ "movq" +#if COMPILE_TEMPLATE_MMXEXT +#define SPREADW(a) "pshufw $0, "a", "a" \n\t" +#define PMAXW(a,b) "pmaxsw "a", "b" \n\t" +#define PMAX(a,b) \ + "pshufw $0x0E, "a", "b" \n\t"\ + PMAXW(b, a)\ + "pshufw $0x01, "a", "b" \n\t"\ + PMAXW(b, a) +#else +#define SPREADW(a) \ + "punpcklwd "a", "a" \n\t"\ + "punpcklwd "a", "a" \n\t" +#define PMAXW(a,b) \ + "psubusw "a", "b" \n\t"\ + "paddw "a", "b" \n\t" +#define PMAX(a,b) \ + "movq "a", "b" \n\t"\ + "psrlq $32, "a" \n\t"\ + PMAXW(b, a)\ + "movq "a", "b" \n\t"\ + "psrlq $16, "a" \n\t"\ + PMAXW(b, a) + +#endif +#endif + +#if COMPILE_TEMPLATE_SSSE3 +#define SAVE_SIGN(a,b) \ + "movdqa "b", "a" \n\t"\ + "pabsw "b", "b" \n\t" +#define RESTORE_SIGN(a,b) \ + "psignw "a", "b" \n\t" +#else +#define SAVE_SIGN(a,b) \ + "pxor "a", "a" \n\t"\ + "pcmpgtw "b", "a" \n\t" /* block[i] <= 0 ? 0xFF : 0x00 */\ + "pxor "a", "b" \n\t"\ + "psubw "a", "b" \n\t" /* ABS(block[i]) */ +#define RESTORE_SIGN(a,b) \ + "pxor "a", "b" \n\t"\ + "psubw "a", "b" \n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) +#endif + +static int RENAME(dct_quantize)(MpegEncContext *s, + int16_t *block, int n, + int qscale, int *overflow) +{ + x86_reg last_non_zero_p1; + int level=0, q; //=0 is because gcc says uninitialized ... + const uint16_t *qmat, *bias; + LOCAL_ALIGNED_16(int16_t, temp_block, [64]); + + av_assert2((7&(int)(&temp_block[0])) == 0); //did gcc align it correctly? + + //s->fdct (block); + RENAME_FDCT(ff_fdct)(block); // cannot be anything else ... + + if(s->dct_error_sum) + s->denoise_dct(s, block); + + if (s->mb_intra) { + int dummy; + if (n < 4){ + q = s->y_dc_scale; + bias = s->q_intra_matrix16[qscale][1]; + qmat = s->q_intra_matrix16[qscale][0]; + }else{ + q = s->c_dc_scale; + bias = s->q_chroma_intra_matrix16[qscale][1]; + qmat = s->q_chroma_intra_matrix16[qscale][0]; + } + /* note: block[0] is assumed to be positive */ + if (!s->h263_aic) { + __asm__ volatile ( + "mul %%ecx \n\t" + : "=d" (level), "=a"(dummy) + : "a" ((block[0]>>2) + q), "c" (ff_inverse[q<<1]) + ); + } else + /* For AIC we skip quant/dequant of INTRADC */ + level = (block[0] + 4)>>3; + + block[0]=0; //avoid fake overflow +// temp_block[0] = (block[0] + (q >> 1)) / q; + last_non_zero_p1 = 1; + } else { + last_non_zero_p1 = 0; + bias = s->q_inter_matrix16[qscale][1]; + qmat = s->q_inter_matrix16[qscale][0]; + } + + if((s->out_format == FMT_H263 || s->out_format == FMT_H261) && s->mpeg_quant==0){ + + __asm__ volatile( + "movd %%"FF_REG_a", "MM"3 \n\t" // last_non_zero_p1 + SPREADW(MM"3") + "pxor "MM"7, "MM"7 \n\t" // 0 + "pxor "MM"4, "MM"4 \n\t" // 0 + MOVQ" (%2), "MM"5 \n\t" // qmat[0] + "pxor "MM"6, "MM"6 \n\t" + "psubw (%3), "MM"6 \n\t" // -bias[0] + "mov $-128, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + MOVQ" (%1, %%"FF_REG_a"), "MM"0 \n\t" // block[i] + SAVE_SIGN(MM"1", MM"0") // ABS(block[i]) + "psubusw "MM"6, "MM"0 \n\t" // ABS(block[i]) + bias[0] + "pmulhw "MM"5, "MM"0 \n\t" // (ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16 + "por "MM"0, "MM"4 \n\t" + RESTORE_SIGN(MM"1", MM"0") // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) + MOVQ" "MM"0, (%5, %%"FF_REG_a") \n\t" + "pcmpeqw "MM"7, "MM"0 \n\t" // out==0 ? 0xFF : 0x00 + MOVQ" (%4, %%"FF_REG_a"), "MM"1 \n\t" + MOVQ" "MM"7, (%1, %%"FF_REG_a") \n\t" // 0 + "pandn "MM"1, "MM"0 \n\t" + PMAXW(MM"0", MM"3") + "add $"MMREG_WIDTH", %%"FF_REG_a" \n\t" + " js 1b \n\t" + PMAX(MM"3", MM"0") + "movd "MM"3, %%"FF_REG_a" \n\t" + "movzbl %%al, %%eax \n\t" // last_non_zero_p1 + : "+a" (last_non_zero_p1) + : "r" (block+64), "r" (qmat), "r" (bias), + "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7") + ); + }else{ // FMT_H263 + __asm__ volatile( + "movd %%"FF_REG_a", "MM"3 \n\t" // last_non_zero_p1 + SPREADW(MM"3") + "pxor "MM"7, "MM"7 \n\t" // 0 + "pxor "MM"4, "MM"4 \n\t" // 0 + "mov $-128, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + MOVQ" (%1, %%"FF_REG_a"), "MM"0 \n\t" // block[i] + SAVE_SIGN(MM"1", MM"0") // ABS(block[i]) + MOVQ" (%3, %%"FF_REG_a"), "MM"6 \n\t" // bias[0] + "paddusw "MM"6, "MM"0 \n\t" // ABS(block[i]) + bias[0] + MOVQ" (%2, %%"FF_REG_a"), "MM"5 \n\t" // qmat[i] + "pmulhw "MM"5, "MM"0 \n\t" // (ABS(block[i])*qmat[0] + bias[0]*qmat[0])>>16 + "por "MM"0, "MM"4 \n\t" + RESTORE_SIGN(MM"1", MM"0") // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) + MOVQ" "MM"0, (%5, %%"FF_REG_a") \n\t" + "pcmpeqw "MM"7, "MM"0 \n\t" // out==0 ? 0xFF : 0x00 + MOVQ" (%4, %%"FF_REG_a"), "MM"1 \n\t" + MOVQ" "MM"7, (%1, %%"FF_REG_a") \n\t" // 0 + "pandn "MM"1, "MM"0 \n\t" + PMAXW(MM"0", MM"3") + "add $"MMREG_WIDTH", %%"FF_REG_a" \n\t" + " js 1b \n\t" + PMAX(MM"3", MM"0") + "movd "MM"3, %%"FF_REG_a" \n\t" + "movzbl %%al, %%eax \n\t" // last_non_zero_p1 + : "+a" (last_non_zero_p1) + : "r" (block+64), "r" (qmat+64), "r" (bias+64), + "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7") + ); + } + __asm__ volatile( + "movd %1, "MM"1 \n\t" // max_qcoeff + SPREADW(MM"1") + "psubusw "MM"1, "MM"4 \n\t" + "packuswb "MM"4, "MM"4 \n\t" +#if COMPILE_TEMPLATE_SSE2 + "packsswb "MM"4, "MM"4 \n\t" +#endif + "movd "MM"4, %0 \n\t" // *overflow + : "=g" (*overflow) + : "g" (s->max_qcoeff) + ); + + if(s->mb_intra) block[0]= level; + else block[0]= temp_block[0]; + + if (s->idsp.perm_type == FF_IDCT_PERM_SIMPLE) { + if(last_non_zero_p1 <= 1) goto end; + block[0x08] = temp_block[0x01]; block[0x10] = temp_block[0x08]; + block[0x20] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x18] = temp_block[0x09]; block[0x04] = temp_block[0x02]; + block[0x09] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x14] = temp_block[0x0A]; block[0x28] = temp_block[0x11]; + block[0x12] = temp_block[0x18]; block[0x02] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x1A] = temp_block[0x19]; block[0x24] = temp_block[0x12]; + block[0x19] = temp_block[0x0B]; block[0x01] = temp_block[0x04]; + block[0x0C] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x11] = temp_block[0x0C]; block[0x29] = temp_block[0x13]; + block[0x16] = temp_block[0x1A]; block[0x0A] = temp_block[0x21]; + block[0x30] = temp_block[0x28]; block[0x22] = temp_block[0x30]; + block[0x38] = temp_block[0x29]; block[0x06] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1B] = temp_block[0x1B]; block[0x21] = temp_block[0x14]; + block[0x1C] = temp_block[0x0D]; block[0x05] = temp_block[0x06]; + block[0x0D] = temp_block[0x07]; block[0x15] = temp_block[0x0E]; + block[0x2C] = temp_block[0x15]; block[0x13] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x0B] = temp_block[0x23]; block[0x34] = temp_block[0x2A]; + block[0x2A] = temp_block[0x31]; block[0x32] = temp_block[0x38]; + block[0x3A] = temp_block[0x39]; block[0x26] = temp_block[0x32]; + block[0x39] = temp_block[0x2B]; block[0x03] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x1E] = temp_block[0x1D]; block[0x25] = temp_block[0x16]; + block[0x1D] = temp_block[0x0F]; block[0x2D] = temp_block[0x17]; + block[0x17] = temp_block[0x1E]; block[0x0E] = temp_block[0x25]; + block[0x31] = temp_block[0x2C]; block[0x2B] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x36] = temp_block[0x3A]; block[0x3B] = temp_block[0x3B]; + block[0x23] = temp_block[0x34]; block[0x3C] = temp_block[0x2D]; + block[0x07] = temp_block[0x26]; block[0x1F] = temp_block[0x1F]; + block[0x0F] = temp_block[0x27]; block[0x35] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x2E] = temp_block[0x35]; block[0x33] = temp_block[0x3C]; + block[0x3E] = temp_block[0x3D]; block[0x27] = temp_block[0x36]; + block[0x3D] = temp_block[0x2F]; block[0x2F] = temp_block[0x37]; + block[0x37] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + }else if(s->idsp.perm_type == FF_IDCT_PERM_LIBMPEG2){ + if(last_non_zero_p1 <= 1) goto end; + block[0x04] = temp_block[0x01]; + block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x0C] = temp_block[0x09]; block[0x01] = temp_block[0x02]; + block[0x05] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x09] = temp_block[0x0A]; block[0x14] = temp_block[0x11]; + block[0x18] = temp_block[0x18]; block[0x20] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x1C] = temp_block[0x19]; + block[0x11] = temp_block[0x12]; block[0x0D] = temp_block[0x0B]; + block[0x02] = temp_block[0x04]; block[0x06] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x0A] = temp_block[0x0C]; block[0x15] = temp_block[0x13]; + block[0x19] = temp_block[0x1A]; block[0x24] = temp_block[0x21]; + block[0x28] = temp_block[0x28]; block[0x30] = temp_block[0x30]; + block[0x2C] = temp_block[0x29]; block[0x21] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1D] = temp_block[0x1B]; block[0x12] = temp_block[0x14]; + block[0x0E] = temp_block[0x0D]; block[0x03] = temp_block[0x06]; + block[0x07] = temp_block[0x07]; block[0x0B] = temp_block[0x0E]; + block[0x16] = temp_block[0x15]; block[0x1A] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x25] = temp_block[0x23]; block[0x29] = temp_block[0x2A]; + block[0x34] = temp_block[0x31]; block[0x38] = temp_block[0x38]; + block[0x3C] = temp_block[0x39]; block[0x31] = temp_block[0x32]; + block[0x2D] = temp_block[0x2B]; block[0x22] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x1E] = temp_block[0x1D]; block[0x13] = temp_block[0x16]; + block[0x0F] = temp_block[0x0F]; block[0x17] = temp_block[0x17]; + block[0x1B] = temp_block[0x1E]; block[0x26] = temp_block[0x25]; + block[0x2A] = temp_block[0x2C]; block[0x35] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x39] = temp_block[0x3A]; block[0x3D] = temp_block[0x3B]; + block[0x32] = temp_block[0x34]; block[0x2E] = temp_block[0x2D]; + block[0x23] = temp_block[0x26]; block[0x1F] = temp_block[0x1F]; + block[0x27] = temp_block[0x27]; block[0x2B] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x36] = temp_block[0x35]; block[0x3A] = temp_block[0x3C]; + block[0x3E] = temp_block[0x3D]; block[0x33] = temp_block[0x36]; + block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37]; + block[0x3B] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + } else if (s->idsp.perm_type == FF_IDCT_PERM_NONE) { + if(last_non_zero_p1 <= 1) goto end; + block[0x01] = temp_block[0x01]; + block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x09] = temp_block[0x09]; block[0x02] = temp_block[0x02]; + block[0x03] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x0A] = temp_block[0x0A]; block[0x11] = temp_block[0x11]; + block[0x18] = temp_block[0x18]; block[0x20] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x19] = temp_block[0x19]; + block[0x12] = temp_block[0x12]; block[0x0B] = temp_block[0x0B]; + block[0x04] = temp_block[0x04]; block[0x05] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x0C] = temp_block[0x0C]; block[0x13] = temp_block[0x13]; + block[0x1A] = temp_block[0x1A]; block[0x21] = temp_block[0x21]; + block[0x28] = temp_block[0x28]; block[0x30] = temp_block[0x30]; + block[0x29] = temp_block[0x29]; block[0x22] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1B] = temp_block[0x1B]; block[0x14] = temp_block[0x14]; + block[0x0D] = temp_block[0x0D]; block[0x06] = temp_block[0x06]; + block[0x07] = temp_block[0x07]; block[0x0E] = temp_block[0x0E]; + block[0x15] = temp_block[0x15]; block[0x1C] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x23] = temp_block[0x23]; block[0x2A] = temp_block[0x2A]; + block[0x31] = temp_block[0x31]; block[0x38] = temp_block[0x38]; + block[0x39] = temp_block[0x39]; block[0x32] = temp_block[0x32]; + block[0x2B] = temp_block[0x2B]; block[0x24] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x1D] = temp_block[0x1D]; block[0x16] = temp_block[0x16]; + block[0x0F] = temp_block[0x0F]; block[0x17] = temp_block[0x17]; + block[0x1E] = temp_block[0x1E]; block[0x25] = temp_block[0x25]; + block[0x2C] = temp_block[0x2C]; block[0x33] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x3A] = temp_block[0x3A]; block[0x3B] = temp_block[0x3B]; + block[0x34] = temp_block[0x34]; block[0x2D] = temp_block[0x2D]; + block[0x26] = temp_block[0x26]; block[0x1F] = temp_block[0x1F]; + block[0x27] = temp_block[0x27]; block[0x2E] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x35] = temp_block[0x35]; block[0x3C] = temp_block[0x3C]; + block[0x3D] = temp_block[0x3D]; block[0x36] = temp_block[0x36]; + block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37]; + block[0x3E] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + } else if (s->idsp.perm_type == FF_IDCT_PERM_TRANSPOSE) { + if(last_non_zero_p1 <= 1) goto end; + block[0x08] = temp_block[0x01]; + block[0x01] = temp_block[0x08]; block[0x02] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x09] = temp_block[0x09]; block[0x10] = temp_block[0x02]; + block[0x18] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x11] = temp_block[0x0A]; block[0x0A] = temp_block[0x11]; + block[0x03] = temp_block[0x18]; block[0x04] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x0B] = temp_block[0x19]; + block[0x12] = temp_block[0x12]; block[0x19] = temp_block[0x0B]; + block[0x20] = temp_block[0x04]; block[0x28] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x21] = temp_block[0x0C]; block[0x1A] = temp_block[0x13]; + block[0x13] = temp_block[0x1A]; block[0x0C] = temp_block[0x21]; + block[0x05] = temp_block[0x28]; block[0x06] = temp_block[0x30]; + block[0x0D] = temp_block[0x29]; block[0x14] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1B] = temp_block[0x1B]; block[0x22] = temp_block[0x14]; + block[0x29] = temp_block[0x0D]; block[0x30] = temp_block[0x06]; + block[0x38] = temp_block[0x07]; block[0x31] = temp_block[0x0E]; + block[0x2A] = temp_block[0x15]; block[0x23] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x1C] = temp_block[0x23]; block[0x15] = temp_block[0x2A]; + block[0x0E] = temp_block[0x31]; block[0x07] = temp_block[0x38]; + block[0x0F] = temp_block[0x39]; block[0x16] = temp_block[0x32]; + block[0x1D] = temp_block[0x2B]; block[0x24] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x2B] = temp_block[0x1D]; block[0x32] = temp_block[0x16]; + block[0x39] = temp_block[0x0F]; block[0x3A] = temp_block[0x17]; + block[0x33] = temp_block[0x1E]; block[0x2C] = temp_block[0x25]; + block[0x25] = temp_block[0x2C]; block[0x1E] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x17] = temp_block[0x3A]; block[0x1F] = temp_block[0x3B]; + block[0x26] = temp_block[0x34]; block[0x2D] = temp_block[0x2D]; + block[0x34] = temp_block[0x26]; block[0x3B] = temp_block[0x1F]; + block[0x3C] = temp_block[0x27]; block[0x35] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x2E] = temp_block[0x35]; block[0x27] = temp_block[0x3C]; + block[0x2F] = temp_block[0x3D]; block[0x36] = temp_block[0x36]; + block[0x3D] = temp_block[0x2F]; block[0x3E] = temp_block[0x37]; + block[0x37] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + } else { + av_log(s, AV_LOG_DEBUG, "s->idsp.perm_type: %d\n", + (int)s->idsp.perm_type); + av_assert0(s->idsp.perm_type == FF_IDCT_PERM_NONE || + s->idsp.perm_type == FF_IDCT_PERM_LIBMPEG2 || + s->idsp.perm_type == FF_IDCT_PERM_SIMPLE || + s->idsp.perm_type == FF_IDCT_PERM_TRANSPOSE); + } + end: + return last_non_zero_p1 - 1; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoencdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoencdsp_init.c new file mode 100644 index 000000000..532836cec --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mpegvideoencdsp_init.c @@ -0,0 +1,272 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/mpegvideoencdsp.h" + +int ff_pix_sum16_mmx(uint8_t *pix, int line_size); +int ff_pix_sum16_mmxext(uint8_t *pix, int line_size); +int ff_pix_sum16_sse2(uint8_t *pix, int line_size); +int ff_pix_sum16_xop(uint8_t *pix, int line_size); +int ff_pix_norm1_mmx(uint8_t *pix, int line_size); +int ff_pix_norm1_sse2(uint8_t *pix, int line_size); + +#if HAVE_INLINE_ASM + +#define PHADDD(a, t) \ + "movq " #a ", " #t " \n\t" \ + "psrlq $32, " #a " \n\t" \ + "paddd " #t ", " #a " \n\t" + +/* + * pmulhw: dst[0 - 15] = (src[0 - 15] * dst[0 - 15])[16 - 31] + * pmulhrw: dst[0 - 15] = (src[0 - 15] * dst[0 - 15] + 0x8000)[16 - 31] + * pmulhrsw: dst[0 - 15] = (src[0 - 15] * dst[0 - 15] + 0x4000)[15 - 30] + */ +#define PMULHRW(x, y, s, o) \ + "pmulhw " #s ", " #x " \n\t" \ + "pmulhw " #s ", " #y " \n\t" \ + "paddw " #o ", " #x " \n\t" \ + "paddw " #o ", " #y " \n\t" \ + "psraw $1, " #x " \n\t" \ + "psraw $1, " #y " \n\t" +#define DEF(x) x ## _mmx +#define SET_RND MOVQ_WONE +#define SCALE_OFFSET 1 + +#include "mpegvideoenc_qns_template.c" + +#undef DEF +#undef SET_RND +#undef SCALE_OFFSET +#undef PMULHRW + +#define DEF(x) x ## _3dnow +#define SET_RND(x) +#define SCALE_OFFSET 0 +#define PMULHRW(x, y, s, o) \ + "pmulhrw " #s ", " #x " \n\t" \ + "pmulhrw " #s ", " #y " \n\t" + +#include "mpegvideoenc_qns_template.c" + +#undef DEF +#undef SET_RND +#undef SCALE_OFFSET +#undef PMULHRW + +#if HAVE_SSSE3_INLINE +#undef PHADDD +#define DEF(x) x ## _ssse3 +#define SET_RND(x) +#define SCALE_OFFSET -1 + +#define PHADDD(a, t) \ + "pshufw $0x0E, " #a ", " #t " \n\t" \ + /* faster than phaddd on core2 */ \ + "paddd " #t ", " #a " \n\t" + +#define PMULHRW(x, y, s, o) \ + "pmulhrsw " #s ", " #x " \n\t" \ + "pmulhrsw " #s ", " #y " \n\t" + +#include "mpegvideoenc_qns_template.c" + +#undef DEF +#undef SET_RND +#undef SCALE_OFFSET +#undef PMULHRW +#undef PHADDD +#endif /* HAVE_SSSE3_INLINE */ + +/* Draw the edges of width 'w' of an image of size width, height + * this MMX version can only handle w == 8 || w == 16. */ +static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, + int w, int h, int sides) +{ + uint8_t *ptr, *last_line; + int i; + + last_line = buf + (height - 1) * wrap; + /* left and right */ + ptr = buf; + if (w == 8) { + __asm__ volatile ( + "1: \n\t" + "movd (%0), %%mm0 \n\t" + "punpcklbw %%mm0, %%mm0 \n\t" + "punpcklwd %%mm0, %%mm0 \n\t" + "punpckldq %%mm0, %%mm0 \n\t" + "movq %%mm0, -8(%0) \n\t" + "movq -8(%0, %2), %%mm1 \n\t" + "punpckhbw %%mm1, %%mm1 \n\t" + "punpckhwd %%mm1, %%mm1 \n\t" + "punpckhdq %%mm1, %%mm1 \n\t" + "movq %%mm1, (%0, %2) \n\t" + "add %1, %0 \n\t" + "cmp %3, %0 \n\t" + "jb 1b \n\t" + : "+r" (ptr) + : "r" ((x86_reg) wrap), "r" ((x86_reg) width), + "r" (ptr + wrap * height)); + } else if (w == 16) { + __asm__ volatile ( + "1: \n\t" + "movd (%0), %%mm0 \n\t" + "punpcklbw %%mm0, %%mm0 \n\t" + "punpcklwd %%mm0, %%mm0 \n\t" + "punpckldq %%mm0, %%mm0 \n\t" + "movq %%mm0, -8(%0) \n\t" + "movq %%mm0, -16(%0) \n\t" + "movq -8(%0, %2), %%mm1 \n\t" + "punpckhbw %%mm1, %%mm1 \n\t" + "punpckhwd %%mm1, %%mm1 \n\t" + "punpckhdq %%mm1, %%mm1 \n\t" + "movq %%mm1, (%0, %2) \n\t" + "movq %%mm1, 8(%0, %2) \n\t" + "add %1, %0 \n\t" + "cmp %3, %0 \n\t" + "jb 1b \n\t" + : "+r"(ptr) + : "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height) + ); + } else { + av_assert1(w == 4); + __asm__ volatile ( + "1: \n\t" + "movd (%0), %%mm0 \n\t" + "punpcklbw %%mm0, %%mm0 \n\t" + "punpcklwd %%mm0, %%mm0 \n\t" + "movd %%mm0, -4(%0) \n\t" + "movd -4(%0, %2), %%mm1 \n\t" + "punpcklbw %%mm1, %%mm1 \n\t" + "punpckhwd %%mm1, %%mm1 \n\t" + "punpckhdq %%mm1, %%mm1 \n\t" + "movd %%mm1, (%0, %2) \n\t" + "add %1, %0 \n\t" + "cmp %3, %0 \n\t" + "jb 1b \n\t" + : "+r" (ptr) + : "r" ((x86_reg) wrap), "r" ((x86_reg) width), + "r" (ptr + wrap * height)); + } + + /* top and bottom (and hopefully also the corners) */ + if (sides & EDGE_TOP) { + for (i = 0; i < h; i += 4) { + ptr = buf - (i + 1) * wrap - w; + __asm__ volatile ( + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq %%mm0, (%0) \n\t" + "movq %%mm0, (%0, %2) \n\t" + "movq %%mm0, (%0, %2, 2) \n\t" + "movq %%mm0, (%0, %3) \n\t" + "add $8, %0 \n\t" + "cmp %4, %0 \n\t" + "jb 1b \n\t" + : "+r" (ptr) + : "r" ((x86_reg) buf - (x86_reg) ptr - w), + "r" ((x86_reg) - wrap), "r" ((x86_reg) - wrap * 3), + "r" (ptr + width + 2 * w)); + } + } + + if (sides & EDGE_BOTTOM) { + for (i = 0; i < h; i += 4) { + ptr = last_line + (i + 1) * wrap - w; + __asm__ volatile ( + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq %%mm0, (%0) \n\t" + "movq %%mm0, (%0, %2) \n\t" + "movq %%mm0, (%0, %2, 2) \n\t" + "movq %%mm0, (%0, %3) \n\t" + "add $8, %0 \n\t" + "cmp %4, %0 \n\t" + "jb 1b \n\t" + : "+r" (ptr) + : "r" ((x86_reg) last_line - (x86_reg) ptr - w), + "r" ((x86_reg) wrap), "r" ((x86_reg) wrap * 3), + "r" (ptr + width + 2 * w)); + } + } +} + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c, + AVCodecContext *avctx) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags)) { + c->pix_sum = ff_pix_sum16_mmx; + c->pix_norm1 = ff_pix_norm1_mmx; + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->pix_sum = ff_pix_sum16_mmxext; + } +#endif + + if (EXTERNAL_SSE2(cpu_flags)) { + c->pix_sum = ff_pix_sum16_sse2; + c->pix_norm1 = ff_pix_norm1_sse2; + } + + if (EXTERNAL_XOP(cpu_flags)) { + c->pix_sum = ff_pix_sum16_xop; + } + +#if HAVE_INLINE_ASM + + if (INLINE_MMX(cpu_flags)) { + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->try_8x8basis = try_8x8basis_mmx; + } + c->add_8x8basis = add_8x8basis_mmx; + + if (avctx->bits_per_raw_sample <= 8) { + c->draw_edges = draw_edges_mmx; + } + } + + if (INLINE_AMD3DNOW(cpu_flags)) { + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->try_8x8basis = try_8x8basis_3dnow; + } + c->add_8x8basis = add_8x8basis_3dnow; + } + +#if HAVE_SSSE3_INLINE + if (INLINE_SSSE3(cpu_flags)) { + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->try_8x8basis = try_8x8basis_ssse3; + } + c->add_8x8basis = add_8x8basis_ssse3; + } +#endif /* HAVE_SSSE3_INLINE */ + +#endif /* HAVE_INLINE_ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/opusdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/opusdsp_init.c new file mode 100644 index 000000000..6834c4e6a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/opusdsp_init.c @@ -0,0 +1,35 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/x86/cpu.h" +#include "libavcodec/opusdsp.h" + +void ff_opus_postfilter_fma3(float *data, int period, float *gains, int len); +float ff_opus_deemphasis_fma3(float *out, float *in, float coeff, int len); + +av_cold void ff_opus_dsp_init_x86(OpusDSP *ctx) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + ctx->postfilter = ff_opus_postfilter_fma3; + ctx->deemphasis = ff_opus_deemphasis_fma3; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/pixblockdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/pixblockdsp_init.c new file mode 100644 index 000000000..ade55e01a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/pixblockdsp_init.c @@ -0,0 +1,52 @@ +/* + * SIMD-optimized pixel operations + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/pixblockdsp.h" + +void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, ptrdiff_t stride); +void ff_get_pixels_sse2(int16_t *block, const uint8_t *pixels, ptrdiff_t stride); +void ff_diff_pixels_mmx(int16_t *block, const uint8_t *s1, const uint8_t *s2, + ptrdiff_t stride); +void ff_diff_pixels_sse2(int16_t *block, const uint8_t *s1, const uint8_t *s2, + ptrdiff_t stride); + +av_cold void ff_pixblockdsp_init_x86(PixblockDSPContext *c, + AVCodecContext *avctx, + unsigned high_bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + if (!high_bit_depth) + c->get_pixels = ff_get_pixels_mmx; + c->diff_pixels_unaligned = + c->diff_pixels = ff_diff_pixels_mmx; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + if (!high_bit_depth) + c->get_pixels = ff_get_pixels_sse2; + c->diff_pixels_unaligned = + c->diff_pixels = ff_diff_pixels_sse2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/pngdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/pngdsp_init.c new file mode 100644 index 000000000..7dca62c67 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/pngdsp_init.c @@ -0,0 +1,50 @@ +/* + * x86 PNG optimizations. + * Copyright (c) 2008 Loren Merrit + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/common.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/pngdsp.h" + +void ff_add_png_paeth_prediction_mmxext(uint8_t *dst, uint8_t *src, + uint8_t *top, int w, int bpp); +void ff_add_png_paeth_prediction_ssse3(uint8_t *dst, uint8_t *src, + uint8_t *top, int w, int bpp); +void ff_add_bytes_l2_mmx (uint8_t *dst, uint8_t *src1, + uint8_t *src2, int w); +void ff_add_bytes_l2_sse2(uint8_t *dst, uint8_t *src1, + uint8_t *src2, int w); + +av_cold void ff_pngdsp_init_x86(PNGDSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags)) + dsp->add_bytes_l2 = ff_add_bytes_l2_mmx; +#endif + if (EXTERNAL_MMXEXT(cpu_flags)) + dsp->add_paeth_prediction = ff_add_png_paeth_prediction_mmxext; + if (EXTERNAL_SSE2(cpu_flags)) + dsp->add_bytes_l2 = ff_add_bytes_l2_sse2; + if (EXTERNAL_SSSE3(cpu_flags)) + dsp->add_paeth_prediction = ff_add_png_paeth_prediction_ssse3; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/proresdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/proresdsp_init.c new file mode 100644 index 000000000..bde79ab8c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/proresdsp_init.c @@ -0,0 +1,50 @@ +/* + * Apple ProRes compatible decoder + * + * Copyright (c) 2010-2011 Maxim Poliakovski + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/idctdsp.h" +#include "libavcodec/proresdsp.h" + +void ff_prores_idct_put_10_sse2(uint16_t *dst, ptrdiff_t linesize, + int16_t *block, const int16_t *qmat); +void ff_prores_idct_put_10_avx (uint16_t *dst, ptrdiff_t linesize, + int16_t *block, const int16_t *qmat); + +av_cold void ff_proresdsp_init_x86(ProresDSPContext *dsp, AVCodecContext *avctx) +{ +#if ARCH_X86_64 + int cpu_flags = av_get_cpu_flags(); + + if (avctx->bits_per_raw_sample == 10){ + if (EXTERNAL_SSE2(cpu_flags)) { + dsp->idct_permutation_type = FF_IDCT_PERM_TRANSPOSE; + dsp->idct_put = ff_prores_idct_put_10_sse2; + } + + if (EXTERNAL_AVX(cpu_flags)) { + dsp->idct_permutation_type = FF_IDCT_PERM_TRANSPOSE; + dsp->idct_put = ff_prores_idct_put_10_avx; + } + } +#endif /* ARCH_X86_64 */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/qpeldsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/qpeldsp_init.c new file mode 100644 index 000000000..3b05e156c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/qpeldsp_init.c @@ -0,0 +1,544 @@ +/* + * quarterpel DSP functions + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/pixels.h" +#include "libavcodec/qpeldsp.h" +#include "fpel.h" + +void ff_put_pixels8_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_no_rnd_pixels8_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels8_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_pixels16_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels16_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_no_rnd_pixels16_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride, int h); +void ff_avg_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride, int h); +void ff_put_no_rnd_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, + const uint8_t *src, + int dstStride, int srcStride, + int h); +void ff_put_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride, int h); +void ff_avg_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride, int h); +void ff_put_no_rnd_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, + const uint8_t *src, + int dstStride, int srcStride, + int h); +void ff_put_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride); +void ff_avg_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride); +void ff_put_no_rnd_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, + const uint8_t *src, + int dstStride, int srcStride); +void ff_put_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride); +void ff_avg_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride); +void ff_put_no_rnd_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, + const uint8_t *src, + int dstStride, int srcStride); +#define ff_put_no_rnd_pixels16_mmxext ff_put_pixels16_mmx +#define ff_put_no_rnd_pixels8_mmxext ff_put_pixels8_mmx + +#if HAVE_X86ASM + +#define ff_put_pixels16_mmxext ff_put_pixels16_mmx +#define ff_put_pixels8_mmxext ff_put_pixels8_mmx + +#define QPEL_OP(OPNAME, RND, MMX) \ +static void OPNAME ## qpel8_mc00_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## pixels8_ ## MMX(dst, src, stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[8]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8, \ + stride, 8); \ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half, \ + stride, stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc20_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[8]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8, \ + stride, 8); \ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc01_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[8]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, \ + 8, stride); \ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half, \ + stride, stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc02_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src, \ + stride, stride); \ +} \ + \ +static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[8]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, \ + 8, stride); \ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,\ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc11_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc31_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc13_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc33_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc21_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc23_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc12_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, \ + 8, stride, 9); \ + ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc32_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \ + stride, 9); \ + ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[9]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel16_mc00_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## pixels16_ ## MMX(dst, src, stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[32]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16, \ + stride, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, \ + stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc20_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src, \ + stride, stride, 16);\ +} \ + \ +static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[32]; \ + uint8_t *const half = (uint8_t*) temp; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16, \ + stride, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half, \ + stride, stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc01_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[32]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16, \ + stride); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, \ + stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc02_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src, \ + stride, stride); \ +} \ + \ +static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[32]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16, \ + stride); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half, \ + stride, stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc11_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc31_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc13_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc33_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc21_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc23_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc12_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \ + stride, 17); \ + ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \ + stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc32_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \ + stride, 17); \ + ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \ + stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc22_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \ + stride, 16); \ +} + +QPEL_OP(put_, _, mmxext) +QPEL_OP(avg_, _, mmxext) +QPEL_OP(put_no_rnd_, _no_rnd_, mmxext) + +#endif /* HAVE_X86ASM */ + +#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX) \ +do { \ + c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \ +} while (0) + +av_cold void ff_qpeldsp_init_x86(QpelDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (X86_MMXEXT(cpu_flags)) { +#if HAVE_MMXEXT_EXTERNAL + SET_QPEL_FUNCS(avg_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(avg_qpel, 1, 8, mmxext, ); + + SET_QPEL_FUNCS(put_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(put_qpel, 1, 8, mmxext, ); + SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, mmxext, ); +#endif /* HAVE_MMXEXT_EXTERNAL */ + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rnd_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rnd_template.c new file mode 100644 index 000000000..09946bd23 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rnd_template.c @@ -0,0 +1,175 @@ +/* + * SIMD-optimized halfpel functions are compiled twice for rnd/no_rnd + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2003-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * mostly rewritten by Michael Niedermayer + * and improved by Zdenek Kabelac + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "inline_asm.h" + +// put_pixels +av_unused STATIC void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h) +{ + MOVQ_ZERO(mm7); + SET_RND(mm6); // =2 for rnd and =1 for no_rnd version + __asm__ volatile( + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm4 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "xor %%"FF_REG_a", %%"FF_REG_a" \n\t" + "add %3, %1 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + "movq 1(%1, %%"FF_REG_a"), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddusw %%mm2, %%mm0 \n\t" + "paddusw %%mm3, %%mm1 \n\t" + "paddusw %%mm6, %%mm4 \n\t" + "paddusw %%mm6, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "psrlw $2, %%mm4 \n\t" + "psrlw $2, %%mm5 \n\t" + "packuswb %%mm5, %%mm4 \n\t" + "movq %%mm4, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 + "movq 1(%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm2, %%mm4 \n\t" + "paddusw %%mm3, %%mm5 \n\t" + "paddusw %%mm6, %%mm0 \n\t" + "paddusw %%mm6, %%mm1 \n\t" + "paddusw %%mm4, %%mm0 \n\t" + "paddusw %%mm5, %%mm1 \n\t" + "psrlw $2, %%mm0 \n\t" + "psrlw $2, %%mm1 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "movq %%mm0, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "subl $2, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels) + :"D"(block), "r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +// avg_pixels +// this routine is 'slightly' suboptimal but mostly unused +av_unused STATIC void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h) +{ + MOVQ_ZERO(mm7); + SET_RND(mm6); // =2 for rnd and =1 for no_rnd version + __asm__ volatile( + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm4 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "xor %%"FF_REG_a", %%"FF_REG_a" \n\t" + "add %3, %1 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + "movq 1(%1, %%"FF_REG_a"), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddusw %%mm2, %%mm0 \n\t" + "paddusw %%mm3, %%mm1 \n\t" + "paddusw %%mm6, %%mm4 \n\t" + "paddusw %%mm6, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "psrlw $2, %%mm4 \n\t" + "psrlw $2, %%mm5 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "packuswb %%mm5, %%mm4 \n\t" + "pcmpeqd %%mm2, %%mm2 \n\t" + "paddb %%mm2, %%mm2 \n\t" + PAVGB_MMX(%%mm3, %%mm4, %%mm5, %%mm2) + "movq %%mm5, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 + "movq 1(%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm2, %%mm4 \n\t" + "paddusw %%mm3, %%mm5 \n\t" + "paddusw %%mm6, %%mm0 \n\t" + "paddusw %%mm6, %%mm1 \n\t" + "paddusw %%mm4, %%mm0 \n\t" + "paddusw %%mm5, %%mm1 \n\t" + "psrlw $2, %%mm0 \n\t" + "psrlw $2, %%mm1 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "pcmpeqd %%mm2, %%mm2 \n\t" + "paddb %%mm2, %%mm2 \n\t" + PAVGB_MMX(%%mm3, %%mm0, %%mm1, %%mm2) + "movq %%mm1, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "subl $2, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels) + :"D"(block), "r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rv34dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rv34dsp_init.c new file mode 100644 index 000000000..731012245 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rv34dsp_init.c @@ -0,0 +1,48 @@ +/* + * RV30/40 MMX/SSE2 optimizations + * Copyright (C) 2012 Christophe Gisquet + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/rv34dsp.h" + +void ff_rv34_idct_dc_mmxext(int16_t *block); +void ff_rv34_idct_dc_noround_mmxext(int16_t *block); +void ff_rv34_idct_dc_add_mmx(uint8_t *dst, ptrdiff_t stride, int dc); +void ff_rv34_idct_dc_add_sse2(uint8_t *dst, ptrdiff_t stride, int dc); +void ff_rv34_idct_dc_add_sse4(uint8_t *dst, ptrdiff_t stride, int dc); +void ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, int16_t *block); + +av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) + c->rv34_idct_dc_add = ff_rv34_idct_dc_add_mmx; + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->rv34_inv_transform_dc = ff_rv34_idct_dc_noround_mmxext; + c->rv34_idct_add = ff_rv34_idct_add_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) + c->rv34_idct_dc_add = ff_rv34_idct_dc_add_sse2; + if (EXTERNAL_SSE4(cpu_flags)) + c->rv34_idct_dc_add = ff_rv34_idct_dc_add_sse4; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rv40dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rv40dsp_init.c new file mode 100644 index 000000000..b57a3fc31 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/rv40dsp_init.c @@ -0,0 +1,278 @@ +/* + * RV40 decoder motion compensation functions x86-optimised + * Copyright (c) 2008 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * RV40 decoder motion compensation functions x86-optimised + * 2,0 and 0,2 have h264 equivalents. + * 3,3 is bugged in the rv40 format and maps to _xy2 version + */ + +#include "libavcodec/rv34dsp.h" +#include "libavutil/attributes.h" +#include "libavutil/mem.h" +#include "libavutil/x86/cpu.h" +#include "hpeldsp.h" + +#define DEFINE_FN(op, size, insn) \ +static void op##_rv40_qpel##size##_mc33_##insn(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_##op##_pixels##size##_xy2_##insn(dst, src, stride, size); \ +} + +#if HAVE_X86ASM +void ff_put_rv40_chroma_mc8_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_rv40_chroma_mc8_mmxext(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_rv40_chroma_mc8_3dnow(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_put_rv40_chroma_mc4_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_rv40_chroma_mc4_mmxext(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_rv40_chroma_mc4_3dnow(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +#define DECLARE_WEIGHT(opt) \ +void ff_rv40_weight_func_rnd_16_##opt(uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, ptrdiff_t stride); \ +void ff_rv40_weight_func_rnd_8_##opt (uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, ptrdiff_t stride); \ +void ff_rv40_weight_func_nornd_16_##opt(uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, ptrdiff_t stride); \ +void ff_rv40_weight_func_nornd_8_##opt (uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, ptrdiff_t stride); +DECLARE_WEIGHT(mmxext) +DECLARE_WEIGHT(sse2) +DECLARE_WEIGHT(ssse3) + +/** @{ */ +/** + * Define one qpel function. + * LOOPSIZE must be already set to the number of pixels processed per + * iteration in the inner loop of the called functions. + * COFF(x) must be already defined so as to provide the offset into any + * array of coeffs used by the called function for the qpel position x. + */ +#define QPEL_FUNC_DECL(OP, SIZE, PH, PV, OPT) \ +static void OP ## rv40_qpel ##SIZE ##_mc ##PH ##PV ##OPT(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + int i; \ + if (PH && PV) { \ + LOCAL_ALIGNED(16, uint8_t, tmp, [SIZE * (SIZE + 5)]); \ + uint8_t *tmpptr = tmp + SIZE * 2; \ + src -= stride * 2; \ + \ + for (i = 0; i < SIZE; i += LOOPSIZE) \ + ff_put_rv40_qpel_h ##OPT(tmp + i, SIZE, src + i, stride, \ + SIZE + 5, HCOFF(PH)); \ + for (i = 0; i < SIZE; i += LOOPSIZE) \ + ff_ ##OP ##rv40_qpel_v ##OPT(dst + i, stride, tmpptr + i, \ + SIZE, SIZE, VCOFF(PV)); \ + } else if (PV) { \ + for (i = 0; i < SIZE; i += LOOPSIZE) \ + ff_ ##OP ##rv40_qpel_v ## OPT(dst + i, stride, src + i, \ + stride, SIZE, VCOFF(PV)); \ + } else { \ + for (i = 0; i < SIZE; i += LOOPSIZE) \ + ff_ ##OP ##rv40_qpel_h ## OPT(dst + i, stride, src + i, \ + stride, SIZE, HCOFF(PH)); \ + } \ +} + +/** Declare functions for sizes 8 and 16 and given operations + * and qpel position. */ +#define QPEL_FUNCS_DECL(OP, PH, PV, OPT) \ + QPEL_FUNC_DECL(OP, 8, PH, PV, OPT) \ + QPEL_FUNC_DECL(OP, 16, PH, PV, OPT) + +/** Declare all functions for all sizes and qpel positions */ +#define QPEL_MC_DECL(OP, OPT) \ +void ff_ ##OP ##rv40_qpel_h ##OPT(uint8_t *dst, ptrdiff_t dstStride, \ + const uint8_t *src, \ + ptrdiff_t srcStride, \ + int len, int m); \ +void ff_ ##OP ##rv40_qpel_v ##OPT(uint8_t *dst, ptrdiff_t dstStride, \ + const uint8_t *src, \ + ptrdiff_t srcStride, \ + int len, int m); \ +QPEL_FUNCS_DECL(OP, 0, 1, OPT) \ +QPEL_FUNCS_DECL(OP, 0, 3, OPT) \ +QPEL_FUNCS_DECL(OP, 1, 0, OPT) \ +QPEL_FUNCS_DECL(OP, 1, 1, OPT) \ +QPEL_FUNCS_DECL(OP, 1, 2, OPT) \ +QPEL_FUNCS_DECL(OP, 1, 3, OPT) \ +QPEL_FUNCS_DECL(OP, 2, 1, OPT) \ +QPEL_FUNCS_DECL(OP, 2, 2, OPT) \ +QPEL_FUNCS_DECL(OP, 2, 3, OPT) \ +QPEL_FUNCS_DECL(OP, 3, 0, OPT) \ +QPEL_FUNCS_DECL(OP, 3, 1, OPT) \ +QPEL_FUNCS_DECL(OP, 3, 2, OPT) +/** @} */ + +#define LOOPSIZE 8 +#define HCOFF(x) (32 * ((x) - 1)) +#define VCOFF(x) (32 * ((x) - 1)) +QPEL_MC_DECL(put_, _ssse3) +QPEL_MC_DECL(avg_, _ssse3) + +#undef LOOPSIZE +#undef HCOFF +#undef VCOFF +#define LOOPSIZE 8 +#define HCOFF(x) (64 * ((x) - 1)) +#define VCOFF(x) (64 * ((x) - 1)) +QPEL_MC_DECL(put_, _sse2) +QPEL_MC_DECL(avg_, _sse2) + +#if ARCH_X86_32 +#undef LOOPSIZE +#undef HCOFF +#undef VCOFF +#define LOOPSIZE 4 +#define HCOFF(x) (64 * ((x) - 1)) +#define VCOFF(x) (64 * ((x) - 1)) + +QPEL_MC_DECL(put_, _mmx) + +#define ff_put_rv40_qpel_h_mmxext ff_put_rv40_qpel_h_mmx +#define ff_put_rv40_qpel_v_mmxext ff_put_rv40_qpel_v_mmx +QPEL_MC_DECL(avg_, _mmxext) + +#define ff_put_rv40_qpel_h_3dnow ff_put_rv40_qpel_h_mmx +#define ff_put_rv40_qpel_v_3dnow ff_put_rv40_qpel_v_mmx +QPEL_MC_DECL(avg_, _3dnow) +#endif + +/** @{ */ +/** Set one function */ +#define QPEL_FUNC_SET(OP, SIZE, PH, PV, OPT) \ + c-> OP ## pixels_tab[2 - SIZE / 8][4 * PV + PH] = OP ## rv40_qpel ##SIZE ## _mc ##PH ##PV ##OPT; + +/** Set functions put and avg for sizes 8 and 16 and a given qpel position */ +#define QPEL_FUNCS_SET(OP, PH, PV, OPT) \ + QPEL_FUNC_SET(OP, 8, PH, PV, OPT) \ + QPEL_FUNC_SET(OP, 16, PH, PV, OPT) + +/** Set all functions for all sizes and qpel positions */ +#define QPEL_MC_SET(OP, OPT) \ +QPEL_FUNCS_SET (OP, 0, 1, OPT) \ +QPEL_FUNCS_SET (OP, 0, 3, OPT) \ +QPEL_FUNCS_SET (OP, 1, 0, OPT) \ +QPEL_FUNCS_SET (OP, 1, 1, OPT) \ +QPEL_FUNCS_SET (OP, 1, 2, OPT) \ +QPEL_FUNCS_SET (OP, 1, 3, OPT) \ +QPEL_FUNCS_SET (OP, 2, 1, OPT) \ +QPEL_FUNCS_SET (OP, 2, 2, OPT) \ +QPEL_FUNCS_SET (OP, 2, 3, OPT) \ +QPEL_FUNCS_SET (OP, 3, 0, OPT) \ +QPEL_FUNCS_SET (OP, 3, 1, OPT) \ +QPEL_FUNCS_SET (OP, 3, 2, OPT) +/** @} */ + +DEFINE_FN(put, 8, ssse3) + +DEFINE_FN(put, 16, sse2) +DEFINE_FN(put, 16, ssse3) + +DEFINE_FN(avg, 8, mmxext) +DEFINE_FN(avg, 8, ssse3) + +DEFINE_FN(avg, 16, sse2) +DEFINE_FN(avg, 16, ssse3) +#endif /* HAVE_X86ASM */ + +#if HAVE_MMX_INLINE +DEFINE_FN(put, 8, mmx) +DEFINE_FN(avg, 8, mmx) +DEFINE_FN(put, 16, mmx) +DEFINE_FN(avg, 16, mmx) +#endif + +av_cold void ff_rv40dsp_init_x86(RV34DSPContext *c) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + +#if HAVE_MMX_INLINE + if (INLINE_MMX(cpu_flags)) { + c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_mmx; + c->put_pixels_tab[1][15] = put_rv40_qpel8_mc33_mmx; + c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_mmx; + c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_mmx; + } +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_X86ASM + if (EXTERNAL_MMX(cpu_flags)) { + c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx; + c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx; +#if ARCH_X86_32 + QPEL_MC_SET(put_, _mmx) +#endif + } + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow; + c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow; +#if ARCH_X86_32 + QPEL_MC_SET(avg_, _3dnow) +#endif + } + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_mmxext; + c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_mmxext; + c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_mmxext; + c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_mmxext; + c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_mmxext; + c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_mmxext; + c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_mmxext; +#if ARCH_X86_32 + QPEL_MC_SET(avg_, _mmxext) +#endif + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_sse2; + c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_sse2; + c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_sse2; + c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_sse2; + c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_sse2; + c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_sse2; + QPEL_MC_SET(put_, _sse2) + QPEL_MC_SET(avg_, _sse2) + } + if (EXTERNAL_SSSE3(cpu_flags)) { + c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_ssse3; + c->put_pixels_tab[1][15] = put_rv40_qpel8_mc33_ssse3; + c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_ssse3; + c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_ssse3; + c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_ssse3; + c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_ssse3; + c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_ssse3; + c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_ssse3; + QPEL_MC_SET(put_, _ssse3) + QPEL_MC_SET(avg_, _ssse3) + } +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbcdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbcdsp_init.c new file mode 100644 index 000000000..86effecfd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbcdsp_init.c @@ -0,0 +1,51 @@ +/* + * Bluetooth low-complexity, subband codec (SBC) + * + * Copyright (C) 2017 Aurelien Jacobs + * Copyright (C) 2008-2010 Nokia Corporation + * Copyright (C) 2004-2010 Marcel Holtmann + * Copyright (C) 2004-2005 Henryk Ploetz + * Copyright (C) 2005-2006 Brad Midgley + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * SBC MMX optimization for some basic "building bricks" + */ + +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/sbcdsp.h" + +void ff_sbc_analyze_4_mmx(const int16_t *in, int32_t *out, const int16_t *consts); +void ff_sbc_analyze_8_mmx(const int16_t *in, int32_t *out, const int16_t *consts); +void ff_sbc_calc_scalefactors_mmx(int32_t sb_sample_f[16][2][8], + uint32_t scale_factor[2][8], + int blocks, int channels, int subbands); + +av_cold void ff_sbcdsp_init_x86(SBCDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + s->sbc_analyze_4 = ff_sbc_analyze_4_mmx; + s->sbc_analyze_8 = ff_sbc_analyze_8_mmx; + s->sbc_calc_scalefactors = ff_sbc_calc_scalefactors_mmx; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbrdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbrdsp_init.c new file mode 100644 index 000000000..6911a1a51 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbrdsp_init.c @@ -0,0 +1,87 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2012 Christophe Gisquet + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/sbrdsp.h" + +float ff_sbr_sum_square_sse(float (*x)[2], int n); +void ff_sbr_sum64x5_sse(float *z); +void ff_sbr_hf_g_filt_sse(float (*Y)[2], const float (*X_high)[40][2], + const float *g_filt, int m_max, intptr_t ixh); +void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2], + const float alpha0[2], const float alpha1[2], + float bw, int start, int end); +void ff_sbr_neg_odd_64_sse(float *z); +void ff_sbr_qmf_post_shuffle_sse(float W[32][2], const float *z); +void ff_sbr_qmf_deint_bfly_sse(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_pre_shuffle_sse2(float *z); + +void ff_sbr_hf_apply_noise_0_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_1_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_2_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_3_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); + +void ff_sbr_qmf_deint_neg_sse(float *v, const float *src); + +void ff_sbr_autocorrelate_sse (const float x[40][2], float phi[3][2][2]); +void ff_sbr_autocorrelate_sse3(const float x[40][2], float phi[3][2][2]); + +av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + s->neg_odd_64 = ff_sbr_neg_odd_64_sse; + s->sum_square = ff_sbr_sum_square_sse; + s->sum64x5 = ff_sbr_sum64x5_sse; + s->hf_g_filt = ff_sbr_hf_g_filt_sse; + s->hf_gen = ff_sbr_hf_gen_sse; + s->qmf_post_shuffle = ff_sbr_qmf_post_shuffle_sse; + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse; + s->qmf_deint_neg = ff_sbr_qmf_deint_neg_sse; + s->autocorrelate = ff_sbr_autocorrelate_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse2; + s->qmf_pre_shuffle = ff_sbr_qmf_pre_shuffle_sse2; + s->hf_apply_noise[0] = ff_sbr_hf_apply_noise_0_sse2; + s->hf_apply_noise[1] = ff_sbr_hf_apply_noise_1_sse2; + s->hf_apply_noise[2] = ff_sbr_hf_apply_noise_2_sse2; + s->hf_apply_noise[3] = ff_sbr_hf_apply_noise_3_sse2; + } + + if (EXTERNAL_SSE3(cpu_flags)) { + s->autocorrelate = ff_sbr_autocorrelate_sse3; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/simple_idct.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/simple_idct.h new file mode 100644 index 000000000..9b64cfe9b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/simple_idct.h @@ -0,0 +1,53 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_SIMPLE_IDCT_H +#define AVCODEC_X86_SIMPLE_IDCT_H + +#include +#include + +void ff_simple_idct_mmx(int16_t *block); +void ff_simple_idct_add_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_put_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct_add_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_put_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct8_sse2(int16_t *block); +void ff_simple_idct8_avx(int16_t *block); + +void ff_simple_idct8_put_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct8_put_avx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct8_add_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct8_add_avx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct10_sse2(int16_t *block); +void ff_simple_idct10_avx(int16_t *block); + +void ff_simple_idct10_put_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct10_put_avx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct12_sse2(int16_t *block); +void ff_simple_idct12_avx(int16_t *block); + +void ff_simple_idct12_put_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct12_put_avx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +#endif /* AVCODEC_X86_SIMPLE_IDCT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/snowdsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/snowdsp.c new file mode 100644 index 000000000..218e6864d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/snowdsp.c @@ -0,0 +1,908 @@ +/* + * MMX and SSE2 optimized snow DSP utils + * Copyright (c) 2005-2006 Robert Edele + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/snow.h" +#include "libavcodec/snow_dwt.h" + +#if HAVE_INLINE_ASM + +static void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, IDWTELEM *temp, int width){ + const int w2= (width+1)>>1; + const int w_l= (width>>1); + const int w_r= w2 - 1; + int i; + + { // Lift 0 + IDWTELEM * const ref = b + w2 - 1; + IDWTELEM b_0 = b[0]; //By allowing the first entry in b[0] to be calculated twice + // (the first time erroneously), we allow the SSE2 code to run an extra pass. + // The savings in code and time are well worth having to store this value and + // calculate b[0] correctly afterwards. + + i = 0; + __asm__ volatile( + "pcmpeqd %%xmm7, %%xmm7 \n\t" + "pcmpeqd %%xmm3, %%xmm3 \n\t" + "psllw $1, %%xmm3 \n\t" + "paddw %%xmm7, %%xmm3 \n\t" + "psllw $13, %%xmm3 \n\t" + ::); + for(; i>W_DS); + } + + { // Lift 1 + IDWTELEM * const dst = b+w2; + + i = 0; + for(; (((x86_reg)&dst[i]) & 0x1F) && i> W_BS); + } + + { // Lift 3 + IDWTELEM * const src = b+w2; + + i = 0; + for(; (((x86_reg)&temp[i]) & 0x1F) && i>W_AS); + } + for(; i>1]; + b[i] = b[i>>1]; + } + for (i-=62; i>=0; i-=64){ + __asm__ volatile( + "movdqa (%1), %%xmm0 \n\t" + "movdqa 16(%1), %%xmm2 \n\t" + "movdqa 32(%1), %%xmm4 \n\t" + "movdqa 48(%1), %%xmm6 \n\t" + "movdqa (%1), %%xmm1 \n\t" + "movdqa 16(%1), %%xmm3 \n\t" + "movdqa 32(%1), %%xmm5 \n\t" + "movdqa 48(%1), %%xmm7 \n\t" + "punpcklwd (%2), %%xmm0 \n\t" + "punpcklwd 16(%2), %%xmm2 \n\t" + "punpcklwd 32(%2), %%xmm4 \n\t" + "punpcklwd 48(%2), %%xmm6 \n\t" + "movdqa %%xmm0, (%0) \n\t" + "movdqa %%xmm2, 32(%0) \n\t" + "movdqa %%xmm4, 64(%0) \n\t" + "movdqa %%xmm6, 96(%0) \n\t" + "punpckhwd (%2), %%xmm1 \n\t" + "punpckhwd 16(%2), %%xmm3 \n\t" + "punpckhwd 32(%2), %%xmm5 \n\t" + "punpckhwd 48(%2), %%xmm7 \n\t" + "movdqa %%xmm1, 16(%0) \n\t" + "movdqa %%xmm3, 48(%0) \n\t" + "movdqa %%xmm5, 80(%0) \n\t" + "movdqa %%xmm7, 112(%0) \n\t" + :: "r"(&(b)[i]), "r"(&(b)[i>>1]), "r"(&(temp)[i>>1]) + : "memory" + ); + } + } +} + +static void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, IDWTELEM *temp, int width){ + const int w2= (width+1)>>1; + const int w_l= (width>>1); + const int w_r= w2 - 1; + int i; + + { // Lift 0 + IDWTELEM * const ref = b + w2 - 1; + + i = 1; + b[0] = b[0] - ((W_DM * 2 * ref[1]+W_DO)>>W_DS); + __asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "pcmpeqw %%mm3, %%mm3 \n\t" + "psllw $1, %%mm3 \n\t" + "paddw %%mm7, %%mm3 \n\t" + "psllw $13, %%mm3 \n\t" + ::); + for(; i> W_BS); + __asm__ volatile( + "psllw $15, %%mm7 \n\t" + "pcmpeqw %%mm6, %%mm6 \n\t" + "psrlw $13, %%mm6 \n\t" + "paddw %%mm7, %%mm6 \n\t" + ::); + for(; i>1]; + b[i] = b[i>>1]; + } + for (i-=30; i>=0; i-=32){ + __asm__ volatile( + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm2 \n\t" + "movq 16(%1), %%mm4 \n\t" + "movq 24(%1), %%mm6 \n\t" + "movq (%1), %%mm1 \n\t" + "movq 8(%1), %%mm3 \n\t" + "movq 16(%1), %%mm5 \n\t" + "movq 24(%1), %%mm7 \n\t" + "punpcklwd (%2), %%mm0 \n\t" + "punpcklwd 8(%2), %%mm2 \n\t" + "punpcklwd 16(%2), %%mm4 \n\t" + "punpcklwd 24(%2), %%mm6 \n\t" + "movq %%mm0, (%0) \n\t" + "movq %%mm2, 16(%0) \n\t" + "movq %%mm4, 32(%0) \n\t" + "movq %%mm6, 48(%0) \n\t" + "punpckhwd (%2), %%mm1 \n\t" + "punpckhwd 8(%2), %%mm3 \n\t" + "punpckhwd 16(%2), %%mm5 \n\t" + "punpckhwd 24(%2), %%mm7 \n\t" + "movq %%mm1, 8(%0) \n\t" + "movq %%mm3, 24(%0) \n\t" + "movq %%mm5, 40(%0) \n\t" + "movq %%mm7, 56(%0) \n\t" + :: "r"(&b[i]), "r"(&b[i>>1]), "r"(&temp[i>>1]) + : "memory" + ); + } + } +} + +#if HAVE_7REGS +#define snow_vertical_compose_sse2_load_add(op,r,t0,t1,t2,t3)\ + ""op" ("r",%%"FF_REG_d"), %%"t0" \n\t"\ + ""op" 16("r",%%"FF_REG_d"), %%"t1" \n\t"\ + ""op" 32("r",%%"FF_REG_d"), %%"t2" \n\t"\ + ""op" 48("r",%%"FF_REG_d"), %%"t3" \n\t" + +#define snow_vertical_compose_sse2_load(r,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_load_add("movdqa",r,t0,t1,t2,t3) + +#define snow_vertical_compose_sse2_add(r,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_load_add("paddw",r,t0,t1,t2,t3) + +#define snow_vertical_compose_r2r_sub(s0,s1,s2,s3,t0,t1,t2,t3)\ + "psubw %%"s0", %%"t0" \n\t"\ + "psubw %%"s1", %%"t1" \n\t"\ + "psubw %%"s2", %%"t2" \n\t"\ + "psubw %%"s3", %%"t3" \n\t" + +#define snow_vertical_compose_sse2_store(w,s0,s1,s2,s3)\ + "movdqa %%"s0", ("w",%%"FF_REG_d") \n\t"\ + "movdqa %%"s1", 16("w",%%"FF_REG_d") \n\t"\ + "movdqa %%"s2", 32("w",%%"FF_REG_d") \n\t"\ + "movdqa %%"s3", 48("w",%%"FF_REG_d") \n\t" + +#define snow_vertical_compose_sra(n,t0,t1,t2,t3)\ + "psraw $"n", %%"t0" \n\t"\ + "psraw $"n", %%"t1" \n\t"\ + "psraw $"n", %%"t2" \n\t"\ + "psraw $"n", %%"t3" \n\t" + +#define snow_vertical_compose_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3)\ + "paddw %%"s0", %%"t0" \n\t"\ + "paddw %%"s1", %%"t1" \n\t"\ + "paddw %%"s2", %%"t2" \n\t"\ + "paddw %%"s3", %%"t3" \n\t" + +#define snow_vertical_compose_r2r_pmulhw(s0,s1,s2,s3,t0,t1,t2,t3)\ + "pmulhw %%"s0", %%"t0" \n\t"\ + "pmulhw %%"s1", %%"t1" \n\t"\ + "pmulhw %%"s2", %%"t2" \n\t"\ + "pmulhw %%"s3", %%"t3" \n\t" + +#define snow_vertical_compose_sse2_move(s0,s1,s2,s3,t0,t1,t2,t3)\ + "movdqa %%"s0", %%"t0" \n\t"\ + "movdqa %%"s1", %%"t1" \n\t"\ + "movdqa %%"s2", %%"t2" \n\t"\ + "movdqa %%"s3", %%"t3" \n\t" + +static void ff_snow_vertical_compose97i_sse2(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ + x86_reg i = width; + + while(i & 0x1F) + { + i--; + b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; + b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; + b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; + b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; + } + i+=i; + + __asm__ volatile ( + "jmp 2f \n\t" + "1: \n\t" + snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%6","xmm0","xmm2","xmm4","xmm6") + + + "pcmpeqw %%xmm0, %%xmm0 \n\t" + "pcmpeqw %%xmm2, %%xmm2 \n\t" + "paddw %%xmm2, %%xmm2 \n\t" + "paddw %%xmm0, %%xmm2 \n\t" + "psllw $13, %%xmm2 \n\t" + snow_vertical_compose_r2r_add("xmm0","xmm0","xmm0","xmm0","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_r2r_pmulhw("xmm2","xmm2","xmm2","xmm2","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_add("%5","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_store("%5","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%3","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_r2r_sub("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store("%4","xmm0","xmm2","xmm4","xmm6") + + "pcmpeqw %%xmm7, %%xmm7 \n\t" + "pcmpeqw %%xmm5, %%xmm5 \n\t" + "psllw $15, %%xmm7 \n\t" + "psrlw $13, %%xmm5 \n\t" + "paddw %%xmm7, %%xmm5 \n\t" + snow_vertical_compose_r2r_add("xmm5","xmm5","xmm5","xmm5","xmm0","xmm2","xmm4","xmm6") + "movq (%2,%%"FF_REG_d"), %%xmm1 \n\t" + "movq 8(%2,%%"FF_REG_d"), %%xmm3 \n\t" + "paddw %%xmm7, %%xmm1 \n\t" + "paddw %%xmm7, %%xmm3 \n\t" + "pavgw %%xmm1, %%xmm0 \n\t" + "pavgw %%xmm3, %%xmm2 \n\t" + "movq 16(%2,%%"FF_REG_d"), %%xmm1 \n\t" + "movq 24(%2,%%"FF_REG_d"), %%xmm3 \n\t" + "paddw %%xmm7, %%xmm1 \n\t" + "paddw %%xmm7, %%xmm3 \n\t" + "pavgw %%xmm1, %%xmm4 \n\t" + "pavgw %%xmm3, %%xmm6 \n\t" + snow_vertical_compose_r2r_sub("xmm7","xmm7","xmm7","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6") + + snow_vertical_compose_sra("2","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store("%3","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_move("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%2","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store("%2","xmm0","xmm2","xmm4","xmm6") + + "2: \n\t" + "sub $64, %%"FF_REG_d" \n\t" + "jge 1b \n\t" + :"+d"(i) + :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5)); +} + +#define snow_vertical_compose_mmx_load_add(op,r,t0,t1,t2,t3)\ + ""op" ("r",%%"FF_REG_d"), %%"t0" \n\t"\ + ""op" 8("r",%%"FF_REG_d"), %%"t1" \n\t"\ + ""op" 16("r",%%"FF_REG_d"), %%"t2" \n\t"\ + ""op" 24("r",%%"FF_REG_d"), %%"t3" \n\t" + +#define snow_vertical_compose_mmx_load(r,t0,t1,t2,t3)\ + snow_vertical_compose_mmx_load_add("movq",r,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_add(r,t0,t1,t2,t3)\ + snow_vertical_compose_mmx_load_add("paddw",r,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_store(w,s0,s1,s2,s3)\ + "movq %%"s0", ("w",%%"FF_REG_d") \n\t"\ + "movq %%"s1", 8("w",%%"FF_REG_d") \n\t"\ + "movq %%"s2", 16("w",%%"FF_REG_d") \n\t"\ + "movq %%"s3", 24("w",%%"FF_REG_d") \n\t" + +#define snow_vertical_compose_mmx_move(s0,s1,s2,s3,t0,t1,t2,t3)\ + "movq %%"s0", %%"t0" \n\t"\ + "movq %%"s1", %%"t1" \n\t"\ + "movq %%"s2", %%"t2" \n\t"\ + "movq %%"s3", %%"t3" \n\t" + + +static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ + x86_reg i = width; + while(i & 15) + { + i--; + b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; + b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; + b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; + b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; + } + i+=i; + __asm__ volatile( + "jmp 2f \n\t" + "1: \n\t" + + snow_vertical_compose_mmx_load("%4","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_add("%6","mm1","mm3","mm5","mm7") + "pcmpeqw %%mm0, %%mm0 \n\t" + "pcmpeqw %%mm2, %%mm2 \n\t" + "paddw %%mm2, %%mm2 \n\t" + "paddw %%mm0, %%mm2 \n\t" + "psllw $13, %%mm2 \n\t" + snow_vertical_compose_r2r_add("mm0","mm0","mm0","mm0","mm1","mm3","mm5","mm7") + snow_vertical_compose_r2r_pmulhw("mm2","mm2","mm2","mm2","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_add("%5","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_store("%5","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_load("%4","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%3","mm1","mm3","mm5","mm7") + snow_vertical_compose_r2r_sub("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store("%4","mm0","mm2","mm4","mm6") + "pcmpeqw %%mm7, %%mm7 \n\t" + "pcmpeqw %%mm5, %%mm5 \n\t" + "psllw $15, %%mm7 \n\t" + "psrlw $13, %%mm5 \n\t" + "paddw %%mm7, %%mm5 \n\t" + snow_vertical_compose_r2r_add("mm5","mm5","mm5","mm5","mm0","mm2","mm4","mm6") + "movq (%2,%%"FF_REG_d"), %%mm1 \n\t" + "movq 8(%2,%%"FF_REG_d"), %%mm3 \n\t" + "paddw %%mm7, %%mm1 \n\t" + "paddw %%mm7, %%mm3 \n\t" + "pavgw %%mm1, %%mm0 \n\t" + "pavgw %%mm3, %%mm2 \n\t" + "movq 16(%2,%%"FF_REG_d"), %%mm1 \n\t" + "movq 24(%2,%%"FF_REG_d"), %%mm3 \n\t" + "paddw %%mm7, %%mm1 \n\t" + "paddw %%mm7, %%mm3 \n\t" + "pavgw %%mm1, %%mm4 \n\t" + "pavgw %%mm3, %%mm6 \n\t" + snow_vertical_compose_r2r_sub("mm7","mm7","mm7","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6") + + snow_vertical_compose_sra("2","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store("%3","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_move("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7") + snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6") + snow_vertical_compose_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%2","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store("%2","mm0","mm2","mm4","mm6") + + "2: \n\t" + "sub $32, %%"FF_REG_d" \n\t" + "jge 1b \n\t" + :"+d"(i) + :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5)); +} +#endif //HAVE_7REGS + +#if HAVE_6REGS +#define snow_inner_add_yblock_sse2_header \ + IDWTELEM * * dst_array = sb->line + src_y;\ + x86_reg tmp;\ + __asm__ volatile(\ + "mov %7, %%"FF_REG_c" \n\t"\ + "mov %6, %2 \n\t"\ + "mov %4, %%"FF_REG_S" \n\t"\ + "pxor %%xmm7, %%xmm7 \n\t" /* 0 */\ + "pcmpeqd %%xmm3, %%xmm3 \n\t"\ + "psllw $15, %%xmm3 \n\t"\ + "psrlw $12, %%xmm3 \n\t" /* FRAC_BITS >> 1 */\ + "1: \n\t"\ + "mov %1, %%"FF_REG_D" \n\t"\ + "mov (%%"FF_REG_D"), %%"FF_REG_D" \n\t"\ + "add %3, %%"FF_REG_D" \n\t" + +#define snow_inner_add_yblock_sse2_start_8(out_reg1, out_reg2, ptr_offset, s_offset)\ + "mov "FF_PTR_SIZE"*"ptr_offset"(%%"FF_REG_a"), %%"FF_REG_d"; \n\t"\ + "movq (%%"FF_REG_d"), %%"out_reg1" \n\t"\ + "movq (%%"FF_REG_d", %%"FF_REG_c"), %%"out_reg2" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg1" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg2" \n\t"\ + "movq "s_offset"(%%"FF_REG_S"), %%xmm0 \n\t"\ + "movq "s_offset"+16(%%"FF_REG_S"), %%xmm4 \n\t"\ + "punpcklbw %%xmm7, %%xmm0 \n\t"\ + "punpcklbw %%xmm7, %%xmm4 \n\t"\ + "pmullw %%xmm0, %%"out_reg1" \n\t"\ + "pmullw %%xmm4, %%"out_reg2" \n\t" + +#define snow_inner_add_yblock_sse2_start_16(out_reg1, out_reg2, ptr_offset, s_offset)\ + "mov "FF_PTR_SIZE"*"ptr_offset"(%%"FF_REG_a"), %%"FF_REG_d"; \n\t"\ + "movq (%%"FF_REG_d"), %%"out_reg1" \n\t"\ + "movq 8(%%"FF_REG_d"), %%"out_reg2" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg1" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg2" \n\t"\ + "movq "s_offset"(%%"FF_REG_S"), %%xmm0 \n\t"\ + "movq "s_offset"+8(%%"FF_REG_S"), %%xmm4 \n\t"\ + "punpcklbw %%xmm7, %%xmm0 \n\t"\ + "punpcklbw %%xmm7, %%xmm4 \n\t"\ + "pmullw %%xmm0, %%"out_reg1" \n\t"\ + "pmullw %%xmm4, %%"out_reg2" \n\t" + +#define snow_inner_add_yblock_sse2_accum_8(ptr_offset, s_offset) \ + snow_inner_add_yblock_sse2_start_8("xmm2", "xmm6", ptr_offset, s_offset)\ + "paddusw %%xmm2, %%xmm1 \n\t"\ + "paddusw %%xmm6, %%xmm5 \n\t" + +#define snow_inner_add_yblock_sse2_accum_16(ptr_offset, s_offset) \ + snow_inner_add_yblock_sse2_start_16("xmm2", "xmm6", ptr_offset, s_offset)\ + "paddusw %%xmm2, %%xmm1 \n\t"\ + "paddusw %%xmm6, %%xmm5 \n\t" + +#define snow_inner_add_yblock_sse2_end_common1\ + "add $32, %%"FF_REG_S" \n\t"\ + "add %%"FF_REG_c", %0 \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*3(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*2(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*1(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", (%%"FF_REG_a") \n\t" + +#define snow_inner_add_yblock_sse2_end_common2\ + "jnz 1b \n\t"\ + :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\ + :\ + "rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\ + XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", )\ + "%"FF_REG_c"","%"FF_REG_S"","%"FF_REG_D"","%"FF_REG_d""); + +#define snow_inner_add_yblock_sse2_end_8\ + "sal $1, %%"FF_REG_c" \n\t"\ + "add"FF_OPSIZE" $"FF_PTR_SIZE"*2, %1 \n\t"\ + snow_inner_add_yblock_sse2_end_common1\ + "sar $1, %%"FF_REG_c" \n\t"\ + "sub $2, %2 \n\t"\ + snow_inner_add_yblock_sse2_end_common2 + +#define snow_inner_add_yblock_sse2_end_16\ + "add"FF_OPSIZE" $"FF_PTR_SIZE"*1, %1 \n\t"\ + snow_inner_add_yblock_sse2_end_common1\ + "dec %2 \n\t"\ + snow_inner_add_yblock_sse2_end_common2 + +static void inner_add_yblock_bw_8_obmc_16_bh_even_sse2(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, + int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_sse2_header +snow_inner_add_yblock_sse2_start_8("xmm1", "xmm5", "3", "0") +snow_inner_add_yblock_sse2_accum_8("2", "8") +snow_inner_add_yblock_sse2_accum_8("1", "128") +snow_inner_add_yblock_sse2_accum_8("0", "136") + + "mov %0, %%"FF_REG_d" \n\t" + "movdqa (%%"FF_REG_D"), %%xmm0 \n\t" + "movdqa %%xmm1, %%xmm2 \n\t" + + "punpckhwd %%xmm7, %%xmm1 \n\t" + "punpcklwd %%xmm7, %%xmm2 \n\t" + "paddd %%xmm2, %%xmm0 \n\t" + "movdqa 16(%%"FF_REG_D"), %%xmm2\n\t" + "paddd %%xmm1, %%xmm2 \n\t" + "paddd %%xmm3, %%xmm0 \n\t" + "paddd %%xmm3, %%xmm2 \n\t" + + "mov %1, %%"FF_REG_D" \n\t" + "mov "FF_PTR_SIZE"(%%"FF_REG_D"), %%"FF_REG_D"; \n\t" + "add %3, %%"FF_REG_D" \n\t" + + "movdqa (%%"FF_REG_D"), %%xmm4 \n\t" + "movdqa %%xmm5, %%xmm6 \n\t" + "punpckhwd %%xmm7, %%xmm5 \n\t" + "punpcklwd %%xmm7, %%xmm6 \n\t" + "paddd %%xmm6, %%xmm4 \n\t" + "movdqa 16(%%"FF_REG_D"), %%xmm6\n\t" + "paddd %%xmm5, %%xmm6 \n\t" + "paddd %%xmm3, %%xmm4 \n\t" + "paddd %%xmm3, %%xmm6 \n\t" + + "psrad $8, %%xmm0 \n\t" /* FRAC_BITS. */ + "psrad $8, %%xmm2 \n\t" /* FRAC_BITS. */ + "packssdw %%xmm2, %%xmm0 \n\t" + "packuswb %%xmm7, %%xmm0 \n\t" + "movq %%xmm0, (%%"FF_REG_d") \n\t" + + "psrad $8, %%xmm4 \n\t" /* FRAC_BITS. */ + "psrad $8, %%xmm6 \n\t" /* FRAC_BITS. */ + "packssdw %%xmm6, %%xmm4 \n\t" + "packuswb %%xmm7, %%xmm4 \n\t" + "movq %%xmm4, (%%"FF_REG_d",%%"FF_REG_c"); \n\t" +snow_inner_add_yblock_sse2_end_8 +} + +static void inner_add_yblock_bw_16_obmc_32_sse2(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, + int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_sse2_header +snow_inner_add_yblock_sse2_start_16("xmm1", "xmm5", "3", "0") +snow_inner_add_yblock_sse2_accum_16("2", "16") +snow_inner_add_yblock_sse2_accum_16("1", "512") +snow_inner_add_yblock_sse2_accum_16("0", "528") + + "mov %0, %%"FF_REG_d" \n\t" + "psrlw $4, %%xmm1 \n\t" + "psrlw $4, %%xmm5 \n\t" + "paddw (%%"FF_REG_D"), %%xmm1 \n\t" + "paddw 16(%%"FF_REG_D"), %%xmm5 \n\t" + "paddw %%xmm3, %%xmm1 \n\t" + "paddw %%xmm3, %%xmm5 \n\t" + "psraw $4, %%xmm1 \n\t" /* FRAC_BITS. */ + "psraw $4, %%xmm5 \n\t" /* FRAC_BITS. */ + "packuswb %%xmm5, %%xmm1 \n\t" + + "movdqu %%xmm1, (%%"FF_REG_d") \n\t" + +snow_inner_add_yblock_sse2_end_16 +} + +#define snow_inner_add_yblock_mmx_header \ + IDWTELEM * * dst_array = sb->line + src_y;\ + x86_reg tmp;\ + __asm__ volatile(\ + "mov %7, %%"FF_REG_c" \n\t"\ + "mov %6, %2 \n\t"\ + "mov %4, %%"FF_REG_S" \n\t"\ + "pxor %%mm7, %%mm7 \n\t" /* 0 */\ + "pcmpeqd %%mm3, %%mm3 \n\t"\ + "psllw $15, %%mm3 \n\t"\ + "psrlw $12, %%mm3 \n\t" /* FRAC_BITS >> 1 */\ + "1: \n\t"\ + "mov %1, %%"FF_REG_D" \n\t"\ + "mov (%%"FF_REG_D"), %%"FF_REG_D" \n\t"\ + "add %3, %%"FF_REG_D" \n\t" + +#define snow_inner_add_yblock_mmx_start(out_reg1, out_reg2, ptr_offset, s_offset, d_offset)\ + "mov "FF_PTR_SIZE"*"ptr_offset"(%%"FF_REG_a"), %%"FF_REG_d"; \n\t"\ + "movd "d_offset"(%%"FF_REG_d"), %%"out_reg1" \n\t"\ + "movd "d_offset"+4(%%"FF_REG_d"), %%"out_reg2" \n\t"\ + "punpcklbw %%mm7, %%"out_reg1" \n\t"\ + "punpcklbw %%mm7, %%"out_reg2" \n\t"\ + "movd "s_offset"(%%"FF_REG_S"), %%mm0 \n\t"\ + "movd "s_offset"+4(%%"FF_REG_S"), %%mm4 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + "pmullw %%mm0, %%"out_reg1" \n\t"\ + "pmullw %%mm4, %%"out_reg2" \n\t" + +#define snow_inner_add_yblock_mmx_accum(ptr_offset, s_offset, d_offset) \ + snow_inner_add_yblock_mmx_start("mm2", "mm6", ptr_offset, s_offset, d_offset)\ + "paddusw %%mm2, %%mm1 \n\t"\ + "paddusw %%mm6, %%mm5 \n\t" + +#define snow_inner_add_yblock_mmx_mix(read_offset, write_offset)\ + "mov %0, %%"FF_REG_d" \n\t"\ + "psrlw $4, %%mm1 \n\t"\ + "psrlw $4, %%mm5 \n\t"\ + "paddw "read_offset"(%%"FF_REG_D"), %%mm1 \n\t"\ + "paddw "read_offset"+8(%%"FF_REG_D"), %%mm5 \n\t"\ + "paddw %%mm3, %%mm1 \n\t"\ + "paddw %%mm3, %%mm5 \n\t"\ + "psraw $4, %%mm1 \n\t"\ + "psraw $4, %%mm5 \n\t"\ + "packuswb %%mm5, %%mm1 \n\t"\ + "movq %%mm1, "write_offset"(%%"FF_REG_d") \n\t" + +#define snow_inner_add_yblock_mmx_end(s_step)\ + "add $"s_step", %%"FF_REG_S" \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*3(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*2(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*1(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", (%%"FF_REG_a") \n\t"\ + "add"FF_OPSIZE " $"FF_PTR_SIZE"*1, %1 \n\t"\ + "add %%"FF_REG_c", %0 \n\t"\ + "dec %2 \n\t"\ + "jnz 1b \n\t"\ + :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\ + :\ + "rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\ + "%"FF_REG_c"","%"FF_REG_S"","%"FF_REG_D"","%"FF_REG_d""); + +static void inner_add_yblock_bw_8_obmc_16_mmx(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, + int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_mmx_header +snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0") +snow_inner_add_yblock_mmx_accum("2", "8", "0") +snow_inner_add_yblock_mmx_accum("1", "128", "0") +snow_inner_add_yblock_mmx_accum("0", "136", "0") +snow_inner_add_yblock_mmx_mix("0", "0") +snow_inner_add_yblock_mmx_end("16") +} + +static void inner_add_yblock_bw_16_obmc_32_mmx(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, + int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_mmx_header +snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0") +snow_inner_add_yblock_mmx_accum("2", "16", "0") +snow_inner_add_yblock_mmx_accum("1", "512", "0") +snow_inner_add_yblock_mmx_accum("0", "528", "0") +snow_inner_add_yblock_mmx_mix("0", "0") + +snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "8", "8") +snow_inner_add_yblock_mmx_accum("2", "24", "8") +snow_inner_add_yblock_mmx_accum("1", "520", "8") +snow_inner_add_yblock_mmx_accum("0", "536", "8") +snow_inner_add_yblock_mmx_mix("16", "8") +snow_inner_add_yblock_mmx_end("32") +} + +static void ff_snow_inner_add_yblock_sse2(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, + int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){ + + if (b_w == 16) + inner_add_yblock_bw_16_obmc_32_sse2(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else if (b_w == 8 && obmc_stride == 16) { + if (!(b_h & 1)) + inner_add_yblock_bw_8_obmc_16_bh_even_sse2(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else + inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + } else + ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); +} + +static void ff_snow_inner_add_yblock_mmx(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, + int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){ + if (b_w == 16) + inner_add_yblock_bw_16_obmc_32_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else if (b_w == 8 && obmc_stride == 16) + inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else + ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); +} +#endif /* HAVE_6REGS */ + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_dwt_init_x86(SnowDWTContext *c) +{ +#if HAVE_INLINE_ASM + int mm_flags = av_get_cpu_flags(); + + if (mm_flags & AV_CPU_FLAG_MMX) { + if(mm_flags & AV_CPU_FLAG_SSE2 & 0){ + c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2; +#if HAVE_7REGS + c->vertical_compose97i = ff_snow_vertical_compose97i_sse2; +#endif +#if HAVE_6REGS + c->inner_add_yblock = ff_snow_inner_add_yblock_sse2; +#endif + } + else{ + if (mm_flags & AV_CPU_FLAG_MMXEXT) { + c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx; +#if HAVE_7REGS + c->vertical_compose97i = ff_snow_vertical_compose97i_mmx; +#endif + } +#if HAVE_6REGS + c->inner_add_yblock = ff_snow_inner_add_yblock_mmx; +#endif + } + } +#endif /* HAVE_INLINE_ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/svq1enc_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/svq1enc_init.c new file mode 100644 index 000000000..40b4b0e18 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/svq1enc_init.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2007 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/svq1enc.h" + +int ff_ssd_int8_vs_int16_mmx(const int8_t *pix1, const int16_t *pix2, + intptr_t size); +int ff_ssd_int8_vs_int16_sse2(const int8_t *pix1, const int16_t *pix2, + intptr_t size); + +av_cold void ff_svq1enc_init_x86(SVQ1EncContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->ssd_int8_vs_int16 = ff_ssd_int8_vs_int16_mmx; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->ssd_int8_vs_int16 = ff_ssd_int8_vs_int16_sse2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/synth_filter_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/synth_filter_init.c new file mode 100644 index 000000000..35e2b47a3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/synth_filter_init.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012-2014 Christophe Gisquet + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/synth_filter.h" + +#define SYNTH_FILTER_FUNC(opt) \ +void ff_synth_filter_inner_##opt(float *synth_buf_ptr, float synth_buf2[32], \ + const float window[512], \ + float out[32], intptr_t offset, float scale); \ +static void synth_filter_##opt(FFTContext *imdct, \ + float *synth_buf_ptr, int *synth_buf_offset, \ + float synth_buf2[32], const float window[512], \ + float out[32], const float in[32], float scale) \ +{ \ + float *synth_buf= synth_buf_ptr + *synth_buf_offset; \ + \ + imdct->imdct_half(imdct, synth_buf, in); \ + \ + ff_synth_filter_inner_##opt(synth_buf, synth_buf2, window, \ + out, *synth_buf_offset, scale); \ + \ + *synth_buf_offset = (*synth_buf_offset - 32) & 511; \ +} \ + +#if HAVE_X86ASM +#if ARCH_X86_32 +SYNTH_FILTER_FUNC(sse) +#endif +SYNTH_FILTER_FUNC(sse2) +SYNTH_FILTER_FUNC(avx) +SYNTH_FILTER_FUNC(fma3) +#endif /* HAVE_X86ASM */ + +av_cold void ff_synth_filter_init_x86(SynthFilterContext *s) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags)) { + s->synth_filter_float = synth_filter_sse; + } +#endif + if (EXTERNAL_SSE2(cpu_flags)) { + s->synth_filter_float = synth_filter_sse2; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + s->synth_filter_float = synth_filter_avx; + } + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + s->synth_filter_float = synth_filter_fma3; + } +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/takdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/takdsp_init.c new file mode 100644 index 000000000..fe0c846af --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/takdsp_init.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015 Paul B Mahol + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavcodec/takdsp.h" +#include "libavutil/x86/cpu.h" +#include "config.h" + +void ff_tak_decorrelate_ls_sse2(int32_t *p1, int32_t *p2, int length); +void ff_tak_decorrelate_sr_sse2(int32_t *p1, int32_t *p2, int length); +void ff_tak_decorrelate_sm_sse2(int32_t *p1, int32_t *p2, int length); +void ff_tak_decorrelate_sf_sse4(int32_t *p1, int32_t *p2, int length, int dshift, int dfactor); + +av_cold void ff_takdsp_init_x86(TAKDSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + c->decorrelate_ls = ff_tak_decorrelate_ls_sse2; + c->decorrelate_sr = ff_tak_decorrelate_sr_sse2; + c->decorrelate_sm = ff_tak_decorrelate_sm_sse2; + } + + if (EXTERNAL_SSE4(cpu_flags)) { + c->decorrelate_sf = ff_tak_decorrelate_sf_sse4; + } +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ttadsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ttadsp_init.c new file mode 100644 index 000000000..7441c9776 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ttadsp_init.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavcodec/ttadsp.h" +#include "libavutil/x86/cpu.h" +#include "config.h" + +void ff_tta_filter_process_ssse3(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); +void ff_tta_filter_process_sse4(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); + +av_cold void ff_ttadsp_init_x86(TTADSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSSE3(cpu_flags)) + c->filter_process = ff_tta_filter_process_ssse3; + if (EXTERNAL_SSE4(cpu_flags)) + c->filter_process = ff_tta_filter_process_sse4; +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ttaencdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ttaencdsp_init.c new file mode 100644 index 000000000..61971a428 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/ttaencdsp_init.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014-2016 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavcodec/ttaencdsp.h" +#include "libavutil/x86/cpu.h" +#include "config.h" + +void ff_ttaenc_filter_process_ssse3(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); +void ff_ttaenc_filter_process_sse4(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); + +av_cold void ff_ttaencdsp_init_x86(TTAEncDSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSSE3(cpu_flags)) + c->filter_process = ff_ttaenc_filter_process_ssse3; + if (EXTERNAL_SSE4(cpu_flags)) + c->filter_process = ff_ttaenc_filter_process_sse4; +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/utvideodsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/utvideodsp_init.c new file mode 100644 index 000000000..2b436c6c5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/utvideodsp_init.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Paul B Mahol + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/utvideodsp.h" + +void ff_restore_rgb_planes_sse2(uint8_t *src_r, uint8_t *src_g, uint8_t *src_b, + ptrdiff_t linesize_r, ptrdiff_t linesize_g, + ptrdiff_t linesize_b, int width, int height); +void ff_restore_rgb_planes_avx2(uint8_t *src_r, uint8_t *src_g, uint8_t *src_b, + ptrdiff_t linesize_r, ptrdiff_t linesize_g, + ptrdiff_t linesize_b, int width, int height); + +void ff_restore_rgb_planes10_sse2(uint16_t *src_r, uint16_t *src_g, uint16_t *src_b, + ptrdiff_t linesize_r, ptrdiff_t linesize_g, + ptrdiff_t linesize_b, int width, int height); +void ff_restore_rgb_planes10_avx2(uint16_t *src_r, uint16_t *src_g, uint16_t *src_b, + ptrdiff_t linesize_r, ptrdiff_t linesize_g, + ptrdiff_t linesize_b, int width, int height); + +av_cold void ff_utvideodsp_init_x86(UTVideoDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + c->restore_rgb_planes = ff_restore_rgb_planes_sse2; + c->restore_rgb_planes10 = ff_restore_rgb_planes10_sse2; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->restore_rgb_planes = ff_restore_rgb_planes_avx2; + c->restore_rgb_planes10 = ff_restore_rgb_planes10_avx2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/v210-init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/v210-init.c new file mode 100644 index 000000000..cb9a6cbd6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/v210-init.c @@ -0,0 +1,56 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/cpu.h" +#include "libavcodec/v210dec.h" + +extern void ff_v210_planar_unpack_unaligned_ssse3(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_unaligned_avx(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_unaligned_avx2(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); + +extern void ff_v210_planar_unpack_aligned_ssse3(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_aligned_avx(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_aligned_avx2(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); + +av_cold void ff_v210_x86_init(V210DecContext *s) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (s->aligned_input) { + if (cpu_flags & AV_CPU_FLAG_SSSE3) + s->unpack_frame = ff_v210_planar_unpack_aligned_ssse3; + + if (HAVE_AVX_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX) + s->unpack_frame = ff_v210_planar_unpack_aligned_avx; + + if (HAVE_AVX2_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX2) + s->unpack_frame = ff_v210_planar_unpack_aligned_avx2; + } + else { + if (cpu_flags & AV_CPU_FLAG_SSSE3) + s->unpack_frame = ff_v210_planar_unpack_unaligned_ssse3; + + if (HAVE_AVX_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX) + s->unpack_frame = ff_v210_planar_unpack_unaligned_avx; + + if (HAVE_AVX2_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX2) + s->unpack_frame = ff_v210_planar_unpack_unaligned_avx2; + } +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/v210enc_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/v210enc_init.c new file mode 100644 index 000000000..e997b4b67 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/v210enc_init.c @@ -0,0 +1,54 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/x86/cpu.h" +#include "libavcodec/v210enc.h" + +void ff_v210_planar_pack_8_ssse3(const uint8_t *y, const uint8_t *u, + const uint8_t *v, uint8_t *dst, + ptrdiff_t width); +void ff_v210_planar_pack_8_avx(const uint8_t *y, const uint8_t *u, + const uint8_t *v, uint8_t *dst, ptrdiff_t width); +void ff_v210_planar_pack_8_avx2(const uint8_t *y, const uint8_t *u, + const uint8_t *v, uint8_t *dst, ptrdiff_t width); +void ff_v210_planar_pack_10_ssse3(const uint16_t *y, const uint16_t *u, + const uint16_t *v, uint8_t *dst, + ptrdiff_t width); +void ff_v210_planar_pack_10_avx2(const uint16_t *y, const uint16_t *u, + const uint16_t *v, uint8_t *dst, + ptrdiff_t width); + +av_cold void ff_v210enc_init_x86(V210EncContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSSE3(cpu_flags)) { + s->pack_line_8 = ff_v210_planar_pack_8_ssse3; + s->pack_line_10 = ff_v210_planar_pack_10_ssse3; + } + + if (EXTERNAL_AVX(cpu_flags)) + s->pack_line_8 = ff_v210_planar_pack_8_avx; + + if (EXTERNAL_AVX2(cpu_flags)) { + s->sample_factor_8 = 2; + s->pack_line_8 = ff_v210_planar_pack_8_avx2; + s->sample_factor_10 = 2; + s->pack_line_10 = ff_v210_planar_pack_10_avx2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp.h new file mode 100644 index 000000000..fdd4de181 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp.h @@ -0,0 +1,29 @@ +/* + * VC-1 and WMV3 decoder - X86 DSP init functions + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_VC1DSP_H +#define AVCODEC_X86_VC1DSP_H + +#include "libavcodec/vc1dsp.h" + +void ff_vc1dsp_init_mmx(VC1DSPContext *dsp); +void ff_vc1dsp_init_mmxext(VC1DSPContext *dsp); + +#endif /* AVCODEC_X86_VC1DSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp_init.c new file mode 100644 index 000000000..8e0c284cc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp_init.c @@ -0,0 +1,168 @@ +/* + * VC-1 and WMV3 - DSP functions MMX-optimized + * Copyright (c) 2007 Christophe GISQUET + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavcodec/vc1dsp.h" +#include "fpel.h" +#include "vc1dsp.h" +#include "config.h" + +#define LOOP_FILTER(EXT) \ +void ff_vc1_v_loop_filter4_ ## EXT(uint8_t *src, int stride, int pq); \ +void ff_vc1_h_loop_filter4_ ## EXT(uint8_t *src, int stride, int pq); \ +void ff_vc1_v_loop_filter8_ ## EXT(uint8_t *src, int stride, int pq); \ +void ff_vc1_h_loop_filter8_ ## EXT(uint8_t *src, int stride, int pq); \ +\ +static void vc1_v_loop_filter16_ ## EXT(uint8_t *src, int stride, int pq) \ +{ \ + ff_vc1_v_loop_filter8_ ## EXT(src, stride, pq); \ + ff_vc1_v_loop_filter8_ ## EXT(src+8, stride, pq); \ +} \ +\ +static void vc1_h_loop_filter16_ ## EXT(uint8_t *src, int stride, int pq) \ +{ \ + ff_vc1_h_loop_filter8_ ## EXT(src, stride, pq); \ + ff_vc1_h_loop_filter8_ ## EXT(src+8*stride, stride, pq); \ +} + +#if HAVE_X86ASM +LOOP_FILTER(mmxext) +LOOP_FILTER(sse2) +LOOP_FILTER(ssse3) + +void ff_vc1_h_loop_filter8_sse4(uint8_t *src, int stride, int pq); + +static void vc1_h_loop_filter16_sse4(uint8_t *src, int stride, int pq) +{ + ff_vc1_h_loop_filter8_sse4(src, stride, pq); + ff_vc1_h_loop_filter8_sse4(src+8*stride, stride, pq); +} + +#define DECLARE_FUNCTION(OP, DEPTH, INSN) \ + static void OP##vc1_mspel_mc00_##DEPTH##INSN(uint8_t *dst, \ + const uint8_t *src, ptrdiff_t stride, int rnd) \ + { \ + ff_ ## OP ## pixels ## DEPTH ## INSN(dst, src, stride, DEPTH); \ + } + +DECLARE_FUNCTION(put_, 8, _mmx) +DECLARE_FUNCTION(put_, 16, _mmx) +DECLARE_FUNCTION(avg_, 8, _mmx) +DECLARE_FUNCTION(avg_, 16, _mmx) +DECLARE_FUNCTION(avg_, 8, _mmxext) +DECLARE_FUNCTION(avg_, 16, _mmxext) +DECLARE_FUNCTION(put_, 16, _sse2) +DECLARE_FUNCTION(avg_, 16, _sse2) + +#endif /* HAVE_X86ASM */ + +void ff_put_vc1_chroma_mc8_nornd_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_vc1_chroma_mc8_nornd_mmxext(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_vc1_chroma_mc8_nornd_3dnow(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_put_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_vc1_inv_trans_4x4_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); +void ff_vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); +void ff_vc1_inv_trans_8x4_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); +void ff_vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); + + +av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (HAVE_6REGS && INLINE_MMX(cpu_flags)) + if (EXTERNAL_MMX(cpu_flags)) + ff_vc1dsp_init_mmx(dsp); + + if (HAVE_6REGS && INLINE_MMXEXT(cpu_flags)) + if (EXTERNAL_MMXEXT(cpu_flags)) + ff_vc1dsp_init_mmxext(dsp); + +#define ASSIGN_LF(EXT) \ + dsp->vc1_v_loop_filter4 = ff_vc1_v_loop_filter4_ ## EXT; \ + dsp->vc1_h_loop_filter4 = ff_vc1_h_loop_filter4_ ## EXT; \ + dsp->vc1_v_loop_filter8 = ff_vc1_v_loop_filter8_ ## EXT; \ + dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_ ## EXT; \ + dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_ ## EXT; \ + dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_ ## EXT + +#if HAVE_X86ASM + if (EXTERNAL_MMX(cpu_flags)) { + dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_mmx; + + dsp->put_vc1_mspel_pixels_tab[1][0] = put_vc1_mspel_mc00_8_mmx; + dsp->put_vc1_mspel_pixels_tab[0][0] = put_vc1_mspel_mc00_16_mmx; + dsp->avg_vc1_mspel_pixels_tab[1][0] = avg_vc1_mspel_mc00_8_mmx; + dsp->avg_vc1_mspel_pixels_tab[0][0] = avg_vc1_mspel_mc00_16_mmx; + } + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_3dnow; + } + if (EXTERNAL_MMXEXT(cpu_flags)) { + ASSIGN_LF(mmxext); + dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_mmxext; + + dsp->avg_vc1_mspel_pixels_tab[1][0] = avg_vc1_mspel_mc00_8_mmxext; + dsp->avg_vc1_mspel_pixels_tab[0][0] = avg_vc1_mspel_mc00_16_mmxext; + + dsp->vc1_inv_trans_8x8_dc = ff_vc1_inv_trans_8x8_dc_mmxext; + dsp->vc1_inv_trans_4x8_dc = ff_vc1_inv_trans_4x8_dc_mmxext; + dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_mmxext; + dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + dsp->vc1_v_loop_filter8 = ff_vc1_v_loop_filter8_sse2; + dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_sse2; + dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_sse2; + dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse2; + + dsp->put_vc1_mspel_pixels_tab[0][0] = put_vc1_mspel_mc00_16_sse2; + dsp->avg_vc1_mspel_pixels_tab[0][0] = avg_vc1_mspel_mc00_16_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + ASSIGN_LF(ssse3); + dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_ssse3; + dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_ssse3; + } + if (EXTERNAL_SSE4(cpu_flags)) { + dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_sse4; + dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse4; + } +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp_mmx.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp_mmx.c new file mode 100644 index 000000000..45c8a68f2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vc1dsp_mmx.c @@ -0,0 +1,486 @@ +/* + * VC-1 and WMV3 - DSP functions MMX-optimized + * Copyright (c) 2007 Christophe GISQUET + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vc1dsp.h" +#include "constants.h" +#include "fpel.h" +#include "vc1dsp.h" + +#if HAVE_6REGS && HAVE_INLINE_ASM && HAVE_MMX_EXTERNAL + +void ff_vc1_put_ver_16b_shift2_mmx(int16_t *dst, + const uint8_t *src, x86_reg stride, + int rnd, int64_t shift); +void ff_vc1_put_hor_16b_shift2_mmx(uint8_t *dst, x86_reg stride, + const int16_t *src, int rnd); +void ff_vc1_avg_hor_16b_shift2_mmxext(uint8_t *dst, x86_reg stride, + const int16_t *src, int rnd); + +#define OP_PUT(S,D) +#define OP_AVG(S,D) "pavgb " #S ", " #D " \n\t" + +/** Add rounder from mm7 to mm3 and pack result at destination */ +#define NORMALIZE_MMX(SHIFT) \ + "paddw %%mm7, %%mm3 \n\t" /* +bias-r */ \ + "paddw %%mm7, %%mm4 \n\t" /* +bias-r */ \ + "psraw "SHIFT", %%mm3 \n\t" \ + "psraw "SHIFT", %%mm4 \n\t" + +#define TRANSFER_DO_PACK(OP) \ + "packuswb %%mm4, %%mm3 \n\t" \ + OP((%2), %%mm3) \ + "movq %%mm3, (%2) \n\t" + +#define TRANSFER_DONT_PACK(OP) \ + OP(0(%2), %%mm3) \ + OP(8(%2), %%mm4) \ + "movq %%mm3, 0(%2) \n\t" \ + "movq %%mm4, 8(%2) \n\t" + +/** @see MSPEL_FILTER13_CORE for use as UNPACK macro */ +#define DO_UNPACK(reg) "punpcklbw %%mm0, " reg "\n\t" +#define DONT_UNPACK(reg) + +/** Compute the rounder 32-r or 8-r and unpacks it to mm7 */ +#define LOAD_ROUNDER_MMX(ROUND) \ + "movd "ROUND", %%mm7 \n\t" \ + "punpcklwd %%mm7, %%mm7 \n\t" \ + "punpckldq %%mm7, %%mm7 \n\t" + +/** + * Purely vertical or horizontal 1/2 shift interpolation. + * Sacrifice mm6 for *9 factor. + */ +#define VC1_SHIFT2(OP, OPNAME)\ +static void OPNAME ## vc1_shift2_mmx(uint8_t *dst, const uint8_t *src,\ + x86_reg stride, int rnd, x86_reg offset)\ +{\ + rnd = 8-rnd;\ + __asm__ volatile(\ + "mov $8, %%"FF_REG_c" \n\t"\ + LOAD_ROUNDER_MMX("%5")\ + "movq "MANGLE(ff_pw_9)", %%mm6\n\t"\ + "1: \n\t"\ + "movd 0(%0 ), %%mm3 \n\t"\ + "movd 4(%0 ), %%mm4 \n\t"\ + "movd 0(%0,%2), %%mm1 \n\t"\ + "movd 4(%0,%2), %%mm2 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm0, %%mm3 \n\t"\ + "punpcklbw %%mm0, %%mm4 \n\t"\ + "punpcklbw %%mm0, %%mm1 \n\t"\ + "punpcklbw %%mm0, %%mm2 \n\t"\ + "paddw %%mm1, %%mm3 \n\t"\ + "paddw %%mm2, %%mm4 \n\t"\ + "movd 0(%0,%3), %%mm1 \n\t"\ + "movd 4(%0,%3), %%mm2 \n\t"\ + "pmullw %%mm6, %%mm3 \n\t" /* 0,9,9,0*/\ + "pmullw %%mm6, %%mm4 \n\t" /* 0,9,9,0*/\ + "punpcklbw %%mm0, %%mm1 \n\t"\ + "punpcklbw %%mm0, %%mm2 \n\t"\ + "psubw %%mm1, %%mm3 \n\t" /*-1,9,9,0*/\ + "psubw %%mm2, %%mm4 \n\t" /*-1,9,9,0*/\ + "movd 0(%0,%2), %%mm1 \n\t"\ + "movd 4(%0,%2), %%mm2 \n\t"\ + "punpcklbw %%mm0, %%mm1 \n\t"\ + "punpcklbw %%mm0, %%mm2 \n\t"\ + "psubw %%mm1, %%mm3 \n\t" /*-1,9,9,-1*/\ + "psubw %%mm2, %%mm4 \n\t" /*-1,9,9,-1*/\ + NORMALIZE_MMX("$4")\ + "packuswb %%mm4, %%mm3 \n\t"\ + OP((%1), %%mm3)\ + "movq %%mm3, (%1) \n\t"\ + "add %6, %0 \n\t"\ + "add %4, %1 \n\t"\ + "dec %%"FF_REG_c" \n\t"\ + "jnz 1b \n\t"\ + : "+r"(src), "+r"(dst)\ + : "r"(offset), "r"(-2*offset), "g"(stride), "m"(rnd),\ + "g"(stride-offset)\ + NAMED_CONSTRAINTS_ADD(ff_pw_9)\ + : "%"FF_REG_c, "memory"\ + );\ +} + +VC1_SHIFT2(OP_PUT, put_) +VC1_SHIFT2(OP_AVG, avg_) + +/** + * Core of the 1/4 and 3/4 shift bicubic interpolation. + * + * @param UNPACK Macro unpacking arguments from 8 to 16 bits (can be empty). + * @param MOVQ "movd 1" or "movq 2", if data read is already unpacked. + * @param A1 Address of 1st tap (beware of unpacked/packed). + * @param A2 Address of 2nd tap + * @param A3 Address of 3rd tap + * @param A4 Address of 4th tap + */ +#define MSPEL_FILTER13_CORE(UNPACK, MOVQ, A1, A2, A3, A4) \ + MOVQ "*0+"A1", %%mm1 \n\t" \ + MOVQ "*4+"A1", %%mm2 \n\t" \ + UNPACK("%%mm1") \ + UNPACK("%%mm2") \ + "pmullw "MANGLE(ff_pw_3)", %%mm1\n\t" \ + "pmullw "MANGLE(ff_pw_3)", %%mm2\n\t" \ + MOVQ "*0+"A2", %%mm3 \n\t" \ + MOVQ "*4+"A2", %%mm4 \n\t" \ + UNPACK("%%mm3") \ + UNPACK("%%mm4") \ + "pmullw %%mm6, %%mm3 \n\t" /* *18 */ \ + "pmullw %%mm6, %%mm4 \n\t" /* *18 */ \ + "psubw %%mm1, %%mm3 \n\t" /* 18,-3 */ \ + "psubw %%mm2, %%mm4 \n\t" /* 18,-3 */ \ + MOVQ "*0+"A4", %%mm1 \n\t" \ + MOVQ "*4+"A4", %%mm2 \n\t" \ + UNPACK("%%mm1") \ + UNPACK("%%mm2") \ + "psllw $2, %%mm1 \n\t" /* 4* */ \ + "psllw $2, %%mm2 \n\t" /* 4* */ \ + "psubw %%mm1, %%mm3 \n\t" /* -4,18,-3 */ \ + "psubw %%mm2, %%mm4 \n\t" /* -4,18,-3 */ \ + MOVQ "*0+"A3", %%mm1 \n\t" \ + MOVQ "*4+"A3", %%mm2 \n\t" \ + UNPACK("%%mm1") \ + UNPACK("%%mm2") \ + "pmullw %%mm5, %%mm1 \n\t" /* *53 */ \ + "pmullw %%mm5, %%mm2 \n\t" /* *53 */ \ + "paddw %%mm1, %%mm3 \n\t" /* 4,53,18,-3 */ \ + "paddw %%mm2, %%mm4 \n\t" /* 4,53,18,-3 */ + +/** + * Macro to build the vertical 16 bits version of vc1_put_shift[13]. + * Here, offset=src_stride. Parameters passed A1 to A4 must use + * %3 (src_stride) and %4 (3*src_stride). + * + * @param NAME Either 1 or 3 + * @see MSPEL_FILTER13_CORE for information on A1->A4 + */ +#define MSPEL_FILTER13_VER_16B(NAME, A1, A2, A3, A4) \ +static void \ +vc1_put_ver_16b_ ## NAME ## _mmx(int16_t *dst, const uint8_t *src, \ + x86_reg src_stride, \ + int rnd, int64_t shift) \ +{ \ + int h = 8; \ + src -= src_stride; \ + __asm__ volatile( \ + LOAD_ROUNDER_MMX("%5") \ + "movq "MANGLE(ff_pw_53)", %%mm5\n\t" \ + "movq "MANGLE(ff_pw_18)", %%mm6\n\t" \ + ".p2align 3 \n\t" \ + "1: \n\t" \ + MSPEL_FILTER13_CORE(DO_UNPACK, "movd 1", A1, A2, A3, A4) \ + NORMALIZE_MMX("%6") \ + TRANSFER_DONT_PACK(OP_PUT) \ + /* Last 3 (in fact 4) bytes on the line */ \ + "movd 8+"A1", %%mm1 \n\t" \ + DO_UNPACK("%%mm1") \ + "movq %%mm1, %%mm3 \n\t" \ + "paddw %%mm1, %%mm1 \n\t" \ + "paddw %%mm3, %%mm1 \n\t" /* 3* */ \ + "movd 8+"A2", %%mm3 \n\t" \ + DO_UNPACK("%%mm3") \ + "pmullw %%mm6, %%mm3 \n\t" /* *18 */ \ + "psubw %%mm1, %%mm3 \n\t" /*18,-3 */ \ + "movd 8+"A3", %%mm1 \n\t" \ + DO_UNPACK("%%mm1") \ + "pmullw %%mm5, %%mm1 \n\t" /* *53 */ \ + "paddw %%mm1, %%mm3 \n\t" /*53,18,-3 */ \ + "movd 8+"A4", %%mm1 \n\t" \ + DO_UNPACK("%%mm1") \ + "psllw $2, %%mm1 \n\t" /* 4* */ \ + "psubw %%mm1, %%mm3 \n\t" \ + "paddw %%mm7, %%mm3 \n\t" \ + "psraw %6, %%mm3 \n\t" \ + "movq %%mm3, 16(%2) \n\t" \ + "add %3, %1 \n\t" \ + "add $24, %2 \n\t" \ + "decl %0 \n\t" \ + "jnz 1b \n\t" \ + : "+r"(h), "+r" (src), "+r" (dst) \ + : "r"(src_stride), "r"(3*src_stride), \ + "m"(rnd), "m"(shift) \ + NAMED_CONSTRAINTS_ADD(ff_pw_3,ff_pw_53,ff_pw_18) \ + : "memory" \ + ); \ +} + +/** + * Macro to build the horizontal 16 bits version of vc1_put_shift[13]. + * Here, offset=16 bits, so parameters passed A1 to A4 should be simple. + * + * @param NAME Either 1 or 3 + * @see MSPEL_FILTER13_CORE for information on A1->A4 + */ +#define MSPEL_FILTER13_HOR_16B(NAME, A1, A2, A3, A4, OP, OPNAME) \ +static void \ +OPNAME ## vc1_hor_16b_ ## NAME ## _mmx(uint8_t *dst, x86_reg stride, \ + const int16_t *src, int rnd) \ +{ \ + int h = 8; \ + src -= 1; \ + rnd -= (-4+58+13-3)*256; /* Add -256 bias */ \ + __asm__ volatile( \ + LOAD_ROUNDER_MMX("%4") \ + "movq "MANGLE(ff_pw_18)", %%mm6 \n\t" \ + "movq "MANGLE(ff_pw_53)", %%mm5 \n\t" \ + ".p2align 3 \n\t" \ + "1: \n\t" \ + MSPEL_FILTER13_CORE(DONT_UNPACK, "movq 2", A1, A2, A3, A4) \ + NORMALIZE_MMX("$7") \ + /* Remove bias */ \ + "paddw "MANGLE(ff_pw_128)", %%mm3 \n\t" \ + "paddw "MANGLE(ff_pw_128)", %%mm4 \n\t" \ + TRANSFER_DO_PACK(OP) \ + "add $24, %1 \n\t" \ + "add %3, %2 \n\t" \ + "decl %0 \n\t" \ + "jnz 1b \n\t" \ + : "+r"(h), "+r" (src), "+r" (dst) \ + : "r"(stride), "m"(rnd) \ + NAMED_CONSTRAINTS_ADD(ff_pw_3,ff_pw_18,ff_pw_53,ff_pw_128) \ + : "memory" \ + ); \ +} + +/** + * Macro to build the 8 bits, any direction, version of vc1_put_shift[13]. + * Here, offset=src_stride. Parameters passed A1 to A4 must use + * %3 (offset) and %4 (3*offset). + * + * @param NAME Either 1 or 3 + * @see MSPEL_FILTER13_CORE for information on A1->A4 + */ +#define MSPEL_FILTER13_8B(NAME, A1, A2, A3, A4, OP, OPNAME) \ +static void \ +OPNAME ## vc1_## NAME ## _mmx(uint8_t *dst, const uint8_t *src, \ + x86_reg stride, int rnd, x86_reg offset) \ +{ \ + int h = 8; \ + src -= offset; \ + rnd = 32-rnd; \ + __asm__ volatile ( \ + LOAD_ROUNDER_MMX("%6") \ + "movq "MANGLE(ff_pw_53)", %%mm5 \n\t" \ + "movq "MANGLE(ff_pw_18)", %%mm6 \n\t" \ + ".p2align 3 \n\t" \ + "1: \n\t" \ + MSPEL_FILTER13_CORE(DO_UNPACK, "movd 1", A1, A2, A3, A4) \ + NORMALIZE_MMX("$6") \ + TRANSFER_DO_PACK(OP) \ + "add %5, %1 \n\t" \ + "add %5, %2 \n\t" \ + "decl %0 \n\t" \ + "jnz 1b \n\t" \ + : "+r"(h), "+r" (src), "+r" (dst) \ + : "r"(offset), "r"(3*offset), "g"(stride), "m"(rnd) \ + NAMED_CONSTRAINTS_ADD(ff_pw_53,ff_pw_18,ff_pw_3) \ + : "memory" \ + ); \ +} + +/** 1/4 shift bicubic interpolation */ +MSPEL_FILTER13_8B (shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )", OP_PUT, put_) +MSPEL_FILTER13_8B (shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )", OP_AVG, avg_) +MSPEL_FILTER13_VER_16B(shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )") +MSPEL_FILTER13_HOR_16B(shift1, "2*3(%1)", "2*2(%1)", "2*1(%1)", "2*0(%1)", OP_PUT, put_) +MSPEL_FILTER13_HOR_16B(shift1, "2*3(%1)", "2*2(%1)", "2*1(%1)", "2*0(%1)", OP_AVG, avg_) + +/** 3/4 shift bicubic interpolation */ +MSPEL_FILTER13_8B (shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )", OP_PUT, put_) +MSPEL_FILTER13_8B (shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )", OP_AVG, avg_) +MSPEL_FILTER13_VER_16B(shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )") +MSPEL_FILTER13_HOR_16B(shift3, "2*0(%1)", "2*1(%1)", "2*2(%1)", "2*3(%1)", OP_PUT, put_) +MSPEL_FILTER13_HOR_16B(shift3, "2*0(%1)", "2*1(%1)", "2*2(%1)", "2*3(%1)", OP_AVG, avg_) + +typedef void (*vc1_mspel_mc_filter_ver_16bits)(int16_t *dst, const uint8_t *src, x86_reg src_stride, int rnd, int64_t shift); +typedef void (*vc1_mspel_mc_filter_hor_16bits)(uint8_t *dst, x86_reg dst_stride, const int16_t *src, int rnd); +typedef void (*vc1_mspel_mc_filter_8bits)(uint8_t *dst, const uint8_t *src, x86_reg stride, int rnd, x86_reg offset); + +/** + * Interpolate fractional pel values by applying proper vertical then + * horizontal filter. + * + * @param dst Destination buffer for interpolated pels. + * @param src Source buffer. + * @param stride Stride for both src and dst buffers. + * @param hmode Horizontal filter (expressed in quarter pixels shift). + * @param hmode Vertical filter. + * @param rnd Rounding bias. + */ +#define VC1_MSPEL_MC(OP, INSTR)\ +static void OP ## vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride,\ + int hmode, int vmode, int rnd)\ +{\ + static const vc1_mspel_mc_filter_ver_16bits vc1_put_shift_ver_16bits[] =\ + { NULL, vc1_put_ver_16b_shift1_mmx, ff_vc1_put_ver_16b_shift2_mmx, vc1_put_ver_16b_shift3_mmx };\ + static const vc1_mspel_mc_filter_hor_16bits vc1_put_shift_hor_16bits[] =\ + { NULL, OP ## vc1_hor_16b_shift1_mmx, ff_vc1_ ## OP ## hor_16b_shift2_ ## INSTR, OP ## vc1_hor_16b_shift3_mmx };\ + static const vc1_mspel_mc_filter_8bits vc1_put_shift_8bits[] =\ + { NULL, OP ## vc1_shift1_mmx, OP ## vc1_shift2_mmx, OP ## vc1_shift3_mmx };\ +\ + __asm__ volatile(\ + "pxor %%mm0, %%mm0 \n\t"\ + ::: "memory"\ + );\ +\ + if (vmode) { /* Vertical filter to apply */\ + if (hmode) { /* Horizontal filter to apply, output to tmp */\ + static const int shift_value[] = { 0, 5, 1, 5 };\ + int shift = (shift_value[hmode]+shift_value[vmode])>>1;\ + int r;\ + LOCAL_ALIGNED(16, int16_t, tmp, [12*8]);\ +\ + r = (1<<(shift-1)) + rnd-1;\ + vc1_put_shift_ver_16bits[vmode](tmp, src-1, stride, r, shift);\ +\ + vc1_put_shift_hor_16bits[hmode](dst, stride, tmp+1, 64-rnd);\ + return;\ + }\ + else { /* No horizontal filter, output 8 lines to dst */\ + vc1_put_shift_8bits[vmode](dst, src, stride, 1-rnd, stride);\ + return;\ + }\ + }\ +\ + /* Horizontal mode with no vertical mode */\ + vc1_put_shift_8bits[hmode](dst, src, stride, rnd, 1);\ +} \ +static void OP ## vc1_mspel_mc_16(uint8_t *dst, const uint8_t *src, \ + int stride, int hmode, int vmode, int rnd)\ +{ \ + OP ## vc1_mspel_mc(dst + 0, src + 0, stride, hmode, vmode, rnd); \ + OP ## vc1_mspel_mc(dst + 8, src + 8, stride, hmode, vmode, rnd); \ + dst += 8*stride; src += 8*stride; \ + OP ## vc1_mspel_mc(dst + 0, src + 0, stride, hmode, vmode, rnd); \ + OP ## vc1_mspel_mc(dst + 8, src + 8, stride, hmode, vmode, rnd); \ +} + +VC1_MSPEL_MC(put_, mmx) +VC1_MSPEL_MC(avg_, mmxext) + +/** Macro to ease bicubic filter interpolation functions declarations */ +#define DECLARE_FUNCTION(a, b) \ +static void put_vc1_mspel_mc ## a ## b ## _mmx(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride, \ + int rnd) \ +{ \ + put_vc1_mspel_mc(dst, src, stride, a, b, rnd); \ +}\ +static void avg_vc1_mspel_mc ## a ## b ## _mmxext(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride, \ + int rnd) \ +{ \ + avg_vc1_mspel_mc(dst, src, stride, a, b, rnd); \ +}\ +static void put_vc1_mspel_mc ## a ## b ## _16_mmx(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride, \ + int rnd) \ +{ \ + put_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \ +}\ +static void avg_vc1_mspel_mc ## a ## b ## _16_mmxext(uint8_t *dst, \ + const uint8_t *src,\ + ptrdiff_t stride, \ + int rnd) \ +{ \ + avg_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \ +} + +DECLARE_FUNCTION(0, 1) +DECLARE_FUNCTION(0, 2) +DECLARE_FUNCTION(0, 3) + +DECLARE_FUNCTION(1, 0) +DECLARE_FUNCTION(1, 1) +DECLARE_FUNCTION(1, 2) +DECLARE_FUNCTION(1, 3) + +DECLARE_FUNCTION(2, 0) +DECLARE_FUNCTION(2, 1) +DECLARE_FUNCTION(2, 2) +DECLARE_FUNCTION(2, 3) + +DECLARE_FUNCTION(3, 0) +DECLARE_FUNCTION(3, 1) +DECLARE_FUNCTION(3, 2) +DECLARE_FUNCTION(3, 3) + +#define FN_ASSIGN(OP, X, Y, INSN) \ + dsp->OP##vc1_mspel_pixels_tab[1][X+4*Y] = OP##vc1_mspel_mc##X##Y##INSN; \ + dsp->OP##vc1_mspel_pixels_tab[0][X+4*Y] = OP##vc1_mspel_mc##X##Y##_16##INSN + +av_cold void ff_vc1dsp_init_mmx(VC1DSPContext *dsp) +{ + FN_ASSIGN(put_, 0, 1, _mmx); + FN_ASSIGN(put_, 0, 2, _mmx); + FN_ASSIGN(put_, 0, 3, _mmx); + + FN_ASSIGN(put_, 1, 0, _mmx); + FN_ASSIGN(put_, 1, 1, _mmx); + FN_ASSIGN(put_, 1, 2, _mmx); + FN_ASSIGN(put_, 1, 3, _mmx); + + FN_ASSIGN(put_, 2, 0, _mmx); + FN_ASSIGN(put_, 2, 1, _mmx); + FN_ASSIGN(put_, 2, 2, _mmx); + FN_ASSIGN(put_, 2, 3, _mmx); + + FN_ASSIGN(put_, 3, 0, _mmx); + FN_ASSIGN(put_, 3, 1, _mmx); + FN_ASSIGN(put_, 3, 2, _mmx); + FN_ASSIGN(put_, 3, 3, _mmx); +} + +av_cold void ff_vc1dsp_init_mmxext(VC1DSPContext *dsp) +{ + FN_ASSIGN(avg_, 0, 1, _mmxext); + FN_ASSIGN(avg_, 0, 2, _mmxext); + FN_ASSIGN(avg_, 0, 3, _mmxext); + + FN_ASSIGN(avg_, 1, 0, _mmxext); + FN_ASSIGN(avg_, 1, 1, _mmxext); + FN_ASSIGN(avg_, 1, 2, _mmxext); + FN_ASSIGN(avg_, 1, 3, _mmxext); + + FN_ASSIGN(avg_, 2, 0, _mmxext); + FN_ASSIGN(avg_, 2, 1, _mmxext); + FN_ASSIGN(avg_, 2, 2, _mmxext); + FN_ASSIGN(avg_, 2, 3, _mmxext); + + FN_ASSIGN(avg_, 3, 0, _mmxext); + FN_ASSIGN(avg_, 3, 1, _mmxext); + FN_ASSIGN(avg_, 3, 2, _mmxext); + FN_ASSIGN(avg_, 3, 3, _mmxext); +} +#endif /* HAVE_6REGS && HAVE_INLINE_ASM && HAVE_MMX_EXTERNAL */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/videodsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/videodsp_init.c new file mode 100644 index 000000000..eeebb4154 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/videodsp_init.c @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2002-2012 Michael Niedermayer + * Copyright (C) 2012 Ronald S. Bultje + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/videodsp.h" + +#if HAVE_X86ASM +typedef void emu_edge_vfix_func(uint8_t *dst, x86_reg dst_stride, + const uint8_t *src, x86_reg src_stride, + x86_reg start_y, x86_reg end_y, x86_reg bh); +typedef void emu_edge_vvar_func(uint8_t *dst, x86_reg dst_stride, + const uint8_t *src, x86_reg src_stride, + x86_reg start_y, x86_reg end_y, x86_reg bh, + x86_reg w); + +extern emu_edge_vfix_func ff_emu_edge_vfix1_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix2_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix3_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix4_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix5_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix6_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix7_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix8_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix9_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix10_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix11_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix12_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix13_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix14_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix15_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix16_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix17_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix18_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix19_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix20_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix21_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix22_mmx; +#if ARCH_X86_32 +static emu_edge_vfix_func * const vfixtbl_mmx[22] = { + &ff_emu_edge_vfix1_mmx, &ff_emu_edge_vfix2_mmx, &ff_emu_edge_vfix3_mmx, + &ff_emu_edge_vfix4_mmx, &ff_emu_edge_vfix5_mmx, &ff_emu_edge_vfix6_mmx, + &ff_emu_edge_vfix7_mmx, &ff_emu_edge_vfix8_mmx, &ff_emu_edge_vfix9_mmx, + &ff_emu_edge_vfix10_mmx, &ff_emu_edge_vfix11_mmx, &ff_emu_edge_vfix12_mmx, + &ff_emu_edge_vfix13_mmx, &ff_emu_edge_vfix14_mmx, &ff_emu_edge_vfix15_mmx, + &ff_emu_edge_vfix16_mmx, &ff_emu_edge_vfix17_mmx, &ff_emu_edge_vfix18_mmx, + &ff_emu_edge_vfix19_mmx, &ff_emu_edge_vfix20_mmx, &ff_emu_edge_vfix21_mmx, + &ff_emu_edge_vfix22_mmx +}; +#endif +extern emu_edge_vvar_func ff_emu_edge_vvar_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix16_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix17_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix18_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix19_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix20_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix21_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix22_sse; +static emu_edge_vfix_func * const vfixtbl_sse[22] = { + ff_emu_edge_vfix1_mmx, ff_emu_edge_vfix2_mmx, ff_emu_edge_vfix3_mmx, + ff_emu_edge_vfix4_mmx, ff_emu_edge_vfix5_mmx, ff_emu_edge_vfix6_mmx, + ff_emu_edge_vfix7_mmx, ff_emu_edge_vfix8_mmx, ff_emu_edge_vfix9_mmx, + ff_emu_edge_vfix10_mmx, ff_emu_edge_vfix11_mmx, ff_emu_edge_vfix12_mmx, + ff_emu_edge_vfix13_mmx, ff_emu_edge_vfix14_mmx, ff_emu_edge_vfix15_mmx, + ff_emu_edge_vfix16_sse, ff_emu_edge_vfix17_sse, ff_emu_edge_vfix18_sse, + ff_emu_edge_vfix19_sse, ff_emu_edge_vfix20_sse, ff_emu_edge_vfix21_sse, + ff_emu_edge_vfix22_sse +}; +extern emu_edge_vvar_func ff_emu_edge_vvar_sse; + +typedef void emu_edge_hfix_func(uint8_t *dst, x86_reg dst_stride, + x86_reg start_x, x86_reg bh); +typedef void emu_edge_hvar_func(uint8_t *dst, x86_reg dst_stride, + x86_reg start_x, x86_reg n_words, x86_reg bh); + +extern emu_edge_hfix_func ff_emu_edge_hfix2_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix4_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix6_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix8_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix10_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix12_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix14_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix16_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix18_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix20_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix22_mmx; +#if ARCH_X86_32 +static emu_edge_hfix_func * const hfixtbl_mmx[11] = { + ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, + ff_emu_edge_hfix8_mmx, ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx, + ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_mmx, ff_emu_edge_hfix18_mmx, + ff_emu_edge_hfix20_mmx, ff_emu_edge_hfix22_mmx +}; +#endif +extern emu_edge_hvar_func ff_emu_edge_hvar_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix16_sse2; +extern emu_edge_hfix_func ff_emu_edge_hfix18_sse2; +extern emu_edge_hfix_func ff_emu_edge_hfix20_sse2; +extern emu_edge_hfix_func ff_emu_edge_hfix22_sse2; +static emu_edge_hfix_func * const hfixtbl_sse2[11] = { + ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, + ff_emu_edge_hfix8_mmx, ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx, + ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_sse2, ff_emu_edge_hfix18_sse2, + ff_emu_edge_hfix20_sse2, ff_emu_edge_hfix22_sse2 +}; +extern emu_edge_hvar_func ff_emu_edge_hvar_sse2; +#if HAVE_AVX2_EXTERNAL +extern emu_edge_hfix_func ff_emu_edge_hfix8_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix10_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix12_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix14_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix16_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix18_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix20_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix22_avx2; +static emu_edge_hfix_func * const hfixtbl_avx2[11] = { + ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, + ff_emu_edge_hfix8_avx2, ff_emu_edge_hfix10_avx2, ff_emu_edge_hfix12_avx2, + ff_emu_edge_hfix14_avx2, ff_emu_edge_hfix16_avx2, ff_emu_edge_hfix18_avx2, + ff_emu_edge_hfix20_avx2, ff_emu_edge_hfix22_avx2 +}; +extern emu_edge_hvar_func ff_emu_edge_hvar_avx2; +#endif + +static av_always_inline void emulated_edge_mc(uint8_t *dst, const uint8_t *src, + ptrdiff_t dst_stride, + ptrdiff_t src_stride, + x86_reg block_w, x86_reg block_h, + x86_reg src_x, x86_reg src_y, + x86_reg w, x86_reg h, + emu_edge_vfix_func * const *vfix_tbl, + emu_edge_vvar_func *v_extend_var, + emu_edge_hfix_func * const *hfix_tbl, + emu_edge_hvar_func *h_extend_var) +{ + x86_reg start_y, start_x, end_y, end_x, src_y_add = 0, p; + + if (!w || !h) + return; + + av_assert2(block_w <= FFABS(dst_stride)); + + if (src_y >= h) { + src -= src_y*src_stride; + src_y_add = h - 1; + src_y = h - 1; + } else if (src_y <= -block_h) { + src -= src_y*src_stride; + src_y_add = 1 - block_h; + src_y = 1 - block_h; + } + if (src_x >= w) { + src += w - 1 - src_x; + src_x = w - 1; + } else if (src_x <= -block_w) { + src += 1 - block_w - src_x; + src_x = 1 - block_w; + } + + start_y = FFMAX(0, -src_y); + start_x = FFMAX(0, -src_x); + end_y = FFMIN(block_h, h-src_y); + end_x = FFMIN(block_w, w-src_x); + av_assert2(start_x < end_x && block_w > 0); + av_assert2(start_y < end_y && block_h > 0); + + // fill in the to-be-copied part plus all above/below + src += (src_y_add + start_y) * src_stride + start_x; + w = end_x - start_x; + if (w <= 22) { + vfix_tbl[w - 1](dst + start_x, dst_stride, src, src_stride, + start_y, end_y, block_h); + } else { + v_extend_var(dst + start_x, dst_stride, src, src_stride, + start_y, end_y, block_h, w); + } + + // fill left + if (start_x) { + if (start_x <= 22) { + hfix_tbl[(start_x - 1) >> 1](dst, dst_stride, start_x, block_h); + } else { + h_extend_var(dst, dst_stride, + start_x, (start_x + 1) >> 1, block_h); + } + } + + // fill right + p = block_w - end_x; + if (p) { + if (p <= 22) { + hfix_tbl[(p - 1) >> 1](dst + end_x - (p & 1), dst_stride, + -!(p & 1), block_h); + } else { + h_extend_var(dst + end_x - (p & 1), dst_stride, + -!(p & 1), (p + 1) >> 1, block_h); + } + } +} + +#if ARCH_X86_32 +static av_noinline void emulated_edge_mc_mmx(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, + int block_w, int block_h, + int src_x, int src_y, int w, int h) +{ + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_mmx, &ff_emu_edge_vvar_mmx, + hfixtbl_mmx, &ff_emu_edge_hvar_mmx); +} + +static av_noinline void emulated_edge_mc_sse(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, + int block_w, int block_h, + int src_x, int src_y, int w, int h) +{ + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse, + hfixtbl_mmx, &ff_emu_edge_hvar_mmx); +} +#endif + +static av_noinline void emulated_edge_mc_sse2(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, + int block_w, int block_h, + int src_x, int src_y, int w, + int h) +{ + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse, + hfixtbl_sse2, &ff_emu_edge_hvar_sse2); +} + +#if HAVE_AVX2_EXTERNAL +static av_noinline void emulated_edge_mc_avx2(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, + int block_w, int block_h, + int src_x, int src_y, int w, + int h) +{ + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse, + hfixtbl_avx2, &ff_emu_edge_hvar_avx2); +} +#endif /* HAVE_AVX2_EXTERNAL */ +#endif /* HAVE_X86ASM */ + +void ff_prefetch_mmxext(uint8_t *buf, ptrdiff_t stride, int h); +void ff_prefetch_3dnow(uint8_t *buf, ptrdiff_t stride, int h); + +av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags) && bpc <= 8) { + ctx->emulated_edge_mc = emulated_edge_mc_mmx; + } + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + ctx->prefetch = ff_prefetch_3dnow; + } +#endif /* ARCH_X86_32 */ + if (EXTERNAL_MMXEXT(cpu_flags)) { + ctx->prefetch = ff_prefetch_mmxext; + } +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags) && bpc <= 8) { + ctx->emulated_edge_mc = emulated_edge_mc_sse; + } +#endif /* ARCH_X86_32 */ + if (EXTERNAL_SSE2(cpu_flags) && bpc <= 8) { + ctx->emulated_edge_mc = emulated_edge_mc_sse2; + } +#if HAVE_AVX2_EXTERNAL + if (EXTERNAL_AVX2(cpu_flags) && bpc <= 8) { + ctx->emulated_edge_mc = emulated_edge_mc_avx2; + } +#endif +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vorbisdsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vorbisdsp_init.c new file mode 100644 index 000000000..bc1cc43a1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vorbisdsp_init.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vorbisdsp.h" + +void ff_vorbis_inverse_coupling_3dnow(float *mag, float *ang, + intptr_t blocksize); +void ff_vorbis_inverse_coupling_sse(float *mag, float *ang, + intptr_t blocksize); + +av_cold void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_AMD3DNOW(cpu_flags)) + dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_3dnow; +#endif /* ARCH_X86_32 */ + if (EXTERNAL_SSE(cpu_flags)) + dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_sse; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp3dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp3dsp_init.c new file mode 100644 index 000000000..1ba957643 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp3dsp_init.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009 David Conrad + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/vp3dsp.h" + +void ff_vp3_idct_put_mmx(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vp3_idct_add_mmx(uint8_t *dest, ptrdiff_t stride, int16_t *block); + +void ff_vp3_idct_put_sse2(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vp3_idct_add_sse2(uint8_t *dest, ptrdiff_t stride, int16_t *block); + +void ff_vp3_idct_dc_add_mmxext(uint8_t *dest, ptrdiff_t stride, int16_t *block); + +void ff_vp3_v_loop_filter_mmxext(uint8_t *src, ptrdiff_t stride, + int *bounding_values); +void ff_vp3_h_loop_filter_mmxext(uint8_t *src, ptrdiff_t stride, + int *bounding_values); + +void ff_put_vp_no_rnd_pixels8_l2_mmx(uint8_t *dst, const uint8_t *a, + const uint8_t *b, ptrdiff_t stride, + int h); + +av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->put_no_rnd_pixels_l2 = ff_put_vp_no_rnd_pixels8_l2_mmx; +#if ARCH_X86_32 + c->idct_put = ff_vp3_idct_put_mmx; + c->idct_add = ff_vp3_idct_add_mmx; +#endif + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->idct_dc_add = ff_vp3_idct_dc_add_mmxext; + + if (!(flags & AV_CODEC_FLAG_BITEXACT)) { + c->v_loop_filter = ff_vp3_v_loop_filter_mmxext; + c->h_loop_filter = ff_vp3_h_loop_filter_mmxext; + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct_put = ff_vp3_idct_put_sse2; + c->idct_add = ff_vp3_idct_add_sse2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp56_arith.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp56_arith.h new file mode 100644 index 000000000..810cc8dcd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp56_arith.h @@ -0,0 +1,51 @@ +/** + * VP5 and VP6 compatible video decoder (arith decoder) + * + * Copyright (C) 2006 Aurelien Jacobs + * Copyright (C) 2010 Eli Friedman + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_VP56_ARITH_H +#define AVCODEC_X86_VP56_ARITH_H + +#if HAVE_INLINE_ASM && HAVE_FAST_CMOV && HAVE_6REGS +#define vp56_rac_get_prob vp56_rac_get_prob +static av_always_inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob) +{ + unsigned int code_word = vp56_rac_renorm(c); + unsigned int low = 1 + (((c->high - 1) * prob) >> 8); + unsigned int low_shift = low << 16; + int bit = 0; + c->code_word = code_word; + + __asm__( + "subl %4, %1 \n\t" + "subl %3, %2 \n\t" + "setae %b0 \n\t" + "cmovb %4, %1 \n\t" + "cmovb %5, %2 \n\t" + : "+q"(bit), "+&r"(c->high), "+&r"(c->code_word) + : "r"(low_shift), "r"(low), "r"(code_word) + ); + + return bit; +} +#endif + +#endif /* AVCODEC_X86_VP56_ARITH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp6dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp6dsp_init.c new file mode 100644 index 000000000..ce498931d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp6dsp_init.c @@ -0,0 +1,45 @@ +/* + * VP6 MMX/SSE2 optimizations + * Copyright (C) 2009 Sebastien Lucas + * Copyright (C) 2009 Zuxy Meng + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp56dsp.h" + +void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + const int16_t *h_weights,const int16_t *v_weights); +void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + const int16_t *h_weights,const int16_t *v_weights); + +av_cold void ff_vp6dsp_init_x86(VP56DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags)) { + c->vp6_filter_diag4 = ff_vp6_filter_diag4_mmx; + } +#endif + if (EXTERNAL_SSE2(cpu_flags)) { + c->vp6_filter_diag4 = ff_vp6_filter_diag4_sse2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp8dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp8dsp_init.c new file mode 100644 index 000000000..397b2518c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp8dsp_init.c @@ -0,0 +1,467 @@ +/* + * VP8 DSP functions x86-optimized + * Copyright (c) 2010 Ronald S. Bultje + * Copyright (c) 2010 Fiona Glaser + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp8dsp.h" + +#if HAVE_X86ASM + +/* + * MC functions + */ +void ff_put_vp8_epel4_h4_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_h6_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v4_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v6_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_epel8_h4_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_h6_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v4_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v6_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_epel4_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_bilinear4_h_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_h_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear4_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_bilinear4_v_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_v_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear4_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + + +void ff_put_vp8_pixels8_mmx (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_pixels16_mmx(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_pixels16_sse(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +#define TAP_W16(OPT, FILTERTYPE, TAPTYPE) \ +static void ff_put_vp8_ ## FILTERTYPE ## 16_ ## TAPTYPE ## _ ## OPT( \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ +{ \ + ff_put_vp8_ ## FILTERTYPE ## 8_ ## TAPTYPE ## _ ## OPT( \ + dst, dststride, src, srcstride, height, mx, my); \ + ff_put_vp8_ ## FILTERTYPE ## 8_ ## TAPTYPE ## _ ## OPT( \ + dst + 8, dststride, src + 8, srcstride, height, mx, my); \ +} +#define TAP_W8(OPT, FILTERTYPE, TAPTYPE) \ +static void ff_put_vp8_ ## FILTERTYPE ## 8_ ## TAPTYPE ## _ ## OPT( \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ +{ \ + ff_put_vp8_ ## FILTERTYPE ## 4_ ## TAPTYPE ## _ ## OPT( \ + dst, dststride, src, srcstride, height, mx, my); \ + ff_put_vp8_ ## FILTERTYPE ## 4_ ## TAPTYPE ## _ ## OPT( \ + dst + 4, dststride, src + 4, srcstride, height, mx, my); \ +} + +#if ARCH_X86_32 +TAP_W8 (mmxext, epel, h4) +TAP_W8 (mmxext, epel, h6) +TAP_W16(mmxext, epel, h6) +TAP_W8 (mmxext, epel, v4) +TAP_W8 (mmxext, epel, v6) +TAP_W16(mmxext, epel, v6) +TAP_W8 (mmxext, bilinear, h) +TAP_W16(mmxext, bilinear, h) +TAP_W8 (mmxext, bilinear, v) +TAP_W16(mmxext, bilinear, v) +#endif + +TAP_W16(sse2, epel, h6) +TAP_W16(sse2, epel, v6) +TAP_W16(sse2, bilinear, h) +TAP_W16(sse2, bilinear, v) + +TAP_W16(ssse3, epel, h6) +TAP_W16(ssse3, epel, v6) +TAP_W16(ssse3, bilinear, h) +TAP_W16(ssse3, bilinear, v) + +#define HVTAP(OPT, ALIGN, TAPNUMX, TAPNUMY, SIZE, MAXHEIGHT) \ +static void ff_put_vp8_epel ## SIZE ## _h ## TAPNUMX ## v ## TAPNUMY ## _ ## OPT( \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ +{ \ + LOCAL_ALIGNED(ALIGN, uint8_t, tmp, [SIZE * (MAXHEIGHT + TAPNUMY - 1)]); \ + uint8_t *tmpptr = tmp + SIZE * (TAPNUMY / 2 - 1); \ + src -= srcstride * (TAPNUMY / 2 - 1); \ + ff_put_vp8_epel ## SIZE ## _h ## TAPNUMX ## _ ## OPT( \ + tmp, SIZE, src, srcstride, height + TAPNUMY - 1, mx, my); \ + ff_put_vp8_epel ## SIZE ## _v ## TAPNUMY ## _ ## OPT( \ + dst, dststride, tmpptr, SIZE, height, mx, my); \ +} + +#if ARCH_X86_32 +#define HVTAPMMX(x, y) \ +HVTAP(mmxext, 8, x, y, 4, 8) \ +HVTAP(mmxext, 8, x, y, 8, 16) + +HVTAP(mmxext, 8, 6, 6, 16, 16) +#else +#define HVTAPMMX(x, y) \ +HVTAP(mmxext, 8, x, y, 4, 8) +#endif + +HVTAPMMX(4, 4) +HVTAPMMX(4, 6) +HVTAPMMX(6, 4) +HVTAPMMX(6, 6) + +#define HVTAPSSE2(x, y, w) \ +HVTAP(sse2, 16, x, y, w, 16) \ +HVTAP(ssse3, 16, x, y, w, 16) + +HVTAPSSE2(4, 4, 8) +HVTAPSSE2(4, 6, 8) +HVTAPSSE2(6, 4, 8) +HVTAPSSE2(6, 6, 8) +HVTAPSSE2(6, 6, 16) + +HVTAP(ssse3, 16, 4, 4, 4, 8) +HVTAP(ssse3, 16, 4, 6, 4, 8) +HVTAP(ssse3, 16, 6, 4, 4, 8) +HVTAP(ssse3, 16, 6, 6, 4, 8) + +#define HVBILIN(OPT, ALIGN, SIZE, MAXHEIGHT) \ +static void ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT( \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ +{ \ + LOCAL_ALIGNED(ALIGN, uint8_t, tmp, [SIZE * (MAXHEIGHT + 2)]); \ + ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT( \ + tmp, SIZE, src, srcstride, height + 1, mx, my); \ + ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT( \ + dst, dststride, tmp, SIZE, height, mx, my); \ +} + +HVBILIN(mmxext, 8, 4, 8) +#if ARCH_X86_32 +HVBILIN(mmxext, 8, 8, 16) +HVBILIN(mmxext, 8, 16, 16) +#endif +HVBILIN(sse2, 8, 8, 16) +HVBILIN(sse2, 8, 16, 16) +HVBILIN(ssse3, 8, 4, 8) +HVBILIN(ssse3, 8, 8, 16) +HVBILIN(ssse3, 8, 16, 16) + +void ff_vp8_idct_dc_add_mmx(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add_sse2(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add_sse4(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, int16_t block[4][16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, int16_t block[4][16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, int16_t block[2][16], + ptrdiff_t stride); +void ff_vp8_luma_dc_wht_mmx(int16_t block[4][4][16], int16_t dc[16]); +void ff_vp8_luma_dc_wht_sse(int16_t block[4][4][16], int16_t dc[16]); +void ff_vp8_idct_add_mmx(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +void ff_vp8_idct_add_sse(uint8_t *dst, int16_t block[16], ptrdiff_t stride); + +#define DECLARE_LOOP_FILTER(NAME) \ +void ff_vp8_v_loop_filter_simple_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim); \ +void ff_vp8_h_loop_filter_simple_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim); \ +void ff_vp8_v_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_v_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); \ +void ff_vp8_v_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_v_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); + +DECLARE_LOOP_FILTER(mmx) +DECLARE_LOOP_FILTER(mmxext) +DECLARE_LOOP_FILTER(sse2) +DECLARE_LOOP_FILTER(ssse3) +DECLARE_LOOP_FILTER(sse4) + +#endif /* HAVE_X86ASM */ + +#define VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) \ + c->put_vp8_epel_pixels_tab[IDX][0][2] = ff_put_vp8_epel ## SIZE ## _h6_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][2][0] = ff_put_vp8_epel ## SIZE ## _v6_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][2][2] = ff_put_vp8_epel ## SIZE ## _h6v6_ ## OPT + +#define VP8_MC_FUNC(IDX, SIZE, OPT) \ + c->put_vp8_epel_pixels_tab[IDX][0][1] = ff_put_vp8_epel ## SIZE ## _h4_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][1][0] = ff_put_vp8_epel ## SIZE ## _v4_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][1][1] = ff_put_vp8_epel ## SIZE ## _h4v4_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][1][2] = ff_put_vp8_epel ## SIZE ## _h6v4_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][2][1] = ff_put_vp8_epel ## SIZE ## _h4v6_ ## OPT; \ + VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) + +#define VP8_BILINEAR_MC_FUNC(IDX, SIZE, OPT) \ + c->put_vp8_bilinear_pixels_tab[IDX][0][1] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][0][2] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][1][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][1][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][1][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][2][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][2][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][2][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT + + +av_cold void ff_vp78dsp_init_x86(VP8DSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { +#if ARCH_X86_32 + c->put_vp8_epel_pixels_tab[0][0][0] = + c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmx; +#endif + c->put_vp8_epel_pixels_tab[1][0][0] = + c->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmx; + } + + /* note that 4-tap width=16 functions are missing because w=16 + * is only used for luma, and luma is always a copy or sixtap. */ + if (EXTERNAL_MMXEXT(cpu_flags)) { + VP8_MC_FUNC(2, 4, mmxext); + VP8_BILINEAR_MC_FUNC(2, 4, mmxext); +#if ARCH_X86_32 + VP8_LUMA_MC_FUNC(0, 16, mmxext); + VP8_MC_FUNC(1, 8, mmxext); + VP8_BILINEAR_MC_FUNC(0, 16, mmxext); + VP8_BILINEAR_MC_FUNC(1, 8, mmxext); +#endif + } + + if (EXTERNAL_SSE(cpu_flags)) { + c->put_vp8_epel_pixels_tab[0][0][0] = + c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse; + } + + if (EXTERNAL_SSE2(cpu_flags) || EXTERNAL_SSE2_SLOW(cpu_flags)) { + VP8_LUMA_MC_FUNC(0, 16, sse2); + VP8_MC_FUNC(1, 8, sse2); + VP8_BILINEAR_MC_FUNC(0, 16, sse2); + VP8_BILINEAR_MC_FUNC(1, 8, sse2); + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + VP8_LUMA_MC_FUNC(0, 16, ssse3); + VP8_MC_FUNC(1, 8, ssse3); + VP8_MC_FUNC(2, 4, ssse3); + VP8_BILINEAR_MC_FUNC(0, 16, ssse3); + VP8_BILINEAR_MC_FUNC(1, 8, ssse3); + VP8_BILINEAR_MC_FUNC(2, 4, ssse3); + } +#endif /* HAVE_X86ASM */ +} + +av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx; +#if ARCH_X86_32 + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; + c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmx; + c->vp8_idct_add = ff_vp8_idct_add_mmx; + c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_mmx; + + c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmx; + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmx; + + c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmx; + c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmx; + c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmx; + c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmx; + + c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_mmx; + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_mmx; + c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_mmx; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_mmx; +#endif + } + + /* note that 4-tap width=16 functions are missing because w=16 + * is only used for luma, and luma is always a copy or sixtap. */ + if (EXTERNAL_MMXEXT(cpu_flags)) { +#if ARCH_X86_32 + c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmxext; + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmxext; + + c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmxext; + c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmxext; + c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmxext; + c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmxext; + + c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_mmxext; + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_mmxext; + c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_mmxext; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_mmxext; +#endif + } + + if (EXTERNAL_SSE(cpu_flags)) { + c->vp8_idct_add = ff_vp8_idct_add_sse; + c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_sse; + } + + if (EXTERNAL_SSE2(cpu_flags) || EXTERNAL_SSE2_SLOW(cpu_flags)) { + c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_sse2; + + c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_sse2; + c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_sse2; + + c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_sse2; + c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_sse2; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse2; + c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_sse2; + + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2; + + c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_sse2; + c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_sse2; + + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse2; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse2; + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_ssse3; + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_ssse3; + + c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_ssse3; + c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_ssse3; + c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_ssse3; + c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_ssse3; + + c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_ssse3; + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_ssse3; + c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_ssse3; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_ssse3; + } + + if (EXTERNAL_SSE4(cpu_flags)) { + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse4; + + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse4; + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse4; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse4; + } +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init.c new file mode 100644 index 000000000..837cce850 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init.c @@ -0,0 +1,416 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp9dsp.h" +#include "libavcodec/x86/vp9dsp_init.h" + +#if HAVE_X86ASM + +decl_fpel_func(put, 4, , mmx); +decl_fpel_func(put, 8, , mmx); +decl_fpel_func(put, 16, , sse); +decl_fpel_func(put, 32, , sse); +decl_fpel_func(put, 64, , sse); +decl_fpel_func(avg, 4, _8, mmxext); +decl_fpel_func(avg, 8, _8, mmxext); +decl_fpel_func(avg, 16, _8, sse2); +decl_fpel_func(avg, 32, _8, sse2); +decl_fpel_func(avg, 64, _8, sse2); +decl_fpel_func(put, 32, , avx); +decl_fpel_func(put, 64, , avx); +decl_fpel_func(avg, 32, _8, avx2); +decl_fpel_func(avg, 64, _8, avx2); + +decl_mc_funcs(4, mmxext, int16_t, 8, 8); +decl_mc_funcs(8, sse2, int16_t, 8, 8); +decl_mc_funcs(4, ssse3, int8_t, 32, 8); +decl_mc_funcs(8, ssse3, int8_t, 32, 8); +#if ARCH_X86_64 +decl_mc_funcs(16, ssse3, int8_t, 32, 8); +decl_mc_funcs(32, avx2, int8_t, 32, 8); +#endif + +mc_rep_funcs(16, 8, 8, sse2, int16_t, 8, 8) +#if ARCH_X86_32 +mc_rep_funcs(16, 8, 8, ssse3, int8_t, 32, 8) +#endif +mc_rep_funcs(32, 16, 16, sse2, int16_t, 8, 8) +mc_rep_funcs(32, 16, 16, ssse3, int8_t, 32, 8) +mc_rep_funcs(64, 32, 32, sse2, int16_t, 8, 8) +mc_rep_funcs(64, 32, 32, ssse3, int8_t, 32, 8) +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +mc_rep_funcs(64, 32, 32, avx2, int8_t, 32, 8) +#endif + +extern const int8_t ff_filters_ssse3[3][15][4][32]; +extern const int16_t ff_filters_sse2[3][15][8][8]; + +filters_8tap_2d_fn2(put, 16, 8, 1, mmxext, sse2, sse2) +filters_8tap_2d_fn2(avg, 16, 8, 1, mmxext, sse2, sse2) +filters_8tap_2d_fn2(put, 16, 8, 1, ssse3, ssse3, ssse3) +filters_8tap_2d_fn2(avg, 16, 8, 1, ssse3, ssse3, ssse3) +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +filters_8tap_2d_fn(put, 64, 32, 8, 1, avx2, ssse3) +filters_8tap_2d_fn(put, 32, 32, 8, 1, avx2, ssse3) +filters_8tap_2d_fn(avg, 64, 32, 8, 1, avx2, ssse3) +filters_8tap_2d_fn(avg, 32, 32, 8, 1, avx2, ssse3) +#endif + +filters_8tap_1d_fn3(put, 8, mmxext, sse2, sse2) +filters_8tap_1d_fn3(avg, 8, mmxext, sse2, sse2) +filters_8tap_1d_fn3(put, 8, ssse3, ssse3, ssse3) +filters_8tap_1d_fn3(avg, 8, ssse3, ssse3, ssse3) +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +filters_8tap_1d_fn2(put, 64, 8, avx2, ssse3) +filters_8tap_1d_fn2(put, 32, 8, avx2, ssse3) +filters_8tap_1d_fn2(avg, 64, 8, avx2, ssse3) +filters_8tap_1d_fn2(avg, 32, 8, avx2, ssse3) +#endif + +#define itxfm_func(typea, typeb, size, opt) \ +void ff_vp9_##typea##_##typeb##_##size##x##size##_add_##opt(uint8_t *dst, ptrdiff_t stride, \ + int16_t *block, int eob) +#define itxfm_funcs(size, opt) \ +itxfm_func(idct, idct, size, opt); \ +itxfm_func(iadst, idct, size, opt); \ +itxfm_func(idct, iadst, size, opt); \ +itxfm_func(iadst, iadst, size, opt) + +itxfm_func(idct, idct, 4, mmxext); +itxfm_func(idct, iadst, 4, sse2); +itxfm_func(iadst, idct, 4, sse2); +itxfm_func(iadst, iadst, 4, sse2); +itxfm_funcs(4, ssse3); +itxfm_funcs(8, sse2); +itxfm_funcs(8, ssse3); +itxfm_funcs(8, avx); +itxfm_funcs(16, sse2); +itxfm_funcs(16, ssse3); +itxfm_funcs(16, avx); +itxfm_func(idct, idct, 32, sse2); +itxfm_func(idct, idct, 32, ssse3); +itxfm_func(idct, idct, 32, avx); +itxfm_func(iwht, iwht, 4, mmx); +itxfm_funcs(16, avx2); +itxfm_func(idct, idct, 32, avx2); + +#undef itxfm_func +#undef itxfm_funcs + +#define lpf_funcs(size1, size2, opt) \ +void ff_vp9_loop_filter_v_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H); \ +void ff_vp9_loop_filter_h_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H) + +lpf_funcs(4, 8, mmxext); +lpf_funcs(8, 8, mmxext); +lpf_funcs(16, 16, sse2); +lpf_funcs(16, 16, ssse3); +lpf_funcs(16, 16, avx); +lpf_funcs(44, 16, sse2); +lpf_funcs(44, 16, ssse3); +lpf_funcs(44, 16, avx); +lpf_funcs(84, 16, sse2); +lpf_funcs(84, 16, ssse3); +lpf_funcs(84, 16, avx); +lpf_funcs(48, 16, sse2); +lpf_funcs(48, 16, ssse3); +lpf_funcs(48, 16, avx); +lpf_funcs(88, 16, sse2); +lpf_funcs(88, 16, ssse3); +lpf_funcs(88, 16, avx); + +#undef lpf_funcs + +#define ipred_func(size, type, opt) \ +void ff_vp9_ipred_##type##_##size##x##size##_##opt(uint8_t *dst, ptrdiff_t stride, \ + const uint8_t *l, const uint8_t *a) + +ipred_func(8, v, mmx); + +#define ipred_dc_funcs(size, opt) \ +ipred_func(size, dc, opt); \ +ipred_func(size, dc_left, opt); \ +ipred_func(size, dc_top, opt) + +ipred_dc_funcs(4, mmxext); +ipred_dc_funcs(8, mmxext); + +#define ipred_dir_tm_funcs(size, opt) \ +ipred_func(size, tm, opt); \ +ipred_func(size, dl, opt); \ +ipred_func(size, dr, opt); \ +ipred_func(size, hd, opt); \ +ipred_func(size, hu, opt); \ +ipred_func(size, vl, opt); \ +ipred_func(size, vr, opt) + +ipred_dir_tm_funcs(4, mmxext); + +ipred_func(16, v, sse); +ipred_func(32, v, sse); + +ipred_dc_funcs(16, sse2); +ipred_dc_funcs(32, sse2); + +#define ipred_dir_tm_h_funcs(size, opt) \ +ipred_dir_tm_funcs(size, opt); \ +ipred_func(size, h, opt) + +ipred_dir_tm_h_funcs(8, sse2); +ipred_dir_tm_h_funcs(16, sse2); +ipred_dir_tm_h_funcs(32, sse2); + +ipred_func(4, h, sse2); + +#define ipred_all_funcs(size, opt) \ +ipred_dc_funcs(size, opt); \ +ipred_dir_tm_h_funcs(size, opt) + +// FIXME hd/vl_4x4_ssse3 does not exist +ipred_all_funcs(4, ssse3); +ipred_all_funcs(8, ssse3); +ipred_all_funcs(16, ssse3); +ipred_all_funcs(32, ssse3); + +ipred_dir_tm_h_funcs(8, avx); +ipred_dir_tm_h_funcs(16, avx); +ipred_dir_tm_h_funcs(32, avx); + +ipred_func(32, v, avx); + +ipred_dc_funcs(32, avx2); +ipred_func(32, h, avx2); +ipred_func(32, tm, avx2); + +#undef ipred_func +#undef ipred_dir_tm_h_funcs +#undef ipred_dir_tm_funcs +#undef ipred_dc_funcs + +#endif /* HAVE_X86ASM */ + +av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact) +{ +#if HAVE_X86ASM + int cpu_flags; + + if (bpp == 10) { + ff_vp9dsp_init_10bpp_x86(dsp, bitexact); + return; + } else if (bpp == 12) { + ff_vp9dsp_init_12bpp_x86(dsp, bitexact); + return; + } + + cpu_flags = av_get_cpu_flags(); + +#define init_lpf(opt) do { \ + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \ + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ + dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \ + dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ + dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \ + dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \ + dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \ + dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_##opt; \ + dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_##opt; \ + dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_##opt; \ +} while (0) + +#define init_ipred(sz, opt, t, e) \ + dsp->intra_pred[TX_##sz##X##sz][e##_PRED] = ff_vp9_ipred_##t##_##sz##x##sz##_##opt + +#define ff_vp9_ipred_hd_4x4_ssse3 ff_vp9_ipred_hd_4x4_mmxext +#define ff_vp9_ipred_vl_4x4_ssse3 ff_vp9_ipred_vl_4x4_mmxext +#define init_dir_tm_ipred(sz, opt) do { \ + init_ipred(sz, opt, dl, DIAG_DOWN_LEFT); \ + init_ipred(sz, opt, dr, DIAG_DOWN_RIGHT); \ + init_ipred(sz, opt, hd, HOR_DOWN); \ + init_ipred(sz, opt, vl, VERT_LEFT); \ + init_ipred(sz, opt, hu, HOR_UP); \ + init_ipred(sz, opt, tm, TM_VP8); \ + init_ipred(sz, opt, vr, VERT_RIGHT); \ +} while (0) +#define init_dir_tm_h_ipred(sz, opt) do { \ + init_dir_tm_ipred(sz, opt); \ + init_ipred(sz, opt, h, HOR); \ +} while (0) +#define init_dc_ipred(sz, opt) do { \ + init_ipred(sz, opt, dc, DC); \ + init_ipred(sz, opt, dc_left, LEFT_DC); \ + init_ipred(sz, opt, dc_top, TOP_DC); \ +} while (0) +#define init_all_ipred(sz, opt) do { \ + init_dc_ipred(sz, opt); \ + init_dir_tm_h_ipred(sz, opt); \ +} while (0) + + if (EXTERNAL_MMX(cpu_flags)) { + init_fpel_func(4, 0, 4, put, , mmx); + init_fpel_func(3, 0, 8, put, , mmx); + if (!bitexact) { + dsp->itxfm_add[4 /* lossless */][DCT_DCT] = + dsp->itxfm_add[4 /* lossless */][ADST_DCT] = + dsp->itxfm_add[4 /* lossless */][DCT_ADST] = + dsp->itxfm_add[4 /* lossless */][ADST_ADST] = ff_vp9_iwht_iwht_4x4_add_mmx; + } + init_ipred(8, mmx, v, VERT); + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + dsp->loop_filter_8[0][0] = ff_vp9_loop_filter_h_4_8_mmxext; + dsp->loop_filter_8[0][1] = ff_vp9_loop_filter_v_4_8_mmxext; + dsp->loop_filter_8[1][0] = ff_vp9_loop_filter_h_8_8_mmxext; + dsp->loop_filter_8[1][1] = ff_vp9_loop_filter_v_8_8_mmxext; + init_subpel2(4, 0, 4, put, 8, mmxext); + init_subpel2(4, 1, 4, avg, 8, mmxext); + init_fpel_func(4, 1, 4, avg, _8, mmxext); + init_fpel_func(3, 1, 8, avg, _8, mmxext); + dsp->itxfm_add[TX_4X4][DCT_DCT] = ff_vp9_idct_idct_4x4_add_mmxext; + init_dc_ipred(4, mmxext); + init_dc_ipred(8, mmxext); + init_dir_tm_ipred(4, mmxext); + } + + if (EXTERNAL_SSE(cpu_flags)) { + init_fpel_func(2, 0, 16, put, , sse); + init_fpel_func(1, 0, 32, put, , sse); + init_fpel_func(0, 0, 64, put, , sse); + init_ipred(16, sse, v, VERT); + init_ipred(32, sse, v, VERT); + } + + if (EXTERNAL_SSE2(cpu_flags)) { + init_subpel3_8to64(0, put, 8, sse2); + init_subpel3_8to64(1, avg, 8, sse2); + init_fpel_func(2, 1, 16, avg, _8, sse2); + init_fpel_func(1, 1, 32, avg, _8, sse2); + init_fpel_func(0, 1, 64, avg, _8, sse2); + init_lpf(sse2); + dsp->itxfm_add[TX_4X4][ADST_DCT] = ff_vp9_idct_iadst_4x4_add_sse2; + dsp->itxfm_add[TX_4X4][DCT_ADST] = ff_vp9_iadst_idct_4x4_add_sse2; + dsp->itxfm_add[TX_4X4][ADST_ADST] = ff_vp9_iadst_iadst_4x4_add_sse2; + dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_sse2; + dsp->itxfm_add[TX_8X8][ADST_DCT] = ff_vp9_idct_iadst_8x8_add_sse2; + dsp->itxfm_add[TX_8X8][DCT_ADST] = ff_vp9_iadst_idct_8x8_add_sse2; + dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_sse2; + dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_sse2; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_sse2; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_sse2; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_sse2; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = + dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_sse2; + init_dc_ipred(16, sse2); + init_dc_ipred(32, sse2); + init_dir_tm_h_ipred(8, sse2); + init_dir_tm_h_ipred(16, sse2); + init_dir_tm_h_ipred(32, sse2); + init_ipred(4, sse2, h, HOR); + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + init_subpel3(0, put, 8, ssse3); + init_subpel3(1, avg, 8, ssse3); + dsp->itxfm_add[TX_4X4][DCT_DCT] = ff_vp9_idct_idct_4x4_add_ssse3; + dsp->itxfm_add[TX_4X4][ADST_DCT] = ff_vp9_idct_iadst_4x4_add_ssse3; + dsp->itxfm_add[TX_4X4][DCT_ADST] = ff_vp9_iadst_idct_4x4_add_ssse3; + dsp->itxfm_add[TX_4X4][ADST_ADST] = ff_vp9_iadst_iadst_4x4_add_ssse3; + dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_ssse3; + dsp->itxfm_add[TX_8X8][ADST_DCT] = ff_vp9_idct_iadst_8x8_add_ssse3; + dsp->itxfm_add[TX_8X8][DCT_ADST] = ff_vp9_iadst_idct_8x8_add_ssse3; + dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_ssse3; + dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_ssse3; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_ssse3; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_ssse3; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_ssse3; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = + dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_ssse3; + init_lpf(ssse3); + init_all_ipred(4, ssse3); + init_all_ipred(8, ssse3); + init_all_ipred(16, ssse3); + init_all_ipred(32, ssse3); + } + + if (EXTERNAL_AVX(cpu_flags)) { + dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_avx; + dsp->itxfm_add[TX_8X8][ADST_DCT] = ff_vp9_idct_iadst_8x8_add_avx; + dsp->itxfm_add[TX_8X8][DCT_ADST] = ff_vp9_iadst_idct_8x8_add_avx; + dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_avx; + dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_avx; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_avx; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_avx; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_avx; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = + dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_avx; + init_lpf(avx); + init_dir_tm_h_ipred(8, avx); + init_dir_tm_h_ipred(16, avx); + init_dir_tm_h_ipred(32, avx); + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + init_fpel_func(1, 0, 32, put, , avx); + init_fpel_func(0, 0, 64, put, , avx); + init_ipred(32, avx, v, VERT); + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + init_fpel_func(1, 1, 32, avg, _8, avx2); + init_fpel_func(0, 1, 64, avg, _8, avx2); + if (ARCH_X86_64) { +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL + dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_avx2; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = + dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_avx2; + init_subpel3_32_64(0, put, 8, avx2); + init_subpel3_32_64(1, avg, 8, avx2); +#endif + } + init_dc_ipred(32, avx2); + init_ipred(32, avx2, h, HOR); + init_ipred(32, avx2, tm, TM_VP8); + } + +#undef init_fpel +#undef init_subpel1 +#undef init_subpel2 +#undef init_subpel3 + +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init.h new file mode 100644 index 000000000..e410cab3a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init.h @@ -0,0 +1,189 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_VP9DSP_INIT_H +#define AVCODEC_X86_VP9DSP_INIT_H + +#include "libavcodec/vp9dsp.h" + +// hack to force-expand BPC +#define cat(a, bpp, b) a##bpp##b + +#define decl_fpel_func(avg, sz, bpp, opt) \ +void ff_vp9_##avg##sz##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define decl_mc_func(avg, sz, dir, opt, type, f_sz, bpp) \ +void ff_vp9_##avg##_8tap_1d_##dir##_##sz##_##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, const type (*filter)[f_sz]) + +#define decl_mc_funcs(sz, opt, type, fsz, bpp) \ +decl_mc_func(put, sz, h, opt, type, fsz, bpp); \ +decl_mc_func(avg, sz, h, opt, type, fsz, bpp); \ +decl_mc_func(put, sz, v, opt, type, fsz, bpp); \ +decl_mc_func(avg, sz, v, opt, type, fsz, bpp) + +#define decl_ipred_fn(type, sz, bpp, opt) \ +void ff_vp9_ipred_##type##_##sz##x##sz##_##bpp##_##opt(uint8_t *dst, \ + ptrdiff_t stride, \ + const uint8_t *l, \ + const uint8_t *a) + +#define decl_ipred_fns(type, bpp, opt4, opt8_16_32) \ +decl_ipred_fn(type, 4, bpp, opt4); \ +decl_ipred_fn(type, 8, bpp, opt8_16_32); \ +decl_ipred_fn(type, 16, bpp, opt8_16_32); \ +decl_ipred_fn(type, 32, bpp, opt8_16_32) + +#define decl_itxfm_func(typea, typeb, size, bpp, opt) \ +void cat(ff_vp9_##typea##_##typeb##_##size##x##size##_add_, bpp, _##opt)(uint8_t *dst, \ + ptrdiff_t stride, \ + int16_t *block, \ + int eob) + +#define decl_itxfm_funcs(size, bpp, opt) \ +decl_itxfm_func(idct, idct, size, bpp, opt); \ +decl_itxfm_func(iadst, idct, size, bpp, opt); \ +decl_itxfm_func(idct, iadst, size, bpp, opt); \ +decl_itxfm_func(iadst, iadst, size, bpp, opt) + +#define mc_rep_func(avg, sz, hsz, hszb, dir, opt, type, f_sz, bpp) \ +static av_always_inline void \ +ff_vp9_##avg##_8tap_1d_##dir##_##sz##_##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, const type (*filter)[f_sz]) \ +{ \ + ff_vp9_##avg##_8tap_1d_##dir##_##hsz##_##bpp##_##opt(dst, dst_stride, src, \ + src_stride, h, filter); \ + ff_vp9_##avg##_8tap_1d_##dir##_##hsz##_##bpp##_##opt(dst + hszb, dst_stride, src + hszb, \ + src_stride, h, filter); \ +} + +#define mc_rep_funcs(sz, hsz, hszb, opt, type, fsz, bpp) \ +mc_rep_func(put, sz, hsz, hszb, h, opt, type, fsz, bpp) \ +mc_rep_func(avg, sz, hsz, hszb, h, opt, type, fsz, bpp) \ +mc_rep_func(put, sz, hsz, hszb, v, opt, type, fsz, bpp) \ +mc_rep_func(avg, sz, hsz, hszb, v, opt, type, fsz, bpp) + +#define filter_8tap_1d_fn(op, sz, f, f_opt, fname, dir, dvar, bpp, opt) \ +static void op##_8tap_##fname##_##sz##dir##_##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + ff_vp9_##op##_8tap_1d_##dir##_##sz##_##bpp##_##opt(dst, dst_stride, src, src_stride, \ + h, ff_filters_##f_opt[f][dvar - 1]); \ +} + +#define filters_8tap_1d_fn(op, sz, dir, dvar, bpp, opt, f_opt) \ +filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, f_opt, regular, dir, dvar, bpp, opt) \ +filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, f_opt, sharp, dir, dvar, bpp, opt) \ +filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, f_opt, smooth, dir, dvar, bpp, opt) + +#define filters_8tap_1d_fn2(op, sz, bpp, opt, f_opt) \ +filters_8tap_1d_fn(op, sz, h, mx, bpp, opt, f_opt) \ +filters_8tap_1d_fn(op, sz, v, my, bpp, opt, f_opt) + +#define filters_8tap_1d_fn3(op, bpp, opt4, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 64, bpp, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 32, bpp, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 16, bpp, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 8, bpp, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 4, bpp, opt4, f_opt) + +#define filter_8tap_2d_fn(op, sz, f, f_opt, fname, align, bpp, bytes, opt) \ +static void op##_8tap_##fname##_##sz##hv_##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + LOCAL_ALIGNED_##align(uint8_t, temp, [71 * 64 * bytes]); \ + ff_vp9_put_8tap_1d_h_##sz##_##bpp##_##opt(temp, 64 * bytes, src - 3 * src_stride, \ + src_stride, h + 7, \ + ff_filters_##f_opt[f][mx - 1]); \ + ff_vp9_##op##_8tap_1d_v_##sz##_##bpp##_##opt(dst, dst_stride, temp + 3 * bytes * 64, \ + 64 * bytes, h, \ + ff_filters_##f_opt[f][my - 1]); \ +} + +#define filters_8tap_2d_fn(op, sz, align, bpp, bytes, opt, f_opt) \ +filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, f_opt, regular, align, bpp, bytes, opt) \ +filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, f_opt, sharp, align, bpp, bytes, opt) \ +filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, f_opt, smooth, align, bpp, bytes, opt) + +#define filters_8tap_2d_fn2(op, align, bpp, bytes, opt4, opt8, f_opt) \ +filters_8tap_2d_fn(op, 64, align, bpp, bytes, opt8, f_opt) \ +filters_8tap_2d_fn(op, 32, align, bpp, bytes, opt8, f_opt) \ +filters_8tap_2d_fn(op, 16, align, bpp, bytes, opt8, f_opt) \ +filters_8tap_2d_fn(op, 8, align, bpp, bytes, opt8, f_opt) \ +filters_8tap_2d_fn(op, 4, align, bpp, bytes, opt4, f_opt) + +#define init_fpel_func(idx1, idx2, sz, type, bpp, opt) \ + dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_BILINEAR ][idx2][0][0] = ff_vp9_##type##sz##bpp##_##opt + +#define init_subpel1(idx1, idx2, idxh, idxv, sz, dir, type, bpp, opt) \ + dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][idxh][idxv] = \ + type##_8tap_smooth_##sz##dir##_##bpp##_##opt; \ + dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = \ + type##_8tap_regular_##sz##dir##_##bpp##_##opt; \ + dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][idxh][idxv] = \ + type##_8tap_sharp_##sz##dir##_##bpp##_##opt + +#define init_subpel2(idx1, idx2, sz, type, bpp, opt) \ + init_subpel1(idx1, idx2, 1, 1, sz, hv, type, bpp, opt); \ + init_subpel1(idx1, idx2, 0, 1, sz, v, type, bpp, opt); \ + init_subpel1(idx1, idx2, 1, 0, sz, h, type, bpp, opt) + +#define init_subpel3_32_64(idx, type, bpp, opt) \ + init_subpel2(0, idx, 64, type, bpp, opt); \ + init_subpel2(1, idx, 32, type, bpp, opt) + +#define init_subpel3_8to64(idx, type, bpp, opt) \ + init_subpel3_32_64(idx, type, bpp, opt); \ + init_subpel2(2, idx, 16, type, bpp, opt); \ + init_subpel2(3, idx, 8, type, bpp, opt) + +#define init_subpel3(idx, type, bpp, opt) \ + init_subpel3_8to64(idx, type, bpp, opt); \ + init_subpel2(4, idx, 4, type, bpp, opt) + +#define init_ipred_func(type, enum, sz, bpp, opt) \ + dsp->intra_pred[TX_##sz##X##sz][enum##_PRED] = \ + cat(ff_vp9_ipred_##type##_##sz##x##sz##_, bpp, _##opt) + +#define init_8_16_32_ipred_funcs(type, enum, bpp, opt) \ + init_ipred_func(type, enum, 8, bpp, opt); \ + init_ipred_func(type, enum, 16, bpp, opt); \ + init_ipred_func(type, enum, 32, bpp, opt) + +#define init_ipred_funcs(type, enum, bpp, opt) \ + init_ipred_func(type, enum, 4, bpp, opt); \ + init_8_16_32_ipred_funcs(type, enum, bpp, opt) + +void ff_vp9dsp_init_10bpp_x86(VP9DSPContext *dsp, int bitexact); +void ff_vp9dsp_init_12bpp_x86(VP9DSPContext *dsp, int bitexact); +void ff_vp9dsp_init_16bpp_x86(VP9DSPContext *dsp); + +#endif /* AVCODEC_X86_VP9DSP_INIT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_10bpp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_10bpp.c new file mode 100644 index 000000000..2694c06cb --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_10bpp.c @@ -0,0 +1,25 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define BPC 10 +#define INIT_FUNC ff_vp9dsp_init_10bpp_x86 +#include "vp9dsp_init_16bpp_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_12bpp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_12bpp.c new file mode 100644 index 000000000..5da3bc184 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_12bpp.c @@ -0,0 +1,25 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define BPC 12 +#define INIT_FUNC ff_vp9dsp_init_12bpp_x86 +#include "vp9dsp_init_16bpp_template.c" diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_16bpp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_16bpp.c new file mode 100644 index 000000000..60d10a12a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_16bpp.c @@ -0,0 +1,149 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp9dsp.h" +#include "libavcodec/x86/vp9dsp_init.h" + +#if HAVE_X86ASM + +decl_fpel_func(put, 8, , mmx); +decl_fpel_func(avg, 8, _16, mmxext); +decl_fpel_func(put, 16, , sse); +decl_fpel_func(put, 32, , sse); +decl_fpel_func(put, 64, , sse); +decl_fpel_func(put, 128, , sse); +decl_fpel_func(avg, 16, _16, sse2); +decl_fpel_func(avg, 32, _16, sse2); +decl_fpel_func(avg, 64, _16, sse2); +decl_fpel_func(avg, 128, _16, sse2); +decl_fpel_func(put, 32, , avx); +decl_fpel_func(put, 64, , avx); +decl_fpel_func(put, 128, , avx); +decl_fpel_func(avg, 32, _16, avx2); +decl_fpel_func(avg, 64, _16, avx2); +decl_fpel_func(avg, 128, _16, avx2); + +decl_ipred_fns(v, 16, mmx, sse); +decl_ipred_fns(h, 16, mmxext, sse2); +decl_ipred_fns(dc, 16, mmxext, sse2); +decl_ipred_fns(dc_top, 16, mmxext, sse2); +decl_ipred_fns(dc_left, 16, mmxext, sse2); +decl_ipred_fn(dl, 16, 16, avx2); +decl_ipred_fn(dl, 32, 16, avx2); +decl_ipred_fn(dr, 16, 16, avx2); +decl_ipred_fn(dr, 32, 16, avx2); + +#define decl_ipred_dir_funcs(type) \ +decl_ipred_fns(type, 16, sse2, sse2); \ +decl_ipred_fns(type, 16, ssse3, ssse3); \ +decl_ipred_fns(type, 16, avx, avx) + +decl_ipred_dir_funcs(dl); +decl_ipred_dir_funcs(dr); +decl_ipred_dir_funcs(vl); +decl_ipred_dir_funcs(vr); +decl_ipred_dir_funcs(hu); +decl_ipred_dir_funcs(hd); +#endif /* HAVE_X86ASM */ + +av_cold void ff_vp9dsp_init_16bpp_x86(VP9DSPContext *dsp) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + init_fpel_func(4, 0, 8, put, , mmx); + init_ipred_func(v, VERT, 4, 16, mmx); + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + init_fpel_func(4, 1, 8, avg, _16, mmxext); + init_ipred_func(h, HOR, 4, 16, mmxext); + init_ipred_func(dc, DC, 4, 16, mmxext); + init_ipred_func(dc_top, TOP_DC, 4, 16, mmxext); + init_ipred_func(dc_left, LEFT_DC, 4, 16, mmxext); + } + + if (EXTERNAL_SSE(cpu_flags)) { + init_fpel_func(3, 0, 16, put, , sse); + init_fpel_func(2, 0, 32, put, , sse); + init_fpel_func(1, 0, 64, put, , sse); + init_fpel_func(0, 0, 128, put, , sse); + init_8_16_32_ipred_funcs(v, VERT, 16, sse); + } + + if (EXTERNAL_SSE2(cpu_flags)) { + init_fpel_func(3, 1, 16, avg, _16, sse2); + init_fpel_func(2, 1, 32, avg, _16, sse2); + init_fpel_func(1, 1, 64, avg, _16, sse2); + init_fpel_func(0, 1, 128, avg, _16, sse2); + init_8_16_32_ipred_funcs(h, HOR, 16, sse2); + init_8_16_32_ipred_funcs(dc, DC, 16, sse2); + init_8_16_32_ipred_funcs(dc_top, TOP_DC, 16, sse2); + init_8_16_32_ipred_funcs(dc_left, LEFT_DC, 16, sse2); + init_ipred_funcs(dl, DIAG_DOWN_LEFT, 16, sse2); + init_ipred_funcs(dr, DIAG_DOWN_RIGHT, 16, sse2); + init_ipred_funcs(vl, VERT_LEFT, 16, sse2); + init_ipred_funcs(vr, VERT_RIGHT, 16, sse2); + init_ipred_funcs(hu, HOR_UP, 16, sse2); + init_ipred_funcs(hd, HOR_DOWN, 16, sse2); + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + init_ipred_funcs(dl, DIAG_DOWN_LEFT, 16, ssse3); + init_ipred_funcs(dr, DIAG_DOWN_RIGHT, 16, ssse3); + init_ipred_funcs(vl, VERT_LEFT, 16, ssse3); + init_ipred_funcs(vr, VERT_RIGHT, 16, ssse3); + init_ipred_funcs(hu, HOR_UP, 16, ssse3); + init_ipred_funcs(hd, HOR_DOWN, 16, ssse3); + } + + if (EXTERNAL_AVX_FAST(cpu_flags)) { + init_fpel_func(2, 0, 32, put, , avx); + init_fpel_func(1, 0, 64, put, , avx); + init_fpel_func(0, 0, 128, put, , avx); + init_ipred_funcs(dl, DIAG_DOWN_LEFT, 16, avx); + init_ipred_funcs(dr, DIAG_DOWN_RIGHT, 16, avx); + init_ipred_funcs(vl, VERT_LEFT, 16, avx); + init_ipred_funcs(vr, VERT_RIGHT, 16, avx); + init_ipred_funcs(hu, HOR_UP, 16, avx); + init_ipred_funcs(hd, HOR_DOWN, 16, avx); + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + init_fpel_func(2, 1, 32, avg, _16, avx2); + init_fpel_func(1, 1, 64, avg, _16, avx2); + init_fpel_func(0, 1, 128, avg, _16, avx2); + init_ipred_func(dl, DIAG_DOWN_LEFT, 16, 16, avx2); + init_ipred_func(dl, DIAG_DOWN_LEFT, 32, 16, avx2); + init_ipred_func(dr, DIAG_DOWN_RIGHT, 16, 16, avx2); +#if ARCH_X86_64 + init_ipred_func(dr, DIAG_DOWN_RIGHT, 32, 16, avx2); +#endif + } + +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_16bpp_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_16bpp_template.c new file mode 100644 index 000000000..b56afc7f5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/vp9dsp_init_16bpp_template.c @@ -0,0 +1,240 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp9dsp.h" +#include "libavcodec/x86/vp9dsp_init.h" + +#if HAVE_X86ASM + +extern const int16_t ff_filters_16bpp[3][15][4][16]; + +decl_mc_funcs(4, sse2, int16_t, 16, BPC); +decl_mc_funcs(8, sse2, int16_t, 16, BPC); +decl_mc_funcs(16, avx2, int16_t, 16, BPC); + +mc_rep_funcs(16, 8, 16, sse2, int16_t, 16, BPC) +mc_rep_funcs(32, 16, 32, sse2, int16_t, 16, BPC) +mc_rep_funcs(64, 32, 64, sse2, int16_t, 16, BPC) +#if HAVE_AVX2_EXTERNAL +mc_rep_funcs(32, 16, 32, avx2, int16_t, 16, BPC) +mc_rep_funcs(64, 32, 64, avx2, int16_t, 16, BPC) +#endif + +filters_8tap_2d_fn2(put, 16, BPC, 2, sse2, sse2, 16bpp) +filters_8tap_2d_fn2(avg, 16, BPC, 2, sse2, sse2, 16bpp) +#if HAVE_AVX2_EXTERNAL +filters_8tap_2d_fn(put, 64, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(avg, 64, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(put, 32, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(avg, 32, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(put, 16, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(avg, 16, 32, BPC, 2, avx2, 16bpp) +#endif + +filters_8tap_1d_fn3(put, BPC, sse2, sse2, 16bpp) +filters_8tap_1d_fn3(avg, BPC, sse2, sse2, 16bpp) +#if HAVE_AVX2_EXTERNAL +filters_8tap_1d_fn2(put, 64, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(avg, 64, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(put, 32, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(avg, 32, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(put, 16, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(avg, 16, BPC, avx2, 16bpp) +#endif + +#define decl_lpf_func(dir, wd, bpp, opt) \ +void ff_vp9_loop_filter_##dir##_##wd##_##bpp##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H) + +#define decl_lpf_funcs(dir, wd, bpp) \ +decl_lpf_func(dir, wd, bpp, sse2); \ +decl_lpf_func(dir, wd, bpp, ssse3); \ +decl_lpf_func(dir, wd, bpp, avx) + +#define decl_lpf_funcs_wd(dir) \ +decl_lpf_funcs(dir, 4, BPC); \ +decl_lpf_funcs(dir, 8, BPC); \ +decl_lpf_funcs(dir, 16, BPC) + +decl_lpf_funcs_wd(h); +decl_lpf_funcs_wd(v); + +#define lpf_16_wrapper(dir, off, bpp, opt) \ +static void loop_filter_##dir##_16_##bpp##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H) \ +{ \ + ff_vp9_loop_filter_##dir##_16_##bpp##_##opt(dst, stride, E, I, H); \ + ff_vp9_loop_filter_##dir##_16_##bpp##_##opt(dst + off, stride, E, I, H); \ +} + +#define lpf_16_wrappers(bpp, opt) \ +lpf_16_wrapper(h, 8 * stride, bpp, opt) \ +lpf_16_wrapper(v, 16, bpp, opt) + +lpf_16_wrappers(BPC, sse2) +lpf_16_wrappers(BPC, ssse3) +lpf_16_wrappers(BPC, avx) + +#define lpf_mix2_wrapper(dir, off, wd1, wd2, bpp, opt) \ +static void loop_filter_##dir##_##wd1##wd2##_##bpp##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H) \ +{ \ + ff_vp9_loop_filter_##dir##_##wd1##_##bpp##_##opt(dst, stride, \ + E & 0xff, I & 0xff, H & 0xff); \ + ff_vp9_loop_filter_##dir##_##wd2##_##bpp##_##opt(dst + off, stride, \ + E >> 8, I >> 8, H >> 8); \ +} + +#define lpf_mix2_wrappers(wd1, wd2, bpp, opt) \ +lpf_mix2_wrapper(h, 8 * stride, wd1, wd2, bpp, opt) \ +lpf_mix2_wrapper(v, 16, wd1, wd2, bpp, opt) + +#define lpf_mix2_wrappers_set(bpp, opt) \ +lpf_mix2_wrappers(4, 4, bpp, opt) \ +lpf_mix2_wrappers(4, 8, bpp, opt) \ +lpf_mix2_wrappers(8, 4, bpp, opt) \ +lpf_mix2_wrappers(8, 8, bpp, opt) \ + +lpf_mix2_wrappers_set(BPC, sse2) +lpf_mix2_wrappers_set(BPC, ssse3) +lpf_mix2_wrappers_set(BPC, avx) + +decl_ipred_fns(tm, BPC, mmxext, sse2); + +decl_itxfm_func(iwht, iwht, 4, BPC, mmxext); +#if BPC == 10 +decl_itxfm_func(idct, idct, 4, BPC, mmxext); +decl_itxfm_funcs(4, BPC, ssse3); +#else +decl_itxfm_func(idct, idct, 4, BPC, sse2); +#endif +decl_itxfm_func(idct, iadst, 4, BPC, sse2); +decl_itxfm_func(iadst, idct, 4, BPC, sse2); +decl_itxfm_func(iadst, iadst, 4, BPC, sse2); +decl_itxfm_funcs(8, BPC, sse2); +decl_itxfm_funcs(16, BPC, sse2); +decl_itxfm_func(idct, idct, 32, BPC, sse2); +#endif /* HAVE_X86ASM */ + +av_cold void INIT_FUNC(VP9DSPContext *dsp, int bitexact) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + +#define init_lpf_8_func(idx1, idx2, dir, wd, bpp, opt) \ + dsp->loop_filter_8[idx1][idx2] = ff_vp9_loop_filter_##dir##_##wd##_##bpp##_##opt +#define init_lpf_16_func(idx, dir, bpp, opt) \ + dsp->loop_filter_16[idx] = loop_filter_##dir##_16_##bpp##_##opt +#define init_lpf_mix2_func(idx1, idx2, idx3, dir, wd1, wd2, bpp, opt) \ + dsp->loop_filter_mix2[idx1][idx2][idx3] = loop_filter_##dir##_##wd1##wd2##_##bpp##_##opt + +#define init_lpf_funcs(bpp, opt) \ + init_lpf_8_func(0, 0, h, 4, bpp, opt); \ + init_lpf_8_func(0, 1, v, 4, bpp, opt); \ + init_lpf_8_func(1, 0, h, 8, bpp, opt); \ + init_lpf_8_func(1, 1, v, 8, bpp, opt); \ + init_lpf_8_func(2, 0, h, 16, bpp, opt); \ + init_lpf_8_func(2, 1, v, 16, bpp, opt); \ + init_lpf_16_func(0, h, bpp, opt); \ + init_lpf_16_func(1, v, bpp, opt); \ + init_lpf_mix2_func(0, 0, 0, h, 4, 4, bpp, opt); \ + init_lpf_mix2_func(0, 1, 0, h, 4, 8, bpp, opt); \ + init_lpf_mix2_func(1, 0, 0, h, 8, 4, bpp, opt); \ + init_lpf_mix2_func(1, 1, 0, h, 8, 8, bpp, opt); \ + init_lpf_mix2_func(0, 0, 1, v, 4, 4, bpp, opt); \ + init_lpf_mix2_func(0, 1, 1, v, 4, 8, bpp, opt); \ + init_lpf_mix2_func(1, 0, 1, v, 8, 4, bpp, opt); \ + init_lpf_mix2_func(1, 1, 1, v, 8, 8, bpp, opt) + +#define init_itx_func(idxa, idxb, typea, typeb, size, bpp, opt) \ + dsp->itxfm_add[idxa][idxb] = \ + cat(ff_vp9_##typea##_##typeb##_##size##x##size##_add_, bpp, _##opt); +#define init_itx_func_one(idx, typea, typeb, size, bpp, opt) \ + init_itx_func(idx, DCT_DCT, typea, typeb, size, bpp, opt); \ + init_itx_func(idx, ADST_DCT, typea, typeb, size, bpp, opt); \ + init_itx_func(idx, DCT_ADST, typea, typeb, size, bpp, opt); \ + init_itx_func(idx, ADST_ADST, typea, typeb, size, bpp, opt) +#define init_itx_funcs(idx, size, bpp, opt) \ + init_itx_func(idx, DCT_DCT, idct, idct, size, bpp, opt); \ + init_itx_func(idx, ADST_DCT, idct, iadst, size, bpp, opt); \ + init_itx_func(idx, DCT_ADST, iadst, idct, size, bpp, opt); \ + init_itx_func(idx, ADST_ADST, iadst, iadst, size, bpp, opt); \ + + if (EXTERNAL_MMXEXT(cpu_flags)) { + init_ipred_func(tm, TM_VP8, 4, BPC, mmxext); + if (!bitexact) { + init_itx_func_one(4 /* lossless */, iwht, iwht, 4, BPC, mmxext); +#if BPC == 10 + init_itx_func(TX_4X4, DCT_DCT, idct, idct, 4, 10, mmxext); +#endif + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + init_subpel3(0, put, BPC, sse2); + init_subpel3(1, avg, BPC, sse2); + init_lpf_funcs(BPC, sse2); + init_8_16_32_ipred_funcs(tm, TM_VP8, BPC, sse2); +#if BPC == 10 + if (!bitexact) { + init_itx_func(TX_4X4, ADST_DCT, idct, iadst, 4, 10, sse2); + init_itx_func(TX_4X4, DCT_ADST, iadst, idct, 4, 10, sse2); + init_itx_func(TX_4X4, ADST_ADST, iadst, iadst, 4, 10, sse2); + } +#else + init_itx_funcs(TX_4X4, 4, 12, sse2); +#endif + init_itx_funcs(TX_8X8, 8, BPC, sse2); + init_itx_funcs(TX_16X16, 16, BPC, sse2); + init_itx_func_one(TX_32X32, idct, idct, 32, BPC, sse2); + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + init_lpf_funcs(BPC, ssse3); +#if BPC == 10 + if (!bitexact) { + init_itx_funcs(TX_4X4, 4, BPC, ssse3); + } +#endif + } + + if (EXTERNAL_AVX(cpu_flags)) { + init_lpf_funcs(BPC, avx); + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { +#if HAVE_AVX2_EXTERNAL + init_subpel3_32_64(0, put, BPC, avx2); + init_subpel3_32_64(1, avg, BPC, avx2); + init_subpel2(2, 0, 16, put, BPC, avx2); + init_subpel2(2, 1, 16, avg, BPC, avx2); +#endif + } + +#endif /* HAVE_X86ASM */ + + ff_vp9dsp_init_16bpp_x86(dsp); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/xvididct.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/xvididct.h new file mode 100644 index 000000000..edb5ebfd3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/xvididct.h @@ -0,0 +1,44 @@ +/* + * XVID MPEG-4 VIDEO CODEC + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * header for Xvid IDCT functions + */ + +#ifndef AVCODEC_X86_XVIDIDCT_H +#define AVCODEC_X86_XVIDIDCT_H + +#include +#include + +void ff_xvid_idct_mmx(short *block); +void ff_xvid_idct_mmx_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_xvid_idct_mmx_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_xvid_idct_mmxext(short *block); +void ff_xvid_idct_mmxext_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_xvid_idct_mmxext_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_xvid_idct_sse2(short *block); +void ff_xvid_idct_put_sse2(uint8_t *dest, ptrdiff_t line_size, short *block); +void ff_xvid_idct_add_sse2(uint8_t *dest, ptrdiff_t line_size, short *block); + +#endif /* AVCODEC_X86_XVIDIDCT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/xvididct_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/xvididct_init.c new file mode 100644 index 000000000..a91b416b7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/xvididct_init.c @@ -0,0 +1,89 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/idctdsp.h" +#include "libavcodec/xvididct.h" + +#include "idctdsp.h" +#include "xvididct.h" + +#if ARCH_X86_32 && HAVE_X86ASM +static void xvid_idct_mmx_put(uint8_t *dest, ptrdiff_t line_size, short *block) +{ + ff_xvid_idct_mmx(block); + ff_put_pixels_clamped_mmx(block, dest, line_size); +} + +static void xvid_idct_mmx_add(uint8_t *dest, ptrdiff_t line_size, short *block) +{ + ff_xvid_idct_mmx(block); + ff_add_pixels_clamped_mmx(block, dest, line_size); +} + +static void xvid_idct_mmxext_put(uint8_t *dest, ptrdiff_t line_size, short *block) +{ + ff_xvid_idct_mmxext(block); + ff_put_pixels_clamped_mmx(block, dest, line_size); +} + +static void xvid_idct_mmxext_add(uint8_t *dest, ptrdiff_t line_size, short *block) +{ + ff_xvid_idct_mmxext(block); + ff_add_pixels_clamped_mmx(block, dest, line_size); +} +#endif + +av_cold void ff_xvid_idct_init_x86(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (high_bit_depth || + !(avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_XVID)) + return; + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags)) { + c->idct_put = xvid_idct_mmx_put; + c->idct_add = xvid_idct_mmx_add; + c->idct = ff_xvid_idct_mmx; + c->perm_type = FF_IDCT_PERM_NONE; + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->idct_put = xvid_idct_mmxext_put; + c->idct_add = xvid_idct_mmxext_add; + c->idct = ff_xvid_idct_mmxext; + c->perm_type = FF_IDCT_PERM_NONE; + } +#endif + + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct_put = ff_xvid_idct_put_sse2; + c->idct_add = ff_xvid_idct_add_sse2; + c->idct = ff_xvid_idct_sse2; + c->perm_type = FF_IDCT_PERM_SSE2; + } +#endif /* HAVE_X86ASM */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.c new file mode 100644 index 000000000..d072224b4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007 The FFmpeg Project + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/intreadwrite.h" +#include "xiph.h" + +int avpriv_split_xiph_headers(const uint8_t *extradata, int extradata_size, + int first_header_size, const uint8_t *header_start[3], + int header_len[3]) +{ + int i; + + if (extradata_size >= 6 && AV_RB16(extradata) == first_header_size) { + int overall_len = 6; + for (i=0; i<3; i++) { + header_len[i] = AV_RB16(extradata); + extradata += 2; + header_start[i] = extradata; + extradata += header_len[i]; + if (overall_len > extradata_size - header_len[i]) + return -1; + overall_len += header_len[i]; + } + } else if (extradata_size >= 3 && extradata_size < INT_MAX - 0x1ff && extradata[0] == 2) { + int overall_len = 3; + extradata++; + for (i=0; i<2; i++, extradata++) { + header_len[i] = 0; + for (; overall_len < extradata_size && *extradata==0xff; extradata++) { + header_len[i] += 0xff; + overall_len += 0xff + 1; + } + header_len[i] += *extradata; + overall_len += *extradata; + if (overall_len > extradata_size) + return -1; + } + header_len[2] = extradata_size - overall_len; + header_start[0] = extradata; + header_start[1] = header_start[0] + header_len[0]; + header_start[2] = header_start[1] + header_len[1]; + } else { + return -1; + } + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.h new file mode 100644 index 000000000..1741a51b6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xiph.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007 The FFmpeg Project + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_XIPH_H +#define AVCODEC_XIPH_H + +#include "libavutil/common.h" + +/** + * Split a single extradata buffer into the three headers that most + * Xiph codecs use. (e.g. Theora and Vorbis) + * Works both with Matroska's packing and lavc's packing. + * + * @param[in] extradata The single chunk that combines all three headers + * @param[in] extradata_size The size of the extradata buffer + * @param[in] first_header_size The size of the first header, used to + * differentiate between the Matroska packing and lavc packing. + * @param[out] header_start Pointers to the start of the three separate headers. + * @param[out] header_len The sizes of each of the three headers. + * @return On error a negative value is returned, on success zero. + */ +int avpriv_split_xiph_headers(const uint8_t *extradata, int extradata_size, + int first_header_size, const uint8_t *header_start[3], + int header_len[3]); + +#endif /* AVCODEC_XIPH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xvmc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xvmc.h new file mode 100644 index 000000000..465ee78d6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/xvmc.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2003 Ivan Kalvachev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_XVMC_H +#define AVCODEC_XVMC_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_xvmc + * Public libavcodec XvMC header. + */ + +#include + +#include "libavutil/attributes.h" +#include "version.h" +#include "avcodec.h" + +/** + * @defgroup lavc_codec_hwaccel_xvmc XvMC + * @ingroup lavc_codec_hwaccel + * + * @{ + */ + +#define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct + the number is 1337 speak for the letters IDCT MCo (motion compensation) */ + +struct attribute_deprecated xvmc_pix_fmt { + /** The field contains the special constant value AV_XVMC_ID. + It is used as a test that the application correctly uses the API, + and that there is no corruption caused by pixel routines. + - application - set during initialization + - libavcodec - unchanged + */ + int xvmc_id; + + /** Pointer to the block array allocated by XvMCCreateBlocks(). + The array has to be freed by XvMCDestroyBlocks(). + Each group of 64 values represents one data block of differential + pixel information (in MoCo mode) or coefficients for IDCT. + - application - set the pointer during initialization + - libavcodec - fills coefficients/pixel data into the array + */ + short* data_blocks; + + /** Pointer to the macroblock description array allocated by + XvMCCreateMacroBlocks() and freed by XvMCDestroyMacroBlocks(). + - application - set the pointer during initialization + - libavcodec - fills description data into the array + */ + XvMCMacroBlock* mv_blocks; + + /** Number of macroblock descriptions that can be stored in the mv_blocks + array. + - application - set during initialization + - libavcodec - unchanged + */ + int allocated_mv_blocks; + + /** Number of blocks that can be stored at once in the data_blocks array. + - application - set during initialization + - libavcodec - unchanged + */ + int allocated_data_blocks; + + /** Indicate that the hardware would interpret data_blocks as IDCT + coefficients and perform IDCT on them. + - application - set during initialization + - libavcodec - unchanged + */ + int idct; + + /** In MoCo mode it indicates that intra macroblocks are assumed to be in + unsigned format; same as the XVMC_INTRA_UNSIGNED flag. + - application - set during initialization + - libavcodec - unchanged + */ + int unsigned_intra; + + /** Pointer to the surface allocated by XvMCCreateSurface(). + It has to be freed by XvMCDestroySurface() on application exit. + It identifies the frame and its state on the video hardware. + - application - set during initialization + - libavcodec - unchanged + */ + XvMCSurface* p_surface; + +/** Set by the decoder before calling ff_draw_horiz_band(), + needed by the XvMCRenderSurface function. */ +//@{ + /** Pointer to the surface used as past reference + - application - unchanged + - libavcodec - set + */ + XvMCSurface* p_past_surface; + + /** Pointer to the surface used as future reference + - application - unchanged + - libavcodec - set + */ + XvMCSurface* p_future_surface; + + /** top/bottom field or frame + - application - unchanged + - libavcodec - set + */ + unsigned int picture_structure; + + /** XVMC_SECOND_FIELD - 1st or 2nd field in the sequence + - application - unchanged + - libavcodec - set + */ + unsigned int flags; +//}@ + + /** Number of macroblock descriptions in the mv_blocks array + that have already been passed to the hardware. + - application - zeroes it on get_buffer(). + A successful ff_draw_horiz_band() may increment it + with filled_mb_block_num or zero both. + - libavcodec - unchanged + */ + int start_mv_blocks_num; + + /** Number of new macroblock descriptions in the mv_blocks array (after + start_mv_blocks_num) that are filled by libavcodec and have to be + passed to the hardware. + - application - zeroes it on get_buffer() or after successful + ff_draw_horiz_band(). + - libavcodec - increment with one of each stored MB + */ + int filled_mv_blocks_num; + + /** Number of the next free data block; one data block consists of + 64 short values in the data_blocks array. + All blocks before this one have already been claimed by placing their + position into the corresponding block description structure field, + that are part of the mv_blocks array. + - application - zeroes it on get_buffer(). + A successful ff_draw_horiz_band() may zero it together + with start_mb_blocks_num. + - libavcodec - each decoded macroblock increases it by the number + of coded blocks it contains. + */ + int next_free_data_block_num; +}; + +/** + * @} + */ + +#endif /* AVCODEC_XVMC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/alldevices.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/alldevices.c new file mode 100644 index 000000000..863343325 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/alldevices.c @@ -0,0 +1,68 @@ +/* + * Register all the grabbing devices. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/thread.h" +#include "libavformat/internal.h" +#include "avdevice.h" + +/* devices */ +extern AVInputFormat ff_alsa_demuxer; +extern AVOutputFormat ff_alsa_muxer; +extern AVInputFormat ff_android_camera_demuxer; +extern AVInputFormat ff_avfoundation_demuxer; +extern AVInputFormat ff_bktr_demuxer; +extern AVOutputFormat ff_caca_muxer; +extern AVInputFormat ff_decklink_demuxer; +extern AVOutputFormat ff_decklink_muxer; +extern AVInputFormat ff_dshow_demuxer; +extern AVInputFormat ff_fbdev_demuxer; +extern AVOutputFormat ff_fbdev_muxer; +extern AVInputFormat ff_gdigrab_demuxer; +extern AVInputFormat ff_iec61883_demuxer; +extern AVInputFormat ff_jack_demuxer; +extern AVInputFormat ff_kmsgrab_demuxer; +extern AVInputFormat ff_lavfi_demuxer; +extern AVInputFormat ff_openal_demuxer; +extern AVOutputFormat ff_opengl_muxer; +extern AVInputFormat ff_oss_demuxer; +extern AVOutputFormat ff_oss_muxer; +extern AVInputFormat ff_pulse_demuxer; +extern AVOutputFormat ff_pulse_muxer; +extern AVOutputFormat ff_sdl2_muxer; +extern AVInputFormat ff_sndio_demuxer; +extern AVOutputFormat ff_sndio_muxer; +extern AVInputFormat ff_v4l2_demuxer; +extern AVOutputFormat ff_v4l2_muxer; +extern AVInputFormat ff_vfwcap_demuxer; +extern AVInputFormat ff_xcbgrab_demuxer; +extern AVOutputFormat ff_xv_muxer; + +/* external libraries */ +extern AVInputFormat ff_libcdio_demuxer; +extern AVInputFormat ff_libdc1394_demuxer; + +#include "libavdevice/outdev_list.c" +#include "libavdevice/indev_list.c" + +void avdevice_register_all(void) +{ + avpriv_register_devices(outdev_list, indev_list); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/indev_list.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/indev_list.c new file mode 100644 index 000000000..03ffb4036 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/indev_list.c @@ -0,0 +1,2 @@ +static const AVInputFormat * const indev_list[] = { + NULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/outdev_list.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/outdev_list.c new file mode 100644 index 000000000..d1b87ed7b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavdevice/outdev_list.c @@ -0,0 +1,2 @@ +static const AVOutputFormat * const outdev_list[] = { + NULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/allfilters.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/allfilters.c new file mode 100644 index 000000000..04a3df7d5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/allfilters.c @@ -0,0 +1,536 @@ +/* + * filter registration + * Copyright (c) 2008 Vitor Sessak + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/thread.h" +#include "avfilter.h" +#include "config.h" + +extern AVFilter ff_af_abench; +extern AVFilter ff_af_acompressor; +extern AVFilter ff_af_acontrast; +extern AVFilter ff_af_acopy; +extern AVFilter ff_af_acue; +extern AVFilter ff_af_acrossfade; +extern AVFilter ff_af_acrossover; +extern AVFilter ff_af_acrusher; +extern AVFilter ff_af_adeclick; +extern AVFilter ff_af_adeclip; +extern AVFilter ff_af_adelay; +extern AVFilter ff_af_aderivative; +extern AVFilter ff_af_aecho; +extern AVFilter ff_af_aemphasis; +extern AVFilter ff_af_aeval; +extern AVFilter ff_af_afade; +extern AVFilter ff_af_afftdn; +extern AVFilter ff_af_afftfilt; +extern AVFilter ff_af_afir; +extern AVFilter ff_af_aformat; +extern AVFilter ff_af_agate; +extern AVFilter ff_af_aiir; +extern AVFilter ff_af_aintegral; +extern AVFilter ff_af_ainterleave; +extern AVFilter ff_af_alimiter; +extern AVFilter ff_af_allpass; +extern AVFilter ff_af_aloop; +extern AVFilter ff_af_amerge; +extern AVFilter ff_af_ametadata; +extern AVFilter ff_af_amix; +extern AVFilter ff_af_amultiply; +extern AVFilter ff_af_anequalizer; +extern AVFilter ff_af_anlmdn; +extern AVFilter ff_af_anull; +extern AVFilter ff_af_apad; +extern AVFilter ff_af_aperms; +extern AVFilter ff_af_aphaser; +extern AVFilter ff_af_apulsator; +extern AVFilter ff_af_arealtime; +extern AVFilter ff_af_aresample; +extern AVFilter ff_af_areverse; +extern AVFilter ff_af_aselect; +extern AVFilter ff_af_asendcmd; +extern AVFilter ff_af_asetnsamples; +extern AVFilter ff_af_asetpts; +extern AVFilter ff_af_asetrate; +extern AVFilter ff_af_asettb; +extern AVFilter ff_af_ashowinfo; +extern AVFilter ff_af_asidedata; +extern AVFilter ff_af_asoftclip; +extern AVFilter ff_af_asplit; +extern AVFilter ff_af_asr; +extern AVFilter ff_af_astats; +extern AVFilter ff_af_astreamselect; +extern AVFilter ff_af_atempo; +extern AVFilter ff_af_atrim; +extern AVFilter ff_af_azmq; +extern AVFilter ff_af_bandpass; +extern AVFilter ff_af_bandreject; +extern AVFilter ff_af_bass; +extern AVFilter ff_af_biquad; +extern AVFilter ff_af_bs2b; +extern AVFilter ff_af_channelmap; +extern AVFilter ff_af_channelsplit; +extern AVFilter ff_af_chorus; +extern AVFilter ff_af_compand; +extern AVFilter ff_af_compensationdelay; +extern AVFilter ff_af_crossfeed; +extern AVFilter ff_af_crystalizer; +extern AVFilter ff_af_dcshift; +extern AVFilter ff_af_deesser; +extern AVFilter ff_af_drmeter; +extern AVFilter ff_af_dynaudnorm; +extern AVFilter ff_af_earwax; +extern AVFilter ff_af_ebur128; +extern AVFilter ff_af_equalizer; +extern AVFilter ff_af_extrastereo; +extern AVFilter ff_af_firequalizer; +extern AVFilter ff_af_flanger; +extern AVFilter ff_af_haas; +extern AVFilter ff_af_hdcd; +extern AVFilter ff_af_headphone; +extern AVFilter ff_af_highpass; +extern AVFilter ff_af_highshelf; +extern AVFilter ff_af_join; +extern AVFilter ff_af_ladspa; +extern AVFilter ff_af_loudnorm; +extern AVFilter ff_af_lowpass; +extern AVFilter ff_af_lowshelf; +extern AVFilter ff_af_lv2; +extern AVFilter ff_af_mcompand; +extern AVFilter ff_af_pan; +extern AVFilter ff_af_replaygain; +extern AVFilter ff_af_resample; +extern AVFilter ff_af_rubberband; +extern AVFilter ff_af_sidechaincompress; +extern AVFilter ff_af_sidechaingate; +extern AVFilter ff_af_silencedetect; +extern AVFilter ff_af_silenceremove; +extern AVFilter ff_af_sofalizer; +extern AVFilter ff_af_stereotools; +extern AVFilter ff_af_stereowiden; +extern AVFilter ff_af_superequalizer; +extern AVFilter ff_af_surround; +extern AVFilter ff_af_treble; +extern AVFilter ff_af_tremolo; +extern AVFilter ff_af_vibrato; +extern AVFilter ff_af_volume; +extern AVFilter ff_af_volumedetect; + +extern AVFilter ff_asrc_aevalsrc; +extern AVFilter ff_asrc_anoisesrc; +extern AVFilter ff_asrc_anullsrc; +extern AVFilter ff_asrc_flite; +extern AVFilter ff_asrc_hilbert; +extern AVFilter ff_asrc_sinc; +extern AVFilter ff_asrc_sine; + +extern AVFilter ff_asink_anullsink; + +extern AVFilter ff_vf_alphaextract; +extern AVFilter ff_vf_alphamerge; +extern AVFilter ff_vf_amplify; +extern AVFilter ff_vf_ass; +extern AVFilter ff_vf_atadenoise; +extern AVFilter ff_vf_avgblur; +extern AVFilter ff_vf_avgblur_opencl; +extern AVFilter ff_vf_bbox; +extern AVFilter ff_vf_bench; +extern AVFilter ff_vf_bitplanenoise; +extern AVFilter ff_vf_blackdetect; +extern AVFilter ff_vf_blackframe; +extern AVFilter ff_vf_blend; +extern AVFilter ff_vf_bm3d; +extern AVFilter ff_vf_boxblur; +extern AVFilter ff_vf_boxblur_opencl; +extern AVFilter ff_vf_bwdif; +extern AVFilter ff_vf_chromahold; +extern AVFilter ff_vf_chromakey; +extern AVFilter ff_vf_chromashift; +extern AVFilter ff_vf_ciescope; +extern AVFilter ff_vf_codecview; +extern AVFilter ff_vf_colorbalance; +extern AVFilter ff_vf_colorchannelmixer; +extern AVFilter ff_vf_colorkey; +extern AVFilter ff_vf_colorkey_opencl; +extern AVFilter ff_vf_colorhold; +extern AVFilter ff_vf_colorlevels; +extern AVFilter ff_vf_colormatrix; +extern AVFilter ff_vf_colorspace; +extern AVFilter ff_vf_convolution; +extern AVFilter ff_vf_convolution_opencl; +extern AVFilter ff_vf_convolve; +extern AVFilter ff_vf_copy; +extern AVFilter ff_vf_coreimage; +extern AVFilter ff_vf_cover_rect; +extern AVFilter ff_vf_crop; +extern AVFilter ff_vf_cropdetect; +extern AVFilter ff_vf_cue; +extern AVFilter ff_vf_curves; +extern AVFilter ff_vf_datascope; +extern AVFilter ff_vf_dctdnoiz; +extern AVFilter ff_vf_deband; +extern AVFilter ff_vf_deblock; +extern AVFilter ff_vf_decimate; +extern AVFilter ff_vf_deconvolve; +extern AVFilter ff_vf_dedot; +extern AVFilter ff_vf_deflate; +extern AVFilter ff_vf_deflicker; +extern AVFilter ff_vf_deinterlace_qsv; +extern AVFilter ff_vf_deinterlace_vaapi; +extern AVFilter ff_vf_dejudder; +extern AVFilter ff_vf_delogo; +extern AVFilter ff_vf_denoise_vaapi; +extern AVFilter ff_vf_derain; +extern AVFilter ff_vf_deshake; +extern AVFilter ff_vf_despill; +extern AVFilter ff_vf_detelecine; +extern AVFilter ff_vf_dilation; +extern AVFilter ff_vf_dilation_opencl; +extern AVFilter ff_vf_displace; +extern AVFilter ff_vf_doubleweave; +extern AVFilter ff_vf_drawbox; +extern AVFilter ff_vf_drawgraph; +extern AVFilter ff_vf_drawgrid; +extern AVFilter ff_vf_drawtext; +extern AVFilter ff_vf_edgedetect; +extern AVFilter ff_vf_elbg; +extern AVFilter ff_vf_entropy; +extern AVFilter ff_vf_eq; +extern AVFilter ff_vf_erosion; +extern AVFilter ff_vf_erosion_opencl; +extern AVFilter ff_vf_extractplanes; +extern AVFilter ff_vf_fade; +extern AVFilter ff_vf_fftdnoiz; +extern AVFilter ff_vf_fftfilt; +extern AVFilter ff_vf_field; +extern AVFilter ff_vf_fieldhint; +extern AVFilter ff_vf_fieldmatch; +extern AVFilter ff_vf_fieldorder; +extern AVFilter ff_vf_fillborders; +extern AVFilter ff_vf_find_rect; +extern AVFilter ff_vf_floodfill; +extern AVFilter ff_vf_format; +extern AVFilter ff_vf_fps; +extern AVFilter ff_vf_framepack; +extern AVFilter ff_vf_framerate; +extern AVFilter ff_vf_framestep; +extern AVFilter ff_vf_freezedetect; +extern AVFilter ff_vf_frei0r; +extern AVFilter ff_vf_fspp; +extern AVFilter ff_vf_gblur; +extern AVFilter ff_vf_geq; +extern AVFilter ff_vf_gradfun; +extern AVFilter ff_vf_graphmonitor; +extern AVFilter ff_vf_greyedge; +extern AVFilter ff_vf_haldclut; +extern AVFilter ff_vf_hflip; +extern AVFilter ff_vf_histeq; +extern AVFilter ff_vf_histogram; +extern AVFilter ff_vf_hqdn3d; +extern AVFilter ff_vf_hqx; +extern AVFilter ff_vf_hstack; +extern AVFilter ff_vf_hue; +extern AVFilter ff_vf_hwdownload; +extern AVFilter ff_vf_hwmap; +extern AVFilter ff_vf_hwupload; +extern AVFilter ff_vf_hwupload_cuda; +extern AVFilter ff_vf_hysteresis; +extern AVFilter ff_vf_idet; +extern AVFilter ff_vf_il; +extern AVFilter ff_vf_inflate; +extern AVFilter ff_vf_interlace; +extern AVFilter ff_vf_interleave; +extern AVFilter ff_vf_kerndeint; +extern AVFilter ff_vf_lagfun; +extern AVFilter ff_vf_lenscorrection; +extern AVFilter ff_vf_lensfun; +extern AVFilter ff_vf_libvmaf; +extern AVFilter ff_vf_limiter; +extern AVFilter ff_vf_loop; +extern AVFilter ff_vf_lumakey; +extern AVFilter ff_vf_lut; +extern AVFilter ff_vf_lut1d; +extern AVFilter ff_vf_lut2; +extern AVFilter ff_vf_lut3d; +extern AVFilter ff_vf_lutrgb; +extern AVFilter ff_vf_lutyuv; +extern AVFilter ff_vf_maskedclamp; +extern AVFilter ff_vf_maskedmerge; +extern AVFilter ff_vf_maskfun; +extern AVFilter ff_vf_mcdeint; +extern AVFilter ff_vf_mergeplanes; +extern AVFilter ff_vf_mestimate; +extern AVFilter ff_vf_metadata; +extern AVFilter ff_vf_midequalizer; +extern AVFilter ff_vf_minterpolate; +extern AVFilter ff_vf_mix; +extern AVFilter ff_vf_mpdecimate; +extern AVFilter ff_vf_negate; +extern AVFilter ff_vf_nlmeans; +extern AVFilter ff_vf_nlmeans_opencl; +extern AVFilter ff_vf_nnedi; +extern AVFilter ff_vf_noformat; +extern AVFilter ff_vf_noise; +extern AVFilter ff_vf_normalize; +extern AVFilter ff_vf_null; +extern AVFilter ff_vf_ocr; +extern AVFilter ff_vf_ocv; +extern AVFilter ff_vf_oscilloscope; +extern AVFilter ff_vf_overlay; +extern AVFilter ff_vf_overlay_opencl; +extern AVFilter ff_vf_overlay_qsv; +extern AVFilter ff_vf_owdenoise; +extern AVFilter ff_vf_pad; +extern AVFilter ff_vf_palettegen; +extern AVFilter ff_vf_paletteuse; +extern AVFilter ff_vf_perms; +extern AVFilter ff_vf_perspective; +extern AVFilter ff_vf_phase; +extern AVFilter ff_vf_pixdesctest; +extern AVFilter ff_vf_pixscope; +extern AVFilter ff_vf_pp; +extern AVFilter ff_vf_pp7; +extern AVFilter ff_vf_premultiply; +extern AVFilter ff_vf_prewitt; +extern AVFilter ff_vf_prewitt_opencl; +extern AVFilter ff_vf_procamp_vaapi; +extern AVFilter ff_vf_program_opencl; +extern AVFilter ff_vf_pseudocolor; +extern AVFilter ff_vf_psnr; +extern AVFilter ff_vf_pullup; +extern AVFilter ff_vf_qp; +extern AVFilter ff_vf_random; +extern AVFilter ff_vf_readeia608; +extern AVFilter ff_vf_readvitc; +extern AVFilter ff_vf_realtime; +extern AVFilter ff_vf_remap; +extern AVFilter ff_vf_removegrain; +extern AVFilter ff_vf_removelogo; +extern AVFilter ff_vf_repeatfields; +extern AVFilter ff_vf_reverse; +extern AVFilter ff_vf_rgbashift; +extern AVFilter ff_vf_roberts; +extern AVFilter ff_vf_roberts_opencl; +extern AVFilter ff_vf_rotate; +extern AVFilter ff_vf_sab; +extern AVFilter ff_vf_scale; +extern AVFilter ff_vf_scale_cuda; +extern AVFilter ff_vf_scale_npp; +extern AVFilter ff_vf_scale_qsv; +extern AVFilter ff_vf_scale_vaapi; +extern AVFilter ff_vf_scale2ref; +extern AVFilter ff_vf_select; +extern AVFilter ff_vf_selectivecolor; +extern AVFilter ff_vf_sendcmd; +extern AVFilter ff_vf_separatefields; +extern AVFilter ff_vf_setdar; +extern AVFilter ff_vf_setfield; +extern AVFilter ff_vf_setparams; +extern AVFilter ff_vf_setpts; +extern AVFilter ff_vf_setrange; +extern AVFilter ff_vf_setsar; +extern AVFilter ff_vf_settb; +extern AVFilter ff_vf_sharpness_vaapi; +extern AVFilter ff_vf_showinfo; +extern AVFilter ff_vf_showpalette; +extern AVFilter ff_vf_shuffleframes; +extern AVFilter ff_vf_shuffleplanes; +extern AVFilter ff_vf_sidedata; +extern AVFilter ff_vf_signalstats; +extern AVFilter ff_vf_signature; +extern AVFilter ff_vf_smartblur; +extern AVFilter ff_vf_sobel; +extern AVFilter ff_vf_sobel_opencl; +extern AVFilter ff_vf_split; +extern AVFilter ff_vf_spp; +extern AVFilter ff_vf_sr; +extern AVFilter ff_vf_ssim; +extern AVFilter ff_vf_stereo3d; +extern AVFilter ff_vf_streamselect; +extern AVFilter ff_vf_subtitles; +extern AVFilter ff_vf_super2xsai; +extern AVFilter ff_vf_swaprect; +extern AVFilter ff_vf_swapuv; +extern AVFilter ff_vf_tblend; +extern AVFilter ff_vf_telecine; +extern AVFilter ff_vf_threshold; +extern AVFilter ff_vf_thumbnail; +extern AVFilter ff_vf_thumbnail_cuda; +extern AVFilter ff_vf_tile; +extern AVFilter ff_vf_tinterlace; +extern AVFilter ff_vf_tlut2; +extern AVFilter ff_vf_tmix; +extern AVFilter ff_vf_tonemap; +extern AVFilter ff_vf_tonemap_opencl; +extern AVFilter ff_vf_tpad; +extern AVFilter ff_vf_transpose; +extern AVFilter ff_vf_transpose_npp; +extern AVFilter ff_vf_transpose_opencl; +extern AVFilter ff_vf_transpose_vaapi; +extern AVFilter ff_vf_trim; +extern AVFilter ff_vf_unpremultiply; +extern AVFilter ff_vf_unsharp; +extern AVFilter ff_vf_unsharp_opencl; +extern AVFilter ff_vf_uspp; +extern AVFilter ff_vf_vaguedenoiser; +extern AVFilter ff_vf_vectorscope; +extern AVFilter ff_vf_vflip; +extern AVFilter ff_vf_vfrdet; +extern AVFilter ff_vf_vibrance; +extern AVFilter ff_vf_vidstabdetect; +extern AVFilter ff_vf_vidstabtransform; +extern AVFilter ff_vf_vignette; +extern AVFilter ff_vf_vmafmotion; +extern AVFilter ff_vf_vpp_qsv; +extern AVFilter ff_vf_vstack; +extern AVFilter ff_vf_w3fdif; +extern AVFilter ff_vf_waveform; +extern AVFilter ff_vf_weave; +extern AVFilter ff_vf_xbr; +extern AVFilter ff_vf_xmedian; +extern AVFilter ff_vf_xstack; +extern AVFilter ff_vf_yadif; +extern AVFilter ff_vf_yadif_cuda; +extern AVFilter ff_vf_zmq; +extern AVFilter ff_vf_zoompan; +extern AVFilter ff_vf_zscale; + +extern AVFilter ff_vsrc_allrgb; +extern AVFilter ff_vsrc_allyuv; +extern AVFilter ff_vsrc_cellauto; +extern AVFilter ff_vsrc_color; +extern AVFilter ff_vsrc_coreimagesrc; +extern AVFilter ff_vsrc_frei0r_src; +extern AVFilter ff_vsrc_haldclutsrc; +extern AVFilter ff_vsrc_life; +extern AVFilter ff_vsrc_mandelbrot; +extern AVFilter ff_vsrc_mptestsrc; +extern AVFilter ff_vsrc_nullsrc; +extern AVFilter ff_vsrc_openclsrc; +extern AVFilter ff_vsrc_pal75bars; +extern AVFilter ff_vsrc_pal100bars; +extern AVFilter ff_vsrc_rgbtestsrc; +extern AVFilter ff_vsrc_smptebars; +extern AVFilter ff_vsrc_smptehdbars; +extern AVFilter ff_vsrc_testsrc; +extern AVFilter ff_vsrc_testsrc2; +extern AVFilter ff_vsrc_yuvtestsrc; + +extern AVFilter ff_vsink_nullsink; + +/* multimedia filters */ +extern AVFilter ff_avf_abitscope; +extern AVFilter ff_avf_adrawgraph; +extern AVFilter ff_avf_agraphmonitor; +extern AVFilter ff_avf_ahistogram; +extern AVFilter ff_avf_aphasemeter; +extern AVFilter ff_avf_avectorscope; +extern AVFilter ff_avf_concat; +extern AVFilter ff_avf_showcqt; +extern AVFilter ff_avf_showfreqs; +extern AVFilter ff_avf_showspatial; +extern AVFilter ff_avf_showspectrum; +extern AVFilter ff_avf_showspectrumpic; +extern AVFilter ff_avf_showvolume; +extern AVFilter ff_avf_showwaves; +extern AVFilter ff_avf_showwavespic; +extern AVFilter ff_vaf_spectrumsynth; + +/* multimedia sources */ +extern AVFilter ff_avsrc_amovie; +extern AVFilter ff_avsrc_movie; + +/* those filters are part of public or internal API, + * they are formatted to not be found by the grep + * as they are manually added again (due to their 'names' + * being the same while having different 'types'). */ +extern AVFilter ff_asrc_abuffer; +extern AVFilter ff_vsrc_buffer; +extern AVFilter ff_asink_abuffer; +extern AVFilter ff_vsink_buffer; +extern AVFilter ff_af_afifo; +extern AVFilter ff_vf_fifo; + +#include "libavfilter/filter_list.c" + + +const AVFilter *av_filter_iterate(void **opaque) +{ + uintptr_t i = (uintptr_t)*opaque; + const AVFilter *f = filter_list[i]; + + if (f) + *opaque = (void*)(i + 1); + + return f; +} + +const AVFilter *avfilter_get_by_name(const char *name) +{ + const AVFilter *f = NULL; + void *opaque = 0; + + if (!name) + return NULL; + + while ((f = av_filter_iterate(&opaque))) + if (!strcmp(f->name, name)) + return (AVFilter *)f; + + return NULL; +} + + +#if FF_API_NEXT +FF_DISABLE_DEPRECATION_WARNINGS +static AVOnce av_filter_next_init = AV_ONCE_INIT; + +static void av_filter_init_next(void) +{ + AVFilter *prev = NULL, *p; + void *i = 0; + while ((p = (AVFilter*)av_filter_iterate(&i))) { + if (prev) + prev->next = p; + prev = p; + } +} + +void avfilter_register_all(void) +{ + ff_thread_once(&av_filter_next_init, av_filter_init_next); +} + +int avfilter_register(AVFilter *filter) +{ + ff_thread_once(&av_filter_next_init, av_filter_init_next); + + return 0; +} + +const AVFilter *avfilter_next(const AVFilter *prev) +{ + ff_thread_once(&av_filter_next_init, av_filter_init_next); + + return prev ? prev->next : filter_list[0]; +} + +FF_ENABLE_DEPRECATION_WARNINGS +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/avfilter.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/avfilter.h new file mode 100644 index 000000000..9d70e7118 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/avfilter.h @@ -0,0 +1,1168 @@ +/* + * filter layer + * Copyright (c) 2007 Bobby Bingham + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_AVFILTER_H +#define AVFILTER_AVFILTER_H + +/** + * @file + * @ingroup lavfi + * Main libavfilter public API header + */ + +/** + * @defgroup lavfi libavfilter + * Graph-based frame editing library. + * + * @{ + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/avutil.h" +#include "libavutil/buffer.h" +#include "libavutil/dict.h" +#include "libavutil/frame.h" +#include "libavutil/log.h" +#include "libavutil/samplefmt.h" +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" + +#include "libavfilter/version.h" + +/** + * Return the LIBAVFILTER_VERSION_INT constant. + */ +unsigned avfilter_version(void); + +/** + * Return the libavfilter build-time configuration. + */ +const char *avfilter_configuration(void); + +/** + * Return the libavfilter license. + */ +const char *avfilter_license(void); + +typedef struct AVFilterContext AVFilterContext; +typedef struct AVFilterLink AVFilterLink; +typedef struct AVFilterPad AVFilterPad; +typedef struct AVFilterFormats AVFilterFormats; + +/** + * Get the number of elements in a NULL-terminated array of AVFilterPads (e.g. + * AVFilter.inputs/outputs). + */ +int avfilter_pad_count(const AVFilterPad *pads); + +/** + * Get the name of an AVFilterPad. + * + * @param pads an array of AVFilterPads + * @param pad_idx index of the pad in the array it; is the caller's + * responsibility to ensure the index is valid + * + * @return name of the pad_idx'th pad in pads + */ +const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx); + +/** + * Get the type of an AVFilterPad. + * + * @param pads an array of AVFilterPads + * @param pad_idx index of the pad in the array; it is the caller's + * responsibility to ensure the index is valid + * + * @return type of the pad_idx'th pad in pads + */ +enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx); + +/** + * The number of the filter inputs is not determined just by AVFilter.inputs. + * The filter might add additional inputs during initialization depending on the + * options supplied to it. + */ +#define AVFILTER_FLAG_DYNAMIC_INPUTS (1 << 0) +/** + * The number of the filter outputs is not determined just by AVFilter.outputs. + * The filter might add additional outputs during initialization depending on + * the options supplied to it. + */ +#define AVFILTER_FLAG_DYNAMIC_OUTPUTS (1 << 1) +/** + * The filter supports multithreading by splitting frames into multiple parts + * and processing them concurrently. + */ +#define AVFILTER_FLAG_SLICE_THREADS (1 << 2) +/** + * Some filters support a generic "enable" expression option that can be used + * to enable or disable a filter in the timeline. Filters supporting this + * option have this flag set. When the enable expression is false, the default + * no-op filter_frame() function is called in place of the filter_frame() + * callback defined on each input pad, thus the frame is passed unchanged to + * the next filters. + */ +#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC (1 << 16) +/** + * Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will + * have its filter_frame() callback(s) called as usual even when the enable + * expression is false. The filter will disable filtering within the + * filter_frame() callback(s) itself, for example executing code depending on + * the AVFilterContext->is_disabled value. + */ +#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL (1 << 17) +/** + * Handy mask to test whether the filter supports or no the timeline feature + * (internally or generically). + */ +#define AVFILTER_FLAG_SUPPORT_TIMELINE (AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL) + +/** + * Filter definition. This defines the pads a filter contains, and all the + * callback functions used to interact with the filter. + */ +typedef struct AVFilter { + /** + * Filter name. Must be non-NULL and unique among filters. + */ + const char *name; + + /** + * A description of the filter. May be NULL. + * + * You should use the NULL_IF_CONFIG_SMALL() macro to define it. + */ + const char *description; + + /** + * List of inputs, terminated by a zeroed element. + * + * NULL if there are no (static) inputs. Instances of filters with + * AVFILTER_FLAG_DYNAMIC_INPUTS set may have more inputs than present in + * this list. + */ + const AVFilterPad *inputs; + /** + * List of outputs, terminated by a zeroed element. + * + * NULL if there are no (static) outputs. Instances of filters with + * AVFILTER_FLAG_DYNAMIC_OUTPUTS set may have more outputs than present in + * this list. + */ + const AVFilterPad *outputs; + + /** + * A class for the private data, used to declare filter private AVOptions. + * This field is NULL for filters that do not declare any options. + * + * If this field is non-NULL, the first member of the filter private data + * must be a pointer to AVClass, which will be set by libavfilter generic + * code to this class. + */ + const AVClass *priv_class; + + /** + * A combination of AVFILTER_FLAG_* + */ + int flags; + + /***************************************************************** + * All fields below this line are not part of the public API. They + * may not be used outside of libavfilter and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + + /** + * Filter pre-initialization function + * + * This callback will be called immediately after the filter context is + * allocated, to allow allocating and initing sub-objects. + * + * If this callback is not NULL, the uninit callback will be called on + * allocation failure. + * + * @return 0 on success, + * AVERROR code on failure (but the code will be + * dropped and treated as ENOMEM by the calling code) + */ + int (*preinit)(AVFilterContext *ctx); + + /** + * Filter initialization function. + * + * This callback will be called only once during the filter lifetime, after + * all the options have been set, but before links between filters are + * established and format negotiation is done. + * + * Basic filter initialization should be done here. Filters with dynamic + * inputs and/or outputs should create those inputs/outputs here based on + * provided options. No more changes to this filter's inputs/outputs can be + * done after this callback. + * + * This callback must not assume that the filter links exist or frame + * parameters are known. + * + * @ref AVFilter.uninit "uninit" is guaranteed to be called even if + * initialization fails, so this callback does not have to clean up on + * failure. + * + * @return 0 on success, a negative AVERROR on failure + */ + int (*init)(AVFilterContext *ctx); + + /** + * Should be set instead of @ref AVFilter.init "init" by the filters that + * want to pass a dictionary of AVOptions to nested contexts that are + * allocated during init. + * + * On return, the options dict should be freed and replaced with one that + * contains all the options which could not be processed by this filter (or + * with NULL if all the options were processed). + * + * Otherwise the semantics is the same as for @ref AVFilter.init "init". + */ + int (*init_dict)(AVFilterContext *ctx, AVDictionary **options); + + /** + * Filter uninitialization function. + * + * Called only once right before the filter is freed. Should deallocate any + * memory held by the filter, release any buffer references, etc. It does + * not need to deallocate the AVFilterContext.priv memory itself. + * + * This callback may be called even if @ref AVFilter.init "init" was not + * called or failed, so it must be prepared to handle such a situation. + */ + void (*uninit)(AVFilterContext *ctx); + + /** + * Query formats supported by the filter on its inputs and outputs. + * + * This callback is called after the filter is initialized (so the inputs + * and outputs are fixed), shortly before the format negotiation. This + * callback may be called more than once. + * + * This callback must set AVFilterLink.out_formats on every input link and + * AVFilterLink.in_formats on every output link to a list of pixel/sample + * formats that the filter supports on that link. For audio links, this + * filter must also set @ref AVFilterLink.in_samplerates "in_samplerates" / + * @ref AVFilterLink.out_samplerates "out_samplerates" and + * @ref AVFilterLink.in_channel_layouts "in_channel_layouts" / + * @ref AVFilterLink.out_channel_layouts "out_channel_layouts" analogously. + * + * This callback may be NULL for filters with one input, in which case + * libavfilter assumes that it supports all input formats and preserves + * them on output. + * + * @return zero on success, a negative value corresponding to an + * AVERROR code otherwise + */ + int (*query_formats)(AVFilterContext *); + + int priv_size; ///< size of private data to allocate for the filter + + int flags_internal; ///< Additional flags for avfilter internal use only. + + /** + * Used by the filter registration system. Must not be touched by any other + * code. + */ + struct AVFilter *next; + + /** + * Make the filter instance process a command. + * + * @param cmd the command to process, for handling simplicity all commands must be alphanumeric only + * @param arg the argument for the command + * @param res a buffer with size res_size where the filter(s) can return a response. This must not change when the command is not supported. + * @param flags if AVFILTER_CMD_FLAG_FAST is set and the command would be + * time consuming then a filter should treat it like an unsupported command + * + * @returns >=0 on success otherwise an error code. + * AVERROR(ENOSYS) on unsupported commands + */ + int (*process_command)(AVFilterContext *, const char *cmd, const char *arg, char *res, int res_len, int flags); + + /** + * Filter initialization function, alternative to the init() + * callback. Args contains the user-supplied parameters, opaque is + * used for providing binary data. + */ + int (*init_opaque)(AVFilterContext *ctx, void *opaque); + + /** + * Filter activation function. + * + * Called when any processing is needed from the filter, instead of any + * filter_frame and request_frame on pads. + * + * The function must examine inlinks and outlinks and perform a single + * step of processing. If there is nothing to do, the function must do + * nothing and not return an error. If more steps are or may be + * possible, it must use ff_filter_set_ready() to schedule another + * activation. + */ + int (*activate)(AVFilterContext *ctx); +} AVFilter; + +/** + * Process multiple parts of the frame concurrently. + */ +#define AVFILTER_THREAD_SLICE (1 << 0) + +typedef struct AVFilterInternal AVFilterInternal; + +/** An instance of a filter */ +struct AVFilterContext { + const AVClass *av_class; ///< needed for av_log() and filters common options + + const AVFilter *filter; ///< the AVFilter of which this is an instance + + char *name; ///< name of this filter instance + + AVFilterPad *input_pads; ///< array of input pads + AVFilterLink **inputs; ///< array of pointers to input links + unsigned nb_inputs; ///< number of input pads + + AVFilterPad *output_pads; ///< array of output pads + AVFilterLink **outputs; ///< array of pointers to output links + unsigned nb_outputs; ///< number of output pads + + void *priv; ///< private data for use by the filter + + struct AVFilterGraph *graph; ///< filtergraph this filter belongs to + + /** + * Type of multithreading being allowed/used. A combination of + * AVFILTER_THREAD_* flags. + * + * May be set by the caller before initializing the filter to forbid some + * or all kinds of multithreading for this filter. The default is allowing + * everything. + * + * When the filter is initialized, this field is combined using bit AND with + * AVFilterGraph.thread_type to get the final mask used for determining + * allowed threading types. I.e. a threading type needs to be set in both + * to be allowed. + * + * After the filter is initialized, libavfilter sets this field to the + * threading type that is actually used (0 for no multithreading). + */ + int thread_type; + + /** + * An opaque struct for libavfilter internal use. + */ + AVFilterInternal *internal; + + struct AVFilterCommand *command_queue; + + char *enable_str; ///< enable expression string + void *enable; ///< parsed expression (AVExpr*) + double *var_values; ///< variable values for the enable expression + int is_disabled; ///< the enabled state from the last expression evaluation + + /** + * For filters which will create hardware frames, sets the device the + * filter should create them in. All other filters will ignore this field: + * in particular, a filter which consumes or processes hardware frames will + * instead use the hw_frames_ctx field in AVFilterLink to carry the + * hardware context information. + */ + AVBufferRef *hw_device_ctx; + + /** + * Max number of threads allowed in this filter instance. + * If <= 0, its value is ignored. + * Overrides global number of threads set per filter graph. + */ + int nb_threads; + + /** + * Ready status of the filter. + * A non-0 value means that the filter needs activating; + * a higher value suggests a more urgent activation. + */ + unsigned ready; + + /** + * Sets the number of extra hardware frames which the filter will + * allocate on its output links for use in following filters or by + * the caller. + * + * Some hardware filters require all frames that they will use for + * output to be defined in advance before filtering starts. For such + * filters, any hardware frame pools used for output must therefore be + * of fixed size. The extra frames set here are on top of any number + * that the filter needs internally in order to operate normally. + * + * This field must be set before the graph containing this filter is + * configured. + */ + int extra_hw_frames; +}; + +/** + * A link between two filters. This contains pointers to the source and + * destination filters between which this link exists, and the indexes of + * the pads involved. In addition, this link also contains the parameters + * which have been negotiated and agreed upon between the filter, such as + * image dimensions, format, etc. + * + * Applications must not normally access the link structure directly. + * Use the buffersrc and buffersink API instead. + * In the future, access to the header may be reserved for filters + * implementation. + */ +struct AVFilterLink { + AVFilterContext *src; ///< source filter + AVFilterPad *srcpad; ///< output pad on the source filter + + AVFilterContext *dst; ///< dest filter + AVFilterPad *dstpad; ///< input pad on the dest filter + + enum AVMediaType type; ///< filter media type + + /* These parameters apply only to video */ + int w; ///< agreed upon image width + int h; ///< agreed upon image height + AVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio + /* These parameters apply only to audio */ + uint64_t channel_layout; ///< channel layout of current buffer (see libavutil/channel_layout.h) + int sample_rate; ///< samples per second + + int format; ///< agreed upon media format + + /** + * Define the time base used by the PTS of the frames/samples + * which will pass through this link. + * During the configuration stage, each filter is supposed to + * change only the output timebase, while the timebase of the + * input link is assumed to be an unchangeable property. + */ + AVRational time_base; + + /***************************************************************** + * All fields below this line are not part of the public API. They + * may not be used outside of libavfilter and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + /** + * Lists of formats and channel layouts supported by the input and output + * filters respectively. These lists are used for negotiating the format + * to actually be used, which will be loaded into the format and + * channel_layout members, above, when chosen. + * + */ + AVFilterFormats *in_formats; + AVFilterFormats *out_formats; + + /** + * Lists of channel layouts and sample rates used for automatic + * negotiation. + */ + AVFilterFormats *in_samplerates; + AVFilterFormats *out_samplerates; + struct AVFilterChannelLayouts *in_channel_layouts; + struct AVFilterChannelLayouts *out_channel_layouts; + + /** + * Audio only, the destination filter sets this to a non-zero value to + * request that buffers with the given number of samples should be sent to + * it. AVFilterPad.needs_fifo must also be set on the corresponding input + * pad. + * Last buffer before EOF will be padded with silence. + */ + int request_samples; + + /** stage of the initialization of the link properties (dimensions, etc) */ + enum { + AVLINK_UNINIT = 0, ///< not started + AVLINK_STARTINIT, ///< started, but incomplete + AVLINK_INIT ///< complete + } init_state; + + /** + * Graph the filter belongs to. + */ + struct AVFilterGraph *graph; + + /** + * Current timestamp of the link, as defined by the most recent + * frame(s), in link time_base units. + */ + int64_t current_pts; + + /** + * Current timestamp of the link, as defined by the most recent + * frame(s), in AV_TIME_BASE units. + */ + int64_t current_pts_us; + + /** + * Index in the age array. + */ + int age_index; + + /** + * Frame rate of the stream on the link, or 1/0 if unknown or variable; + * if left to 0/0, will be automatically copied from the first input + * of the source filter if it exists. + * + * Sources should set it to the best estimation of the real frame rate. + * If the source frame rate is unknown or variable, set this to 1/0. + * Filters should update it if necessary depending on their function. + * Sinks can use it to set a default output frame rate. + * It is similar to the r_frame_rate field in AVStream. + */ + AVRational frame_rate; + + /** + * Buffer partially filled with samples to achieve a fixed/minimum size. + */ + AVFrame *partial_buf; + + /** + * Size of the partial buffer to allocate. + * Must be between min_samples and max_samples. + */ + int partial_buf_size; + + /** + * Minimum number of samples to filter at once. If filter_frame() is + * called with fewer samples, it will accumulate them in partial_buf. + * This field and the related ones must not be changed after filtering + * has started. + * If 0, all related fields are ignored. + */ + int min_samples; + + /** + * Maximum number of samples to filter at once. If filter_frame() is + * called with more samples, it will split them. + */ + int max_samples; + + /** + * Number of channels. + */ + int channels; + + /** + * Link processing flags. + */ + unsigned flags; + + /** + * Number of past frames sent through the link. + */ + int64_t frame_count_in, frame_count_out; + + /** + * A pointer to a FFFramePool struct. + */ + void *frame_pool; + + /** + * True if a frame is currently wanted on the output of this filter. + * Set when ff_request_frame() is called by the output, + * cleared when a frame is filtered. + */ + int frame_wanted_out; + + /** + * For hwaccel pixel formats, this should be a reference to the + * AVHWFramesContext describing the frames. + */ + AVBufferRef *hw_frames_ctx; + +#ifndef FF_INTERNAL_FIELDS + + /** + * Internal structure members. + * The fields below this limit are internal for libavfilter's use + * and must in no way be accessed by applications. + */ + char reserved[0xF000]; + +#else /* FF_INTERNAL_FIELDS */ + + /** + * Queue of frames waiting to be filtered. + */ + FFFrameQueue fifo; + + /** + * If set, the source filter can not generate a frame as is. + * The goal is to avoid repeatedly calling the request_frame() method on + * the same link. + */ + int frame_blocked_in; + + /** + * Link input status. + * If not zero, all attempts of filter_frame will fail with the + * corresponding code. + */ + int status_in; + + /** + * Timestamp of the input status change. + */ + int64_t status_in_pts; + + /** + * Link output status. + * If not zero, all attempts of request_frame will fail with the + * corresponding code. + */ + int status_out; + +#endif /* FF_INTERNAL_FIELDS */ + +}; + +/** + * Link two filters together. + * + * @param src the source filter + * @param srcpad index of the output pad on the source filter + * @param dst the destination filter + * @param dstpad index of the input pad on the destination filter + * @return zero on success + */ +int avfilter_link(AVFilterContext *src, unsigned srcpad, + AVFilterContext *dst, unsigned dstpad); + +/** + * Free the link in *link, and set its pointer to NULL. + */ +void avfilter_link_free(AVFilterLink **link); + +#if FF_API_FILTER_GET_SET +/** + * Get the number of channels of a link. + * @deprecated Use av_buffersink_get_channels() + */ +attribute_deprecated +int avfilter_link_get_channels(AVFilterLink *link); +#endif + +/** + * Set the closed field of a link. + * @deprecated applications are not supposed to mess with links, they should + * close the sinks. + */ +attribute_deprecated +void avfilter_link_set_closed(AVFilterLink *link, int closed); + +/** + * Negotiate the media format, dimensions, etc of all inputs to a filter. + * + * @param filter the filter to negotiate the properties for its inputs + * @return zero on successful negotiation + */ +int avfilter_config_links(AVFilterContext *filter); + +#define AVFILTER_CMD_FLAG_ONE 1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically +#define AVFILTER_CMD_FLAG_FAST 2 ///< Only execute command when its fast (like a video out that supports contrast adjustment in hw) + +/** + * Make the filter instance process a command. + * It is recommended to use avfilter_graph_send_command(). + */ +int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags); + +/** + * Iterate over all registered filters. + * + * @param opaque a pointer where libavfilter will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered filter or NULL when the iteration is + * finished + */ +const AVFilter *av_filter_iterate(void **opaque); + +#if FF_API_NEXT +/** Initialize the filter system. Register all builtin filters. */ +attribute_deprecated +void avfilter_register_all(void); + +/** + * Register a filter. This is only needed if you plan to use + * avfilter_get_by_name later to lookup the AVFilter structure by name. A + * filter can still by instantiated with avfilter_graph_alloc_filter even if it + * is not registered. + * + * @param filter the filter to register + * @return 0 if the registration was successful, a negative value + * otherwise + */ +attribute_deprecated +int avfilter_register(AVFilter *filter); + +/** + * Iterate over all registered filters. + * @return If prev is non-NULL, next registered filter after prev or NULL if + * prev is the last filter. If prev is NULL, return the first registered filter. + */ +attribute_deprecated +const AVFilter *avfilter_next(const AVFilter *prev); +#endif + +/** + * Get a filter definition matching the given name. + * + * @param name the filter name to find + * @return the filter definition, if any matching one is registered. + * NULL if none found. + */ +const AVFilter *avfilter_get_by_name(const char *name); + + +/** + * Initialize a filter with the supplied parameters. + * + * @param ctx uninitialized filter context to initialize + * @param args Options to initialize the filter with. This must be a + * ':'-separated list of options in the 'key=value' form. + * May be NULL if the options have been set directly using the + * AVOptions API or there are no options that need to be set. + * @return 0 on success, a negative AVERROR on failure + */ +int avfilter_init_str(AVFilterContext *ctx, const char *args); + +/** + * Initialize a filter with the supplied dictionary of options. + * + * @param ctx uninitialized filter context to initialize + * @param options An AVDictionary filled with options for this filter. On + * return this parameter will be destroyed and replaced with + * a dict containing options that were not found. This dictionary + * must be freed by the caller. + * May be NULL, then this function is equivalent to + * avfilter_init_str() with the second parameter set to NULL. + * @return 0 on success, a negative AVERROR on failure + * + * @note This function and avfilter_init_str() do essentially the same thing, + * the difference is in manner in which the options are passed. It is up to the + * calling code to choose whichever is more preferable. The two functions also + * behave differently when some of the provided options are not declared as + * supported by the filter. In such a case, avfilter_init_str() will fail, but + * this function will leave those extra options in the options AVDictionary and + * continue as usual. + */ +int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options); + +/** + * Free a filter context. This will also remove the filter from its + * filtergraph's list of filters. + * + * @param filter the filter to free + */ +void avfilter_free(AVFilterContext *filter); + +/** + * Insert a filter in the middle of an existing link. + * + * @param link the link into which the filter should be inserted + * @param filt the filter to be inserted + * @param filt_srcpad_idx the input pad on the filter to connect + * @param filt_dstpad_idx the output pad on the filter to connect + * @return zero on success + */ +int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, + unsigned filt_srcpad_idx, unsigned filt_dstpad_idx); + +/** + * @return AVClass for AVFilterContext. + * + * @see av_opt_find(). + */ +const AVClass *avfilter_get_class(void); + +typedef struct AVFilterGraphInternal AVFilterGraphInternal; + +/** + * A function pointer passed to the @ref AVFilterGraph.execute callback to be + * executed multiple times, possibly in parallel. + * + * @param ctx the filter context the job belongs to + * @param arg an opaque parameter passed through from @ref + * AVFilterGraph.execute + * @param jobnr the index of the job being executed + * @param nb_jobs the total number of jobs + * + * @return 0 on success, a negative AVERROR on error + */ +typedef int (avfilter_action_func)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); + +/** + * A function executing multiple jobs, possibly in parallel. + * + * @param ctx the filter context to which the jobs belong + * @param func the function to be called multiple times + * @param arg the argument to be passed to func + * @param ret a nb_jobs-sized array to be filled with return values from each + * invocation of func + * @param nb_jobs the number of jobs to execute + * + * @return 0 on success, a negative AVERROR on error + */ +typedef int (avfilter_execute_func)(AVFilterContext *ctx, avfilter_action_func *func, + void *arg, int *ret, int nb_jobs); + +typedef struct AVFilterGraph { + const AVClass *av_class; + AVFilterContext **filters; + unsigned nb_filters; + + char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters +#if FF_API_LAVR_OPTS + attribute_deprecated char *resample_lavr_opts; ///< libavresample options to use for the auto-inserted resample filters +#endif + + /** + * Type of multithreading allowed for filters in this graph. A combination + * of AVFILTER_THREAD_* flags. + * + * May be set by the caller at any point, the setting will apply to all + * filters initialized after that. The default is allowing everything. + * + * When a filter in this graph is initialized, this field is combined using + * bit AND with AVFilterContext.thread_type to get the final mask used for + * determining allowed threading types. I.e. a threading type needs to be + * set in both to be allowed. + */ + int thread_type; + + /** + * Maximum number of threads used by filters in this graph. May be set by + * the caller before adding any filters to the filtergraph. Zero (the + * default) means that the number of threads is determined automatically. + */ + int nb_threads; + + /** + * Opaque object for libavfilter internal use. + */ + AVFilterGraphInternal *internal; + + /** + * Opaque user data. May be set by the caller to an arbitrary value, e.g. to + * be used from callbacks like @ref AVFilterGraph.execute. + * Libavfilter will not touch this field in any way. + */ + void *opaque; + + /** + * This callback may be set by the caller immediately after allocating the + * graph and before adding any filters to it, to provide a custom + * multithreading implementation. + * + * If set, filters with slice threading capability will call this callback + * to execute multiple jobs in parallel. + * + * If this field is left unset, libavfilter will use its internal + * implementation, which may or may not be multithreaded depending on the + * platform and build options. + */ + avfilter_execute_func *execute; + + char *aresample_swr_opts; ///< swr options to use for the auto-inserted aresample filters, Access ONLY through AVOptions + + /** + * Private fields + * + * The following fields are for internal use only. + * Their type, offset, number and semantic can change without notice. + */ + + AVFilterLink **sink_links; + int sink_links_count; + + unsigned disable_auto_convert; +} AVFilterGraph; + +/** + * Allocate a filter graph. + * + * @return the allocated filter graph on success or NULL. + */ +AVFilterGraph *avfilter_graph_alloc(void); + +/** + * Create a new filter instance in a filter graph. + * + * @param graph graph in which the new filter will be used + * @param filter the filter to create an instance of + * @param name Name to give to the new instance (will be copied to + * AVFilterContext.name). This may be used by the caller to identify + * different filters, libavfilter itself assigns no semantics to + * this parameter. May be NULL. + * + * @return the context of the newly created filter instance (note that it is + * also retrievable directly through AVFilterGraph.filters or with + * avfilter_graph_get_filter()) on success or NULL on failure. + */ +AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph, + const AVFilter *filter, + const char *name); + +/** + * Get a filter instance identified by instance name from graph. + * + * @param graph filter graph to search through. + * @param name filter instance name (should be unique in the graph). + * @return the pointer to the found filter instance or NULL if it + * cannot be found. + */ +AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, const char *name); + +/** + * Create and add a filter instance into an existing graph. + * The filter instance is created from the filter filt and inited + * with the parameters args and opaque. + * + * In case of success put in *filt_ctx the pointer to the created + * filter instance, otherwise set *filt_ctx to NULL. + * + * @param name the instance name to give to the created filter instance + * @param graph_ctx the filter graph + * @return a negative AVERROR error code in case of failure, a non + * negative value otherwise + */ +int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, + const char *name, const char *args, void *opaque, + AVFilterGraph *graph_ctx); + +/** + * Enable or disable automatic format conversion inside the graph. + * + * Note that format conversion can still happen inside explicitly inserted + * scale and aresample filters. + * + * @param flags any of the AVFILTER_AUTO_CONVERT_* constants + */ +void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags); + +enum { + AVFILTER_AUTO_CONVERT_ALL = 0, /**< all automatic conversions enabled */ + AVFILTER_AUTO_CONVERT_NONE = -1, /**< all automatic conversions disabled */ +}; + +/** + * Check validity and configure all the links and formats in the graph. + * + * @param graphctx the filter graph + * @param log_ctx context used for logging + * @return >= 0 in case of success, a negative AVERROR code otherwise + */ +int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx); + +/** + * Free a graph, destroy its links, and set *graph to NULL. + * If *graph is NULL, do nothing. + */ +void avfilter_graph_free(AVFilterGraph **graph); + +/** + * A linked-list of the inputs/outputs of the filter chain. + * + * This is mainly useful for avfilter_graph_parse() / avfilter_graph_parse2(), + * where it is used to communicate open (unlinked) inputs and outputs from and + * to the caller. + * This struct specifies, per each not connected pad contained in the graph, the + * filter context and the pad index required for establishing a link. + */ +typedef struct AVFilterInOut { + /** unique name for this input/output in the list */ + char *name; + + /** filter context associated to this input/output */ + AVFilterContext *filter_ctx; + + /** index of the filt_ctx pad to use for linking */ + int pad_idx; + + /** next input/input in the list, NULL if this is the last */ + struct AVFilterInOut *next; +} AVFilterInOut; + +/** + * Allocate a single AVFilterInOut entry. + * Must be freed with avfilter_inout_free(). + * @return allocated AVFilterInOut on success, NULL on failure. + */ +AVFilterInOut *avfilter_inout_alloc(void); + +/** + * Free the supplied list of AVFilterInOut and set *inout to NULL. + * If *inout is NULL, do nothing. + */ +void avfilter_inout_free(AVFilterInOut **inout); + +/** + * Add a graph described by a string to a graph. + * + * @note The caller must provide the lists of inputs and outputs, + * which therefore must be known before calling the function. + * + * @note The inputs parameter describes inputs of the already existing + * part of the graph; i.e. from the point of view of the newly created + * part, they are outputs. Similarly the outputs parameter describes + * outputs of the already existing filters, which are provided as + * inputs to the parsed filters. + * + * @param graph the filter graph where to link the parsed graph context + * @param filters string to be parsed + * @param inputs linked list to the inputs of the graph + * @param outputs linked list to the outputs of the graph + * @return zero on success, a negative AVERROR code on error + */ +int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, + AVFilterInOut *inputs, AVFilterInOut *outputs, + void *log_ctx); + +/** + * Add a graph described by a string to a graph. + * + * In the graph filters description, if the input label of the first + * filter is not specified, "in" is assumed; if the output label of + * the last filter is not specified, "out" is assumed. + * + * @param graph the filter graph where to link the parsed graph context + * @param filters string to be parsed + * @param inputs pointer to a linked list to the inputs of the graph, may be NULL. + * If non-NULL, *inputs is updated to contain the list of open inputs + * after the parsing, should be freed with avfilter_inout_free(). + * @param outputs pointer to a linked list to the outputs of the graph, may be NULL. + * If non-NULL, *outputs is updated to contain the list of open outputs + * after the parsing, should be freed with avfilter_inout_free(). + * @return non negative on success, a negative AVERROR code on error + */ +int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, + AVFilterInOut **inputs, AVFilterInOut **outputs, + void *log_ctx); + +/** + * Add a graph described by a string to a graph. + * + * @param[in] graph the filter graph where to link the parsed graph context + * @param[in] filters string to be parsed + * @param[out] inputs a linked list of all free (unlinked) inputs of the + * parsed graph will be returned here. It is to be freed + * by the caller using avfilter_inout_free(). + * @param[out] outputs a linked list of all free (unlinked) outputs of the + * parsed graph will be returned here. It is to be freed by the + * caller using avfilter_inout_free(). + * @return zero on success, a negative AVERROR code on error + * + * @note This function returns the inputs and outputs that are left + * unlinked after parsing the graph and the caller then deals with + * them. + * @note This function makes no reference whatsoever to already + * existing parts of the graph and the inputs parameter will on return + * contain inputs of the newly parsed part of the graph. Analogously + * the outputs parameter will contain outputs of the newly created + * filters. + */ +int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, + AVFilterInOut **inputs, + AVFilterInOut **outputs); + +/** + * Send a command to one or more filter instances. + * + * @param graph the filter graph + * @param target the filter(s) to which the command should be sent + * "all" sends to all filters + * otherwise it can be a filter or filter instance name + * which will send the command to all matching filters. + * @param cmd the command to send, for handling simplicity all commands must be alphanumeric only + * @param arg the argument for the command + * @param res a buffer with size res_size where the filter(s) can return a response. + * + * @returns >=0 on success otherwise an error code. + * AVERROR(ENOSYS) on unsupported commands + */ +int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags); + +/** + * Queue a command for one or more filter instances. + * + * @param graph the filter graph + * @param target the filter(s) to which the command should be sent + * "all" sends to all filters + * otherwise it can be a filter or filter instance name + * which will send the command to all matching filters. + * @param cmd the command to sent, for handling simplicity all commands must be alphanumeric only + * @param arg the argument for the command + * @param ts time at which the command should be sent to the filter + * + * @note As this executes commands after this function returns, no return code + * from the filter is provided, also AVFILTER_CMD_FLAG_ONE is not supported. + */ +int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, int flags, double ts); + + +/** + * Dump a graph into a human-readable string representation. + * + * @param graph the graph to dump + * @param options formatting options; currently ignored + * @return a string, or NULL in case of memory allocation failure; + * the string must be freed using av_free + */ +char *avfilter_graph_dump(AVFilterGraph *graph, const char *options); + +/** + * Request a frame on the oldest sink link. + * + * If the request returns AVERROR_EOF, try the next. + * + * Note that this function is not meant to be the sole scheduling mechanism + * of a filtergraph, only a convenience function to help drain a filtergraph + * in a balanced way under normal circumstances. + * + * Also note that AVERROR_EOF does not mean that frames did not arrive on + * some of the sinks during the process. + * When there are multiple sink links, in case the requested link + * returns an EOF, this may cause a filter to flush pending frames + * which are sent to another sink link, although unrequested. + * + * @return the return value of ff_request_frame(), + * or AVERROR_EOF if all links returned AVERROR_EOF + */ +int avfilter_graph_request_oldest(AVFilterGraph *graph); + +/** + * @} + */ + +#endif /* AVFILTER_AVFILTER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/bufferqueue.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/bufferqueue.h new file mode 100644 index 000000000..f5e5df2d7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/bufferqueue.h @@ -0,0 +1,121 @@ +/* + * Generic buffer queue + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_BUFFERQUEUE_H +#define AVFILTER_BUFFERQUEUE_H + +/** + * FFBufQueue: simple AVFrame queue API + * + * Note: this API is not thread-safe. Concurrent access to the same queue + * must be protected by a mutex or any synchronization mechanism. + */ + +/** + * Maximum size of the queue. + * + * This value can be overridden by definying it before including this + * header. + * Powers of 2 are recommended. + */ +#ifndef FF_BUFQUEUE_SIZE +#define FF_BUFQUEUE_SIZE 64 +#endif + +#include "avfilter.h" +#include "libavutil/avassert.h" + +/** + * Structure holding the queue + */ +struct FFBufQueue { + AVFrame *queue[FF_BUFQUEUE_SIZE]; + unsigned short head; + unsigned short available; /**< number of available buffers */ +}; + +#define BUCKET(i) queue->queue[(queue->head + (i)) % FF_BUFQUEUE_SIZE] + +/** + * Test if a buffer queue is full. + */ +static inline int ff_bufqueue_is_full(struct FFBufQueue *queue) +{ + return queue->available == FF_BUFQUEUE_SIZE; +} + +/** + * Add a buffer to the queue. + * + * If the queue is already full, then the current last buffer is dropped + * (and unrefed) with a warning before adding the new buffer. + */ +static inline void ff_bufqueue_add(void *log, struct FFBufQueue *queue, + AVFrame *buf) +{ + if (ff_bufqueue_is_full(queue)) { + av_log(log, AV_LOG_WARNING, "Buffer queue overflow, dropping.\n"); + av_frame_free(&BUCKET(--queue->available)); + } + BUCKET(queue->available++) = buf; +} + +/** + * Get a buffer from the queue without altering it. + * + * Buffer with index 0 is the first buffer in the queue. + * Return NULL if the queue has not enough buffers. + */ +static inline AVFrame *ff_bufqueue_peek(struct FFBufQueue *queue, + unsigned index) +{ + return index < queue->available ? BUCKET(index) : NULL; +} + +/** + * Get the first buffer from the queue and remove it. + * + * Do not use on an empty queue. + */ +static inline AVFrame *ff_bufqueue_get(struct FFBufQueue *queue) +{ + AVFrame *ret = queue->queue[queue->head]; + av_assert0(queue->available); + queue->available--; + queue->queue[queue->head] = NULL; + queue->head = (queue->head + 1) % FF_BUFQUEUE_SIZE; + return ret; +} + +/** + * Unref and remove all buffers from the queue. + */ +static inline void ff_bufqueue_discard_all(struct FFBufQueue *queue) +{ + while (queue->available) { + AVFrame *buf = ff_bufqueue_get(queue); + av_frame_free(&buf); + } +} + +#undef BUCKET + +#endif /* AVFILTER_BUFFERQUEUE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/filter_list.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/filter_list.c new file mode 100644 index 000000000..9a55cb886 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/filter_list.c @@ -0,0 +1,6 @@ +static const AVFilter * const filter_list[] = { + &ff_asrc_abuffer, + &ff_vsrc_buffer, + &ff_asink_abuffer, + &ff_vsink_buffer, + NULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/version.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/version.h new file mode 100644 index 000000000..cc5b23b70 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/version.h @@ -0,0 +1,66 @@ +/* + * Version macros. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_VERSION_H +#define AVFILTER_VERSION_H + +/** + * @file + * @ingroup lavfi + * Libavfilter version macros + */ + +#include "libavutil/version.h" + +#define LIBAVFILTER_VERSION_MAJOR 7 +#define LIBAVFILTER_VERSION_MINOR 57 +#define LIBAVFILTER_VERSION_MICRO 100 + + +#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ + LIBAVFILTER_VERSION_MINOR, \ + LIBAVFILTER_VERSION_MICRO) +#define LIBAVFILTER_VERSION AV_VERSION(LIBAVFILTER_VERSION_MAJOR, \ + LIBAVFILTER_VERSION_MINOR, \ + LIBAVFILTER_VERSION_MICRO) +#define LIBAVFILTER_BUILD LIBAVFILTER_VERSION_INT + +#define LIBAVFILTER_IDENT "Lavfi" AV_STRINGIFY(LIBAVFILTER_VERSION) + +/** + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + */ + +#ifndef FF_API_OLD_FILTER_OPTS_ERROR +#define FF_API_OLD_FILTER_OPTS_ERROR (LIBAVFILTER_VERSION_MAJOR < 8) +#endif +#ifndef FF_API_LAVR_OPTS +#define FF_API_LAVR_OPTS (LIBAVFILTER_VERSION_MAJOR < 8) +#endif +#ifndef FF_API_FILTER_GET_SET +#define FF_API_FILTER_GET_SET (LIBAVFILTER_VERSION_MAJOR < 8) +#endif +#ifndef FF_API_NEXT +#define FF_API_NEXT (LIBAVFILTER_VERSION_MAJOR < 8) +#endif + +#endif /* AVFILTER_VERSION_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/window_func.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/window_func.h new file mode 100644 index 000000000..1de8f1fbd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavfilter/window_func.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2015 Paul B Mahol + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVFILTER_WINDOW_FUNC_H +#define AVFILTER_WINDOW_FUNC_H + +#include +#include "libavutil/avassert.h" + +enum WindowFunc { WFUNC_RECT, WFUNC_HANNING, WFUNC_HAMMING, WFUNC_BLACKMAN, + WFUNC_BARTLETT, WFUNC_WELCH, WFUNC_FLATTOP, + WFUNC_BHARRIS, WFUNC_BNUTTALL, WFUNC_SINE, WFUNC_NUTTALL, + WFUNC_BHANN, WFUNC_LANCZOS, WFUNC_GAUSS, WFUNC_TUKEY, + WFUNC_DOLPH, WFUNC_CAUCHY, WFUNC_PARZEN, WFUNC_POISSON, + WFUNC_BOHMAN, + NB_WFUNC }; + +static inline void generate_window_func(float *lut, int N, int win_func, + float *overlap) +{ + int n; + + switch (win_func) { + case WFUNC_RECT: + for (n = 0; n < N; n++) + lut[n] = 1.; + *overlap = 0.; + break; + case WFUNC_BARTLETT: + for (n = 0; n < N; n++) + lut[n] = 1.-fabs((n-(N-1)/2.)/((N-1)/2.)); + *overlap = 0.5; + break; + case WFUNC_HANNING: + for (n = 0; n < N; n++) + lut[n] = .5*(1-cos(2*M_PI*n/(N-1))); + *overlap = 0.5; + break; + case WFUNC_HAMMING: + for (n = 0; n < N; n++) + lut[n] = .54-.46*cos(2*M_PI*n/(N-1)); + *overlap = 0.5; + break; + case WFUNC_BLACKMAN: + for (n = 0; n < N; n++) + lut[n] = .42659-.49656*cos(2*M_PI*n/(N-1))+.076849*cos(4*M_PI*n/(N-1)); + *overlap = 0.661; + break; + case WFUNC_WELCH: + for (n = 0; n < N; n++) + lut[n] = 1.-(n-(N-1)/2.)/((N-1)/2.)*(n-(N-1)/2.)/((N-1)/2.); + *overlap = 0.293; + break; + case WFUNC_FLATTOP: + for (n = 0; n < N; n++) + lut[n] = 1.-1.985844164102*cos( 2*M_PI*n/(N-1))+1.791176438506*cos( 4*M_PI*n/(N-1))- + 1.282075284005*cos( 6*M_PI*n/(N-1))+0.667777530266*cos( 8*M_PI*n/(N-1))- + 0.240160796576*cos(10*M_PI*n/(N-1))+0.056656381764*cos(12*M_PI*n/(N-1))- + 0.008134974479*cos(14*M_PI*n/(N-1))+0.000624544650*cos(16*M_PI*n/(N-1))- + 0.000019808998*cos(18*M_PI*n/(N-1))+0.000000132974*cos(20*M_PI*n/(N-1)); + *overlap = 0.841; + break; + case WFUNC_BHARRIS: + for (n = 0; n < N; n++) + lut[n] = 0.35875-0.48829*cos(2*M_PI*n/(N-1))+0.14128*cos(4*M_PI*n/(N-1))-0.01168*cos(6*M_PI*n/(N-1)); + *overlap = 0.661; + break; + case WFUNC_BNUTTALL: + for (n = 0; n < N; n++) + lut[n] = 0.3635819-0.4891775*cos(2*M_PI*n/(N-1))+0.1365995*cos(4*M_PI*n/(N-1))-0.0106411*cos(6*M_PI*n/(N-1)); + *overlap = 0.661; + break; + case WFUNC_BHANN: + for (n = 0; n < N; n++) + lut[n] = 0.62-0.48*fabs(n/(double)(N-1)-.5)-0.38*cos(2*M_PI*n/(N-1)); + *overlap = 0.5; + break; + case WFUNC_SINE: + for (n = 0; n < N; n++) + lut[n] = sin(M_PI*n/(N-1)); + *overlap = 0.75; + break; + case WFUNC_NUTTALL: + for (n = 0; n < N; n++) + lut[n] = 0.355768-0.487396*cos(2*M_PI*n/(N-1))+0.144232*cos(4*M_PI*n/(N-1))-0.012604*cos(6*M_PI*n/(N-1)); + *overlap = 0.663; + break; + case WFUNC_LANCZOS: + #define SINC(x) (!(x)) ? 1 : sin(M_PI * (x))/(M_PI * (x)); + for (n = 0; n < N; n++) + lut[n] = SINC((2.*n)/(N-1)-1); + *overlap = 0.75; + break; + case WFUNC_GAUSS: + #define SQR(x) ((x)*(x)) + for (n = 0; n < N; n++) + lut[n] = exp(-0.5 * SQR((n-(N-1)/2)/(0.4*(N-1)/2.f))); + *overlap = 0.75; + break; + case WFUNC_TUKEY: + for (n = 0; n < N; n++) { + float M = (N-1)/2.; + + if (FFABS(n - M) >= 0.3 * M) { + lut[n] = 0.5 * (1 + cos((M_PI*(FFABS(n - M) - 0.3 * M))/((1 - 0.3) * M))); + } else { + lut[n] = 1; + } + } + *overlap = 0.33; + break; + case WFUNC_DOLPH: { + double b = cosh(7.6009022095419887 / (N-1)), sum, t, c, norm = 0; + int j; + for (c = 1 - 1 / (b*b), n = (N-1) / 2; n >= 0; --n) { + for (sum = !n, b = t = j = 1; j <= n && sum != t; b *= (n-j) * (1./j), ++j) + t = sum, sum += (b *= c * (N - n - j) * (1./j)); + sum /= (N - 1 - n), sum /= (norm = norm ? norm : sum); + lut[n] = sum; + lut[N - 1 - n] = sum; + } + *overlap = 0.5;} + break; + case WFUNC_CAUCHY: + for (n = 0; n < N; n++) { + double x = 2 * ((n / (double)(N - 1)) - .5); + + if (x <= -.5 || x >= .5) { + lut[n] = 0; + } else { + lut[n] = FFMIN(1, fabs(1/(1+4*16*x*x))); + } + } + *overlap = 0.75; + break; + case WFUNC_PARZEN: + for (n = 0; n < N; n++) { + double x = 2 * ((n / (double)(N - 1)) - .5); + + if (x > 0.25 && x <= 0.5) { + lut[n] = -2 * powf(-1 + 2 * x, 3); + } else if (x >= -.5 && x < -.25) { + lut[n] = 2 * powf(1 + 2 * x, 3); + } else if (x >= -.25 && x < 0) { + lut[n] = 1 - 24 * x * x - 48 * x * x * x; + } else if (x >= 0 && x <= .25) { + lut[n] = 1 - 24 * x * x + 48 * x * x * x; + } else { + lut[n] = 0; + } + } + *overlap = 0.75; + break; + case WFUNC_POISSON: + for (n = 0; n < N; n++) { + double x = 2 * ((n / (double)(N - 1)) - .5); + + if (x >= 0 && x <= .5) { + lut[n] = exp(-6*x); + } else if (x < 0 && x >= -.5) { + lut[n] = exp(6*x); + } else { + lut[n] = 0; + } + } + *overlap = 0.75; + break; + case WFUNC_BOHMAN: + for (n = 0; n < N; n++) { + double x = 2 * ((n / (double)(N - 1))) - 1.; + + lut[n] = (1 - fabs(x)) * cos(M_PI*fabs(x)) + 1./M_PI*sin(M_PI*fabs(x)); + } + *overlap = 0.75; + break; + default: + av_assert0(0); + } +} + +#endif /* AVFILTER_WINDOW_FUNC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/allformats.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/allformats.c new file mode 100644 index 000000000..cd0083480 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/allformats.c @@ -0,0 +1,641 @@ +/* + * Register all the formats and protocols + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/thread.h" +#include "libavformat/internal.h" +#include "avformat.h" +#include "rtp.h" +#include "rdt.h" +#include "url.h" +#include "version.h" + +/* (de)muxers */ +extern AVOutputFormat ff_a64_muxer; +extern AVInputFormat ff_aa_demuxer; +extern AVInputFormat ff_aac_demuxer; +extern AVInputFormat ff_ac3_demuxer; +extern AVOutputFormat ff_ac3_muxer; +extern AVInputFormat ff_acm_demuxer; +extern AVInputFormat ff_act_demuxer; +extern AVInputFormat ff_adf_demuxer; +extern AVInputFormat ff_adp_demuxer; +extern AVInputFormat ff_ads_demuxer; +extern AVOutputFormat ff_adts_muxer; +extern AVInputFormat ff_adx_demuxer; +extern AVOutputFormat ff_adx_muxer; +extern AVInputFormat ff_aea_demuxer; +extern AVInputFormat ff_afc_demuxer; +extern AVInputFormat ff_aiff_demuxer; +extern AVOutputFormat ff_aiff_muxer; +extern AVInputFormat ff_aix_demuxer; +extern AVInputFormat ff_amr_demuxer; +extern AVOutputFormat ff_amr_muxer; +extern AVInputFormat ff_amrnb_demuxer; +extern AVInputFormat ff_amrwb_demuxer; +extern AVInputFormat ff_anm_demuxer; +extern AVInputFormat ff_apc_demuxer; +extern AVInputFormat ff_ape_demuxer; +extern AVInputFormat ff_apng_demuxer; +extern AVOutputFormat ff_apng_muxer; +extern AVInputFormat ff_aptx_demuxer; +extern AVOutputFormat ff_aptx_muxer; +extern AVInputFormat ff_aptx_hd_demuxer; +extern AVOutputFormat ff_aptx_hd_muxer; +extern AVInputFormat ff_aqtitle_demuxer; +extern AVInputFormat ff_asf_demuxer; +extern AVOutputFormat ff_asf_muxer; +extern AVInputFormat ff_asf_o_demuxer; +extern AVInputFormat ff_ass_demuxer; +extern AVOutputFormat ff_ass_muxer; +extern AVInputFormat ff_ast_demuxer; +extern AVOutputFormat ff_ast_muxer; +extern AVOutputFormat ff_asf_stream_muxer; +extern AVInputFormat ff_au_demuxer; +extern AVOutputFormat ff_au_muxer; +extern AVInputFormat ff_avi_demuxer; +extern AVOutputFormat ff_avi_muxer; +extern AVInputFormat ff_avisynth_demuxer; +extern AVOutputFormat ff_avm2_muxer; +extern AVInputFormat ff_avr_demuxer; +extern AVInputFormat ff_avs_demuxer; +extern AVInputFormat ff_avs2_demuxer; +extern AVOutputFormat ff_avs2_muxer; +extern AVInputFormat ff_bethsoftvid_demuxer; +extern AVInputFormat ff_bfi_demuxer; +extern AVInputFormat ff_bintext_demuxer; +extern AVInputFormat ff_bink_demuxer; +extern AVInputFormat ff_bit_demuxer; +extern AVOutputFormat ff_bit_muxer; +extern AVInputFormat ff_bmv_demuxer; +extern AVInputFormat ff_bfstm_demuxer; +extern AVInputFormat ff_brstm_demuxer; +extern AVInputFormat ff_boa_demuxer; +extern AVInputFormat ff_c93_demuxer; +extern AVInputFormat ff_caf_demuxer; +extern AVOutputFormat ff_caf_muxer; +extern AVInputFormat ff_cavsvideo_demuxer; +extern AVOutputFormat ff_cavsvideo_muxer; +extern AVInputFormat ff_cdg_demuxer; +extern AVInputFormat ff_cdxl_demuxer; +extern AVInputFormat ff_cine_demuxer; +extern AVInputFormat ff_codec2_demuxer; +extern AVOutputFormat ff_codec2_muxer; +extern AVInputFormat ff_codec2raw_demuxer; +extern AVOutputFormat ff_codec2raw_muxer; +extern AVInputFormat ff_concat_demuxer; +extern AVOutputFormat ff_crc_muxer; +extern AVInputFormat ff_dash_demuxer; +extern AVOutputFormat ff_dash_muxer; +extern AVInputFormat ff_data_demuxer; +extern AVOutputFormat ff_data_muxer; +extern AVInputFormat ff_daud_demuxer; +extern AVOutputFormat ff_daud_muxer; +extern AVInputFormat ff_dcstr_demuxer; +extern AVInputFormat ff_dfa_demuxer; +extern AVInputFormat ff_dhav_demuxer; +extern AVInputFormat ff_dirac_demuxer; +extern AVOutputFormat ff_dirac_muxer; +extern AVInputFormat ff_dnxhd_demuxer; +extern AVOutputFormat ff_dnxhd_muxer; +extern AVInputFormat ff_dsf_demuxer; +extern AVInputFormat ff_dsicin_demuxer; +extern AVInputFormat ff_dss_demuxer; +extern AVInputFormat ff_dts_demuxer; +extern AVOutputFormat ff_dts_muxer; +extern AVInputFormat ff_dtshd_demuxer; +extern AVInputFormat ff_dv_demuxer; +extern AVOutputFormat ff_dv_muxer; +extern AVInputFormat ff_dvbsub_demuxer; +extern AVInputFormat ff_dvbtxt_demuxer; +extern AVInputFormat ff_dxa_demuxer; +extern AVInputFormat ff_ea_demuxer; +extern AVInputFormat ff_ea_cdata_demuxer; +extern AVInputFormat ff_eac3_demuxer; +extern AVOutputFormat ff_eac3_muxer; +extern AVInputFormat ff_epaf_demuxer; +extern AVOutputFormat ff_f4v_muxer; +extern AVInputFormat ff_ffmetadata_demuxer; +extern AVOutputFormat ff_ffmetadata_muxer; +extern AVOutputFormat ff_fifo_muxer; +extern AVOutputFormat ff_fifo_test_muxer; +extern AVInputFormat ff_filmstrip_demuxer; +extern AVOutputFormat ff_filmstrip_muxer; +extern AVInputFormat ff_fits_demuxer; +extern AVOutputFormat ff_fits_muxer; +extern AVInputFormat ff_flac_demuxer; +extern AVOutputFormat ff_flac_muxer; +extern AVInputFormat ff_flic_demuxer; +extern AVInputFormat ff_flv_demuxer; +extern AVOutputFormat ff_flv_muxer; +extern AVInputFormat ff_live_flv_demuxer; +extern AVInputFormat ff_fourxm_demuxer; +extern AVOutputFormat ff_framecrc_muxer; +extern AVOutputFormat ff_framehash_muxer; +extern AVOutputFormat ff_framemd5_muxer; +extern AVInputFormat ff_frm_demuxer; +extern AVInputFormat ff_fsb_demuxer; +extern AVInputFormat ff_g722_demuxer; +extern AVOutputFormat ff_g722_muxer; +extern AVInputFormat ff_g723_1_demuxer; +extern AVOutputFormat ff_g723_1_muxer; +extern AVInputFormat ff_g726_demuxer; +extern AVOutputFormat ff_g726_muxer; +extern AVInputFormat ff_g726le_demuxer; +extern AVOutputFormat ff_g726le_muxer; +extern AVInputFormat ff_g729_demuxer; +extern AVInputFormat ff_gdv_demuxer; +extern AVInputFormat ff_genh_demuxer; +extern AVInputFormat ff_gif_demuxer; +extern AVOutputFormat ff_gif_muxer; +extern AVInputFormat ff_gsm_demuxer; +extern AVOutputFormat ff_gsm_muxer; +extern AVInputFormat ff_gxf_demuxer; +extern AVOutputFormat ff_gxf_muxer; +extern AVInputFormat ff_h261_demuxer; +extern AVOutputFormat ff_h261_muxer; +extern AVInputFormat ff_h263_demuxer; +extern AVOutputFormat ff_h263_muxer; +extern AVInputFormat ff_h264_demuxer; +extern AVOutputFormat ff_h264_muxer; +extern AVOutputFormat ff_hash_muxer; +extern AVInputFormat ff_hcom_demuxer; +extern AVOutputFormat ff_hds_muxer; +extern AVInputFormat ff_hevc_demuxer; +extern AVOutputFormat ff_hevc_muxer; +extern AVInputFormat ff_hls_demuxer; +extern AVOutputFormat ff_hls_muxer; +extern AVInputFormat ff_hnm_demuxer; +extern AVInputFormat ff_ico_demuxer; +extern AVOutputFormat ff_ico_muxer; +extern AVInputFormat ff_idcin_demuxer; +extern AVInputFormat ff_idf_demuxer; +extern AVInputFormat ff_iff_demuxer; +extern AVInputFormat ff_ifv_demuxer; +extern AVInputFormat ff_ilbc_demuxer; +extern AVOutputFormat ff_ilbc_muxer; +extern AVInputFormat ff_image2_demuxer; +extern AVOutputFormat ff_image2_muxer; +extern AVInputFormat ff_image2pipe_demuxer; +extern AVOutputFormat ff_image2pipe_muxer; +extern AVInputFormat ff_image2_alias_pix_demuxer; +extern AVInputFormat ff_image2_brender_pix_demuxer; +extern AVInputFormat ff_ingenient_demuxer; +extern AVInputFormat ff_ipmovie_demuxer; +extern AVOutputFormat ff_ipod_muxer; +extern AVInputFormat ff_ircam_demuxer; +extern AVOutputFormat ff_ircam_muxer; +extern AVOutputFormat ff_ismv_muxer; +extern AVInputFormat ff_iss_demuxer; +extern AVInputFormat ff_iv8_demuxer; +extern AVInputFormat ff_ivf_demuxer; +extern AVOutputFormat ff_ivf_muxer; +extern AVInputFormat ff_ivr_demuxer; +extern AVInputFormat ff_jacosub_demuxer; +extern AVOutputFormat ff_jacosub_muxer; +extern AVInputFormat ff_jv_demuxer; +extern AVInputFormat ff_kux_demuxer; +extern AVOutputFormat ff_latm_muxer; +extern AVInputFormat ff_lmlm4_demuxer; +extern AVInputFormat ff_loas_demuxer; +extern AVInputFormat ff_lrc_demuxer; +extern AVOutputFormat ff_lrc_muxer; +extern AVInputFormat ff_lvf_demuxer; +extern AVInputFormat ff_lxf_demuxer; +extern AVInputFormat ff_m4v_demuxer; +extern AVOutputFormat ff_m4v_muxer; +extern AVOutputFormat ff_md5_muxer; +extern AVInputFormat ff_matroska_demuxer; +extern AVOutputFormat ff_matroska_muxer; +extern AVOutputFormat ff_matroska_audio_muxer; +extern AVInputFormat ff_mgsts_demuxer; +extern AVInputFormat ff_microdvd_demuxer; +extern AVOutputFormat ff_microdvd_muxer; +extern AVInputFormat ff_mjpeg_demuxer; +extern AVOutputFormat ff_mjpeg_muxer; +extern AVInputFormat ff_mjpeg_2000_demuxer; +extern AVInputFormat ff_mlp_demuxer; +extern AVOutputFormat ff_mlp_muxer; +extern AVInputFormat ff_mlv_demuxer; +extern AVInputFormat ff_mm_demuxer; +extern AVInputFormat ff_mmf_demuxer; +extern AVOutputFormat ff_mmf_muxer; +extern AVInputFormat ff_mov_demuxer; +extern AVOutputFormat ff_mov_muxer; +extern AVOutputFormat ff_mp2_muxer; +extern AVInputFormat ff_mp3_demuxer; +extern AVOutputFormat ff_mp3_muxer; +extern AVOutputFormat ff_mp4_muxer; +extern AVInputFormat ff_mpc_demuxer; +extern AVInputFormat ff_mpc8_demuxer; +extern AVOutputFormat ff_mpeg1system_muxer; +extern AVOutputFormat ff_mpeg1vcd_muxer; +extern AVOutputFormat ff_mpeg1video_muxer; +extern AVOutputFormat ff_mpeg2dvd_muxer; +extern AVOutputFormat ff_mpeg2svcd_muxer; +extern AVOutputFormat ff_mpeg2video_muxer; +extern AVOutputFormat ff_mpeg2vob_muxer; +extern AVInputFormat ff_mpegps_demuxer; +extern AVInputFormat ff_mpegts_demuxer; +extern AVOutputFormat ff_mpegts_muxer; +extern AVInputFormat ff_mpegtsraw_demuxer; +extern AVInputFormat ff_mpegvideo_demuxer; +extern AVInputFormat ff_mpjpeg_demuxer; +extern AVOutputFormat ff_mpjpeg_muxer; +extern AVInputFormat ff_mpl2_demuxer; +extern AVInputFormat ff_mpsub_demuxer; +extern AVInputFormat ff_msf_demuxer; +extern AVInputFormat ff_msnwc_tcp_demuxer; +extern AVInputFormat ff_mtaf_demuxer; +extern AVInputFormat ff_mtv_demuxer; +extern AVInputFormat ff_musx_demuxer; +extern AVInputFormat ff_mv_demuxer; +extern AVInputFormat ff_mvi_demuxer; +extern AVInputFormat ff_mxf_demuxer; +extern AVOutputFormat ff_mxf_muxer; +extern AVOutputFormat ff_mxf_d10_muxer; +extern AVOutputFormat ff_mxf_opatom_muxer; +extern AVInputFormat ff_mxg_demuxer; +extern AVInputFormat ff_nc_demuxer; +extern AVInputFormat ff_nistsphere_demuxer; +extern AVInputFormat ff_nsp_demuxer; +extern AVInputFormat ff_nsv_demuxer; +extern AVOutputFormat ff_null_muxer; +extern AVInputFormat ff_nut_demuxer; +extern AVOutputFormat ff_nut_muxer; +extern AVInputFormat ff_nuv_demuxer; +extern AVOutputFormat ff_oga_muxer; +extern AVInputFormat ff_ogg_demuxer; +extern AVOutputFormat ff_ogg_muxer; +extern AVOutputFormat ff_ogv_muxer; +extern AVInputFormat ff_oma_demuxer; +extern AVOutputFormat ff_oma_muxer; +extern AVOutputFormat ff_opus_muxer; +extern AVInputFormat ff_paf_demuxer; +extern AVInputFormat ff_pcm_alaw_demuxer; +extern AVOutputFormat ff_pcm_alaw_muxer; +extern AVInputFormat ff_pcm_mulaw_demuxer; +extern AVOutputFormat ff_pcm_mulaw_muxer; +extern AVInputFormat ff_pcm_vidc_demuxer; +extern AVOutputFormat ff_pcm_vidc_muxer; +extern AVInputFormat ff_pcm_f64be_demuxer; +extern AVOutputFormat ff_pcm_f64be_muxer; +extern AVInputFormat ff_pcm_f64le_demuxer; +extern AVOutputFormat ff_pcm_f64le_muxer; +extern AVInputFormat ff_pcm_f32be_demuxer; +extern AVOutputFormat ff_pcm_f32be_muxer; +extern AVInputFormat ff_pcm_f32le_demuxer; +extern AVOutputFormat ff_pcm_f32le_muxer; +extern AVInputFormat ff_pcm_s32be_demuxer; +extern AVOutputFormat ff_pcm_s32be_muxer; +extern AVInputFormat ff_pcm_s32le_demuxer; +extern AVOutputFormat ff_pcm_s32le_muxer; +extern AVInputFormat ff_pcm_s24be_demuxer; +extern AVOutputFormat ff_pcm_s24be_muxer; +extern AVInputFormat ff_pcm_s24le_demuxer; +extern AVOutputFormat ff_pcm_s24le_muxer; +extern AVInputFormat ff_pcm_s16be_demuxer; +extern AVOutputFormat ff_pcm_s16be_muxer; +extern AVInputFormat ff_pcm_s16le_demuxer; +extern AVOutputFormat ff_pcm_s16le_muxer; +extern AVInputFormat ff_pcm_s8_demuxer; +extern AVOutputFormat ff_pcm_s8_muxer; +extern AVInputFormat ff_pcm_u32be_demuxer; +extern AVOutputFormat ff_pcm_u32be_muxer; +extern AVInputFormat ff_pcm_u32le_demuxer; +extern AVOutputFormat ff_pcm_u32le_muxer; +extern AVInputFormat ff_pcm_u24be_demuxer; +extern AVOutputFormat ff_pcm_u24be_muxer; +extern AVInputFormat ff_pcm_u24le_demuxer; +extern AVOutputFormat ff_pcm_u24le_muxer; +extern AVInputFormat ff_pcm_u16be_demuxer; +extern AVOutputFormat ff_pcm_u16be_muxer; +extern AVInputFormat ff_pcm_u16le_demuxer; +extern AVOutputFormat ff_pcm_u16le_muxer; +extern AVInputFormat ff_pcm_u8_demuxer; +extern AVOutputFormat ff_pcm_u8_muxer; +extern AVInputFormat ff_pjs_demuxer; +extern AVInputFormat ff_pmp_demuxer; +extern AVOutputFormat ff_psp_muxer; +extern AVInputFormat ff_pva_demuxer; +extern AVInputFormat ff_pvf_demuxer; +extern AVInputFormat ff_qcp_demuxer; +extern AVInputFormat ff_r3d_demuxer; +extern AVInputFormat ff_rawvideo_demuxer; +extern AVOutputFormat ff_rawvideo_muxer; +extern AVInputFormat ff_realtext_demuxer; +extern AVInputFormat ff_redspark_demuxer; +extern AVInputFormat ff_rl2_demuxer; +extern AVInputFormat ff_rm_demuxer; +extern AVOutputFormat ff_rm_muxer; +extern AVInputFormat ff_roq_demuxer; +extern AVOutputFormat ff_roq_muxer; +extern AVInputFormat ff_rpl_demuxer; +extern AVInputFormat ff_rsd_demuxer; +extern AVInputFormat ff_rso_demuxer; +extern AVOutputFormat ff_rso_muxer; +extern AVInputFormat ff_rtp_demuxer; +extern AVOutputFormat ff_rtp_muxer; +extern AVOutputFormat ff_rtp_mpegts_muxer; +extern AVInputFormat ff_rtsp_demuxer; +extern AVOutputFormat ff_rtsp_muxer; +extern AVInputFormat ff_s337m_demuxer; +extern AVInputFormat ff_sami_demuxer; +extern AVInputFormat ff_sap_demuxer; +extern AVOutputFormat ff_sap_muxer; +extern AVInputFormat ff_sbc_demuxer; +extern AVOutputFormat ff_sbc_muxer; +extern AVInputFormat ff_sbg_demuxer; +extern AVInputFormat ff_scc_demuxer; +extern AVOutputFormat ff_scc_muxer; +extern AVInputFormat ff_sdp_demuxer; +extern AVInputFormat ff_sdr2_demuxer; +extern AVInputFormat ff_sds_demuxer; +extern AVInputFormat ff_sdx_demuxer; +extern AVInputFormat ff_segafilm_demuxer; +extern AVOutputFormat ff_segafilm_muxer; +extern AVOutputFormat ff_segment_muxer; +extern AVOutputFormat ff_stream_segment_muxer; +extern AVInputFormat ff_ser_demuxer; +extern AVInputFormat ff_shorten_demuxer; +extern AVInputFormat ff_siff_demuxer; +extern AVOutputFormat ff_singlejpeg_muxer; +extern AVInputFormat ff_sln_demuxer; +extern AVInputFormat ff_smacker_demuxer; +extern AVInputFormat ff_smjpeg_demuxer; +extern AVOutputFormat ff_smjpeg_muxer; +extern AVOutputFormat ff_smoothstreaming_muxer; +extern AVInputFormat ff_smush_demuxer; +extern AVInputFormat ff_sol_demuxer; +extern AVInputFormat ff_sox_demuxer; +extern AVOutputFormat ff_sox_muxer; +extern AVOutputFormat ff_spx_muxer; +extern AVInputFormat ff_spdif_demuxer; +extern AVOutputFormat ff_spdif_muxer; +extern AVInputFormat ff_srt_demuxer; +extern AVOutputFormat ff_srt_muxer; +extern AVInputFormat ff_str_demuxer; +extern AVInputFormat ff_stl_demuxer; +extern AVInputFormat ff_subviewer1_demuxer; +extern AVInputFormat ff_subviewer_demuxer; +extern AVInputFormat ff_sup_demuxer; +extern AVOutputFormat ff_sup_muxer; +extern AVInputFormat ff_svag_demuxer; +extern AVInputFormat ff_swf_demuxer; +extern AVOutputFormat ff_swf_muxer; +extern AVInputFormat ff_tak_demuxer; +extern AVOutputFormat ff_tee_muxer; +extern AVInputFormat ff_tedcaptions_demuxer; +extern AVOutputFormat ff_tg2_muxer; +extern AVOutputFormat ff_tgp_muxer; +extern AVInputFormat ff_thp_demuxer; +extern AVInputFormat ff_threedostr_demuxer; +extern AVInputFormat ff_tiertexseq_demuxer; +extern AVOutputFormat ff_mkvtimestamp_v2_muxer; +extern AVInputFormat ff_tmv_demuxer; +extern AVInputFormat ff_truehd_demuxer; +extern AVOutputFormat ff_truehd_muxer; +extern AVInputFormat ff_tta_demuxer; +extern AVOutputFormat ff_tta_muxer; +extern AVInputFormat ff_txd_demuxer; +extern AVInputFormat ff_tty_demuxer; +extern AVInputFormat ff_ty_demuxer; +extern AVOutputFormat ff_uncodedframecrc_muxer; +extern AVInputFormat ff_v210_demuxer; +extern AVInputFormat ff_v210x_demuxer; +extern AVInputFormat ff_vag_demuxer; +extern AVInputFormat ff_vc1_demuxer; +extern AVOutputFormat ff_vc1_muxer; +extern AVInputFormat ff_vc1t_demuxer; +extern AVOutputFormat ff_vc1t_muxer; +extern AVInputFormat ff_vividas_demuxer; +extern AVInputFormat ff_vivo_demuxer; +extern AVInputFormat ff_vmd_demuxer; +extern AVInputFormat ff_vobsub_demuxer; +extern AVInputFormat ff_voc_demuxer; +extern AVOutputFormat ff_voc_muxer; +extern AVInputFormat ff_vpk_demuxer; +extern AVInputFormat ff_vplayer_demuxer; +extern AVInputFormat ff_vqf_demuxer; +extern AVInputFormat ff_w64_demuxer; +extern AVOutputFormat ff_w64_muxer; +extern AVInputFormat ff_wav_demuxer; +extern AVOutputFormat ff_wav_muxer; +extern AVInputFormat ff_wc3_demuxer; +extern AVOutputFormat ff_webm_muxer; +extern AVInputFormat ff_webm_dash_manifest_demuxer; +extern AVOutputFormat ff_webm_dash_manifest_muxer; +extern AVOutputFormat ff_webm_chunk_muxer; +extern AVOutputFormat ff_webp_muxer; +extern AVInputFormat ff_webvtt_demuxer; +extern AVOutputFormat ff_webvtt_muxer; +extern AVInputFormat ff_wsaud_demuxer; +extern AVInputFormat ff_wsd_demuxer; +extern AVInputFormat ff_wsvqa_demuxer; +extern AVInputFormat ff_wtv_demuxer; +extern AVOutputFormat ff_wtv_muxer; +extern AVInputFormat ff_wve_demuxer; +extern AVInputFormat ff_wv_demuxer; +extern AVOutputFormat ff_wv_muxer; +extern AVInputFormat ff_xa_demuxer; +extern AVInputFormat ff_xbin_demuxer; +extern AVInputFormat ff_xmv_demuxer; +extern AVInputFormat ff_xvag_demuxer; +extern AVInputFormat ff_xwma_demuxer; +extern AVInputFormat ff_yop_demuxer; +extern AVInputFormat ff_yuv4mpegpipe_demuxer; +extern AVOutputFormat ff_yuv4mpegpipe_muxer; +/* image demuxers */ +extern AVInputFormat ff_image_bmp_pipe_demuxer; +extern AVInputFormat ff_image_dds_pipe_demuxer; +extern AVInputFormat ff_image_dpx_pipe_demuxer; +extern AVInputFormat ff_image_exr_pipe_demuxer; +extern AVInputFormat ff_image_gif_pipe_demuxer; +extern AVInputFormat ff_image_j2k_pipe_demuxer; +extern AVInputFormat ff_image_jpeg_pipe_demuxer; +extern AVInputFormat ff_image_jpegls_pipe_demuxer; +extern AVInputFormat ff_image_pam_pipe_demuxer; +extern AVInputFormat ff_image_pbm_pipe_demuxer; +extern AVInputFormat ff_image_pcx_pipe_demuxer; +extern AVInputFormat ff_image_pgmyuv_pipe_demuxer; +extern AVInputFormat ff_image_pgm_pipe_demuxer; +extern AVInputFormat ff_image_pictor_pipe_demuxer; +extern AVInputFormat ff_image_png_pipe_demuxer; +extern AVInputFormat ff_image_ppm_pipe_demuxer; +extern AVInputFormat ff_image_psd_pipe_demuxer; +extern AVInputFormat ff_image_qdraw_pipe_demuxer; +extern AVInputFormat ff_image_sgi_pipe_demuxer; +extern AVInputFormat ff_image_svg_pipe_demuxer; +extern AVInputFormat ff_image_sunrast_pipe_demuxer; +extern AVInputFormat ff_image_tiff_pipe_demuxer; +extern AVInputFormat ff_image_webp_pipe_demuxer; +extern AVInputFormat ff_image_xpm_pipe_demuxer; +extern AVInputFormat ff_image_xwd_pipe_demuxer; + +/* external libraries */ +extern AVOutputFormat ff_chromaprint_muxer; +extern AVInputFormat ff_libgme_demuxer; +extern AVInputFormat ff_libmodplug_demuxer; +extern AVInputFormat ff_libopenmpt_demuxer; +extern AVInputFormat ff_vapoursynth_demuxer; + +#include "libavformat/muxer_list.c" +#include "libavformat/demuxer_list.c" + +static const AVInputFormat * const *indev_list = NULL; +static const AVOutputFormat * const *outdev_list = NULL; + +const AVOutputFormat *av_muxer_iterate(void **opaque) +{ + static const uintptr_t size = sizeof(muxer_list)/sizeof(muxer_list[0]) - 1; + uintptr_t i = (uintptr_t)*opaque; + const AVOutputFormat *f = NULL; + + if (i < size) { + f = muxer_list[i]; + } else if (indev_list) { + f = outdev_list[i - size]; + } + + if (f) + *opaque = (void*)(i + 1); + return f; +} + +const AVInputFormat *av_demuxer_iterate(void **opaque) +{ + static const uintptr_t size = sizeof(demuxer_list)/sizeof(demuxer_list[0]) - 1; + uintptr_t i = (uintptr_t)*opaque; + const AVInputFormat *f = NULL; + + if (i < size) { + f = demuxer_list[i]; + } else if (outdev_list) { + f = indev_list[i - size]; + } + + if (f) + *opaque = (void*)(i + 1); + return f; +} + +static AVMutex avpriv_register_devices_mutex = AV_MUTEX_INITIALIZER; + +#if FF_API_NEXT +FF_DISABLE_DEPRECATION_WARNINGS +static AVOnce av_format_next_init = AV_ONCE_INIT; + +static void av_format_init_next(void) +{ + AVOutputFormat *prevout = NULL, *out; + AVInputFormat *previn = NULL, *in; + + ff_mutex_lock(&avpriv_register_devices_mutex); + + for (int i = 0; (out = (AVOutputFormat*)muxer_list[i]); i++) { + if (prevout) + prevout->next = out; + prevout = out; + } + + if (outdev_list) { + for (int i = 0; (out = (AVOutputFormat*)outdev_list[i]); i++) { + if (prevout) + prevout->next = out; + prevout = out; + } + } + + for (int i = 0; (in = (AVInputFormat*)demuxer_list[i]); i++) { + if (previn) + previn->next = in; + previn = in; + } + + if (indev_list) { + for (int i = 0; (in = (AVInputFormat*)indev_list[i]); i++) { + if (previn) + previn->next = in; + previn = in; + } + } + + ff_mutex_unlock(&avpriv_register_devices_mutex); +} + +AVInputFormat *av_iformat_next(const AVInputFormat *f) +{ + ff_thread_once(&av_format_next_init, av_format_init_next); + + if (f) +#if FF_API_AVIOFORMAT + return f->next; +#else + return (AVInputFormat *) f->next; +#endif + else { + void *opaque = NULL; + return (AVInputFormat *)av_demuxer_iterate(&opaque); + } +} + +AVOutputFormat *av_oformat_next(const AVOutputFormat *f) +{ + ff_thread_once(&av_format_next_init, av_format_init_next); + + if (f) +#if FF_API_AVIOFORMAT + return f->next; +#else + return (AVOutputFormat *) f->next; +#endif + else { + void *opaque = NULL; + return (AVOutputFormat *)av_muxer_iterate(&opaque); + } +} + +void av_register_all(void) +{ + ff_thread_once(&av_format_next_init, av_format_init_next); +} + +void av_register_input_format(AVInputFormat *format) +{ + ff_thread_once(&av_format_next_init, av_format_init_next); +} + +void av_register_output_format(AVOutputFormat *format) +{ + ff_thread_once(&av_format_next_init, av_format_init_next); +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +void avpriv_register_devices(const AVOutputFormat * const o[], const AVInputFormat * const i[]) +{ + ff_mutex_lock(&avpriv_register_devices_mutex); + outdev_list = o; + indev_list = i; + ff_mutex_unlock(&avpriv_register_devices_mutex); +#if FF_API_NEXT + av_format_init_next(); +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/demuxer_list.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/demuxer_list.c new file mode 100644 index 000000000..1c8fb117f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/demuxer_list.c @@ -0,0 +1,2 @@ +static const AVInputFormat * const demuxer_list[] = { + NULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/muxer_list.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/muxer_list.c new file mode 100644 index 000000000..f36d9499c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/muxer_list.c @@ -0,0 +1,2 @@ +static const AVOutputFormat * const muxer_list[] = { + NULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/protocol_list.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/protocol_list.c new file mode 100644 index 000000000..247e1e4c3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/protocol_list.c @@ -0,0 +1,2 @@ +static const URLProtocol * const url_protocols[] = { + NULL }; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/protocols.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/protocols.c new file mode 100644 index 000000000..ad9565979 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavformat/protocols.c @@ -0,0 +1,131 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/avstring.h" +#include "libavutil/mem.h" + +#include "url.h" + +extern const URLProtocol ff_async_protocol; +extern const URLProtocol ff_bluray_protocol; +extern const URLProtocol ff_cache_protocol; +extern const URLProtocol ff_concat_protocol; +extern const URLProtocol ff_crypto_protocol; +extern const URLProtocol ff_data_protocol; +extern const URLProtocol ff_ffrtmpcrypt_protocol; +extern const URLProtocol ff_ffrtmphttp_protocol; +extern const URLProtocol ff_file_protocol; +extern const URLProtocol ff_ftp_protocol; +extern const URLProtocol ff_gopher_protocol; +extern const URLProtocol ff_hls_protocol; +extern const URLProtocol ff_http_protocol; +extern const URLProtocol ff_httpproxy_protocol; +extern const URLProtocol ff_https_protocol; +extern const URLProtocol ff_icecast_protocol; +extern const URLProtocol ff_mmsh_protocol; +extern const URLProtocol ff_mmst_protocol; +extern const URLProtocol ff_md5_protocol; +extern const URLProtocol ff_pipe_protocol; +extern const URLProtocol ff_prompeg_protocol; +extern const URLProtocol ff_rtmp_protocol; +extern const URLProtocol ff_rtmpe_protocol; +extern const URLProtocol ff_rtmps_protocol; +extern const URLProtocol ff_rtmpt_protocol; +extern const URLProtocol ff_rtmpte_protocol; +extern const URLProtocol ff_rtmpts_protocol; +extern const URLProtocol ff_rtp_protocol; +extern const URLProtocol ff_sctp_protocol; +extern const URLProtocol ff_srtp_protocol; +extern const URLProtocol ff_subfile_protocol; +extern const URLProtocol ff_tee_protocol; +extern const URLProtocol ff_tcp_protocol; +extern const URLProtocol ff_tls_protocol; +extern const URLProtocol ff_udp_protocol; +extern const URLProtocol ff_udplite_protocol; +extern const URLProtocol ff_unix_protocol; +extern const URLProtocol ff_librtmp_protocol; +extern const URLProtocol ff_librtmpe_protocol; +extern const URLProtocol ff_librtmps_protocol; +extern const URLProtocol ff_librtmpt_protocol; +extern const URLProtocol ff_librtmpte_protocol; +extern const URLProtocol ff_libsrt_protocol; +extern const URLProtocol ff_libssh_protocol; +extern const URLProtocol ff_libsmbclient_protocol; + +#include "libavformat/protocol_list.c" + +const AVClass *ff_urlcontext_child_class_next(const AVClass *prev) +{ + int i; + + /* find the protocol that corresponds to prev */ + for (i = 0; prev && url_protocols[i]; i++) { + if (url_protocols[i]->priv_data_class == prev) { + i++; + break; + } + } + + /* find next protocol with priv options */ + for (; url_protocols[i]; i++) + if (url_protocols[i]->priv_data_class) + return url_protocols[i]->priv_data_class; + return NULL; +} + + +const char *avio_enum_protocols(void **opaque, int output) +{ + const URLProtocol **p = *opaque; + + p = p ? p + 1 : url_protocols; + *opaque = p; + if (!*p) { + *opaque = NULL; + return NULL; + } + if ((output && (*p)->url_write) || (!output && (*p)->url_read)) + return (*p)->name; + return avio_enum_protocols(opaque, output); +} + +const URLProtocol **ffurl_get_protocols(const char *whitelist, + const char *blacklist) +{ + const URLProtocol **ret; + int i, ret_idx = 0; + + ret = av_mallocz_array(FF_ARRAY_ELEMS(url_protocols), sizeof(*ret)); + if (!ret) + return NULL; + + for (i = 0; url_protocols[i]; i++) { + const URLProtocol *up = url_protocols[i]; + + if (whitelist && *whitelist && !av_match_name(up->name, whitelist)) + continue; + if (blacklist && *blacklist && av_match_name(up->name, blacklist)) + continue; + + ret[ret_idx++] = up; + } + + return ret; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/Makefile new file mode 100644 index 000000000..8a7a44e4b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/Makefile @@ -0,0 +1,250 @@ +NAME = avutil +DESC = FFmpeg utility library + +HEADERS = adler32.h \ + aes.h \ + aes_ctr.h \ + attributes.h \ + audio_fifo.h \ + avassert.h \ + avstring.h \ + avutil.h \ + base64.h \ + blowfish.h \ + bprint.h \ + bswap.h \ + buffer.h \ + cast5.h \ + camellia.h \ + channel_layout.h \ + common.h \ + cpu.h \ + crc.h \ + des.h \ + dict.h \ + display.h \ + downmix_info.h \ + encryption_info.h \ + error.h \ + eval.h \ + fifo.h \ + file.h \ + frame.h \ + hash.h \ + hdr_dynamic_metadata.h \ + hmac.h \ + hwcontext.h \ + hwcontext_cuda.h \ + hwcontext_d3d11va.h \ + hwcontext_drm.h \ + hwcontext_dxva2.h \ + hwcontext_qsv.h \ + hwcontext_mediacodec.h \ + hwcontext_vaapi.h \ + hwcontext_videotoolbox.h \ + hwcontext_vdpau.h \ + imgutils.h \ + intfloat.h \ + intreadwrite.h \ + lfg.h \ + log.h \ + macros.h \ + mathematics.h \ + mastering_display_metadata.h \ + md5.h \ + mem.h \ + motion_vector.h \ + murmur3.h \ + opt.h \ + parseutils.h \ + pixdesc.h \ + pixelutils.h \ + pixfmt.h \ + random_seed.h \ + rc4.h \ + rational.h \ + replaygain.h \ + ripemd.h \ + samplefmt.h \ + sha.h \ + sha512.h \ + spherical.h \ + stereo3d.h \ + threadmessage.h \ + time.h \ + timecode.h \ + timestamp.h \ + tree.h \ + twofish.h \ + version.h \ + xtea.h \ + tea.h \ + tx.h \ + +HEADERS-$(CONFIG_LZO) += lzo.h + +ARCH_HEADERS = bswap.h \ + intmath.h \ + intreadwrite.h \ + timer.h \ + +BUILT_HEADERS = avconfig.h \ + ffversion.h + +OBJS = adler32.o \ + aes.o \ + aes_ctr.o \ + audio_fifo.o \ + avstring.o \ + avsscanf.o \ + base64.o \ + blowfish.o \ + bprint.o \ + buffer.o \ + cast5.o \ + camellia.o \ + channel_layout.o \ + color_utils.o \ + cpu.o \ + crc.o \ + des.o \ + dict.o \ + display.o \ + downmix_info.o \ + encryption_info.o \ + error.o \ + eval.o \ + fifo.o \ + file.o \ + file_open.o \ + float_dsp.o \ + fixed_dsp.o \ + frame.o \ + hash.o \ + hdr_dynamic_metadata.o \ + hmac.o \ + hwcontext.o \ + imgutils.o \ + integer.o \ + intmath.o \ + lfg.o \ + lls.o \ + log.o \ + log2_tab.o \ + mathematics.o \ + mastering_display_metadata.o \ + md5.o \ + mem.o \ + murmur3.o \ + opt.o \ + parseutils.o \ + pixdesc.o \ + pixelutils.o \ + random_seed.o \ + rational.o \ + reverse.o \ + rc4.o \ + ripemd.o \ + samplefmt.o \ + sha.o \ + sha512.o \ + slicethread.o \ + spherical.o \ + stereo3d.o \ + threadmessage.o \ + time.o \ + timecode.o \ + tree.o \ + twofish.o \ + utils.o \ + xga_font_data.o \ + xtea.o \ + tea.o \ + tx.o \ + +OBJS-$(CONFIG_CUDA) += hwcontext_cuda.o +OBJS-$(CONFIG_D3D11VA) += hwcontext_d3d11va.o +OBJS-$(CONFIG_DXVA2) += hwcontext_dxva2.o +OBJS-$(CONFIG_LIBDRM) += hwcontext_drm.o +OBJS-$(CONFIG_LZO) += lzo.o +OBJS-$(CONFIG_MEDIACODEC) += hwcontext_mediacodec.o +OBJS-$(CONFIG_OPENCL) += hwcontext_opencl.o +OBJS-$(CONFIG_QSV) += hwcontext_qsv.o +OBJS-$(CONFIG_VAAPI) += hwcontext_vaapi.o +OBJS-$(CONFIG_VIDEOTOOLBOX) += hwcontext_videotoolbox.o +OBJS-$(CONFIG_VDPAU) += hwcontext_vdpau.o + +OBJS += $(COMPAT_OBJS:%=../compat/%) + +# Windows resource file +SLIBOBJS-$(HAVE_GNU_WINDRES) += avutilres.o + +SKIPHEADERS-$(HAVE_CUDA_H) += hwcontext_cuda.h +SKIPHEADERS-$(CONFIG_CUDA) += hwcontext_cuda_internal.h \ + cuda_check.h +SKIPHEADERS-$(CONFIG_D3D11VA) += hwcontext_d3d11va.h +SKIPHEADERS-$(CONFIG_DXVA2) += hwcontext_dxva2.h +SKIPHEADERS-$(CONFIG_QSV) += hwcontext_qsv.h +SKIPHEADERS-$(CONFIG_OPENCL) += hwcontext_opencl.h +SKIPHEADERS-$(CONFIG_VAAPI) += hwcontext_vaapi.h +SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += hwcontext_videotoolbox.h +SKIPHEADERS-$(CONFIG_VDPAU) += hwcontext_vdpau.h + +TESTPROGS = adler32 \ + aes \ + aes_ctr \ + audio_fifo \ + avstring \ + base64 \ + blowfish \ + bprint \ + cast5 \ + camellia \ + color_utils \ + cpu \ + crc \ + des \ + dict \ + display \ + encryption_info \ + error \ + eval \ + file \ + fifo \ + hash \ + hmac \ + hwdevice \ + integer \ + imgutils \ + lfg \ + lls \ + log \ + md5 \ + murmur3 \ + opt \ + pca \ + parseutils \ + pixdesc \ + pixelutils \ + pixfmt_best \ + random_seed \ + rational \ + ripemd \ + sha \ + sha512 \ + softfloat \ + tree \ + twofish \ + utf8 \ + xtea \ + tea \ + +TESTPROGS-$(HAVE_THREADS) += cpu_init +TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo + +TOOLS = crypto_bench ffhash ffeval ffescape + +tools/crypto_bench$(EXESUF): ELIBS += $(if $(VERSUS),$(subst +, -l,+$(VERSUS)),) +tools/crypto_bench$(EXESUF): CFLAGS += -DUSE_EXT_LIBS=0$(if $(VERSUS),$(subst +,+USE_,+$(VERSUS)),) + +$(SUBDIR)tests/lzo$(EXESUF): ELIBS = -llzo2 diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/bswap.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/bswap.h new file mode 100644 index 000000000..1e735c52c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/bswap.h @@ -0,0 +1,50 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AARCH64_BSWAP_H +#define AVUTIL_AARCH64_BSWAP_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_INLINE_ASM + +#define av_bswap16 av_bswap16 +static av_always_inline av_const unsigned av_bswap16(unsigned x) +{ + __asm__("rev16 %w0, %w0" : "+r"(x)); + return x; +} + +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + __asm__("rev %w0, %w0" : "+r"(x)); + return x; +} + +#define av_bswap64 av_bswap64 +static av_always_inline av_const uint64_t av_bswap64(uint64_t x) +{ + __asm__("rev %0, %0" : "+r"(x)); + return x; +} + +#endif /* HAVE_INLINE_ASM */ +#endif /* AVUTIL_AARCH64_BSWAP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/cpu.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/cpu.c new file mode 100644 index 000000000..cc641da57 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/cpu.c @@ -0,0 +1,38 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" +#include "config.h" + +int ff_get_cpu_flags_aarch64(void) +{ + return AV_CPU_FLAG_ARMV8 * HAVE_ARMV8 | + AV_CPU_FLAG_NEON * HAVE_NEON | + AV_CPU_FLAG_VFP * HAVE_VFP; +} + +size_t ff_get_cpu_max_align_aarch64(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_NEON) + return 16; + + return 8; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/cpu.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/cpu.h new file mode 100644 index 000000000..2ee3f9323 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/cpu.h @@ -0,0 +1,29 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AARCH64_CPU_H +#define AVUTIL_AARCH64_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define have_armv8(flags) CPUEXT(flags, ARMV8) +#define have_neon(flags) CPUEXT(flags, NEON) +#define have_vfp(flags) CPUEXT(flags, VFP) + +#endif /* AVUTIL_AARCH64_CPU_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/float_dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/float_dsp_init.c new file mode 100644 index 000000000..432507182 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/float_dsp_init.c @@ -0,0 +1,69 @@ +/* + * ARM NEON optimised Float DSP functions + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/float_dsp.h" +#include "cpu.h" + +void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, + int len); + +void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul, + int len); + +void ff_vector_dmul_scalar_neon(double *dst, const double *src, double mul, + int len); + +void ff_vector_fmul_window_neon(float *dst, const float *src0, + const float *src1, const float *win, int len); + +void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1, + const float *src2, int len); + +void ff_vector_fmul_reverse_neon(float *dst, const float *src0, + const float *src1, int len); + +void ff_butterflies_float_neon(float *v1, float *v2, int len); + +float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); + +av_cold void ff_float_dsp_init_aarch64(AVFloatDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + fdsp->butterflies_float = ff_butterflies_float_neon; + fdsp->scalarproduct_float = ff_scalarproduct_float_neon; + fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_neon; + fdsp->vector_fmul = ff_vector_fmul_neon; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon; + fdsp->vector_fmul_add = ff_vector_fmul_add_neon; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_neon; + fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_neon; + fdsp->vector_fmul_window = ff_vector_fmul_window_neon; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/neontest.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/neontest.h new file mode 100644 index 000000000..2d0fc1999 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/neontest.h @@ -0,0 +1,70 @@ +/* + * check NEON registers for clobbering + * Copyright (c) 2008 Ramiro Polla + * Copyright (c) 2013 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AARCH64_NEONTEST_H +#define AVUTIL_AARCH64_NEONTEST_H + +#include +#include +#include +#include +#include + +#include "libavutil/bswap.h" + +#define storeneonregs(mem) \ + __asm__ volatile( \ + "stp d8, d9, [%0]\n\t" \ + "stp d10, d11, [%0, #16]\n\t" \ + "stp d12, d13, [%0, #32]\n\t" \ + "stp d14, d15, [%0, #48]\n\t" \ + :: "r"(mem) : "memory") + +#define testneonclobbers(func, ctx, ...) \ + uint64_t neon[2][8]; \ + int ret; \ + storeneonregs(neon[0]); \ + ret = __real_ ## func(ctx, __VA_ARGS__); \ + storeneonregs(neon[1]); \ + if (memcmp(neon[0], neon[1], sizeof(neon[0]))) { \ + int i; \ + av_log(ctx, AV_LOG_ERROR, \ + "NEON REGS CLOBBERED IN %s!\n", #func); \ + for (i = 0; i < 8; i ++) \ + if (neon[0][i] != neon[1][i]) { \ + av_log(ctx, AV_LOG_ERROR, \ + "d%-2d = %016"PRIx64"\n", \ + 8 + i, av_bswap64(neon[0][i])); \ + av_log(ctx, AV_LOG_ERROR, \ + " -> %016"PRIx64"\n", \ + av_bswap64(neon[1][i])); \ + } \ + abort(); \ + } \ + return ret + +#define wrap(func) \ +int __real_ ## func; \ +int __wrap_ ## func; \ +int __wrap_ ## func + +#endif /* AVUTIL_AARCH64_NEONTEST_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/timer.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/timer.h new file mode 100644 index 000000000..b57003941 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/timer.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 Janne Grunau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AARCH64_TIMER_H +#define AVUTIL_AARCH64_TIMER_H + +#include +#include "config.h" + +#if HAVE_INLINE_ASM + +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + uint64_t cycle_counter; + __asm__ volatile( + "isb \t\n" + "mrs %0, pmccntr_el0 " + : "=r"(cycle_counter) :: "memory" ); + + return cycle_counter; +} + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_AARCH64_TIMER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/adler32.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/adler32.c new file mode 100644 index 000000000..c87d5e261 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/adler32.c @@ -0,0 +1,97 @@ +/* + * Compute the Adler-32 checksum of a data stream. + * This is a modified version based on adler32.c from the zlib library. + * + * Copyright (C) 1995 Mark Adler + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +/** + * @file + * Computes the Adler-32 checksum of a data stream + * + * This is a modified version based on adler32.c from the zlib library. + * @author Mark Adler + * @ingroup lavu_adler32 + */ + +#include "config.h" +#include "adler32.h" +#include "common.h" +#include "intreadwrite.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ + +#define DO1(buf) { s1 += *buf++; s2 += s1; } +#define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(buf); +#define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf); + +unsigned long av_adler32_update(unsigned long adler, const uint8_t * buf, + unsigned int len) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = adler >> 16; + + while (len > 0) { +#if HAVE_FAST_64BIT && HAVE_FAST_UNALIGNED && !CONFIG_SMALL + unsigned len2 = FFMIN((len-1) & ~7, 23*8); + if (len2) { + uint64_t a1= 0; + uint64_t a2= 0; + uint64_t b1= 0; + uint64_t b2= 0; + len -= len2; + s2 += s1*len2; + while (len2 >= 8) { + uint64_t v = AV_RN64(buf); + a2 += a1; + b2 += b1; + a1 += v &0x00FF00FF00FF00FF; + b1 += (v>>8)&0x00FF00FF00FF00FF; + len2 -= 8; + buf+=8; + } + + //We combine the 8 interleaved adler32 checksums without overflows + //Decreasing the number of iterations would allow below code to be + //simplified but would likely be slower due to the fewer iterations + //of the inner loop + s1 += ((a1+b1)*0x1000100010001)>>48; + s2 += ((((a2&0xFFFF0000FFFF)+(b2&0xFFFF0000FFFF)+((a2>>16)&0xFFFF0000FFFF)+((b2>>16)&0xFFFF0000FFFF))*0x800000008)>>32) +#if HAVE_BIGENDIAN + + 2*((b1*0x1000200030004)>>48) + + ((a1*0x1000100010001)>>48) + + 2*((a1*0x0000100020003)>>48); +#else + + 2*((a1*0x4000300020001)>>48) + + ((b1*0x1000100010001)>>48) + + 2*((b1*0x3000200010000)>>48); +#endif + } +#else + while (len > 4 && s2 < (1U << 31)) { + DO4(buf); + len -= 4; + } +#endif + DO1(buf); len--; + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/adler32.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/adler32.h new file mode 100644 index 000000000..a1f035b73 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/adler32.h @@ -0,0 +1,60 @@ +/* + * copyright (c) 2006 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_adler32 + * Public header for Adler-32 hash function implementation. + */ + +#ifndef AVUTIL_ADLER32_H +#define AVUTIL_ADLER32_H + +#include +#include "attributes.h" + +/** + * @defgroup lavu_adler32 Adler-32 + * @ingroup lavu_hash + * Adler-32 hash function implementation. + * + * @{ + */ + +/** + * Calculate the Adler32 checksum of a buffer. + * + * Passing the return value to a subsequent av_adler32_update() call + * allows the checksum of multiple buffers to be calculated as though + * they were concatenated. + * + * @param adler initial checksum value + * @param buf pointer to input buffer + * @param len size of input buffer + * @return updated checksum + */ +unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, + unsigned int len) av_pure; + +/** + * @} + */ + +#endif /* AVUTIL_ADLER32_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.c new file mode 100644 index 000000000..397ea7738 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.c @@ -0,0 +1,268 @@ +/* + * copyright (c) 2007 Michael Niedermayer + * + * some optimization ideas from aes128.c by Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "common.h" +#include "aes.h" +#include "aes_internal.h" +#include "intreadwrite.h" +#include "timer.h" + +const int av_aes_size= sizeof(AVAES); + +struct AVAES *av_aes_alloc(void) +{ + return av_mallocz(sizeof(struct AVAES)); +} + +static const uint8_t rcon[10] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 +}; + +static uint8_t sbox[256]; +static uint8_t inv_sbox[256]; +#if CONFIG_SMALL +static uint32_t enc_multbl[1][256]; +static uint32_t dec_multbl[1][256]; +#else +static uint32_t enc_multbl[4][256]; +static uint32_t dec_multbl[4][256]; +#endif + +#if HAVE_BIGENDIAN +# define ROT(x, s) (((x) >> (s)) | ((x) << (32-(s)))) +#else +# define ROT(x, s) (((x) << (s)) | ((x) >> (32-(s)))) +#endif + +static inline void addkey(av_aes_block *dst, const av_aes_block *src, + const av_aes_block *round_key) +{ + dst->u64[0] = src->u64[0] ^ round_key->u64[0]; + dst->u64[1] = src->u64[1] ^ round_key->u64[1]; +} + +static inline void addkey_s(av_aes_block *dst, const uint8_t *src, + const av_aes_block *round_key) +{ + dst->u64[0] = AV_RN64(src) ^ round_key->u64[0]; + dst->u64[1] = AV_RN64(src + 8) ^ round_key->u64[1]; +} + +static inline void addkey_d(uint8_t *dst, const av_aes_block *src, + const av_aes_block *round_key) +{ + AV_WN64(dst, src->u64[0] ^ round_key->u64[0]); + AV_WN64(dst + 8, src->u64[1] ^ round_key->u64[1]); +} + +static void subshift(av_aes_block s0[2], int s, const uint8_t *box) +{ + av_aes_block *s1 = (av_aes_block *) (s0[0].u8 - s); + av_aes_block *s3 = (av_aes_block *) (s0[0].u8 + s); + + s0[0].u8[ 0] = box[s0[1].u8[ 0]]; + s0[0].u8[ 4] = box[s0[1].u8[ 4]]; + s0[0].u8[ 8] = box[s0[1].u8[ 8]]; + s0[0].u8[12] = box[s0[1].u8[12]]; + s1[0].u8[ 3] = box[s1[1].u8[ 7]]; + s1[0].u8[ 7] = box[s1[1].u8[11]]; + s1[0].u8[11] = box[s1[1].u8[15]]; + s1[0].u8[15] = box[s1[1].u8[ 3]]; + s0[0].u8[ 2] = box[s0[1].u8[10]]; + s0[0].u8[10] = box[s0[1].u8[ 2]]; + s0[0].u8[ 6] = box[s0[1].u8[14]]; + s0[0].u8[14] = box[s0[1].u8[ 6]]; + s3[0].u8[ 1] = box[s3[1].u8[13]]; + s3[0].u8[13] = box[s3[1].u8[ 9]]; + s3[0].u8[ 9] = box[s3[1].u8[ 5]]; + s3[0].u8[ 5] = box[s3[1].u8[ 1]]; +} + +static inline int mix_core(uint32_t multbl[][256], int a, int b, int c, int d) +{ +#if CONFIG_SMALL + return multbl[0][a] ^ ROT(multbl[0][b], 8) ^ ROT(multbl[0][c], 16) ^ ROT(multbl[0][d], 24); +#else + return multbl[0][a] ^ multbl[1][b] ^ multbl[2][c] ^ multbl[3][d]; +#endif +} + +static inline void mix(av_aes_block state[2], uint32_t multbl[][256], int s1, int s3) +{ + uint8_t (*src)[4] = state[1].u8x4; + state[0].u32[0] = mix_core(multbl, src[0][0], src[s1 ][1], src[2][2], src[s3 ][3]); + state[0].u32[1] = mix_core(multbl, src[1][0], src[s3 - 1][1], src[3][2], src[s1 - 1][3]); + state[0].u32[2] = mix_core(multbl, src[2][0], src[s3 ][1], src[0][2], src[s1 ][3]); + state[0].u32[3] = mix_core(multbl, src[3][0], src[s1 - 1][1], src[1][2], src[s3 - 1][3]); +} + +static inline void aes_crypt(AVAES *a, int s, const uint8_t *sbox, + uint32_t multbl[][256]) +{ + int r; + + for (r = a->rounds - 1; r > 0; r--) { + mix(a->state, multbl, 3 - s, 1 + s); + addkey(&a->state[1], &a->state[0], &a->round_key[r]); + } + + subshift(&a->state[0], s, sbox); +} + +static void aes_encrypt(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds) +{ + while (count--) { + addkey_s(&a->state[1], src, &a->round_key[rounds]); + if (iv) + addkey_s(&a->state[1], iv, &a->state[1]); + aes_crypt(a, 2, sbox, enc_multbl); + addkey_d(dst, &a->state[0], &a->round_key[0]); + if (iv) + memcpy(iv, dst, 16); + src += 16; + dst += 16; + } +} + +static void aes_decrypt(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds) +{ + while (count--) { + addkey_s(&a->state[1], src, &a->round_key[rounds]); + aes_crypt(a, 0, inv_sbox, dec_multbl); + if (iv) { + addkey_s(&a->state[0], iv, &a->state[0]); + memcpy(iv, src, 16); + } + addkey_d(dst, &a->state[0], &a->round_key[0]); + src += 16; + dst += 16; + } +} + +void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt) +{ + a->crypt(a, dst, src, count, iv, a->rounds); +} + +static void init_multbl2(uint32_t tbl[][256], const int c[4], + const uint8_t *log8, const uint8_t *alog8, + const uint8_t *sbox) +{ + int i; + + for (i = 0; i < 256; i++) { + int x = sbox[i]; + if (x) { + int k, l, m, n; + x = log8[x]; + k = alog8[x + log8[c[0]]]; + l = alog8[x + log8[c[1]]]; + m = alog8[x + log8[c[2]]]; + n = alog8[x + log8[c[3]]]; + tbl[0][i] = AV_NE(MKBETAG(k, l, m, n), MKTAG(k, l, m, n)); +#if !CONFIG_SMALL + tbl[1][i] = ROT(tbl[0][i], 8); + tbl[2][i] = ROT(tbl[0][i], 16); + tbl[3][i] = ROT(tbl[0][i], 24); +#endif + } + } +} + +// this is based on the reference AES code by Paulo Barreto and Vincent Rijmen +int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) +{ + int i, j, t, rconpointer = 0; + uint8_t tk[8][4]; + int KC = key_bits >> 5; + int rounds = KC + 6; + uint8_t log8[256]; + uint8_t alog8[512]; + + a->crypt = decrypt ? aes_decrypt : aes_encrypt; + + if (!enc_multbl[FF_ARRAY_ELEMS(enc_multbl) - 1][FF_ARRAY_ELEMS(enc_multbl[0]) - 1]) { + j = 1; + for (i = 0; i < 255; i++) { + alog8[i] = alog8[i + 255] = j; + log8[j] = i; + j ^= j + j; + if (j > 255) + j ^= 0x11B; + } + for (i = 0; i < 256; i++) { + j = i ? alog8[255 - log8[i]] : 0; + j ^= (j << 1) ^ (j << 2) ^ (j << 3) ^ (j << 4); + j = (j ^ (j >> 8) ^ 99) & 255; + inv_sbox[j] = i; + sbox[i] = j; + } + init_multbl2(dec_multbl, (const int[4]) { 0xe, 0x9, 0xd, 0xb }, + log8, alog8, inv_sbox); + init_multbl2(enc_multbl, (const int[4]) { 0x2, 0x1, 0x1, 0x3 }, + log8, alog8, sbox); + } + + if (key_bits != 128 && key_bits != 192 && key_bits != 256) + return AVERROR(EINVAL); + + a->rounds = rounds; + + memcpy(tk, key, KC * 4); + memcpy(a->round_key[0].u8, key, KC * 4); + + for (t = KC * 4; t < (rounds + 1) * 16; t += KC * 4) { + for (i = 0; i < 4; i++) + tk[0][i] ^= sbox[tk[KC - 1][(i + 1) & 3]]; + tk[0][0] ^= rcon[rconpointer++]; + + for (j = 1; j < KC; j++) { + if (KC != 8 || j != KC >> 1) + for (i = 0; i < 4; i++) + tk[j][i] ^= tk[j - 1][i]; + else + for (i = 0; i < 4; i++) + tk[j][i] ^= sbox[tk[j - 1][i]]; + } + + memcpy(a->round_key[0].u8 + t, tk, KC * 4); + } + + if (decrypt) { + for (i = 1; i < rounds; i++) { + av_aes_block tmp[3]; + tmp[2] = a->round_key[i]; + subshift(&tmp[1], 0, sbox); + mix(tmp, dec_multbl, 1, 3); + a->round_key[i] = tmp[0]; + } + } else { + for (i = 0; i < (rounds + 1) >> 1; i++) + FFSWAP(av_aes_block, a->round_key[i], a->round_key[rounds - i]); + } + + return 0; +} + diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.h new file mode 100644 index 000000000..09efbda10 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes.h @@ -0,0 +1,65 @@ +/* + * copyright (c) 2007 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AES_H +#define AVUTIL_AES_H + +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_aes AES + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_aes_size; + +struct AVAES; + +/** + * Allocate an AVAES context. + */ +struct AVAES *av_aes_alloc(void); + +/** + * Initialize an AVAES context. + * @param key_bits 128, 192 or 256 + * @param decrypt 0 for encryption, 1 for decryption + */ +int av_aes_init(struct AVAES *a, const uint8_t *key, int key_bits, int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * @param count number of 16 byte blocks + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_aes_crypt(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_AES_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_ctr.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_ctr.c new file mode 100644 index 000000000..0c2e86785 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_ctr.c @@ -0,0 +1,135 @@ +/* + * AES-CTR cipher + * Copyright (c) 2015 Eran Kornblau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "common.h" +#include "aes_ctr.h" +#include "aes.h" +#include "random_seed.h" + +#define AES_BLOCK_SIZE (16) + +typedef struct AVAESCTR { + struct AVAES* aes; + uint8_t counter[AES_BLOCK_SIZE]; + uint8_t encrypted_counter[AES_BLOCK_SIZE]; + int block_offset; +} AVAESCTR; + +struct AVAESCTR *av_aes_ctr_alloc(void) +{ + return av_mallocz(sizeof(struct AVAESCTR)); +} + +void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv) +{ + memcpy(a->counter, iv, AES_CTR_IV_SIZE); + memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE); + a->block_offset = 0; +} + +void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t* iv) +{ + memcpy(a->counter, iv, sizeof(a->counter)); + a->block_offset = 0; +} + +const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a) +{ + return a->counter; +} + +void av_aes_ctr_set_random_iv(struct AVAESCTR *a) +{ + uint32_t iv[2]; + + iv[0] = av_get_random_seed(); + iv[1] = av_get_random_seed(); + + av_aes_ctr_set_iv(a, (uint8_t*)iv); +} + +int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key) +{ + a->aes = av_aes_alloc(); + if (!a->aes) { + return AVERROR(ENOMEM); + } + + av_aes_init(a->aes, key, 128, 0); + + memset(a->counter, 0, sizeof(a->counter)); + a->block_offset = 0; + + return 0; +} + +void av_aes_ctr_free(struct AVAESCTR *a) +{ + if (a) { + av_freep(&a->aes); + av_free(a); + } +} + +static void av_aes_ctr_increment_be64(uint8_t* counter) +{ + uint8_t* cur_pos; + + for (cur_pos = counter + 7; cur_pos >= counter; cur_pos--) { + (*cur_pos)++; + if (*cur_pos != 0) { + break; + } + } +} + +void av_aes_ctr_increment_iv(struct AVAESCTR *a) +{ + av_aes_ctr_increment_be64(a->counter); + memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE); + a->block_offset = 0; +} + +void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count) +{ + const uint8_t* src_end = src + count; + const uint8_t* cur_end_pos; + uint8_t* encrypted_counter_pos; + + while (src < src_end) { + if (a->block_offset == 0) { + av_aes_crypt(a->aes, a->encrypted_counter, a->counter, 1, NULL, 0); + + av_aes_ctr_increment_be64(a->counter + 8); + } + + encrypted_counter_pos = a->encrypted_counter + a->block_offset; + cur_end_pos = src + AES_BLOCK_SIZE - a->block_offset; + cur_end_pos = FFMIN(cur_end_pos, src_end); + + a->block_offset += cur_end_pos - src; + a->block_offset &= (AES_BLOCK_SIZE - 1); + + while (src < cur_end_pos) { + *dst++ = *src++ ^ *encrypted_counter_pos++; + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_ctr.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_ctr.h new file mode 100644 index 000000000..e4aae126a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_ctr.h @@ -0,0 +1,88 @@ +/* + * AES-CTR cipher + * Copyright (c) 2015 Eran Kornblau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AES_CTR_H +#define AVUTIL_AES_CTR_H + +#include + +#include "attributes.h" +#include "version.h" + +#define AES_CTR_KEY_SIZE (16) +#define AES_CTR_IV_SIZE (8) + +struct AVAESCTR; + +/** + * Allocate an AVAESCTR context. + */ +struct AVAESCTR *av_aes_ctr_alloc(void); + +/** + * Initialize an AVAESCTR context. + * @param key encryption key, must have a length of AES_CTR_KEY_SIZE + */ +int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key); + +/** + * Release an AVAESCTR context. + */ +void av_aes_ctr_free(struct AVAESCTR *a); + +/** + * Process a buffer using a previously initialized context. + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param size the size of src and dst + */ +void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int size); + +/** + * Get the current iv + */ +const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a); + +/** + * Generate a random iv + */ +void av_aes_ctr_set_random_iv(struct AVAESCTR *a); + +/** + * Forcefully change the 8-byte iv + */ +void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv); + +/** + * Forcefully change the "full" 16-byte iv, including the counter + */ +void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t* iv); + +/** + * Increment the top 64 bit of the iv (performed after each frame) + */ +void av_aes_ctr_increment_iv(struct AVAESCTR *a); + +/** + * @} + */ + +#endif /* AVUTIL_AES_CTR_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_internal.h new file mode 100644 index 000000000..494425878 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aes_internal.h @@ -0,0 +1,43 @@ +/* + * copyright (c) 2015 Rodger Combs + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AES_INTERNAL_H +#define AVUTIL_AES_INTERNAL_H + +#include "mem.h" +#include + +typedef union { + uint64_t u64[2]; + uint32_t u32[4]; + uint8_t u8x4[4][4]; + uint8_t u8[16]; +} av_aes_block; + +typedef struct AVAES { + // Note: round_key[16] is accessed in the init code, but this only + // overwrites state, which does not matter (see also commit ba554c0). + DECLARE_ALIGNED(16, av_aes_block, round_key)[15]; + DECLARE_ALIGNED(16, av_aes_block, state)[2]; + int rounds; + void (*crypt)(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int rounds); +} AVAES; + +#endif /* AVUTIL_AES_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/bswap.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/bswap.h new file mode 100644 index 000000000..611ff0ad5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/bswap.h @@ -0,0 +1,67 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_BSWAP_H +#define AVUTIL_ARM_BSWAP_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#ifdef __ARMCC_VERSION + +#if HAVE_ARMV6 +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + return __rev(x); +} +#endif /* HAVE_ARMV6 */ + +#elif HAVE_INLINE_ASM + +#if HAVE_ARMV6_INLINE +#define av_bswap16 av_bswap16 +static av_always_inline av_const unsigned av_bswap16(unsigned x) +{ + __asm__("rev16 %0, %0" : "+r"(x)); + return x; +} +#endif + +#if AV_GCC_VERSION_AT_MOST(4,4) +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ +#if HAVE_ARMV6_INLINE + __asm__("rev %0, %0" : "+r"(x)); +#else + uint32_t t; + __asm__ ("eor %1, %0, %0, ror #16 \n\t" + "bic %1, %1, #0xFF0000 \n\t" + "mov %0, %0, ror #8 \n\t" + "eor %0, %0, %1, lsr #8 \n\t" + : "+r"(x), "=&r"(t)); +#endif /* HAVE_ARMV6_INLINE */ + return x; +} +#endif /* AV_GCC_VERSION_AT_MOST(4,4) */ + +#endif /* __ARMCC_VERSION */ + +#endif /* AVUTIL_ARM_BSWAP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/cpu.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/cpu.c new file mode 100644 index 000000000..81e85e252 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/cpu.c @@ -0,0 +1,170 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" +#include "config.h" + +#define CORE_FLAG(f) \ + (AV_CPU_FLAG_ ## f * (HAVE_ ## f ## _EXTERNAL || HAVE_ ## f ## _INLINE)) + +#define CORE_CPU_FLAGS \ + (CORE_FLAG(ARMV5TE) | \ + CORE_FLAG(ARMV6) | \ + CORE_FLAG(ARMV6T2) | \ + CORE_FLAG(VFP) | \ + CORE_FLAG(VFPV3) | \ + CORE_FLAG(NEON)) + +#if defined __linux__ || defined __ANDROID__ + +#include +#include +#include +#include "libavutil/avstring.h" + +#define AT_HWCAP 16 + +/* Relevant HWCAP values from kernel headers */ +#define HWCAP_VFP (1 << 6) +#define HWCAP_EDSP (1 << 7) +#define HWCAP_THUMBEE (1 << 11) +#define HWCAP_NEON (1 << 12) +#define HWCAP_VFPv3 (1 << 13) +#define HWCAP_TLS (1 << 15) + +static int get_hwcap(uint32_t *hwcap) +{ + struct { uint32_t a_type; uint32_t a_val; } auxv; + FILE *f = fopen("/proc/self/auxv", "r"); + int err = -1; + + if (!f) + return -1; + + while (fread(&auxv, sizeof(auxv), 1, f) > 0) { + if (auxv.a_type == AT_HWCAP) { + *hwcap = auxv.a_val; + err = 0; + break; + } + } + + fclose(f); + return err; +} + +static int get_cpuinfo(uint32_t *hwcap) +{ + FILE *f = fopen("/proc/cpuinfo", "r"); + char buf[200]; + + if (!f) + return -1; + + *hwcap = 0; + while (fgets(buf, sizeof(buf), f)) { + if (av_strstart(buf, "Features", NULL)) { + if (strstr(buf, " edsp ")) + *hwcap |= HWCAP_EDSP; + if (strstr(buf, " tls ")) + *hwcap |= HWCAP_TLS; + if (strstr(buf, " thumbee ")) + *hwcap |= HWCAP_THUMBEE; + if (strstr(buf, " vfp ")) + *hwcap |= HWCAP_VFP; + if (strstr(buf, " vfpv3 ")) + *hwcap |= HWCAP_VFPv3; + if (strstr(buf, " neon ") || strstr(buf, " asimd ")) + *hwcap |= HWCAP_NEON; + if (strstr(buf, " fp ")) // Listed on 64 bit ARMv8 kernels + *hwcap |= HWCAP_VFP | HWCAP_VFPv3; + break; + } + } + fclose(f); + return 0; +} + +int ff_get_cpu_flags_arm(void) +{ + int flags = CORE_CPU_FLAGS; + uint32_t hwcap; + + if (get_hwcap(&hwcap) < 0) + if (get_cpuinfo(&hwcap) < 0) + return flags; + +#define check_cap(cap, flag) do { \ + if (hwcap & HWCAP_ ## cap) \ + flags |= AV_CPU_FLAG_ ## flag; \ + } while (0) + + /* No flags explicitly indicate v6 or v6T2 so check others which + imply support. */ + check_cap(EDSP, ARMV5TE); + check_cap(TLS, ARMV6); + check_cap(THUMBEE, ARMV6T2); + check_cap(VFP, VFP); + check_cap(VFPv3, VFPV3); + check_cap(NEON, NEON); + + /* The v6 checks above are not reliable so let higher flags + trickle down. */ + if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON)) + flags |= AV_CPU_FLAG_ARMV6T2; + else if (flags & (AV_CPU_FLAG_ARMV6T2 | AV_CPU_FLAG_ARMV6)) + /* Some functions use the 'setend' instruction which is deprecated on ARMv8 + * and serializing on some ARMv7 cores. This ensures such functions + * are only enabled on ARMv6. */ + flags |= AV_CPU_FLAG_SETEND; + + if (flags & AV_CPU_FLAG_ARMV6T2) + flags |= AV_CPU_FLAG_ARMV6; + + /* set the virtual VFPv2 vector mode flag */ + if ((flags & AV_CPU_FLAG_VFP) && !(flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON))) + flags |= AV_CPU_FLAG_VFP_VM; + + return flags; +} + +#else + +int ff_get_cpu_flags_arm(void) +{ + return AV_CPU_FLAG_ARMV5TE * HAVE_ARMV5TE | + AV_CPU_FLAG_ARMV6 * HAVE_ARMV6 | + AV_CPU_FLAG_ARMV6T2 * HAVE_ARMV6T2 | + AV_CPU_FLAG_VFP * HAVE_VFP | + AV_CPU_FLAG_VFPV3 * HAVE_VFPV3 | + AV_CPU_FLAG_NEON * HAVE_NEON | + AV_CPU_FLAG_SETEND * !(HAVE_NEON | HAVE_VFPV3); +} + +#endif + +size_t ff_get_cpu_max_align_arm(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_NEON) + return 16; + + return 8; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/cpu.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/cpu.h new file mode 100644 index 000000000..1d6cc65dc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/cpu.h @@ -0,0 +1,38 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_CPU_H +#define AVUTIL_ARM_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define have_armv5te(flags) CPUEXT(flags, ARMV5TE) +#define have_armv6(flags) CPUEXT(flags, ARMV6) +#define have_armv6t2(flags) CPUEXT(flags, ARMV6T2) +#define have_vfp(flags) CPUEXT(flags, VFP) +#define have_vfpv3(flags) CPUEXT(flags, VFPV3) +#define have_neon(flags) CPUEXT(flags, NEON) +#define have_setend(flags) CPUEXT(flags, SETEND) + +/* some functions use the VFPv2 vector mode which is deprecated in ARMv7-A + * and might trap on such CPU depending on the OS configuration */ +#define have_vfp_vm(flags) \ + (HAVE_VFP && ((flags) & AV_CPU_FLAG_VFP_VM)) + +#endif /* AVUTIL_ARM_CPU_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_arm.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_arm.h new file mode 100644 index 000000000..fe311cc0d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_arm.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2009 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_FLOAT_DSP_ARM_H +#define AVUTIL_ARM_FLOAT_DSP_ARM_H + +#include "libavutil/float_dsp.h" + +void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp, int cpu_flags); +void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp); + +#endif /* AVUTIL_ARM_FLOAT_DSP_ARM_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_arm.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_arm.c new file mode 100644 index 000000000..678762862 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_arm.c @@ -0,0 +1,32 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/float_dsp.h" +#include "cpu.h" +#include "float_dsp_arm.h" + +av_cold void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_vfp(cpu_flags)) + ff_float_dsp_init_vfp(fdsp, cpu_flags); + if (have_neon(cpu_flags)) + ff_float_dsp_init_neon(fdsp); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_neon.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_neon.c new file mode 100644 index 000000000..689aa77c7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_neon.c @@ -0,0 +1,59 @@ +/* + * ARM NEON optimised Float DSP functions + * Copyright (c) 2008 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/float_dsp.h" +#include "float_dsp_arm.h" + +void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, int len); + +void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_window_neon(float *dst, const float *src0, + const float *src1, const float *win, int len); + +void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1, + const float *src2, int len); + +void ff_vector_fmul_reverse_neon(float *dst, const float *src0, + const float *src1, int len); + +void ff_butterflies_float_neon(float *v1, float *v2, int len); + +float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); + +av_cold void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp) +{ + fdsp->vector_fmul = ff_vector_fmul_neon; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon; + fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_neon; + fdsp->vector_fmul_window = ff_vector_fmul_window_neon; + fdsp->vector_fmul_add = ff_vector_fmul_add_neon; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_neon; + fdsp->butterflies_float = ff_butterflies_float_neon; + fdsp->scalarproduct_float = ff_scalarproduct_float_neon; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_vfp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_vfp.c new file mode 100644 index 000000000..05873e7e3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/float_dsp_init_vfp.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2008 Siarhei Siamashka + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/float_dsp.h" +#include "cpu.h" +#include "float_dsp_arm.h" + +void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1, + int len); + +void ff_vector_fmul_window_vfp(float *dst, const float *src0, + const float *src1, const float *win, int len); + +void ff_vector_fmul_reverse_vfp(float *dst, const float *src0, + const float *src1, int len); + +void ff_butterflies_float_vfp(float *av_restrict v1, float *av_restrict v2, int len); + +av_cold void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp, int cpu_flags) +{ + if (have_vfp_vm(cpu_flags)) { + fdsp->vector_fmul = ff_vector_fmul_vfp; + fdsp->vector_fmul_window = ff_vector_fmul_window_vfp; + } + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_vfp; + if (have_vfp_vm(cpu_flags)) + fdsp->butterflies_float = ff_butterflies_float_vfp; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/intmath.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/intmath.h new file mode 100644 index 000000000..5311a7d52 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/intmath.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2010 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_INTMATH_H +#define AVUTIL_ARM_INTMATH_H + +#include + +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_INLINE_ASM + +#if HAVE_ARMV6_INLINE + +#define av_clip_uint8 av_clip_uint8_arm +static av_always_inline av_const int av_clip_uint8_arm(int a) +{ + int x; + __asm__ ("usat %0, #8, %1" : "=r"(x) : "r"(a)); + return x; +} + +#define av_clip_int8 av_clip_int8_arm +static av_always_inline av_const int av_clip_int8_arm(int a) +{ + int x; + __asm__ ("ssat %0, #8, %1" : "=r"(x) : "r"(a)); + return x; +} + +#define av_clip_uint16 av_clip_uint16_arm +static av_always_inline av_const int av_clip_uint16_arm(int a) +{ + int x; + __asm__ ("usat %0, #16, %1" : "=r"(x) : "r"(a)); + return x; +} + +#define av_clip_int16 av_clip_int16_arm +static av_always_inline av_const int av_clip_int16_arm(int a) +{ + int x; + __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a)); + return x; +} + +#define av_clip_intp2 av_clip_intp2_arm +static av_always_inline av_const int av_clip_intp2_arm(int a, int p) +{ + unsigned x; + __asm__ ("ssat %0, %2, %1" : "=r"(x) : "r"(a), "i"(p+1)); + return x; +} + +#define av_clip_uintp2 av_clip_uintp2_arm +static av_always_inline av_const unsigned av_clip_uintp2_arm(int a, int p) +{ + unsigned x; + __asm__ ("usat %0, %2, %1" : "=r"(x) : "r"(a), "i"(p)); + return x; +} + +#define av_sat_add32 av_sat_add32_arm +static av_always_inline int av_sat_add32_arm(int a, int b) +{ + int r; + __asm__ ("qadd %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); + return r; +} + +#define av_sat_dadd32 av_sat_dadd32_arm +static av_always_inline int av_sat_dadd32_arm(int a, int b) +{ + int r; + __asm__ ("qdadd %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); + return r; +} + +#define av_sat_sub32 av_sat_sub32_arm +static av_always_inline int av_sat_sub32_arm(int a, int b) +{ + int r; + __asm__ ("qsub %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); + return r; +} + +#define av_sat_dsub32 av_sat_dsub32_arm +static av_always_inline int av_sat_dsub32_arm(int a, int b) +{ + int r; + __asm__ ("qdsub %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); + return r; +} + +#endif /* HAVE_ARMV6_INLINE */ + +#if HAVE_ASM_MOD_Q + +#define av_clipl_int32 av_clipl_int32_arm +static av_always_inline av_const int32_t av_clipl_int32_arm(int64_t a) +{ + int x, y; + __asm__ ("adds %1, %R2, %Q2, lsr #31 \n\t" + "itet ne \n\t" + "mvnne %1, #1<<31 \n\t" + "moveq %0, %Q2 \n\t" + "eorne %0, %1, %R2, asr #31 \n\t" + : "=r"(x), "=&r"(y) : "r"(a) : "cc"); + return x; +} + +#endif /* HAVE_ASM_MOD_Q */ + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_ARM_INTMATH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/intreadwrite.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/intreadwrite.h new file mode 100644 index 000000000..60fc860cb --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/intreadwrite.h @@ -0,0 +1,91 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_INTREADWRITE_H +#define AVUTIL_ARM_INTREADWRITE_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_FAST_UNALIGNED && HAVE_INLINE_ASM && AV_GCC_VERSION_AT_MOST(4,6) + +#define AV_RN16 AV_RN16 +static av_always_inline unsigned AV_RN16(const void *p) +{ + const uint8_t *q = p; + unsigned v; +#if AV_GCC_VERSION_AT_MOST(4,5) + __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(*(const uint16_t *)q)); +#elif defined __thumb__ + __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(q[0]), "m"(q[1])); +#else + __asm__ ("ldrh %0, %1" : "=r"(v) : "Uq"(q[0]), "m"(q[1])); +#endif + return v; +} + +#define AV_WN16 AV_WN16 +static av_always_inline void AV_WN16(void *p, uint16_t v) +{ + __asm__ ("strh %1, %0" : "=m"(*(uint16_t *)p) : "r"(v)); +} + +#define AV_RN32 AV_RN32 +static av_always_inline uint32_t AV_RN32(const void *p) +{ + const struct __attribute__((packed)) { uint32_t v; } *q = p; + uint32_t v; + __asm__ ("ldr %0, %1" : "=r"(v) : "m"(*q)); + return v; +} + +#define AV_WN32 AV_WN32 +static av_always_inline void AV_WN32(void *p, uint32_t v) +{ + __asm__ ("str %1, %0" : "=m"(*(uint32_t *)p) : "r"(v)); +} + +#if HAVE_ASM_MOD_Q + +#define AV_RN64 AV_RN64 +static av_always_inline uint64_t AV_RN64(const void *p) +{ + const struct __attribute__((packed)) { uint32_t v; } *q = p; + uint64_t v; + __asm__ ("ldr %Q0, %1 \n\t" + "ldr %R0, %2 \n\t" + : "=&r"(v) + : "m"(q[0]), "m"(q[1])); + return v; +} + +#define AV_WN64 AV_WN64 +static av_always_inline void AV_WN64(void *p, uint64_t v) +{ + __asm__ ("str %Q2, %0 \n\t" + "str %R2, %1 \n\t" + : "=m"(*(uint32_t*)p), "=m"(*((uint32_t*)p+1)) + : "r"(v)); +} + +#endif /* HAVE_ASM_MOD_Q */ + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_ARM_INTREADWRITE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/neontest.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/neontest.h new file mode 100644 index 000000000..d75ab8380 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/neontest.h @@ -0,0 +1,67 @@ +/* + * check NEON registers for clobbering + * Copyright (c) 2008 Ramiro Polla + * Copyright (c) 2013 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_NEONTEST_H +#define AVUTIL_ARM_NEONTEST_H + +#include +#include +#include +#include +#include + +#include "libavutil/bswap.h" + +#define storeneonregs(mem) \ + __asm__ volatile( \ + "vstm %0, {d8-d15}\n\t" \ + :: "r"(mem) : "memory") + +#define testneonclobbers(func, ctx, ...) \ + uint64_t neon[2][8]; \ + int ret; \ + storeneonregs(neon[0]); \ + ret = __real_ ## func(ctx, __VA_ARGS__); \ + storeneonregs(neon[1]); \ + if (memcmp(neon[0], neon[1], sizeof(neon[0]))) { \ + int i; \ + av_log(ctx, AV_LOG_ERROR, \ + "NEON REGS CLOBBERED IN %s!\n", #func); \ + for (i = 0; i < 8; i ++) \ + if (neon[0][i] != neon[1][i]) { \ + av_log(ctx, AV_LOG_ERROR, \ + "d%-2d = %016"PRIx64"\n", \ + 8 + i, av_bswap64(neon[0][i])); \ + av_log(ctx, AV_LOG_ERROR, \ + " -> %016"PRIx64"\n", \ + av_bswap64(neon[1][i])); \ + } \ + abort(); \ + } \ + return ret + +#define wrap(func) \ +int __real_ ## func; \ +int __wrap_ ## func; \ +int __wrap_ ## func + +#endif /* AVUTIL_ARM_NEONTEST_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/timer.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/timer.h new file mode 100644 index 000000000..5e8bc8edd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/timer.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2009 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ARM_TIMER_H +#define AVUTIL_ARM_TIMER_H + +#include +#include "config.h" + +#if HAVE_INLINE_ASM && defined(__ARM_ARCH_7A__) + +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + unsigned cc; + __asm__ volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(cc)); + return cc; +} + +#endif /* HAVE_INLINE_ASM && __ARM_ARCH_7A__ */ + +#endif /* AVUTIL_ARM_TIMER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/attributes.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/attributes.h new file mode 100644 index 000000000..ced108aa2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/attributes.h @@ -0,0 +1,167 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Macro definitions for various function/variable attributes + */ + +#ifndef AVUTIL_ATTRIBUTES_H +#define AVUTIL_ATTRIBUTES_H + +#ifdef __GNUC__ +# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +# define AV_GCC_VERSION_AT_MOST(x,y) (__GNUC__ < (x) || __GNUC__ == (x) && __GNUC_MINOR__ <= (y)) +#else +# define AV_GCC_VERSION_AT_LEAST(x,y) 0 +# define AV_GCC_VERSION_AT_MOST(x,y) 0 +#endif + +#ifndef av_always_inline +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_always_inline __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +# define av_always_inline __forceinline +#else +# define av_always_inline inline +#endif +#endif + +#ifndef av_extern_inline +#if defined(__ICL) && __ICL >= 1210 || defined(__GNUC_STDC_INLINE__) +# define av_extern_inline extern inline +#else +# define av_extern_inline inline +#endif +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,4) +# define av_warn_unused_result __attribute__((warn_unused_result)) +#else +# define av_warn_unused_result +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_noinline __attribute__((noinline)) +#elif defined(_MSC_VER) +# define av_noinline __declspec(noinline) +#else +# define av_noinline +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) +# define av_pure __attribute__((pure)) +#else +# define av_pure +#endif + +#if AV_GCC_VERSION_AT_LEAST(2,6) || defined(__clang__) +# define av_const __attribute__((const)) +#else +# define av_const +#endif + +#if AV_GCC_VERSION_AT_LEAST(4,3) || defined(__clang__) +# define av_cold __attribute__((cold)) +#else +# define av_cold +#endif + +#if AV_GCC_VERSION_AT_LEAST(4,1) && !defined(__llvm__) +# define av_flatten __attribute__((flatten)) +#else +# define av_flatten +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define attribute_deprecated __attribute__((deprecated)) +#elif defined(_MSC_VER) +# define attribute_deprecated __declspec(deprecated) +#else +# define attribute_deprecated +#endif + +/** + * Disable warnings about deprecated features + * This is useful for sections of code kept for backward compatibility and + * scheduled for removal. + */ +#ifndef AV_NOWARN_DEPRECATED +#if AV_GCC_VERSION_AT_LEAST(4,6) +# define AV_NOWARN_DEPRECATED(code) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \ + code \ + _Pragma("GCC diagnostic pop") +#elif defined(_MSC_VER) +# define AV_NOWARN_DEPRECATED(code) \ + __pragma(warning(push)) \ + __pragma(warning(disable : 4996)) \ + code; \ + __pragma(warning(pop)) +#else +# define AV_NOWARN_DEPRECATED(code) code +#endif +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define av_unused __attribute__((unused)) +#else +# define av_unused +#endif + +/** + * Mark a variable as used and prevent the compiler from optimizing it + * away. This is useful for variables accessed only from inline + * assembler without the compiler being aware. + */ +#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) +# define av_used __attribute__((used)) +#else +# define av_used +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,3) || defined(__clang__) +# define av_alias __attribute__((may_alias)) +#else +# define av_alias +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__INTEL_COMPILER) +# define av_uninit(x) x=x +#else +# define av_uninit(x) x +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define av_builtin_constant_p __builtin_constant_p +# define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos))) +#else +# define av_builtin_constant_p(x) 0 +# define av_printf_format(fmtpos, attrpos) +#endif + +#if AV_GCC_VERSION_AT_LEAST(2,5) || defined(__clang__) +# define av_noreturn __attribute__((noreturn)) +#else +# define av_noreturn +#endif + +#endif /* AVUTIL_ATTRIBUTES_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/audio_fifo.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/audio_fifo.c new file mode 100644 index 000000000..1bf75ced5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/audio_fifo.c @@ -0,0 +1,236 @@ +/* + * Audio FIFO + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Audio FIFO + */ + +#include "avutil.h" +#include "audio_fifo.h" +#include "common.h" +#include "fifo.h" +#include "mem.h" +#include "samplefmt.h" + +struct AVAudioFifo { + AVFifoBuffer **buf; /**< single buffer for interleaved, per-channel buffers for planar */ + int nb_buffers; /**< number of buffers */ + int nb_samples; /**< number of samples currently in the FIFO */ + int allocated_samples; /**< current allocated size, in samples */ + + int channels; /**< number of channels */ + enum AVSampleFormat sample_fmt; /**< sample format */ + int sample_size; /**< size, in bytes, of one sample in a buffer */ +}; + +void av_audio_fifo_free(AVAudioFifo *af) +{ + if (af) { + if (af->buf) { + int i; + for (i = 0; i < af->nb_buffers; i++) { + av_fifo_freep(&af->buf[i]); + } + av_freep(&af->buf); + } + av_free(af); + } +} + +AVAudioFifo *av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, + int nb_samples) +{ + AVAudioFifo *af; + int buf_size, i; + + /* get channel buffer size (also validates parameters) */ + if (av_samples_get_buffer_size(&buf_size, channels, nb_samples, sample_fmt, 1) < 0) + return NULL; + + af = av_mallocz(sizeof(*af)); + if (!af) + return NULL; + + af->channels = channels; + af->sample_fmt = sample_fmt; + af->sample_size = buf_size / nb_samples; + af->nb_buffers = av_sample_fmt_is_planar(sample_fmt) ? channels : 1; + + af->buf = av_mallocz_array(af->nb_buffers, sizeof(*af->buf)); + if (!af->buf) + goto error; + + for (i = 0; i < af->nb_buffers; i++) { + af->buf[i] = av_fifo_alloc(buf_size); + if (!af->buf[i]) + goto error; + } + af->allocated_samples = nb_samples; + + return af; + +error: + av_audio_fifo_free(af); + return NULL; +} + +int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples) +{ + int i, ret, buf_size; + + if ((ret = av_samples_get_buffer_size(&buf_size, af->channels, nb_samples, + af->sample_fmt, 1)) < 0) + return ret; + + for (i = 0; i < af->nb_buffers; i++) { + if ((ret = av_fifo_realloc2(af->buf[i], buf_size)) < 0) + return ret; + } + af->allocated_samples = nb_samples; + return 0; +} + +int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples) +{ + int i, ret, size; + + /* automatically reallocate buffers if needed */ + if (av_audio_fifo_space(af) < nb_samples) { + int current_size = av_audio_fifo_size(af); + /* check for integer overflow in new size calculation */ + if (INT_MAX / 2 - current_size < nb_samples) + return AVERROR(EINVAL); + /* reallocate buffers */ + if ((ret = av_audio_fifo_realloc(af, 2 * (current_size + nb_samples))) < 0) + return ret; + } + + size = nb_samples * af->sample_size; + for (i = 0; i < af->nb_buffers; i++) { + ret = av_fifo_generic_write(af->buf[i], data[i], size, NULL); + if (ret != size) + return AVERROR_BUG; + } + af->nb_samples += nb_samples; + + return nb_samples; +} + +int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples) +{ + int i, ret, size; + + if (nb_samples < 0) + return AVERROR(EINVAL); + nb_samples = FFMIN(nb_samples, af->nb_samples); + if (!nb_samples) + return 0; + + size = nb_samples * af->sample_size; + for (i = 0; i < af->nb_buffers; i++) { + if ((ret = av_fifo_generic_peek(af->buf[i], data[i], size, NULL)) < 0) + return AVERROR_BUG; + } + + return nb_samples; +} + +int av_audio_fifo_peek_at(AVAudioFifo *af, void **data, int nb_samples, int offset) +{ + int i, ret, size; + + if (offset < 0 || offset >= af->nb_samples) + return AVERROR(EINVAL); + if (nb_samples < 0) + return AVERROR(EINVAL); + nb_samples = FFMIN(nb_samples, af->nb_samples); + if (!nb_samples) + return 0; + if (offset > af->nb_samples - nb_samples) + return AVERROR(EINVAL); + + offset *= af->sample_size; + size = nb_samples * af->sample_size; + for (i = 0; i < af->nb_buffers; i++) { + if ((ret = av_fifo_generic_peek_at(af->buf[i], data[i], offset, size, NULL)) < 0) + return AVERROR_BUG; + } + + return nb_samples; +} + +int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples) +{ + int i, size; + + if (nb_samples < 0) + return AVERROR(EINVAL); + nb_samples = FFMIN(nb_samples, af->nb_samples); + if (!nb_samples) + return 0; + + size = nb_samples * af->sample_size; + for (i = 0; i < af->nb_buffers; i++) { + if (av_fifo_generic_read(af->buf[i], data[i], size, NULL) < 0) + return AVERROR_BUG; + } + af->nb_samples -= nb_samples; + + return nb_samples; +} + +int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples) +{ + int i, size; + + if (nb_samples < 0) + return AVERROR(EINVAL); + nb_samples = FFMIN(nb_samples, af->nb_samples); + + if (nb_samples) { + size = nb_samples * af->sample_size; + for (i = 0; i < af->nb_buffers; i++) + av_fifo_drain(af->buf[i], size); + af->nb_samples -= nb_samples; + } + return 0; +} + +void av_audio_fifo_reset(AVAudioFifo *af) +{ + int i; + + for (i = 0; i < af->nb_buffers; i++) + av_fifo_reset(af->buf[i]); + + af->nb_samples = 0; +} + +int av_audio_fifo_size(AVAudioFifo *af) +{ + return af->nb_samples; +} + +int av_audio_fifo_space(AVAudioFifo *af) +{ + return af->allocated_samples - af->nb_samples; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/audio_fifo.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/audio_fifo.h new file mode 100644 index 000000000..d8a9194a8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/audio_fifo.h @@ -0,0 +1,187 @@ +/* + * Audio FIFO + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Audio FIFO Buffer + */ + +#ifndef AVUTIL_AUDIO_FIFO_H +#define AVUTIL_AUDIO_FIFO_H + +#include "avutil.h" +#include "fifo.h" +#include "samplefmt.h" + +/** + * @addtogroup lavu_audio + * @{ + * + * @defgroup lavu_audiofifo Audio FIFO Buffer + * @{ + */ + +/** + * Context for an Audio FIFO Buffer. + * + * - Operates at the sample level rather than the byte level. + * - Supports multiple channels with either planar or packed sample format. + * - Automatic reallocation when writing to a full buffer. + */ +typedef struct AVAudioFifo AVAudioFifo; + +/** + * Free an AVAudioFifo. + * + * @param af AVAudioFifo to free + */ +void av_audio_fifo_free(AVAudioFifo *af); + +/** + * Allocate an AVAudioFifo. + * + * @param sample_fmt sample format + * @param channels number of channels + * @param nb_samples initial allocation size, in samples + * @return newly allocated AVAudioFifo, or NULL on error + */ +AVAudioFifo *av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, + int nb_samples); + +/** + * Reallocate an AVAudioFifo. + * + * @param af AVAudioFifo to reallocate + * @param nb_samples new allocation size, in samples + * @return 0 if OK, or negative AVERROR code on failure + */ +av_warn_unused_result +int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples); + +/** + * Write data to an AVAudioFifo. + * + * The AVAudioFifo will be reallocated automatically if the available space + * is less than nb_samples. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to write to + * @param data audio data plane pointers + * @param nb_samples number of samples to write + * @return number of samples actually written, or negative AVERROR + * code on failure. If successful, the number of samples + * actually written will always be nb_samples. + */ +int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples); + +/** + * Peek data from an AVAudioFifo. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to read from + * @param data audio data plane pointers + * @param nb_samples number of samples to peek + * @return number of samples actually peek, or negative AVERROR code + * on failure. The number of samples actually peek will not + * be greater than nb_samples, and will only be less than + * nb_samples if av_audio_fifo_size is less than nb_samples. + */ +int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples); + +/** + * Peek data from an AVAudioFifo. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to read from + * @param data audio data plane pointers + * @param nb_samples number of samples to peek + * @param offset offset from current read position + * @return number of samples actually peek, or negative AVERROR code + * on failure. The number of samples actually peek will not + * be greater than nb_samples, and will only be less than + * nb_samples if av_audio_fifo_size is less than nb_samples. + */ +int av_audio_fifo_peek_at(AVAudioFifo *af, void **data, int nb_samples, int offset); + +/** + * Read data from an AVAudioFifo. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to read from + * @param data audio data plane pointers + * @param nb_samples number of samples to read + * @return number of samples actually read, or negative AVERROR code + * on failure. The number of samples actually read will not + * be greater than nb_samples, and will only be less than + * nb_samples if av_audio_fifo_size is less than nb_samples. + */ +int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples); + +/** + * Drain data from an AVAudioFifo. + * + * Removes the data without reading it. + * + * @param af AVAudioFifo to drain + * @param nb_samples number of samples to drain + * @return 0 if OK, or negative AVERROR code on failure + */ +int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples); + +/** + * Reset the AVAudioFifo buffer. + * + * This empties all data in the buffer. + * + * @param af AVAudioFifo to reset + */ +void av_audio_fifo_reset(AVAudioFifo *af); + +/** + * Get the current number of samples in the AVAudioFifo available for reading. + * + * @param af the AVAudioFifo to query + * @return number of samples available for reading + */ +int av_audio_fifo_size(AVAudioFifo *af); + +/** + * Get the current number of samples in the AVAudioFifo available for writing. + * + * @param af the AVAudioFifo to query + * @return number of samples available for writing + */ +int av_audio_fifo_space(AVAudioFifo *af); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_AUDIO_FIFO_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avassert.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avassert.h new file mode 100644 index 000000000..9abeadea4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avassert.h @@ -0,0 +1,75 @@ +/* + * copyright (c) 2010 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * simple assert() macros that are a bit more flexible than ISO C assert(). + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_AVASSERT_H +#define AVUTIL_AVASSERT_H + +#include +#include "avutil.h" +#include "log.h" + +/** + * assert() equivalent, that is always enabled. + */ +#define av_assert0(cond) do { \ + if (!(cond)) { \ + av_log(NULL, AV_LOG_PANIC, "Assertion %s failed at %s:%d\n", \ + AV_STRINGIFY(cond), __FILE__, __LINE__); \ + abort(); \ + } \ +} while (0) + + +/** + * assert() equivalent, that does not lie in speed critical code. + * These asserts() thus can be enabled without fearing speed loss. + */ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 0 +#define av_assert1(cond) av_assert0(cond) +#else +#define av_assert1(cond) ((void)0) +#endif + + +/** + * assert() equivalent, that does lie in speed critical code. + */ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 +#define av_assert2(cond) av_assert0(cond) +#define av_assert2_fpu() av_assert0_fpu() +#else +#define av_assert2(cond) ((void)0) +#define av_assert2_fpu() ((void)0) +#endif + +/** + * Assert that floating point operations can be executed. + * + * This will av_assert0() that the cpu is not in MMX state on X86 + */ +void av_assert0_fpu(void); + +#endif /* AVUTIL_AVASSERT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avconfig.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avconfig.h new file mode 100644 index 000000000..c289fbb55 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avconfig.h @@ -0,0 +1,6 @@ +/* Generated by ffmpeg configure */ +#ifndef AVUTIL_AVCONFIG_H +#define AVUTIL_AVCONFIG_H +#define AV_HAVE_BIGENDIAN 0 +#define AV_HAVE_FAST_UNALIGNED 1 +#endif /* AVUTIL_AVCONFIG_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avsscanf.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avsscanf.c new file mode 100644 index 000000000..1c85412fd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avsscanf.c @@ -0,0 +1,970 @@ +/* + * Copyright (c) 2005-2014 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "config.h" +#include "common.h" +#include "mem.h" +#include "avassert.h" +#include "avstring.h" +#include "bprint.h" + +typedef struct FFFILE { + size_t buf_size; + unsigned char *buf; + unsigned char *rpos, *rend; + unsigned char *shend; + ptrdiff_t shlim, shcnt; + void *cookie; + size_t (*read)(struct FFFILE *, unsigned char *, size_t); +} FFFILE; + +#define SIZE_hh -2 +#define SIZE_h -1 +#define SIZE_def 0 +#define SIZE_l 1 +#define SIZE_L 2 +#define SIZE_ll 3 + +#define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf)) + +static int fftoread(FFFILE *f) +{ + f->rpos = f->rend = f->buf + f->buf_size; + return 0; +} + +static size_t ffstring_read(FFFILE *f, unsigned char *buf, size_t len) +{ + char *src = f->cookie; + size_t k = len+256; + char *end = memchr(src, 0, k); + + if (end) k = end-src; + if (k < len) len = k; + memcpy(buf, src, len); + f->rpos = (void *)(src+len); + f->rend = (void *)(src+k); + f->cookie = src+k; + + return len; +} + +static int ffuflow(FFFILE *f) +{ + unsigned char c; + if (!fftoread(f) && f->read(f, &c, 1)==1) return c; + return EOF; +} + +static void ffshlim(FFFILE *f, ptrdiff_t lim) +{ + f->shlim = lim; + f->shcnt = f->buf - f->rpos; + /* If lim is nonzero, rend must be a valid pointer. */ + if (lim && f->rend - f->rpos > lim) + f->shend = f->rpos + lim; + else + f->shend = f->rend; +} + +static int ffshgetc(FFFILE *f) +{ + int c; + ptrdiff_t cnt = shcnt(f); + if (f->shlim && cnt >= f->shlim || (c=ffuflow(f)) < 0) { + f->shcnt = f->buf - f->rpos + cnt; + f->shend = 0; + return EOF; + } + cnt++; + if (f->shlim && f->rend - f->rpos > f->shlim - cnt) + f->shend = f->rpos + (f->shlim - cnt); + else + f->shend = f->rend; + f->shcnt = f->buf - f->rpos + cnt; + if (f->rpos[-1] != c) f->rpos[-1] = c; + return c; +} + +#define shlim(f, lim) ffshlim((f), (lim)) +#define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : ffshgetc(f)) +#define shunget(f) ((f)->shend ? (void)(f)->rpos-- : (void)0) + +static const unsigned char table[] = { -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,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, + -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, + 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1, + -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, + 25,26,27,28,29,30,31,32,33,34,35,-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,-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,-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, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +}; + +static unsigned long long ffintscan(FFFILE *f, unsigned base, int pok, unsigned long long lim) +{ + const unsigned char *val = table+1; + int c, neg=0; + unsigned x; + unsigned long long y; + if (base > 36 || base == 1) { + errno = EINVAL; + return 0; + } + while (av_isspace((c=shgetc(f)))); + if (c=='+' || c=='-') { + neg = -(c=='-'); + c = shgetc(f); + } + if ((base == 0 || base == 16) && c=='0') { + c = shgetc(f); + if ((c|32)=='x') { + c = shgetc(f); + if (val[c]>=16) { + shunget(f); + if (pok) shunget(f); + else shlim(f, 0); + return 0; + } + base = 16; + } else if (base == 0) { + base = 8; + } + } else { + if (base == 0) base = 10; + if (val[c] >= base) { + shunget(f); + shlim(f, 0); + errno = EINVAL; + return 0; + } + } + if (base == 10) { + for (x=0; c-'0'<10U && x<=UINT_MAX/10-1; c=shgetc(f)) + x = x*10 + (c-'0'); + for (y=x; c-'0'<10U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(c-'0'); c=shgetc(f)) + y = y*10 + (c-'0'); + if (c-'0'>=10U) goto done; + } else if (!(base & base-1)) { + int bs = "\0\1\2\4\7\3\6\5"[(0x17*base)>>5&7]; + for (x=0; val[c]>bs; c=shgetc(f)) + y = y<=lim) { + if (!(lim&1) && !neg) { + errno = ERANGE; + return lim-1; + } else if (y>lim) { + errno = ERANGE; + return lim; + } + } + return (y^neg)-neg; +} + +static long long scanexp(FFFILE *f, int pok) +{ + int c; + int x; + long long y; + int neg = 0; + + c = shgetc(f); + if (c=='+' || c=='-') { + neg = (c=='-'); + c = shgetc(f); + if (c-'0'>=10U && pok) shunget(f); + } + if (c-'0'>=10U) { + shunget(f); + return LLONG_MIN; + } + for (x=0; c-'0'<10U && x=0) { + shunget(f); + } + if (!gotdig) { + errno = EINVAL; + shlim(f, 0); + return 0; + } + + /* Handle zero specially to avoid nasty special cases later */ + if (!x[0]) return sign * 0.0; + + /* Optimize small integers (w/no exponent) and over/under-flow */ + if (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0)) + return sign * (double)x[0]; + if (lrp > -emin/2) { + errno = ERANGE; + return sign * DBL_MAX * DBL_MAX; + } + if (lrp < emin-2*DBL_MANT_DIG) { + errno = ERANGE; + return sign * DBL_MIN * DBL_MIN; + } + + /* Align incomplete final B1B digit */ + if (j) { + for (; j<9; j++) x[k]*=10; + k++; + j=0; + } + + a = 0; + z = k; + e2 = 0; + rp = lrp; + + /* Optimize small to mid-size integers (even in exp. notation) */ + if (lnz<9 && lnz<=rp && rp < 18) { + int bitlim; + if (rp == 9) return sign * (double)x[0]; + if (rp < 9) return sign * (double)x[0] / p10s[8-rp]; + bitlim = bits-3*(int)(rp-9); + if (bitlim>30 || x[0]>>bitlim==0) + return sign * (double)x[0] * p10s[rp-10]; + } + + /* Drop trailing zeros */ + for (; !x[z-1]; z--); + + /* Align radix point to B1B digit boundary */ + if (rp % 9) { + int rpm9 = rp>=0 ? rp%9 : rp%9+9; + int p10 = p10s[8-rpm9]; + uint32_t carry = 0; + for (k=a; k!=z; k++) { + uint32_t tmp = x[k] % p10; + x[k] = x[k]/p10 + carry; + carry = 1000000000/p10 * tmp; + if (k==a && !x[k]) { + a = (a+1 & MASK); + rp -= 9; + } + } + if (carry) x[z++] = carry; + rp += 9-rpm9; + } + + /* Upscale until desired number of bits are left of radix point */ + while (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[a] 1000000000) { + carry = tmp / 1000000000; + x[k] = tmp % 1000000000; + } else { + carry = 0; + x[k] = tmp; + } + if (k==(z-1 & MASK) && k!=a && !x[k]) z = k; + if (k==a) break; + } + if (carry) { + rp += 9; + a = (a-1 & MASK); + if (a == z) { + z = (z-1 & MASK); + x[z-1 & MASK] |= x[z]; + } + x[a] = carry; + } + } + + /* Downscale until exactly number of bits are left of radix point */ + for (;;) { + uint32_t carry = 0; + int sh = 1; + for (i=0; i th[i]) break; + } + if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break; + /* FIXME: find a way to compute optimal sh */ + if (rp > 9+9*LD_B1B_DIG) sh = 9; + e2 += sh; + for (k=a; k!=z; k=(k+1 & MASK)) { + uint32_t tmp = x[k] & (1<>sh) + carry; + carry = (1000000000>>sh) * tmp; + if (k==a && !x[k]) { + a = (a+1 & MASK); + i--; + rp -= 9; + } + } + if (carry) { + if ((z+1 & MASK) != a) { + x[z] = carry; + z = (z+1 & MASK); + } else x[z-1 & MASK] |= 1; + } + } + + /* Assemble desired bits into floating point variable */ + for (y=i=0; i DBL_MANT_DIG+e2-emin) { + bits = DBL_MANT_DIG+e2-emin; + if (bits<0) bits=0; + denormal = 1; + } + + /* Calculate bias term to force rounding, move out lower bits */ + if (bits < DBL_MANT_DIG) { + bias = copysign(scalbn(1, 2*DBL_MANT_DIG-bits-1), y); + frac = fmod(y, scalbn(1, DBL_MANT_DIG-bits)); + y -= frac; + y += bias; + } + + /* Process tail of decimal input so it can affect rounding */ + if ((a+i & MASK) != z) { + uint32_t t = x[a+i & MASK]; + if (t < 500000000 && (t || (a+i+1 & MASK) != z)) + frac += 0.25*sign; + else if (t > 500000000) + frac += 0.75*sign; + else if (t == 500000000) { + if ((a+i+1 & MASK) == z) + frac += 0.5*sign; + else + frac += 0.75*sign; + } + if (DBL_MANT_DIG-bits >= 2 && !fmod(frac, 1)) + frac++; + } + + y += frac; + y -= bias; + + if ((e2+DBL_MANT_DIG & INT_MAX) > emax-5) { + if (fabs(y) >= pow(2, DBL_MANT_DIG)) { + if (denormal && bits==DBL_MANT_DIG+e2-emin) + denormal = 0; + y *= 0.5; + e2++; + } + if (e2+DBL_MANT_DIG>emax || (denormal && frac)) + errno = ERANGE; + } + + return scalbn(y, e2); +} + +static double hexfloat(FFFILE *f, int bits, int emin, int sign, int pok) +{ + uint32_t x = 0; + double y = 0; + double scale = 1; + double bias = 0; + int gottail = 0, gotrad = 0, gotdig = 0; + long long rp = 0; + long long dc = 0; + long long e2 = 0; + int d; + int c; + + c = shgetc(f); + + /* Skip leading zeros */ + for (; c=='0'; c = shgetc(f)) + gotdig = 1; + + if (c=='.') { + gotrad = 1; + c = shgetc(f); + /* Count zeros after the radix point before significand */ + for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1; + } + + for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) { + if (c=='.') { + if (gotrad) break; + rp = dc; + gotrad = 1; + } else { + gotdig = 1; + if (c > '9') d = (c|32)+10-'a'; + else d = c-'0'; + if (dc<8) { + x = x*16 + d; + } else if (dc < DBL_MANT_DIG/4+1) { + y += d*(scale/=16); + } else if (d && !gottail) { + y += 0.5*scale; + gottail = 1; + } + dc++; + } + } + if (!gotdig) { + shunget(f); + if (pok) { + shunget(f); + if (gotrad) shunget(f); + } else { + shlim(f, 0); + } + return sign * 0.0; + } + if (!gotrad) rp = dc; + while (dc<8) x *= 16, dc++; + if ((c|32)=='p') { + e2 = scanexp(f, pok); + if (e2 == LLONG_MIN) { + if (pok) { + shunget(f); + } else { + shlim(f, 0); + return 0; + } + e2 = 0; + } + } else { + shunget(f); + } + e2 += 4*rp - 32; + + if (!x) return sign * 0.0; + if (e2 > -emin) { + errno = ERANGE; + return sign * DBL_MAX * DBL_MAX; + } + if (e2 < emin-2*DBL_MANT_DIG) { + errno = ERANGE; + return sign * DBL_MIN * DBL_MIN; + } + + while (x < 0x80000000) { + if (y>=0.5) { + x += x + 1; + y += y - 1; + } else { + x += x; + y += y; + } + e2--; + } + + if (bits > 32+e2-emin) { + bits = 32+e2-emin; + if (bits<0) bits=0; + } + + if (bits < DBL_MANT_DIG) + bias = copysign(scalbn(1, 32+DBL_MANT_DIG-bits-1), sign); + + if (bits<32 && y && !(x&1)) x++, y=0; + + y = bias + sign*(double)x + sign*y; + y -= bias; + + if (!y) errno = ERANGE; + + return scalbn(y, e2); +} + +static double fffloatscan(FFFILE *f, int prec, int pok) +{ + int sign = 1; + size_t i; + int bits; + int emin; + int c; + + switch (prec) { + case 0: + bits = FLT_MANT_DIG; + emin = FLT_MIN_EXP-bits; + break; + case 1: + bits = DBL_MANT_DIG; + emin = DBL_MIN_EXP-bits; + break; + case 2: + bits = DBL_MANT_DIG; + emin = DBL_MIN_EXP-bits; + break; + default: + return 0; + } + + while (av_isspace((c = shgetc(f)))); + + if (c=='+' || c=='-') { + sign -= 2*(c=='-'); + c = shgetc(f); + } + + for (i=0; i<8 && (c|32)=="infinity"[i]; i++) + if (i<7) c = shgetc(f); + if (i==3 || i==8 || (i>3 && pok)) { + if (i!=8) { + shunget(f); + if (pok) for (; i>3; i--) shunget(f); + } + return sign * INFINITY; + } + if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++) + if (i<2) c = shgetc(f); + if (i==3) { + if (shgetc(f) != '(') { + shunget(f); + return NAN; + } + for (i=1; ; i++) { + c = shgetc(f); + if (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_') + continue; + if (c==')') return NAN; + shunget(f); + if (!pok) { + errno = EINVAL; + shlim(f, 0); + return 0; + } + while (i--) shunget(f); + return NAN; + } + return NAN; + } + + if (i) { + shunget(f); + errno = EINVAL; + shlim(f, 0); + return 0; + } + + if (c=='0') { + c = shgetc(f); + if ((c|32) == 'x') + return hexfloat(f, bits, emin, sign, pok); + shunget(f); + c = '0'; + } + + return decfloat(f, c, bits, emin, sign, pok); +} + +static void *arg_n(va_list ap, unsigned int n) +{ + void *p; + unsigned int i; + va_list ap2; + va_copy(ap2, ap); + for (i=n; i>1; i--) va_arg(ap2, void *); + p = va_arg(ap2, void *); + va_end(ap2); + return p; +} + +static void store_int(void *dest, int size, unsigned long long i) +{ + if (!dest) return; + switch (size) { + case SIZE_hh: + *(char *)dest = i; + break; + case SIZE_h: + *(short *)dest = i; + break; + case SIZE_def: + *(int *)dest = i; + break; + case SIZE_l: + *(long *)dest = i; + break; + case SIZE_ll: + *(long long *)dest = i; + break; + } +} + +static int ff_vfscanf(FFFILE *f, const char *fmt, va_list ap) +{ + int width; + int size; + int base; + const unsigned char *p; + int c, t; + char *s; + void *dest=NULL; + int invert; + int matches=0; + unsigned long long x; + double y; + ptrdiff_t pos = 0; + unsigned char scanset[257]; + size_t i; + + for (p=(const unsigned char *)fmt; *p; p++) { + + if (av_isspace(*p)) { + while (av_isspace(p[1])) p++; + shlim(f, 0); + while (av_isspace(shgetc(f))); + shunget(f); + pos += shcnt(f); + continue; + } + if (*p != '%' || p[1] == '%') { + shlim(f, 0); + if (*p == '%') { + p++; + while (av_isspace((c=shgetc(f)))); + } else { + c = shgetc(f); + } + if (c!=*p) { + shunget(f); + if (c<0) goto input_fail; + goto match_fail; + } + pos += shcnt(f); + continue; + } + + p++; + if (*p=='*') { + dest = 0; p++; + } else if (av_isdigit(*p) && p[1]=='$') { + dest = arg_n(ap, *p-'0'); p+=2; + } else { + dest = va_arg(ap, void *); + } + + for (width=0; av_isdigit(*p); p++) { + width = 10*width + *p - '0'; + } + + if (*p=='m') { + s = 0; + p++; + } + + size = SIZE_def; + switch (*p++) { + case 'h': + if (*p == 'h') p++, size = SIZE_hh; + else size = SIZE_h; + break; + case 'l': + if (*p == 'l') p++, size = SIZE_ll; + else size = SIZE_l; + break; + case 'j': + size = SIZE_ll; + break; + case 'z': + case 't': + size = SIZE_l; + break; + case 'L': + size = SIZE_L; + break; + case 'd': case 'i': case 'o': case 'u': case 'x': + case 'a': case 'e': case 'f': case 'g': + case 'A': case 'E': case 'F': case 'G': case 'X': + case 's': case 'c': case '[': + case 'S': case 'C': + case 'p': case 'n': + p--; + break; + default: + goto fmt_fail; + } + + t = *p; + + /* C or S */ + if ((t&0x2f) == 3) { + t |= 32; + size = SIZE_l; + } + + switch (t) { + case 'c': + if (width < 1) width = 1; + case '[': + break; + case 'n': + store_int(dest, size, pos); + /* do not increment match count, etc! */ + continue; + default: + shlim(f, 0); + while (av_isspace(shgetc(f))); + shunget(f); + pos += shcnt(f); + } + + shlim(f, width); + if (shgetc(f) < 0) goto input_fail; + shunget(f); + + switch (t) { + case 's': + case 'c': + case '[': + if (t == 'c' || t == 's') { + memset(scanset, -1, sizeof scanset); + scanset[0] = 0; + if (t == 's') { + scanset[1 + '\t'] = 0; + scanset[1 + '\n'] = 0; + scanset[1 + '\v'] = 0; + scanset[1 + '\f'] = 0; + scanset[1 + '\r'] = 0; + scanset[1 + ' ' ] = 0; + } + } else { + if (*++p == '^') p++, invert = 1; + else invert = 0; + memset(scanset, invert, sizeof scanset); + scanset[0] = 0; + if (*p == '-') p++, scanset[1+'-'] = 1-invert; + else if (*p == ']') p++, scanset[1+']'] = 1-invert; + for (; *p != ']'; p++) { + if (!*p) goto fmt_fail; + if (*p=='-' && p[1] && p[1] != ']') + for (c=p++[-1]; c<*p; c++) + scanset[1+c] = 1-invert; + scanset[1+*p] = 1-invert; + } + } + s = 0; + i = 0; + if ((s = dest)) { + while (scanset[(c=shgetc(f))+1]) + s[i++] = c; + } else { + while (scanset[(c=shgetc(f))+1]); + } + shunget(f); + if (!shcnt(f)) goto match_fail; + if (t == 'c' && shcnt(f) != width) goto match_fail; + if (t != 'c') { + if (s) s[i] = 0; + } + break; + case 'p': + case 'X': + case 'x': + base = 16; + goto int_common; + case 'o': + base = 8; + goto int_common; + case 'd': + case 'u': + base = 10; + goto int_common; + case 'i': + base = 0; +int_common: + x = ffintscan(f, base, 0, ULLONG_MAX); + if (!shcnt(f)) + goto match_fail; + if (t=='p' && dest) + *(void **)dest = (void *)(uintptr_t)x; + else + store_int(dest, size, x); + break; + case 'a': case 'A': + case 'e': case 'E': + case 'f': case 'F': + case 'g': case 'G': + y = fffloatscan(f, size, 0); + if (!shcnt(f)) + goto match_fail; + if (dest) { + switch (size) { + case SIZE_def: + *(float *)dest = y; + break; + case SIZE_l: + *(double *)dest = y; + break; + case SIZE_L: + *(double *)dest = y; + break; + } + } + break; + } + + pos += shcnt(f); + if (dest) matches++; + } + if (0) { +fmt_fail: +input_fail: + if (!matches) matches--; + } +match_fail: + return matches; +} + +static int ff_vsscanf(const char *s, const char *fmt, va_list ap) +{ + FFFILE f = { + .buf = (void *)s, .cookie = (void *)s, + .read = ffstring_read, + }; + + return ff_vfscanf(&f, fmt, ap); +} + +int av_sscanf(const char *string, const char *format, ...) +{ + int ret; + va_list ap; + va_start(ap, format); + ret = ff_vsscanf(string, format, ap); + va_end(ap); + return ret; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avstring.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avstring.c new file mode 100644 index 000000000..4c068f5bc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avstring.c @@ -0,0 +1,461 @@ +/* + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * Copyright (c) 2007 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include "config.h" +#include "common.h" +#include "mem.h" +#include "avassert.h" +#include "avstring.h" +#include "bprint.h" + +int av_strstart(const char *str, const char *pfx, const char **ptr) +{ + while (*pfx && *pfx == *str) { + pfx++; + str++; + } + if (!*pfx && ptr) + *ptr = str; + return !*pfx; +} + +int av_stristart(const char *str, const char *pfx, const char **ptr) +{ + while (*pfx && av_toupper((unsigned)*pfx) == av_toupper((unsigned)*str)) { + pfx++; + str++; + } + if (!*pfx && ptr) + *ptr = str; + return !*pfx; +} + +char *av_stristr(const char *s1, const char *s2) +{ + if (!*s2) + return (char*)(intptr_t)s1; + + do + if (av_stristart(s1, s2, NULL)) + return (char*)(intptr_t)s1; + while (*s1++); + + return NULL; +} + +char *av_strnstr(const char *haystack, const char *needle, size_t hay_length) +{ + size_t needle_len = strlen(needle); + if (!needle_len) + return (char*)haystack; + while (hay_length >= needle_len) { + hay_length--; + if (!memcmp(haystack, needle, needle_len)) + return (char*)haystack; + haystack++; + } + return NULL; +} + +size_t av_strlcpy(char *dst, const char *src, size_t size) +{ + size_t len = 0; + while (++len < size && *src) + *dst++ = *src++; + if (len <= size) + *dst = 0; + return len + strlen(src) - 1; +} + +size_t av_strlcat(char *dst, const char *src, size_t size) +{ + size_t len = strlen(dst); + if (size <= len + 1) + return len + strlen(src); + return len + av_strlcpy(dst + len, src, size - len); +} + +size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) +{ + size_t len = strlen(dst); + va_list vl; + + va_start(vl, fmt); + len += vsnprintf(dst + len, size > len ? size - len : 0, fmt, vl); + va_end(vl); + + return len; +} + +char *av_asprintf(const char *fmt, ...) +{ + char *p = NULL; + va_list va; + int len; + + va_start(va, fmt); + len = vsnprintf(NULL, 0, fmt, va); + va_end(va); + if (len < 0) + goto end; + + p = av_malloc(len + 1); + if (!p) + goto end; + + va_start(va, fmt); + len = vsnprintf(p, len + 1, fmt, va); + va_end(va); + if (len < 0) + av_freep(&p); + +end: + return p; +} + +char *av_d2str(double d) +{ + char *str = av_malloc(16); + if (str) + snprintf(str, 16, "%f", d); + return str; +} + +#define WHITESPACES " \n\t\r" + +char *av_get_token(const char **buf, const char *term) +{ + char *out = av_malloc(strlen(*buf) + 1); + char *ret = out, *end = out; + const char *p = *buf; + if (!out) + return NULL; + p += strspn(p, WHITESPACES); + + while (*p && !strspn(p, term)) { + char c = *p++; + if (c == '\\' && *p) { + *out++ = *p++; + end = out; + } else if (c == '\'') { + while (*p && *p != '\'') + *out++ = *p++; + if (*p) { + p++; + end = out; + } + } else { + *out++ = c; + } + } + + do + *out-- = 0; + while (out >= end && strspn(out, WHITESPACES)); + + *buf = p; + + return ret; +} + +char *av_strtok(char *s, const char *delim, char **saveptr) +{ + char *tok; + + if (!s && !(s = *saveptr)) + return NULL; + + /* skip leading delimiters */ + s += strspn(s, delim); + + /* s now points to the first non delimiter char, or to the end of the string */ + if (!*s) { + *saveptr = NULL; + return NULL; + } + tok = s++; + + /* skip non delimiters */ + s += strcspn(s, delim); + if (*s) { + *s = 0; + *saveptr = s+1; + } else { + *saveptr = NULL; + } + + return tok; +} + +int av_strcasecmp(const char *a, const char *b) +{ + uint8_t c1, c2; + do { + c1 = av_tolower(*a++); + c2 = av_tolower(*b++); + } while (c1 && c1 == c2); + return c1 - c2; +} + +int av_strncasecmp(const char *a, const char *b, size_t n) +{ + uint8_t c1, c2; + if (n <= 0) + return 0; + do { + c1 = av_tolower(*a++); + c2 = av_tolower(*b++); + } while (--n && c1 && c1 == c2); + return c1 - c2; +} + +char *av_strireplace(const char *str, const char *from, const char *to) +{ + char *ret = NULL; + const char *pstr2, *pstr = str; + size_t tolen = strlen(to), fromlen = strlen(from); + AVBPrint pbuf; + + av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); + while ((pstr2 = av_stristr(pstr, from))) { + av_bprint_append_data(&pbuf, pstr, pstr2 - pstr); + pstr = pstr2 + fromlen; + av_bprint_append_data(&pbuf, to, tolen); + } + av_bprint_append_data(&pbuf, pstr, strlen(pstr)); + if (!av_bprint_is_complete(&pbuf)) { + av_bprint_finalize(&pbuf, NULL); + } else { + av_bprint_finalize(&pbuf, &ret); + } + + return ret; +} + +const char *av_basename(const char *path) +{ + char *p = strrchr(path, '/'); + +#if HAVE_DOS_PATHS + char *q = strrchr(path, '\\'); + char *d = strchr(path, ':'); + + p = FFMAX3(p, q, d); +#endif + + if (!p) + return path; + + return p + 1; +} + +const char *av_dirname(char *path) +{ + char *p = strrchr(path, '/'); + +#if HAVE_DOS_PATHS + char *q = strrchr(path, '\\'); + char *d = strchr(path, ':'); + + d = d ? d + 1 : d; + + p = FFMAX3(p, q, d); +#endif + + if (!p) + return "."; + + *p = '\0'; + + return path; +} + +char *av_append_path_component(const char *path, const char *component) +{ + size_t p_len, c_len; + char *fullpath; + + if (!path) + return av_strdup(component); + if (!component) + return av_strdup(path); + + p_len = strlen(path); + c_len = strlen(component); + if (p_len > SIZE_MAX - c_len || p_len + c_len > SIZE_MAX - 2) + return NULL; + fullpath = av_malloc(p_len + c_len + 2); + if (fullpath) { + if (p_len) { + av_strlcpy(fullpath, path, p_len + 1); + if (c_len) { + if (fullpath[p_len - 1] != '/' && component[0] != '/') + fullpath[p_len++] = '/'; + else if (fullpath[p_len - 1] == '/' && component[0] == '/') + p_len--; + } + } + av_strlcpy(&fullpath[p_len], component, c_len + 1); + fullpath[p_len + c_len] = 0; + } + return fullpath; +} + +int av_escape(char **dst, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags) +{ + AVBPrint dstbuf; + + av_bprint_init(&dstbuf, 1, AV_BPRINT_SIZE_UNLIMITED); + av_bprint_escape(&dstbuf, src, special_chars, mode, flags); + + if (!av_bprint_is_complete(&dstbuf)) { + av_bprint_finalize(&dstbuf, NULL); + return AVERROR(ENOMEM); + } else { + av_bprint_finalize(&dstbuf, dst); + return dstbuf.len; + } +} + +int av_match_name(const char *name, const char *names) +{ + const char *p; + int len, namelen; + + if (!name || !names) + return 0; + + namelen = strlen(name); + while (*names) { + int negate = '-' == *names; + p = strchr(names, ','); + if (!p) + p = names + strlen(names); + names += negate; + len = FFMAX(p - names, namelen); + if (!av_strncasecmp(name, names, len) || !strncmp("ALL", names, FFMAX(3, p - names))) + return !negate; + names = p + (*p == ','); + } + return 0; +} + +int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, + unsigned int flags) +{ + const uint8_t *p = *bufp; + uint32_t top; + uint64_t code; + int ret = 0, tail_len; + uint32_t overlong_encoding_mins[6] = { + 0x00000000, 0x00000080, 0x00000800, 0x00010000, 0x00200000, 0x04000000, + }; + + if (p >= buf_end) + return 0; + + code = *p++; + + /* first sequence byte starts with 10, or is 1111-1110 or 1111-1111, + which is not admitted */ + if ((code & 0xc0) == 0x80 || code >= 0xFE) { + ret = AVERROR(EILSEQ); + goto end; + } + top = (code & 128) >> 1; + + tail_len = 0; + while (code & top) { + int tmp; + tail_len++; + if (p >= buf_end) { + (*bufp) ++; + return AVERROR(EILSEQ); /* incomplete sequence */ + } + + /* we assume the byte to be in the form 10xx-xxxx */ + tmp = *p++ - 128; /* strip leading 1 */ + if (tmp>>6) { + (*bufp) ++; + return AVERROR(EILSEQ); + } + code = (code<<6) + tmp; + top <<= 5; + } + code &= (top << 1) - 1; + + /* check for overlong encodings */ + av_assert0(tail_len <= 5); + if (code < overlong_encoding_mins[tail_len]) { + ret = AVERROR(EILSEQ); + goto end; + } + + if (code >= 1U<<31) { + ret = AVERROR(EILSEQ); /* out-of-range value */ + goto end; + } + + *codep = code; + + if (code > 0x10FFFF && + !(flags & AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES)) + ret = AVERROR(EILSEQ); + if (code < 0x20 && code != 0x9 && code != 0xA && code != 0xD && + flags & AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES) + ret = AVERROR(EILSEQ); + if (code >= 0xD800 && code <= 0xDFFF && + !(flags & AV_UTF8_FLAG_ACCEPT_SURROGATES)) + ret = AVERROR(EILSEQ); + if ((code == 0xFFFE || code == 0xFFFF) && + !(flags & AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS)) + ret = AVERROR(EILSEQ); + +end: + *bufp = p; + return ret; +} + +int av_match_list(const char *name, const char *list, char separator) +{ + const char *p, *q; + + for (p = name; p && *p; ) { + for (q = list; q && *q; ) { + int k; + for (k = 0; p[k] == q[k] || (p[k]*q[k] == 0 && p[k]+q[k] == separator); k++) + if (k && (!p[k] || p[k] == separator)) + return 1; + q = strchr(q, separator); + q += !!q; + } + p = strchr(p, separator); + p += !!p; + } + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avstring.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avstring.h new file mode 100644 index 000000000..37dd4e2da --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avstring.h @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2007 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVSTRING_H +#define AVUTIL_AVSTRING_H + +#include +#include +#include "attributes.h" + +/** + * @addtogroup lavu_string + * @{ + */ + +/** + * Return non-zero if pfx is a prefix of str. If it is, *ptr is set to + * the address of the first character in str after the prefix. + * + * @param str input string + * @param pfx prefix to test + * @param ptr updated if the prefix is matched inside str + * @return non-zero if the prefix matches, zero otherwise + */ +int av_strstart(const char *str, const char *pfx, const char **ptr); + +/** + * Return non-zero if pfx is a prefix of str independent of case. If + * it is, *ptr is set to the address of the first character in str + * after the prefix. + * + * @param str input string + * @param pfx prefix to test + * @param ptr updated if the prefix is matched inside str + * @return non-zero if the prefix matches, zero otherwise + */ +int av_stristart(const char *str, const char *pfx, const char **ptr); + +/** + * Locate the first case-independent occurrence in the string haystack + * of the string needle. A zero-length string needle is considered to + * match at the start of haystack. + * + * This function is a case-insensitive version of the standard strstr(). + * + * @param haystack string to search in + * @param needle string to search for + * @return pointer to the located match within haystack + * or a null pointer if no match + */ +char *av_stristr(const char *haystack, const char *needle); + +/** + * Locate the first occurrence of the string needle in the string haystack + * where not more than hay_length characters are searched. A zero-length + * string needle is considered to match at the start of haystack. + * + * This function is a length-limited version of the standard strstr(). + * + * @param haystack string to search in + * @param needle string to search for + * @param hay_length length of string to search in + * @return pointer to the located match within haystack + * or a null pointer if no match + */ +char *av_strnstr(const char *haystack, const char *needle, size_t hay_length); + +/** + * Copy the string src to dst, but no more than size - 1 bytes, and + * null-terminate dst. + * + * This function is the same as BSD strlcpy(). + * + * @param dst destination buffer + * @param src source string + * @param size size of destination buffer + * @return the length of src + * + * @warning since the return value is the length of src, src absolutely + * _must_ be a properly 0-terminated string, otherwise this will read beyond + * the end of the buffer and possibly crash. + */ +size_t av_strlcpy(char *dst, const char *src, size_t size); + +/** + * Append the string src to the string dst, but to a total length of + * no more than size - 1 bytes, and null-terminate dst. + * + * This function is similar to BSD strlcat(), but differs when + * size <= strlen(dst). + * + * @param dst destination buffer + * @param src source string + * @param size size of destination buffer + * @return the total length of src and dst + * + * @warning since the return value use the length of src and dst, these + * absolutely _must_ be a properly 0-terminated strings, otherwise this + * will read beyond the end of the buffer and possibly crash. + */ +size_t av_strlcat(char *dst, const char *src, size_t size); + +/** + * Append output to a string, according to a format. Never write out of + * the destination buffer, and always put a terminating 0 within + * the buffer. + * @param dst destination buffer (string to which the output is + * appended) + * @param size total size of the destination buffer + * @param fmt printf-compatible format string, specifying how the + * following parameters are used + * @return the length of the string that would have been generated + * if enough space had been available + */ +size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) av_printf_format(3, 4); + +/** + * Get the count of continuous non zero chars starting from the beginning. + * + * @param len maximum number of characters to check in the string, that + * is the maximum value which is returned by the function + */ +static inline size_t av_strnlen(const char *s, size_t len) +{ + size_t i; + for (i = 0; i < len && s[i]; i++) + ; + return i; +} + +/** + * Print arguments following specified format into a large enough auto + * allocated buffer. It is similar to GNU asprintf(). + * @param fmt printf-compatible format string, specifying how the + * following parameters are used. + * @return the allocated string + * @note You have to free the string yourself with av_free(). + */ +char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2); + +/** + * Convert a number to an av_malloced string. + */ +char *av_d2str(double d); + +/** + * Unescape the given string until a non escaped terminating char, + * and return the token corresponding to the unescaped string. + * + * The normal \ and ' escaping is supported. Leading and trailing + * whitespaces are removed, unless they are escaped with '\' or are + * enclosed between ''. + * + * @param buf the buffer to parse, buf will be updated to point to the + * terminating char + * @param term a 0-terminated list of terminating chars + * @return the malloced unescaped string, which must be av_freed by + * the user, NULL in case of allocation failure + */ +char *av_get_token(const char **buf, const char *term); + +/** + * Split the string into several tokens which can be accessed by + * successive calls to av_strtok(). + * + * A token is defined as a sequence of characters not belonging to the + * set specified in delim. + * + * On the first call to av_strtok(), s should point to the string to + * parse, and the value of saveptr is ignored. In subsequent calls, s + * should be NULL, and saveptr should be unchanged since the previous + * call. + * + * This function is similar to strtok_r() defined in POSIX.1. + * + * @param s the string to parse, may be NULL + * @param delim 0-terminated list of token delimiters, must be non-NULL + * @param saveptr user-provided pointer which points to stored + * information necessary for av_strtok() to continue scanning the same + * string. saveptr is updated to point to the next character after the + * first delimiter found, or to NULL if the string was terminated + * @return the found token, or NULL when no token is found + */ +char *av_strtok(char *s, const char *delim, char **saveptr); + +/** + * Locale-independent conversion of ASCII isdigit. + */ +static inline av_const int av_isdigit(int c) +{ + return c >= '0' && c <= '9'; +} + +/** + * Locale-independent conversion of ASCII isgraph. + */ +static inline av_const int av_isgraph(int c) +{ + return c > 32 && c < 127; +} + +/** + * Locale-independent conversion of ASCII isspace. + */ +static inline av_const int av_isspace(int c) +{ + return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || + c == '\v'; +} + +/** + * Locale-independent conversion of ASCII characters to uppercase. + */ +static inline av_const int av_toupper(int c) +{ + if (c >= 'a' && c <= 'z') + c ^= 0x20; + return c; +} + +/** + * Locale-independent conversion of ASCII characters to lowercase. + */ +static inline av_const int av_tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + c ^= 0x20; + return c; +} + +/** + * Locale-independent conversion of ASCII isxdigit. + */ +static inline av_const int av_isxdigit(int c) +{ + c = av_tolower(c); + return av_isdigit(c) || (c >= 'a' && c <= 'f'); +} + +/** + * Locale-independent case-insensitive compare. + * @note This means only ASCII-range characters are case-insensitive + */ +int av_strcasecmp(const char *a, const char *b); + +/** + * Locale-independent case-insensitive compare. + * @note This means only ASCII-range characters are case-insensitive + */ +int av_strncasecmp(const char *a, const char *b, size_t n); + +/** + * Locale-independent strings replace. + * @note This means only ASCII-range characters are replace + */ +char *av_strireplace(const char *str, const char *from, const char *to); + +/** + * Thread safe basename. + * @param path the path, on DOS both \ and / are considered separators. + * @return pointer to the basename substring. + */ +const char *av_basename(const char *path); + +/** + * Thread safe dirname. + * @param path the path, on DOS both \ and / are considered separators. + * @return the path with the separator replaced by the string terminator or ".". + * @note the function may change the input string. + */ +const char *av_dirname(char *path); + +/** + * Match instances of a name in a comma-separated list of names. + * List entries are checked from the start to the end of the names list, + * the first match ends further processing. If an entry prefixed with '-' + * matches, then 0 is returned. The "ALL" list entry is considered to + * match all names. + * + * @param name Name to look for. + * @param names List of names. + * @return 1 on match, 0 otherwise. + */ +int av_match_name(const char *name, const char *names); + +/** + * Append path component to the existing path. + * Path separator '/' is placed between when needed. + * Resulting string have to be freed with av_free(). + * @param path base path + * @param component component to be appended + * @return new path or NULL on error. + */ +char *av_append_path_component(const char *path, const char *component); + +enum AVEscapeMode { + AV_ESCAPE_MODE_AUTO, ///< Use auto-selected escaping mode. + AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping. + AV_ESCAPE_MODE_QUOTE, ///< Use single-quote escaping. +}; + +/** + * Consider spaces special and escape them even in the middle of the + * string. + * + * This is equivalent to adding the whitespace characters to the special + * characters lists, except it is guaranteed to use the exact same list + * of whitespace characters as the rest of libavutil. + */ +#define AV_ESCAPE_FLAG_WHITESPACE (1 << 0) + +/** + * Escape only specified special characters. + * Without this flag, escape also any characters that may be considered + * special by av_get_token(), such as the single quote. + */ +#define AV_ESCAPE_FLAG_STRICT (1 << 1) + +/** + * Escape string in src, and put the escaped string in an allocated + * string in *dst, which must be freed with av_free(). + * + * @param dst pointer where an allocated string is put + * @param src string to escape, must be non-NULL + * @param special_chars string containing the special characters which + * need to be escaped, can be NULL + * @param mode escape mode to employ, see AV_ESCAPE_MODE_* macros. + * Any unknown value for mode will be considered equivalent to + * AV_ESCAPE_MODE_BACKSLASH, but this behaviour can change without + * notice. + * @param flags flags which control how to escape, see AV_ESCAPE_FLAG_ macros + * @return the length of the allocated string, or a negative error code in case of error + * @see av_bprint_escape() + */ +av_warn_unused_result +int av_escape(char **dst, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags); + +#define AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES 1 ///< accept codepoints over 0x10FFFF +#define AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS 2 ///< accept non-characters - 0xFFFE and 0xFFFF +#define AV_UTF8_FLAG_ACCEPT_SURROGATES 4 ///< accept UTF-16 surrogates codes +#define AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES 8 ///< exclude control codes not accepted by XML + +#define AV_UTF8_FLAG_ACCEPT_ALL \ + AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES|AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS|AV_UTF8_FLAG_ACCEPT_SURROGATES + +/** + * Read and decode a single UTF-8 code point (character) from the + * buffer in *buf, and update *buf to point to the next byte to + * decode. + * + * In case of an invalid byte sequence, the pointer will be updated to + * the next byte after the invalid sequence and the function will + * return an error code. + * + * Depending on the specified flags, the function will also fail in + * case the decoded code point does not belong to a valid range. + * + * @note For speed-relevant code a carefully implemented use of + * GET_UTF8() may be preferred. + * + * @param codep pointer used to return the parsed code in case of success. + * The value in *codep is set even in case the range check fails. + * @param bufp pointer to the address the first byte of the sequence + * to decode, updated by the function to point to the + * byte next after the decoded sequence + * @param buf_end pointer to the end of the buffer, points to the next + * byte past the last in the buffer. This is used to + * avoid buffer overreads (in case of an unfinished + * UTF-8 sequence towards the end of the buffer). + * @param flags a collection of AV_UTF8_FLAG_* flags + * @return >= 0 in case a sequence was successfully read, a negative + * value in case of invalid sequence + */ +av_warn_unused_result +int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, + unsigned int flags); + +/** + * Check if a name is in a list. + * @returns 0 if not found, or the 1 based index where it has been found in the + * list. + */ +int av_match_list(const char *name, const char *list, char separator); + +/** + * See libc sscanf manual for more information. + * Locale-independent sscanf implementation. + */ +int av_sscanf(const char *string, const char *format, ...); + +/** + * @} + */ + +#endif /* AVUTIL_AVSTRING_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avutil.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avutil.h new file mode 100644 index 000000000..4d633156d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/avutil.h @@ -0,0 +1,365 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVUTIL_H +#define AVUTIL_AVUTIL_H + +/** + * @file + * @ingroup lavu + * Convenience header that includes @ref lavu "libavutil"'s core. + */ + +/** + * @mainpage + * + * @section ffmpeg_intro Introduction + * + * This document describes the usage of the different libraries + * provided by FFmpeg. + * + * @li @ref libavc "libavcodec" encoding/decoding library + * @li @ref lavfi "libavfilter" graph-based frame editing library + * @li @ref libavf "libavformat" I/O and muxing/demuxing library + * @li @ref lavd "libavdevice" special devices muxing/demuxing library + * @li @ref lavu "libavutil" common utility library + * @li @ref lswr "libswresample" audio resampling, format conversion and mixing + * @li @ref lpp "libpostproc" post processing library + * @li @ref libsws "libswscale" color conversion and scaling library + * + * @section ffmpeg_versioning Versioning and compatibility + * + * Each of the FFmpeg libraries contains a version.h header, which defines a + * major, minor and micro version number with the + * LIBRARYNAME_VERSION_{MAJOR,MINOR,MICRO} macros. The major version + * number is incremented with backward incompatible changes - e.g. removing + * parts of the public API, reordering public struct members, etc. The minor + * version number is incremented for backward compatible API changes or major + * new features - e.g. adding a new public function or a new decoder. The micro + * version number is incremented for smaller changes that a calling program + * might still want to check for - e.g. changing behavior in a previously + * unspecified situation. + * + * FFmpeg guarantees backward API and ABI compatibility for each library as long + * as its major version number is unchanged. This means that no public symbols + * will be removed or renamed. Types and names of the public struct members and + * values of public macros and enums will remain the same (unless they were + * explicitly declared as not part of the public API). Documented behavior will + * not change. + * + * In other words, any correct program that works with a given FFmpeg snapshot + * should work just as well without any changes with any later snapshot with the + * same major versions. This applies to both rebuilding the program against new + * FFmpeg versions or to replacing the dynamic FFmpeg libraries that a program + * links against. + * + * However, new public symbols may be added and new members may be appended to + * public structs whose size is not part of public ABI (most public structs in + * FFmpeg). New macros and enum values may be added. Behavior in undocumented + * situations may change slightly (and be documented). All those are accompanied + * by an entry in doc/APIchanges and incrementing either the minor or micro + * version number. + */ + +/** + * @defgroup lavu libavutil + * Common code shared across all FFmpeg libraries. + * + * @note + * libavutil is designed to be modular. In most cases, in order to use the + * functions provided by one component of libavutil you must explicitly include + * the specific header containing that feature. If you are only using + * media-related components, you could simply include libavutil/avutil.h, which + * brings in most of the "core" components. + * + * @{ + * + * @defgroup lavu_crypto Crypto and Hashing + * + * @{ + * @} + * + * @defgroup lavu_math Mathematics + * @{ + * + * @} + * + * @defgroup lavu_string String Manipulation + * + * @{ + * + * @} + * + * @defgroup lavu_mem Memory Management + * + * @{ + * + * @} + * + * @defgroup lavu_data Data Structures + * @{ + * + * @} + * + * @defgroup lavu_video Video related + * + * @{ + * + * @} + * + * @defgroup lavu_audio Audio related + * + * @{ + * + * @} + * + * @defgroup lavu_error Error Codes + * + * @{ + * + * @} + * + * @defgroup lavu_log Logging Facility + * + * @{ + * + * @} + * + * @defgroup lavu_misc Other + * + * @{ + * + * @defgroup preproc_misc Preprocessor String Macros + * + * @{ + * + * @} + * + * @defgroup version_utils Library Version Macros + * + * @{ + * + * @} + */ + + +/** + * @addtogroup lavu_ver + * @{ + */ + +/** + * Return the LIBAVUTIL_VERSION_INT constant. + */ +unsigned avutil_version(void); + +/** + * Return an informative version string. This usually is the actual release + * version number or a git commit description. This string has no fixed format + * and can change any time. It should never be parsed by code. + */ +const char *av_version_info(void); + +/** + * Return the libavutil build-time configuration. + */ +const char *avutil_configuration(void); + +/** + * Return the libavutil license. + */ +const char *avutil_license(void); + +/** + * @} + */ + +/** + * @addtogroup lavu_media Media Type + * @brief Media Type + */ + +enum AVMediaType { + AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA + AVMEDIA_TYPE_VIDEO, + AVMEDIA_TYPE_AUDIO, + AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous + AVMEDIA_TYPE_SUBTITLE, + AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse + AVMEDIA_TYPE_NB +}; + +/** + * Return a string describing the media_type enum, NULL if media_type + * is unknown. + */ +const char *av_get_media_type_string(enum AVMediaType media_type); + +/** + * @defgroup lavu_const Constants + * @{ + * + * @defgroup lavu_enc Encoding specific + * + * @note those definition should move to avcodec + * @{ + */ + +#define FF_LAMBDA_SHIFT 7 +#define FF_LAMBDA_SCALE (1< +#include "libavutil/version.h" +#include "libavutil/ffversion.h" +#include "config.h" + +1 VERSIONINFO +FILEVERSION LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO, 0 +PRODUCTVERSION LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO, 0 +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_DLL +{ + BLOCK "StringFileInfo" + { + BLOCK "040904B0" + { + VALUE "CompanyName", "FFmpeg Project" + VALUE "FileDescription", "FFmpeg utility library" + VALUE "FileVersion", AV_STRINGIFY(LIBAVUTIL_VERSION) + VALUE "InternalName", "libavutil" + VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project" + VALUE "OriginalFilename", "avutil" BUILDSUF "-" AV_STRINGIFY(LIBAVUTIL_VERSION_MAJOR) SLIBSUF + VALUE "ProductName", "FFmpeg" + VALUE "ProductVersion", FFMPEG_VERSION + } + } + + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 0x04B0 + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/base64.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/base64.c new file mode 100644 index 000000000..25ae8c411 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/base64.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief Base64 encode/decode + * @author Ryan Martell (with lots of Michael) + */ + +#include "common.h" +#include "base64.h" +#include "intreadwrite.h" +#include "timer.h" + +/* ---------------- private code */ +static const uint8_t map2[256] = +{ + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, + + 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, + 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + + 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +#define BASE64_DEC_STEP(i) do { \ + bits = map2[in[i]]; \ + if (bits & 0x80) \ + goto out ## i; \ + v = i ? (v << 6) + bits : bits; \ +} while(0) + +int av_base64_decode(uint8_t *out, const char *in_str, int out_size) +{ + uint8_t *dst = out; + uint8_t *end = out + out_size; + // no sign extension + const uint8_t *in = in_str; + unsigned bits = 0xff; + unsigned v; + + while (end - dst > 3) { + BASE64_DEC_STEP(0); + BASE64_DEC_STEP(1); + BASE64_DEC_STEP(2); + BASE64_DEC_STEP(3); + // Using AV_WB32 directly confuses compiler + v = av_be2ne32(v << 8); + AV_WN32(dst, v); + dst += 3; + in += 4; + } + if (end - dst) { + BASE64_DEC_STEP(0); + BASE64_DEC_STEP(1); + BASE64_DEC_STEP(2); + BASE64_DEC_STEP(3); + *dst++ = v >> 16; + if (end - dst) + *dst++ = v >> 8; + if (end - dst) + *dst++ = v; + in += 4; + } + while (1) { + BASE64_DEC_STEP(0); + in++; + BASE64_DEC_STEP(0); + in++; + BASE64_DEC_STEP(0); + in++; + BASE64_DEC_STEP(0); + in++; + } + +out3: + *dst++ = v >> 10; + v <<= 2; +out2: + *dst++ = v >> 4; +out1: +out0: + return bits & 1 ? AVERROR_INVALIDDATA : dst - out; +} + +/***************************************************************************** +* b64_encode: Stolen from VLC's http.c. +* Simplified by Michael. +* Fixed edge cases and made it work from data (vs. strings) by Ryan. +*****************************************************************************/ + +char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size) +{ + static const char b64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + char *ret, *dst; + unsigned i_bits = 0; + int i_shift = 0; + int bytes_remaining = in_size; + + if (in_size >= UINT_MAX / 4 || + out_size < AV_BASE64_SIZE(in_size)) + return NULL; + ret = dst = out; + while (bytes_remaining > 3) { + i_bits = AV_RB32(in); + in += 3; bytes_remaining -= 3; + *dst++ = b64[ i_bits>>26 ]; + *dst++ = b64[(i_bits>>20) & 0x3F]; + *dst++ = b64[(i_bits>>14) & 0x3F]; + *dst++ = b64[(i_bits>>8 ) & 0x3F]; + } + i_bits = 0; + while (bytes_remaining) { + i_bits = (i_bits << 8) + *in++; + bytes_remaining--; + i_shift += 8; + } + while (i_shift > 0) { + *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f]; + i_shift -= 6; + } + while ((dst - ret) & 3) + *dst++ = '='; + *dst = '\0'; + + return ret; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/base64.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/base64.h new file mode 100644 index 000000000..2954c12d4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/base64.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BASE64_H +#define AVUTIL_BASE64_H + +#include + +/** + * @defgroup lavu_base64 Base64 + * @ingroup lavu_crypto + * @{ + */ + +/** + * Decode a base64-encoded string. + * + * @param out buffer for decoded data + * @param in null-terminated input string + * @param out_size size in bytes of the out buffer, must be at + * least 3/4 of the length of in, that is AV_BASE64_DECODE_SIZE(strlen(in)) + * @return number of bytes written, or a negative value in case of + * invalid input + */ +int av_base64_decode(uint8_t *out, const char *in, int out_size); + +/** + * Calculate the output size in bytes needed to decode a base64 string + * with length x to a data buffer. + */ +#define AV_BASE64_DECODE_SIZE(x) ((x) * 3LL / 4) + +/** + * Encode data to base64 and null-terminate. + * + * @param out buffer for encoded data + * @param out_size size in bytes of the out buffer (including the + * null terminator), must be at least AV_BASE64_SIZE(in_size) + * @param in input buffer containing the data to encode + * @param in_size size in bytes of the in buffer + * @return out or NULL in case of error + */ +char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size); + +/** + * Calculate the output size needed to base64-encode x bytes to a + * null-terminated string. + */ +#define AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) + + /** + * @} + */ + +#endif /* AVUTIL_BASE64_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/blowfish.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/blowfish.c new file mode 100644 index 000000000..abc0e03d4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/blowfish.c @@ -0,0 +1,424 @@ +/* + * Blowfish algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * loosely based on Paul Kocher's implementation + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avutil.h" +#include "common.h" +#include "intreadwrite.h" +#include "mem.h" +#include "blowfish.h" + +static const uint32_t orig_p[AV_BF_ROUNDS + 2] = { + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, + 0x9216D5D9, 0x8979FB1B +}; + +static const uint32_t orig_s[4][256] = { + { 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, + 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, + 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, + 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, + 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, + 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, + 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, + 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, + 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, + 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, + 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, + 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, + 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, + 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, + 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, + 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, + 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, + 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, + 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, + 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, + 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, + 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, + 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, + 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, + 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, + 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, + 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, + 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, + 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, + 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, + 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, + 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, + 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, + 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, + 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, + 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, + 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, + 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, + 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, + 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, + 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, + 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, + 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, + 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, + 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, + 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, + 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, + 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, + 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, + 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, + 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, + 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, + 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, + 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, + 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, + 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, + 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, + 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, + 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, + 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, + 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, + 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, + 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, + 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A }, + { 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, + 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, + 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, + 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, + 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, + 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, + 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, + 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, + 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, + 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, + 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, + 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, + 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, + 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, + 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, + 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, + 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, + 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, + 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, + 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, + 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, + 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, + 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, + 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, + 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, + 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, + 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, + 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, + 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, + 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, + 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, + 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, + 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, + 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, + 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, + 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, + 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, + 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, + 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, + 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, + 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, + 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, + 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, + 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, + 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, + 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, + 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, + 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, + 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, + 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, + 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, + 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, + 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, + 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, + 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, + 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, + 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, + 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, + 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, + 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, + 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, + 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, + 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, + 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 }, + { 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, + 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, + 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, + 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, + 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, + 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, + 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, + 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, + 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, + 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, + 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, + 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, + 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, + 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, + 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, + 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, + 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, + 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, + 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, + 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, + 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, + 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, + 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, + 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, + 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, + 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, + 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, + 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, + 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, + 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, + 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, + 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, + 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, + 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, + 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, + 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, + 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, + 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, + 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, + 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, + 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, + 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, + 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, + 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, + 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, + 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, + 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, + 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, + 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, + 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, + 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, + 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, + 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, + 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, + 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, + 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, + 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, + 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, + 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, + 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, + 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, + 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, + 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, + 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 }, + { 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, + 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, + 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, + 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, + 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, + 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, + 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, + 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, + 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, + 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, + 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, + 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, + 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, + 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, + 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, + 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, + 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, + 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, + 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, + 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, + 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, + 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, + 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, + 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, + 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, + 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, + 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, + 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, + 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, + 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, + 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, + 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, + 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, + 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, + 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, + 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, + 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, + 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, + 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, + 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, + 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, + 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, + 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, + 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, + 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, + 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, + 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, + 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, + 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, + 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, + 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, + 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, + 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, + 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, + 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, + 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, + 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, + 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, + 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, + 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, + 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, + 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, + 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, + 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 } +}; + +#define F(Xl, Xr, P) \ + Xr ^=((( ctx->s[0][ Xl >> 24 ] \ + + ctx->s[1][(Xl >> 16) & 0xFF])\ + ^ ctx->s[2][(Xl >> 8) & 0xFF])\ + + ctx->s[3][ Xl & 0xFF])\ + ^ P; + +AVBlowfish *av_blowfish_alloc(void) +{ + return av_mallocz(sizeof(struct AVBlowfish)); +} + +av_cold void av_blowfish_init(AVBlowfish *ctx, const uint8_t *key, int key_len) +{ + uint32_t data, data_l, data_r; + int i, j, k; + + memcpy(ctx->s, orig_s, sizeof(orig_s)); + + j = 0; + for (i = 0; i < AV_BF_ROUNDS + 2; ++i) { + data = 0; + for (k = 0; k < 4; k++) { + data = (data << 8) | key[j]; + if (++j >= key_len) + j = 0; + } + ctx->p[i] = orig_p[i] ^ data; + } + + data_l = data_r = 0; + + for (i = 0; i < AV_BF_ROUNDS + 2; i += 2) { + av_blowfish_crypt_ecb(ctx, &data_l, &data_r, 0); + ctx->p[i] = data_l; + ctx->p[i + 1] = data_r; + } + + for (i = 0; i < 4; ++i) { + for (j = 0; j < 256; j += 2) { + av_blowfish_crypt_ecb(ctx, &data_l, &data_r, 0); + ctx->s[i][j] = data_l; + ctx->s[i][j + 1] = data_r; + } + } +} + +void av_blowfish_crypt_ecb(AVBlowfish *ctx, uint32_t *xl, uint32_t *xr, + int decrypt) +{ + uint32_t Xl, Xr; + int i; + + Xl = *xl; + Xr = *xr; + + if (decrypt) { + Xl ^= ctx->p[AV_BF_ROUNDS + 1]; + for (i = AV_BF_ROUNDS; i > 0; i-=2) { + F(Xl, Xr, ctx->p[i ]); + F(Xr, Xl, ctx->p[i-1]); + } + + Xr ^= ctx->p[0]; + } else { + Xl ^= ctx->p[0]; + for (i = 1; i < AV_BF_ROUNDS+1; i+=2){ + F(Xl, Xr, ctx->p[i ]); + F(Xr, Xl, ctx->p[i+1]); + } + + Xr ^= ctx->p[AV_BF_ROUNDS + 1]; + } + + *xl = Xr; + *xr = Xl; +} + +void av_blowfish_crypt(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt) +{ + uint32_t v0, v1; + int i; + + if (decrypt) { + while (count--) { + v0 = AV_RB32(src); + v1 = AV_RB32(src + 4); + + av_blowfish_crypt_ecb(ctx, &v0, &v1, decrypt); + + if (iv) { + v0 ^= AV_RB32(iv); + v1 ^= AV_RB32(iv + 4); + memcpy(iv, src, 8); + } + + AV_WB32(dst, v0); + AV_WB32(dst + 4, v1); + + src += 8; + dst += 8; + } + } else { + while (count--) { + if (iv) { + for (i = 0; i < 8; i++) + dst[i] = src[i] ^ iv[i]; + v0 = AV_RB32(dst); + v1 = AV_RB32(dst + 4); + } else { + v0 = AV_RB32(src); + v1 = AV_RB32(src + 4); + } + + av_blowfish_crypt_ecb(ctx, &v0, &v1, decrypt); + + AV_WB32(dst, v0); + AV_WB32(dst + 4, v1); + + if (iv) + memcpy(iv, dst, 8); + + src += 8; + dst += 8; + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/blowfish.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/blowfish.h new file mode 100644 index 000000000..9e289a40d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/blowfish.h @@ -0,0 +1,82 @@ +/* + * Blowfish algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BLOWFISH_H +#define AVUTIL_BLOWFISH_H + +#include + +/** + * @defgroup lavu_blowfish Blowfish + * @ingroup lavu_crypto + * @{ + */ + +#define AV_BF_ROUNDS 16 + +typedef struct AVBlowfish { + uint32_t p[AV_BF_ROUNDS + 2]; + uint32_t s[4][256]; +} AVBlowfish; + +/** + * Allocate an AVBlowfish context. + */ +AVBlowfish *av_blowfish_alloc(void); + +/** + * Initialize an AVBlowfish context. + * + * @param ctx an AVBlowfish context + * @param key a key + * @param key_len length of the key + */ +void av_blowfish_init(struct AVBlowfish *ctx, const uint8_t *key, int key_len); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param ctx an AVBlowfish context + * @param xl left four bytes halves of input to be encrypted + * @param xr right four bytes halves of input to be encrypted + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_blowfish_crypt_ecb(struct AVBlowfish *ctx, uint32_t *xl, uint32_t *xr, + int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param ctx an AVBlowfish context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_blowfish_crypt(struct AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_BLOWFISH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bprint.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bprint.c new file mode 100644 index 000000000..2f059c5ba --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bprint.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include "avassert.h" +#include "avstring.h" +#include "bprint.h" +#include "common.h" +#include "compat/va_copy.h" +#include "error.h" +#include "mem.h" + +#define av_bprint_room(buf) ((buf)->size - FFMIN((buf)->len, (buf)->size)) +#define av_bprint_is_allocated(buf) ((buf)->str != (buf)->reserved_internal_buffer) + +static int av_bprint_alloc(AVBPrint *buf, unsigned room) +{ + char *old_str, *new_str; + unsigned min_size, new_size; + + if (buf->size == buf->size_max) + return AVERROR(EIO); + if (!av_bprint_is_complete(buf)) + return AVERROR_INVALIDDATA; /* it is already truncated anyway */ + min_size = buf->len + 1 + FFMIN(UINT_MAX - buf->len - 1, room); + new_size = buf->size > buf->size_max / 2 ? buf->size_max : buf->size * 2; + if (new_size < min_size) + new_size = FFMIN(buf->size_max, min_size); + old_str = av_bprint_is_allocated(buf) ? buf->str : NULL; + new_str = av_realloc(old_str, new_size); + if (!new_str) + return AVERROR(ENOMEM); + if (!old_str) + memcpy(new_str, buf->str, buf->len + 1); + buf->str = new_str; + buf->size = new_size; + return 0; +} + +static void av_bprint_grow(AVBPrint *buf, unsigned extra_len) +{ + /* arbitrary margin to avoid small overflows */ + extra_len = FFMIN(extra_len, UINT_MAX - 5 - buf->len); + buf->len += extra_len; + if (buf->size) + buf->str[FFMIN(buf->len, buf->size - 1)] = 0; +} + +void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max) +{ + unsigned size_auto = (char *)buf + sizeof(*buf) - + buf->reserved_internal_buffer; + + if (size_max == 1) + size_max = size_auto; + buf->str = buf->reserved_internal_buffer; + buf->len = 0; + buf->size = FFMIN(size_auto, size_max); + buf->size_max = size_max; + *buf->str = 0; + if (size_init > buf->size) + av_bprint_alloc(buf, size_init - 1); +} + +void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size) +{ + buf->str = buffer; + buf->len = 0; + buf->size = size; + buf->size_max = size; + *buf->str = 0; +} + +void av_bprintf(AVBPrint *buf, const char *fmt, ...) +{ + unsigned room; + char *dst; + va_list vl; + int extra_len; + + while (1) { + room = av_bprint_room(buf); + dst = room ? buf->str + buf->len : NULL; + va_start(vl, fmt); + extra_len = vsnprintf(dst, room, fmt, vl); + va_end(vl); + if (extra_len <= 0) + return; + if (extra_len < room) + break; + if (av_bprint_alloc(buf, extra_len)) + break; + } + av_bprint_grow(buf, extra_len); +} + +void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg) +{ + unsigned room; + char *dst; + int extra_len; + va_list vl; + + while (1) { + room = av_bprint_room(buf); + dst = room ? buf->str + buf->len : NULL; + va_copy(vl, vl_arg); + extra_len = vsnprintf(dst, room, fmt, vl); + va_end(vl); + if (extra_len <= 0) + return; + if (extra_len < room) + break; + if (av_bprint_alloc(buf, extra_len)) + break; + } + av_bprint_grow(buf, extra_len); +} + +void av_bprint_chars(AVBPrint *buf, char c, unsigned n) +{ + unsigned room, real_n; + + while (1) { + room = av_bprint_room(buf); + if (n < room) + break; + if (av_bprint_alloc(buf, n)) + break; + } + if (room) { + real_n = FFMIN(n, room - 1); + memset(buf->str + buf->len, c, real_n); + } + av_bprint_grow(buf, n); +} + +void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size) +{ + unsigned room, real_n; + + while (1) { + room = av_bprint_room(buf); + if (size < room) + break; + if (av_bprint_alloc(buf, size)) + break; + } + if (room) { + real_n = FFMIN(size, room - 1); + memcpy(buf->str + buf->len, data, real_n); + } + av_bprint_grow(buf, size); +} + +void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm) +{ + unsigned room; + size_t l; + + if (!*fmt) + return; + while (1) { + room = av_bprint_room(buf); + if (room && (l = strftime(buf->str + buf->len, room, fmt, tm))) + break; + /* strftime does not tell us how much room it would need: let us + retry with twice as much until the buffer is large enough */ + room = !room ? strlen(fmt) + 1 : + room <= INT_MAX / 2 ? room * 2 : INT_MAX; + if (av_bprint_alloc(buf, room)) { + /* impossible to grow, try to manage something useful anyway */ + room = av_bprint_room(buf); + if (room < 1024) { + /* if strftime fails because the buffer has (almost) reached + its maximum size, let us try in a local buffer; 1k should + be enough to format any real date+time string */ + char buf2[1024]; + if ((l = strftime(buf2, sizeof(buf2), fmt, tm))) { + av_bprintf(buf, "%s", buf2); + return; + } + } + if (room) { + /* if anything else failed and the buffer is not already + truncated, let us add a stock string and force truncation */ + static const char txt[] = "[truncated strftime output]"; + memset(buf->str + buf->len, '!', room); + memcpy(buf->str + buf->len, txt, FFMIN(sizeof(txt) - 1, room)); + av_bprint_grow(buf, room); /* force truncation */ + } + return; + } + } + av_bprint_grow(buf, l); +} + +void av_bprint_get_buffer(AVBPrint *buf, unsigned size, + unsigned char **mem, unsigned *actual_size) +{ + if (size > av_bprint_room(buf)) + av_bprint_alloc(buf, size); + *actual_size = av_bprint_room(buf); + *mem = *actual_size ? buf->str + buf->len : NULL; +} + +void av_bprint_clear(AVBPrint *buf) +{ + if (buf->len) { + *buf->str = 0; + buf->len = 0; + } +} + +int av_bprint_finalize(AVBPrint *buf, char **ret_str) +{ + unsigned real_size = FFMIN(buf->len + 1, buf->size); + char *str; + int ret = 0; + + if (ret_str) { + if (av_bprint_is_allocated(buf)) { + str = av_realloc(buf->str, real_size); + if (!str) + str = buf->str; + buf->str = NULL; + } else { + str = av_malloc(real_size); + if (str) + memcpy(str, buf->str, real_size); + else + ret = AVERROR(ENOMEM); + } + *ret_str = str; + } else { + if (av_bprint_is_allocated(buf)) + av_freep(&buf->str); + } + buf->size = real_size; + return ret; +} + +#define WHITESPACES " \n\t\r" + +void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags) +{ + const char *src0 = src; + + if (mode == AV_ESCAPE_MODE_AUTO) + mode = AV_ESCAPE_MODE_BACKSLASH; /* TODO: implement a heuristic */ + + switch (mode) { + case AV_ESCAPE_MODE_QUOTE: + /* enclose the string between '' */ + av_bprint_chars(dstbuf, '\'', 1); + for (; *src; src++) { + if (*src == '\'') + av_bprintf(dstbuf, "'\\''"); + else + av_bprint_chars(dstbuf, *src, 1); + } + av_bprint_chars(dstbuf, '\'', 1); + break; + + /* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */ + default: + /* \-escape characters */ + for (; *src; src++) { + int is_first_last = src == src0 || !*(src+1); + int is_ws = !!strchr(WHITESPACES, *src); + int is_strictly_special = special_chars && strchr(special_chars, *src); + int is_special = + is_strictly_special || strchr("'\\", *src) || + (is_ws && (flags & AV_ESCAPE_FLAG_WHITESPACE)); + + if (is_strictly_special || + (!(flags & AV_ESCAPE_FLAG_STRICT) && + (is_special || (is_ws && is_first_last)))) + av_bprint_chars(dstbuf, '\\', 1); + av_bprint_chars(dstbuf, *src, 1); + } + break; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bprint.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bprint.h new file mode 100644 index 000000000..c09b1ac1e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bprint.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BPRINT_H +#define AVUTIL_BPRINT_H + +#include + +#include "attributes.h" +#include "avstring.h" + +/** + * Define a structure with extra padding to a fixed size + * This helps ensuring binary compatibility with future versions. + */ + +#define FF_PAD_STRUCTURE(name, size, ...) \ +struct ff_pad_helper_##name { __VA_ARGS__ }; \ +typedef struct name { \ + __VA_ARGS__ \ + char reserved_padding[size - sizeof(struct ff_pad_helper_##name)]; \ +} name; + +/** + * Buffer to print data progressively + * + * The string buffer grows as necessary and is always 0-terminated. + * The content of the string is never accessed, and thus is + * encoding-agnostic and can even hold binary data. + * + * Small buffers are kept in the structure itself, and thus require no + * memory allocation at all (unless the contents of the buffer is needed + * after the structure goes out of scope). This is almost as lightweight as + * declaring a local "char buf[512]". + * + * The length of the string can go beyond the allocated size: the buffer is + * then truncated, but the functions still keep account of the actual total + * length. + * + * In other words, buf->len can be greater than buf->size and records the + * total length of what would have been to the buffer if there had been + * enough memory. + * + * Append operations do not need to be tested for failure: if a memory + * allocation fails, data stop being appended to the buffer, but the length + * is still updated. This situation can be tested with + * av_bprint_is_complete(). + * + * The size_max field determines several possible behaviours: + * + * size_max = -1 (= UINT_MAX) or any large value will let the buffer be + * reallocated as necessary, with an amortized linear cost. + * + * size_max = 0 prevents writing anything to the buffer: only the total + * length is computed. The write operations can then possibly be repeated in + * a buffer with exactly the necessary size + * (using size_init = size_max = len + 1). + * + * size_max = 1 is automatically replaced by the exact size available in the + * structure itself, thus ensuring no dynamic memory allocation. The + * internal buffer is large enough to hold a reasonable paragraph of text, + * such as the current paragraph. + */ + +FF_PAD_STRUCTURE(AVBPrint, 1024, + char *str; /**< string so far */ + unsigned len; /**< length so far */ + unsigned size; /**< allocated memory */ + unsigned size_max; /**< maximum allocated memory */ + char reserved_internal_buffer[1]; +) + +/** + * Convenience macros for special values for av_bprint_init() size_max + * parameter. + */ +#define AV_BPRINT_SIZE_UNLIMITED ((unsigned)-1) +#define AV_BPRINT_SIZE_AUTOMATIC 1 +#define AV_BPRINT_SIZE_COUNT_ONLY 0 + +/** + * Init a print buffer. + * + * @param buf buffer to init + * @param size_init initial size (including the final 0) + * @param size_max maximum size; + * 0 means do not write anything, just count the length; + * 1 is replaced by the maximum value for automatic storage; + * any large value means that the internal buffer will be + * reallocated as needed up to that limit; -1 is converted to + * UINT_MAX, the largest limit possible. + * Check also AV_BPRINT_SIZE_* macros. + */ +void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max); + +/** + * Init a print buffer using a pre-existing buffer. + * + * The buffer will not be reallocated. + * + * @param buf buffer structure to init + * @param buffer byte buffer to use for the string data + * @param size size of buffer + */ +void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size); + +/** + * Append a formatted string to a print buffer. + */ +void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3); + +/** + * Append a formatted string to a print buffer. + */ +void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg); + +/** + * Append char c n times to a print buffer. + */ +void av_bprint_chars(AVBPrint *buf, char c, unsigned n); + +/** + * Append data to a print buffer. + * + * param buf bprint buffer to use + * param data pointer to data + * param size size of data + */ +void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size); + +struct tm; +/** + * Append a formatted date and time to a print buffer. + * + * param buf bprint buffer to use + * param fmt date and time format string, see strftime() + * param tm broken-down time structure to translate + * + * @note due to poor design of the standard strftime function, it may + * produce poor results if the format string expands to a very long text and + * the bprint buffer is near the limit stated by the size_max option. + */ +void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm); + +/** + * Allocate bytes in the buffer for external use. + * + * @param[in] buf buffer structure + * @param[in] size required size + * @param[out] mem pointer to the memory area + * @param[out] actual_size size of the memory area after allocation; + * can be larger or smaller than size + */ +void av_bprint_get_buffer(AVBPrint *buf, unsigned size, + unsigned char **mem, unsigned *actual_size); + +/** + * Reset the string to "" but keep internal allocated data. + */ +void av_bprint_clear(AVBPrint *buf); + +/** + * Test if the print buffer is complete (not truncated). + * + * It may have been truncated due to a memory allocation failure + * or the size_max limit (compare size and size_max if necessary). + */ +static inline int av_bprint_is_complete(const AVBPrint *buf) +{ + return buf->len < buf->size; +} + +/** + * Finalize a print buffer. + * + * The print buffer can no longer be used afterwards, + * but the len and size fields are still valid. + * + * @arg[out] ret_str if not NULL, used to return a permanent copy of the + * buffer contents, or NULL if memory allocation fails; + * if NULL, the buffer is discarded and freed + * @return 0 for success or error code (probably AVERROR(ENOMEM)) + */ +int av_bprint_finalize(AVBPrint *buf, char **ret_str); + +/** + * Escape the content in src and append it to dstbuf. + * + * @param dstbuf already inited destination bprint buffer + * @param src string containing the text to escape + * @param special_chars string containing the special characters which + * need to be escaped, can be NULL + * @param mode escape mode to employ, see AV_ESCAPE_MODE_* macros. + * Any unknown value for mode will be considered equivalent to + * AV_ESCAPE_MODE_BACKSLASH, but this behaviour can change without + * notice. + * @param flags flags which control how to escape, see AV_ESCAPE_FLAG_* macros + */ +void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags); + +#endif /* AVUTIL_BPRINT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bswap.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bswap.h new file mode 100644 index 000000000..91cb79538 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/bswap.h @@ -0,0 +1,109 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * byte swapping routines + */ + +#ifndef AVUTIL_BSWAP_H +#define AVUTIL_BSWAP_H + +#include +#include "libavutil/avconfig.h" +#include "attributes.h" + +#ifdef HAVE_AV_CONFIG_H + +#include "config.h" + +#if ARCH_AARCH64 +# include "aarch64/bswap.h" +#elif ARCH_ARM +# include "arm/bswap.h" +#elif ARCH_AVR32 +# include "avr32/bswap.h" +#elif ARCH_SH4 +# include "sh4/bswap.h" +#elif ARCH_X86 +# include "x86/bswap.h" +#endif + +#endif /* HAVE_AV_CONFIG_H */ + +#define AV_BSWAP16C(x) (((x) << 8 & 0xff00) | ((x) >> 8 & 0x00ff)) +#define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C((x) >> 16)) +#define AV_BSWAP64C(x) (AV_BSWAP32C(x) << 32 | AV_BSWAP32C((x) >> 32)) + +#define AV_BSWAPC(s, x) AV_BSWAP##s##C(x) + +#ifndef av_bswap16 +static av_always_inline av_const uint16_t av_bswap16(uint16_t x) +{ + x= (x>>8) | (x<<8); + return x; +} +#endif + +#ifndef av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + return AV_BSWAP32C(x); +} +#endif + +#ifndef av_bswap64 +static inline uint64_t av_const av_bswap64(uint64_t x) +{ + return (uint64_t)av_bswap32(x) << 32 | av_bswap32(x >> 32); +} +#endif + +// be2ne ... big-endian to native-endian +// le2ne ... little-endian to native-endian + +#if AV_HAVE_BIGENDIAN +#define av_be2ne16(x) (x) +#define av_be2ne32(x) (x) +#define av_be2ne64(x) (x) +#define av_le2ne16(x) av_bswap16(x) +#define av_le2ne32(x) av_bswap32(x) +#define av_le2ne64(x) av_bswap64(x) +#define AV_BE2NEC(s, x) (x) +#define AV_LE2NEC(s, x) AV_BSWAPC(s, x) +#else +#define av_be2ne16(x) av_bswap16(x) +#define av_be2ne32(x) av_bswap32(x) +#define av_be2ne64(x) av_bswap64(x) +#define av_le2ne16(x) (x) +#define av_le2ne32(x) (x) +#define av_le2ne64(x) (x) +#define AV_BE2NEC(s, x) AV_BSWAPC(s, x) +#define AV_LE2NEC(s, x) (x) +#endif + +#define AV_BE2NE16C(x) AV_BE2NEC(16, x) +#define AV_BE2NE32C(x) AV_BE2NEC(32, x) +#define AV_BE2NE64C(x) AV_BE2NEC(64, x) +#define AV_LE2NE16C(x) AV_LE2NEC(16, x) +#define AV_LE2NE32C(x) AV_LE2NEC(32, x) +#define AV_LE2NE64C(x) AV_LE2NEC(64, x) + +#endif /* AVUTIL_BSWAP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer.c new file mode 100644 index 000000000..8d1aa5fa8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer.c @@ -0,0 +1,357 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "buffer_internal.h" +#include "common.h" +#include "mem.h" +#include "thread.h" + +AVBufferRef *av_buffer_create(uint8_t *data, int size, + void (*free)(void *opaque, uint8_t *data), + void *opaque, int flags) +{ + AVBufferRef *ref = NULL; + AVBuffer *buf = NULL; + + buf = av_mallocz(sizeof(*buf)); + if (!buf) + return NULL; + + buf->data = data; + buf->size = size; + buf->free = free ? free : av_buffer_default_free; + buf->opaque = opaque; + + atomic_init(&buf->refcount, 1); + + if (flags & AV_BUFFER_FLAG_READONLY) + buf->flags |= BUFFER_FLAG_READONLY; + + ref = av_mallocz(sizeof(*ref)); + if (!ref) { + av_freep(&buf); + return NULL; + } + + ref->buffer = buf; + ref->data = data; + ref->size = size; + + return ref; +} + +void av_buffer_default_free(void *opaque, uint8_t *data) +{ + av_free(data); +} + +AVBufferRef *av_buffer_alloc(int size) +{ + AVBufferRef *ret = NULL; + uint8_t *data = NULL; + + data = av_malloc(size); + if (!data) + return NULL; + + ret = av_buffer_create(data, size, av_buffer_default_free, NULL, 0); + if (!ret) + av_freep(&data); + + return ret; +} + +AVBufferRef *av_buffer_allocz(int size) +{ + AVBufferRef *ret = av_buffer_alloc(size); + if (!ret) + return NULL; + + memset(ret->data, 0, size); + return ret; +} + +AVBufferRef *av_buffer_ref(AVBufferRef *buf) +{ + AVBufferRef *ret = av_mallocz(sizeof(*ret)); + + if (!ret) + return NULL; + + *ret = *buf; + + atomic_fetch_add_explicit(&buf->buffer->refcount, 1, memory_order_relaxed); + + return ret; +} + +static void buffer_replace(AVBufferRef **dst, AVBufferRef **src) +{ + AVBuffer *b; + + b = (*dst)->buffer; + + if (src) { + **dst = **src; + av_freep(src); + } else + av_freep(dst); + + if (atomic_fetch_add_explicit(&b->refcount, -1, memory_order_acq_rel) == 1) { + b->free(b->opaque, b->data); + av_freep(&b); + } +} + +void av_buffer_unref(AVBufferRef **buf) +{ + if (!buf || !*buf) + return; + + buffer_replace(buf, NULL); +} + +int av_buffer_is_writable(const AVBufferRef *buf) +{ + if (buf->buffer->flags & AV_BUFFER_FLAG_READONLY) + return 0; + + return atomic_load(&buf->buffer->refcount) == 1; +} + +void *av_buffer_get_opaque(const AVBufferRef *buf) +{ + return buf->buffer->opaque; +} + +int av_buffer_get_ref_count(const AVBufferRef *buf) +{ + return atomic_load(&buf->buffer->refcount); +} + +int av_buffer_make_writable(AVBufferRef **pbuf) +{ + AVBufferRef *newbuf, *buf = *pbuf; + + if (av_buffer_is_writable(buf)) + return 0; + + newbuf = av_buffer_alloc(buf->size); + if (!newbuf) + return AVERROR(ENOMEM); + + memcpy(newbuf->data, buf->data, buf->size); + + buffer_replace(pbuf, &newbuf); + + return 0; +} + +int av_buffer_realloc(AVBufferRef **pbuf, int size) +{ + AVBufferRef *buf = *pbuf; + uint8_t *tmp; + + if (!buf) { + /* allocate a new buffer with av_realloc(), so it will be reallocatable + * later */ + uint8_t *data = av_realloc(NULL, size); + if (!data) + return AVERROR(ENOMEM); + + buf = av_buffer_create(data, size, av_buffer_default_free, NULL, 0); + if (!buf) { + av_freep(&data); + return AVERROR(ENOMEM); + } + + buf->buffer->flags |= BUFFER_FLAG_REALLOCATABLE; + *pbuf = buf; + + return 0; + } else if (buf->size == size) + return 0; + + if (!(buf->buffer->flags & BUFFER_FLAG_REALLOCATABLE) || + !av_buffer_is_writable(buf) || buf->data != buf->buffer->data) { + /* cannot realloc, allocate a new reallocable buffer and copy data */ + AVBufferRef *new = NULL; + + av_buffer_realloc(&new, size); + if (!new) + return AVERROR(ENOMEM); + + memcpy(new->data, buf->data, FFMIN(size, buf->size)); + + buffer_replace(pbuf, &new); + return 0; + } + + tmp = av_realloc(buf->buffer->data, size); + if (!tmp) + return AVERROR(ENOMEM); + + buf->buffer->data = buf->data = tmp; + buf->buffer->size = buf->size = size; + return 0; +} + +AVBufferPool *av_buffer_pool_init2(int size, void *opaque, + AVBufferRef* (*alloc)(void *opaque, int size), + void (*pool_free)(void *opaque)) +{ + AVBufferPool *pool = av_mallocz(sizeof(*pool)); + if (!pool) + return NULL; + + ff_mutex_init(&pool->mutex, NULL); + + pool->size = size; + pool->opaque = opaque; + pool->alloc2 = alloc; + pool->pool_free = pool_free; + + atomic_init(&pool->refcount, 1); + + return pool; +} + +AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)) +{ + AVBufferPool *pool = av_mallocz(sizeof(*pool)); + if (!pool) + return NULL; + + ff_mutex_init(&pool->mutex, NULL); + + pool->size = size; + pool->alloc = alloc ? alloc : av_buffer_alloc; + + atomic_init(&pool->refcount, 1); + + return pool; +} + +/* + * This function gets called when the pool has been uninited and + * all the buffers returned to it. + */ +static void buffer_pool_free(AVBufferPool *pool) +{ + while (pool->pool) { + BufferPoolEntry *buf = pool->pool; + pool->pool = buf->next; + + buf->free(buf->opaque, buf->data); + av_freep(&buf); + } + ff_mutex_destroy(&pool->mutex); + + if (pool->pool_free) + pool->pool_free(pool->opaque); + + av_freep(&pool); +} + +void av_buffer_pool_uninit(AVBufferPool **ppool) +{ + AVBufferPool *pool; + + if (!ppool || !*ppool) + return; + pool = *ppool; + *ppool = NULL; + + if (atomic_fetch_add_explicit(&pool->refcount, -1, memory_order_acq_rel) == 1) + buffer_pool_free(pool); +} + +static void pool_release_buffer(void *opaque, uint8_t *data) +{ + BufferPoolEntry *buf = opaque; + AVBufferPool *pool = buf->pool; + + if(CONFIG_MEMORY_POISONING) + memset(buf->data, FF_MEMORY_POISON, pool->size); + + ff_mutex_lock(&pool->mutex); + buf->next = pool->pool; + pool->pool = buf; + ff_mutex_unlock(&pool->mutex); + + if (atomic_fetch_add_explicit(&pool->refcount, -1, memory_order_acq_rel) == 1) + buffer_pool_free(pool); +} + +/* allocate a new buffer and override its free() callback so that + * it is returned to the pool on free */ +static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool) +{ + BufferPoolEntry *buf; + AVBufferRef *ret; + + ret = pool->alloc2 ? pool->alloc2(pool->opaque, pool->size) : + pool->alloc(pool->size); + if (!ret) + return NULL; + + buf = av_mallocz(sizeof(*buf)); + if (!buf) { + av_buffer_unref(&ret); + return NULL; + } + + buf->data = ret->buffer->data; + buf->opaque = ret->buffer->opaque; + buf->free = ret->buffer->free; + buf->pool = pool; + + ret->buffer->opaque = buf; + ret->buffer->free = pool_release_buffer; + + return ret; +} + +AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) +{ + AVBufferRef *ret; + BufferPoolEntry *buf; + + ff_mutex_lock(&pool->mutex); + buf = pool->pool; + if (buf) { + ret = av_buffer_create(buf->data, pool->size, pool_release_buffer, + buf, 0); + if (ret) { + pool->pool = buf->next; + buf->next = NULL; + } + } else { + ret = pool_alloc_buffer(pool); + } + ff_mutex_unlock(&pool->mutex); + + if (ret) + atomic_fetch_add_explicit(&pool->refcount, 1, memory_order_relaxed); + + return ret; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer.h new file mode 100644 index 000000000..73b6bd0b1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer.h @@ -0,0 +1,291 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_buffer + * refcounted data buffer API + */ + +#ifndef AVUTIL_BUFFER_H +#define AVUTIL_BUFFER_H + +#include + +/** + * @defgroup lavu_buffer AVBuffer + * @ingroup lavu_data + * + * @{ + * AVBuffer is an API for reference-counted data buffers. + * + * There are two core objects in this API -- AVBuffer and AVBufferRef. AVBuffer + * represents the data buffer itself; it is opaque and not meant to be accessed + * by the caller directly, but only through AVBufferRef. However, the caller may + * e.g. compare two AVBuffer pointers to check whether two different references + * are describing the same data buffer. AVBufferRef represents a single + * reference to an AVBuffer and it is the object that may be manipulated by the + * caller directly. + * + * There are two functions provided for creating a new AVBuffer with a single + * reference -- av_buffer_alloc() to just allocate a new buffer, and + * av_buffer_create() to wrap an existing array in an AVBuffer. From an existing + * reference, additional references may be created with av_buffer_ref(). + * Use av_buffer_unref() to free a reference (this will automatically free the + * data once all the references are freed). + * + * The convention throughout this API and the rest of FFmpeg is such that the + * buffer is considered writable if there exists only one reference to it (and + * it has not been marked as read-only). The av_buffer_is_writable() function is + * provided to check whether this is true and av_buffer_make_writable() will + * automatically create a new writable buffer when necessary. + * Of course nothing prevents the calling code from violating this convention, + * however that is safe only when all the existing references are under its + * control. + * + * @note Referencing and unreferencing the buffers is thread-safe and thus + * may be done from multiple threads simultaneously without any need for + * additional locking. + * + * @note Two different references to the same buffer can point to different + * parts of the buffer (i.e. their AVBufferRef.data will not be equal). + */ + +/** + * A reference counted buffer type. It is opaque and is meant to be used through + * references (AVBufferRef). + */ +typedef struct AVBuffer AVBuffer; + +/** + * A reference to a data buffer. + * + * The size of this struct is not a part of the public ABI and it is not meant + * to be allocated directly. + */ +typedef struct AVBufferRef { + AVBuffer *buffer; + + /** + * The data buffer. It is considered writable if and only if + * this is the only reference to the buffer, in which case + * av_buffer_is_writable() returns 1. + */ + uint8_t *data; + /** + * Size of data in bytes. + */ + int size; +} AVBufferRef; + +/** + * Allocate an AVBuffer of the given size using av_malloc(). + * + * @return an AVBufferRef of given size or NULL when out of memory + */ +AVBufferRef *av_buffer_alloc(int size); + +/** + * Same as av_buffer_alloc(), except the returned buffer will be initialized + * to zero. + */ +AVBufferRef *av_buffer_allocz(int size); + +/** + * Always treat the buffer as read-only, even when it has only one + * reference. + */ +#define AV_BUFFER_FLAG_READONLY (1 << 0) + +/** + * Create an AVBuffer from an existing array. + * + * If this function is successful, data is owned by the AVBuffer. The caller may + * only access data through the returned AVBufferRef and references derived from + * it. + * If this function fails, data is left untouched. + * @param data data array + * @param size size of data in bytes + * @param free a callback for freeing this buffer's data + * @param opaque parameter to be got for processing or passed to free + * @param flags a combination of AV_BUFFER_FLAG_* + * + * @return an AVBufferRef referring to data on success, NULL on failure. + */ +AVBufferRef *av_buffer_create(uint8_t *data, int size, + void (*free)(void *opaque, uint8_t *data), + void *opaque, int flags); + +/** + * Default free callback, which calls av_free() on the buffer data. + * This function is meant to be passed to av_buffer_create(), not called + * directly. + */ +void av_buffer_default_free(void *opaque, uint8_t *data); + +/** + * Create a new reference to an AVBuffer. + * + * @return a new AVBufferRef referring to the same AVBuffer as buf or NULL on + * failure. + */ +AVBufferRef *av_buffer_ref(AVBufferRef *buf); + +/** + * Free a given reference and automatically free the buffer if there are no more + * references to it. + * + * @param buf the reference to be freed. The pointer is set to NULL on return. + */ +void av_buffer_unref(AVBufferRef **buf); + +/** + * @return 1 if the caller may write to the data referred to by buf (which is + * true if and only if buf is the only reference to the underlying AVBuffer). + * Return 0 otherwise. + * A positive answer is valid until av_buffer_ref() is called on buf. + */ +int av_buffer_is_writable(const AVBufferRef *buf); + +/** + * @return the opaque parameter set by av_buffer_create. + */ +void *av_buffer_get_opaque(const AVBufferRef *buf); + +int av_buffer_get_ref_count(const AVBufferRef *buf); + +/** + * Create a writable reference from a given buffer reference, avoiding data copy + * if possible. + * + * @param buf buffer reference to make writable. On success, buf is either left + * untouched, or it is unreferenced and a new writable AVBufferRef is + * written in its place. On failure, buf is left untouched. + * @return 0 on success, a negative AVERROR on failure. + */ +int av_buffer_make_writable(AVBufferRef **buf); + +/** + * Reallocate a given buffer. + * + * @param buf a buffer reference to reallocate. On success, buf will be + * unreferenced and a new reference with the required size will be + * written in its place. On failure buf will be left untouched. *buf + * may be NULL, then a new buffer is allocated. + * @param size required new buffer size. + * @return 0 on success, a negative AVERROR on failure. + * + * @note the buffer is actually reallocated with av_realloc() only if it was + * initially allocated through av_buffer_realloc(NULL) and there is only one + * reference to it (i.e. the one passed to this function). In all other cases + * a new buffer is allocated and the data is copied. + */ +int av_buffer_realloc(AVBufferRef **buf, int size); + +/** + * @} + */ + +/** + * @defgroup lavu_bufferpool AVBufferPool + * @ingroup lavu_data + * + * @{ + * AVBufferPool is an API for a lock-free thread-safe pool of AVBuffers. + * + * Frequently allocating and freeing large buffers may be slow. AVBufferPool is + * meant to solve this in cases when the caller needs a set of buffers of the + * same size (the most obvious use case being buffers for raw video or audio + * frames). + * + * At the beginning, the user must call av_buffer_pool_init() to create the + * buffer pool. Then whenever a buffer is needed, call av_buffer_pool_get() to + * get a reference to a new buffer, similar to av_buffer_alloc(). This new + * reference works in all aspects the same way as the one created by + * av_buffer_alloc(). However, when the last reference to this buffer is + * unreferenced, it is returned to the pool instead of being freed and will be + * reused for subsequent av_buffer_pool_get() calls. + * + * When the caller is done with the pool and no longer needs to allocate any new + * buffers, av_buffer_pool_uninit() must be called to mark the pool as freeable. + * Once all the buffers are released, it will automatically be freed. + * + * Allocating and releasing buffers with this API is thread-safe as long as + * either the default alloc callback is used, or the user-supplied one is + * thread-safe. + */ + +/** + * The buffer pool. This structure is opaque and not meant to be accessed + * directly. It is allocated with av_buffer_pool_init() and freed with + * av_buffer_pool_uninit(). + */ +typedef struct AVBufferPool AVBufferPool; + +/** + * Allocate and initialize a buffer pool. + * + * @param size size of each buffer in this pool + * @param alloc a function that will be used to allocate new buffers when the + * pool is empty. May be NULL, then the default allocator will be used + * (av_buffer_alloc()). + * @return newly created buffer pool on success, NULL on error. + */ +AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)); + +/** + * Allocate and initialize a buffer pool with a more complex allocator. + * + * @param size size of each buffer in this pool + * @param opaque arbitrary user data used by the allocator + * @param alloc a function that will be used to allocate new buffers when the + * pool is empty. + * @param pool_free a function that will be called immediately before the pool + * is freed. I.e. after av_buffer_pool_uninit() is called + * by the caller and all the frames are returned to the pool + * and freed. It is intended to uninitialize the user opaque + * data. + * @return newly created buffer pool on success, NULL on error. + */ +AVBufferPool *av_buffer_pool_init2(int size, void *opaque, + AVBufferRef* (*alloc)(void *opaque, int size), + void (*pool_free)(void *opaque)); + +/** + * Mark the pool as being available for freeing. It will actually be freed only + * once all the allocated buffers associated with the pool are released. Thus it + * is safe to call this function while some of the allocated buffers are still + * in use. + * + * @param pool pointer to the pool to be freed. It will be set to NULL. + */ +void av_buffer_pool_uninit(AVBufferPool **pool); + +/** + * Allocate a new AVBuffer, reusing an old buffer from the pool when available. + * This function may be called simultaneously from multiple threads. + * + * @return a reference to the new buffer on success, NULL on error. + */ +AVBufferRef *av_buffer_pool_get(AVBufferPool *pool); + +/** + * @} + */ + +#endif /* AVUTIL_BUFFER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer_internal.h new file mode 100644 index 000000000..54b67047e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/buffer_internal.h @@ -0,0 +1,98 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BUFFER_INTERNAL_H +#define AVUTIL_BUFFER_INTERNAL_H + +#include +#include + +#include "buffer.h" +#include "thread.h" + +/** + * The buffer is always treated as read-only. + */ +#define BUFFER_FLAG_READONLY (1 << 0) +/** + * The buffer was av_realloc()ed, so it is reallocatable. + */ +#define BUFFER_FLAG_REALLOCATABLE (1 << 1) + +struct AVBuffer { + uint8_t *data; /**< data described by this buffer */ + int size; /**< size of data in bytes */ + + /** + * number of existing AVBufferRef instances referring to this buffer + */ + atomic_uint refcount; + + /** + * a callback for freeing the data + */ + void (*free)(void *opaque, uint8_t *data); + + /** + * an opaque pointer, to be used by the freeing callback + */ + void *opaque; + + /** + * A combination of BUFFER_FLAG_* + */ + int flags; +}; + +typedef struct BufferPoolEntry { + uint8_t *data; + + /* + * Backups of the original opaque/free of the AVBuffer corresponding to + * data. They will be used to free the buffer when the pool is freed. + */ + void *opaque; + void (*free)(void *opaque, uint8_t *data); + + AVBufferPool *pool; + struct BufferPoolEntry *next; +} BufferPoolEntry; + +struct AVBufferPool { + AVMutex mutex; + BufferPoolEntry *pool; + + /* + * This is used to track when the pool is to be freed. + * The pointer to the pool itself held by the caller is considered to + * be one reference. Each buffer requested by the caller increases refcount + * by one, returning the buffer to the pool decreases it by one. + * refcount reaches zero when the buffer has been uninited AND all the + * buffers have been released, then it's safe to free the pool and all + * the buffers in it. + */ + atomic_uint refcount; + + int size; + void *opaque; + AVBufferRef* (*alloc)(int size); + AVBufferRef* (*alloc2)(void *opaque, int size); + void (*pool_free)(void *opaque); +}; + +#endif /* AVUTIL_BUFFER_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/camellia.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/camellia.c new file mode 100644 index 000000000..f33ee9bab --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/camellia.c @@ -0,0 +1,412 @@ +/* + * An implementation of the CAMELLIA algorithm as mentioned in RFC3713 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "camellia.h" +#include "common.h" +#include "intreadwrite.h" +#include "attributes.h" + +#define LR32(x,c) ((x) << (c) | (x) >> (32 - (c))) +#define RR32(x,c) ((x) >> (c) | (x) << (32 - (c))) + +#define MASK8 0xff +#define MASK32 0xffffffff +#define MASK64 0xffffffffffffffff + +#define Sigma1 0xA09E667F3BCC908B +#define Sigma2 0xB67AE8584CAA73B2 +#define Sigma3 0xC6EF372FE94F82BE +#define Sigma4 0x54FF53A5F1D36F1C +#define Sigma5 0x10E527FADE682D1D +#define Sigma6 0xB05688C2B3E6C1FD + +static uint64_t SP[8][256]; + +typedef struct AVCAMELLIA { + uint64_t Kw[4]; + uint64_t Ke[6]; + uint64_t K[24]; + int key_bits; +} AVCAMELLIA; + +static const uint8_t SBOX1[256] = { +112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, + 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, +134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, +166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, +139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, +223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, + 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, +254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, +170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, + 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, +135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, + 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, +233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, +120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, +114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, + 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 +}; + +static const uint8_t SBOX2[256] = { +224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, + 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, + 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, + 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, + 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, +191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, + 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, +253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, + 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, + 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, + 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, +164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, +211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, +240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, +228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, +128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 +}; + +static const uint8_t SBOX3[256] = { + 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, +145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, + 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, + 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, +197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, +239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, + 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, +127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, + 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, + 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, +195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, + 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, +244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, + 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, + 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, + 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 +}; + +static const uint8_t SBOX4[256] = { +112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, +134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, +139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, + 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, +170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, +135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, +233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, +114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, +130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, +184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, + 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, + 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, +208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, + 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, +121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, + 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 +}; + +const int av_camellia_size = sizeof(AVCAMELLIA); + +static void LR128(uint64_t d[2], const uint64_t K[2], int x) +{ + int i = 0; + if (64 <= x && x < 128) { + i = 1; + x -= 64; + } + if (x <= 0 || x >= 128) { + d[0] = K[i]; + d[1] = K[!i]; + return; + } + d[0] = (K[i] << x | K[!i] >> (64 - x)); + d[1] = (K[!i] << x | K[i] >> (64 - x)); +} + +static uint64_t F(uint64_t F_IN, uint64_t KE) +{ + KE ^= F_IN; + F_IN=SP[0][KE >> 56]^SP[1][(KE >> 48) & MASK8]^SP[2][(KE >> 40) & MASK8]^SP[3][(KE >> 32) & MASK8]^SP[4][(KE >> 24) & MASK8]^SP[5][(KE >> 16) & MASK8]^SP[6][(KE >> 8) & MASK8]^SP[7][KE & MASK8]; + return F_IN; +} + +static uint64_t FL(uint64_t FL_IN, uint64_t KE) +{ + uint32_t x1, x2, k1, k2; + x1 = FL_IN >> 32; + x2 = FL_IN & MASK32; + k1 = KE >> 32; + k2 = KE & MASK32; + x2 = x2 ^ LR32((x1 & k1), 1); + x1 = x1 ^ (x2 | k2); + return ((uint64_t)x1 << 32) | (uint64_t)x2; +} + +static uint64_t FLINV(uint64_t FLINV_IN, uint64_t KE) +{ + uint32_t x1, x2, k1, k2; + x1 = FLINV_IN >> 32; + x2 = FLINV_IN & MASK32; + k1 = KE >> 32; + k2 = KE & MASK32; + x1 = x1 ^ (x2 | k2); + x2 = x2 ^ LR32((x1 & k1), 1); + return ((uint64_t)x1 << 32) | (uint64_t)x2; +} + +static const uint8_t shifts[2][12] = { + {0, 15, 15, 45, 45, 60, 94, 94, 111}, + {0, 15, 15, 30, 45, 45, 60, 60, 77, 94, 94, 111} +}; + +static const uint8_t vars[2][12] = { + {2, 0, 2, 0, 2, 2, 0, 2, 0}, + {3, 1, 2, 3, 0, 2, 1, 3, 0, 1, 2, 0} +}; + +static void generate_round_keys(AVCAMELLIA *cs, uint64_t Kl[2], uint64_t Kr[2], uint64_t Ka[2], uint64_t Kb[2]) +{ + int i; + uint64_t *Kd[4], d[2]; + Kd[0] = Kl; + Kd[1] = Kr; + Kd[2] = Ka; + Kd[3] = Kb; + cs->Kw[0] = Kl[0]; + cs->Kw[1] = Kl[1]; + if (cs->key_bits == 128) { + for (i = 0; i < 9; i++) { + LR128(d, Kd[vars[0][i]], shifts[0][i]); + cs->K[2*i] = d[0]; + cs->K[2*i+1] = d[1]; + } + LR128(d, Kd[0], 60); + cs->K[9] = d[1]; + LR128(d, Kd[2], 30); + cs->Ke[0] = d[0]; + cs->Ke[1] = d[1]; + LR128(d, Kd[0], 77); + cs->Ke[2] = d[0]; + cs->Ke[3] = d[1]; + LR128(d, Kd[2], 111); + cs->Kw[2] = d[0]; + cs->Kw[3] = d[1]; + } else { + for (i = 0; i < 12; i++) { + LR128(d, Kd[vars[1][i]], shifts[1][i]); + cs->K[2*i] = d[0]; + cs->K[2*i+1] = d[1]; + } + LR128(d, Kd[1], 30); + cs->Ke[0] = d[0]; + cs->Ke[1] = d[1]; + LR128(d, Kd[0], 60); + cs->Ke[2] = d[0]; + cs->Ke[3] = d[1]; + LR128(d, Kd[2], 77); + cs->Ke[4] = d[0]; + cs->Ke[5] = d[1]; + LR128(d, Kd[3], 111); + cs->Kw[2] = d[0]; + cs->Kw[3] = d[1]; + } +} + +static void camellia_encrypt(AVCAMELLIA *cs, uint8_t *dst, const uint8_t *src) +{ + uint64_t D1, D2; + D1 = AV_RB64(src); + D2 = AV_RB64(src + 8); + D1 ^= cs->Kw[0]; + D2 ^= cs->Kw[1]; + D2 ^= F(D1, cs->K[0]); + D1 ^= F(D2, cs->K[1]); + D2 ^= F(D1, cs->K[2]); + D1 ^= F(D2, cs->K[3]); + D2 ^= F(D1, cs->K[4]); + D1 ^= F(D2, cs->K[5]); + D1 = FL(D1, cs->Ke[0]); + D2 = FLINV(D2, cs->Ke[1]); + D2 ^= F(D1, cs->K[6]); + D1 ^= F(D2, cs->K[7]); + D2 ^= F(D1, cs->K[8]); + D1 ^= F(D2, cs->K[9]); + D2 ^= F(D1, cs->K[10]); + D1 ^= F(D2, cs->K[11]); + D1 = FL(D1, cs->Ke[2]); + D2 = FLINV(D2, cs->Ke[3]); + D2 ^= F(D1, cs->K[12]); + D1 ^= F(D2, cs->K[13]); + D2 ^= F(D1, cs->K[14]); + D1 ^= F(D2, cs->K[15]); + D2 ^= F(D1, cs->K[16]); + D1 ^= F(D2, cs->K[17]); + if (cs->key_bits != 128) { + D1 = FL(D1, cs->Ke[4]); + D2 = FLINV(D2, cs->Ke[5]); + D2 ^= F(D1, cs->K[18]); + D1 ^= F(D2, cs->K[19]); + D2 ^= F(D1, cs->K[20]); + D1 ^= F(D2, cs->K[21]); + D2 ^= F(D1, cs->K[22]); + D1 ^= F(D2, cs->K[23]); + } + D2 ^= cs->Kw[2]; + D1 ^= cs->Kw[3]; + AV_WB64(dst, D2); + AV_WB64(dst + 8, D1); +} + +static void camellia_decrypt(AVCAMELLIA *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv) +{ + uint64_t D1, D2; + D1 = AV_RB64(src); + D2 = AV_RB64(src + 8); + D1 ^= cs->Kw[2]; + D2 ^= cs->Kw[3]; + if (cs->key_bits != 128) { + D2 ^= F(D1, cs->K[23]); + D1 ^= F(D2, cs->K[22]); + D2 ^= F(D1, cs->K[21]); + D1 ^= F(D2, cs->K[20]); + D2 ^= F(D1, cs->K[19]); + D1 ^= F(D2, cs->K[18]); + D1 = FL(D1, cs->Ke[5]); + D2 = FLINV(D2, cs->Ke[4]); + } + D2 ^= F(D1, cs->K[17]); + D1 ^= F(D2, cs->K[16]); + D2 ^= F(D1, cs->K[15]); + D1 ^= F(D2, cs->K[14]); + D2 ^= F(D1, cs->K[13]); + D1 ^= F(D2, cs->K[12]); + D1 = FL(D1, cs->Ke[3]); + D2 = FLINV(D2, cs->Ke[2]); + D2 ^= F(D1, cs->K[11]); + D1 ^= F(D2, cs->K[10]); + D2 ^= F(D1, cs->K[9]); + D1 ^= F(D2, cs->K[8]); + D2 ^= F(D1, cs->K[7]); + D1 ^= F(D2, cs->K[6]); + D1 = FL(D1, cs->Ke[1]); + D2 = FLINV(D2, cs->Ke[0]); + D2 ^= F(D1, cs->K[5]); + D1 ^= F(D2, cs->K[4]); + D2 ^= F(D1, cs->K[3]); + D1 ^= F(D2, cs->K[2]); + D2 ^= F(D1, cs->K[1]); + D1 ^= F(D2, cs->K[0]); + D2 ^= cs->Kw[0]; + D1 ^= cs->Kw[1]; + if (iv) { + D2 ^= AV_RB64(iv); + D1 ^= AV_RB64(iv + 8); + memcpy(iv, src, 16); + } + AV_WB64(dst, D2); + AV_WB64(dst + 8, D1); +} + +static void computeSP(void) +{ + uint64_t z; + int i; + for (i = 0; i < 256; i++) { + z = SBOX1[i]; + SP[0][i] = (z << 56) ^ (z << 48) ^ (z << 40) ^ (z << 24) ^ z; + SP[7][i] = (z << 56) ^ (z << 48) ^ (z << 40) ^ (z << 24) ^ (z << 16) ^ (z << 8); + z = SBOX2[i]; + SP[1][i] = (z << 48) ^ (z << 40) ^ (z << 32) ^ (z << 24) ^ (z << 16); + SP[4][i] = (z << 48) ^ (z << 40) ^ (z << 32) ^ (z << 16) ^ (z << 8) ^ z; + z = SBOX3[i]; + SP[2][i] = (z << 56) ^ (z << 40) ^ (z << 32) ^ (z << 16) ^ (z << 8); + SP[5][i] = (z << 56) ^ (z << 40) ^ (z << 32) ^ (z << 24) ^ (z << 8) ^ z; + z = SBOX4[i]; + SP[3][i] = (z << 56) ^ (z << 48) ^ (z << 32) ^ (z << 8) ^ z; + SP[6][i] = (z << 56) ^ (z << 48) ^ (z << 32) ^ (z << 24) ^ (z << 16) ^ z; + } +} + +struct AVCAMELLIA *av_camellia_alloc(void) +{ + return av_mallocz(sizeof(struct AVCAMELLIA)); +} + +av_cold int av_camellia_init(AVCAMELLIA *cs, const uint8_t *key, int key_bits) +{ + uint64_t Kl[2], Kr[2], Ka[2], Kb[2]; + uint64_t D1, D2; + if (key_bits != 128 && key_bits != 192 && key_bits != 256) + return AVERROR(EINVAL); + memset(Kb, 0, sizeof(Kb)); + memset(Kr, 0, sizeof(Kr)); + cs->key_bits = key_bits; + Kl[0] = AV_RB64(key); + Kl[1] = AV_RB64(key + 8); + if (key_bits == 192) { + Kr[0] = AV_RB64(key + 16); + Kr[1] = ~Kr[0]; + } else if (key_bits == 256) { + Kr[0] = AV_RB64(key + 16); + Kr[1] = AV_RB64(key + 24); + } + computeSP(); + D1 = Kl[0] ^ Kr[0]; + D2 = Kl[1] ^ Kr[1]; + D2 ^= F(D1, Sigma1); + D1 ^= F(D2, Sigma2); + D1 ^= Kl[0]; + D2 ^= Kl[1]; + D2 ^= F(D1, Sigma3); + D1 ^= F(D2, Sigma4); + Ka[0] = D1; + Ka[1] = D2; + if (key_bits != 128) { + D1 = Ka[0] ^ Kr[0]; + D2 = Ka[1] ^ Kr[1]; + D2 ^= F(D1, Sigma5); + D1 ^= F(D2, Sigma6); + Kb[0] = D1; + Kb[1] = D2; + } + generate_round_keys(cs, Kl, Kr, Ka, Kb); + return 0; +} + +void av_camellia_crypt(AVCAMELLIA *cs, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) +{ + int i; + while (count--) { + if (decrypt) { + camellia_decrypt(cs, dst, src, iv); + } else { + if (iv) { + for (i = 0; i < 16; i++) + dst[i] = src[i] ^ iv[i]; + camellia_encrypt(cs, dst, dst); + memcpy(iv, dst, 16); + } else { + camellia_encrypt(cs, dst, src); + } + } + src = src + 16; + dst = dst + 16; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/camellia.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/camellia.h new file mode 100644 index 000000000..e674c9b9a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/camellia.h @@ -0,0 +1,70 @@ +/* + * An implementation of the CAMELLIA algorithm as mentioned in RFC3713 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CAMELLIA_H +#define AVUTIL_CAMELLIA_H + +#include + + +/** + * @file + * @brief Public header for libavutil CAMELLIA algorithm + * @defgroup lavu_camellia CAMELLIA + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_camellia_size; + +struct AVCAMELLIA; + +/** + * Allocate an AVCAMELLIA context + * To free the struct: av_free(ptr) + */ +struct AVCAMELLIA *av_camellia_alloc(void); + +/** + * Initialize an AVCAMELLIA context. + * + * @param ctx an AVCAMELLIA context + * @param key a key of 16, 24, 32 bytes used for encryption/decryption + * @param key_bits number of keybits: possible are 128, 192, 256 + */ +int av_camellia_init(struct AVCAMELLIA *ctx, const uint8_t *key, int key_bits); + +/** + * Encrypt or decrypt a buffer using a previously initialized context + * + * @param ctx an AVCAMELLIA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 16 byte blocks + * @paran iv initialization vector for CBC mode, NULL for ECB mode + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_camellia_crypt(struct AVCAMELLIA *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t* iv, int decrypt); + +/** + * @} + */ +#endif /* AVUTIL_CAMELLIA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cast5.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cast5.c new file mode 100644 index 000000000..445eb55c1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cast5.c @@ -0,0 +1,507 @@ +/* + * An implementation of the CAST128 algorithm as mentioned in RFC2144 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "cast5.h" +#include "common.h" +#include "intreadwrite.h" +#include "attributes.h" + +#define IA(x) ((x) >> 24) +#define IB(x) (((x) >> 16) & 0xff) +#define IC(x) (((x) >> 8) & 0xff) +#define ID(x) ((x) & 0xff) + +#define LR(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) + +#define F3(l, r, i) \ + do { \ + I = LR(cs->Km[i] - r, cs->Kr[i]); \ + f = ((S1[IA(I)] + S2[IB(I)]) ^ S3[IC(I)]) - S4[ID(I)]; \ + l = f ^ l; \ + } while (0) + +#define F2(l, r, i) \ + do { \ + I = LR(cs->Km[i] ^ r, cs->Kr[i]); \ + f = ((S1[IA(I)] - S2[IB(I)]) + S3[IC(I)]) ^ S4[ID(I)]; \ + l = f ^ l; \ + } while (0) + +#define F1(l, r, i) \ + do { \ + I = LR(cs->Km[i] + r, cs->Kr[i]); \ + f = ((S1[IA(I)] ^ S2[IB(I)]) - S3[IC(I)]) + S4[ID(I)]; \ + l = f ^ l; \ + } while (0) + +#define COMPUTE_Z \ + do { \ + z[0] = x[0] ^ S5[IB(x[3])] ^ S6[ID(x[3])] ^ S7[IA(x[3])] ^ S8[IC(x[3])] ^ S7[IA(x[2])]; \ + z[1] = x[2] ^ S5[IA(z[0])] ^ S6[IC(z[0])] ^ S7[IB(z[0])] ^ S8[ID(z[0])] ^ S8[IC(x[2])]; \ + z[2] = x[3] ^ S5[ID(z[1])] ^ S6[IC(z[1])] ^ S7[IB(z[1])] ^ S8[IA(z[1])] ^ S5[IB(x[2])]; \ + z[3] = x[1] ^ S5[IC(z[2])] ^ S6[IB(z[2])] ^ S7[ID(z[2])] ^ S8[IA(z[2])] ^ S6[ID(x[2])]; \ + } while (0) + +#define COMPUTE_X \ + do { \ + x[0] = z[2] ^ S5[IB(z[1])] ^ S6[ID(z[1])] ^ S7[IA(z[1])] ^ S8[IC(z[1])] ^ S7[IA(z[0])]; \ + x[1] = z[0] ^ S5[IA(x[0])] ^ S6[IC(x[0])] ^ S7[IB(x[0])] ^ S8[ID(x[0])] ^ S8[IC(z[0])]; \ + x[2] = z[1] ^ S5[ID(x[1])] ^ S6[IC(x[1])] ^ S7[IB(x[1])] ^ S8[IA(x[1])] ^ S5[IB(z[0])]; \ + x[3] = z[3] ^ S5[IC(x[2])] ^ S6[IB(x[2])] ^ S7[ID(x[2])] ^ S8[IA(x[2])] ^ S6[ID(z[0])]; \ + } while (0) + + +typedef struct AVCAST5 { + uint32_t Km[17]; + uint32_t Kr[17]; + int rounds; +} AVCAST5; + +const int av_cast5_size = sizeof(AVCAST5); + +static const uint32_t S1[256] = { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf +}; + +static const uint32_t S2[256] = { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1 +}; + +static const uint32_t S3[256] = { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783 +}; + +static const uint32_t S4[256] = { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 +}; + +static const uint32_t S5[256] = { + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4 +}; + +static const uint32_t S6[256] = { + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f +}; + +static const uint32_t S7[256] = { + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3 +}; + +static const uint32_t S8[256] = { + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e +}; + +static void generate_round_keys(int rnds, uint32_t* K, uint32_t* x, uint32_t* z) +{ + COMPUTE_Z; + + K[1] = S5[IA(z[2])] ^ S6[IB(z[2])] ^ S7[ID(z[1])] ^ S8[IC(z[1])] ^ S5[IC(z[0])]; + K[2] = S5[IC(z[2])] ^ S6[ID(z[2])] ^ S7[IB(z[1])] ^ S8[IA(z[1])] ^ S6[IC(z[1])]; + K[3] = S5[IA(z[3])] ^ S6[IB(z[3])] ^ S7[ID(z[0])] ^ S8[IC(z[0])] ^ S7[IB(z[2])]; + K[4] = S5[IC(z[3])] ^ S6[ID(z[3])] ^ S7[IB(z[0])] ^ S8[IA(z[0])] ^ S8[IA(z[3])]; + + COMPUTE_X; + + K[5] = S5[ID(x[0])] ^ S6[IC(x[0])] ^ S7[IA(x[3])] ^ S8[IB(x[3])] ^ S5[IA(x[2])]; + K[6] = S5[IB(x[0])] ^ S6[IA(x[0])] ^ S7[IC(x[3])] ^ S8[ID(x[3])] ^ S6[IB(x[3])]; + K[7] = S5[ID(x[1])] ^ S6[IC(x[1])] ^ S7[IA(x[2])] ^ S8[IB(x[2])] ^ S7[ID(x[0])]; + K[8] = S5[IB(x[1])] ^ S6[IA(x[1])] ^ S7[IC(x[2])] ^ S8[ID(x[2])] ^ S8[ID(x[1])]; + + COMPUTE_Z; + + K[9] = S5[ID(z[0])] ^ S6[IC(z[0])] ^ S7[IA(z[3])] ^ S8[IB(z[3])] ^ S5[IB(z[2])]; + K[10] = S5[IB(z[0])] ^ S6[IA(z[0])] ^ S7[IC(z[3])] ^ S8[ID(z[3])] ^ S6[IA(z[3])]; + K[11] = S5[ID(z[1])] ^ S6[IC(z[1])] ^ S7[IA(z[2])] ^ S8[IB(z[2])] ^ S7[IC(z[0])]; + K[12] = S5[IB(z[1])] ^ S6[IA(z[1])] ^ S7[IC(z[2])] ^ S8[ID(z[2])] ^ S8[IC(z[1])]; + + COMPUTE_X; + + if (rnds == 16) { + K[13] = S5[IA(x[2])] ^ S6[IB(x[2])] ^ S7[ID(x[1])] ^ S8[IC(x[1])] ^ S5[ID(x[0])]; + K[14] = S5[IC(x[2])] ^ S6[ID(x[2])] ^ S7[IB(x[1])] ^ S8[IA(x[1])] ^ S6[ID(x[1])]; + K[15] = S5[IA(x[3])] ^ S6[IB(x[3])] ^ S7[ID(x[0])] ^ S8[IC(x[0])] ^ S7[IA(x[2])]; + K[16] = S5[IC(x[3])] ^ S6[ID(x[3])] ^ S7[IB(x[0])] ^ S8[IA(x[0])] ^ S8[IB(x[3])]; + } +} + +static void encipher(AVCAST5* cs, uint8_t* dst, const uint8_t* src) +{ + uint32_t r, l, f, I; + l = AV_RB32(src); + r = AV_RB32(src + 4); + F1(l, r, 1); + F2(r, l, 2); + F3(l, r, 3); + F1(r, l, 4); + F2(l, r, 5); + F3(r, l, 6); + F1(l, r, 7); + F2(r, l, 8); + F3(l, r, 9); + F1(r, l, 10); + F2(l, r, 11); + F3(r, l, 12); + if (cs->rounds == 16) { + F1(l, r, 13); + F2(r, l, 14); + F3(l, r, 15); + F1(r, l, 16); + } + AV_WB32(dst, r); + AV_WB32(dst + 4, l); +} + +static void decipher(AVCAST5* cs, uint8_t* dst, const uint8_t* src, uint8_t *iv) +{ + uint32_t f, I, r, l; + l = AV_RB32(src); + r = AV_RB32(src + 4); + if (cs->rounds == 16) { + F1(l, r, 16); + F3(r, l, 15); + F2(l, r, 14); + F1(r, l, 13); + } + F3(l, r, 12); + F2(r, l, 11); + F1(l, r, 10); + F3(r, l, 9); + F2(l, r, 8); + F1(r, l, 7); + F3(l, r, 6); + F2(r, l, 5); + F1(l, r, 4); + F3(r, l, 3); + F2(l, r, 2); + F1(r, l, 1); + if (iv) { + r ^= AV_RB32(iv); + l ^= AV_RB32(iv + 4); + memcpy(iv, src, 8); + } + AV_WB32(dst, r); + AV_WB32(dst + 4, l); +} + +struct AVCAST5 *av_cast5_alloc(void) +{ + return av_mallocz(sizeof(struct AVCAST5)); +} + +av_cold int av_cast5_init(AVCAST5* cs, const uint8_t *key, int key_bits) +{ + uint8_t newKey[16]; + int i; + uint32_t p[4], q[4]; + if (key_bits % 8 || key_bits < 40 || key_bits > 128) + return AVERROR(EINVAL); + memset(newKey, 0, sizeof(newKey)); + memcpy(newKey, key, key_bits >> 3); + + cs->rounds = key_bits <= 80 ? 12 : 16; + for (i = 0; i < 4; i++) + q[i] = AV_RB32(newKey + (4 * i)); + generate_round_keys(cs->rounds, cs->Km, q, p); + generate_round_keys(cs->rounds, cs->Kr, q, p); + for (i = 0; i <= cs->rounds; i++) + cs->Kr[i] = cs->Kr[i] & 0x1f; + return 0; +} + +void av_cast5_crypt2(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, uint8_t *iv, int decrypt) +{ + int i; + while (count--) { + if (decrypt) { + decipher(cs, dst, src, iv); + } else { + if (iv) { + for (i = 0; i < 8; i++) + dst[i] = src[i] ^ iv[i]; + encipher(cs, dst, dst); + memcpy(iv, dst, 8); + } else { + encipher(cs, dst, src); + } + } + src = src + 8; + dst = dst + 8; + } +} +void av_cast5_crypt(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, int decrypt) +{ + while (count--) { + if (decrypt){ + decipher(cs, dst, src, NULL); + } else { + encipher(cs, dst, src); + } + src = src + 8; + dst = dst + 8; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cast5.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cast5.h new file mode 100644 index 000000000..ad5b347e6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cast5.h @@ -0,0 +1,80 @@ +/* + * An implementation of the CAST128 algorithm as mentioned in RFC2144 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CAST5_H +#define AVUTIL_CAST5_H + +#include + + +/** + * @file + * @brief Public header for libavutil CAST5 algorithm + * @defgroup lavu_cast5 CAST5 + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_cast5_size; + +struct AVCAST5; + +/** + * Allocate an AVCAST5 context + * To free the struct: av_free(ptr) + */ +struct AVCAST5 *av_cast5_alloc(void); +/** + * Initialize an AVCAST5 context. + * + * @param ctx an AVCAST5 context + * @param key a key of 5,6,...16 bytes used for encryption/decryption + * @param key_bits number of keybits: possible are 40,48,...,128 + * @return 0 on success, less than 0 on failure + */ +int av_cast5_init(struct AVCAST5 *ctx, const uint8_t *key, int key_bits); + +/** + * Encrypt or decrypt a buffer using a previously initialized context, ECB mode only + * + * @param ctx an AVCAST5 context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_cast5_crypt(struct AVCAST5 *ctx, uint8_t *dst, const uint8_t *src, int count, int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context + * + * @param ctx an AVCAST5 context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, NULL for ECB mode + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_cast5_crypt2(struct AVCAST5 *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); +/** + * @} + */ +#endif /* AVUTIL_CAST5_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/channel_layout.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/channel_layout.c new file mode 100644 index 000000000..3bd5ee29b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/channel_layout.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio channel layout utility functions + */ + +#include + +#include "avstring.h" +#include "avutil.h" +#include "channel_layout.h" +#include "bprint.h" +#include "common.h" + +struct channel_name { + const char *name; + const char *description; +}; + +static const struct channel_name channel_names[] = { + [0] = { "FL", "front left" }, + [1] = { "FR", "front right" }, + [2] = { "FC", "front center" }, + [3] = { "LFE", "low frequency" }, + [4] = { "BL", "back left" }, + [5] = { "BR", "back right" }, + [6] = { "FLC", "front left-of-center" }, + [7] = { "FRC", "front right-of-center" }, + [8] = { "BC", "back center" }, + [9] = { "SL", "side left" }, + [10] = { "SR", "side right" }, + [11] = { "TC", "top center" }, + [12] = { "TFL", "top front left" }, + [13] = { "TFC", "top front center" }, + [14] = { "TFR", "top front right" }, + [15] = { "TBL", "top back left" }, + [16] = { "TBC", "top back center" }, + [17] = { "TBR", "top back right" }, + [29] = { "DL", "downmix left" }, + [30] = { "DR", "downmix right" }, + [31] = { "WL", "wide left" }, + [32] = { "WR", "wide right" }, + [33] = { "SDL", "surround direct left" }, + [34] = { "SDR", "surround direct right" }, + [35] = { "LFE2", "low frequency 2" }, +}; + +static const char *get_channel_name(int channel_id) +{ + if (channel_id < 0 || channel_id >= FF_ARRAY_ELEMS(channel_names)) + return NULL; + return channel_names[channel_id].name; +} + +static const struct { + const char *name; + int nb_channels; + uint64_t layout; +} channel_layout_map[] = { + { "mono", 1, AV_CH_LAYOUT_MONO }, + { "stereo", 2, AV_CH_LAYOUT_STEREO }, + { "2.1", 3, AV_CH_LAYOUT_2POINT1 }, + { "3.0", 3, AV_CH_LAYOUT_SURROUND }, + { "3.0(back)", 3, AV_CH_LAYOUT_2_1 }, + { "4.0", 4, AV_CH_LAYOUT_4POINT0 }, + { "quad", 4, AV_CH_LAYOUT_QUAD }, + { "quad(side)", 4, AV_CH_LAYOUT_2_2 }, + { "3.1", 4, AV_CH_LAYOUT_3POINT1 }, + { "5.0", 5, AV_CH_LAYOUT_5POINT0_BACK }, + { "5.0(side)", 5, AV_CH_LAYOUT_5POINT0 }, + { "4.1", 5, AV_CH_LAYOUT_4POINT1 }, + { "5.1", 6, AV_CH_LAYOUT_5POINT1_BACK }, + { "5.1(side)", 6, AV_CH_LAYOUT_5POINT1 }, + { "6.0", 6, AV_CH_LAYOUT_6POINT0 }, + { "6.0(front)", 6, AV_CH_LAYOUT_6POINT0_FRONT }, + { "hexagonal", 6, AV_CH_LAYOUT_HEXAGONAL }, + { "6.1", 7, AV_CH_LAYOUT_6POINT1 }, + { "6.1(back)", 7, AV_CH_LAYOUT_6POINT1_BACK }, + { "6.1(front)", 7, AV_CH_LAYOUT_6POINT1_FRONT }, + { "7.0", 7, AV_CH_LAYOUT_7POINT0 }, + { "7.0(front)", 7, AV_CH_LAYOUT_7POINT0_FRONT }, + { "7.1", 8, AV_CH_LAYOUT_7POINT1 }, + { "7.1(wide)", 8, AV_CH_LAYOUT_7POINT1_WIDE_BACK }, + { "7.1(wide-side)", 8, AV_CH_LAYOUT_7POINT1_WIDE }, + { "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL }, + { "hexadecagonal", 16, AV_CH_LAYOUT_HEXADECAGONAL }, + { "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, }, +}; + +static uint64_t get_channel_layout_single(const char *name, int name_len) +{ + int i; + char *end; + int64_t layout; + + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) { + if (strlen(channel_layout_map[i].name) == name_len && + !memcmp(channel_layout_map[i].name, name, name_len)) + return channel_layout_map[i].layout; + } + for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) + if (channel_names[i].name && + strlen(channel_names[i].name) == name_len && + !memcmp(channel_names[i].name, name, name_len)) + return (int64_t)1 << i; + + errno = 0; + i = strtol(name, &end, 10); + + if (!errno && (end + 1 - name == name_len && *end == 'c')) + return av_get_default_channel_layout(i); + + errno = 0; + layout = strtoll(name, &end, 0); + if (!errno && end - name == name_len) + return FFMAX(layout, 0); + return 0; +} + +uint64_t av_get_channel_layout(const char *name) +{ + const char *n, *e; + const char *name_end = name + strlen(name); + int64_t layout = 0, layout_single; + + for (n = name; n < name_end; n = e + 1) { + for (e = n; e < name_end && *e != '+' && *e != '|'; e++); + layout_single = get_channel_layout_single(n, e - n); + if (!layout_single) + return 0; + layout |= layout_single; + } + return layout; +} + +int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels) +{ + int nb = 0; + char *end; + uint64_t layout = av_get_channel_layout(name); + + if (layout) { + *channel_layout = layout; + *nb_channels = av_get_channel_layout_nb_channels(layout); + return 0; + } + + nb = strtol(name, &end, 10); + if (!errno && *end == 'C' && *(end + 1) == '\0' && nb > 0 && nb < 64) { + *channel_layout = 0; + *nb_channels = nb; + return 0; + } + + return AVERROR(EINVAL); +} + +void av_bprint_channel_layout(struct AVBPrint *bp, + int nb_channels, uint64_t channel_layout) +{ + int i; + + if (nb_channels <= 0) + nb_channels = av_get_channel_layout_nb_channels(channel_layout); + + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) + if (nb_channels == channel_layout_map[i].nb_channels && + channel_layout == channel_layout_map[i].layout) { + av_bprintf(bp, "%s", channel_layout_map[i].name); + return; + } + + av_bprintf(bp, "%d channels", nb_channels); + if (channel_layout) { + int i, ch; + av_bprintf(bp, " ("); + for (i = 0, ch = 0; i < 64; i++) { + if ((channel_layout & (UINT64_C(1) << i))) { + const char *name = get_channel_name(i); + if (name) { + if (ch > 0) + av_bprintf(bp, "+"); + av_bprintf(bp, "%s", name); + } + ch++; + } + } + av_bprintf(bp, ")"); + } +} + +void av_get_channel_layout_string(char *buf, int buf_size, + int nb_channels, uint64_t channel_layout) +{ + AVBPrint bp; + + av_bprint_init_for_buffer(&bp, buf, buf_size); + av_bprint_channel_layout(&bp, nb_channels, channel_layout); +} + +int av_get_channel_layout_nb_channels(uint64_t channel_layout) +{ + return av_popcount64(channel_layout); +} + +int64_t av_get_default_channel_layout(int nb_channels) { + int i; + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) + if (nb_channels == channel_layout_map[i].nb_channels) + return channel_layout_map[i].layout; + return 0; +} + +int av_get_channel_layout_channel_index(uint64_t channel_layout, + uint64_t channel) +{ + if (!(channel_layout & channel) || + av_get_channel_layout_nb_channels(channel) != 1) + return AVERROR(EINVAL); + channel_layout &= channel - 1; + return av_get_channel_layout_nb_channels(channel_layout); +} + +const char *av_get_channel_name(uint64_t channel) +{ + int i; + if (av_get_channel_layout_nb_channels(channel) != 1) + return NULL; + for (i = 0; i < 64; i++) + if ((1ULL<= FF_ARRAY_ELEMS(channel_layout_map)) + return AVERROR_EOF; + if (layout) *layout = channel_layout_map[index].layout; + if (name) *name = channel_layout_map[index].name; + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/channel_layout.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/channel_layout.h new file mode 100644 index 000000000..50bb8f03c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/channel_layout.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2006 Michael Niedermayer + * Copyright (c) 2008 Peter Ross + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CHANNEL_LAYOUT_H +#define AVUTIL_CHANNEL_LAYOUT_H + +#include + +/** + * @file + * audio channel layout utility functions + */ + +/** + * @addtogroup lavu_audio + * @{ + */ + +/** + * @defgroup channel_masks Audio channel masks + * + * A channel layout is a 64-bits integer with a bit set for every channel. + * The number of bits set must be equal to the number of channels. + * The value 0 means that the channel layout is not known. + * @note this data structure is not powerful enough to handle channels + * combinations that have the same channel multiple times, such as + * dual-mono. + * + * @{ + */ +#define AV_CH_FRONT_LEFT 0x00000001 +#define AV_CH_FRONT_RIGHT 0x00000002 +#define AV_CH_FRONT_CENTER 0x00000004 +#define AV_CH_LOW_FREQUENCY 0x00000008 +#define AV_CH_BACK_LEFT 0x00000010 +#define AV_CH_BACK_RIGHT 0x00000020 +#define AV_CH_FRONT_LEFT_OF_CENTER 0x00000040 +#define AV_CH_FRONT_RIGHT_OF_CENTER 0x00000080 +#define AV_CH_BACK_CENTER 0x00000100 +#define AV_CH_SIDE_LEFT 0x00000200 +#define AV_CH_SIDE_RIGHT 0x00000400 +#define AV_CH_TOP_CENTER 0x00000800 +#define AV_CH_TOP_FRONT_LEFT 0x00001000 +#define AV_CH_TOP_FRONT_CENTER 0x00002000 +#define AV_CH_TOP_FRONT_RIGHT 0x00004000 +#define AV_CH_TOP_BACK_LEFT 0x00008000 +#define AV_CH_TOP_BACK_CENTER 0x00010000 +#define AV_CH_TOP_BACK_RIGHT 0x00020000 +#define AV_CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. +#define AV_CH_STEREO_RIGHT 0x40000000 ///< See AV_CH_STEREO_LEFT. +#define AV_CH_WIDE_LEFT 0x0000000080000000ULL +#define AV_CH_WIDE_RIGHT 0x0000000100000000ULL +#define AV_CH_SURROUND_DIRECT_LEFT 0x0000000200000000ULL +#define AV_CH_SURROUND_DIRECT_RIGHT 0x0000000400000000ULL +#define AV_CH_LOW_FREQUENCY_2 0x0000000800000000ULL + +/** Channel mask value used for AVCodecContext.request_channel_layout + to indicate that the user requests the channel order of the decoder output + to be the native codec channel order. */ +#define AV_CH_LAYOUT_NATIVE 0x8000000000000000ULL + +/** + * @} + * @defgroup channel_mask_c Audio channel layouts + * @{ + * */ +#define AV_CH_LAYOUT_MONO (AV_CH_FRONT_CENTER) +#define AV_CH_LAYOUT_STEREO (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT) +#define AV_CH_LAYOUT_2POINT1 (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_2_1 (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_SURROUND (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) +#define AV_CH_LAYOUT_3POINT1 (AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_4POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_4POINT1 (AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_2_2 (AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) +#define AV_CH_LAYOUT_QUAD (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_5POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) +#define AV_CH_LAYOUT_5POINT1 (AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_5POINT0_BACK (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_5POINT1_BACK (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_6POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT0_FRONT (AV_CH_LAYOUT_2_2|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_HEXAGONAL (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT1_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT1_FRONT (AV_CH_LAYOUT_6POINT0_FRONT|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_7POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_7POINT0_FRONT (AV_CH_LAYOUT_5POINT0|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_7POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_7POINT1_WIDE (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_7POINT1_WIDE_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_HEXADECAGONAL (AV_CH_LAYOUT_OCTAGONAL|AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) +#define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT) + +enum AVMatrixEncoding { + AV_MATRIX_ENCODING_NONE, + AV_MATRIX_ENCODING_DOLBY, + AV_MATRIX_ENCODING_DPLII, + AV_MATRIX_ENCODING_DPLIIX, + AV_MATRIX_ENCODING_DPLIIZ, + AV_MATRIX_ENCODING_DOLBYEX, + AV_MATRIX_ENCODING_DOLBYHEADPHONE, + AV_MATRIX_ENCODING_NB +}; + +/** + * Return a channel layout id that matches name, or 0 if no match is found. + * + * name can be one or several of the following notations, + * separated by '+' or '|': + * - the name of an usual channel layout (mono, stereo, 4.0, quad, 5.0, + * 5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix); + * - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC, + * SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR); + * - a number of channels, in decimal, followed by 'c', yielding + * the default channel layout for that number of channels (@see + * av_get_default_channel_layout); + * - a channel layout mask, in hexadecimal starting with "0x" (see the + * AV_CH_* macros). + * + * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7" + */ +uint64_t av_get_channel_layout(const char *name); + +/** + * Return a channel layout and the number of channels based on the specified name. + * + * This function is similar to (@see av_get_channel_layout), but can also parse + * unknown channel layout specifications. + * + * @param[in] name channel layout specification string + * @param[out] channel_layout parsed channel layout (0 if unknown) + * @param[out] nb_channels number of channels + * + * @return 0 on success, AVERROR(EINVAL) if the parsing fails. + */ +int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels); + +/** + * Return a description of a channel layout. + * If nb_channels is <= 0, it is guessed from the channel_layout. + * + * @param buf put here the string containing the channel layout + * @param buf_size size in bytes of the buffer + */ +void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout); + +struct AVBPrint; +/** + * Append a description of a channel layout to a bprint buffer. + */ +void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout); + +/** + * Return the number of channels in the channel layout. + */ +int av_get_channel_layout_nb_channels(uint64_t channel_layout); + +/** + * Return default channel layout for a given number of channels. + */ +int64_t av_get_default_channel_layout(int nb_channels); + +/** + * Get the index of a channel in channel_layout. + * + * @param channel a channel layout describing exactly one channel which must be + * present in channel_layout. + * + * @return index of channel in channel_layout on success, a negative AVERROR + * on error. + */ +int av_get_channel_layout_channel_index(uint64_t channel_layout, + uint64_t channel); + +/** + * Get the channel with the given index in channel_layout. + */ +uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index); + +/** + * Get the name of a given channel. + * + * @return channel name on success, NULL on error. + */ +const char *av_get_channel_name(uint64_t channel); + +/** + * Get the description of a given channel. + * + * @param channel a channel layout with a single channel + * @return channel description on success, NULL on error + */ +const char *av_get_channel_description(uint64_t channel); + +/** + * Get the value and name of a standard channel layout. + * + * @param[in] index index in an internal list, starting at 0 + * @param[out] layout channel layout mask + * @param[out] name name of the layout + * @return 0 if the layout exists, + * <0 if index is beyond the limits + */ +int av_get_standard_channel_layout(unsigned index, uint64_t *layout, + const char **name); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_CHANNEL_LAYOUT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/color_utils.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/color_utils.c new file mode 100644 index 000000000..eb8bc7b5f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/color_utils.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2015 Kevin Wheatley + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "common.h" +#include "libavutil/color_utils.h" +#include "libavutil/pixfmt.h" + +double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc) +{ + double gamma; + switch (trc) { + case AVCOL_TRC_BT709: + case AVCOL_TRC_SMPTE170M: + case AVCOL_TRC_SMPTE240M: + case AVCOL_TRC_BT1361_ECG: + case AVCOL_TRC_BT2020_10: + case AVCOL_TRC_BT2020_12: + /* these share a segmented TRC, but gamma 1.961 is a close + approximation, and also more correct for decoding content */ + gamma = 1.961; + break; + case AVCOL_TRC_GAMMA22: + case AVCOL_TRC_IEC61966_2_1: + gamma = 2.2; + break; + case AVCOL_TRC_GAMMA28: + gamma = 2.8; + break; + case AVCOL_TRC_LINEAR: + gamma = 1.0; + break; + default: + gamma = 0.0; // Unknown value representation + } + return gamma; +} + +#define BT709_alpha 1.099296826809442 +#define BT709_beta 0.018053968510807 + +static double avpriv_trc_bt709(double Lc) +{ + const double a = BT709_alpha; + const double b = BT709_beta; + + return (0.0 > Lc) ? 0.0 + : ( b > Lc) ? 4.500 * Lc + : a * pow(Lc, 0.45) - (a - 1.0); +} + +static double avpriv_trc_gamma22(double Lc) +{ + return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2); +} + +static double avpriv_trc_gamma28(double Lc) +{ + return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8); +} + +static double avpriv_trc_smpte240M(double Lc) +{ + const double a = 1.1115; + const double b = 0.0228; + + return (0.0 > Lc) ? 0.0 + : ( b > Lc) ? 4.000 * Lc + : a * pow(Lc, 0.45) - (a - 1.0); +} + +static double avpriv_trc_linear(double Lc) +{ + return Lc; +} + +static double avpriv_trc_log(double Lc) +{ + return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0; +} + +static double avpriv_trc_log_sqrt(double Lc) +{ + // sqrt(10) / 1000 + return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5; +} + +static double avpriv_trc_iec61966_2_4(double Lc) +{ + const double a = BT709_alpha; + const double b = BT709_beta; + + return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0) + : ( b > Lc) ? 4.500 * Lc + : a * pow( Lc, 0.45) - (a - 1.0); +} + +static double avpriv_trc_bt1361(double Lc) +{ + const double a = BT709_alpha; + const double b = BT709_beta; + + return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0 + : ( b > Lc) ? 4.500 * Lc + : a * pow( Lc, 0.45) - (a - 1.0); +} + +static double avpriv_trc_iec61966_2_1(double Lc) +{ + const double a = 1.055; + const double b = 0.0031308; + + return (0.0 > Lc) ? 0.0 + : ( b > Lc) ? 12.92 * Lc + : a * pow(Lc, 1.0 / 2.4) - (a - 1.0); +} + +static double avpriv_trc_smpte_st2084(double Lc) +{ + const double c1 = 3424.0 / 4096.0; // c3-c2 + 1 + const double c2 = 32.0 * 2413.0 / 4096.0; + const double c3 = 32.0 * 2392.0 / 4096.0; + const double m = 128.0 * 2523.0 / 4096.0; + const double n = 0.25 * 2610.0 / 4096.0; + const double L = Lc / 10000.0; + const double Ln = pow(L, n); + + return (0.0 > Lc) ? 0.0 + : pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m); + +} + +static double avpriv_trc_smpte_st428_1(double Lc) +{ + return (0.0 > Lc) ? 0.0 + : pow(48.0 * Lc / 52.37, 1.0 / 2.6); +} + + +static double avpriv_trc_arib_std_b67(double Lc) { + // The function uses the definition from HEVC, which assumes that the peak + // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and + // using the definition from the ARIB STD-B67 spec) + const double a = 0.17883277; + const double b = 0.28466892; + const double c = 0.55991073; + return (0.0 > Lc) ? 0.0 : + (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c); +} + +avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc) +{ + avpriv_trc_function func = NULL; + switch (trc) { + case AVCOL_TRC_BT709: + case AVCOL_TRC_SMPTE170M: + case AVCOL_TRC_BT2020_10: + case AVCOL_TRC_BT2020_12: + func = avpriv_trc_bt709; + break; + + case AVCOL_TRC_GAMMA22: + func = avpriv_trc_gamma22; + break; + case AVCOL_TRC_GAMMA28: + func = avpriv_trc_gamma28; + break; + + case AVCOL_TRC_SMPTE240M: + func = avpriv_trc_smpte240M; + break; + + case AVCOL_TRC_LINEAR: + func = avpriv_trc_linear; + break; + + case AVCOL_TRC_LOG: + func = avpriv_trc_log; + break; + + case AVCOL_TRC_LOG_SQRT: + func = avpriv_trc_log_sqrt; + break; + + case AVCOL_TRC_IEC61966_2_4: + func = avpriv_trc_iec61966_2_4; + break; + + case AVCOL_TRC_BT1361_ECG: + func = avpriv_trc_bt1361; + break; + + case AVCOL_TRC_IEC61966_2_1: + func = avpriv_trc_iec61966_2_1; + break; + + case AVCOL_TRC_SMPTEST2084: + func = avpriv_trc_smpte_st2084; + break; + + case AVCOL_TRC_SMPTEST428_1: + func = avpriv_trc_smpte_st428_1; + break; + + case AVCOL_TRC_ARIB_STD_B67: + func = avpriv_trc_arib_std_b67; + break; + + case AVCOL_TRC_RESERVED0: + case AVCOL_TRC_UNSPECIFIED: + case AVCOL_TRC_RESERVED: + default: + break; + } + return func; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/color_utils.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/color_utils.h new file mode 100644 index 000000000..952900645 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/color_utils.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015 Kevin Wheatley + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_COLOR_UTILS_H +#define AVUTIL_COLOR_UTILS_H + + +#include "libavutil/pixfmt.h" + +/** + * Determine a suitable 'gamma' value to match the supplied + * AVColorTransferCharacteristic. + * + * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html) + * + * @return Will return an approximation to the simple gamma function matching + * the supplied Transfer Characteristic, Will return 0.0 for any + * we cannot reasonably match against. + */ +double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc); + + +typedef double (*avpriv_trc_function)(double); + +/** + * Determine the function needed to apply the given + * AVColorTransferCharacteristic to linear input. + * + * The function returned should expect a nominal domain and range of [0.0-1.0] + * values outside of this range maybe valid depending on the chosen + * characteristic function. + * + * @return Will return pointer to the function matching the + * supplied Transfer Characteristic. If unspecified will + * return NULL: + */ +avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc); + +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/colorspace.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/colorspace.h new file mode 100644 index 000000000..ef6f6107d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/colorspace.h @@ -0,0 +1,150 @@ +/* + * Colorspace conversion defines + * Copyright (c) 2001, 2002, 2003 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Various defines for YUV<->RGB conversion + */ + +#ifndef AVUTIL_COLORSPACE_H +#define AVUTIL_COLORSPACE_H + +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<> SCALEBITS];\ + g = cm[(y + g_add) >> SCALEBITS];\ + b = cm[(y + b_add) >> SCALEBITS];\ +} + +#define YUV_TO_RGB1(cb1, cr1)\ +{\ + cb = (cb1) - 128;\ + cr = (cr1) - 128;\ + r_add = FIX(1.40200) * cr + ONE_HALF;\ + g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\ + b_add = FIX(1.77200) * cb + ONE_HALF;\ +} + +#define YUV_TO_RGB2(r, g, b, y1)\ +{\ + y = (y1) << SCALEBITS;\ + r = cm[(y + r_add) >> SCALEBITS];\ + g = cm[(y + g_add) >> SCALEBITS];\ + b = cm[(y + b_add) >> SCALEBITS];\ +} + +#define Y_CCIR_TO_JPEG(y)\ + cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS] + +#define Y_JPEG_TO_CCIR(y)\ + (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) + +#define C_CCIR_TO_JPEG(y)\ + cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS] + +/* NOTE: the clamp is really necessary! */ +static inline int C_JPEG_TO_CCIR(int y) { + y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS); + if (y < 16) + y = 16; + return y; +} + + +#define RGB_TO_Y_CCIR(r, g, b) \ +((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ + FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) + +#define RGB_TO_U_CCIR(r1, g1, b1, shift)\ +(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ + FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V_CCIR(r1, g1, b1, shift)\ +(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ + FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_Y_JPEG(r, g, b) \ +(FFMIN((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \ + FIX(0.11400) * (b) + (ONE_HALF)) >> SCALEBITS, 255)) + +#define RGB_TO_U_JPEG(r1, g1, b1)\ +(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ + FIX(0.50000) * b1 + (ONE_HALF) - 1) >> (SCALEBITS)) + 128) + +#define RGB_TO_V_JPEG(r1, g1, b1)\ +(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ + FIX(0.08131) * b1 + (ONE_HALF) - 1) >> (SCALEBITS)) + 128) + +// Conversion macros for 8-bit RGB to YUV +// Derived from ITU-R BT.709-6 (06/2015) Item 3.5 +// https://www.itu.int/rec/R-REC-BT.709-6-201506-I/en + +#define RGB_TO_Y_BT709(r, g, b) \ +((FIX(0.21260*219.0/255.0) * (r) + FIX(0.71520*219.0/255.0) * (g) + \ + FIX(0.07220*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) + +#define RGB_TO_U_BT709(r1, g1, b1, shift)\ +(((- FIX(0.11457*224.0/255.0) * r1 - FIX(0.38543*224.0/255.0) * g1 + \ + FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V_BT709(r1, g1, b1, shift)\ +(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.45415*224.0/255.0) * g1 - \ + FIX(0.04585*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_Y_BT709_FULL(r, g, b) \ +(FFMIN((FIX(0.21260) * (r) + FIX(0.71520) * (g) + \ + FIX(0.07220) * (b) + (ONE_HALF)) >> SCALEBITS, 255)) + +#define RGB_TO_U_BT709_FULL(r1, g1, b1)\ +(((- FIX(0.11457) * r1 - FIX(0.38543) * g1 + \ + FIX(0.50000) * b1 + (ONE_HALF) - 1) >> (SCALEBITS)) + 128) + +#define RGB_TO_V_BT709_FULL(r1, g1, b1)\ +(((FIX(0.50000) * r1 - FIX(0.45415) * g1 - \ + FIX(0.04585) * b1 + (ONE_HALF) - 1) >> (SCALEBITS)) + 128) + +#endif /* AVUTIL_COLORSPACE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/common.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/common.h new file mode 100644 index 000000000..8db029117 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/common.h @@ -0,0 +1,560 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * common internal and external API header + */ + +#ifndef AVUTIL_COMMON_H +#define AVUTIL_COMMON_H + +#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && !defined(UINT64_C) +#error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "attributes.h" +#include "macros.h" +#include "version.h" +#include "libavutil/avconfig.h" + +#if AV_HAVE_BIGENDIAN +# define AV_NE(be, le) (be) +#else +# define AV_NE(be, le) (le) +#endif + +//rounded division & shift +#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) +/* assume b>0 */ +#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) +/* Fast a/(1<=0 and b>=0 */ +#define AV_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \ + : ((a) + (1<<(b)) - 1) >> (b)) +/* Backwards compat. */ +#define FF_CEIL_RSHIFT AV_CEIL_RSHIFT + +#define FFUDIV(a,b) (((a)>0 ?(a):(a)-(b)+1) / (b)) +#define FFUMOD(a,b) ((a)-(b)*FFUDIV(a,b)) + +/** + * Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they + * are not representable as absolute values of their type. This is the same + * as with *abs() + * @see FFNABS() + */ +#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFSIGN(a) ((a) > 0 ? 1 : -1) + +/** + * Negative Absolute value. + * this works for all integers of all types. + * As with many macros, this evaluates its argument twice, it thus must not have + * a sideeffect, that is FFNABS(x++) has undefined behavior. + */ +#define FFNABS(a) ((a) <= 0 ? (a) : (-(a))) + +/** + * Comparator. + * For two numerical expressions x and y, gives 1 if x > y, -1 if x < y, and 0 + * if x == y. This is useful for instance in a qsort comparator callback. + * Furthermore, compilers are able to optimize this to branchless code, and + * there is no risk of overflow with signed types. + * As with many macros, this evaluates its argument multiple times, it thus + * must not have a side-effect. + */ +#define FFDIFFSIGN(x,y) (((x)>(y)) - ((x)<(y))) + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) +#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) + +#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) + +/* misc math functions */ + +#ifdef HAVE_AV_CONFIG_H +# include "config.h" +# include "intmath.h" +#endif + +/* Pull in unguarded fallback defines at the end of this file. */ +#include "common.h" + +#ifndef av_log2 +av_const int av_log2(unsigned v); +#endif + +#ifndef av_log2_16bit +av_const int av_log2_16bit(unsigned v); +#endif + +/** + * Clip a signed integer value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const int av_clip_c(int a, int amin, int amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clip a signed 64bit integer value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, int64_t amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clip a signed integer value into the 0-255 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const uint8_t av_clip_uint8_c(int a) +{ + if (a&(~0xFF)) return (~a)>>31; + else return a; +} + +/** + * Clip a signed integer value into the -128,127 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const int8_t av_clip_int8_c(int a) +{ + if ((a+0x80U) & ~0xFF) return (a>>31) ^ 0x7F; + else return a; +} + +/** + * Clip a signed integer value into the 0-65535 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const uint16_t av_clip_uint16_c(int a) +{ + if (a&(~0xFFFF)) return (~a)>>31; + else return a; +} + +/** + * Clip a signed integer value into the -32768,32767 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const int16_t av_clip_int16_c(int a) +{ + if ((a+0x8000U) & ~0xFFFF) return (a>>31) ^ 0x7FFF; + else return a; +} + +/** + * Clip a signed 64-bit integer value into the -2147483648,2147483647 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const int32_t av_clipl_int32_c(int64_t a) +{ + if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (int32_t)((a>>63) ^ 0x7FFFFFFF); + else return (int32_t)a; +} + +/** + * Clip a signed integer into the -(2^p),(2^p-1) range. + * @param a value to clip + * @param p bit position to clip at + * @return clipped value + */ +static av_always_inline av_const int av_clip_intp2_c(int a, int p) +{ + if (((unsigned)a + (1 << p)) & ~((2 << p) - 1)) + return (a >> 31) ^ ((1 << p) - 1); + else + return a; +} + +/** + * Clip a signed integer to an unsigned power of two range. + * @param a value to clip + * @param p bit position to clip at + * @return clipped value + */ +static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p) +{ + if (a & ~((1<> 31 & ((1<= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clip a double value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const double av_clipd_c(double a, double amin, double amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** Compute ceil(log2(x)). + * @param x value used to compute ceil(log2(x)) + * @return computed ceiling of log2(x) + */ +static av_always_inline av_const int av_ceil_log2_c(int x) +{ + return av_log2((x - 1) << 1); +} + +/** + * Count number of bits set to one in x + * @param x value to count bits of + * @return the number of bits set to one in x + */ +static av_always_inline av_const int av_popcount_c(uint32_t x) +{ + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0F0F0F0F; + x += x >> 8; + return (x + (x >> 16)) & 0x3F; +} + +/** + * Count number of bits set to one in x + * @param x value to count bits of + * @return the number of bits set to one in x + */ +static av_always_inline av_const int av_popcount64_c(uint64_t x) +{ + return av_popcount((uint32_t)x) + av_popcount((uint32_t)(x >> 32)); +} + +static av_always_inline av_const int av_parity_c(uint32_t v) +{ + return av_popcount(v) & 1; +} + +#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24)) +#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24)) + +/** + * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form. + * + * @param val Output value, must be an lvalue of type uint32_t. + * @param GET_BYTE Expression reading one byte from the input. + * Evaluated up to 7 times (4 for the currently + * assigned Unicode range). With a memory buffer + * input, this could be *ptr++. + * @param ERROR Expression to be evaluated on invalid input, + * typically a goto statement. + * + * @warning ERROR should not contain a loop control statement which + * could interact with the internal while loop, and should force an + * exit from the macro code (e.g. through a goto or a return) in order + * to prevent undefined results. + */ +#define GET_UTF8(val, GET_BYTE, ERROR)\ + val= (GET_BYTE);\ + {\ + uint32_t top = (val & 128) >> 1;\ + if ((val & 0xc0) == 0x80 || val >= 0xFE)\ + ERROR\ + while (val & top) {\ + int tmp= (GET_BYTE) - 128;\ + if(tmp>>6)\ + ERROR\ + val= (val<<6) + tmp;\ + top <<= 5;\ + }\ + val &= (top << 1) - 1;\ + } + +/** + * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form. + * + * @param val Output value, must be an lvalue of type uint32_t. + * @param GET_16BIT Expression returning two bytes of UTF-16 data converted + * to native byte order. Evaluated one or two times. + * @param ERROR Expression to be evaluated on invalid input, + * typically a goto statement. + */ +#define GET_UTF16(val, GET_16BIT, ERROR)\ + val = GET_16BIT;\ + {\ + unsigned int hi = val - 0xD800;\ + if (hi < 0x800) {\ + val = GET_16BIT - 0xDC00;\ + if (val > 0x3FFU || hi > 0x3FFU)\ + ERROR\ + val += (hi<<10) + 0x10000;\ + }\ + }\ + +/** + * @def PUT_UTF8(val, tmp, PUT_BYTE) + * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). + * @param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If + * val is given as a function it is executed only once. + * @param tmp is a temporary variable and should be of type uint8_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_BYTE. + * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. + * It could be a function or a statement, and uses tmp as the input byte. + * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be + * executed up to 4 times for values in the valid UTF-8 range and up to + * 7 times in the general case, depending on the length of the converted + * Unicode character. + */ +#define PUT_UTF8(val, tmp, PUT_BYTE)\ + {\ + int bytes, shift;\ + uint32_t in = val;\ + if (in < 0x80) {\ + tmp = in;\ + PUT_BYTE\ + } else {\ + bytes = (av_log2(in) + 4) / 5;\ + shift = (bytes - 1) * 6;\ + tmp = (256 - (256 >> bytes)) | (in >> shift);\ + PUT_BYTE\ + while (shift >= 6) {\ + shift -= 6;\ + tmp = 0x80 | ((in >> shift) & 0x3f);\ + PUT_BYTE\ + }\ + }\ + } + +/** + * @def PUT_UTF16(val, tmp, PUT_16BIT) + * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). + * @param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If + * val is given as a function it is executed only once. + * @param tmp is a temporary variable and should be of type uint16_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_16BIT. + * @param PUT_16BIT writes the converted UTF-16 data to any proper destination + * in desired endianness. It could be a function or a statement, and uses tmp + * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" + * PUT_BYTE will be executed 1 or 2 times depending on input character. + */ +#define PUT_UTF16(val, tmp, PUT_16BIT)\ + {\ + uint32_t in = val;\ + if (in < 0x10000) {\ + tmp = in;\ + PUT_16BIT\ + } else {\ + tmp = 0xD800 | ((in - 0x10000) >> 10);\ + PUT_16BIT\ + tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\ + PUT_16BIT\ + }\ + }\ + + + +#include "mem.h" + +#ifdef HAVE_AV_CONFIG_H +# include "internal.h" +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* AVUTIL_COMMON_H */ + +/* + * The following definitions are outside the multiple inclusion guard + * to ensure they are immediately available in intmath.h. + */ + +#ifndef av_ceil_log2 +# define av_ceil_log2 av_ceil_log2_c +#endif +#ifndef av_clip +# define av_clip av_clip_c +#endif +#ifndef av_clip64 +# define av_clip64 av_clip64_c +#endif +#ifndef av_clip_uint8 +# define av_clip_uint8 av_clip_uint8_c +#endif +#ifndef av_clip_int8 +# define av_clip_int8 av_clip_int8_c +#endif +#ifndef av_clip_uint16 +# define av_clip_uint16 av_clip_uint16_c +#endif +#ifndef av_clip_int16 +# define av_clip_int16 av_clip_int16_c +#endif +#ifndef av_clipl_int32 +# define av_clipl_int32 av_clipl_int32_c +#endif +#ifndef av_clip_intp2 +# define av_clip_intp2 av_clip_intp2_c +#endif +#ifndef av_clip_uintp2 +# define av_clip_uintp2 av_clip_uintp2_c +#endif +#ifndef av_mod_uintp2 +# define av_mod_uintp2 av_mod_uintp2_c +#endif +#ifndef av_sat_add32 +# define av_sat_add32 av_sat_add32_c +#endif +#ifndef av_sat_dadd32 +# define av_sat_dadd32 av_sat_dadd32_c +#endif +#ifndef av_sat_sub32 +# define av_sat_sub32 av_sat_sub32_c +#endif +#ifndef av_sat_dsub32 +# define av_sat_dsub32 av_sat_dsub32_c +#endif +#ifndef av_clipf +# define av_clipf av_clipf_c +#endif +#ifndef av_clipd +# define av_clipd av_clipd_c +#endif +#ifndef av_popcount +# define av_popcount av_popcount_c +#endif +#ifndef av_popcount64 +# define av_popcount64 av_popcount64_c +#endif +#ifndef av_parity +# define av_parity av_parity_c +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.c new file mode 100644 index 000000000..6548cc304 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.c @@ -0,0 +1,321 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "attributes.h" +#include "cpu.h" +#include "cpu_internal.h" +#include "config.h" +#include "opt.h" +#include "common.h" + +#if HAVE_SCHED_GETAFFINITY +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include +#endif +#if HAVE_GETPROCESSAFFINITYMASK || HAVE_WINRT +#include +#endif +#if HAVE_SYSCTL +#if HAVE_SYS_PARAM_H +#include +#endif +#include +#include +#endif +#if HAVE_UNISTD_H +#include +#endif + +static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1); + +static int get_cpu_flags(void) +{ + if (ARCH_AARCH64) + return ff_get_cpu_flags_aarch64(); + if (ARCH_ARM) + return ff_get_cpu_flags_arm(); + if (ARCH_PPC) + return ff_get_cpu_flags_ppc(); + if (ARCH_X86) + return ff_get_cpu_flags_x86(); + return 0; +} + +void av_force_cpu_flags(int arg){ + if (ARCH_X86 && + (arg & ( AV_CPU_FLAG_3DNOW | + AV_CPU_FLAG_3DNOWEXT | + AV_CPU_FLAG_MMXEXT | + AV_CPU_FLAG_SSE | + AV_CPU_FLAG_SSE2 | + AV_CPU_FLAG_SSE2SLOW | + AV_CPU_FLAG_SSE3 | + AV_CPU_FLAG_SSE3SLOW | + AV_CPU_FLAG_SSSE3 | + AV_CPU_FLAG_SSE4 | + AV_CPU_FLAG_SSE42 | + AV_CPU_FLAG_AVX | + AV_CPU_FLAG_AVXSLOW | + AV_CPU_FLAG_XOP | + AV_CPU_FLAG_FMA3 | + AV_CPU_FLAG_FMA4 | + AV_CPU_FLAG_AVX2 | + AV_CPU_FLAG_AVX512 )) + && !(arg & AV_CPU_FLAG_MMX)) { + av_log(NULL, AV_LOG_WARNING, "MMX implied by specified flags\n"); + arg |= AV_CPU_FLAG_MMX; + } + + atomic_store_explicit(&cpu_flags, arg, memory_order_relaxed); +} + +int av_get_cpu_flags(void) +{ + int flags = atomic_load_explicit(&cpu_flags, memory_order_relaxed); + if (flags == -1) { + flags = get_cpu_flags(); + atomic_store_explicit(&cpu_flags, flags, memory_order_relaxed); + } + return flags; +} + +void av_set_cpu_flags_mask(int mask) +{ + atomic_store_explicit(&cpu_flags, get_cpu_flags() & mask, + memory_order_relaxed); +} + +int av_parse_cpu_flags(const char *s) +{ +#define CPUFLAG_MMXEXT (AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT | AV_CPU_FLAG_CMOV) +#define CPUFLAG_3DNOW (AV_CPU_FLAG_3DNOW | AV_CPU_FLAG_MMX) +#define CPUFLAG_3DNOWEXT (AV_CPU_FLAG_3DNOWEXT | CPUFLAG_3DNOW) +#define CPUFLAG_SSE (AV_CPU_FLAG_SSE | CPUFLAG_MMXEXT) +#define CPUFLAG_SSE2 (AV_CPU_FLAG_SSE2 | CPUFLAG_SSE) +#define CPUFLAG_SSE2SLOW (AV_CPU_FLAG_SSE2SLOW | CPUFLAG_SSE2) +#define CPUFLAG_SSE3 (AV_CPU_FLAG_SSE3 | CPUFLAG_SSE2) +#define CPUFLAG_SSE3SLOW (AV_CPU_FLAG_SSE3SLOW | CPUFLAG_SSE3) +#define CPUFLAG_SSSE3 (AV_CPU_FLAG_SSSE3 | CPUFLAG_SSE3) +#define CPUFLAG_SSE4 (AV_CPU_FLAG_SSE4 | CPUFLAG_SSSE3) +#define CPUFLAG_SSE42 (AV_CPU_FLAG_SSE42 | CPUFLAG_SSE4) +#define CPUFLAG_AVX (AV_CPU_FLAG_AVX | CPUFLAG_SSE42) +#define CPUFLAG_AVXSLOW (AV_CPU_FLAG_AVXSLOW | CPUFLAG_AVX) +#define CPUFLAG_XOP (AV_CPU_FLAG_XOP | CPUFLAG_AVX) +#define CPUFLAG_FMA3 (AV_CPU_FLAG_FMA3 | CPUFLAG_AVX) +#define CPUFLAG_FMA4 (AV_CPU_FLAG_FMA4 | CPUFLAG_AVX) +#define CPUFLAG_AVX2 (AV_CPU_FLAG_AVX2 | CPUFLAG_AVX) +#define CPUFLAG_BMI2 (AV_CPU_FLAG_BMI2 | AV_CPU_FLAG_BMI1) +#define CPUFLAG_AESNI (AV_CPU_FLAG_AESNI | CPUFLAG_SSE42) +#define CPUFLAG_AVX512 (AV_CPU_FLAG_AVX512 | CPUFLAG_AVX2) + static const AVOption cpuflags_opts[] = { + { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, +#if ARCH_PPC + { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ALTIVEC }, .unit = "flags" }, +#elif ARCH_X86 + { "mmx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX }, .unit = "flags" }, + { "mmxext" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_MMXEXT }, .unit = "flags" }, + { "sse" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE }, .unit = "flags" }, + { "sse2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE2 }, .unit = "flags" }, + { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE2SLOW }, .unit = "flags" }, + { "sse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE3 }, .unit = "flags" }, + { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE3SLOW }, .unit = "flags" }, + { "ssse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSSE3 }, .unit = "flags" }, + { "atom" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ATOM }, .unit = "flags" }, + { "sse4.1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE4 }, .unit = "flags" }, + { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE42 }, .unit = "flags" }, + { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX }, .unit = "flags" }, + { "avxslow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVXSLOW }, .unit = "flags" }, + { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_XOP }, .unit = "flags" }, + { "fma3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_FMA3 }, .unit = "flags" }, + { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_FMA4 }, .unit = "flags" }, + { "avx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX2 }, .unit = "flags" }, + { "bmi1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_BMI1 }, .unit = "flags" }, + { "bmi2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_BMI2 }, .unit = "flags" }, + { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOW }, .unit = "flags" }, + { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOWEXT }, .unit = "flags" }, + { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" }, + { "aesni" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AESNI }, .unit = "flags" }, + { "avx512" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX512 }, .unit = "flags" }, +#elif ARCH_ARM + { "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV5TE }, .unit = "flags" }, + { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6 }, .unit = "flags" }, + { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" }, + { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, + { "vfp_vm", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP_VM }, .unit = "flags" }, + { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" }, + { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, +#elif ARCH_AARCH64 + { "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" }, + { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, + { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, +#endif + { NULL }, + }; + static const AVClass class = { + .class_name = "cpuflags", + .item_name = av_default_item_name, + .option = cpuflags_opts, + .version = LIBAVUTIL_VERSION_INT, + }; + + int flags = 0, ret; + const AVClass *pclass = &class; + + if ((ret = av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, &flags)) < 0) + return ret; + + return flags & INT_MAX; +} + +int av_parse_cpu_caps(unsigned *flags, const char *s) +{ + static const AVOption cpuflags_opts[] = { + { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, +#if ARCH_PPC + { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ALTIVEC }, .unit = "flags" }, +#elif ARCH_X86 + { "mmx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX }, .unit = "flags" }, + { "mmx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX2 }, .unit = "flags" }, + { "mmxext" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX2 }, .unit = "flags" }, + { "sse" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE }, .unit = "flags" }, + { "sse2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE2 }, .unit = "flags" }, + { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE2SLOW }, .unit = "flags" }, + { "sse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE3 }, .unit = "flags" }, + { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE3SLOW }, .unit = "flags" }, + { "ssse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSSE3 }, .unit = "flags" }, + { "atom" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ATOM }, .unit = "flags" }, + { "sse4.1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE4 }, .unit = "flags" }, + { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE42 }, .unit = "flags" }, + { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX }, .unit = "flags" }, + { "avxslow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVXSLOW }, .unit = "flags" }, + { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_XOP }, .unit = "flags" }, + { "fma3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_FMA3 }, .unit = "flags" }, + { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_FMA4 }, .unit = "flags" }, + { "avx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX2 }, .unit = "flags" }, + { "bmi1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_BMI1 }, .unit = "flags" }, + { "bmi2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_BMI2 }, .unit = "flags" }, + { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOW }, .unit = "flags" }, + { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOWEXT }, .unit = "flags" }, + { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" }, + { "aesni", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AESNI }, .unit = "flags" }, + { "avx512" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX512 }, .unit = "flags" }, + +#define CPU_FLAG_P2 AV_CPU_FLAG_CMOV | AV_CPU_FLAG_MMX +#define CPU_FLAG_P3 CPU_FLAG_P2 | AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE +#define CPU_FLAG_P4 CPU_FLAG_P3| AV_CPU_FLAG_SSE2 + { "pentium2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_P2 }, .unit = "flags" }, + { "pentium3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_P3 }, .unit = "flags" }, + { "pentium4", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_P4 }, .unit = "flags" }, + +#define CPU_FLAG_K62 AV_CPU_FLAG_MMX | AV_CPU_FLAG_3DNOW +#define CPU_FLAG_ATHLON CPU_FLAG_K62 | AV_CPU_FLAG_CMOV | AV_CPU_FLAG_3DNOWEXT | AV_CPU_FLAG_MMX2 +#define CPU_FLAG_ATHLONXP CPU_FLAG_ATHLON | AV_CPU_FLAG_SSE +#define CPU_FLAG_K8 CPU_FLAG_ATHLONXP | AV_CPU_FLAG_SSE2 + { "k6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX }, .unit = "flags" }, + { "k62", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_K62 }, .unit = "flags" }, + { "athlon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_ATHLON }, .unit = "flags" }, + { "athlonxp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_ATHLONXP }, .unit = "flags" }, + { "k8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPU_FLAG_K8 }, .unit = "flags" }, +#elif ARCH_ARM + { "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV5TE }, .unit = "flags" }, + { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6 }, .unit = "flags" }, + { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" }, + { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, + { "vfp_vm", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP_VM }, .unit = "flags" }, + { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" }, + { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, + { "setend", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SETEND }, .unit = "flags" }, +#elif ARCH_AARCH64 + { "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" }, + { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, + { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, +#endif + { NULL }, + }; + static const AVClass class = { + .class_name = "cpuflags", + .item_name = av_default_item_name, + .option = cpuflags_opts, + .version = LIBAVUTIL_VERSION_INT, + }; + const AVClass *pclass = &class; + + return av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, flags); +} + +int av_cpu_count(void) +{ + static volatile int printed; + + int nb_cpus = 1; +#if HAVE_WINRT + SYSTEM_INFO sysinfo; +#endif +#if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT) + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + + if (!sched_getaffinity(0, sizeof(cpuset), &cpuset)) + nb_cpus = CPU_COUNT(&cpuset); +#elif HAVE_GETPROCESSAFFINITYMASK + DWORD_PTR proc_aff, sys_aff; + if (GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff)) + nb_cpus = av_popcount64(proc_aff); +#elif HAVE_SYSCTL && defined(HW_NCPU) + int mib[2] = { CTL_HW, HW_NCPU }; + size_t len = sizeof(nb_cpus); + + if (sysctl(mib, 2, &nb_cpus, &len, NULL, 0) == -1) + nb_cpus = 0; +#elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN) + nb_cpus = sysconf(_SC_NPROC_ONLN); +#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN) + nb_cpus = sysconf(_SC_NPROCESSORS_ONLN); +#elif HAVE_WINRT + GetNativeSystemInfo(&sysinfo); + nb_cpus = sysinfo.dwNumberOfProcessors; +#endif + + if (!printed) { + av_log(NULL, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus); + printed = 1; + } + + return nb_cpus; +} + +size_t av_cpu_max_align(void) +{ + if (ARCH_AARCH64) + return ff_get_cpu_max_align_aarch64(); + if (ARCH_ARM) + return ff_get_cpu_max_align_arm(); + if (ARCH_PPC) + return ff_get_cpu_max_align_ppc(); + if (ARCH_X86) + return ff_get_cpu_max_align_x86(); + + return 8; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.h new file mode 100644 index 000000000..8bb9eb606 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CPU_H +#define AVUTIL_CPU_H + +#include + +#include "attributes.h" + +#define AV_CPU_FLAG_FORCE 0x80000000 /* force usage of selected flags (OR) */ + + /* lower 16 bits - CPU features */ +#define AV_CPU_FLAG_MMX 0x0001 ///< standard MMX +#define AV_CPU_FLAG_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext +#define AV_CPU_FLAG_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext +#define AV_CPU_FLAG_3DNOW 0x0004 ///< AMD 3DNOW +#define AV_CPU_FLAG_SSE 0x0008 ///< SSE functions +#define AV_CPU_FLAG_SSE2 0x0010 ///< PIV SSE2 functions +#define AV_CPU_FLAG_SSE2SLOW 0x40000000 ///< SSE2 supported, but usually not faster + ///< than regular MMX/SSE (e.g. Core1) +#define AV_CPU_FLAG_3DNOWEXT 0x0020 ///< AMD 3DNowExt +#define AV_CPU_FLAG_SSE3 0x0040 ///< Prescott SSE3 functions +#define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster + ///< than regular MMX/SSE (e.g. Core1) +#define AV_CPU_FLAG_SSSE3 0x0080 ///< Conroe SSSE3 functions +#define AV_CPU_FLAG_SSSE3SLOW 0x4000000 ///< SSSE3 supported, but usually not faster +#define AV_CPU_FLAG_ATOM 0x10000000 ///< Atom processor, some SSSE3 instructions are slower +#define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions +#define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions +#define AV_CPU_FLAG_AESNI 0x80000 ///< Advanced Encryption Standard functions +#define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used +#define AV_CPU_FLAG_AVXSLOW 0x8000000 ///< AVX supported, but slow when using YMM registers (e.g. Bulldozer) +#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions +#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions +#define AV_CPU_FLAG_CMOV 0x1000 ///< supports cmov instruction +#define AV_CPU_FLAG_AVX2 0x8000 ///< AVX2 functions: requires OS support even if YMM registers aren't used +#define AV_CPU_FLAG_FMA3 0x10000 ///< Haswell FMA3 functions +#define AV_CPU_FLAG_BMI1 0x20000 ///< Bit Manipulation Instruction Set 1 +#define AV_CPU_FLAG_BMI2 0x40000 ///< Bit Manipulation Instruction Set 2 +#define AV_CPU_FLAG_AVX512 0x100000 ///< AVX-512 functions: requires OS support even if YMM/ZMM registers aren't used + +#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard +#define AV_CPU_FLAG_VSX 0x0002 ///< ISA 2.06 +#define AV_CPU_FLAG_POWER8 0x0004 ///< ISA 2.07 + +#define AV_CPU_FLAG_ARMV5TE (1 << 0) +#define AV_CPU_FLAG_ARMV6 (1 << 1) +#define AV_CPU_FLAG_ARMV6T2 (1 << 2) +#define AV_CPU_FLAG_VFP (1 << 3) +#define AV_CPU_FLAG_VFPV3 (1 << 4) +#define AV_CPU_FLAG_NEON (1 << 5) +#define AV_CPU_FLAG_ARMV8 (1 << 6) +#define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations +#define AV_CPU_FLAG_SETEND (1 <<16) + +/** + * Return the flags which specify extensions supported by the CPU. + * The returned value is affected by av_force_cpu_flags() if that was used + * before. So av_get_cpu_flags() can easily be used in an application to + * detect the enabled cpu flags. + */ +int av_get_cpu_flags(void); + +/** + * Disables cpu detection and forces the specified flags. + * -1 is a special case that disables forcing of specific flags. + */ +void av_force_cpu_flags(int flags); + +/** + * Set a mask on flags returned by av_get_cpu_flags(). + * This function is mainly useful for testing. + * Please use av_force_cpu_flags() and av_get_cpu_flags() instead which are more flexible + */ +attribute_deprecated void av_set_cpu_flags_mask(int mask); + +/** + * Parse CPU flags from a string. + * + * The returned flags contain the specified flags as well as related unspecified flags. + * + * This function exists only for compatibility with libav. + * Please use av_parse_cpu_caps() when possible. + * @return a combination of AV_CPU_* flags, negative on error. + */ +attribute_deprecated +int av_parse_cpu_flags(const char *s); + +/** + * Parse CPU caps from a string and update the given AV_CPU_* flags based on that. + * + * @return negative on error. + */ +int av_parse_cpu_caps(unsigned *flags, const char *s); + +/** + * @return the number of logical CPU cores present. + */ +int av_cpu_count(void); + +/** + * Get the maximum data alignment that may be required by FFmpeg. + * + * Note that this is affected by the build configuration and the CPU flags mask, + * so e.g. if the CPU supports AVX, but libavutil has been built with + * --disable-avx or the AV_CPU_FLAG_AVX flag has been disabled through + * av_set_cpu_flags_mask(), then this function will behave as if AVX is not + * present. + */ +size_t av_cpu_max_align(void); + +#endif /* AVUTIL_CPU_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu_internal.h new file mode 100644 index 000000000..37122d1c5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/cpu_internal.h @@ -0,0 +1,54 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CPU_INTERNAL_H +#define AVUTIL_CPU_INTERNAL_H + +#include "config.h" + +#include "cpu.h" + +#define CPUEXT_SUFFIX(flags, suffix, cpuext) \ + (HAVE_ ## cpuext ## suffix && ((flags) & AV_CPU_FLAG_ ## cpuext)) + +#define CPUEXT_SUFFIX_FAST2(flags, suffix, cpuext, slow_cpuext) \ + (HAVE_ ## cpuext ## suffix && ((flags) & AV_CPU_FLAG_ ## cpuext) && \ + !((flags) & AV_CPU_FLAG_ ## slow_cpuext ## SLOW)) + +#define CPUEXT_SUFFIX_SLOW2(flags, suffix, cpuext, slow_cpuext) \ + (HAVE_ ## cpuext ## suffix && ((flags) & AV_CPU_FLAG_ ## cpuext) && \ + ((flags) & AV_CPU_FLAG_ ## slow_cpuext ## SLOW)) + +#define CPUEXT_SUFFIX_FAST(flags, suffix, cpuext) CPUEXT_SUFFIX_FAST2(flags, suffix, cpuext, cpuext) +#define CPUEXT_SUFFIX_SLOW(flags, suffix, cpuext) CPUEXT_SUFFIX_SLOW2(flags, suffix, cpuext, cpuext) + +#define CPUEXT(flags, cpuext) CPUEXT_SUFFIX(flags, , cpuext) +#define CPUEXT_FAST(flags, cpuext) CPUEXT_SUFFIX_FAST(flags, , cpuext) +#define CPUEXT_SLOW(flags, cpuext) CPUEXT_SUFFIX_SLOW(flags, , cpuext) + +int ff_get_cpu_flags_aarch64(void); +int ff_get_cpu_flags_arm(void); +int ff_get_cpu_flags_ppc(void); +int ff_get_cpu_flags_x86(void); + +size_t ff_get_cpu_max_align_aarch64(void); +size_t ff_get_cpu_max_align_arm(void); +size_t ff_get_cpu_max_align_ppc(void); +size_t ff_get_cpu_max_align_x86(void); + +#endif /* AVUTIL_CPU_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.c new file mode 100644 index 000000000..c45ea63a6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.c @@ -0,0 +1,415 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "thread.h" +#include "avassert.h" +#include "bswap.h" +#include "common.h" +#include "crc.h" + +#if CONFIG_HARDCODED_TABLES +static const AVCRC av_crc_table[AV_CRC_MAX][257] = { + [AV_CRC_8_ATM] = { + 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, + 0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, + 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, + 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, + 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, + 0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, + 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE, + 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, + 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, + 0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, + 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, + 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, + 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, + 0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, + 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10, + 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, + 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, + 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, + 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7, + 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, + 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, + 0xFA, 0xFD, 0xF4, 0xF3, 0x01 + }, + [AV_CRC_8_EBU] = { + 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, + 0x9C, 0x81, 0xA6, 0xBB, 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, + 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 0x87, 0x9A, 0xBD, 0xA0, + 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, + 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, + 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, + 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, + 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, + 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, + 0x08, 0x15, 0x32, 0x2F, 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, + 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 0x26, 0x3B, 0x1C, 0x01, + 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, + 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, + 0x77, 0x6A, 0x4D, 0x50, 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, + 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B, + 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, + 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, + 0xA9, 0xB4, 0x93, 0x8E, 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, + 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88, 0x95, + 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, + 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, + 0xE3, 0xFE, 0xD9, 0xC4, 0x01 + }, + [AV_CRC_16_ANSI] = { + 0x0000, 0x0580, 0x0F80, 0x0A00, 0x1B80, 0x1E00, 0x1400, 0x1180, + 0x3380, 0x3600, 0x3C00, 0x3980, 0x2800, 0x2D80, 0x2780, 0x2200, + 0x6380, 0x6600, 0x6C00, 0x6980, 0x7800, 0x7D80, 0x7780, 0x7200, + 0x5000, 0x5580, 0x5F80, 0x5A00, 0x4B80, 0x4E00, 0x4400, 0x4180, + 0xC380, 0xC600, 0xCC00, 0xC980, 0xD800, 0xDD80, 0xD780, 0xD200, + 0xF000, 0xF580, 0xFF80, 0xFA00, 0xEB80, 0xEE00, 0xE400, 0xE180, + 0xA000, 0xA580, 0xAF80, 0xAA00, 0xBB80, 0xBE00, 0xB400, 0xB180, + 0x9380, 0x9600, 0x9C00, 0x9980, 0x8800, 0x8D80, 0x8780, 0x8200, + 0x8381, 0x8601, 0x8C01, 0x8981, 0x9801, 0x9D81, 0x9781, 0x9201, + 0xB001, 0xB581, 0xBF81, 0xBA01, 0xAB81, 0xAE01, 0xA401, 0xA181, + 0xE001, 0xE581, 0xEF81, 0xEA01, 0xFB81, 0xFE01, 0xF401, 0xF181, + 0xD381, 0xD601, 0xDC01, 0xD981, 0xC801, 0xCD81, 0xC781, 0xC201, + 0x4001, 0x4581, 0x4F81, 0x4A01, 0x5B81, 0x5E01, 0x5401, 0x5181, + 0x7381, 0x7601, 0x7C01, 0x7981, 0x6801, 0x6D81, 0x6781, 0x6201, + 0x2381, 0x2601, 0x2C01, 0x2981, 0x3801, 0x3D81, 0x3781, 0x3201, + 0x1001, 0x1581, 0x1F81, 0x1A01, 0x0B81, 0x0E01, 0x0401, 0x0181, + 0x0383, 0x0603, 0x0C03, 0x0983, 0x1803, 0x1D83, 0x1783, 0x1203, + 0x3003, 0x3583, 0x3F83, 0x3A03, 0x2B83, 0x2E03, 0x2403, 0x2183, + 0x6003, 0x6583, 0x6F83, 0x6A03, 0x7B83, 0x7E03, 0x7403, 0x7183, + 0x5383, 0x5603, 0x5C03, 0x5983, 0x4803, 0x4D83, 0x4783, 0x4203, + 0xC003, 0xC583, 0xCF83, 0xCA03, 0xDB83, 0xDE03, 0xD403, 0xD183, + 0xF383, 0xF603, 0xFC03, 0xF983, 0xE803, 0xED83, 0xE783, 0xE203, + 0xA383, 0xA603, 0xAC03, 0xA983, 0xB803, 0xBD83, 0xB783, 0xB203, + 0x9003, 0x9583, 0x9F83, 0x9A03, 0x8B83, 0x8E03, 0x8403, 0x8183, + 0x8002, 0x8582, 0x8F82, 0x8A02, 0x9B82, 0x9E02, 0x9402, 0x9182, + 0xB382, 0xB602, 0xBC02, 0xB982, 0xA802, 0xAD82, 0xA782, 0xA202, + 0xE382, 0xE602, 0xEC02, 0xE982, 0xF802, 0xFD82, 0xF782, 0xF202, + 0xD002, 0xD582, 0xDF82, 0xDA02, 0xCB82, 0xCE02, 0xC402, 0xC182, + 0x4382, 0x4602, 0x4C02, 0x4982, 0x5802, 0x5D82, 0x5782, 0x5202, + 0x7002, 0x7582, 0x7F82, 0x7A02, 0x6B82, 0x6E02, 0x6402, 0x6182, + 0x2002, 0x2582, 0x2F82, 0x2A02, 0x3B82, 0x3E02, 0x3402, 0x3182, + 0x1382, 0x1602, 0x1C02, 0x1982, 0x0802, 0x0D82, 0x0782, 0x0202, + 0x0001 + }, + [AV_CRC_16_CCITT] = { + 0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xA550, 0xC660, 0xE770, + 0x0881, 0x2991, 0x4AA1, 0x6BB1, 0x8CC1, 0xADD1, 0xCEE1, 0xEFF1, + 0x3112, 0x1002, 0x7332, 0x5222, 0xB552, 0x9442, 0xF772, 0xD662, + 0x3993, 0x1883, 0x7BB3, 0x5AA3, 0xBDD3, 0x9CC3, 0xFFF3, 0xDEE3, + 0x6224, 0x4334, 0x2004, 0x0114, 0xE664, 0xC774, 0xA444, 0x8554, + 0x6AA5, 0x4BB5, 0x2885, 0x0995, 0xEEE5, 0xCFF5, 0xACC5, 0x8DD5, + 0x5336, 0x7226, 0x1116, 0x3006, 0xD776, 0xF666, 0x9556, 0xB446, + 0x5BB7, 0x7AA7, 0x1997, 0x3887, 0xDFF7, 0xFEE7, 0x9DD7, 0xBCC7, + 0xC448, 0xE558, 0x8668, 0xA778, 0x4008, 0x6118, 0x0228, 0x2338, + 0xCCC9, 0xEDD9, 0x8EE9, 0xAFF9, 0x4889, 0x6999, 0x0AA9, 0x2BB9, + 0xF55A, 0xD44A, 0xB77A, 0x966A, 0x711A, 0x500A, 0x333A, 0x122A, + 0xFDDB, 0xDCCB, 0xBFFB, 0x9EEB, 0x799B, 0x588B, 0x3BBB, 0x1AAB, + 0xA66C, 0x877C, 0xE44C, 0xC55C, 0x222C, 0x033C, 0x600C, 0x411C, + 0xAEED, 0x8FFD, 0xECCD, 0xCDDD, 0x2AAD, 0x0BBD, 0x688D, 0x499D, + 0x977E, 0xB66E, 0xD55E, 0xF44E, 0x133E, 0x322E, 0x511E, 0x700E, + 0x9FFF, 0xBEEF, 0xDDDF, 0xFCCF, 0x1BBF, 0x3AAF, 0x599F, 0x788F, + 0x8891, 0xA981, 0xCAB1, 0xEBA1, 0x0CD1, 0x2DC1, 0x4EF1, 0x6FE1, + 0x8010, 0xA100, 0xC230, 0xE320, 0x0450, 0x2540, 0x4670, 0x6760, + 0xB983, 0x9893, 0xFBA3, 0xDAB3, 0x3DC3, 0x1CD3, 0x7FE3, 0x5EF3, + 0xB102, 0x9012, 0xF322, 0xD232, 0x3542, 0x1452, 0x7762, 0x5672, + 0xEAB5, 0xCBA5, 0xA895, 0x8985, 0x6EF5, 0x4FE5, 0x2CD5, 0x0DC5, + 0xE234, 0xC324, 0xA014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544, + 0xDBA7, 0xFAB7, 0x9987, 0xB897, 0x5FE7, 0x7EF7, 0x1DC7, 0x3CD7, + 0xD326, 0xF236, 0x9106, 0xB016, 0x5766, 0x7676, 0x1546, 0x3456, + 0x4CD9, 0x6DC9, 0x0EF9, 0x2FE9, 0xC899, 0xE989, 0x8AB9, 0xABA9, + 0x4458, 0x6548, 0x0678, 0x2768, 0xC018, 0xE108, 0x8238, 0xA328, + 0x7DCB, 0x5CDB, 0x3FEB, 0x1EFB, 0xF98B, 0xD89B, 0xBBAB, 0x9ABB, + 0x754A, 0x545A, 0x376A, 0x167A, 0xF10A, 0xD01A, 0xB32A, 0x923A, + 0x2EFD, 0x0FED, 0x6CDD, 0x4DCD, 0xAABD, 0x8BAD, 0xE89D, 0xC98D, + 0x267C, 0x076C, 0x645C, 0x454C, 0xA23C, 0x832C, 0xE01C, 0xC10C, + 0x1FEF, 0x3EFF, 0x5DCF, 0x7CDF, 0x9BAF, 0xBABF, 0xD98F, 0xF89F, + 0x176E, 0x367E, 0x554E, 0x745E, 0x932E, 0xB23E, 0xD10E, 0xF01E, + 0x0001 + }, + [AV_CRC_24_IEEE] = { + 0x000000, 0xFB4C86, 0x0DD58A, 0xF6990C, 0xE1E693, 0x1AAA15, 0xEC3319, + 0x177F9F, 0x3981A1, 0xC2CD27, 0x34542B, 0xCF18AD, 0xD86732, 0x232BB4, + 0xD5B2B8, 0x2EFE3E, 0x894EC5, 0x720243, 0x849B4F, 0x7FD7C9, 0x68A856, + 0x93E4D0, 0x657DDC, 0x9E315A, 0xB0CF64, 0x4B83E2, 0xBD1AEE, 0x465668, + 0x5129F7, 0xAA6571, 0x5CFC7D, 0xA7B0FB, 0xE9D10C, 0x129D8A, 0xE40486, + 0x1F4800, 0x08379F, 0xF37B19, 0x05E215, 0xFEAE93, 0xD050AD, 0x2B1C2B, + 0xDD8527, 0x26C9A1, 0x31B63E, 0xCAFAB8, 0x3C63B4, 0xC72F32, 0x609FC9, + 0x9BD34F, 0x6D4A43, 0x9606C5, 0x81795A, 0x7A35DC, 0x8CACD0, 0x77E056, + 0x591E68, 0xA252EE, 0x54CBE2, 0xAF8764, 0xB8F8FB, 0x43B47D, 0xB52D71, + 0x4E61F7, 0xD2A319, 0x29EF9F, 0xDF7693, 0x243A15, 0x33458A, 0xC8090C, + 0x3E9000, 0xC5DC86, 0xEB22B8, 0x106E3E, 0xE6F732, 0x1DBBB4, 0x0AC42B, + 0xF188AD, 0x0711A1, 0xFC5D27, 0x5BEDDC, 0xA0A15A, 0x563856, 0xAD74D0, + 0xBA0B4F, 0x4147C9, 0xB7DEC5, 0x4C9243, 0x626C7D, 0x9920FB, 0x6FB9F7, + 0x94F571, 0x838AEE, 0x78C668, 0x8E5F64, 0x7513E2, 0x3B7215, 0xC03E93, + 0x36A79F, 0xCDEB19, 0xDA9486, 0x21D800, 0xD7410C, 0x2C0D8A, 0x02F3B4, + 0xF9BF32, 0x0F263E, 0xF46AB8, 0xE31527, 0x1859A1, 0xEEC0AD, 0x158C2B, + 0xB23CD0, 0x497056, 0xBFE95A, 0x44A5DC, 0x53DA43, 0xA896C5, 0x5E0FC9, + 0xA5434F, 0x8BBD71, 0x70F1F7, 0x8668FB, 0x7D247D, 0x6A5BE2, 0x911764, + 0x678E68, 0x9CC2EE, 0xA44733, 0x5F0BB5, 0xA992B9, 0x52DE3F, 0x45A1A0, + 0xBEED26, 0x48742A, 0xB338AC, 0x9DC692, 0x668A14, 0x901318, 0x6B5F9E, + 0x7C2001, 0x876C87, 0x71F58B, 0x8AB90D, 0x2D09F6, 0xD64570, 0x20DC7C, + 0xDB90FA, 0xCCEF65, 0x37A3E3, 0xC13AEF, 0x3A7669, 0x148857, 0xEFC4D1, + 0x195DDD, 0xE2115B, 0xF56EC4, 0x0E2242, 0xF8BB4E, 0x03F7C8, 0x4D963F, + 0xB6DAB9, 0x4043B5, 0xBB0F33, 0xAC70AC, 0x573C2A, 0xA1A526, 0x5AE9A0, + 0x74179E, 0x8F5B18, 0x79C214, 0x828E92, 0x95F10D, 0x6EBD8B, 0x982487, + 0x636801, 0xC4D8FA, 0x3F947C, 0xC90D70, 0x3241F6, 0x253E69, 0xDE72EF, + 0x28EBE3, 0xD3A765, 0xFD595B, 0x0615DD, 0xF08CD1, 0x0BC057, 0x1CBFC8, + 0xE7F34E, 0x116A42, 0xEA26C4, 0x76E42A, 0x8DA8AC, 0x7B31A0, 0x807D26, + 0x9702B9, 0x6C4E3F, 0x9AD733, 0x619BB5, 0x4F658B, 0xB4290D, 0x42B001, + 0xB9FC87, 0xAE8318, 0x55CF9E, 0xA35692, 0x581A14, 0xFFAAEF, 0x04E669, + 0xF27F65, 0x0933E3, 0x1E4C7C, 0xE500FA, 0x1399F6, 0xE8D570, 0xC62B4E, + 0x3D67C8, 0xCBFEC4, 0x30B242, 0x27CDDD, 0xDC815B, 0x2A1857, 0xD154D1, + 0x9F3526, 0x6479A0, 0x92E0AC, 0x69AC2A, 0x7ED3B5, 0x859F33, 0x73063F, + 0x884AB9, 0xA6B487, 0x5DF801, 0xAB610D, 0x502D8B, 0x475214, 0xBC1E92, + 0x4A879E, 0xB1CB18, 0x167BE3, 0xED3765, 0x1BAE69, 0xE0E2EF, 0xF79D70, + 0x0CD1F6, 0xFA48FA, 0x01047C, 0x2FFA42, 0xD4B6C4, 0x222FC8, 0xD9634E, + 0xCE1CD1, 0x355057, 0xC3C95B, 0x3885DD, 0x000001, + }, + [AV_CRC_32_IEEE] = { + 0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517, + 0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B, + 0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048, + 0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652, + 0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D, + 0x7A7B9F70, 0xCD665E74, 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095, + 0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486, 0x585B2BBE, 0xEF46EABA, + 0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0, + 0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3, + 0x2220B4CE, 0x953D75CA, 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF, + 0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC, 0x77708634, 0xC06D4730, + 0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A, + 0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05, + 0x7DD00808, 0xCACDC90C, 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475, + 0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066, 0xBF469F5E, 0x085B5E5A, + 0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840, + 0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB, + 0x258B23B6, 0x9296E2B2, 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87, + 0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94, 0xE71DB4E0, 0x500075E4, + 0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE, + 0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1, + 0xEDBD3ADC, 0x5AA0FBD8, 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64, + 0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77, 0x560D044F, 0xE110C54B, + 0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351, + 0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832, + 0x2C769B3F, 0x9B6B5A3B, 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E, + 0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D, 0x0E562FF1, 0xB94BEEF5, + 0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF, + 0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0, + 0x04F6A1CD, 0xB3EB60C9, 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0, + 0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3, 0xC660369B, 0x717DF79F, + 0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185, + 0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A, + 0x2BDD0C47, 0x9CC0CD43, 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176, + 0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565, 0xE94B9B11, 0x5E565A15, + 0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F, + 0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620, + 0xE3EB152D, 0x54F6D429, 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8, + 0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB, 0xC1CBA1E3, 0x76D660E7, + 0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD, + 0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E, + 0xBBB03E93, 0x0CADFF97, 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2, + 0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1, 0x00000001 + }, + [AV_CRC_32_IEEE_LE] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, + 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, + 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, + 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, + 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, + 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, + 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, + 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, + 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, + 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, + 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, + 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, + 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, + 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, + 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, + 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, 0x00000001 + }, + [AV_CRC_16_ANSI_LE] = { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, + 0x0001 + }, +}; +#else +#if CONFIG_SMALL +#define CRC_TABLE_SIZE 257 +#else +#define CRC_TABLE_SIZE 1024 +#endif +static AVCRC av_crc_table[AV_CRC_MAX][CRC_TABLE_SIZE]; + +#define DECLARE_CRC_INIT_TABLE_ONCE(id, le, bits, poly) \ +static AVOnce id ## _once_control = AV_ONCE_INIT; \ +static void id ## _init_table_once(void) \ +{ \ + av_assert0(av_crc_init(av_crc_table[id], le, bits, poly, sizeof(av_crc_table[id])) >= 0); \ +} + +#define CRC_INIT_TABLE_ONCE(id) ff_thread_once(&id ## _once_control, id ## _init_table_once) + +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_8_ATM, 0, 8, 0x07) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_8_EBU, 0, 8, 0x1D) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI, 0, 16, 0x8005) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_CCITT, 0, 16, 0x1021) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_24_IEEE, 0, 24, 0x864CFB) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE, 0, 32, 0x04C11DB7) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE_LE, 1, 32, 0xEDB88320) +DECLARE_CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI_LE, 1, 16, 0xA001) +#endif + +int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size) +{ + unsigned i, j; + uint32_t c; + + if (bits < 8 || bits > 32 || poly >= (1LL << bits)) + return AVERROR(EINVAL); + if (ctx_size != sizeof(AVCRC) * 257 && ctx_size != sizeof(AVCRC) * 1024) + return AVERROR(EINVAL); + + for (i = 0; i < 256; i++) { + if (le) { + for (c = i, j = 0; j < 8; j++) + c = (c >> 1) ^ (poly & (-(c & 1))); + ctx[i] = c; + } else { + for (c = i << 24, j = 0; j < 8; j++) + c = (c << 1) ^ ((poly << (32 - bits)) & (((int32_t) c) >> 31)); + ctx[i] = av_bswap32(c); + } + } + ctx[256] = 1; +#if !CONFIG_SMALL + if (ctx_size >= sizeof(AVCRC) * 1024) + for (i = 0; i < 256; i++) + for (j = 0; j < 3; j++) + ctx[256 * (j + 1) + i] = + (ctx[256 * j + i] >> 8) ^ ctx[ctx[256 * j + i] & 0xFF]; +#endif + + return 0; +} + +const AVCRC *av_crc_get_table(AVCRCId crc_id) +{ +#if !CONFIG_HARDCODED_TABLES + switch (crc_id) { + case AV_CRC_8_ATM: CRC_INIT_TABLE_ONCE(AV_CRC_8_ATM); break; + case AV_CRC_8_EBU: CRC_INIT_TABLE_ONCE(AV_CRC_8_EBU); break; + case AV_CRC_16_ANSI: CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI); break; + case AV_CRC_16_CCITT: CRC_INIT_TABLE_ONCE(AV_CRC_16_CCITT); break; + case AV_CRC_24_IEEE: CRC_INIT_TABLE_ONCE(AV_CRC_24_IEEE); break; + case AV_CRC_32_IEEE: CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE); break; + case AV_CRC_32_IEEE_LE: CRC_INIT_TABLE_ONCE(AV_CRC_32_IEEE_LE); break; + case AV_CRC_16_ANSI_LE: CRC_INIT_TABLE_ONCE(AV_CRC_16_ANSI_LE); break; + default: av_assert0(0); + } +#endif + return av_crc_table[crc_id]; +} + +uint32_t av_crc(const AVCRC *ctx, uint32_t crc, + const uint8_t *buffer, size_t length) +{ + const uint8_t *end = buffer + length; + +#if !CONFIG_SMALL + if (!ctx[256]) { + while (((intptr_t) buffer & 3) && buffer < end) + crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8); + + while (buffer < end - 3) { + crc ^= av_le2ne32(*(const uint32_t *) buffer); buffer += 4; + crc = ctx[3 * 256 + ( crc & 0xFF)] ^ + ctx[2 * 256 + ((crc >> 8 ) & 0xFF)] ^ + ctx[1 * 256 + ((crc >> 16) & 0xFF)] ^ + ctx[0 * 256 + ((crc >> 24) )]; + } + } +#endif + while (buffer < end) + crc = ctx[((uint8_t) crc) ^ *buffer++] ^ (crc >> 8); + + return crc; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.h new file mode 100644 index 000000000..47e22b4c7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/crc.h @@ -0,0 +1,100 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_crc32 + * Public header for CRC hash function implementation. + */ + +#ifndef AVUTIL_CRC_H +#define AVUTIL_CRC_H + +#include +#include +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_crc32 CRC + * @ingroup lavu_hash + * CRC (Cyclic Redundancy Check) hash function implementation. + * + * This module supports numerous CRC polynomials, in addition to the most + * widely used CRC-32-IEEE. See @ref AVCRCId for a list of available + * polynomials. + * + * @{ + */ + +typedef uint32_t AVCRC; + +typedef enum { + AV_CRC_8_ATM, + AV_CRC_16_ANSI, + AV_CRC_16_CCITT, + AV_CRC_32_IEEE, + AV_CRC_32_IEEE_LE, /*< reversed bitorder version of AV_CRC_32_IEEE */ + AV_CRC_16_ANSI_LE, /*< reversed bitorder version of AV_CRC_16_ANSI */ + AV_CRC_24_IEEE, + AV_CRC_8_EBU, + AV_CRC_MAX, /*< Not part of public API! Do not use outside libavutil. */ +}AVCRCId; + +/** + * Initialize a CRC table. + * @param ctx must be an array of size sizeof(AVCRC)*257 or sizeof(AVCRC)*1024 + * @param le If 1, the lowest bit represents the coefficient for the highest + * exponent of the corresponding polynomial (both for poly and + * actual CRC). + * If 0, you must swap the CRC parameter and the result of av_crc + * if you need the standard representation (can be simplified in + * most cases to e.g. bswap16): + * av_bswap32(crc << (32-bits)) + * @param bits number of bits for the CRC + * @param poly generator polynomial without the x**bits coefficient, in the + * representation as specified by le + * @param ctx_size size of ctx in bytes + * @return <0 on failure + */ +int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size); + +/** + * Get an initialized standard CRC table. + * @param crc_id ID of a standard CRC + * @return a pointer to the CRC table or NULL on failure + */ +const AVCRC *av_crc_get_table(AVCRCId crc_id); + +/** + * Calculate the CRC of a block. + * @param crc CRC of previous blocks if any or initial value for CRC + * @return CRC updated with the data from the given block + * + * @see av_crc_init() "le" parameter + */ +uint32_t av_crc(const AVCRC *ctx, uint32_t crc, + const uint8_t *buffer, size_t length) av_pure; + +/** + * @} + */ + +#endif /* AVUTIL_CRC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.c new file mode 100644 index 000000000..695766618 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.c @@ -0,0 +1,331 @@ +/* + * DES encryption/decryption + * Copyright (c) 2007 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "avutil.h" +#include "common.h" +#include "intreadwrite.h" +#include "mem.h" +#include "des.h" + +#define T(a, b, c, d, e, f, g, h) 64 - a, 64 - b, 64 - c, 64 - d, 64 - e, 64 - f, 64 - g, 64 - h +static const uint8_t IP_shuffle[] = { + T(58, 50, 42, 34, 26, 18, 10, 2), + T(60, 52, 44, 36, 28, 20, 12, 4), + T(62, 54, 46, 38, 30, 22, 14, 6), + T(64, 56, 48, 40, 32, 24, 16, 8), + T(57, 49, 41, 33, 25, 17, 9, 1), + T(59, 51, 43, 35, 27, 19, 11, 3), + T(61, 53, 45, 37, 29, 21, 13, 5), + T(63, 55, 47, 39, 31, 23, 15, 7) +}; +#undef T + +#if CONFIG_SMALL || defined(GENTABLES) +#define T(a, b, c, d) 32 - a, 32 - b, 32 - c, 32 - d +static const uint8_t P_shuffle[] = { + T(16, 7, 20, 21), + T(29, 12, 28, 17), + T( 1, 15, 23, 26), + T( 5, 18, 31, 10), + T( 2, 8, 24, 14), + T(32, 27, 3, 9), + T(19, 13, 30, 6), + T(22, 11, 4, 25) +}; +#undef T +#endif + +#define T(a, b, c, d, e, f, g) 64 - a, 64 - b, 64 - c, 64 - d, 64 - e, 64 - f, 64 - g +static const uint8_t PC1_shuffle[] = { + T(57, 49, 41, 33, 25, 17, 9), + T( 1, 58, 50, 42, 34, 26, 18), + T(10, 2, 59, 51, 43, 35, 27), + T(19, 11, 3, 60, 52, 44, 36), + T(63, 55, 47, 39, 31, 23, 15), + T( 7, 62, 54, 46, 38, 30, 22), + T(14, 6, 61, 53, 45, 37, 29), + T(21, 13, 5, 28, 20, 12, 4) +}; +#undef T + +#define T(a, b, c, d, e, f) 56 - a, 56 - b, 56 - c, 56 - d, 56 - e, 56 - f +static const uint8_t PC2_shuffle[] = { + T(14, 17, 11, 24, 1, 5), + T( 3, 28, 15, 6, 21, 10), + T(23, 19, 12, 4, 26, 8), + T(16, 7, 27, 20, 13, 2), + T(41, 52, 31, 37, 47, 55), + T(30, 40, 51, 45, 33, 48), + T(44, 49, 39, 56, 34, 53), + T(46, 42, 50, 36, 29, 32) +}; +#undef T + +#if CONFIG_SMALL +static const uint8_t S_boxes[8][32] = { + { 0x0e, 0xf4, 0x7d, 0x41, 0xe2, 0x2f, 0xdb, 0x18, 0xa3, 0x6a, 0xc6, 0xbc, 0x95, 0x59, 0x30, 0x87, + 0xf4, 0xc1, 0x8e, 0x28, 0x4d, 0x96, 0x12, 0x7b, 0x5f, 0xbc, 0x39, 0xe7, 0xa3, 0x0a, 0x65, 0xd0, }, + { 0x3f, 0xd1, 0x48, 0x7e, 0xf6, 0x2b, 0x83, 0xe4, 0xc9, 0x07, 0x12, 0xad, 0x6c, 0x90, 0xb5, 0x5a, + 0xd0, 0x8e, 0xa7, 0x1b, 0x3a, 0xf4, 0x4d, 0x21, 0xb5, 0x68, 0x7c, 0xc6, 0x09, 0x53, 0xe2, 0x9f, }, + { 0xda, 0x70, 0x09, 0x9e, 0x36, 0x43, 0x6f, 0xa5, 0x21, 0x8d, 0x5c, 0xe7, 0xcb, 0xb4, 0xf2, 0x18, + 0x1d, 0xa6, 0xd4, 0x09, 0x68, 0x9f, 0x83, 0x70, 0x4b, 0xf1, 0xe2, 0x3c, 0xb5, 0x5a, 0x2e, 0xc7, }, + { 0xd7, 0x8d, 0xbe, 0x53, 0x60, 0xf6, 0x09, 0x3a, 0x41, 0x72, 0x28, 0xc5, 0x1b, 0xac, 0xe4, 0x9f, + 0x3a, 0xf6, 0x09, 0x60, 0xac, 0x1b, 0xd7, 0x8d, 0x9f, 0x41, 0x53, 0xbe, 0xc5, 0x72, 0x28, 0xe4, }, + { 0xe2, 0xbc, 0x24, 0xc1, 0x47, 0x7a, 0xdb, 0x16, 0x58, 0x05, 0xf3, 0xaf, 0x3d, 0x90, 0x8e, 0x69, + 0xb4, 0x82, 0xc1, 0x7b, 0x1a, 0xed, 0x27, 0xd8, 0x6f, 0xf9, 0x0c, 0x95, 0xa6, 0x43, 0x50, 0x3e, }, + { 0xac, 0xf1, 0x4a, 0x2f, 0x79, 0xc2, 0x96, 0x58, 0x60, 0x1d, 0xd3, 0xe4, 0x0e, 0xb7, 0x35, 0x8b, + 0x49, 0x3e, 0x2f, 0xc5, 0x92, 0x58, 0xfc, 0xa3, 0xb7, 0xe0, 0x14, 0x7a, 0x61, 0x0d, 0x8b, 0xd6, }, + { 0xd4, 0x0b, 0xb2, 0x7e, 0x4f, 0x90, 0x18, 0xad, 0xe3, 0x3c, 0x59, 0xc7, 0x25, 0xfa, 0x86, 0x61, + 0x61, 0xb4, 0xdb, 0x8d, 0x1c, 0x43, 0xa7, 0x7e, 0x9a, 0x5f, 0x06, 0xf8, 0xe0, 0x25, 0x39, 0xc2, }, + { 0x1d, 0xf2, 0xd8, 0x84, 0xa6, 0x3f, 0x7b, 0x41, 0xca, 0x59, 0x63, 0xbe, 0x05, 0xe0, 0x9c, 0x27, + 0x27, 0x1b, 0xe4, 0x71, 0x49, 0xac, 0x8e, 0xd2, 0xf0, 0xc6, 0x9a, 0x0d, 0x3f, 0x53, 0x65, 0xb8, + } +}; +#else +/** + * This table contains the results of applying both the S-box and P-shuffle. + * It can be regenerated by compiling tests/des.c with "-DCONFIG_SMALL -DGENTABLES". + */ +static const uint32_t S_boxes_P_shuffle[8][64] = { + { 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000, + 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002, + 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202, + 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000, + 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200, + 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202, + 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200, + 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002, }, + { 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010, + 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010, + 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000, + 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010, + 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000, + 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000, + 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010, + 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000, }, + { 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100, + 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104, + 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104, + 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000, + 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000, + 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004, + 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004, + 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100, }, + { 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000, + 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000, + 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040, + 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040, + 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000, + 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040, + 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040, }, + { 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000, + 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000, + 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080, + 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080, + 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080, + 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000, + 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000, + 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080, }, + { 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000, + 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008, + 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008, + 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000, + 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008, + 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000, + 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008, + 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008, }, + { 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400, + 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401, + 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001, + 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400, + 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001, + 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400, + 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401, + 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001, }, + { 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000, + 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020, + 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800, + 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000, + 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820, + 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820, + 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000, + 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800, }, +}; +#endif + +static uint64_t shuffle(uint64_t in, const uint8_t *shuffle, int shuffle_len) +{ + int i; + uint64_t res = 0; + for (i = 0; i < shuffle_len; i++) + res += res + ((in >> *shuffle++) & 1); + return res; +} + +static uint64_t shuffle_inv(uint64_t in, const uint8_t *shuffle, int shuffle_len) +{ + int i; + uint64_t res = 0; + shuffle += shuffle_len - 1; + for (i = 0; i < shuffle_len; i++) { + res |= (in & 1) << *shuffle--; + in >>= 1; + } + return res; +} + +static uint32_t f_func(uint32_t r, uint64_t k) +{ + int i; + uint32_t out = 0; + // rotate to get first part of E-shuffle in the lowest 6 bits + r = (r << 1) | (r >> 31); + // apply S-boxes, those compress the data again from 8 * 6 to 8 * 4 bits + for (i = 7; i >= 0; i--) { + uint8_t tmp = (r ^ k) & 0x3f; +#if CONFIG_SMALL + uint8_t v = S_boxes[i][tmp >> 1]; + if (tmp & 1) + v >>= 4; + out = (out >> 4) | (v << 28); +#else + out |= S_boxes_P_shuffle[i][tmp]; +#endif + // get next 6 bits of E-shuffle and round key k into the lowest bits + r = (r >> 4) | (r << 28); + k >>= 6; + } +#if CONFIG_SMALL + out = shuffle(out, P_shuffle, sizeof(P_shuffle)); +#endif + return out; +} + +/** + * @brief rotate the two halves of the expanded 56 bit key each 1 bit left + * + * Note: the specification calls this "shift", so I kept it although + * it is confusing. + */ +static uint64_t key_shift_left(uint64_t CDn) +{ + uint64_t carries = (CDn >> 27) & 0x10000001; + CDn <<= 1; + CDn &= ~0x10000001; + CDn |= carries; + return CDn; +} + +static void gen_roundkeys(uint64_t K[16], uint64_t key) +{ + int i; + // discard parity bits from key and shuffle it into C and D parts + uint64_t CDn = shuffle(key, PC1_shuffle, sizeof(PC1_shuffle)); + // generate round keys + for (i = 0; i < 16; i++) { + CDn = key_shift_left(CDn); + if (i > 1 && i != 8 && i != 15) + CDn = key_shift_left(CDn); + K[i] = shuffle(CDn, PC2_shuffle, sizeof(PC2_shuffle)); + } +} + +static uint64_t des_encdec(uint64_t in, uint64_t K[16], int decrypt) +{ + int i; + // used to apply round keys in reverse order for decryption + decrypt = decrypt ? 15 : 0; + // shuffle irrelevant to security but to ease hardware implementations + in = shuffle(in, IP_shuffle, sizeof(IP_shuffle)); + for (i = 0; i < 16; i++) { + uint32_t f_res; + f_res = f_func(in, K[decrypt ^ i]); + in = (in << 32) | (in >> 32); + in ^= f_res; + } + in = (in << 32) | (in >> 32); + // reverse shuffle used to ease hardware implementations + in = shuffle_inv(in, IP_shuffle, sizeof(IP_shuffle)); + return in; +} + +AVDES *av_des_alloc(void) +{ + return av_mallocz(sizeof(struct AVDES)); +} + +int av_des_init(AVDES *d, const uint8_t *key, int key_bits, av_unused int decrypt) { + if (key_bits != 64 && key_bits != 192) + return AVERROR(EINVAL); + d->triple_des = key_bits > 64; + gen_roundkeys(d->round_keys[0], AV_RB64(key)); + if (d->triple_des) { + gen_roundkeys(d->round_keys[1], AV_RB64(key + 8)); + gen_roundkeys(d->round_keys[2], AV_RB64(key + 16)); + } + return 0; +} + +static void av_des_crypt_mac(AVDES *d, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt, int mac) +{ + uint64_t iv_val = iv ? AV_RB64(iv) : 0; + while (count-- > 0) { + uint64_t dst_val; + uint64_t src_val = src ? AV_RB64(src) : 0; + if (decrypt) { + uint64_t tmp = src_val; + if (d->triple_des) { + src_val = des_encdec(src_val, d->round_keys[2], 1); + src_val = des_encdec(src_val, d->round_keys[1], 0); + } + dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val; + iv_val = iv ? tmp : 0; + } else { + dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0); + if (d->triple_des) { + dst_val = des_encdec(dst_val, d->round_keys[1], 1); + dst_val = des_encdec(dst_val, d->round_keys[2], 0); + } + iv_val = iv ? dst_val : 0; + } + AV_WB64(dst, dst_val); + src += 8; + if (!mac) + dst += 8; + } + if (iv) + AV_WB64(iv, iv_val); +} + +void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt) +{ + av_des_crypt_mac(d, dst, src, count, iv, decrypt, 0); +} + +void av_des_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count) +{ + av_des_crypt_mac(d, dst, src, count, (uint8_t[8]) { 0 }, 0, 1); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.h new file mode 100644 index 000000000..4cf11f5bc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/des.h @@ -0,0 +1,77 @@ +/* + * DES encryption/decryption + * Copyright (c) 2007 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DES_H +#define AVUTIL_DES_H + +#include + +/** + * @defgroup lavu_des DES + * @ingroup lavu_crypto + * @{ + */ + +typedef struct AVDES { + uint64_t round_keys[3][16]; + int triple_des; +} AVDES; + +/** + * Allocate an AVDES context. + */ +AVDES *av_des_alloc(void); + +/** + * @brief Initializes an AVDES context. + * + * @param key_bits must be 64 or 192 + * @param decrypt 0 for encryption/CBC-MAC, 1 for decryption + * @return zero on success, negative value otherwise + */ +int av_des_init(struct AVDES *d, const uint8_t *key, int key_bits, int decrypt); + +/** + * @brief Encrypts / decrypts using the DES algorithm. + * + * @param count number of 8 byte blocks + * @param dst destination array, can be equal to src, must be 8-byte aligned + * @param src source array, can be equal to dst, must be 8-byte aligned, may be NULL + * @param iv initialization vector for CBC mode, if NULL then ECB will be used, + * must be 8-byte aligned + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_des_crypt(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); + +/** + * @brief Calculates CBC-MAC using the DES algorithm. + * + * @param count number of 8 byte blocks + * @param dst destination array, can be equal to src, must be 8-byte aligned + * @param src source array, can be equal to dst, must be 8-byte aligned, may be NULL + */ +void av_des_mac(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count); + +/** + * @} + */ + +#endif /* AVUTIL_DES_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dict.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dict.c new file mode 100644 index 000000000..0ea71386e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dict.c @@ -0,0 +1,272 @@ +/* + * copyright (c) 2009 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "avstring.h" +#include "dict.h" +#include "internal.h" +#include "mem.h" +#include "time_internal.h" +#include "bprint.h" + +struct AVDictionary { + int count; + AVDictionaryEntry *elems; +}; + +int av_dict_count(const AVDictionary *m) +{ + return m ? m->count : 0; +} + +AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key, + const AVDictionaryEntry *prev, int flags) +{ + unsigned int i, j; + + if (!m) + return NULL; + + if (prev) + i = prev - m->elems + 1; + else + i = 0; + + for (; i < m->count; i++) { + const char *s = m->elems[i].key; + if (flags & AV_DICT_MATCH_CASE) + for (j = 0; s[j] == key[j] && key[j]; j++) + ; + else + for (j = 0; av_toupper(s[j]) == av_toupper(key[j]) && key[j]; j++) + ; + if (key[j]) + continue; + if (s[j] && !(flags & AV_DICT_IGNORE_SUFFIX)) + continue; + return &m->elems[i]; + } + return NULL; +} + +int av_dict_set(AVDictionary **pm, const char *key, const char *value, + int flags) +{ + AVDictionary *m = *pm; + AVDictionaryEntry *tag = NULL; + char *oldval = NULL, *copy_key = NULL, *copy_value = NULL; + + if (!(flags & AV_DICT_MULTIKEY)) { + tag = av_dict_get(m, key, NULL, flags); + } + if (flags & AV_DICT_DONT_STRDUP_KEY) + copy_key = (void *)key; + else + copy_key = av_strdup(key); + if (flags & AV_DICT_DONT_STRDUP_VAL) + copy_value = (void *)value; + else if (copy_key) + copy_value = av_strdup(value); + if (!m) + m = *pm = av_mallocz(sizeof(*m)); + if (!m || (key && !copy_key) || (value && !copy_value)) + goto err_out; + + if (tag) { + if (flags & AV_DICT_DONT_OVERWRITE) { + av_free(copy_key); + av_free(copy_value); + return 0; + } + if (flags & AV_DICT_APPEND) + oldval = tag->value; + else + av_free(tag->value); + av_free(tag->key); + *tag = m->elems[--m->count]; + } else if (copy_value) { + AVDictionaryEntry *tmp = av_realloc(m->elems, + (m->count + 1) * sizeof(*m->elems)); + if (!tmp) + goto err_out; + m->elems = tmp; + } + if (copy_value) { + m->elems[m->count].key = copy_key; + m->elems[m->count].value = copy_value; + if (oldval && flags & AV_DICT_APPEND) { + size_t len = strlen(oldval) + strlen(copy_value) + 1; + char *newval = av_mallocz(len); + if (!newval) + goto err_out; + av_strlcat(newval, oldval, len); + av_freep(&oldval); + av_strlcat(newval, copy_value, len); + m->elems[m->count].value = newval; + av_freep(©_value); + } + m->count++; + } else { + av_freep(©_key); + } + if (!m->count) { + av_freep(&m->elems); + av_freep(pm); + } + + return 0; + +err_out: + if (m && !m->count) { + av_freep(&m->elems); + av_freep(pm); + } + av_free(copy_key); + av_free(copy_value); + return AVERROR(ENOMEM); +} + +int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, + int flags) +{ + char valuestr[22]; + snprintf(valuestr, sizeof(valuestr), "%"PRId64, value); + flags &= ~AV_DICT_DONT_STRDUP_VAL; + return av_dict_set(pm, key, valuestr, flags); +} + +static int parse_key_value_pair(AVDictionary **pm, const char **buf, + const char *key_val_sep, const char *pairs_sep, + int flags) +{ + char *key = av_get_token(buf, key_val_sep); + char *val = NULL; + int ret; + + if (key && *key && strspn(*buf, key_val_sep)) { + (*buf)++; + val = av_get_token(buf, pairs_sep); + } + + if (key && *key && val && *val) + ret = av_dict_set(pm, key, val, flags); + else + ret = AVERROR(EINVAL); + + av_freep(&key); + av_freep(&val); + + return ret; +} + +int av_dict_parse_string(AVDictionary **pm, const char *str, + const char *key_val_sep, const char *pairs_sep, + int flags) +{ + int ret; + + if (!str) + return 0; + + /* ignore STRDUP flags */ + flags &= ~(AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); + + while (*str) { + if ((ret = parse_key_value_pair(pm, &str, key_val_sep, pairs_sep, flags)) < 0) + return ret; + + if (*str) + str++; + } + + return 0; +} + +void av_dict_free(AVDictionary **pm) +{ + AVDictionary *m = *pm; + + if (m) { + while (m->count--) { + av_freep(&m->elems[m->count].key); + av_freep(&m->elems[m->count].value); + } + av_freep(&m->elems); + } + av_freep(pm); +} + +int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags) +{ + AVDictionaryEntry *t = NULL; + + while ((t = av_dict_get(src, "", t, AV_DICT_IGNORE_SUFFIX))) { + int ret = av_dict_set(dst, t->key, t->value, flags); + if (ret < 0) + return ret; + } + + return 0; +} + +int av_dict_get_string(const AVDictionary *m, char **buffer, + const char key_val_sep, const char pairs_sep) +{ + AVDictionaryEntry *t = NULL; + AVBPrint bprint; + int cnt = 0; + char special_chars[] = {pairs_sep, key_val_sep, '\0'}; + + if (!buffer || pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep || + pairs_sep == '\\' || key_val_sep == '\\') + return AVERROR(EINVAL); + + if (!av_dict_count(m)) { + *buffer = av_strdup(""); + return *buffer ? 0 : AVERROR(ENOMEM); + } + + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); + while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) { + if (cnt++) + av_bprint_append_data(&bprint, &pairs_sep, 1); + av_bprint_escape(&bprint, t->key, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + av_bprint_append_data(&bprint, &key_val_sep, 1); + av_bprint_escape(&bprint, t->value, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + } + return av_bprint_finalize(&bprint, buffer); +} + +int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp) +{ + time_t seconds = timestamp / 1000000; + struct tm *ptm, tmbuf; + ptm = gmtime_r(&seconds, &tmbuf); + if (ptm) { + char buf[32]; + if (!strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", ptm)) + return AVERROR_EXTERNAL; + av_strlcatf(buf, sizeof(buf), ".%06dZ", (int)(timestamp % 1000000)); + return av_dict_set(dict, key, buf, 0); + } else { + return AVERROR_EXTERNAL; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dict.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dict.h new file mode 100644 index 000000000..118f1f00e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dict.h @@ -0,0 +1,200 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Public dictionary API. + * @deprecated + * AVDictionary is provided for compatibility with libav. It is both in + * implementation as well as API inefficient. It does not scale and is + * extremely slow with large dictionaries. + * It is recommended that new code uses our tree container from tree.c/h + * where applicable, which uses AVL trees to achieve O(log n) performance. + */ + +#ifndef AVUTIL_DICT_H +#define AVUTIL_DICT_H + +#include + +#include "version.h" + +/** + * @addtogroup lavu_dict AVDictionary + * @ingroup lavu_data + * + * @brief Simple key:value store + * + * @{ + * Dictionaries are used for storing key:value pairs. To create + * an AVDictionary, simply pass an address of a NULL pointer to + * av_dict_set(). NULL can be used as an empty dictionary wherever + * a pointer to an AVDictionary is required. + * Use av_dict_get() to retrieve an entry or iterate over all + * entries and finally av_dict_free() to free the dictionary + * and all its contents. + * + @code + AVDictionary *d = NULL; // "create" an empty dictionary + AVDictionaryEntry *t = NULL; + + av_dict_set(&d, "foo", "bar", 0); // add an entry + + char *k = av_strdup("key"); // if your strings are already allocated, + char *v = av_strdup("value"); // you can avoid copying them like this + av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); + + while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)) { + <....> // iterate over all entries in d + } + av_dict_free(&d); + @endcode + */ + +#define AV_DICT_MATCH_CASE 1 /**< Only get an entry with exact-case key match. Only relevant in av_dict_get(). */ +#define AV_DICT_IGNORE_SUFFIX 2 /**< Return first entry in a dictionary whose first part corresponds to the search key, + ignoring the suffix of the found key string. Only relevant in av_dict_get(). */ +#define AV_DICT_DONT_STRDUP_KEY 4 /**< Take ownership of a key that's been + allocated with av_malloc() or another memory allocation function. */ +#define AV_DICT_DONT_STRDUP_VAL 8 /**< Take ownership of a value that's been + allocated with av_malloc() or another memory allocation function. */ +#define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries. +#define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no + delimiter is added, the strings are simply concatenated. */ +#define AV_DICT_MULTIKEY 64 /**< Allow to store several equal keys in the dictionary */ + +typedef struct AVDictionaryEntry { + char *key; + char *value; +} AVDictionaryEntry; + +typedef struct AVDictionary AVDictionary; + +/** + * Get a dictionary entry with matching key. + * + * The returned entry key or value must not be changed, or it will + * cause undefined behavior. + * + * To iterate through all the dictionary entries, you can set the matching key + * to the null string "" and set the AV_DICT_IGNORE_SUFFIX flag. + * + * @param prev Set to the previous matching element to find the next. + * If set to NULL the first matching element is returned. + * @param key matching key + * @param flags a collection of AV_DICT_* flags controlling how the entry is retrieved + * @return found entry or NULL in case no matching entry was found in the dictionary + */ +AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key, + const AVDictionaryEntry *prev, int flags); + +/** + * Get number of entries in dictionary. + * + * @param m dictionary + * @return number of entries in dictionary + */ +int av_dict_count(const AVDictionary *m); + +/** + * Set the given entry in *pm, overwriting an existing entry. + * + * Note: If AV_DICT_DONT_STRDUP_KEY or AV_DICT_DONT_STRDUP_VAL is set, + * these arguments will be freed on error. + * + * Warning: Adding a new entry to a dictionary invalidates all existing entries + * previously returned with av_dict_get. + * + * @param pm pointer to a pointer to a dictionary struct. If *pm is NULL + * a dictionary struct is allocated and put in *pm. + * @param key entry key to add to *pm (will either be av_strduped or added as a new key depending on flags) + * @param value entry value to add to *pm (will be av_strduped or added as a new key depending on flags). + * Passing a NULL value will cause an existing entry to be deleted. + * @return >= 0 on success otherwise an error code <0 + */ +int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags); + +/** + * Convenience wrapper for av_dict_set that converts the value to a string + * and stores it. + * + * Note: If AV_DICT_DONT_STRDUP_KEY is set, key will be freed on error. + */ +int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags); + +/** + * Parse the key/value pairs list and add the parsed entries to a dictionary. + * + * In case of failure, all the successfully set entries are stored in + * *pm. You may need to manually free the created dictionary. + * + * @param key_val_sep a 0-terminated list of characters used to separate + * key from value + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other + * @param flags flags to use when adding to dictionary. + * AV_DICT_DONT_STRDUP_KEY and AV_DICT_DONT_STRDUP_VAL + * are ignored since the key/value tokens will always + * be duplicated. + * @return 0 on success, negative AVERROR code on failure + */ +int av_dict_parse_string(AVDictionary **pm, const char *str, + const char *key_val_sep, const char *pairs_sep, + int flags); + +/** + * Copy entries from one AVDictionary struct into another. + * @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL, + * this function will allocate a struct for you and put it in *dst + * @param src pointer to source AVDictionary struct + * @param flags flags to use when setting entries in *dst + * @note metadata is read using the AV_DICT_IGNORE_SUFFIX flag + * @return 0 on success, negative AVERROR code on failure. If dst was allocated + * by this function, callers should free the associated memory. + */ +int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags); + +/** + * Free all the memory allocated for an AVDictionary struct + * and all keys and values. + */ +void av_dict_free(AVDictionary **m); + +/** + * Get dictionary entries as a string. + * + * Create a string containing dictionary's entries. + * Such string may be passed back to av_dict_parse_string(). + * @note String is escaped with backslashes ('\'). + * + * @param[in] m dictionary + * @param[out] buffer Pointer to buffer that will be allocated with string containg entries. + * Buffer must be freed by the caller when is no longer needed. + * @param[in] key_val_sep character used to separate key from value + * @param[in] pairs_sep character used to separate two pairs from each other + * @return >= 0 on success, negative on error + * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same. + */ +int av_dict_get_string(const AVDictionary *m, char **buffer, + const char key_val_sep, const char pairs_sep); + +/** + * @} + */ + +#endif /* AVUTIL_DICT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/display.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/display.c new file mode 100644 index 000000000..a0076e067 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/display.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "display.h" +#include "mathematics.h" + +// fixed point to double +#define CONV_FP(x) ((double) (x)) / (1 << 16) + +// double to fixed point +#define CONV_DB(x) (int32_t) ((x) * (1 << 16)) + +double av_display_rotation_get(const int32_t matrix[9]) +{ + double rotation, scale[2]; + + scale[0] = hypot(CONV_FP(matrix[0]), CONV_FP(matrix[3])); + scale[1] = hypot(CONV_FP(matrix[1]), CONV_FP(matrix[4])); + + if (scale[0] == 0.0 || scale[1] == 0.0) + return NAN; + + rotation = atan2(CONV_FP(matrix[1]) / scale[1], + CONV_FP(matrix[0]) / scale[0]) * 180 / M_PI; + + return -rotation; +} + +void av_display_rotation_set(int32_t matrix[9], double angle) +{ + double radians = -angle * M_PI / 180.0f; + double c = cos(radians); + double s = sin(radians); + + memset(matrix, 0, 9 * sizeof(int32_t)); + + matrix[0] = CONV_DB(c); + matrix[1] = CONV_DB(-s); + matrix[3] = CONV_DB(s); + matrix[4] = CONV_DB(c); + matrix[8] = 1 << 30; +} + +void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip) +{ + int i; + const int flip[] = { 1 - 2 * (!!hflip), 1 - 2 * (!!vflip), 1 }; + + if (hflip || vflip) + for (i = 0; i < 9; i++) + matrix[i] *= flip[i % 3]; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/display.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/display.h new file mode 100644 index 000000000..515adad79 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/display.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Display matrix + */ + +#ifndef AVUTIL_DISPLAY_H +#define AVUTIL_DISPLAY_H + +#include +#include "common.h" + +/** + * @addtogroup lavu_video + * @{ + * + * @defgroup lavu_video_display Display transformation matrix functions + * @{ + */ + +/** + * @addtogroup lavu_video_display + * The display transformation matrix specifies an affine transformation that + * should be applied to video frames for correct presentation. It is compatible + * with the matrices stored in the ISO/IEC 14496-12 container format. + * + * The data is a 3x3 matrix represented as a 9-element array: + * + * @code{.unparsed} + * | a b u | + * (a, b, u, c, d, v, x, y, w) -> | c d v | + * | x y w | + * @endcode + * + * All numbers are stored in native endianness, as 16.16 fixed-point values, + * except for u, v and w, which are stored as 2.30 fixed-point values. + * + * The transformation maps a point (p, q) in the source (pre-transformation) + * frame to the point (p', q') in the destination (post-transformation) frame as + * follows: + * + * @code{.unparsed} + * | a b u | + * (p, q, 1) . | c d v | = z * (p', q', 1) + * | x y w | + * @endcode + * + * The transformation can also be more explicitly written in components as + * follows: + * + * @code{.unparsed} + * p' = (a * p + c * q + x) / z; + * q' = (b * p + d * q + y) / z; + * z = u * p + v * q + w + * @endcode + */ + +/** + * Extract the rotation component of the transformation matrix. + * + * @param matrix the transformation matrix + * @return the angle (in degrees) by which the transformation rotates the frame + * counterclockwise. The angle will be in range [-180.0, 180.0], + * or NaN if the matrix is singular. + * + * @note floating point numbers are inherently inexact, so callers are + * recommended to round the return value to nearest integer before use. + */ +double av_display_rotation_get(const int32_t matrix[9]); + +/** + * Initialize a transformation matrix describing a pure counterclockwise + * rotation by the specified angle (in degrees). + * + * @param matrix an allocated transformation matrix (will be fully overwritten + * by this function) + * @param angle rotation angle in degrees. + */ +void av_display_rotation_set(int32_t matrix[9], double angle); + +/** + * Flip the input matrix horizontally and/or vertically. + * + * @param matrix an allocated transformation matrix + * @param hflip whether the matrix should be flipped horizontally + * @param vflip whether the matrix should be flipped vertically + */ +void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_DISPLAY_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/downmix_info.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/downmix_info.c new file mode 100644 index 000000000..c634c6a79 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/downmix_info.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014 Tim Walker + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "downmix_info.h" +#include "frame.h" + +AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data; + + side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO); + + if (!side_data) + side_data = av_frame_new_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO, + sizeof(AVDownmixInfo)); + + if (!side_data) + return NULL; + + return (AVDownmixInfo*)side_data->data; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/downmix_info.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/downmix_info.h new file mode 100644 index 000000000..221cf5bf9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/downmix_info.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014 Tim Walker + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DOWNMIX_INFO_H +#define AVUTIL_DOWNMIX_INFO_H + +#include "frame.h" + +/** + * @file + * audio downmix medatata + */ + +/** + * @addtogroup lavu_audio + * @{ + */ + +/** + * @defgroup downmix_info Audio downmix metadata + * @{ + */ + +/** + * Possible downmix types. + */ +enum AVDownmixType { + AV_DOWNMIX_TYPE_UNKNOWN, /**< Not indicated. */ + AV_DOWNMIX_TYPE_LORO, /**< Lo/Ro 2-channel downmix (Stereo). */ + AV_DOWNMIX_TYPE_LTRT, /**< Lt/Rt 2-channel downmix, Dolby Surround compatible. */ + AV_DOWNMIX_TYPE_DPLII, /**< Lt/Rt 2-channel downmix, Dolby Pro Logic II compatible. */ + AV_DOWNMIX_TYPE_NB /**< Number of downmix types. Not part of ABI. */ +}; + +/** + * This structure describes optional metadata relevant to a downmix procedure. + * + * All fields are set by the decoder to the value indicated in the audio + * bitstream (if present), or to a "sane" default otherwise. + */ +typedef struct AVDownmixInfo { + /** + * Type of downmix preferred by the mastering engineer. + */ + enum AVDownmixType preferred_downmix_type; + + /** + * Absolute scale factor representing the nominal level of the center + * channel during a regular downmix. + */ + double center_mix_level; + + /** + * Absolute scale factor representing the nominal level of the center + * channel during an Lt/Rt compatible downmix. + */ + double center_mix_level_ltrt; + + /** + * Absolute scale factor representing the nominal level of the surround + * channels during a regular downmix. + */ + double surround_mix_level; + + /** + * Absolute scale factor representing the nominal level of the surround + * channels during an Lt/Rt compatible downmix. + */ + double surround_mix_level_ltrt; + + /** + * Absolute scale factor representing the level at which the LFE data is + * mixed into L/R channels during downmixing. + */ + double lfe_mix_level; +} AVDownmixInfo; + +/** + * Get a frame's AV_FRAME_DATA_DOWNMIX_INFO side data for editing. + * + * If the side data is absent, it is created and added to the frame. + * + * @param frame the frame for which the side data is to be obtained or created + * + * @return the AVDownmixInfo structure to be edited by the caller, or NULL if + * the structure cannot be allocated. + */ +AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame); + +/** + * @} + */ + +/** + * @} + */ + +#endif /* AVUTIL_DOWNMIX_INFO_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dynarray.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dynarray.h new file mode 100644 index 000000000..3a7e14642 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/dynarray.h @@ -0,0 +1,70 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FFmpeg; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DYNARRAY_H +#define AVUTIL_DYNARRAY_H + +#include "log.h" +#include "mem.h" + +/** + * Add an element to a dynamic array. + * + * The array is reallocated when its number of elements reaches powers of 2. + * Therefore, the amortized cost of adding an element is constant. + * + * In case of success, the pointer to the array is updated in order to + * point to the new grown array, and the size is incremented. + * + * @param av_size_max maximum size of the array, usually the MAX macro of + * the type of the size + * @param av_elt_size size of the elements in the array, in bytes + * @param av_array pointer to the array, must be a lvalue + * @param av_size size of the array, must be an integer lvalue + * @param av_success statement to execute on success; at this point, the + * size variable is not yet incremented + * @param av_failure statement to execute on failure; if this happens, the + * array and size are not changed; the statement can end + * with a return or a goto + */ +#define FF_DYNARRAY_ADD(av_size_max, av_elt_size, av_array, av_size, \ + av_success, av_failure) \ + do { \ + size_t av_size_new = (av_size); \ + if (!((av_size) & ((av_size) - 1))) { \ + av_size_new = (av_size) ? (av_size) << 1 : 1; \ + if (av_size_new > (av_size_max) / (av_elt_size)) { \ + av_size_new = 0; \ + } else { \ + void *av_array_new = \ + av_realloc((av_array), av_size_new * (av_elt_size)); \ + if (!av_array_new) \ + av_size_new = 0; \ + else \ + (av_array) = av_array_new; \ + } \ + } \ + if (av_size_new) { \ + { av_success } \ + (av_size)++; \ + } else { \ + av_failure \ + } \ + } while (0) + +#endif /* AVUTIL_DYNARRAY_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/encryption_info.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/encryption_info.c new file mode 100644 index 000000000..812c70477 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/encryption_info.c @@ -0,0 +1,339 @@ +/** + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "encryption_info.h" +#include "mem.h" +#include "intreadwrite.h" + +#define FF_ENCRYPTION_INFO_EXTRA 24 + +// The format of the AVEncryptionInfo side data: +// u32be scheme +// u32be crypt_byte_block +// u32be skip_byte_block +// u32be key_id_size +// u32be iv_size +// u32be subsample_count +// u8[key_id_size] key_id +// u8[iv_size] iv +// { +// u32be bytes_of_clear_data +// u32be bytes_of_protected_data +// }[subsample_count] + +AVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size) +{ + AVEncryptionInfo *info; + + info = av_mallocz(sizeof(*info)); + if (!info) + return NULL; + + info->key_id = av_mallocz(key_id_size); + info->key_id_size = key_id_size; + info->iv = av_mallocz(iv_size); + info->iv_size = iv_size; + info->subsamples = av_mallocz_array(subsample_count, sizeof(*info->subsamples)); + info->subsample_count = subsample_count; + + // Allow info->subsamples to be NULL if there are no subsamples. + if (!info->key_id || !info->iv || (!info->subsamples && subsample_count)) { + av_encryption_info_free(info); + return NULL; + } + + return info; +} + +AVEncryptionInfo *av_encryption_info_clone(const AVEncryptionInfo *info) +{ + AVEncryptionInfo *ret; + + ret = av_encryption_info_alloc(info->subsample_count, info->key_id_size, info->iv_size); + if (!ret) + return NULL; + + ret->scheme = info->scheme; + ret->crypt_byte_block = info->crypt_byte_block; + ret->skip_byte_block = info->skip_byte_block; + memcpy(ret->iv, info->iv, info->iv_size); + memcpy(ret->key_id, info->key_id, info->key_id_size); + memcpy(ret->subsamples, info->subsamples, sizeof(*info->subsamples) * info->subsample_count); + return ret; +} + +void av_encryption_info_free(AVEncryptionInfo *info) +{ + if (info) { + av_free(info->key_id); + av_free(info->iv); + av_free(info->subsamples); + av_free(info); + } +} + +AVEncryptionInfo *av_encryption_info_get_side_data(const uint8_t* buffer, size_t size) +{ + AVEncryptionInfo *info; + uint64_t key_id_size, iv_size, subsample_count, i; + + if (!buffer || size < FF_ENCRYPTION_INFO_EXTRA) + return NULL; + + key_id_size = AV_RB32(buffer + 12); + iv_size = AV_RB32(buffer + 16); + subsample_count = AV_RB32(buffer + 20); + + if (size < FF_ENCRYPTION_INFO_EXTRA + key_id_size + iv_size + subsample_count * 8) + return NULL; + + info = av_encryption_info_alloc(subsample_count, key_id_size, iv_size); + if (!info) + return NULL; + + info->scheme = AV_RB32(buffer); + info->crypt_byte_block = AV_RB32(buffer + 4); + info->skip_byte_block = AV_RB32(buffer + 8); + memcpy(info->key_id, buffer + 24, key_id_size); + memcpy(info->iv, buffer + key_id_size + 24, iv_size); + + buffer += key_id_size + iv_size + 24; + for (i = 0; i < subsample_count; i++) { + info->subsamples[i].bytes_of_clear_data = AV_RB32(buffer); + info->subsamples[i].bytes_of_protected_data = AV_RB32(buffer + 4); + buffer += 8; + } + + return info; +} + +uint8_t *av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size) +{ + uint8_t *buffer, *cur_buffer; + uint32_t i; + + if (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA < info->key_id_size || + UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size < info->iv_size || + (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size - info->iv_size) / 8 < info->subsample_count) { + return NULL; + } + + *size = FF_ENCRYPTION_INFO_EXTRA + info->key_id_size + info->iv_size + + (info->subsample_count * 8); + cur_buffer = buffer = av_malloc(*size); + if (!buffer) + return NULL; + + AV_WB32(cur_buffer, info->scheme); + AV_WB32(cur_buffer + 4, info->crypt_byte_block); + AV_WB32(cur_buffer + 8, info->skip_byte_block); + AV_WB32(cur_buffer + 12, info->key_id_size); + AV_WB32(cur_buffer + 16, info->iv_size); + AV_WB32(cur_buffer + 20, info->subsample_count); + cur_buffer += 24; + memcpy(cur_buffer, info->key_id, info->key_id_size); + cur_buffer += info->key_id_size; + memcpy(cur_buffer, info->iv, info->iv_size); + cur_buffer += info->iv_size; + for (i = 0; i < info->subsample_count; i++) { + AV_WB32(cur_buffer, info->subsamples[i].bytes_of_clear_data); + AV_WB32(cur_buffer + 4, info->subsamples[i].bytes_of_protected_data); + cur_buffer += 8; + } + + return buffer; +} + +// The format of the AVEncryptionInitInfo side data: +// u32be init_info_count +// { +// u32be system_id_size +// u32be num_key_ids +// u32be key_id_size +// u32be data_size +// u8[system_id_size] system_id +// u8[key_id_size][num_key_id] key_ids +// u8[data_size] data +// }[init_info_count] + +#define FF_ENCRYPTION_INIT_INFO_EXTRA 16 + +AVEncryptionInitInfo *av_encryption_init_info_alloc( + uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size) +{ + AVEncryptionInitInfo *info; + uint32_t i; + + info = av_mallocz(sizeof(*info)); + if (!info) + return NULL; + + info->system_id = av_mallocz(system_id_size); + info->system_id_size = system_id_size; + info->key_ids = key_id_size ? av_mallocz_array(num_key_ids, sizeof(*info->key_ids)) : NULL; + info->num_key_ids = num_key_ids; + info->key_id_size = key_id_size; + info->data = av_mallocz(data_size); + info->data_size = data_size; + + // Allow pointers to be NULL if the size is 0. + if ((!info->system_id && system_id_size) || (!info->data && data_size) || + (!info->key_ids && num_key_ids && key_id_size)) { + av_encryption_init_info_free(info); + return NULL; + } + + if (key_id_size) { + for (i = 0; i < num_key_ids; i++) { + info->key_ids[i] = av_mallocz(key_id_size); + if (!info->key_ids[i]) { + av_encryption_init_info_free(info); + return NULL; + } + } + } + + return info; +} + +void av_encryption_init_info_free(AVEncryptionInitInfo *info) +{ + uint32_t i; + if (info) { + for (i = 0; i < info->num_key_ids; i++) { + av_free(info->key_ids[i]); + } + av_encryption_init_info_free(info->next); + av_free(info->system_id); + av_free(info->key_ids); + av_free(info->data); + av_free(info); + } +} + +AVEncryptionInitInfo *av_encryption_init_info_get_side_data( + const uint8_t *side_data, size_t side_data_size) +{ + // |ret| tracks the front of the list, |info| tracks the back. + AVEncryptionInitInfo *ret = NULL, *info, *temp_info; + uint64_t system_id_size, num_key_ids, key_id_size, data_size, i, j; + uint64_t init_info_count; + + if (!side_data || side_data_size < 4) + return NULL; + + init_info_count = AV_RB32(side_data); + side_data += 4; + side_data_size -= 4; + for (i = 0; i < init_info_count; i++) { + if (side_data_size < FF_ENCRYPTION_INIT_INFO_EXTRA) { + av_encryption_init_info_free(ret); + return NULL; + } + + system_id_size = AV_RB32(side_data); + num_key_ids = AV_RB32(side_data + 4); + key_id_size = AV_RB32(side_data + 8); + data_size = AV_RB32(side_data + 12); + + // UINT32_MAX + UINT32_MAX + UINT32_MAX * UINT32_MAX == UINT64_MAX + if (side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA < system_id_size + data_size + num_key_ids * key_id_size) { + av_encryption_init_info_free(ret); + return NULL; + } + side_data += FF_ENCRYPTION_INIT_INFO_EXTRA; + side_data_size -= FF_ENCRYPTION_INIT_INFO_EXTRA; + + temp_info = av_encryption_init_info_alloc(system_id_size, num_key_ids, key_id_size, data_size); + if (!temp_info) { + av_encryption_init_info_free(ret); + return NULL; + } + if (i == 0) { + info = ret = temp_info; + } else { + info->next = temp_info; + info = temp_info; + } + + memcpy(info->system_id, side_data, system_id_size); + side_data += system_id_size; + side_data_size -= system_id_size; + for (j = 0; j < num_key_ids; j++) { + memcpy(info->key_ids[j], side_data, key_id_size); + side_data += key_id_size; + side_data_size -= key_id_size; + } + memcpy(info->data, side_data, data_size); + side_data += data_size; + side_data_size -= data_size; + } + + return ret; +} + +uint8_t *av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size) +{ + const AVEncryptionInitInfo *cur_info; + uint8_t *buffer, *cur_buffer; + uint32_t i, init_info_count; + uint64_t temp_side_data_size; + + temp_side_data_size = 4; + init_info_count = 0; + for (cur_info = info; cur_info; cur_info = cur_info->next) { + temp_side_data_size += (uint64_t)FF_ENCRYPTION_INIT_INFO_EXTRA + cur_info->system_id_size + cur_info->data_size; + if (init_info_count == UINT32_MAX || temp_side_data_size > UINT32_MAX) { + return NULL; + } + init_info_count++; + + if (cur_info->num_key_ids) { + temp_side_data_size += (uint64_t)cur_info->num_key_ids * cur_info->key_id_size; + if (temp_side_data_size > UINT32_MAX) { + return NULL; + } + } + } + *side_data_size = temp_side_data_size; + + cur_buffer = buffer = av_malloc(*side_data_size); + if (!buffer) + return NULL; + + AV_WB32(cur_buffer, init_info_count); + cur_buffer += 4; + for (cur_info = info; cur_info; cur_info = cur_info->next) { + AV_WB32(cur_buffer, cur_info->system_id_size); + AV_WB32(cur_buffer + 4, cur_info->num_key_ids); + AV_WB32(cur_buffer + 8, cur_info->key_id_size); + AV_WB32(cur_buffer + 12, cur_info->data_size); + cur_buffer += 16; + + memcpy(cur_buffer, cur_info->system_id, cur_info->system_id_size); + cur_buffer += cur_info->system_id_size; + for (i = 0; i < cur_info->num_key_ids; i++) { + memcpy(cur_buffer, cur_info->key_ids[i], cur_info->key_id_size); + cur_buffer += cur_info->key_id_size; + } + memcpy(cur_buffer, cur_info->data, cur_info->data_size); + cur_buffer += cur_info->data_size; + } + + return buffer; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/encryption_info.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/encryption_info.h new file mode 100644 index 000000000..8fe7ebfe4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/encryption_info.h @@ -0,0 +1,205 @@ +/** + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ENCRYPTION_INFO_H +#define AVUTIL_ENCRYPTION_INFO_H + +#include +#include + +typedef struct AVSubsampleEncryptionInfo { + /** The number of bytes that are clear. */ + unsigned int bytes_of_clear_data; + + /** + * The number of bytes that are protected. If using pattern encryption, + * the pattern applies to only the protected bytes; if not using pattern + * encryption, all these bytes are encrypted. + */ + unsigned int bytes_of_protected_data; +} AVSubsampleEncryptionInfo; + +/** + * This describes encryption info for a packet. This contains frame-specific + * info for how to decrypt the packet before passing it to the decoder. + * + * The size of this struct is not part of the public ABI. + */ +typedef struct AVEncryptionInfo { + /** The fourcc encryption scheme, in big-endian byte order. */ + uint32_t scheme; + + /** + * Only used for pattern encryption. This is the number of 16-byte blocks + * that are encrypted. + */ + uint32_t crypt_byte_block; + + /** + * Only used for pattern encryption. This is the number of 16-byte blocks + * that are clear. + */ + uint32_t skip_byte_block; + + /** + * The ID of the key used to encrypt the packet. This should always be + * 16 bytes long, but may be changed in the future. + */ + uint8_t *key_id; + uint32_t key_id_size; + + /** + * The initialization vector. This may have been zero-filled to be the + * correct block size. This should always be 16 bytes long, but may be + * changed in the future. + */ + uint8_t *iv; + uint32_t iv_size; + + /** + * An array of subsample encryption info specifying how parts of the sample + * are encrypted. If there are no subsamples, then the whole sample is + * encrypted. + */ + AVSubsampleEncryptionInfo *subsamples; + uint32_t subsample_count; +} AVEncryptionInfo; + +/** + * This describes info used to initialize an encryption key system. + * + * The size of this struct is not part of the public ABI. + */ +typedef struct AVEncryptionInitInfo { + /** + * A unique identifier for the key system this is for, can be NULL if it + * is not known. This should always be 16 bytes, but may change in the + * future. + */ + uint8_t* system_id; + uint32_t system_id_size; + + /** + * An array of key IDs this initialization data is for. All IDs are the + * same length. Can be NULL if there are no known key IDs. + */ + uint8_t** key_ids; + /** The number of key IDs. */ + uint32_t num_key_ids; + /** + * The number of bytes in each key ID. This should always be 16, but may + * change in the future. + */ + uint32_t key_id_size; + + /** + * Key-system specific initialization data. This data is copied directly + * from the file and the format depends on the specific key system. This + * can be NULL if there is no initialization data; in that case, there + * will be at least one key ID. + */ + uint8_t* data; + uint32_t data_size; + + /** + * An optional pointer to the next initialization info in the list. + */ + struct AVEncryptionInitInfo *next; +} AVEncryptionInitInfo; + +/** + * Allocates an AVEncryptionInfo structure and sub-pointers to hold the given + * number of subsamples. This will allocate pointers for the key ID, IV, + * and subsample entries, set the size members, and zero-initialize the rest. + * + * @param subsample_count The number of subsamples. + * @param key_id_size The number of bytes in the key ID, should be 16. + * @param iv_size The number of bytes in the IV, should be 16. + * + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size); + +/** + * Allocates an AVEncryptionInfo structure with a copy of the given data. + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_clone(const AVEncryptionInfo *info); + +/** + * Frees the given encryption info object. This MUST NOT be used to free the + * side-data data pointer, that should use normal side-data methods. + */ +void av_encryption_info_free(AVEncryptionInfo *info); + +/** + * Creates a copy of the AVEncryptionInfo that is contained in the given side + * data. The resulting object should be passed to av_encryption_info_free() + * when done. + * + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_get_side_data(const uint8_t *side_data, size_t side_data_size); + +/** + * Allocates and initializes side data that holds a copy of the given encryption + * info. The resulting pointer should be either freed using av_free or given + * to av_packet_add_side_data(). + * + * @return The new side-data pointer, or NULL. + */ +uint8_t *av_encryption_info_add_side_data( + const AVEncryptionInfo *info, size_t *side_data_size); + + +/** + * Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the + * given sizes. This will allocate pointers and set all the fields. + * + * @return The new AVEncryptionInitInfo structure, or NULL on error. + */ +AVEncryptionInitInfo *av_encryption_init_info_alloc( + uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size); + +/** + * Frees the given encryption init info object. This MUST NOT be used to free + * the side-data data pointer, that should use normal side-data methods. + */ +void av_encryption_init_info_free(AVEncryptionInitInfo* info); + +/** + * Creates a copy of the AVEncryptionInitInfo that is contained in the given + * side data. The resulting object should be passed to + * av_encryption_init_info_free() when done. + * + * @return The new AVEncryptionInitInfo structure, or NULL on error. + */ +AVEncryptionInitInfo *av_encryption_init_info_get_side_data( + const uint8_t* side_data, size_t side_data_size); + +/** + * Allocates and initializes side data that holds a copy of the given encryption + * init info. The resulting pointer should be either freed using av_free or + * given to av_packet_add_side_data(). + * + * @return The new side-data pointer, or NULL. + */ +uint8_t *av_encryption_init_info_add_side_data( + const AVEncryptionInitInfo *info, size_t *side_data_size); + +#endif /* AVUTIL_ENCRYPTION_INFO_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/error.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/error.c new file mode 100644 index 000000000..b96304837 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/error.c @@ -0,0 +1,129 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#undef _GNU_SOURCE +#define _XOPEN_SOURCE 600 /* XSI-compliant version of strerror_r */ +#include "avutil.h" +#include "avstring.h" +#include "common.h" + +struct error_entry { + int num; + const char *tag; + const char *str; +}; + +#define ERROR_TAG(tag) AVERROR_##tag, #tag +#define EERROR_TAG(tag) AVERROR(tag), #tag +#define AVERROR_INPUT_AND_OUTPUT_CHANGED (AVERROR_INPUT_CHANGED | AVERROR_OUTPUT_CHANGED) +static const struct error_entry error_entries[] = { + { ERROR_TAG(BSF_NOT_FOUND), "Bitstream filter not found" }, + { ERROR_TAG(BUG), "Internal bug, should not have happened" }, + { ERROR_TAG(BUG2), "Internal bug, should not have happened" }, + { ERROR_TAG(BUFFER_TOO_SMALL), "Buffer too small" }, + { ERROR_TAG(DECODER_NOT_FOUND), "Decoder not found" }, + { ERROR_TAG(DEMUXER_NOT_FOUND), "Demuxer not found" }, + { ERROR_TAG(ENCODER_NOT_FOUND), "Encoder not found" }, + { ERROR_TAG(EOF), "End of file" }, + { ERROR_TAG(EXIT), "Immediate exit requested" }, + { ERROR_TAG(EXTERNAL), "Generic error in an external library" }, + { ERROR_TAG(FILTER_NOT_FOUND), "Filter not found" }, + { ERROR_TAG(INPUT_CHANGED), "Input changed" }, + { ERROR_TAG(INVALIDDATA), "Invalid data found when processing input" }, + { ERROR_TAG(MUXER_NOT_FOUND), "Muxer not found" }, + { ERROR_TAG(OPTION_NOT_FOUND), "Option not found" }, + { ERROR_TAG(OUTPUT_CHANGED), "Output changed" }, + { ERROR_TAG(PATCHWELCOME), "Not yet implemented in FFmpeg, patches welcome" }, + { ERROR_TAG(PROTOCOL_NOT_FOUND), "Protocol not found" }, + { ERROR_TAG(STREAM_NOT_FOUND), "Stream not found" }, + { ERROR_TAG(UNKNOWN), "Unknown error occurred" }, + { ERROR_TAG(EXPERIMENTAL), "Experimental feature" }, + { ERROR_TAG(INPUT_AND_OUTPUT_CHANGED), "Input and output changed" }, + { ERROR_TAG(HTTP_BAD_REQUEST), "Server returned 400 Bad Request" }, + { ERROR_TAG(HTTP_UNAUTHORIZED), "Server returned 401 Unauthorized (authorization failed)" }, + { ERROR_TAG(HTTP_FORBIDDEN), "Server returned 403 Forbidden (access denied)" }, + { ERROR_TAG(HTTP_NOT_FOUND), "Server returned 404 Not Found" }, + { ERROR_TAG(HTTP_OTHER_4XX), "Server returned 4XX Client Error, but not one of 40{0,1,3,4}" }, + { ERROR_TAG(HTTP_SERVER_ERROR), "Server returned 5XX Server Error reply" }, +#if !HAVE_STRERROR_R + { EERROR_TAG(E2BIG), "Argument list too long" }, + { EERROR_TAG(EACCES), "Permission denied" }, + { EERROR_TAG(EAGAIN), "Resource temporarily unavailable" }, + { EERROR_TAG(EBADF), "Bad file descriptor" }, + { EERROR_TAG(EBUSY), "Device or resource busy" }, + { EERROR_TAG(ECHILD), "No child processes" }, + { EERROR_TAG(EDEADLK), "Resource deadlock avoided" }, + { EERROR_TAG(EDOM), "Numerical argument out of domain" }, + { EERROR_TAG(EEXIST), "File exists" }, + { EERROR_TAG(EFAULT), "Bad address" }, + { EERROR_TAG(EFBIG), "File too large" }, + { EERROR_TAG(EILSEQ), "Illegal byte sequence" }, + { EERROR_TAG(EINTR), "Interrupted system call" }, + { EERROR_TAG(EINVAL), "Invalid argument" }, + { EERROR_TAG(EIO), "I/O error" }, + { EERROR_TAG(EISDIR), "Is a directory" }, + { EERROR_TAG(EMFILE), "Too many open files" }, + { EERROR_TAG(EMLINK), "Too many links" }, + { EERROR_TAG(ENAMETOOLONG), "File name too long" }, + { EERROR_TAG(ENFILE), "Too many open files in system" }, + { EERROR_TAG(ENODEV), "No such device" }, + { EERROR_TAG(ENOENT), "No such file or directory" }, + { EERROR_TAG(ENOEXEC), "Exec format error" }, + { EERROR_TAG(ENOLCK), "No locks available" }, + { EERROR_TAG(ENOMEM), "Cannot allocate memory" }, + { EERROR_TAG(ENOSPC), "No space left on device" }, + { EERROR_TAG(ENOSYS), "Function not implemented" }, + { EERROR_TAG(ENOTDIR), "Not a directory" }, + { EERROR_TAG(ENOTEMPTY), "Directory not empty" }, + { EERROR_TAG(ENOTTY), "Inappropriate I/O control operation" }, + { EERROR_TAG(ENXIO), "No such device or address" }, + { EERROR_TAG(EPERM), "Operation not permitted" }, + { EERROR_TAG(EPIPE), "Broken pipe" }, + { EERROR_TAG(ERANGE), "Result too large" }, + { EERROR_TAG(EROFS), "Read-only file system" }, + { EERROR_TAG(ESPIPE), "Illegal seek" }, + { EERROR_TAG(ESRCH), "No such process" }, + { EERROR_TAG(EXDEV), "Cross-device link" }, +#endif +}; + +int av_strerror(int errnum, char *errbuf, size_t errbuf_size) +{ + int ret = 0, i; + const struct error_entry *entry = NULL; + + for (i = 0; i < FF_ARRAY_ELEMS(error_entries); i++) { + if (errnum == error_entries[i].num) { + entry = &error_entries[i]; + break; + } + } + if (entry) { + av_strlcpy(errbuf, entry->str, errbuf_size); + } else { +#if HAVE_STRERROR_R + ret = AVERROR(strerror_r(AVUNERROR(errnum), errbuf, errbuf_size)); +#else + ret = -1; +#endif + if (ret < 0) + snprintf(errbuf, errbuf_size, "Error number %d occurred", errnum); + } + + return ret; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/error.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/error.h new file mode 100644 index 000000000..71df4da35 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/error.h @@ -0,0 +1,126 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * error code definitions + */ + +#ifndef AVUTIL_ERROR_H +#define AVUTIL_ERROR_H + +#include +#include + +/** + * @addtogroup lavu_error + * + * @{ + */ + + +/* error handling */ +#if EDOM > 0 +#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions. +#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value. +#else +/* Some platforms have E* and errno already negated. */ +#define AVERROR(e) (e) +#define AVUNERROR(e) (e) +#endif + +#define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d)) + +#define AVERROR_BSF_NOT_FOUND FFERRTAG(0xF8,'B','S','F') ///< Bitstream filter not found +#define AVERROR_BUG FFERRTAG( 'B','U','G','!') ///< Internal bug, also see AVERROR_BUG2 +#define AVERROR_BUFFER_TOO_SMALL FFERRTAG( 'B','U','F','S') ///< Buffer too small +#define AVERROR_DECODER_NOT_FOUND FFERRTAG(0xF8,'D','E','C') ///< Decoder not found +#define AVERROR_DEMUXER_NOT_FOUND FFERRTAG(0xF8,'D','E','M') ///< Demuxer not found +#define AVERROR_ENCODER_NOT_FOUND FFERRTAG(0xF8,'E','N','C') ///< Encoder not found +#define AVERROR_EOF FFERRTAG( 'E','O','F',' ') ///< End of file +#define AVERROR_EXIT FFERRTAG( 'E','X','I','T') ///< Immediate exit was requested; the called function should not be restarted +#define AVERROR_EXTERNAL FFERRTAG( 'E','X','T',' ') ///< Generic error in an external library +#define AVERROR_FILTER_NOT_FOUND FFERRTAG(0xF8,'F','I','L') ///< Filter not found +#define AVERROR_INVALIDDATA FFERRTAG( 'I','N','D','A') ///< Invalid data found when processing input +#define AVERROR_MUXER_NOT_FOUND FFERRTAG(0xF8,'M','U','X') ///< Muxer not found +#define AVERROR_OPTION_NOT_FOUND FFERRTAG(0xF8,'O','P','T') ///< Option not found +#define AVERROR_PATCHWELCOME FFERRTAG( 'P','A','W','E') ///< Not yet implemented in FFmpeg, patches welcome +#define AVERROR_PROTOCOL_NOT_FOUND FFERRTAG(0xF8,'P','R','O') ///< Protocol not found + +#define AVERROR_STREAM_NOT_FOUND FFERRTAG(0xF8,'S','T','R') ///< Stream not found +/** + * This is semantically identical to AVERROR_BUG + * it has been introduced in Libav after our AVERROR_BUG and with a modified value. + */ +#define AVERROR_BUG2 FFERRTAG( 'B','U','G',' ') +#define AVERROR_UNKNOWN FFERRTAG( 'U','N','K','N') ///< Unknown error, typically from an external library +#define AVERROR_EXPERIMENTAL (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it. +#define AVERROR_INPUT_CHANGED (-0x636e6701) ///< Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED) +#define AVERROR_OUTPUT_CHANGED (-0x636e6702) ///< Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED) +/* HTTP & RTSP errors */ +#define AVERROR_HTTP_BAD_REQUEST FFERRTAG(0xF8,'4','0','0') +#define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8,'4','0','1') +#define AVERROR_HTTP_FORBIDDEN FFERRTAG(0xF8,'4','0','3') +#define AVERROR_HTTP_NOT_FOUND FFERRTAG(0xF8,'4','0','4') +#define AVERROR_HTTP_OTHER_4XX FFERRTAG(0xF8,'4','X','X') +#define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8,'5','X','X') + +#define AV_ERROR_MAX_STRING_SIZE 64 + +/** + * Put a description of the AVERROR code errnum in errbuf. + * In case of failure the global variable errno is set to indicate the + * error. Even in case of failure av_strerror() will print a generic + * error message indicating the errnum provided to errbuf. + * + * @param errnum error code to describe + * @param errbuf buffer to which description is written + * @param errbuf_size the size in bytes of errbuf + * @return 0 on success, a negative value if a description for errnum + * cannot be found + */ +int av_strerror(int errnum, char *errbuf, size_t errbuf_size); + +/** + * Fill the provided buffer with a string containing an error string + * corresponding to the AVERROR code errnum. + * + * @param errbuf a buffer + * @param errbuf_size size in bytes of errbuf + * @param errnum error code to describe + * @return the buffer in input, filled with the error description + * @see av_strerror() + */ +static inline char *av_make_error_string(char *errbuf, size_t errbuf_size, int errnum) +{ + av_strerror(errnum, errbuf, errbuf_size); + return errbuf; +} + +/** + * Convenience macro, the return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_err2str(errnum) \ + av_make_error_string((char[AV_ERROR_MAX_STRING_SIZE]){0}, AV_ERROR_MAX_STRING_SIZE, errnum) + +/** + * @} + */ + +#endif /* AVUTIL_ERROR_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/eval.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/eval.c new file mode 100644 index 000000000..5da9a6d83 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/eval.c @@ -0,0 +1,760 @@ +/* + * Copyright (c) 2002-2006 Michael Niedermayer + * Copyright (c) 2006 Oded Shimon + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * simple arithmetic expression evaluator. + * + * see http://joe.hotchkiss.com/programming/eval/eval.html + */ + +#include +#include "attributes.h" +#include "avutil.h" +#include "common.h" +#include "eval.h" +#include "ffmath.h" +#include "internal.h" +#include "log.h" +#include "mathematics.h" +#include "time.h" +#include "avstring.h" +#include "timer.h" +#include "reverse.h" + +typedef struct Parser { + const AVClass *class; + int stack_index; + char *s; + const double *const_values; + const char * const *const_names; // NULL terminated + double (* const *funcs1)(void *, double a); // NULL terminated + const char * const *func1_names; // NULL terminated + double (* const *funcs2)(void *, double a, double b); // NULL terminated + const char * const *func2_names; // NULL terminated + void *opaque; + int log_offset; + void *log_ctx; +#define VARS 10 + double *var; +} Parser; + +static const AVClass eval_class = { + .class_name = "Eval", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(Parser, log_offset), + .parent_log_context_offset = offsetof(Parser, log_ctx), +}; + +static const struct { + double bin_val; + double dec_val; + int8_t exp; +} si_prefixes['z' - 'E' + 1] = { + ['y'-'E']= { 8.271806125530276749e-25, 1e-24, -24 }, + ['z'-'E']= { 8.4703294725430034e-22, 1e-21, -21 }, + ['a'-'E']= { 8.6736173798840355e-19, 1e-18, -18 }, + ['f'-'E']= { 8.8817841970012523e-16, 1e-15, -15 }, + ['p'-'E']= { 9.0949470177292824e-13, 1e-12, -12 }, + ['n'-'E']= { 9.3132257461547852e-10, 1e-9, -9 }, + ['u'-'E']= { 9.5367431640625e-7, 1e-6, -6 }, + ['m'-'E']= { 9.765625e-4, 1e-3, -3 }, + ['c'-'E']= { 9.8431332023036951e-3, 1e-2, -2 }, + ['d'-'E']= { 9.921256574801246e-2, 1e-1, -1 }, + ['h'-'E']= { 1.0159366732596479e2, 1e2, 2 }, + ['k'-'E']= { 1.024e3, 1e3, 3 }, + ['K'-'E']= { 1.024e3, 1e3, 3 }, + ['M'-'E']= { 1.048576e6, 1e6, 6 }, + ['G'-'E']= { 1.073741824e9, 1e9, 9 }, + ['T'-'E']= { 1.099511627776e12, 1e12, 12 }, + ['P'-'E']= { 1.125899906842624e15, 1e15, 15 }, + ['E'-'E']= { 1.152921504606847e18, 1e18, 18 }, + ['Z'-'E']= { 1.1805916207174113e21, 1e21, 21 }, + ['Y'-'E']= { 1.2089258196146292e24, 1e24, 24 }, +}; + +static const struct { + const char *name; + double value; +} constants[] = { + { "E", M_E }, + { "PI", M_PI }, + { "PHI", M_PHI }, + { "QP2LAMBDA", FF_QP2LAMBDA }, +}; + +double av_strtod(const char *numstr, char **tail) +{ + double d; + char *next; + if(numstr[0]=='0' && (numstr[1]|0x20)=='x') { + d = strtoul(numstr, &next, 16); + } else + d = strtod(numstr, &next); + /* if parsing succeeded, check for and interpret postfixes */ + if (next!=numstr) { + if (next[0] == 'd' && next[1] == 'B') { + /* treat dB as decibels instead of decibytes */ + d = ff_exp10(d / 20); + next += 2; + } else if (*next >= 'E' && *next <= 'z') { + int e= si_prefixes[*next - 'E'].exp; + if (e) { + if (next[1] == 'i') { + d*= si_prefixes[*next - 'E'].bin_val; + next+=2; + } else { + d*= si_prefixes[*next - 'E'].dec_val; + next++; + } + } + } + + if (*next=='B') { + d*=8; + next++; + } + } + /* if requested, fill in tail with the position after the last parsed + character */ + if (tail) + *tail = next; + return d; +} + +#define IS_IDENTIFIER_CHAR(c) ((c) - '0' <= 9U || (c) - 'a' <= 25U || (c) - 'A' <= 25U || (c) == '_') + +static int strmatch(const char *s, const char *prefix) +{ + int i; + for (i=0; prefix[i]; i++) { + if (prefix[i] != s[i]) return 0; + } + /* return 1 only if the s identifier is terminated */ + return !IS_IDENTIFIER_CHAR(s[i]); +} + +struct AVExpr { + enum { + e_value, e_const, e_func0, e_func1, e_func2, + e_squish, e_gauss, e_ld, e_isnan, e_isinf, + e_mod, e_max, e_min, e_eq, e_gt, e_gte, e_lte, e_lt, + e_pow, e_mul, e_div, e_add, + e_last, e_st, e_while, e_taylor, e_root, e_floor, e_ceil, e_trunc, e_round, + e_sqrt, e_not, e_random, e_hypot, e_gcd, + e_if, e_ifnot, e_print, e_bitand, e_bitor, e_between, e_clip, e_atan2, e_lerp, + } type; + double value; // is sign in other types + union { + int const_index; + double (*func0)(double); + double (*func1)(void *, double); + double (*func2)(void *, double, double); + } a; + struct AVExpr *param[3]; + double *var; +}; + +static double etime(double v) +{ + return av_gettime() * 0.000001; +} + +static double eval_expr(Parser *p, AVExpr *e) +{ + switch (e->type) { + case e_value: return e->value; + case e_const: return e->value * p->const_values[e->a.const_index]; + case e_func0: return e->value * e->a.func0(eval_expr(p, e->param[0])); + case e_func1: return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0])); + case e_func2: return e->value * e->a.func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1])); + case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0]))); + case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); } + case e_ld: return e->value * p->var[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)]; + case e_isnan: return e->value * !!isnan(eval_expr(p, e->param[0])); + case e_isinf: return e->value * !!isinf(eval_expr(p, e->param[0])); + case e_floor: return e->value * floor(eval_expr(p, e->param[0])); + case e_ceil : return e->value * ceil (eval_expr(p, e->param[0])); + case e_trunc: return e->value * trunc(eval_expr(p, e->param[0])); + case e_round: return e->value * round(eval_expr(p, e->param[0])); + case e_sqrt: return e->value * sqrt (eval_expr(p, e->param[0])); + case e_not: return e->value * (eval_expr(p, e->param[0]) == 0); + case e_if: return e->value * (eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : + e->param[2] ? eval_expr(p, e->param[2]) : 0); + case e_ifnot: return e->value * (!eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : + e->param[2] ? eval_expr(p, e->param[2]) : 0); + case e_clip: { + double x = eval_expr(p, e->param[0]); + double min = eval_expr(p, e->param[1]), max = eval_expr(p, e->param[2]); + if (isnan(min) || isnan(max) || isnan(x) || min > max) + return NAN; + return e->value * av_clipd(eval_expr(p, e->param[0]), min, max); + } + case e_between: { + double d = eval_expr(p, e->param[0]); + return e->value * (d >= eval_expr(p, e->param[1]) && + d <= eval_expr(p, e->param[2])); + } + case e_lerp: { + double v0 = eval_expr(p, e->param[0]); + double v1 = eval_expr(p, e->param[1]); + double f = eval_expr(p, e->param[2]); + return v0 + (v1 - v0) * f; + } + case e_print: { + double x = eval_expr(p, e->param[0]); + int level = e->param[1] ? av_clip(eval_expr(p, e->param[1]), INT_MIN, INT_MAX) : AV_LOG_INFO; + av_log(p, level, "%f\n", x); + return x; + } + case e_random:{ + int idx= av_clip(eval_expr(p, e->param[0]), 0, VARS-1); + uint64_t r= isnan(p->var[idx]) ? 0 : p->var[idx]; + r= r*1664525+1013904223; + p->var[idx]= r; + return e->value * (r * (1.0/UINT64_MAX)); + } + case e_while: { + double d = NAN; + while (eval_expr(p, e->param[0])) + d=eval_expr(p, e->param[1]); + return d; + } + case e_taylor: { + double t = 1, d = 0, v; + double x = eval_expr(p, e->param[1]); + int id = e->param[2] ? av_clip(eval_expr(p, e->param[2]), 0, VARS-1) : 0; + int i; + double var0 = p->var[id]; + for(i=0; i<1000; i++) { + double ld = d; + p->var[id] = i; + v = eval_expr(p, e->param[0]); + d += t*v; + if(ld==d && v) + break; + t *= x / (i+1); + } + p->var[id] = var0; + return d; + } + case e_root: { + int i, j; + double low = -1, high = -1, v, low_v = -DBL_MAX, high_v = DBL_MAX; + double var0 = p->var[0]; + double x_max = eval_expr(p, e->param[1]); + for(i=-1; i<1024; i++) { + if(i<255) { + p->var[0] = ff_reverse[i&255]*x_max/255; + } else { + p->var[0] = x_max*pow(0.9, i-255); + if (i&1) p->var[0] *= -1; + if (i&2) p->var[0] += low; + else p->var[0] += high; + } + v = eval_expr(p, e->param[0]); + if (v<=0 && v>low_v) { + low = p->var[0]; + low_v = v; + } + if (v>=0 && vvar[0]; + high_v = v; + } + if (low>=0 && high>=0){ + for (j=0; j<1000; j++) { + p->var[0] = (low+high)*0.5; + if (low == p->var[0] || high == p->var[0]) + break; + v = eval_expr(p, e->param[0]); + if (v<=0) low = p->var[0]; + if (v>=0) high= p->var[0]; + if (isnan(v)) { + low = high = v; + break; + } + } + break; + } + } + p->var[0] = var0; + return -low_vparam[0]); + double d2 = eval_expr(p, e->param[1]); + switch (e->type) { + case e_mod: return e->value * (d - floor((!CONFIG_FTRAPV || d2) ? d / d2 : d * INFINITY) * d2); + case e_gcd: return e->value * av_gcd(d,d2); + case e_max: return e->value * (d > d2 ? d : d2); + case e_min: return e->value * (d < d2 ? d : d2); + case e_eq: return e->value * (d == d2 ? 1.0 : 0.0); + case e_gt: return e->value * (d > d2 ? 1.0 : 0.0); + case e_gte: return e->value * (d >= d2 ? 1.0 : 0.0); + case e_lt: return e->value * (d < d2 ? 1.0 : 0.0); + case e_lte: return e->value * (d <= d2 ? 1.0 : 0.0); + case e_pow: return e->value * pow(d, d2); + case e_mul: return e->value * (d * d2); + case e_div: return e->value * ((!CONFIG_FTRAPV || d2 ) ? (d / d2) : d * INFINITY); + case e_add: return e->value * (d + d2); + case e_last:return e->value * d2; + case e_st : return e->value * (p->var[av_clip(d, 0, VARS-1)]= d2); + case e_hypot:return e->value * hypot(d, d2); + case e_atan2:return e->value * atan2(d, d2); + case e_bitand: return isnan(d) || isnan(d2) ? NAN : e->value * ((long int)d & (long int)d2); + case e_bitor: return isnan(d) || isnan(d2) ? NAN : e->value * ((long int)d | (long int)d2); + } + } + } + return NAN; +} + +static int parse_expr(AVExpr **e, Parser *p); + +void av_expr_free(AVExpr *e) +{ + if (!e) return; + av_expr_free(e->param[0]); + av_expr_free(e->param[1]); + av_expr_free(e->param[2]); + av_freep(&e->var); + av_freep(&e); +} + +static int parse_primary(AVExpr **e, Parser *p) +{ + AVExpr *d = av_mallocz(sizeof(AVExpr)); + char *next = p->s, *s0 = p->s; + int ret, i; + + if (!d) + return AVERROR(ENOMEM); + + /* number */ + d->value = av_strtod(p->s, &next); + if (next != p->s) { + d->type = e_value; + p->s= next; + *e = d; + return 0; + } + d->value = 1; + + /* named constants */ + for (i=0; p->const_names && p->const_names[i]; i++) { + if (strmatch(p->s, p->const_names[i])) { + p->s+= strlen(p->const_names[i]); + d->type = e_const; + d->a.const_index = i; + *e = d; + return 0; + } + } + for (i = 0; i < FF_ARRAY_ELEMS(constants); i++) { + if (strmatch(p->s, constants[i].name)) { + p->s += strlen(constants[i].name); + d->type = e_value; + d->value = constants[i].value; + *e = d; + return 0; + } + } + + p->s= strchr(p->s, '('); + if (!p->s) { + av_log(p, AV_LOG_ERROR, "Undefined constant or missing '(' in '%s'\n", s0); + p->s= next; + av_expr_free(d); + return AVERROR(EINVAL); + } + p->s++; // "(" + if (*next == '(') { // special case do-nothing + av_freep(&d); + if ((ret = parse_expr(&d, p)) < 0) + return ret; + if (p->s[0] != ')') { + av_log(p, AV_LOG_ERROR, "Missing ')' in '%s'\n", s0); + av_expr_free(d); + return AVERROR(EINVAL); + } + p->s++; // ")" + *e = d; + return 0; + } + if ((ret = parse_expr(&(d->param[0]), p)) < 0) { + av_expr_free(d); + return ret; + } + if (p->s[0]== ',') { + p->s++; // "," + parse_expr(&d->param[1], p); + } + if (p->s[0]== ',') { + p->s++; // "," + parse_expr(&d->param[2], p); + } + if (p->s[0] != ')') { + av_log(p, AV_LOG_ERROR, "Missing ')' or too many args in '%s'\n", s0); + av_expr_free(d); + return AVERROR(EINVAL); + } + p->s++; // ")" + + d->type = e_func0; + if (strmatch(next, "sinh" )) d->a.func0 = sinh; + else if (strmatch(next, "cosh" )) d->a.func0 = cosh; + else if (strmatch(next, "tanh" )) d->a.func0 = tanh; + else if (strmatch(next, "sin" )) d->a.func0 = sin; + else if (strmatch(next, "cos" )) d->a.func0 = cos; + else if (strmatch(next, "tan" )) d->a.func0 = tan; + else if (strmatch(next, "atan" )) d->a.func0 = atan; + else if (strmatch(next, "asin" )) d->a.func0 = asin; + else if (strmatch(next, "acos" )) d->a.func0 = acos; + else if (strmatch(next, "exp" )) d->a.func0 = exp; + else if (strmatch(next, "log" )) d->a.func0 = log; + else if (strmatch(next, "abs" )) d->a.func0 = fabs; + else if (strmatch(next, "time" )) d->a.func0 = etime; + else if (strmatch(next, "squish")) d->type = e_squish; + else if (strmatch(next, "gauss" )) d->type = e_gauss; + else if (strmatch(next, "mod" )) d->type = e_mod; + else if (strmatch(next, "max" )) d->type = e_max; + else if (strmatch(next, "min" )) d->type = e_min; + else if (strmatch(next, "eq" )) d->type = e_eq; + else if (strmatch(next, "gte" )) d->type = e_gte; + else if (strmatch(next, "gt" )) d->type = e_gt; + else if (strmatch(next, "lte" )) d->type = e_lte; + else if (strmatch(next, "lt" )) d->type = e_lt; + else if (strmatch(next, "ld" )) d->type = e_ld; + else if (strmatch(next, "isnan" )) d->type = e_isnan; + else if (strmatch(next, "isinf" )) d->type = e_isinf; + else if (strmatch(next, "st" )) d->type = e_st; + else if (strmatch(next, "while" )) d->type = e_while; + else if (strmatch(next, "taylor")) d->type = e_taylor; + else if (strmatch(next, "root" )) d->type = e_root; + else if (strmatch(next, "floor" )) d->type = e_floor; + else if (strmatch(next, "ceil" )) d->type = e_ceil; + else if (strmatch(next, "trunc" )) d->type = e_trunc; + else if (strmatch(next, "round" )) d->type = e_round; + else if (strmatch(next, "sqrt" )) d->type = e_sqrt; + else if (strmatch(next, "not" )) d->type = e_not; + else if (strmatch(next, "pow" )) d->type = e_pow; + else if (strmatch(next, "print" )) d->type = e_print; + else if (strmatch(next, "random")) d->type = e_random; + else if (strmatch(next, "hypot" )) d->type = e_hypot; + else if (strmatch(next, "gcd" )) d->type = e_gcd; + else if (strmatch(next, "if" )) d->type = e_if; + else if (strmatch(next, "ifnot" )) d->type = e_ifnot; + else if (strmatch(next, "bitand")) d->type = e_bitand; + else if (strmatch(next, "bitor" )) d->type = e_bitor; + else if (strmatch(next, "between"))d->type = e_between; + else if (strmatch(next, "clip" )) d->type = e_clip; + else if (strmatch(next, "atan2" )) d->type = e_atan2; + else if (strmatch(next, "lerp" )) d->type = e_lerp; + else { + for (i=0; p->func1_names && p->func1_names[i]; i++) { + if (strmatch(next, p->func1_names[i])) { + d->a.func1 = p->funcs1[i]; + d->type = e_func1; + *e = d; + return 0; + } + } + + for (i=0; p->func2_names && p->func2_names[i]; i++) { + if (strmatch(next, p->func2_names[i])) { + d->a.func2 = p->funcs2[i]; + d->type = e_func2; + *e = d; + return 0; + } + } + + av_log(p, AV_LOG_ERROR, "Unknown function in '%s'\n", s0); + av_expr_free(d); + return AVERROR(EINVAL); + } + + *e = d; + return 0; +} + +static AVExpr *make_eval_expr(int type, int value, AVExpr *p0, AVExpr *p1) +{ + AVExpr *e = av_mallocz(sizeof(AVExpr)); + if (!e) + return NULL; + e->type =type ; + e->value =value ; + e->param[0] =p0 ; + e->param[1] =p1 ; + return e; +} + +static int parse_pow(AVExpr **e, Parser *p, int *sign) +{ + *sign= (*p->s == '+') - (*p->s == '-'); + p->s += *sign&1; + return parse_primary(e, p); +} + +static int parse_dB(AVExpr **e, Parser *p, int *sign) +{ + /* do not filter out the negative sign when parsing a dB value. + for example, -3dB is not the same as -(3dB) */ + if (*p->s == '-') { + char *next; + double av_unused ignored = strtod(p->s, &next); + if (next != p->s && next[0] == 'd' && next[1] == 'B') { + *sign = 0; + return parse_primary(e, p); + } + } + return parse_pow(e, p, sign); +} + +static int parse_factor(AVExpr **e, Parser *p) +{ + int sign, sign2, ret; + AVExpr *e0, *e1, *e2; + if ((ret = parse_dB(&e0, p, &sign)) < 0) + return ret; + while(p->s[0]=='^'){ + e1 = e0; + p->s++; + if ((ret = parse_dB(&e2, p, &sign2)) < 0) { + av_expr_free(e1); + return ret; + } + e0 = make_eval_expr(e_pow, 1, e1, e2); + if (!e0) { + av_expr_free(e1); + av_expr_free(e2); + return AVERROR(ENOMEM); + } + if (e0->param[1]) e0->param[1]->value *= (sign2|1); + } + if (e0) e0->value *= (sign|1); + + *e = e0; + return 0; +} + +static int parse_term(AVExpr **e, Parser *p) +{ + int ret; + AVExpr *e0, *e1, *e2; + if ((ret = parse_factor(&e0, p)) < 0) + return ret; + while (p->s[0]=='*' || p->s[0]=='/') { + int c= *p->s++; + e1 = e0; + if ((ret = parse_factor(&e2, p)) < 0) { + av_expr_free(e1); + return ret; + } + e0 = make_eval_expr(c == '*' ? e_mul : e_div, 1, e1, e2); + if (!e0) { + av_expr_free(e1); + av_expr_free(e2); + return AVERROR(ENOMEM); + } + } + *e = e0; + return 0; +} + +static int parse_subexpr(AVExpr **e, Parser *p) +{ + int ret; + AVExpr *e0, *e1, *e2; + if ((ret = parse_term(&e0, p)) < 0) + return ret; + while (*p->s == '+' || *p->s == '-') { + e1 = e0; + if ((ret = parse_term(&e2, p)) < 0) { + av_expr_free(e1); + return ret; + } + e0 = make_eval_expr(e_add, 1, e1, e2); + if (!e0) { + av_expr_free(e1); + av_expr_free(e2); + return AVERROR(ENOMEM); + } + }; + + *e = e0; + return 0; +} + +static int parse_expr(AVExpr **e, Parser *p) +{ + int ret; + AVExpr *e0, *e1, *e2; + if (p->stack_index <= 0) //protect against stack overflows + return AVERROR(EINVAL); + p->stack_index--; + + if ((ret = parse_subexpr(&e0, p)) < 0) + return ret; + while (*p->s == ';') { + p->s++; + e1 = e0; + if ((ret = parse_subexpr(&e2, p)) < 0) { + av_expr_free(e1); + return ret; + } + e0 = make_eval_expr(e_last, 1, e1, e2); + if (!e0) { + av_expr_free(e1); + av_expr_free(e2); + return AVERROR(ENOMEM); + } + }; + + p->stack_index++; + *e = e0; + return 0; +} + +static int verify_expr(AVExpr *e) +{ + if (!e) return 0; + switch (e->type) { + case e_value: + case e_const: return 1; + case e_func0: + case e_func1: + case e_squish: + case e_ld: + case e_gauss: + case e_isnan: + case e_isinf: + case e_floor: + case e_ceil: + case e_trunc: + case e_round: + case e_sqrt: + case e_not: + case e_random: + return verify_expr(e->param[0]) && !e->param[1]; + case e_print: + return verify_expr(e->param[0]) + && (!e->param[1] || verify_expr(e->param[1])); + case e_if: + case e_ifnot: + case e_taylor: + return verify_expr(e->param[0]) && verify_expr(e->param[1]) + && (!e->param[2] || verify_expr(e->param[2])); + case e_between: + case e_clip: + case e_lerp: + return verify_expr(e->param[0]) && + verify_expr(e->param[1]) && + verify_expr(e->param[2]); + default: return verify_expr(e->param[0]) && verify_expr(e->param[1]) && !e->param[2]; + } +} + +int av_expr_parse(AVExpr **expr, const char *s, + const char * const *const_names, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + int log_offset, void *log_ctx) +{ + Parser p = { 0 }; + AVExpr *e = NULL; + char *w = av_malloc(strlen(s) + 1); + char *wp = w; + const char *s0 = s; + int ret = 0; + + if (!w) + return AVERROR(ENOMEM); + + while (*s) + if (!av_isspace(*s++)) *wp++ = s[-1]; + *wp++ = 0; + + p.class = &eval_class; + p.stack_index=100; + p.s= w; + p.const_names = const_names; + p.funcs1 = funcs1; + p.func1_names = func1_names; + p.funcs2 = funcs2; + p.func2_names = func2_names; + p.log_offset = log_offset; + p.log_ctx = log_ctx; + + if ((ret = parse_expr(&e, &p)) < 0) + goto end; + if (*p.s) { + av_log(&p, AV_LOG_ERROR, "Invalid chars '%s' at the end of expression '%s'\n", p.s, s0); + ret = AVERROR(EINVAL); + goto end; + } + if (!verify_expr(e)) { + ret = AVERROR(EINVAL); + goto end; + } + e->var= av_mallocz(sizeof(double) *VARS); + if (!e->var) { + ret = AVERROR(ENOMEM); + goto end; + } + *expr = e; + e = NULL; +end: + av_expr_free(e); + av_free(w); + return ret; +} + +double av_expr_eval(AVExpr *e, const double *const_values, void *opaque) +{ + Parser p = { 0 }; + p.var= e->var; + + p.const_values = const_values; + p.opaque = opaque; + return eval_expr(&p, e); +} + +int av_expr_parse_and_eval(double *d, const char *s, + const char * const *const_names, const double *const_values, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + void *opaque, int log_offset, void *log_ctx) +{ + AVExpr *e = NULL; + int ret = av_expr_parse(&e, s, const_names, func1_names, funcs1, func2_names, funcs2, log_offset, log_ctx); + + if (ret < 0) { + *d = NAN; + return ret; + } + *d = av_expr_eval(e, const_values, opaque); + av_expr_free(e); + return isnan(*d) ? AVERROR(EINVAL) : 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/eval.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/eval.h new file mode 100644 index 000000000..dacd22b96 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/eval.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2002 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * simple arithmetic expression evaluator + */ + +#ifndef AVUTIL_EVAL_H +#define AVUTIL_EVAL_H + +#include "avutil.h" + +typedef struct AVExpr AVExpr; + +/** + * Parse and evaluate an expression. + * Note, this is significantly slower than av_expr_eval(). + * + * @param res a pointer to a double where is put the result value of + * the expression, or NAN in case of error + * @param s expression as a zero terminated string, for example "1+2^3+5*5+sin(2/3)" + * @param const_names NULL terminated array of zero terminated strings of constant identifiers, for example {"PI", "E", 0} + * @param const_values a zero terminated array of values for the identifiers from const_names + * @param func1_names NULL terminated array of zero terminated strings of funcs1 identifiers + * @param funcs1 NULL terminated array of function pointers for functions which take 1 argument + * @param func2_names NULL terminated array of zero terminated strings of funcs2 identifiers + * @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments + * @param opaque a pointer which will be passed to all functions from funcs1 and funcs2 + * @param log_ctx parent logging context + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code otherwise + */ +int av_expr_parse_and_eval(double *res, const char *s, + const char * const *const_names, const double *const_values, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + void *opaque, int log_offset, void *log_ctx); + +/** + * Parse an expression. + * + * @param expr a pointer where is put an AVExpr containing the parsed + * value in case of successful parsing, or NULL otherwise. + * The pointed to AVExpr must be freed with av_expr_free() by the user + * when it is not needed anymore. + * @param s expression as a zero terminated string, for example "1+2^3+5*5+sin(2/3)" + * @param const_names NULL terminated array of zero terminated strings of constant identifiers, for example {"PI", "E", 0} + * @param func1_names NULL terminated array of zero terminated strings of funcs1 identifiers + * @param funcs1 NULL terminated array of function pointers for functions which take 1 argument + * @param func2_names NULL terminated array of zero terminated strings of funcs2 identifiers + * @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments + * @param log_ctx parent logging context + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code otherwise + */ +int av_expr_parse(AVExpr **expr, const char *s, + const char * const *const_names, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + int log_offset, void *log_ctx); + +/** + * Evaluate a previously parsed expression. + * + * @param const_values a zero terminated array of values for the identifiers from av_expr_parse() const_names + * @param opaque a pointer which will be passed to all functions from funcs1 and funcs2 + * @return the value of the expression + */ +double av_expr_eval(AVExpr *e, const double *const_values, void *opaque); + +/** + * Free a parsed expression previously created with av_expr_parse(). + */ +void av_expr_free(AVExpr *e); + +/** + * Parse the string in numstr and return its value as a double. If + * the string is empty, contains only whitespaces, or does not contain + * an initial substring that has the expected syntax for a + * floating-point number, no conversion is performed. In this case, + * returns a value of zero and the value returned in tail is the value + * of numstr. + * + * @param numstr a string representing a number, may contain one of + * the International System number postfixes, for example 'K', 'M', + * 'G'. If 'i' is appended after the postfix, powers of 2 are used + * instead of powers of 10. The 'B' postfix multiplies the value by + * 8, and can be appended after another postfix or used alone. This + * allows using for example 'KB', 'MiB', 'G' and 'B' as postfix. + * @param tail if non-NULL puts here the pointer to the char next + * after the last parsed character + */ +double av_strtod(const char *numstr, char **tail); + +#endif /* AVUTIL_EVAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffmath.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffmath.h new file mode 100644 index 000000000..aad1347f2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffmath.h @@ -0,0 +1,67 @@ +/* + * copyright (c) 2016 Ganesh Ajjanagadde + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * internal math functions header + */ + +#ifndef AVUTIL_FFMATH_H +#define AVUTIL_FFMATH_H + +#include "attributes.h" +#include "libm.h" + +/** + * Compute 10^x for floating point values. Note: this function is by no means + * "correctly rounded", and is meant as a fast, reasonably accurate approximation. + * For instance, maximum relative error for the double precision variant is + * ~ 1e-13 for very small and very large values. + * This is ~2x faster than GNU libm's approach, which is still off by 2ulp on + * some inputs. + * @param x exponent + * @return 10^x + */ +static av_always_inline double ff_exp10(double x) +{ + return exp2(M_LOG2_10 * x); +} + +static av_always_inline float ff_exp10f(float x) +{ + return exp2f(M_LOG2_10 * x); +} + +/** + * Compute x^y for floating point x, y. Note: this function is faster than the + * libm variant due to mainly 2 reasons: + * 1. It does not handle any edge cases. In particular, this is only guaranteed + * to work correctly for x > 0. + * 2. It is not as accurate as a standard nearly "correctly rounded" libm variant. + * @param x base + * @param y exponent + * @return x^y + */ +static av_always_inline float ff_fast_powf(float x, float y) +{ + return expf(logf(x) * y); +} + +#endif /* AVUTIL_FFMATH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffversion.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffversion.h new file mode 100644 index 000000000..723c7d424 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffversion.h @@ -0,0 +1,5 @@ +/* Automatically generated by version.sh, do not manually edit! */ +#ifndef AVUTIL_FFVERSION_H +#define AVUTIL_FFVERSION_H +#define FFMPEG_VERSION "" +#endif /* AVUTIL_FFVERSION_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fifo.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fifo.c new file mode 100644 index 000000000..1060aedf1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fifo.c @@ -0,0 +1,240 @@ +/* + * a very simple circular buffer FIFO implementation + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * Copyright (c) 2006 Roman Shaposhnik + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avassert.h" +#include "common.h" +#include "fifo.h" + +static AVFifoBuffer *fifo_alloc_common(void *buffer, size_t size) +{ + AVFifoBuffer *f; + if (!buffer) + return NULL; + f = av_mallocz(sizeof(AVFifoBuffer)); + if (!f) { + av_free(buffer); + return NULL; + } + f->buffer = buffer; + f->end = f->buffer + size; + av_fifo_reset(f); + return f; +} + +AVFifoBuffer *av_fifo_alloc(unsigned int size) +{ + void *buffer = av_malloc(size); + return fifo_alloc_common(buffer, size); +} + +AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size) +{ + void *buffer = av_malloc_array(nmemb, size); + return fifo_alloc_common(buffer, nmemb * size); +} + +void av_fifo_free(AVFifoBuffer *f) +{ + if (f) { + av_freep(&f->buffer); + av_free(f); + } +} + +void av_fifo_freep(AVFifoBuffer **f) +{ + if (f) { + av_fifo_free(*f); + *f = NULL; + } +} + +void av_fifo_reset(AVFifoBuffer *f) +{ + f->wptr = f->rptr = f->buffer; + f->wndx = f->rndx = 0; +} + +int av_fifo_size(const AVFifoBuffer *f) +{ + return (uint32_t)(f->wndx - f->rndx); +} + +int av_fifo_space(const AVFifoBuffer *f) +{ + return f->end - f->buffer - av_fifo_size(f); +} + +int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) +{ + unsigned int old_size = f->end - f->buffer; + + if (old_size < new_size) { + int len = av_fifo_size(f); + AVFifoBuffer *f2 = av_fifo_alloc(new_size); + + if (!f2) + return AVERROR(ENOMEM); + av_fifo_generic_read(f, f2->buffer, len, NULL); + f2->wptr += len; + f2->wndx += len; + av_free(f->buffer); + *f = *f2; + av_free(f2); + } + return 0; +} + +int av_fifo_grow(AVFifoBuffer *f, unsigned int size) +{ + unsigned int old_size = f->end - f->buffer; + if(size + (unsigned)av_fifo_size(f) < size) + return AVERROR(EINVAL); + + size += av_fifo_size(f); + + if (old_size < size) + return av_fifo_realloc2(f, FFMAX(size, 2*old_size)); + return 0; +} + +/* src must NOT be const as it can be a context for func that may need + * updating (like a pointer or byte counter) */ +int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, + int (*func)(void *, void *, int)) +{ + int total = size; + uint32_t wndx= f->wndx; + uint8_t *wptr= f->wptr; + + do { + int len = FFMIN(f->end - wptr, size); + if (func) { + len = func(src, wptr, len); + if (len <= 0) + break; + } else { + memcpy(wptr, src, len); + src = (uint8_t *)src + len; + } +// Write memory barrier needed for SMP here in theory + wptr += len; + if (wptr >= f->end) + wptr = f->buffer; + wndx += len; + size -= len; + } while (size > 0); + f->wndx= wndx; + f->wptr= wptr; + return total - size; +} + +int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int)) +{ + uint8_t *rptr = f->rptr; + + av_assert2(offset >= 0); + + /* + * *ndx are indexes modulo 2^32, they are intended to overflow, + * to handle *ndx greater than 4gb. + */ + av_assert2(buf_size + (unsigned)offset <= f->wndx - f->rndx); + + if (offset >= f->end - rptr) + rptr += offset - (f->end - f->buffer); + else + rptr += offset; + + while (buf_size > 0) { + int len; + + if (rptr >= f->end) + rptr -= f->end - f->buffer; + + len = FFMIN(f->end - rptr, buf_size); + if (func) + func(dest, rptr, len); + else { + memcpy(dest, rptr, len); + dest = (uint8_t *)dest + len; + } + + buf_size -= len; + rptr += len; + } + + return 0; +} + +int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, + void (*func)(void *, void *, int)) +{ +// Read memory barrier needed for SMP here in theory + uint8_t *rptr = f->rptr; + + do { + int len = FFMIN(f->end - rptr, buf_size); + if (func) + func(dest, rptr, len); + else { + memcpy(dest, rptr, len); + dest = (uint8_t *)dest + len; + } +// memory barrier needed for SMP here in theory + rptr += len; + if (rptr >= f->end) + rptr -= f->end - f->buffer; + buf_size -= len; + } while (buf_size > 0); + + return 0; +} + +int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, + void (*func)(void *, void *, int)) +{ +// Read memory barrier needed for SMP here in theory + do { + int len = FFMIN(f->end - f->rptr, buf_size); + if (func) + func(dest, f->rptr, len); + else { + memcpy(dest, f->rptr, len); + dest = (uint8_t *)dest + len; + } +// memory barrier needed for SMP here in theory + av_fifo_drain(f, len); + buf_size -= len; + } while (buf_size > 0); + return 0; +} + +/** Discard data from the FIFO. */ +void av_fifo_drain(AVFifoBuffer *f, int size) +{ + av_assert2(av_fifo_size(f) >= size); + f->rptr += size; + if (f->rptr >= f->end) + f->rptr -= f->end - f->buffer; + f->rndx += size; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fifo.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fifo.h new file mode 100644 index 000000000..dc7bc6f0d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fifo.h @@ -0,0 +1,179 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * a very simple circular buffer FIFO implementation + */ + +#ifndef AVUTIL_FIFO_H +#define AVUTIL_FIFO_H + +#include +#include "avutil.h" +#include "attributes.h" + +typedef struct AVFifoBuffer { + uint8_t *buffer; + uint8_t *rptr, *wptr, *end; + uint32_t rndx, wndx; +} AVFifoBuffer; + +/** + * Initialize an AVFifoBuffer. + * @param size of FIFO + * @return AVFifoBuffer or NULL in case of memory allocation failure + */ +AVFifoBuffer *av_fifo_alloc(unsigned int size); + +/** + * Initialize an AVFifoBuffer. + * @param nmemb number of elements + * @param size size of the single element + * @return AVFifoBuffer or NULL in case of memory allocation failure + */ +AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size); + +/** + * Free an AVFifoBuffer. + * @param f AVFifoBuffer to free + */ +void av_fifo_free(AVFifoBuffer *f); + +/** + * Free an AVFifoBuffer and reset pointer to NULL. + * @param f AVFifoBuffer to free + */ +void av_fifo_freep(AVFifoBuffer **f); + +/** + * Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied. + * @param f AVFifoBuffer to reset + */ +void av_fifo_reset(AVFifoBuffer *f); + +/** + * Return the amount of data in bytes in the AVFifoBuffer, that is the + * amount of data you can read from it. + * @param f AVFifoBuffer to read from + * @return size + */ +int av_fifo_size(const AVFifoBuffer *f); + +/** + * Return the amount of space in bytes in the AVFifoBuffer, that is the + * amount of data you can write into it. + * @param f AVFifoBuffer to write into + * @return size + */ +int av_fifo_space(const AVFifoBuffer *f); + +/** + * Feed data at specific position from an AVFifoBuffer to a user-supplied callback. + * Similar as av_fifo_gereric_read but without discarding data. + * @param f AVFifoBuffer to read from + * @param offset offset from current read position + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + */ +int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feed data from an AVFifoBuffer to a user-supplied callback. + * Similar as av_fifo_gereric_read but without discarding data. + * @param f AVFifoBuffer to read from + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + */ +int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feed data from an AVFifoBuffer to a user-supplied callback. + * @param f AVFifoBuffer to read from + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + */ +int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feed data from a user-supplied callback to an AVFifoBuffer. + * @param f AVFifoBuffer to write to + * @param src data source; non-const since it may be used as a + * modifiable context by the function defined in func + * @param size number of bytes to write + * @param func generic write function; the first parameter is src, + * the second is dest_buf, the third is dest_buf_size. + * func must return the number of bytes written to dest_buf, or <= 0 to + * indicate no more data available to write. + * If func is NULL, src is interpreted as a simple byte array for source data. + * @return the number of bytes written to the FIFO + */ +int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)); + +/** + * Resize an AVFifoBuffer. + * In case of reallocation failure, the old FIFO is kept unchanged. + * + * @param f AVFifoBuffer to resize + * @param size new AVFifoBuffer size in bytes + * @return <0 for failure, >=0 otherwise + */ +int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size); + +/** + * Enlarge an AVFifoBuffer. + * In case of reallocation failure, the old FIFO is kept unchanged. + * The new fifo size may be larger than the requested size. + * + * @param f AVFifoBuffer to resize + * @param additional_space the amount of space in bytes to allocate in addition to av_fifo_size() + * @return <0 for failure, >=0 otherwise + */ +int av_fifo_grow(AVFifoBuffer *f, unsigned int additional_space); + +/** + * Read and discard the specified amount of data from an AVFifoBuffer. + * @param f AVFifoBuffer to read from + * @param size amount of data to read in bytes + */ +void av_fifo_drain(AVFifoBuffer *f, int size); + +/** + * Return a pointer to the data stored in a FIFO buffer at a certain offset. + * The FIFO buffer is not modified. + * + * @param f AVFifoBuffer to peek at, f must be non-NULL + * @param offs an offset in bytes, its absolute value must be less + * than the used buffer size or the returned pointer will + * point outside to the buffer data. + * The used buffer size can be checked with av_fifo_size(). + */ +static inline uint8_t *av_fifo_peek2(const AVFifoBuffer *f, int offs) +{ + uint8_t *ptr = f->rptr + offs; + if (ptr >= f->end) + ptr = f->buffer + (ptr - f->end); + else if (ptr < f->buffer) + ptr = f->end - (f->buffer - ptr); + return ptr; +} + +#endif /* AVUTIL_FIFO_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file.c new file mode 100644 index 000000000..d946085b2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file.c @@ -0,0 +1,154 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "file.h" +#include "internal.h" +#include "log.h" +#include "mem.h" +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_IO_H +#include +#endif +#if HAVE_MMAP +#include +#elif HAVE_MAPVIEWOFFILE +#include +#endif + +typedef struct FileLogContext { + const AVClass *class; + int log_offset; + void *log_ctx; +} FileLogContext; + +static const AVClass file_log_ctx_class = { + .class_name = "FILE", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(FileLogContext, log_offset), + .parent_log_context_offset = offsetof(FileLogContext, log_ctx), +}; + +int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, + int log_offset, void *log_ctx) +{ + FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx }; + int err, fd = avpriv_open(filename, O_RDONLY); + struct stat st; + av_unused void *ptr; + off_t off_size; + char errbuf[128]; + *bufptr = NULL; + + if (fd < 0) { + err = AVERROR(errno); + av_strerror(err, errbuf, sizeof(errbuf)); + av_log(&file_log_ctx, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, errbuf); + return err; + } + + if (fstat(fd, &st) < 0) { + err = AVERROR(errno); + av_strerror(err, errbuf, sizeof(errbuf)); + av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in fstat(): %s\n", errbuf); + close(fd); + return err; + } + + off_size = st.st_size; + if (off_size > SIZE_MAX) { + av_log(&file_log_ctx, AV_LOG_ERROR, + "File size for file '%s' is too big\n", filename); + close(fd); + return AVERROR(EINVAL); + } + *size = off_size; + + if (!*size) { + *bufptr = NULL; + goto out; + } + +#if HAVE_MMAP + ptr = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); + if (ptr == MAP_FAILED) { + err = AVERROR(errno); + av_strerror(err, errbuf, sizeof(errbuf)); + av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in mmap(): %s\n", errbuf); + close(fd); + return err; + } + *bufptr = ptr; +#elif HAVE_MAPVIEWOFFILE + { + HANDLE mh, fh = (HANDLE)_get_osfhandle(fd); + + mh = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, NULL); + if (!mh) { + av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in CreateFileMapping()\n"); + close(fd); + return -1; + } + + ptr = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, *size); + CloseHandle(mh); + if (!ptr) { + av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in MapViewOfFile()\n"); + close(fd); + return -1; + } + + *bufptr = ptr; + } +#else + *bufptr = av_malloc(*size); + if (!*bufptr) { + av_log(&file_log_ctx, AV_LOG_ERROR, "Memory allocation error occurred\n"); + close(fd); + return AVERROR(ENOMEM); + } + read(fd, *bufptr, *size); +#endif + +out: + close(fd); + return 0; +} + +void av_file_unmap(uint8_t *bufptr, size_t size) +{ + if (!size) + return; +#if HAVE_MMAP + munmap(bufptr, size); +#elif HAVE_MAPVIEWOFFILE + UnmapViewOfFile(bufptr); +#else + av_free(bufptr); +#endif +} + +int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) { + return avpriv_tempfile(prefix, filename, log_offset, log_ctx); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file.h new file mode 100644 index 000000000..3ef4a6022 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file.h @@ -0,0 +1,71 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FILE_H +#define AVUTIL_FILE_H + +#include + +#include "avutil.h" + +/** + * @file + * Misc file utilities. + */ + +/** + * Read the file with name filename, and put its content in a newly + * allocated buffer or map it with mmap() when available. + * In case of success set *bufptr to the read or mmapped buffer, and + * *size to the size in bytes of the buffer in *bufptr. + * Unlike mmap this function succeeds with zero sized files, in this + * case *bufptr will be set to NULL and *size will be set to 0. + * The returned buffer must be released with av_file_unmap(). + * + * @param log_offset loglevel offset used for logging + * @param log_ctx context used for logging + * @return a non negative number in case of success, a negative value + * corresponding to an AVERROR error code in case of failure + */ +av_warn_unused_result +int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, + int log_offset, void *log_ctx); + +/** + * Unmap or free the buffer bufptr created by av_file_map(). + * + * @param size size in bytes of bufptr, must be the same as returned + * by av_file_map() + */ +void av_file_unmap(uint8_t *bufptr, size_t size); + +/** + * Wrapper to work around the lack of mkstemp() on mingw. + * Also, tries to create file in /tmp first, if possible. + * *prefix can be a character constant; *filename will be allocated internally. + * @return file descriptor of opened file (or negative value corresponding to an + * AVERROR code on error) + * and opened file name in **filename. + * @note On very old libcs it is necessary to set a secure umask before + * calling this, av_tempfile() can't call umask itself as it is used in + * libraries and could interfere with the calling application. + * @deprecated as fd numbers cannot be passed saftely between libs on some platforms + */ +int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx); + +#endif /* AVUTIL_FILE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file_open.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file_open.c new file mode 100644 index 000000000..cc302f2f7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/file_open.c @@ -0,0 +1,190 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "internal.h" +#include "mem.h" +#include +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_IO_H +#include +#endif + +#ifdef _WIN32 +#undef open +#undef lseek +#undef stat +#undef fstat +#include +#include +#include +#include "wchar_filename.h" + +static int win32_open(const char *filename_utf8, int oflag, int pmode) +{ + int fd; + wchar_t *filename_w; + + /* convert UTF-8 to wide chars */ + if (utf8towchar(filename_utf8, &filename_w)) + return -1; + if (!filename_w) + goto fallback; + + fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode); + av_freep(&filename_w); + + if (fd != -1 || (oflag & O_CREAT)) + return fd; + +fallback: + /* filename may be in CP_ACP */ + return _sopen(filename_utf8, oflag, SH_DENYNO, pmode); +} +#define open win32_open +#endif + +int avpriv_open(const char *filename, int flags, ...) +{ + int fd; + unsigned int mode = 0; + va_list ap; + + va_start(ap, flags); + if (flags & O_CREAT) + mode = va_arg(ap, unsigned int); + va_end(ap); + +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif +#ifdef O_NOINHERIT + flags |= O_NOINHERIT; +#endif + + fd = open(filename, flags, mode); +#if HAVE_FCNTL + if (fd != -1) { + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + av_log(NULL, AV_LOG_DEBUG, "Failed to set close on exec\n"); + } +#endif + + return fd; +} + +typedef struct FileLogContext { + const AVClass *class; + int log_offset; + void *log_ctx; +} FileLogContext; + +static const AVClass file_log_ctx_class = { + .class_name = "TEMPFILE", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(FileLogContext, log_offset), + .parent_log_context_offset = offsetof(FileLogContext, log_ctx), +}; + +int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) +{ + FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx }; + int fd = -1; +#if !HAVE_MKSTEMP + void *ptr= tempnam(NULL, prefix); + if(!ptr) + ptr= tempnam(".", prefix); + *filename = av_strdup(ptr); +#undef free + free(ptr); +#else + size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ + *filename = av_malloc(len); +#endif + /* -----common section-----*/ + if (!*filename) { + av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); + return AVERROR(ENOMEM); + } +#if !HAVE_MKSTEMP +# ifndef O_BINARY +# define O_BINARY 0 +# endif +# ifndef O_EXCL +# define O_EXCL 0 +# endif + fd = open(*filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600); +#else + snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); + fd = mkstemp(*filename); +#if defined(_WIN32) || defined (__ANDROID__) || defined(__DJGPP__) + if (fd < 0) { + snprintf(*filename, len, "./%sXXXXXX", prefix); + fd = mkstemp(*filename); + } +#endif +#endif + /* -----common section-----*/ + if (fd < 0) { + int err = AVERROR(errno); + av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); + av_freep(filename); + return err; + } + return fd; /* success */ +} + +FILE *av_fopen_utf8(const char *path, const char *mode) +{ + int fd; + int access; + const char *m = mode; + + switch (*m++) { + case 'r': access = O_RDONLY; break; + case 'w': access = O_CREAT|O_WRONLY|O_TRUNC; break; + case 'a': access = O_CREAT|O_WRONLY|O_APPEND; break; + default : + errno = EINVAL; + return NULL; + } + while (*m) { + if (*m == '+') { + access &= ~(O_RDONLY | O_WRONLY); + access |= O_RDWR; + } else if (*m == 'b') { +#ifdef O_BINARY + access |= O_BINARY; +#endif + } else if (*m) { + errno = EINVAL; + return NULL; + } + m++; + } + fd = avpriv_open(path, access, 0666); + if (fd == -1) + return NULL; + return fdopen(fd, mode); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fixed_dsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fixed_dsp.c new file mode 100644 index 000000000..8c018581d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fixed_dsp.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Nedeljko Babic (nedeljko.babic imgtec com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "fixed_dsp.h" + +static void vector_fmul_add_c(int *dst, const int *src0, const int *src1, const int *src2, int len){ + int i; + int64_t accu; + + for (i=0; i> 31); + } +} + +static void vector_fmul_reverse_c(int *dst, const int *src0, const int *src1, int len) +{ + int i; + int64_t accu; + + src1 += len-1; + for (i=0; i> 31); + } +} + +static void vector_fmul_window_scaled_c(int16_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len, uint8_t bits) +{ + int32_t s0, s1, wi, wj, i,j, round; + + dst += len; + win += len; + src0+= len; + round = bits? 1 << (bits-1) : 0; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = av_clip_int16(((((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31) + round) >> bits); + dst[j] = av_clip_int16(((((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31) + round) >> bits); + } +} + +static void vector_fmul_window_c(int32_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len) +{ + int32_t s0, s1, wi, wj, i, j; + + dst += len; + win += len; + src0+= len; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = ((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31; + dst[j] = ((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31; + } +} + +static void vector_fmul_c(int *dst, const int *src0, const int *src1, int len) +{ + int i; + int64_t accu; + + for (i = 0; i < len; i++){ + accu = (int64_t)src0[i] * src1[i]; + dst[i] = (int)((accu+0x40000000) >> 31); + } +} + +static int scalarproduct_fixed_c(const int *v1, const int *v2, int len) +{ + /** p is initialized with 0x40000000 so that the proper rounding will occur + * at the end */ + int64_t p = 0x40000000; + int i; + + for (i = 0; i < len; i++) + p += (int64_t)v1[i] * v2[i]; + + return (int)(p >> 31); +} + +static void butterflies_fixed_c(int *v1, int *v2, int len) +{ + int i; + + for (i = 0; i < len; i++){ + int t = v1[i] - v2[i]; + v1[i] += v2[i]; + v2[i] = t; + } +} + +AVFixedDSPContext * avpriv_alloc_fixed_dsp(int bit_exact) +{ + AVFixedDSPContext * fdsp = av_malloc(sizeof(AVFixedDSPContext)); + + if (!fdsp) + return NULL; + + fdsp->vector_fmul_window_scaled = vector_fmul_window_scaled_c; + fdsp->vector_fmul_window = vector_fmul_window_c; + fdsp->vector_fmul = vector_fmul_c; + fdsp->vector_fmul_add = vector_fmul_add_c; + fdsp->vector_fmul_reverse = vector_fmul_reverse_c; + fdsp->butterflies_fixed = butterflies_fixed_c; + fdsp->scalarproduct_fixed = scalarproduct_fixed_c; + + if (ARCH_X86) + ff_fixed_dsp_init_x86(fdsp); + + return fdsp; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fixed_dsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fixed_dsp.h new file mode 100644 index 000000000..f554cb503 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/fixed_dsp.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Nedeljko Babic (nbabic@mips.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FIXED_DSP_H +#define AVUTIL_FIXED_DSP_H + +#include +#include "attributes.h" +#include "common.h" +#include "libavcodec/mathops.h" + +typedef struct AVFixedDSPContext { + /* Assume len is a multiple of 16, and arrays are 32-byte aligned */ + /* Results of multiplications are scaled down by 31 bit (and rounded) if not + * stated otherwise */ + + /** + * Overlap/add with window function. + * Result is scaled down by "bits" bits. + * Used primarily by MDCT-based audio codecs. + * Source and destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 16-byte aligned + * @param src0 first source vector + * constraints: 16-byte aligned + * @param src1 second source vector + * constraints: 16-byte aligned + * @param win half-window vector + * constraints: 16-byte aligned + * @param len length of vector + * constraints: multiple of 4 + * @param bits scaling parameter + * + */ + void (*vector_fmul_window_scaled)(int16_t *dst, const int32_t *src0, const int32_t *src1, const int32_t *win, int len, uint8_t bits); + + /** + * Overlap/add with window function. + * Used primarily by MDCT-based audio codecs. + * Source and destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 32-byte aligned + * @param src0 first source vector + * constraints: 16-byte aligned + * @param src1 second source vector + * constraints: 16-byte aligned + * @param win half-window vector + * constraints: 16-byte aligned + * @param len length of vector + * constraints: multiple of 4 + */ + void (*vector_fmul_window)(int32_t *dst, const int32_t *src0, const int32_t *src1, const int32_t *win, int len); + + /** + * Fixed-point multiplication that calculates the entry wise product of two + * vectors of integers and stores the result in a vector of integers. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul)(int *dst, const int *src0, const int *src1, + int len); + + void (*vector_fmul_reverse)(int *dst, const int *src0, const int *src1, int len); + /** + * Calculate the entry wise product of two vectors of integers, add a third vector of + * integers and store the result in a vector of integers. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param src2 third input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul_add)(int *dst, const int *src0, const int *src1, + const int *src2, int len); + + /** + * Calculate the scalar product of two vectors of integers. + * + * @param v1 first vector, 16-byte aligned + * @param v2 second vector, 16-byte aligned + * @param len length of vectors, multiple of 4 + * + * @return sum of elementwise products + */ + int (*scalarproduct_fixed)(const int *v1, const int *v2, int len); + + /** + * Calculate the sum and difference of two vectors of integers. + * + * @param v1 first input vector, sum output, 16-byte aligned + * @param v2 second input vector, difference output, 16-byte aligned + * @param len length of vectors, multiple of 4 + */ + void (*butterflies_fixed)(int *av_restrict v1, int *av_restrict v2, int len); +} AVFixedDSPContext; + +/** + * Allocate and initialize a fixed DSP context. + * note: should be freed with a av_free call when no longer needed. + * + * @param strict setting to non-zero avoids using functions which may not be IEEE-754 compliant + */ +AVFixedDSPContext * avpriv_alloc_fixed_dsp(int strict); + +void ff_fixed_dsp_init_x86(AVFixedDSPContext *fdsp); + +/** + * Calculate the square root + * + * @param x input fixed point number + * + * @param bits format of fixed point number (32 - bits).bits + * + * note: input is normalized to (0, 1) fixed point value + */ + +static av_always_inline int fixed_sqrt(int x, int bits) +{ + int retval, bit_mask, guess, square, i; + int64_t accu; + int shift1 = 30 - bits; + int shift2 = bits - 15; + + if (shift1 > 0) retval = ff_sqrt(x << shift1); + else retval = ff_sqrt(x >> -shift1); + + if (shift2 > 0) { + retval = retval << shift2; + bit_mask = (1 << (shift2 - 1)); + + for (i=0; i> bits); + if (x >= square) + retval += bit_mask; + bit_mask >>= 1; + } + + } + else retval >>= (-shift2); + + return retval; +} + +#endif /* AVUTIL_FIXED_DSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/float_dsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/float_dsp.c new file mode 100644 index 000000000..6e28d71b5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/float_dsp.c @@ -0,0 +1,164 @@ +/* + * Copyright 2005 Balatoni Denes + * Copyright 2006 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "attributes.h" +#include "float_dsp.h" +#include "mem.h" + +static void vector_fmul_c(float *dst, const float *src0, const float *src1, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] = src0[i] * src1[i]; +} + +static void vector_dmul_c(double *dst, const double *src0, const double *src1, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] = src0[i] * src1[i]; +} + +static void vector_fmac_scalar_c(float *dst, const float *src, float mul, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] += src[i] * mul; +} + +static void vector_dmac_scalar_c(double *dst, const double *src, double mul, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] += src[i] * mul; +} + +static void vector_fmul_scalar_c(float *dst, const float *src, float mul, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] = src[i] * mul; +} + +static void vector_dmul_scalar_c(double *dst, const double *src, double mul, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] = src[i] * mul; +} + +static void vector_fmul_window_c(float *dst, const float *src0, + const float *src1, const float *win, int len) +{ + int i, j; + + dst += len; + win += len; + src0 += len; + + for (i = -len, j = len - 1; i < 0; i++, j--) { + float s0 = src0[i]; + float s1 = src1[j]; + float wi = win[i]; + float wj = win[j]; + dst[i] = s0 * wj - s1 * wi; + dst[j] = s0 * wi + s1 * wj; + } +} + +static void vector_fmul_add_c(float *dst, const float *src0, const float *src1, + const float *src2, int len){ + int i; + + for (i = 0; i < len; i++) + dst[i] = src0[i] * src1[i] + src2[i]; +} + +static void vector_fmul_reverse_c(float *dst, const float *src0, + const float *src1, int len) +{ + int i; + + src1 += len-1; + for (i = 0; i < len; i++) + dst[i] = src0[i] * src1[-i]; +} + +static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2, + int len) +{ + int i; + + for (i = 0; i < len; i++) { + float t = v1[i] - v2[i]; + v1[i] += v2[i]; + v2[i] = t; + } +} + +float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len) +{ + float p = 0.0; + int i; + + for (i = 0; i < len; i++) + p += v1[i] * v2[i]; + + return p; +} + +av_cold AVFloatDSPContext *avpriv_float_dsp_alloc(int bit_exact) +{ + AVFloatDSPContext *fdsp = av_mallocz(sizeof(AVFloatDSPContext)); + if (!fdsp) + return NULL; + + fdsp->vector_fmul = vector_fmul_c; + fdsp->vector_dmul = vector_dmul_c; + fdsp->vector_fmac_scalar = vector_fmac_scalar_c; + fdsp->vector_fmul_scalar = vector_fmul_scalar_c; + fdsp->vector_dmac_scalar = vector_dmac_scalar_c; + fdsp->vector_dmul_scalar = vector_dmul_scalar_c; + fdsp->vector_fmul_window = vector_fmul_window_c; + fdsp->vector_fmul_add = vector_fmul_add_c; + fdsp->vector_fmul_reverse = vector_fmul_reverse_c; + fdsp->butterflies_float = butterflies_float_c; + fdsp->scalarproduct_float = avpriv_scalarproduct_float_c; + + if (ARCH_AARCH64) + ff_float_dsp_init_aarch64(fdsp); + if (ARCH_ARM) + ff_float_dsp_init_arm(fdsp); + if (ARCH_PPC) + ff_float_dsp_init_ppc(fdsp, bit_exact); + if (ARCH_X86) + ff_float_dsp_init_x86(fdsp); + if (ARCH_MIPS) + ff_float_dsp_init_mips(fdsp); + return fdsp; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/float_dsp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/float_dsp.h new file mode 100644 index 000000000..9c664592b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/float_dsp.h @@ -0,0 +1,218 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FLOAT_DSP_H +#define AVUTIL_FLOAT_DSP_H + +#include "config.h" + +typedef struct AVFloatDSPContext { + /** + * Calculate the entry wise product of two vectors of floats and store the result in + * a vector of floats. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul)(float *dst, const float *src0, const float *src1, + int len); + + /** + * Multiply a vector of floats by a scalar float and add to + * destination vector. Source and destination vectors must + * overlap exactly or not at all. + * + * @param dst result vector + * constraints: 32-byte aligned + * @param src input vector + * constraints: 32-byte aligned + * @param mul scalar value + * @param len length of vector + * constraints: multiple of 16 + */ + void (*vector_fmac_scalar)(float *dst, const float *src, float mul, + int len); + + /** + * Multiply a vector of doubles by a scalar double and add to + * destination vector. Source and destination vectors must + * overlap exactly or not at all. + * + * @param dst result vector + * constraints: 32-byte aligned + * @param src input vector + * constraints: 32-byte aligned + * @param mul scalar value + * @param len length of vector + * constraints: multiple of 16 + */ + void (*vector_dmac_scalar)(double *dst, const double *src, double mul, + int len); + + /** + * Multiply a vector of floats by a scalar float. Source and + * destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 16-byte aligned + * @param src input vector + * constraints: 16-byte aligned + * @param mul scalar value + * @param len length of vector + * constraints: multiple of 4 + */ + void (*vector_fmul_scalar)(float *dst, const float *src, float mul, + int len); + + /** + * Multiply a vector of double by a scalar double. Source and + * destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 32-byte aligned + * @param src input vector + * constraints: 32-byte aligned + * @param mul scalar value + * @param len length of vector + * constraints: multiple of 8 + */ + void (*vector_dmul_scalar)(double *dst, const double *src, double mul, + int len); + + /** + * Overlap/add with window function. + * Used primarily by MDCT-based audio codecs. + * Source and destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 16-byte aligned + * @param src0 first source vector + * constraints: 16-byte aligned + * @param src1 second source vector + * constraints: 16-byte aligned + * @param win half-window vector + * constraints: 16-byte aligned + * @param len length of vector + * constraints: multiple of 4 + */ + void (*vector_fmul_window)(float *dst, const float *src0, + const float *src1, const float *win, int len); + + /** + * Calculate the entry wise product of two vectors of floats, add a third vector of + * floats and store the result in a vector of floats. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param src2 third input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul_add)(float *dst, const float *src0, const float *src1, + const float *src2, int len); + + /** + * Calculate the entry wise product of two vectors of floats, and store the result + * in a vector of floats. The second vector of floats is iterated over + * in reverse order. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_fmul_reverse)(float *dst, const float *src0, + const float *src1, int len); + + /** + * Calculate the sum and difference of two vectors of floats. + * + * @param v1 first input vector, sum output, 16-byte aligned + * @param v2 second input vector, difference output, 16-byte aligned + * @param len length of vectors, multiple of 4 + */ + void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len); + + /** + * Calculate the scalar product of two vectors of floats. + * + * @param v1 first vector, 16-byte aligned + * @param v2 second vector, 16-byte aligned + * @param len length of vectors, multiple of 4 + * + * @return sum of elementwise products + */ + float (*scalarproduct_float)(const float *v1, const float *v2, int len); + + /** + * Calculate the entry wise product of two vectors of doubles and store the result in + * a vector of doubles. + * + * @param dst output vector + * constraints: 32-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 16 + */ + void (*vector_dmul)(double *dst, const double *src0, const double *src1, + int len); +} AVFloatDSPContext; + +/** + * Return the scalar product of two vectors. + * + * @param v1 first input vector + * @param v2 first input vector + * @param len number of elements + * + * @return sum of elementwise products + */ +float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len); + +void ff_float_dsp_init_aarch64(AVFloatDSPContext *fdsp); +void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp); +void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int strict); +void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp); +void ff_float_dsp_init_mips(AVFloatDSPContext *fdsp); + +/** + * Allocate a float DSP context. + * + * @param strict setting to non-zero avoids using functions which may not be IEEE-754 compliant + */ +AVFloatDSPContext *avpriv_float_dsp_alloc(int strict); + +#endif /* AVUTIL_FLOAT_DSP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/frame.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/frame.c new file mode 100644 index 000000000..dcf1fc3d1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/frame.c @@ -0,0 +1,947 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "channel_layout.h" +#include "avassert.h" +#include "buffer.h" +#include "common.h" +#include "dict.h" +#include "frame.h" +#include "imgutils.h" +#include "mem.h" +#include "samplefmt.h" + +#if FF_API_FRAME_GET_SET +MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp) +MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_duration) +MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_pos) +MAKE_ACCESSORS(AVFrame, frame, int64_t, channel_layout) +MAKE_ACCESSORS(AVFrame, frame, int, channels) +MAKE_ACCESSORS(AVFrame, frame, int, sample_rate) +MAKE_ACCESSORS(AVFrame, frame, AVDictionary *, metadata) +MAKE_ACCESSORS(AVFrame, frame, int, decode_error_flags) +MAKE_ACCESSORS(AVFrame, frame, int, pkt_size) +MAKE_ACCESSORS(AVFrame, frame, enum AVColorSpace, colorspace) +MAKE_ACCESSORS(AVFrame, frame, enum AVColorRange, color_range) +#endif + +#define CHECK_CHANNELS_CONSISTENCY(frame) \ + av_assert2(!(frame)->channel_layout || \ + (frame)->channels == \ + av_get_channel_layout_nb_channels((frame)->channel_layout)) + +#if FF_API_FRAME_QP +struct qp_properties { + int stride; + int type; +}; + +int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int qp_type) +{ + struct qp_properties *p; + AVFrameSideData *sd; + AVBufferRef *ref; + +FF_DISABLE_DEPRECATION_WARNINGS + av_buffer_unref(&f->qp_table_buf); + + f->qp_table_buf = buf; + f->qscale_table = buf->data; + f->qstride = stride; + f->qscale_type = qp_type; +FF_ENABLE_DEPRECATION_WARNINGS + + av_frame_remove_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES); + av_frame_remove_side_data(f, AV_FRAME_DATA_QP_TABLE_DATA); + + ref = av_buffer_ref(buf); + if (!av_frame_new_side_data_from_buf(f, AV_FRAME_DATA_QP_TABLE_DATA, ref)) { + av_buffer_unref(&ref); + return AVERROR(ENOMEM); + } + + sd = av_frame_new_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES, + sizeof(struct qp_properties)); + if (!sd) + return AVERROR(ENOMEM); + + p = (struct qp_properties *)sd->data; + p->stride = stride; + p->type = qp_type; + + return 0; +} + +int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type) +{ + AVBufferRef *buf = NULL; + + *stride = 0; + *type = 0; + +FF_DISABLE_DEPRECATION_WARNINGS + if (f->qp_table_buf) { + *stride = f->qstride; + *type = f->qscale_type; + buf = f->qp_table_buf; +FF_ENABLE_DEPRECATION_WARNINGS + } else { + AVFrameSideData *sd; + struct qp_properties *p; + sd = av_frame_get_side_data(f, AV_FRAME_DATA_QP_TABLE_PROPERTIES); + if (!sd) + return NULL; + p = (struct qp_properties *)sd->data; + sd = av_frame_get_side_data(f, AV_FRAME_DATA_QP_TABLE_DATA); + if (!sd) + return NULL; + *stride = p->stride; + *type = p->type; + buf = sd->buf; + } + + return buf ? buf->data : NULL; +} +#endif + +const char *av_get_colorspace_name(enum AVColorSpace val) +{ + static const char * const name[] = { + [AVCOL_SPC_RGB] = "GBR", + [AVCOL_SPC_BT709] = "bt709", + [AVCOL_SPC_FCC] = "fcc", + [AVCOL_SPC_BT470BG] = "bt470bg", + [AVCOL_SPC_SMPTE170M] = "smpte170m", + [AVCOL_SPC_SMPTE240M] = "smpte240m", + [AVCOL_SPC_YCOCG] = "YCgCo", + }; + if ((unsigned)val >= FF_ARRAY_ELEMS(name)) + return NULL; + return name[val]; +} + +static void get_frame_defaults(AVFrame *frame) +{ + if (frame->extended_data != frame->data) + av_freep(&frame->extended_data); + + memset(frame, 0, sizeof(*frame)); + + frame->pts = + frame->pkt_dts = AV_NOPTS_VALUE; +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + frame->pkt_pts = AV_NOPTS_VALUE; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + frame->best_effort_timestamp = AV_NOPTS_VALUE; + frame->pkt_duration = 0; + frame->pkt_pos = -1; + frame->pkt_size = -1; + frame->key_frame = 1; + frame->sample_aspect_ratio = (AVRational){ 0, 1 }; + frame->format = -1; /* unknown */ + frame->extended_data = frame->data; + frame->color_primaries = AVCOL_PRI_UNSPECIFIED; + frame->color_trc = AVCOL_TRC_UNSPECIFIED; + frame->colorspace = AVCOL_SPC_UNSPECIFIED; + frame->color_range = AVCOL_RANGE_UNSPECIFIED; + frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED; + frame->flags = 0; +} + +static void free_side_data(AVFrameSideData **ptr_sd) +{ + AVFrameSideData *sd = *ptr_sd; + + av_buffer_unref(&sd->buf); + av_dict_free(&sd->metadata); + av_freep(ptr_sd); +} + +static void wipe_side_data(AVFrame *frame) +{ + int i; + + for (i = 0; i < frame->nb_side_data; i++) { + free_side_data(&frame->side_data[i]); + } + frame->nb_side_data = 0; + + av_freep(&frame->side_data); +} + +AVFrame *av_frame_alloc(void) +{ + AVFrame *frame = av_mallocz(sizeof(*frame)); + + if (!frame) + return NULL; + + frame->extended_data = NULL; + get_frame_defaults(frame); + + return frame; +} + +void av_frame_free(AVFrame **frame) +{ + if (!frame || !*frame) + return; + + av_frame_unref(*frame); + av_freep(frame); +} + +static int get_video_buffer(AVFrame *frame, int align) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + int ret, i, padded_height; + int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align); + + if (!desc) + return AVERROR(EINVAL); + + if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0) + return ret; + + if (!frame->linesize[0]) { + if (align <= 0) + align = 32; /* STRIDE_ALIGN. Should be av_cpu_max_align() */ + + for(i=1; i<=align; i+=i) { + ret = av_image_fill_linesizes(frame->linesize, frame->format, + FFALIGN(frame->width, i)); + if (ret < 0) + return ret; + if (!(frame->linesize[0] & (align-1))) + break; + } + + for (i = 0; i < 4 && frame->linesize[i]; i++) + frame->linesize[i] = FFALIGN(frame->linesize[i], align); + } + + padded_height = FFALIGN(frame->height, 32); + if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, + NULL, frame->linesize)) < 0) + return ret; + + frame->buf[0] = av_buffer_alloc(ret + 4*plane_padding); + if (!frame->buf[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, + frame->buf[0]->data, frame->linesize)) < 0) + goto fail; + + for (i = 1; i < 4; i++) { + if (frame->data[i]) + frame->data[i] += i * plane_padding; + } + + frame->extended_data = frame->data; + + return 0; +fail: + av_frame_unref(frame); + return ret; +} + +static int get_audio_buffer(AVFrame *frame, int align) +{ + int channels; + int planar = av_sample_fmt_is_planar(frame->format); + int planes; + int ret, i; + + if (!frame->channels) + frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout); + + channels = frame->channels; + planes = planar ? channels : 1; + + CHECK_CHANNELS_CONSISTENCY(frame); + if (!frame->linesize[0]) { + ret = av_samples_get_buffer_size(&frame->linesize[0], channels, + frame->nb_samples, frame->format, + align); + if (ret < 0) + return ret; + } + + if (planes > AV_NUM_DATA_POINTERS) { + frame->extended_data = av_mallocz_array(planes, + sizeof(*frame->extended_data)); + frame->extended_buf = av_mallocz_array((planes - AV_NUM_DATA_POINTERS), + sizeof(*frame->extended_buf)); + if (!frame->extended_data || !frame->extended_buf) { + av_freep(&frame->extended_data); + av_freep(&frame->extended_buf); + return AVERROR(ENOMEM); + } + frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; + } else + frame->extended_data = frame->data; + + for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { + frame->buf[i] = av_buffer_alloc(frame->linesize[0]); + if (!frame->buf[i]) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; + } + for (i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) { + frame->extended_buf[i] = av_buffer_alloc(frame->linesize[0]); + if (!frame->extended_buf[i]) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; + } + return 0; + +} + +int av_frame_get_buffer(AVFrame *frame, int align) +{ + if (frame->format < 0) + return AVERROR(EINVAL); + + if (frame->width > 0 && frame->height > 0) + return get_video_buffer(frame, align); + else if (frame->nb_samples > 0 && (frame->channel_layout || frame->channels > 0)) + return get_audio_buffer(frame, align); + + return AVERROR(EINVAL); +} + +static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) +{ + int i; + + dst->key_frame = src->key_frame; + dst->pict_type = src->pict_type; + dst->sample_aspect_ratio = src->sample_aspect_ratio; + dst->crop_top = src->crop_top; + dst->crop_bottom = src->crop_bottom; + dst->crop_left = src->crop_left; + dst->crop_right = src->crop_right; + dst->pts = src->pts; + dst->repeat_pict = src->repeat_pict; + dst->interlaced_frame = src->interlaced_frame; + dst->top_field_first = src->top_field_first; + dst->palette_has_changed = src->palette_has_changed; + dst->sample_rate = src->sample_rate; + dst->opaque = src->opaque; +#if FF_API_PKT_PTS +FF_DISABLE_DEPRECATION_WARNINGS + dst->pkt_pts = src->pkt_pts; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + dst->pkt_dts = src->pkt_dts; + dst->pkt_pos = src->pkt_pos; + dst->pkt_size = src->pkt_size; + dst->pkt_duration = src->pkt_duration; + dst->reordered_opaque = src->reordered_opaque; + dst->quality = src->quality; + dst->best_effort_timestamp = src->best_effort_timestamp; + dst->coded_picture_number = src->coded_picture_number; + dst->display_picture_number = src->display_picture_number; + dst->flags = src->flags; + dst->decode_error_flags = src->decode_error_flags; + dst->color_primaries = src->color_primaries; + dst->color_trc = src->color_trc; + dst->colorspace = src->colorspace; + dst->color_range = src->color_range; + dst->chroma_location = src->chroma_location; + + av_dict_copy(&dst->metadata, src->metadata, 0); + +#if FF_API_ERROR_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + memcpy(dst->error, src->error, sizeof(dst->error)); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + for (i = 0; i < src->nb_side_data; i++) { + const AVFrameSideData *sd_src = src->side_data[i]; + AVFrameSideData *sd_dst; + if ( sd_src->type == AV_FRAME_DATA_PANSCAN + && (src->width != dst->width || src->height != dst->height)) + continue; + if (force_copy) { + sd_dst = av_frame_new_side_data(dst, sd_src->type, + sd_src->size); + if (!sd_dst) { + wipe_side_data(dst); + return AVERROR(ENOMEM); + } + memcpy(sd_dst->data, sd_src->data, sd_src->size); + } else { + AVBufferRef *ref = av_buffer_ref(sd_src->buf); + sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref); + if (!sd_dst) { + av_buffer_unref(&ref); + wipe_side_data(dst); + return AVERROR(ENOMEM); + } + } + av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); + } + +#if FF_API_FRAME_QP +FF_DISABLE_DEPRECATION_WARNINGS + dst->qscale_table = NULL; + dst->qstride = 0; + dst->qscale_type = 0; + av_buffer_unref(&dst->qp_table_buf); + if (src->qp_table_buf) { + dst->qp_table_buf = av_buffer_ref(src->qp_table_buf); + if (dst->qp_table_buf) { + dst->qscale_table = dst->qp_table_buf->data; + dst->qstride = src->qstride; + dst->qscale_type = src->qscale_type; + } + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + av_buffer_unref(&dst->opaque_ref); + av_buffer_unref(&dst->private_ref); + if (src->opaque_ref) { + dst->opaque_ref = av_buffer_ref(src->opaque_ref); + if (!dst->opaque_ref) + return AVERROR(ENOMEM); + } + if (src->private_ref) { + dst->private_ref = av_buffer_ref(src->private_ref); + if (!dst->private_ref) + return AVERROR(ENOMEM); + } + return 0; +} + +int av_frame_ref(AVFrame *dst, const AVFrame *src) +{ + int i, ret = 0; + + av_assert1(dst->width == 0 && dst->height == 0); + av_assert1(dst->channels == 0); + + dst->format = src->format; + dst->width = src->width; + dst->height = src->height; + dst->channels = src->channels; + dst->channel_layout = src->channel_layout; + dst->nb_samples = src->nb_samples; + + ret = frame_copy_props(dst, src, 0); + if (ret < 0) + return ret; + + /* duplicate the frame data if it's not refcounted */ + if (!src->buf[0]) { + ret = av_frame_get_buffer(dst, 32); + if (ret < 0) + return ret; + + ret = av_frame_copy(dst, src); + if (ret < 0) + av_frame_unref(dst); + + return ret; + } + + /* ref the buffers */ + for (i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) { + if (!src->buf[i]) + continue; + dst->buf[i] = av_buffer_ref(src->buf[i]); + if (!dst->buf[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + + if (src->extended_buf) { + dst->extended_buf = av_mallocz_array(sizeof(*dst->extended_buf), + src->nb_extended_buf); + if (!dst->extended_buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst->nb_extended_buf = src->nb_extended_buf; + + for (i = 0; i < src->nb_extended_buf; i++) { + dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]); + if (!dst->extended_buf[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + } + + if (src->hw_frames_ctx) { + dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); + if (!dst->hw_frames_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + + /* duplicate extended data */ + if (src->extended_data != src->data) { + int ch = src->channels; + + if (!ch) { + ret = AVERROR(EINVAL); + goto fail; + } + CHECK_CHANNELS_CONSISTENCY(src); + + dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch); + if (!dst->extended_data) { + ret = AVERROR(ENOMEM); + goto fail; + } + memcpy(dst->extended_data, src->extended_data, sizeof(*src->extended_data) * ch); + } else + dst->extended_data = dst->data; + + memcpy(dst->data, src->data, sizeof(src->data)); + memcpy(dst->linesize, src->linesize, sizeof(src->linesize)); + + return 0; + +fail: + av_frame_unref(dst); + return ret; +} + +AVFrame *av_frame_clone(const AVFrame *src) +{ + AVFrame *ret = av_frame_alloc(); + + if (!ret) + return NULL; + + if (av_frame_ref(ret, src) < 0) + av_frame_free(&ret); + + return ret; +} + +void av_frame_unref(AVFrame *frame) +{ + int i; + + if (!frame) + return; + + wipe_side_data(frame); + + for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) + av_buffer_unref(&frame->buf[i]); + for (i = 0; i < frame->nb_extended_buf; i++) + av_buffer_unref(&frame->extended_buf[i]); + av_freep(&frame->extended_buf); + av_dict_free(&frame->metadata); +#if FF_API_FRAME_QP +FF_DISABLE_DEPRECATION_WARNINGS + av_buffer_unref(&frame->qp_table_buf); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + av_buffer_unref(&frame->hw_frames_ctx); + + av_buffer_unref(&frame->opaque_ref); + av_buffer_unref(&frame->private_ref); + + get_frame_defaults(frame); +} + +void av_frame_move_ref(AVFrame *dst, AVFrame *src) +{ + av_assert1(dst->width == 0 && dst->height == 0); + av_assert1(dst->channels == 0); + + *dst = *src; + if (src->extended_data == src->data) + dst->extended_data = dst->data; + memset(src, 0, sizeof(*src)); + get_frame_defaults(src); +} + +int av_frame_is_writable(AVFrame *frame) +{ + int i, ret = 1; + + /* assume non-refcounted frames are not writable */ + if (!frame->buf[0]) + return 0; + + for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) + if (frame->buf[i]) + ret &= !!av_buffer_is_writable(frame->buf[i]); + for (i = 0; i < frame->nb_extended_buf; i++) + ret &= !!av_buffer_is_writable(frame->extended_buf[i]); + + return ret; +} + +int av_frame_make_writable(AVFrame *frame) +{ + AVFrame tmp; + int ret; + + if (!frame->buf[0]) + return AVERROR(EINVAL); + + if (av_frame_is_writable(frame)) + return 0; + + memset(&tmp, 0, sizeof(tmp)); + tmp.format = frame->format; + tmp.width = frame->width; + tmp.height = frame->height; + tmp.channels = frame->channels; + tmp.channel_layout = frame->channel_layout; + tmp.nb_samples = frame->nb_samples; + ret = av_frame_get_buffer(&tmp, 32); + if (ret < 0) + return ret; + + ret = av_frame_copy(&tmp, frame); + if (ret < 0) { + av_frame_unref(&tmp); + return ret; + } + + ret = av_frame_copy_props(&tmp, frame); + if (ret < 0) { + av_frame_unref(&tmp); + return ret; + } + + av_frame_unref(frame); + + *frame = tmp; + if (tmp.data == tmp.extended_data) + frame->extended_data = frame->data; + + return 0; +} + +int av_frame_copy_props(AVFrame *dst, const AVFrame *src) +{ + return frame_copy_props(dst, src, 1); +} + +AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane) +{ + uint8_t *data; + int planes, i; + + if (frame->nb_samples) { + int channels = frame->channels; + if (!channels) + return NULL; + CHECK_CHANNELS_CONSISTENCY(frame); + planes = av_sample_fmt_is_planar(frame->format) ? channels : 1; + } else + planes = 4; + + if (plane < 0 || plane >= planes || !frame->extended_data[plane]) + return NULL; + data = frame->extended_data[plane]; + + for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++) { + AVBufferRef *buf = frame->buf[i]; + if (data >= buf->data && data < buf->data + buf->size) + return buf; + } + for (i = 0; i < frame->nb_extended_buf; i++) { + AVBufferRef *buf = frame->extended_buf[i]; + if (data >= buf->data && data < buf->data + buf->size) + return buf; + } + return NULL; +} + +AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf) +{ + AVFrameSideData *ret, **tmp; + + if (!buf) + return NULL; + + if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1) + return NULL; + + tmp = av_realloc(frame->side_data, + (frame->nb_side_data + 1) * sizeof(*frame->side_data)); + if (!tmp) + return NULL; + frame->side_data = tmp; + + ret = av_mallocz(sizeof(*ret)); + if (!ret) + return NULL; + + ret->buf = buf; + ret->data = ret->buf->data; + ret->size = buf->size; + ret->type = type; + + frame->side_data[frame->nb_side_data++] = ret; + + return ret; +} + +AVFrameSideData *av_frame_new_side_data(AVFrame *frame, + enum AVFrameSideDataType type, + int size) +{ + AVFrameSideData *ret; + AVBufferRef *buf = av_buffer_alloc(size); + ret = av_frame_new_side_data_from_buf(frame, type, buf); + if (!ret) + av_buffer_unref(&buf); + return ret; +} + +AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, + enum AVFrameSideDataType type) +{ + int i; + + for (i = 0; i < frame->nb_side_data; i++) { + if (frame->side_data[i]->type == type) + return frame->side_data[i]; + } + return NULL; +} + +static int frame_copy_video(AVFrame *dst, const AVFrame *src) +{ + const uint8_t *src_data[4]; + int i, planes; + + if (dst->width < src->width || + dst->height < src->height) + return AVERROR(EINVAL); + + planes = av_pix_fmt_count_planes(dst->format); + for (i = 0; i < planes; i++) + if (!dst->data[i] || !src->data[i]) + return AVERROR(EINVAL); + + memcpy(src_data, src->data, sizeof(src_data)); + av_image_copy(dst->data, dst->linesize, + src_data, src->linesize, + dst->format, src->width, src->height); + + return 0; +} + +static int frame_copy_audio(AVFrame *dst, const AVFrame *src) +{ + int planar = av_sample_fmt_is_planar(dst->format); + int channels = dst->channels; + int planes = planar ? channels : 1; + int i; + + if (dst->nb_samples != src->nb_samples || + dst->channels != src->channels || + dst->channel_layout != src->channel_layout) + return AVERROR(EINVAL); + + CHECK_CHANNELS_CONSISTENCY(src); + + for (i = 0; i < planes; i++) + if (!dst->extended_data[i] || !src->extended_data[i]) + return AVERROR(EINVAL); + + av_samples_copy(dst->extended_data, src->extended_data, 0, 0, + dst->nb_samples, channels, dst->format); + + return 0; +} + +int av_frame_copy(AVFrame *dst, const AVFrame *src) +{ + if (dst->format != src->format || dst->format < 0) + return AVERROR(EINVAL); + + if (dst->width > 0 && dst->height > 0) + return frame_copy_video(dst, src); + else if (dst->nb_samples > 0 && dst->channels > 0) + return frame_copy_audio(dst, src); + + return AVERROR(EINVAL); +} + +void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type) +{ + int i; + + for (i = 0; i < frame->nb_side_data; i++) { + AVFrameSideData *sd = frame->side_data[i]; + if (sd->type == type) { + free_side_data(&frame->side_data[i]); + frame->side_data[i] = frame->side_data[frame->nb_side_data - 1]; + frame->nb_side_data--; + } + } +} + +const char *av_frame_side_data_name(enum AVFrameSideDataType type) +{ + switch(type) { + case AV_FRAME_DATA_PANSCAN: return "AVPanScan"; + case AV_FRAME_DATA_A53_CC: return "ATSC A53 Part 4 Closed Captions"; + case AV_FRAME_DATA_STEREO3D: return "Stereo 3D"; + case AV_FRAME_DATA_MATRIXENCODING: return "AVMatrixEncoding"; + case AV_FRAME_DATA_DOWNMIX_INFO: return "Metadata relevant to a downmix procedure"; + case AV_FRAME_DATA_REPLAYGAIN: return "AVReplayGain"; + case AV_FRAME_DATA_DISPLAYMATRIX: return "3x3 displaymatrix"; + case AV_FRAME_DATA_AFD: return "Active format description"; + case AV_FRAME_DATA_MOTION_VECTORS: return "Motion vectors"; + case AV_FRAME_DATA_SKIP_SAMPLES: return "Skip samples"; + case AV_FRAME_DATA_AUDIO_SERVICE_TYPE: return "Audio service type"; + case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA: return "Mastering display metadata"; + case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; + case AV_FRAME_DATA_GOP_TIMECODE: return "GOP timecode"; + case AV_FRAME_DATA_S12M_TIMECODE: return "SMPTE 12-1 timecode"; + case AV_FRAME_DATA_SPHERICAL: return "Spherical Mapping"; + case AV_FRAME_DATA_ICC_PROFILE: return "ICC profile"; +#if FF_API_FRAME_QP + case AV_FRAME_DATA_QP_TABLE_PROPERTIES: return "QP table properties"; + case AV_FRAME_DATA_QP_TABLE_DATA: return "QP table data"; +#endif + case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)"; + case AV_FRAME_DATA_REGIONS_OF_INTEREST: return "Regions Of Interest"; + } + return NULL; +} + +static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame, + const AVPixFmtDescriptor *desc) +{ + int i, j; + + for (i = 0; frame->data[i]; i++) { + const AVComponentDescriptor *comp = NULL; + int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0; + int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; + + if (desc->flags & (AV_PIX_FMT_FLAG_PAL | FF_PSEUDOPAL) && i == 1) { + offsets[i] = 0; + break; + } + + /* find any component descriptor for this plane */ + for (j = 0; j < desc->nb_components; j++) { + if (desc->comp[j].plane == i) { + comp = &desc->comp[j]; + break; + } + } + if (!comp) + return AVERROR_BUG; + + offsets[i] = (frame->crop_top >> shift_y) * frame->linesize[i] + + (frame->crop_left >> shift_x) * comp->step; + } + + return 0; +} + +int av_frame_apply_cropping(AVFrame *frame, int flags) +{ + const AVPixFmtDescriptor *desc; + size_t offsets[4]; + int i; + + if (!(frame->width > 0 && frame->height > 0)) + return AVERROR(EINVAL); + + if (frame->crop_left >= INT_MAX - frame->crop_right || + frame->crop_top >= INT_MAX - frame->crop_bottom || + (frame->crop_left + frame->crop_right) >= frame->width || + (frame->crop_top + frame->crop_bottom) >= frame->height) + return AVERROR(ERANGE); + + desc = av_pix_fmt_desc_get(frame->format); + if (!desc) + return AVERROR_BUG; + + /* Apply just the right/bottom cropping for hwaccel formats. Bitstream + * formats cannot be easily handled here either (and corresponding decoders + * should not export any cropping anyway), so do the same for those as well. + * */ + if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL)) { + frame->width -= frame->crop_right; + frame->height -= frame->crop_bottom; + frame->crop_right = 0; + frame->crop_bottom = 0; + return 0; + } + + /* calculate the offsets for each plane */ + calc_cropping_offsets(offsets, frame, desc); + + /* adjust the offsets to avoid breaking alignment */ + if (!(flags & AV_FRAME_CROP_UNALIGNED)) { + int log2_crop_align = frame->crop_left ? ff_ctz(frame->crop_left) : INT_MAX; + int min_log2_align = INT_MAX; + + for (i = 0; frame->data[i]; i++) { + int log2_align = offsets[i] ? ff_ctz(offsets[i]) : INT_MAX; + min_log2_align = FFMIN(log2_align, min_log2_align); + } + + /* we assume, and it should always be true, that the data alignment is + * related to the cropping alignment by a constant power-of-2 factor */ + if (log2_crop_align < min_log2_align) + return AVERROR_BUG; + + if (min_log2_align < 5) { + frame->crop_left &= ~((1 << (5 + log2_crop_align - min_log2_align)) - 1); + calc_cropping_offsets(offsets, frame, desc); + } + } + + for (i = 0; frame->data[i]; i++) + frame->data[i] += offsets[i]; + + frame->width -= (frame->crop_left + frame->crop_right); + frame->height -= (frame->crop_top + frame->crop_bottom); + frame->crop_left = 0; + frame->crop_right = 0; + frame->crop_top = 0; + frame->crop_bottom = 0; + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/frame.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/frame.h new file mode 100644 index 000000000..5d3231e7b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/frame.h @@ -0,0 +1,971 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_frame + * reference-counted frame API + */ + +#ifndef AVUTIL_FRAME_H +#define AVUTIL_FRAME_H + +#include +#include + +#include "avutil.h" +#include "buffer.h" +#include "dict.h" +#include "rational.h" +#include "samplefmt.h" +#include "pixfmt.h" +#include "version.h" + + +/** + * @defgroup lavu_frame AVFrame + * @ingroup lavu_data + * + * @{ + * AVFrame is an abstraction for reference-counted raw multimedia data. + */ + +enum AVFrameSideDataType { + /** + * The data is the AVPanScan struct defined in libavcodec. + */ + AV_FRAME_DATA_PANSCAN, + /** + * ATSC A53 Part 4 Closed Captions. + * A53 CC bitstream is stored as uint8_t in AVFrameSideData.data. + * The number of bytes of CC data is AVFrameSideData.size. + */ + AV_FRAME_DATA_A53_CC, + /** + * Stereoscopic 3d metadata. + * The data is the AVStereo3D struct defined in libavutil/stereo3d.h. + */ + AV_FRAME_DATA_STEREO3D, + /** + * The data is the AVMatrixEncoding enum defined in libavutil/channel_layout.h. + */ + AV_FRAME_DATA_MATRIXENCODING, + /** + * Metadata relevant to a downmix procedure. + * The data is the AVDownmixInfo struct defined in libavutil/downmix_info.h. + */ + AV_FRAME_DATA_DOWNMIX_INFO, + /** + * ReplayGain information in the form of the AVReplayGain struct. + */ + AV_FRAME_DATA_REPLAYGAIN, + /** + * This side data contains a 3x3 transformation matrix describing an affine + * transformation that needs to be applied to the frame for correct + * presentation. + * + * See libavutil/display.h for a detailed description of the data. + */ + AV_FRAME_DATA_DISPLAYMATRIX, + /** + * Active Format Description data consisting of a single byte as specified + * in ETSI TS 101 154 using AVActiveFormatDescription enum. + */ + AV_FRAME_DATA_AFD, + /** + * Motion vectors exported by some codecs (on demand through the export_mvs + * flag set in the libavcodec AVCodecContext flags2 option). + * The data is the AVMotionVector struct defined in + * libavutil/motion_vector.h. + */ + AV_FRAME_DATA_MOTION_VECTORS, + /** + * Recommmends skipping the specified number of samples. This is exported + * only if the "skip_manual" AVOption is set in libavcodec. + * This has the same format as AV_PKT_DATA_SKIP_SAMPLES. + * @code + * u32le number of samples to skip from start of this packet + * u32le number of samples to skip from end of this packet + * u8 reason for start skip + * u8 reason for end skip (0=padding silence, 1=convergence) + * @endcode + */ + AV_FRAME_DATA_SKIP_SAMPLES, + /** + * This side data must be associated with an audio frame and corresponds to + * enum AVAudioServiceType defined in avcodec.h. + */ + AV_FRAME_DATA_AUDIO_SERVICE_TYPE, + /** + * Mastering display metadata associated with a video frame. The payload is + * an AVMasteringDisplayMetadata type and contains information about the + * mastering display color volume. + */ + AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, + /** + * The GOP timecode in 25 bit timecode format. Data format is 64-bit integer. + * This is set on the first frame of a GOP that has a temporal reference of 0. + */ + AV_FRAME_DATA_GOP_TIMECODE, + + /** + * The data represents the AVSphericalMapping structure defined in + * libavutil/spherical.h. + */ + AV_FRAME_DATA_SPHERICAL, + + /** + * Content light level (based on CTA-861.3). This payload contains data in + * the form of the AVContentLightMetadata struct. + */ + AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, + + /** + * The data contains an ICC profile as an opaque octet buffer following the + * format described by ISO 15076-1 with an optional name defined in the + * metadata key entry "name". + */ + AV_FRAME_DATA_ICC_PROFILE, + +#if FF_API_FRAME_QP + /** + * Implementation-specific description of the format of AV_FRAME_QP_TABLE_DATA. + * The contents of this side data are undocumented and internal; use + * av_frame_set_qp_table() and av_frame_get_qp_table() to access this in a + * meaningful way instead. + */ + AV_FRAME_DATA_QP_TABLE_PROPERTIES, + + /** + * Raw QP table data. Its format is described by + * AV_FRAME_DATA_QP_TABLE_PROPERTIES. Use av_frame_set_qp_table() and + * av_frame_get_qp_table() to access this instead. + */ + AV_FRAME_DATA_QP_TABLE_DATA, +#endif + + /** + * Timecode which conforms to SMPTE ST 12-1. The data is an array of 4 uint32_t + * where the first uint32_t describes how many (1-3) of the other timecodes are used. + * The timecode format is described in the av_timecode_get_smpte_from_framenum() + * function in libavutil/timecode.c. + */ + AV_FRAME_DATA_S12M_TIMECODE, + + /** + * HDR dynamic metadata associated with a video frame. The payload is + * an AVDynamicHDRPlus type and contains information for color + * volume transform - application 4 of SMPTE 2094-40:2016 standard. + */ + AV_FRAME_DATA_DYNAMIC_HDR_PLUS, + + /** + * Regions Of Interest, the data is an array of AVRegionOfInterest type, the number of + * array element is implied by AVFrameSideData.size / AVRegionOfInterest.self_size. + */ + AV_FRAME_DATA_REGIONS_OF_INTEREST, +}; + +enum AVActiveFormatDescription { + AV_AFD_SAME = 8, + AV_AFD_4_3 = 9, + AV_AFD_16_9 = 10, + AV_AFD_14_9 = 11, + AV_AFD_4_3_SP_14_9 = 13, + AV_AFD_16_9_SP_14_9 = 14, + AV_AFD_SP_4_3 = 15, +}; + + +/** + * Structure to hold side data for an AVFrame. + * + * sizeof(AVFrameSideData) is not a part of the public ABI, so new fields may be added + * to the end with a minor bump. + */ +typedef struct AVFrameSideData { + enum AVFrameSideDataType type; + uint8_t *data; + int size; + AVDictionary *metadata; + AVBufferRef *buf; +} AVFrameSideData; + +/** + * Structure describing a single Region Of Interest. + * + * When multiple regions are defined in a single side-data block, they + * should be ordered from most to least important - some encoders are only + * capable of supporting a limited number of distinct regions, so will have + * to truncate the list. + * + * When overlapping regions are defined, the first region containing a given + * area of the frame applies. + */ +typedef struct AVRegionOfInterest { + /** + * Must be set to the size of this data structure (that is, + * sizeof(AVRegionOfInterest)). + */ + uint32_t self_size; + /** + * Distance in pixels from the top edge of the frame to the top and + * bottom edges and from the left edge of the frame to the left and + * right edges of the rectangle defining this region of interest. + * + * The constraints on a region are encoder dependent, so the region + * actually affected may be slightly larger for alignment or other + * reasons. + */ + int top; + int bottom; + int left; + int right; + /** + * Quantisation offset. + * + * Must be in the range -1 to +1. A value of zero indicates no quality + * change. A negative value asks for better quality (less quantisation), + * while a positive value asks for worse quality (greater quantisation). + * + * The range is calibrated so that the extreme values indicate the + * largest possible offset - if the rest of the frame is encoded with the + * worst possible quality, an offset of -1 indicates that this region + * should be encoded with the best possible quality anyway. Intermediate + * values are then interpolated in some codec-dependent way. + * + * For example, in 10-bit H.264 the quantisation parameter varies between + * -12 and 51. A typical qoffset value of -1/10 therefore indicates that + * this region should be encoded with a QP around one-tenth of the full + * range better than the rest of the frame. So, if most of the frame + * were to be encoded with a QP of around 30, this region would get a QP + * of around 24 (an offset of approximately -1/10 * (51 - -12) = -6.3). + * An extreme value of -1 would indicate that this region should be + * encoded with the best possible quality regardless of the treatment of + * the rest of the frame - that is, should be encoded at a QP of -12. + */ + AVRational qoffset; +} AVRegionOfInterest; + +/** + * This structure describes decoded (raw) audio or video data. + * + * AVFrame must be allocated using av_frame_alloc(). Note that this only + * allocates the AVFrame itself, the buffers for the data must be managed + * through other means (see below). + * AVFrame must be freed with av_frame_free(). + * + * AVFrame is typically allocated once and then reused multiple times to hold + * different data (e.g. a single AVFrame to hold frames received from a + * decoder). In such a case, av_frame_unref() will free any references held by + * the frame and reset it to its original clean state before it + * is reused again. + * + * The data described by an AVFrame is usually reference counted through the + * AVBuffer API. The underlying buffer references are stored in AVFrame.buf / + * AVFrame.extended_buf. An AVFrame is considered to be reference counted if at + * least one reference is set, i.e. if AVFrame.buf[0] != NULL. In such a case, + * every single data plane must be contained in one of the buffers in + * AVFrame.buf or AVFrame.extended_buf. + * There may be a single buffer for all the data, or one separate buffer for + * each plane, or anything in between. + * + * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added + * to the end with a minor bump. + * + * Fields can be accessed through AVOptions, the name string used, matches the + * C structure field name for fields accessible through AVOptions. The AVClass + * for AVFrame can be obtained from avcodec_get_frame_class() + */ +typedef struct AVFrame { +#define AV_NUM_DATA_POINTERS 8 + /** + * pointer to the picture/channel planes. + * This might be different from the first allocated byte + * + * Some decoders access areas outside 0,0 - width,height, please + * see avcodec_align_dimensions2(). Some filters and swscale can read + * up to 16 bytes beyond the planes, if these filters are to be used, + * then 16 extra bytes must be allocated. + * + * NOTE: Except for hwaccel formats, pointers not needed by the format + * MUST be set to NULL. + */ + uint8_t *data[AV_NUM_DATA_POINTERS]; + + /** + * For video, size in bytes of each picture line. + * For audio, size in bytes of each plane. + * + * For audio, only linesize[0] may be set. For planar audio, each channel + * plane must be the same size. + * + * For video the linesizes should be multiples of the CPUs alignment + * preference, this is 16 or 32 for modern desktop CPUs. + * Some code requires such alignment other code can be slower without + * correct alignment, for yet other it makes no difference. + * + * @note The linesize may be larger than the size of usable data -- there + * may be extra padding present for performance reasons. + */ + int linesize[AV_NUM_DATA_POINTERS]; + + /** + * pointers to the data planes/channels. + * + * For video, this should simply point to data[]. + * + * For planar audio, each channel has a separate data pointer, and + * linesize[0] contains the size of each channel buffer. + * For packed audio, there is just one data pointer, and linesize[0] + * contains the total size of the buffer for all channels. + * + * Note: Both data and extended_data should always be set in a valid frame, + * but for planar audio with more channels that can fit in data, + * extended_data must be used in order to access all channels. + */ + uint8_t **extended_data; + + /** + * @name Video dimensions + * Video frames only. The coded dimensions (in pixels) of the video frame, + * i.e. the size of the rectangle that contains some well-defined values. + * + * @note The part of the frame intended for display/presentation is further + * restricted by the @ref cropping "Cropping rectangle". + * @{ + */ + int width, height; + /** + * @} + */ + + /** + * number of audio samples (per channel) described by this frame + */ + int nb_samples; + + /** + * format of the frame, -1 if unknown or unset + * Values correspond to enum AVPixelFormat for video frames, + * enum AVSampleFormat for audio) + */ + int format; + + /** + * 1 -> keyframe, 0-> not + */ + int key_frame; + + /** + * Picture type of the frame. + */ + enum AVPictureType pict_type; + + /** + * Sample aspect ratio for the video frame, 0/1 if unknown/unspecified. + */ + AVRational sample_aspect_ratio; + + /** + * Presentation timestamp in time_base units (time when frame should be shown to user). + */ + int64_t pts; + +#if FF_API_PKT_PTS + /** + * PTS copied from the AVPacket that was decoded to produce this frame. + * @deprecated use the pts field instead + */ + attribute_deprecated + int64_t pkt_pts; +#endif + + /** + * DTS copied from the AVPacket that triggered returning this frame. (if frame threading isn't used) + * This is also the Presentation time of this AVFrame calculated from + * only AVPacket.dts values without pts values. + */ + int64_t pkt_dts; + + /** + * picture number in bitstream order + */ + int coded_picture_number; + /** + * picture number in display order + */ + int display_picture_number; + + /** + * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) + */ + int quality; + + /** + * for some private data of the user + */ + void *opaque; + +#if FF_API_ERROR_FRAME + /** + * @deprecated unused + */ + attribute_deprecated + uint64_t error[AV_NUM_DATA_POINTERS]; +#endif + + /** + * When decoding, this signals how much the picture must be delayed. + * extra_delay = repeat_pict / (2*fps) + */ + int repeat_pict; + + /** + * The content of the picture is interlaced. + */ + int interlaced_frame; + + /** + * If the content is interlaced, is top field displayed first. + */ + int top_field_first; + + /** + * Tell user application that palette has changed from previous frame. + */ + int palette_has_changed; + + /** + * reordered opaque 64 bits (generally an integer or a double precision float + * PTS but can be anything). + * The user sets AVCodecContext.reordered_opaque to represent the input at + * that time, + * the decoder reorders values as needed and sets AVFrame.reordered_opaque + * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque + */ + int64_t reordered_opaque; + + /** + * Sample rate of the audio data. + */ + int sample_rate; + + /** + * Channel layout of the audio data. + */ + uint64_t channel_layout; + + /** + * AVBuffer references backing the data for this frame. If all elements of + * this array are NULL, then this frame is not reference counted. This array + * must be filled contiguously -- if buf[i] is non-NULL then buf[j] must + * also be non-NULL for all j < i. + * + * There may be at most one AVBuffer per data plane, so for video this array + * always contains all the references. For planar audio with more than + * AV_NUM_DATA_POINTERS channels, there may be more buffers than can fit in + * this array. Then the extra AVBufferRef pointers are stored in the + * extended_buf array. + */ + AVBufferRef *buf[AV_NUM_DATA_POINTERS]; + + /** + * For planar audio which requires more than AV_NUM_DATA_POINTERS + * AVBufferRef pointers, this array will hold all the references which + * cannot fit into AVFrame.buf. + * + * Note that this is different from AVFrame.extended_data, which always + * contains all the pointers. This array only contains the extra pointers, + * which cannot fit into AVFrame.buf. + * + * This array is always allocated using av_malloc() by whoever constructs + * the frame. It is freed in av_frame_unref(). + */ + AVBufferRef **extended_buf; + /** + * Number of elements in extended_buf. + */ + int nb_extended_buf; + + AVFrameSideData **side_data; + int nb_side_data; + +/** + * @defgroup lavu_frame_flags AV_FRAME_FLAGS + * @ingroup lavu_frame + * Flags describing additional frame properties. + * + * @{ + */ + +/** + * The frame data may be corrupted, e.g. due to decoding errors. + */ +#define AV_FRAME_FLAG_CORRUPT (1 << 0) +/** + * A flag to mark the frames which need to be decoded, but shouldn't be output. + */ +#define AV_FRAME_FLAG_DISCARD (1 << 2) +/** + * @} + */ + + /** + * Frame flags, a combination of @ref lavu_frame_flags + */ + int flags; + + /** + * MPEG vs JPEG YUV range. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorRange color_range; + + enum AVColorPrimaries color_primaries; + + enum AVColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorSpace colorspace; + + enum AVChromaLocation chroma_location; + + /** + * frame timestamp estimated using various heuristics, in stream time base + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int64_t best_effort_timestamp; + + /** + * reordered pos from the last AVPacket that has been input into the decoder + * - encoding: unused + * - decoding: Read by user. + */ + int64_t pkt_pos; + + /** + * duration of the corresponding packet, expressed in + * AVStream->time_base units, 0 if unknown. + * - encoding: unused + * - decoding: Read by user. + */ + int64_t pkt_duration; + + /** + * metadata. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + AVDictionary *metadata; + + /** + * decode error flags of the frame, set to a combination of + * FF_DECODE_ERROR_xxx flags if the decoder produced a frame, but there + * were errors during the decoding. + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int decode_error_flags; +#define FF_DECODE_ERROR_INVALID_BITSTREAM 1 +#define FF_DECODE_ERROR_MISSING_REFERENCE 2 +#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4 +#define FF_DECODE_ERROR_DECODE_SLICES 8 + + /** + * number of audio channels, only used for audio. + * - encoding: unused + * - decoding: Read by user. + */ + int channels; + + /** + * size of the corresponding packet containing the compressed + * frame. + * It is set to a negative value if unknown. + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int pkt_size; + +#if FF_API_FRAME_QP + /** + * QP table + */ + attribute_deprecated + int8_t *qscale_table; + /** + * QP store stride + */ + attribute_deprecated + int qstride; + + attribute_deprecated + int qscale_type; + + attribute_deprecated + AVBufferRef *qp_table_buf; +#endif + /** + * For hwaccel-format frames, this should be a reference to the + * AVHWFramesContext describing the frame. + */ + AVBufferRef *hw_frames_ctx; + + /** + * AVBufferRef for free use by the API user. FFmpeg will never check the + * contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when + * the frame is unreferenced. av_frame_copy_props() calls create a new + * reference with av_buffer_ref() for the target frame's opaque_ref field. + * + * This is unrelated to the opaque field, although it serves a similar + * purpose. + */ + AVBufferRef *opaque_ref; + + /** + * @anchor cropping + * @name Cropping + * Video frames only. The number of pixels to discard from the the + * top/bottom/left/right border of the frame to obtain the sub-rectangle of + * the frame intended for presentation. + * @{ + */ + size_t crop_top; + size_t crop_bottom; + size_t crop_left; + size_t crop_right; + /** + * @} + */ + + /** + * AVBufferRef for internal use by a single libav* library. + * Must not be used to transfer data between libraries. + * Has to be NULL when ownership of the frame leaves the respective library. + * + * Code outside the FFmpeg libs should never check or change the contents of the buffer ref. + * + * FFmpeg calls av_buffer_unref() on it when the frame is unreferenced. + * av_frame_copy_props() calls create a new reference with av_buffer_ref() + * for the target frame's private_ref field. + */ + AVBufferRef *private_ref; +} AVFrame; + +#if FF_API_FRAME_GET_SET +/** + * Accessors for some AVFrame fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. + */ +attribute_deprecated +int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame); +attribute_deprecated +void av_frame_set_best_effort_timestamp(AVFrame *frame, int64_t val); +attribute_deprecated +int64_t av_frame_get_pkt_duration (const AVFrame *frame); +attribute_deprecated +void av_frame_set_pkt_duration (AVFrame *frame, int64_t val); +attribute_deprecated +int64_t av_frame_get_pkt_pos (const AVFrame *frame); +attribute_deprecated +void av_frame_set_pkt_pos (AVFrame *frame, int64_t val); +attribute_deprecated +int64_t av_frame_get_channel_layout (const AVFrame *frame); +attribute_deprecated +void av_frame_set_channel_layout (AVFrame *frame, int64_t val); +attribute_deprecated +int av_frame_get_channels (const AVFrame *frame); +attribute_deprecated +void av_frame_set_channels (AVFrame *frame, int val); +attribute_deprecated +int av_frame_get_sample_rate (const AVFrame *frame); +attribute_deprecated +void av_frame_set_sample_rate (AVFrame *frame, int val); +attribute_deprecated +AVDictionary *av_frame_get_metadata (const AVFrame *frame); +attribute_deprecated +void av_frame_set_metadata (AVFrame *frame, AVDictionary *val); +attribute_deprecated +int av_frame_get_decode_error_flags (const AVFrame *frame); +attribute_deprecated +void av_frame_set_decode_error_flags (AVFrame *frame, int val); +attribute_deprecated +int av_frame_get_pkt_size(const AVFrame *frame); +attribute_deprecated +void av_frame_set_pkt_size(AVFrame *frame, int val); +#if FF_API_FRAME_QP +attribute_deprecated +int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type); +attribute_deprecated +int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int type); +#endif +attribute_deprecated +enum AVColorSpace av_frame_get_colorspace(const AVFrame *frame); +attribute_deprecated +void av_frame_set_colorspace(AVFrame *frame, enum AVColorSpace val); +attribute_deprecated +enum AVColorRange av_frame_get_color_range(const AVFrame *frame); +attribute_deprecated +void av_frame_set_color_range(AVFrame *frame, enum AVColorRange val); +#endif + +/** + * Get the name of a colorspace. + * @return a static string identifying the colorspace; can be NULL. + */ +const char *av_get_colorspace_name(enum AVColorSpace val); + +/** + * Allocate an AVFrame and set its fields to default values. The resulting + * struct must be freed using av_frame_free(). + * + * @return An AVFrame filled with default values or NULL on failure. + * + * @note this only allocates the AVFrame itself, not the data buffers. Those + * must be allocated through other means, e.g. with av_frame_get_buffer() or + * manually. + */ +AVFrame *av_frame_alloc(void); + +/** + * Free the frame and any dynamically allocated objects in it, + * e.g. extended_data. If the frame is reference counted, it will be + * unreferenced first. + * + * @param frame frame to be freed. The pointer will be set to NULL. + */ +void av_frame_free(AVFrame **frame); + +/** + * Set up a new reference to the data described by the source frame. + * + * Copy frame properties from src to dst and create a new reference for each + * AVBufferRef from src. + * + * If src is not reference counted, new buffers are allocated and the data is + * copied. + * + * @warning: dst MUST have been either unreferenced with av_frame_unref(dst), + * or newly allocated with av_frame_alloc() before calling this + * function, or undefined behavior will occur. + * + * @return 0 on success, a negative AVERROR on error + */ +int av_frame_ref(AVFrame *dst, const AVFrame *src); + +/** + * Create a new frame that references the same data as src. + * + * This is a shortcut for av_frame_alloc()+av_frame_ref(). + * + * @return newly created AVFrame on success, NULL on error. + */ +AVFrame *av_frame_clone(const AVFrame *src); + +/** + * Unreference all the buffers referenced by frame and reset the frame fields. + */ +void av_frame_unref(AVFrame *frame); + +/** + * Move everything contained in src to dst and reset src. + * + * @warning: dst is not unreferenced, but directly overwritten without reading + * or deallocating its contents. Call av_frame_unref(dst) manually + * before calling this function to ensure that no memory is leaked. + */ +void av_frame_move_ref(AVFrame *dst, AVFrame *src); + +/** + * Allocate new buffer(s) for audio or video data. + * + * The following fields must be set on frame before calling this function: + * - format (pixel format for video, sample format for audio) + * - width and height for video + * - nb_samples and channel_layout for audio + * + * This function will fill AVFrame.data and AVFrame.buf arrays and, if + * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf. + * For planar formats, one buffer will be allocated for each plane. + * + * @warning: if frame already has been allocated, calling this function will + * leak memory. In addition, undefined behavior can occur in certain + * cases. + * + * @param frame frame in which to store the new buffers. + * @param align Required buffer size alignment. If equal to 0, alignment will be + * chosen automatically for the current CPU. It is highly + * recommended to pass 0 here unless you know what you are doing. + * + * @return 0 on success, a negative AVERROR on error. + */ +int av_frame_get_buffer(AVFrame *frame, int align); + +/** + * Check if the frame data is writable. + * + * @return A positive value if the frame data is writable (which is true if and + * only if each of the underlying buffers has only one reference, namely the one + * stored in this frame). Return 0 otherwise. + * + * If 1 is returned the answer is valid until av_buffer_ref() is called on any + * of the underlying AVBufferRefs (e.g. through av_frame_ref() or directly). + * + * @see av_frame_make_writable(), av_buffer_is_writable() + */ +int av_frame_is_writable(AVFrame *frame); + +/** + * Ensure that the frame data is writable, avoiding data copy if possible. + * + * Do nothing if the frame is writable, allocate new buffers and copy the data + * if it is not. + * + * @return 0 on success, a negative AVERROR on error. + * + * @see av_frame_is_writable(), av_buffer_is_writable(), + * av_buffer_make_writable() + */ +int av_frame_make_writable(AVFrame *frame); + +/** + * Copy the frame data from src to dst. + * + * This function does not allocate anything, dst must be already initialized and + * allocated with the same parameters as src. + * + * This function only copies the frame data (i.e. the contents of the data / + * extended data arrays), not any other properties. + * + * @return >= 0 on success, a negative AVERROR on error. + */ +int av_frame_copy(AVFrame *dst, const AVFrame *src); + +/** + * Copy only "metadata" fields from src to dst. + * + * Metadata for the purpose of this function are those fields that do not affect + * the data layout in the buffers. E.g. pts, sample rate (for audio) or sample + * aspect ratio (for video), but not width/height or channel layout. + * Side data is also copied. + */ +int av_frame_copy_props(AVFrame *dst, const AVFrame *src); + +/** + * Get the buffer reference a given data plane is stored in. + * + * @param plane index of the data plane of interest in frame->extended_data. + * + * @return the buffer reference that contains the plane or NULL if the input + * frame is not valid. + */ +AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane); + +/** + * Add a new side data to a frame. + * + * @param frame a frame to which the side data should be added + * @param type type of the added side data + * @param size size of the side data + * + * @return newly added side data on success, NULL on error + */ +AVFrameSideData *av_frame_new_side_data(AVFrame *frame, + enum AVFrameSideDataType type, + int size); + +/** + * Add a new side data to a frame from an existing AVBufferRef + * + * @param frame a frame to which the side data should be added + * @param type the type of the added side data + * @param buf an AVBufferRef to add as side data. The ownership of + * the reference is transferred to the frame. + * + * @return newly added side data on success, NULL on error. On failure + * the frame is unchanged and the AVBufferRef remains owned by + * the caller. + */ +AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf); + +/** + * @return a pointer to the side data of a given type on success, NULL if there + * is no side data with such type in this frame. + */ +AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, + enum AVFrameSideDataType type); + +/** + * If side data of the supplied type exists in the frame, free it and remove it + * from the frame. + */ +void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type); + + +/** + * Flags for frame cropping. + */ +enum { + /** + * Apply the maximum possible cropping, even if it requires setting the + * AVFrame.data[] entries to unaligned pointers. Passing unaligned data + * to FFmpeg API is generally not allowed, and causes undefined behavior + * (such as crashes). You can pass unaligned data only to FFmpeg APIs that + * are explicitly documented to accept it. Use this flag only if you + * absolutely know what you are doing. + */ + AV_FRAME_CROP_UNALIGNED = 1 << 0, +}; + +/** + * Crop the given video AVFrame according to its crop_left/crop_top/crop_right/ + * crop_bottom fields. If cropping is successful, the function will adjust the + * data pointers and the width/height fields, and set the crop fields to 0. + * + * In all cases, the cropping boundaries will be rounded to the inherent + * alignment of the pixel format. In some cases, such as for opaque hwaccel + * formats, the left/top cropping is ignored. The crop fields are set to 0 even + * if the cropping was rounded or ignored. + * + * @param frame the frame which should be cropped + * @param flags Some combination of AV_FRAME_CROP_* flags, or 0. + * + * @return >= 0 on success, a negative AVERROR on error. If the cropping fields + * were invalid, AVERROR(ERANGE) is returned, and nothing is changed. + */ +int av_frame_apply_cropping(AVFrame *frame, int flags); + +/** + * @return a string identifying the side data type + */ +const char *av_frame_side_data_name(enum AVFrameSideDataType type); + +/** + * @} + */ + +#endif /* AVUTIL_FRAME_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hash.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hash.c new file mode 100644 index 000000000..75edb6db7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hash.c @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include "hash.h" + +#include "adler32.h" +#include "crc.h" +#include "md5.h" +#include "murmur3.h" +#include "ripemd.h" +#include "sha.h" +#include "sha512.h" + +#include "avstring.h" +#include "base64.h" +#include "error.h" +#include "intreadwrite.h" +#include "mem.h" + +enum hashtype { + MD5, + MURMUR3, + RIPEMD128, + RIPEMD160, + RIPEMD256, + RIPEMD320, + SHA160, + SHA224, + SHA256, + SHA512_224, + SHA512_256, + SHA384, + SHA512, + CRC32, + ADLER32, + NUM_HASHES +}; + +typedef struct AVHashContext { + void *ctx; + enum hashtype type; + const AVCRC *crctab; + uint32_t crc; +} AVHashContext; + +static const struct { + const char *name; + int size; +} hashdesc[] = { + [MD5] = {"MD5", 16}, + [MURMUR3] = {"murmur3", 16}, + [RIPEMD128] = {"RIPEMD128", 16}, + [RIPEMD160] = {"RIPEMD160", 20}, + [RIPEMD256] = {"RIPEMD256", 32}, + [RIPEMD320] = {"RIPEMD320", 40}, + [SHA160] = {"SHA160", 20}, + [SHA224] = {"SHA224", 28}, + [SHA256] = {"SHA256", 32}, + [SHA512_224] = {"SHA512/224", 28}, + [SHA512_256] = {"SHA512/256", 32}, + [SHA384] = {"SHA384", 48}, + [SHA512] = {"SHA512", 64}, + [CRC32] = {"CRC32", 4}, + [ADLER32] = {"adler32", 4}, +}; + +const char *av_hash_names(int i) +{ + if (i < 0 || i >= NUM_HASHES) return NULL; + return hashdesc[i].name; +} + +const char *av_hash_get_name(const AVHashContext *ctx) +{ + return hashdesc[ctx->type].name; +} + +int av_hash_get_size(const AVHashContext *ctx) +{ + return hashdesc[ctx->type].size; +} + +int av_hash_alloc(AVHashContext **ctx, const char *name) +{ + AVHashContext *res; + int i; + *ctx = NULL; + for (i = 0; i < NUM_HASHES; i++) + if (av_strcasecmp(name, hashdesc[i].name) == 0) + break; + if (i >= NUM_HASHES) return AVERROR(EINVAL); + res = av_mallocz(sizeof(*res)); + if (!res) return AVERROR(ENOMEM); + res->type = i; + switch (i) { + case MD5: res->ctx = av_md5_alloc(); break; + case MURMUR3: res->ctx = av_murmur3_alloc(); break; + case RIPEMD128: + case RIPEMD160: + case RIPEMD256: + case RIPEMD320: res->ctx = av_ripemd_alloc(); break; + case SHA160: + case SHA224: + case SHA256: res->ctx = av_sha_alloc(); break; + case SHA512_224: + case SHA512_256: + case SHA384: + case SHA512: res->ctx = av_sha512_alloc(); break; + case CRC32: res->crctab = av_crc_get_table(AV_CRC_32_IEEE_LE); break; + case ADLER32: break; + } + if (i != ADLER32 && i != CRC32 && !res->ctx) { + av_free(res); + return AVERROR(ENOMEM); + } + *ctx = res; + return 0; +} + +void av_hash_init(AVHashContext *ctx) +{ + switch (ctx->type) { + case MD5: av_md5_init(ctx->ctx); break; + case MURMUR3: av_murmur3_init(ctx->ctx); break; + case RIPEMD128: av_ripemd_init(ctx->ctx, 128); break; + case RIPEMD160: av_ripemd_init(ctx->ctx, 160); break; + case RIPEMD256: av_ripemd_init(ctx->ctx, 256); break; + case RIPEMD320: av_ripemd_init(ctx->ctx, 320); break; + case SHA160: av_sha_init(ctx->ctx, 160); break; + case SHA224: av_sha_init(ctx->ctx, 224); break; + case SHA256: av_sha_init(ctx->ctx, 256); break; + case SHA512_224: av_sha512_init(ctx->ctx, 224); break; + case SHA512_256: av_sha512_init(ctx->ctx, 256); break; + case SHA384: av_sha512_init(ctx->ctx, 384); break; + case SHA512: av_sha512_init(ctx->ctx, 512); break; + case CRC32: ctx->crc = UINT32_MAX; break; + case ADLER32: ctx->crc = 1; break; + } +} + +#if FF_API_CRYPTO_SIZE_T +void av_hash_update(AVHashContext *ctx, const uint8_t *src, int len) +#else +void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len) +#endif +{ + switch (ctx->type) { + case MD5: av_md5_update(ctx->ctx, src, len); break; + case MURMUR3: av_murmur3_update(ctx->ctx, src, len); break; + case RIPEMD128: + case RIPEMD160: + case RIPEMD256: + case RIPEMD320: av_ripemd_update(ctx->ctx, src, len); break; + case SHA160: + case SHA224: + case SHA256: av_sha_update(ctx->ctx, src, len); break; + case SHA512_224: + case SHA512_256: + case SHA384: + case SHA512: av_sha512_update(ctx->ctx, src, len); break; + case CRC32: ctx->crc = av_crc(ctx->crctab, ctx->crc, src, len); break; + case ADLER32: ctx->crc = av_adler32_update(ctx->crc, src, len); break; + } +} + +void av_hash_final(AVHashContext *ctx, uint8_t *dst) +{ + switch (ctx->type) { + case MD5: av_md5_final(ctx->ctx, dst); break; + case MURMUR3: av_murmur3_final(ctx->ctx, dst); break; + case RIPEMD128: + case RIPEMD160: + case RIPEMD256: + case RIPEMD320: av_ripemd_final(ctx->ctx, dst); break; + case SHA160: + case SHA224: + case SHA256: av_sha_final(ctx->ctx, dst); break; + case SHA512_224: + case SHA512_256: + case SHA384: + case SHA512: av_sha512_final(ctx->ctx, dst); break; + case CRC32: AV_WB32(dst, ctx->crc ^ UINT32_MAX); break; + case ADLER32: AV_WB32(dst, ctx->crc); break; + } +} + +void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size) +{ + uint8_t buf[AV_HASH_MAX_SIZE]; + unsigned rsize = av_hash_get_size(ctx); + + av_hash_final(ctx, buf); + memcpy(dst, buf, FFMIN(size, rsize)); + if (size > rsize) + memset(dst + rsize, 0, size - rsize); +} + +void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size) +{ + uint8_t buf[AV_HASH_MAX_SIZE]; + unsigned rsize = av_hash_get_size(ctx), i; + + av_hash_final(ctx, buf); + for (i = 0; i < FFMIN(rsize, size / 2); i++) + snprintf(dst + i * 2, size - i * 2, "%02x", buf[i]); +} + +void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size) +{ + uint8_t buf[AV_HASH_MAX_SIZE], b64[AV_BASE64_SIZE(AV_HASH_MAX_SIZE)]; + unsigned rsize = av_hash_get_size(ctx), osize; + + av_hash_final(ctx, buf); + av_base64_encode(b64, sizeof(b64), buf, rsize); + osize = AV_BASE64_SIZE(rsize); + memcpy(dst, b64, FFMIN(osize, size)); + if (size < osize) + dst[size - 1] = 0; +} + +void av_hash_freep(AVHashContext **ctx) +{ + if (*ctx) + av_freep(&(*ctx)->ctx); + av_freep(ctx); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hash.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hash.h new file mode 100644 index 000000000..7693e6bf0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hash.h @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_hash_generic + * Generic hashing API + */ + +#ifndef AVUTIL_HASH_H +#define AVUTIL_HASH_H + +#include + +#include "version.h" + +/** + * @defgroup lavu_hash Hash Functions + * @ingroup lavu_crypto + * Hash functions useful in multimedia. + * + * Hash functions are widely used in multimedia, from error checking and + * concealment to internal regression testing. libavutil has efficient + * implementations of a variety of hash functions that may be useful for + * FFmpeg and other multimedia applications. + * + * @{ + * + * @defgroup lavu_hash_generic Generic Hashing API + * An abstraction layer for all hash functions supported by libavutil. + * + * If your application needs to support a wide range of different hash + * functions, then the Generic Hashing API is for you. It provides a generic, + * reusable API for @ref lavu_hash "all hash functions" implemented in libavutil. + * If you just need to use one particular hash function, use the @ref lavu_hash + * "individual hash" directly. + * + * @section Sample Code + * + * A basic template for using the Generic Hashing API follows: + * + * @code + * struct AVHashContext *ctx = NULL; + * const char *hash_name = NULL; + * uint8_t *output_buf = NULL; + * + * // Select from a string returned by av_hash_names() + * hash_name = ...; + * + * // Allocate a hash context + * ret = av_hash_alloc(&ctx, hash_name); + * if (ret < 0) + * return ret; + * + * // Initialize the hash context + * av_hash_init(ctx); + * + * // Update the hash context with data + * while (data_left) { + * av_hash_update(ctx, data, size); + * } + * + * // Now we have no more data, so it is time to finalize the hash and get the + * // output. But we need to first allocate an output buffer. Note that you can + * // use any memory allocation function, including malloc(), not just + * // av_malloc(). + * output_buf = av_malloc(av_hash_get_size(ctx)); + * if (!output_buf) + * return AVERROR(ENOMEM); + * + * // Finalize the hash context. + * // You can use any of the av_hash_final*() functions provided, for other + * // output formats. If you do so, be sure to adjust the memory allocation + * // above. See the function documentation below for the exact amount of extra + * // memory needed. + * av_hash_final(ctx, output_buffer); + * + * // Free the context + * av_hash_freep(&ctx); + * @endcode + * + * @section Hash Function-Specific Information + * If the CRC32 hash is selected, the #AV_CRC_32_IEEE polynomial will be + * used. + * + * If the Murmur3 hash is selected, the default seed will be used. See @ref + * lavu_murmur3_seedinfo "Murmur3" for more information. + * + * @{ + */ + +/** + * @example ffhash.c + * This example is a simple command line application that takes one or more + * arguments. It demonstrates a typical use of the hashing API with allocation, + * initialization, updating, and finalizing. + */ + +struct AVHashContext; + +/** + * Allocate a hash context for the algorithm specified by name. + * + * @return >= 0 for success, a negative error code for failure + * + * @note The context is not initialized after a call to this function; you must + * call av_hash_init() to do so. + */ +int av_hash_alloc(struct AVHashContext **ctx, const char *name); + +/** + * Get the names of available hash algorithms. + * + * This function can be used to enumerate the algorithms. + * + * @param[in] i Index of the hash algorithm, starting from 0 + * @return Pointer to a static string or `NULL` if `i` is out of range + */ +const char *av_hash_names(int i); + +/** + * Get the name of the algorithm corresponding to the given hash context. + */ +const char *av_hash_get_name(const struct AVHashContext *ctx); + +/** + * Maximum value that av_hash_get_size() will currently return. + * + * You can use this if you absolutely want or need to use static allocation for + * the output buffer and are fine with not supporting hashes newly added to + * libavutil without recompilation. + * + * @warning + * Adding new hashes with larger sizes, and increasing the macro while doing + * so, will not be considered an ABI change. To prevent your code from + * overflowing a buffer, either dynamically allocate the output buffer with + * av_hash_get_size(), or limit your use of the Hashing API to hashes that are + * already in FFmpeg during the time of compilation. + */ +#define AV_HASH_MAX_SIZE 64 + +/** + * Get the size of the resulting hash value in bytes. + * + * The maximum value this function will currently return is available as macro + * #AV_HASH_MAX_SIZE. + * + * @param[in] ctx Hash context + * @return Size of the hash value in bytes + */ +int av_hash_get_size(const struct AVHashContext *ctx); + +/** + * Initialize or reset a hash context. + * + * @param[in,out] ctx Hash context + */ +void av_hash_init(struct AVHashContext *ctx); + +/** + * Update a hash context with additional data. + * + * @param[in,out] ctx Hash context + * @param[in] src Data to be added to the hash context + * @param[in] len Size of the additional data + */ +#if FF_API_CRYPTO_SIZE_T +void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, int len); +#else +void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, size_t len); +#endif + +/** + * Finalize a hash context and compute the actual hash value. + * + * The minimum size of `dst` buffer is given by av_hash_get_size() or + * #AV_HASH_MAX_SIZE. The use of the latter macro is discouraged. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the final hash value will be stored + * + * @see av_hash_final_bin() provides an alternative API + */ +void av_hash_final(struct AVHashContext *ctx, uint8_t *dst); + +/** + * Finalize a hash context and store the actual hash value in a buffer. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * If `size` is smaller than the hash size (given by av_hash_get_size()), the + * hash is truncated; if size is larger, the buffer is padded with 0. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the final hash value will be stored + * @param[in] size Number of bytes to write to `dst` + */ +void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size); + +/** + * Finalize a hash context and store the hexadecimal representation of the + * actual hash value as a string. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * The string is always 0-terminated. + * + * If `size` is smaller than `2 * hash_size + 1`, where `hash_size` is the + * value returned by av_hash_get_size(), the string will be truncated. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the string will be stored + * @param[in] size Maximum number of bytes to write to `dst` + */ +void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size); + +/** + * Finalize a hash context and store the Base64 representation of the + * actual hash value as a string. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * The string is always 0-terminated. + * + * If `size` is smaller than AV_BASE64_SIZE(hash_size), where `hash_size` is + * the value returned by av_hash_get_size(), the string will be truncated. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the final hash value will be stored + * @param[in] size Maximum number of bytes to write to `dst` + */ +void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size); + +/** + * Free hash context and set hash context pointer to `NULL`. + * + * @param[in,out] ctx Pointer to hash context + */ +void av_hash_freep(struct AVHashContext **ctx); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_HASH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hdr_dynamic_metadata.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hdr_dynamic_metadata.c new file mode 100644 index 000000000..0fa1ee82d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hdr_dynamic_metadata.c @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2018 Mohammad Izadi + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "hdr_dynamic_metadata.h" +#include "mem.h" + +AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size) +{ + AVDynamicHDRPlus *hdr_plus = av_mallocz(sizeof(AVDynamicHDRPlus)); + if (!hdr_plus) + return NULL; + + if (size) + *size = sizeof(*hdr_plus); + + return hdr_plus; +} + +AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_DYNAMIC_HDR_PLUS, + sizeof(AVDynamicHDRPlus)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVDynamicHDRPlus)); + + return (AVDynamicHDRPlus *)side_data->data; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hdr_dynamic_metadata.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hdr_dynamic_metadata.h new file mode 100644 index 000000000..2d72de56a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hdr_dynamic_metadata.h @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2018 Mohammad Izadi + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HDR_DYNAMIC_METADATA_H +#define AVUTIL_HDR_DYNAMIC_METADATA_H + +#include "frame.h" +#include "rational.h" + +/** + * Option for overlapping elliptical pixel selectors in an image. + */ +enum AVHDRPlusOverlapProcessOption { + AV_HDR_PLUS_OVERLAP_PROCESS_WEIGHTED_AVERAGING = 0, + AV_HDR_PLUS_OVERLAP_PROCESS_LAYERING = 1, +}; + +/** + * Represents the percentile at a specific percentage in + * a distribution. + */ +typedef struct AVHDRPlusPercentile { + /** + * The percentage value corresponding to a specific percentile linearized + * RGB value in the processing window in the scene. The value shall be in + * the range of 0 to100, inclusive. + */ + uint8_t percentage; + + /** + * The linearized maxRGB value at a specific percentile in the processing + * window in the scene. The value shall be in the range of 0 to 1, inclusive + * and in multiples of 0.00001. + */ + AVRational percentile; +} AVHDRPlusPercentile; + +/** + * Color transform parameters at a processing window in a dynamic metadata for + * SMPTE 2094-40. + */ +typedef struct AVHDRPlusColorTransformParams { + /** + * The relative x coordinate of the top left pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(width of Picture - 1). The value 1 corresponds + * to the absolute coordinate of width of Picture - 1. The value for + * first processing window shall be 0. + */ + AVRational window_upper_left_corner_x; + + /** + * The relative y coordinate of the top left pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(height of Picture - 1). The value 1 corresponds + * to the absolute coordinate of height of Picture - 1. The value for + * first processing window shall be 0. + */ + AVRational window_upper_left_corner_y; + + /** + * The relative x coordinate of the bottom right pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(width of Picture - 1). The value 1 corresponds + * to the absolute coordinate of width of Picture - 1. The value for + * first processing window shall be 1. + */ + AVRational window_lower_right_corner_x; + + /** + * The relative y coordinate of the bottom right pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(height of Picture - 1). The value 1 corresponds + * to the absolute coordinate of height of Picture - 1. The value for + * first processing window shall be 1. + */ + AVRational window_lower_right_corner_y; + + /** + * The x coordinate of the center position of the concentric internal and + * external ellipses of the elliptical pixel selector in the processing + * window. The value shall be in the range of 0 to (width of Picture - 1), + * inclusive and in multiples of 1 pixel. + */ + uint16_t center_of_ellipse_x; + + /** + * The y coordinate of the center position of the concentric internal and + * external ellipses of the elliptical pixel selector in the processing + * window. The value shall be in the range of 0 to (height of Picture - 1), + * inclusive and in multiples of 1 pixel. + */ + uint16_t center_of_ellipse_y; + + /** + * The clockwise rotation angle in degree of arc with respect to the + * positive direction of the x-axis of the concentric internal and external + * ellipses of the elliptical pixel selector in the processing window. The + * value shall be in the range of 0 to 180, inclusive and in multiples of 1. + */ + uint8_t rotation_angle; + + /** + * The semi-major axis value of the internal ellipse of the elliptical pixel + * selector in amount of pixels in the processing window. The value shall be + * in the range of 1 to 65535, inclusive and in multiples of 1 pixel. + */ + uint16_t semimajor_axis_internal_ellipse; + + /** + * The semi-major axis value of the external ellipse of the elliptical pixel + * selector in amount of pixels in the processing window. The value + * shall not be less than semimajor_axis_internal_ellipse of the current + * processing window. The value shall be in the range of 1 to 65535, + * inclusive and in multiples of 1 pixel. + */ + uint16_t semimajor_axis_external_ellipse; + + /** + * The semi-minor axis value of the external ellipse of the elliptical pixel + * selector in amount of pixels in the processing window. The value shall be + * in the range of 1 to 65535, inclusive and in multiples of 1 pixel. + */ + uint16_t semiminor_axis_external_ellipse; + + /** + * Overlap process option indicates one of the two methods of combining + * rendered pixels in the processing window in an image with at least one + * elliptical pixel selector. For overlapping elliptical pixel selectors + * in an image, overlap_process_option shall have the same value. + */ + enum AVHDRPlusOverlapProcessOption overlap_process_option; + + /** + * The maximum of the color components of linearized RGB values in the + * processing window in the scene. The values should be in the range of 0 to + * 1, inclusive and in multiples of 0.00001. maxscl[ 0 ], maxscl[ 1 ], and + * maxscl[ 2 ] are corresponding to R, G, B color components respectively. + */ + AVRational maxscl[3]; + + /** + * The average of linearized maxRGB values in the processing window in the + * scene. The value should be in the range of 0 to 1, inclusive and in + * multiples of 0.00001. + */ + AVRational average_maxrgb; + + /** + * The number of linearized maxRGB values at given percentiles in the + * processing window in the scene. The maximum value shall be 15. + */ + uint8_t num_distribution_maxrgb_percentiles; + + /** + * The linearized maxRGB values at given percentiles in the + * processing window in the scene. + */ + AVHDRPlusPercentile distribution_maxrgb[15]; + + /** + * The fraction of selected pixels in the image that contains the brightest + * pixel in the scene. The value shall be in the range of 0 to 1, inclusive + * and in multiples of 0.001. + */ + AVRational fraction_bright_pixels; + + /** + * This flag indicates that the metadata for the tone mapping function in + * the processing window is present (for value of 1). + */ + uint8_t tone_mapping_flag; + + /** + * The x coordinate of the separation point between the linear part and the + * curved part of the tone mapping function. The value shall be in the range + * of 0 to 1, excluding 0 and in multiples of 1/4095. + */ + AVRational knee_point_x; + + /** + * The y coordinate of the separation point between the linear part and the + * curved part of the tone mapping function. The value shall be in the range + * of 0 to 1, excluding 0 and in multiples of 1/4095. + */ + AVRational knee_point_y; + + /** + * The number of the intermediate anchor parameters of the tone mapping + * function in the processing window. The maximum value shall be 15. + */ + uint8_t num_bezier_curve_anchors; + + /** + * The intermediate anchor parameters of the tone mapping function in the + * processing window in the scene. The values should be in the range of 0 + * to 1, inclusive and in multiples of 1/1023. + */ + AVRational bezier_curve_anchors[15]; + + /** + * This flag shall be equal to 0 in bitstreams conforming to this version of + * this Specification. Other values are reserved for future use. + */ + uint8_t color_saturation_mapping_flag; + + /** + * The color saturation gain in the processing window in the scene. The + * value shall be in the range of 0 to 63/8, inclusive and in multiples of + * 1/8. The default value shall be 1. + */ + AVRational color_saturation_weight; +} AVHDRPlusColorTransformParams; + +/** + * This struct represents dynamic metadata for color volume transform - + * application 4 of SMPTE 2094-40:2016 standard. + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with + * av_dynamic_hdr_plus_alloc() and its size is not a part of + * the public ABI. + */ +typedef struct AVDynamicHDRPlus { + /** + * Country code by Rec. ITU-T T.35 Annex A. The value shall be 0xB5. + */ + uint8_t itu_t_t35_country_code; + + /** + * Application version in the application defining document in ST-2094 + * suite. The value shall be set to 0. + */ + uint8_t application_version; + + /** + * The number of processing windows. The value shall be in the range + * of 1 to 3, inclusive. + */ + uint8_t num_windows; + + /** + * The color transform parameters for every processing window. + */ + AVHDRPlusColorTransformParams params[3]; + + /** + * The nominal maximum display luminance of the targeted system display, + * in units of 0.0001 candelas per square metre. The value shall be in + * the range of 0 to 10000, inclusive. + */ + AVRational targeted_system_display_maximum_luminance; + + /** + * This flag shall be equal to 0 in bit streams conforming to this version + * of this Specification. The value 1 is reserved for future use. + */ + uint8_t targeted_system_display_actual_peak_luminance_flag; + + /** + * The number of rows in the targeted system_display_actual_peak_luminance + * array. The value shall be in the range of 2 to 25, inclusive. + */ + uint8_t num_rows_targeted_system_display_actual_peak_luminance; + + /** + * The number of columns in the + * targeted_system_display_actual_peak_luminance array. The value shall be + * in the range of 2 to 25, inclusive. + */ + uint8_t num_cols_targeted_system_display_actual_peak_luminance; + + /** + * The normalized actual peak luminance of the targeted system display. The + * values should be in the range of 0 to 1, inclusive and in multiples of + * 1/15. + */ + AVRational targeted_system_display_actual_peak_luminance[25][25]; + + /** + * This flag shall be equal to 0 in bitstreams conforming to this version of + * this Specification. The value 1 is reserved for future use. + */ + uint8_t mastering_display_actual_peak_luminance_flag; + + /** + * The number of rows in the mastering_display_actual_peak_luminance array. + * The value shall be in the range of 2 to 25, inclusive. + */ + uint8_t num_rows_mastering_display_actual_peak_luminance; + + /** + * The number of columns in the mastering_display_actual_peak_luminance + * array. The value shall be in the range of 2 to 25, inclusive. + */ + uint8_t num_cols_mastering_display_actual_peak_luminance; + + /** + * The normalized actual peak luminance of the mastering display used for + * mastering the image essence. The values should be in the range of 0 to 1, + * inclusive and in multiples of 1/15. + */ + AVRational mastering_display_actual_peak_luminance[25][25]; +} AVDynamicHDRPlus; + +/** + * Allocate an AVDynamicHDRPlus structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVDynamicHDRPlus filled with default values or NULL + * on failure. + */ +AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size); + +/** + * Allocate a complete AVDynamicHDRPlus and add it to the frame. + * @param frame The frame which side data is added to. + * + * @return The AVDynamicHDRPlus structure to be filled by caller or NULL + * on failure. + */ +AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_HDR_DYNAMIC_METADATA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hmac.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hmac.c new file mode 100644 index 000000000..d064a105f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hmac.c @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2012 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include "attributes.h" +#include "hmac.h" +#include "md5.h" +#include "sha.h" +#include "sha512.h" +#include "mem.h" +#include "version.h" + +#define MAX_HASHLEN 64 +#define MAX_BLOCKLEN 128 + +typedef void (*hmac_final)(void *ctx, uint8_t *dst); +#if FF_API_CRYPTO_SIZE_T +typedef void (*hmac_update)(void *ctx, const uint8_t *src, int len); +#else +typedef void (*hmac_update)(void *ctx, const uint8_t *src, size_t len); +#endif +typedef void (*hmac_init)(void *ctx); + +struct AVHMAC { + void *hash; + int blocklen, hashlen; + hmac_final final; + hmac_update update; + hmac_init init; + uint8_t key[MAX_BLOCKLEN]; + int keylen; +}; + +#define DEFINE_SHA(bits) \ +static av_cold void sha ## bits ##_init(void *ctx) \ +{ \ + av_sha_init(ctx, bits); \ +} + +#define DEFINE_SHA512(bits) \ +static av_cold void sha ## bits ##_init(void *ctx) \ +{ \ + av_sha512_init(ctx, bits); \ +} + +DEFINE_SHA(160) +DEFINE_SHA(224) +DEFINE_SHA(256) +DEFINE_SHA512(384) +DEFINE_SHA512(512) + +AVHMAC *av_hmac_alloc(enum AVHMACType type) +{ + AVHMAC *c = av_mallocz(sizeof(*c)); + if (!c) + return NULL; + switch (type) { + case AV_HMAC_MD5: + c->blocklen = 64; + c->hashlen = 16; + c->init = (hmac_init) av_md5_init; + c->update = (hmac_update) av_md5_update; + c->final = (hmac_final) av_md5_final; + c->hash = av_md5_alloc(); + break; + case AV_HMAC_SHA1: + c->blocklen = 64; + c->hashlen = 20; + c->init = sha160_init; + c->update = (hmac_update) av_sha_update; + c->final = (hmac_final) av_sha_final; + c->hash = av_sha_alloc(); + break; + case AV_HMAC_SHA224: + c->blocklen = 64; + c->hashlen = 28; + c->init = sha224_init; + c->update = (hmac_update) av_sha_update; + c->final = (hmac_final) av_sha_final; + c->hash = av_sha_alloc(); + break; + case AV_HMAC_SHA256: + c->blocklen = 64; + c->hashlen = 32; + c->init = sha256_init; + c->update = (hmac_update) av_sha_update; + c->final = (hmac_final) av_sha_final; + c->hash = av_sha_alloc(); + break; + case AV_HMAC_SHA384: + c->blocklen = 128; + c->hashlen = 48; + c->init = sha384_init; + c->update = (hmac_update) av_sha512_update; + c->final = (hmac_final) av_sha512_final; + c->hash = av_sha512_alloc(); + break; + case AV_HMAC_SHA512: + c->blocklen = 128; + c->hashlen = 64; + c->init = sha512_init; + c->update = (hmac_update) av_sha512_update; + c->final = (hmac_final) av_sha512_final; + c->hash = av_sha512_alloc(); + break; + default: + av_free(c); + return NULL; + } + if (!c->hash) { + av_free(c); + return NULL; + } + return c; +} + +void av_hmac_free(AVHMAC *c) +{ + if (!c) + return; + av_freep(&c->hash); + av_free(c); +} + +void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen) +{ + int i; + uint8_t block[MAX_BLOCKLEN]; + if (keylen > c->blocklen) { + c->init(c->hash); + c->update(c->hash, key, keylen); + c->final(c->hash, c->key); + c->keylen = c->hashlen; + } else { + memcpy(c->key, key, keylen); + c->keylen = keylen; + } + c->init(c->hash); + for (i = 0; i < c->keylen; i++) + block[i] = c->key[i] ^ 0x36; + for (i = c->keylen; i < c->blocklen; i++) + block[i] = 0x36; + c->update(c->hash, block, c->blocklen); +} + +void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len) +{ + c->update(c->hash, data, len); +} + +int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen) +{ + uint8_t block[MAX_BLOCKLEN]; + int i; + if (outlen < c->hashlen) + return AVERROR(EINVAL); + c->final(c->hash, out); + c->init(c->hash); + for (i = 0; i < c->keylen; i++) + block[i] = c->key[i] ^ 0x5C; + for (i = c->keylen; i < c->blocklen; i++) + block[i] = 0x5C; + c->update(c->hash, block, c->blocklen); + c->update(c->hash, out, c->hashlen); + c->final(c->hash, out); + return c->hashlen; +} + +int av_hmac_calc(AVHMAC *c, const uint8_t *data, unsigned int len, + const uint8_t *key, unsigned int keylen, + uint8_t *out, unsigned int outlen) +{ + av_hmac_init(c, key, keylen); + av_hmac_update(c, data, len); + return av_hmac_final(c, out, outlen); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hmac.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hmac.h new file mode 100644 index 000000000..412e95071 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hmac.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2012 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HMAC_H +#define AVUTIL_HMAC_H + +#include + +#include "version.h" +/** + * @defgroup lavu_hmac HMAC + * @ingroup lavu_crypto + * @{ + */ + +enum AVHMACType { + AV_HMAC_MD5, + AV_HMAC_SHA1, + AV_HMAC_SHA224, + AV_HMAC_SHA256, + AV_HMAC_SHA384, + AV_HMAC_SHA512, +}; + +typedef struct AVHMAC AVHMAC; + +/** + * Allocate an AVHMAC context. + * @param type The hash function used for the HMAC. + */ +AVHMAC *av_hmac_alloc(enum AVHMACType type); + +/** + * Free an AVHMAC context. + * @param ctx The context to free, may be NULL + */ +void av_hmac_free(AVHMAC *ctx); + +/** + * Initialize an AVHMAC context with an authentication key. + * @param ctx The HMAC context + * @param key The authentication key + * @param keylen The length of the key, in bytes + */ +void av_hmac_init(AVHMAC *ctx, const uint8_t *key, unsigned int keylen); + +/** + * Hash data with the HMAC. + * @param ctx The HMAC context + * @param data The data to hash + * @param len The length of the data, in bytes + */ +void av_hmac_update(AVHMAC *ctx, const uint8_t *data, unsigned int len); + +/** + * Finish hashing and output the HMAC digest. + * @param ctx The HMAC context + * @param out The output buffer to write the digest into + * @param outlen The length of the out buffer, in bytes + * @return The number of bytes written to out, or a negative error code. + */ +int av_hmac_final(AVHMAC *ctx, uint8_t *out, unsigned int outlen); + +/** + * Hash an array of data with a key. + * @param ctx The HMAC context + * @param data The data to hash + * @param len The length of the data, in bytes + * @param key The authentication key + * @param keylen The length of the key, in bytes + * @param out The output buffer to write the digest into + * @param outlen The length of the out buffer, in bytes + * @return The number of bytes written to out, or a negative error code. + */ +int av_hmac_calc(AVHMAC *ctx, const uint8_t *data, unsigned int len, + const uint8_t *key, unsigned int keylen, + uint8_t *out, unsigned int outlen); + +/** + * @} + */ + +#endif /* AVUTIL_HMAC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext.c new file mode 100644 index 000000000..f1e404ab2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext.c @@ -0,0 +1,879 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "imgutils.h" +#include "log.h" +#include "mem.h" +#include "pixdesc.h" +#include "pixfmt.h" + +static const HWContextType * const hw_table[] = { +#if CONFIG_CUDA + &ff_hwcontext_type_cuda, +#endif +#if CONFIG_D3D11VA + &ff_hwcontext_type_d3d11va, +#endif +#if CONFIG_LIBDRM + &ff_hwcontext_type_drm, +#endif +#if CONFIG_DXVA2 + &ff_hwcontext_type_dxva2, +#endif +#if CONFIG_OPENCL + &ff_hwcontext_type_opencl, +#endif +#if CONFIG_QSV + &ff_hwcontext_type_qsv, +#endif +#if CONFIG_VAAPI + &ff_hwcontext_type_vaapi, +#endif +#if CONFIG_VDPAU + &ff_hwcontext_type_vdpau, +#endif +#if CONFIG_VIDEOTOOLBOX + &ff_hwcontext_type_videotoolbox, +#endif +#if CONFIG_MEDIACODEC + &ff_hwcontext_type_mediacodec, +#endif + NULL, +}; + +static const char *const hw_type_names[] = { + [AV_HWDEVICE_TYPE_CUDA] = "cuda", + [AV_HWDEVICE_TYPE_DRM] = "drm", + [AV_HWDEVICE_TYPE_DXVA2] = "dxva2", + [AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va", + [AV_HWDEVICE_TYPE_OPENCL] = "opencl", + [AV_HWDEVICE_TYPE_QSV] = "qsv", + [AV_HWDEVICE_TYPE_VAAPI] = "vaapi", + [AV_HWDEVICE_TYPE_VDPAU] = "vdpau", + [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox", + [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec", +}; + +enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name) +{ + int type; + for (type = 0; type < FF_ARRAY_ELEMS(hw_type_names); type++) { + if (hw_type_names[type] && !strcmp(hw_type_names[type], name)) + return type; + } + return AV_HWDEVICE_TYPE_NONE; +} + +const char *av_hwdevice_get_type_name(enum AVHWDeviceType type) +{ + if (type > AV_HWDEVICE_TYPE_NONE && + type < FF_ARRAY_ELEMS(hw_type_names)) + return hw_type_names[type]; + else + return NULL; +} + +enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev) +{ + enum AVHWDeviceType next; + int i, set = 0; + for (i = 0; hw_table[i]; i++) { + if (prev != AV_HWDEVICE_TYPE_NONE && hw_table[i]->type <= prev) + continue; + if (!set || hw_table[i]->type < next) { + next = hw_table[i]->type; + set = 1; + } + } + return set ? next : AV_HWDEVICE_TYPE_NONE; +} + +static const AVClass hwdevice_ctx_class = { + .class_name = "AVHWDeviceContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +static void hwdevice_ctx_free(void *opaque, uint8_t *data) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)data; + + /* uninit might still want access the hw context and the user + * free() callback might destroy it, so uninit has to be called first */ + if (ctx->internal->hw_type->device_uninit) + ctx->internal->hw_type->device_uninit(ctx); + + if (ctx->free) + ctx->free(ctx); + + av_buffer_unref(&ctx->internal->source_device); + + av_freep(&ctx->hwctx); + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx); +} + +AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type) +{ + AVHWDeviceContext *ctx; + AVBufferRef *buf; + const HWContextType *hw_type = NULL; + int i; + + for (i = 0; hw_table[i]; i++) { + if (hw_table[i]->type == type) { + hw_type = hw_table[i]; + break; + } + } + if (!hw_type) + return NULL; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + ctx->internal = av_mallocz(sizeof(*ctx->internal)); + if (!ctx->internal) + goto fail; + + if (hw_type->device_priv_size) { + ctx->internal->priv = av_mallocz(hw_type->device_priv_size); + if (!ctx->internal->priv) + goto fail; + } + + if (hw_type->device_hwctx_size) { + ctx->hwctx = av_mallocz(hw_type->device_hwctx_size); + if (!ctx->hwctx) + goto fail; + } + + buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx), + hwdevice_ctx_free, NULL, + AV_BUFFER_FLAG_READONLY); + if (!buf) + goto fail; + + ctx->type = type; + ctx->av_class = &hwdevice_ctx_class; + + ctx->internal->hw_type = hw_type; + + return buf; + +fail: + if (ctx->internal) + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx->hwctx); + av_freep(&ctx); + return NULL; +} + +int av_hwdevice_ctx_init(AVBufferRef *ref) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data; + int ret; + + if (ctx->internal->hw_type->device_init) { + ret = ctx->internal->hw_type->device_init(ctx); + if (ret < 0) + goto fail; + } + + return 0; +fail: + if (ctx->internal->hw_type->device_uninit) + ctx->internal->hw_type->device_uninit(ctx); + return ret; +} + +static const AVClass hwframe_ctx_class = { + .class_name = "AVHWFramesContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, +}; + +static void hwframe_ctx_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)data; + + if (ctx->internal->pool_internal) + av_buffer_pool_uninit(&ctx->internal->pool_internal); + + if (ctx->internal->hw_type->frames_uninit) + ctx->internal->hw_type->frames_uninit(ctx); + + if (ctx->free) + ctx->free(ctx); + + av_buffer_unref(&ctx->internal->source_frames); + + av_buffer_unref(&ctx->device_ref); + + av_freep(&ctx->hwctx); + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx); +} + +AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in) +{ + AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref_in->data; + const HWContextType *hw_type = device_ctx->internal->hw_type; + AVHWFramesContext *ctx; + AVBufferRef *buf, *device_ref = NULL; + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + ctx->internal = av_mallocz(sizeof(*ctx->internal)); + if (!ctx->internal) + goto fail; + + if (hw_type->frames_priv_size) { + ctx->internal->priv = av_mallocz(hw_type->frames_priv_size); + if (!ctx->internal->priv) + goto fail; + } + + if (hw_type->frames_hwctx_size) { + ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size); + if (!ctx->hwctx) + goto fail; + } + + device_ref = av_buffer_ref(device_ref_in); + if (!device_ref) + goto fail; + + buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx), + hwframe_ctx_free, NULL, + AV_BUFFER_FLAG_READONLY); + if (!buf) + goto fail; + + ctx->av_class = &hwframe_ctx_class; + ctx->device_ref = device_ref; + ctx->device_ctx = device_ctx; + ctx->format = AV_PIX_FMT_NONE; + ctx->sw_format = AV_PIX_FMT_NONE; + + ctx->internal->hw_type = hw_type; + + return buf; + +fail: + if (device_ref) + av_buffer_unref(&device_ref); + if (ctx->internal) + av_freep(&ctx->internal->priv); + av_freep(&ctx->internal); + av_freep(&ctx->hwctx); + av_freep(&ctx); + return NULL; +} + +static int hwframe_pool_prealloc(AVBufferRef *ref) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data; + AVFrame **frames; + int i, ret = 0; + + frames = av_mallocz_array(ctx->initial_pool_size, sizeof(*frames)); + if (!frames) + return AVERROR(ENOMEM); + + for (i = 0; i < ctx->initial_pool_size; i++) { + frames[i] = av_frame_alloc(); + if (!frames[i]) + goto fail; + + ret = av_hwframe_get_buffer(ref, frames[i], 0); + if (ret < 0) + goto fail; + } + +fail: + for (i = 0; i < ctx->initial_pool_size; i++) + av_frame_free(&frames[i]); + av_freep(&frames); + + return ret; +} + +int av_hwframe_ctx_init(AVBufferRef *ref) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data; + const enum AVPixelFormat *pix_fmt; + int ret; + + if (ctx->internal->source_frames) { + /* A derived frame context is already initialised. */ + return 0; + } + + /* validate the pixel format */ + for (pix_fmt = ctx->internal->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) { + if (*pix_fmt == ctx->format) + break; + } + if (*pix_fmt == AV_PIX_FMT_NONE) { + av_log(ctx, AV_LOG_ERROR, + "The hardware pixel format '%s' is not supported by the device type '%s'\n", + av_get_pix_fmt_name(ctx->format), ctx->internal->hw_type->name); + return AVERROR(ENOSYS); + } + + /* validate the dimensions */ + ret = av_image_check_size(ctx->width, ctx->height, 0, ctx); + if (ret < 0) + return ret; + + /* format-specific init */ + if (ctx->internal->hw_type->frames_init) { + ret = ctx->internal->hw_type->frames_init(ctx); + if (ret < 0) + goto fail; + } + + if (ctx->internal->pool_internal && !ctx->pool) + ctx->pool = ctx->internal->pool_internal; + + /* preallocate the frames in the pool, if requested */ + if (ctx->initial_pool_size > 0) { + ret = hwframe_pool_prealloc(ref); + if (ret < 0) + goto fail; + } + + return 0; +fail: + if (ctx->internal->hw_type->frames_uninit) + ctx->internal->hw_type->frames_uninit(ctx); + return ret; +} + +int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats, int flags) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + + if (!ctx->internal->hw_type->transfer_get_formats) + return AVERROR(ENOSYS); + + return ctx->internal->hw_type->transfer_get_formats(ctx, dir, formats); +} + +static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; + AVFrame *frame_tmp; + int ret = 0; + + frame_tmp = av_frame_alloc(); + if (!frame_tmp) + return AVERROR(ENOMEM); + + /* if the format is set, use that + * otherwise pick the first supported one */ + if (dst->format >= 0) { + frame_tmp->format = dst->format; + } else { + enum AVPixelFormat *formats; + + ret = av_hwframe_transfer_get_formats(src->hw_frames_ctx, + AV_HWFRAME_TRANSFER_DIRECTION_FROM, + &formats, 0); + if (ret < 0) + goto fail; + frame_tmp->format = formats[0]; + av_freep(&formats); + } + frame_tmp->width = ctx->width; + frame_tmp->height = ctx->height; + + ret = av_frame_get_buffer(frame_tmp, 32); + if (ret < 0) + goto fail; + + ret = av_hwframe_transfer_data(frame_tmp, src, flags); + if (ret < 0) + goto fail; + + frame_tmp->width = src->width; + frame_tmp->height = src->height; + + av_frame_move_ref(dst, frame_tmp); + +fail: + av_frame_free(&frame_tmp); + return ret; +} + +int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags) +{ + AVHWFramesContext *ctx; + int ret; + + if (!dst->buf[0]) + return transfer_data_alloc(dst, src, flags); + + if (src->hw_frames_ctx) { + ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; + + ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src); + if (ret < 0) + return ret; + } else if (dst->hw_frames_ctx) { + ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src); + if (ret < 0) + return ret; + } else + return AVERROR(ENOSYS); + + return 0; +} + +int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + int ret; + + if (ctx->internal->source_frames) { + // This is a derived frame context, so we allocate in the source + // and map the frame immediately. + AVFrame *src_frame; + + frame->format = ctx->format; + frame->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!frame->hw_frames_ctx) + return AVERROR(ENOMEM); + + src_frame = av_frame_alloc(); + if (!src_frame) + return AVERROR(ENOMEM); + + ret = av_hwframe_get_buffer(ctx->internal->source_frames, + src_frame, 0); + if (ret < 0) { + av_frame_free(&src_frame); + return ret; + } + + ret = av_hwframe_map(frame, src_frame, + ctx->internal->source_allocation_map_flags); + if (ret) { + av_log(ctx, AV_LOG_ERROR, "Failed to map frame into derived " + "frame context: %d.\n", ret); + av_frame_free(&src_frame); + return ret; + } + + // Free the source frame immediately - the mapped frame still + // contains a reference to it. + av_frame_free(&src_frame); + + return 0; + } + + if (!ctx->internal->hw_type->frames_get_buffer) + return AVERROR(ENOSYS); + + if (!ctx->pool) + return AVERROR(EINVAL); + + frame->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!frame->hw_frames_ctx) + return AVERROR(ENOMEM); + + ret = ctx->internal->hw_type->frames_get_buffer(ctx, frame); + if (ret < 0) { + av_buffer_unref(&frame->hw_frames_ctx); + return ret; + } + + return 0; +} + +void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data; + const HWContextType *hw_type = ctx->internal->hw_type; + + if (hw_type->device_hwconfig_size == 0) + return NULL; + + return av_mallocz(hw_type->device_hwconfig_size); +} + +AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, + const void *hwconfig) +{ + AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data; + const HWContextType *hw_type = ctx->internal->hw_type; + AVHWFramesConstraints *constraints; + + if (!hw_type->frames_get_constraints) + return NULL; + + constraints = av_mallocz(sizeof(*constraints)); + if (!constraints) + return NULL; + + constraints->min_width = constraints->min_height = 0; + constraints->max_width = constraints->max_height = INT_MAX; + + if (hw_type->frames_get_constraints(ctx, hwconfig, constraints) >= 0) { + return constraints; + } else { + av_hwframe_constraints_free(&constraints); + return NULL; + } +} + +void av_hwframe_constraints_free(AVHWFramesConstraints **constraints) +{ + if (*constraints) { + av_freep(&(*constraints)->valid_hw_formats); + av_freep(&(*constraints)->valid_sw_formats); + } + av_freep(constraints); +} + +int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, + const char *device, AVDictionary *opts, int flags) +{ + AVBufferRef *device_ref = NULL; + AVHWDeviceContext *device_ctx; + int ret = 0; + + device_ref = av_hwdevice_ctx_alloc(type); + if (!device_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + device_ctx = (AVHWDeviceContext*)device_ref->data; + + if (!device_ctx->internal->hw_type->device_create) { + ret = AVERROR(ENOSYS); + goto fail; + } + + ret = device_ctx->internal->hw_type->device_create(device_ctx, device, + opts, flags); + if (ret < 0) + goto fail; + + ret = av_hwdevice_ctx_init(device_ref); + if (ret < 0) + goto fail; + + *pdevice_ref = device_ref; + return 0; +fail: + av_buffer_unref(&device_ref); + *pdevice_ref = NULL; + return ret; +} + +int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, + enum AVHWDeviceType type, + AVBufferRef *src_ref, int flags) +{ + AVBufferRef *dst_ref = NULL, *tmp_ref; + AVHWDeviceContext *dst_ctx, *tmp_ctx; + int ret = 0; + + tmp_ref = src_ref; + while (tmp_ref) { + tmp_ctx = (AVHWDeviceContext*)tmp_ref->data; + if (tmp_ctx->type == type) { + dst_ref = av_buffer_ref(tmp_ref); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + goto done; + } + tmp_ref = tmp_ctx->internal->source_device; + } + + dst_ref = av_hwdevice_ctx_alloc(type); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst_ctx = (AVHWDeviceContext*)dst_ref->data; + + tmp_ref = src_ref; + while (tmp_ref) { + tmp_ctx = (AVHWDeviceContext*)tmp_ref->data; + if (dst_ctx->internal->hw_type->device_derive) { + ret = dst_ctx->internal->hw_type->device_derive(dst_ctx, + tmp_ctx, + flags); + if (ret == 0) { + dst_ctx->internal->source_device = av_buffer_ref(src_ref); + if (!dst_ctx->internal->source_device) { + ret = AVERROR(ENOMEM); + goto fail; + } + ret = av_hwdevice_ctx_init(dst_ref); + if (ret < 0) + goto fail; + goto done; + } + if (ret != AVERROR(ENOSYS)) + goto fail; + } + tmp_ref = tmp_ctx->internal->source_device; + } + + ret = AVERROR(ENOSYS); + goto fail; + +done: + *dst_ref_ptr = dst_ref; + return 0; + +fail: + av_buffer_unref(&dst_ref); + *dst_ref_ptr = NULL; + return ret; +} + +static void ff_hwframe_unmap(void *opaque, uint8_t *data) +{ + HWMapDescriptor *hwmap = (HWMapDescriptor*)data; + AVHWFramesContext *ctx = opaque; + + if (hwmap->unmap) + hwmap->unmap(ctx, hwmap); + + av_frame_free(&hwmap->source); + + av_buffer_unref(&hwmap->hw_frames_ctx); + + av_free(hwmap); +} + +int ff_hwframe_map_create(AVBufferRef *hwframe_ref, + AVFrame *dst, const AVFrame *src, + void (*unmap)(AVHWFramesContext *ctx, + HWMapDescriptor *hwmap), + void *priv) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; + HWMapDescriptor *hwmap; + int ret; + + hwmap = av_mallocz(sizeof(*hwmap)); + if (!hwmap) { + ret = AVERROR(ENOMEM); + goto fail; + } + + hwmap->source = av_frame_alloc(); + if (!hwmap->source) { + ret = AVERROR(ENOMEM); + goto fail; + } + ret = av_frame_ref(hwmap->source, src); + if (ret < 0) + goto fail; + + hwmap->hw_frames_ctx = av_buffer_ref(hwframe_ref); + if (!hwmap->hw_frames_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + + hwmap->unmap = unmap; + hwmap->priv = priv; + + dst->buf[0] = av_buffer_create((uint8_t*)hwmap, sizeof(*hwmap), + &ff_hwframe_unmap, ctx, 0); + if (!dst->buf[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + return 0; + +fail: + if (hwmap) { + av_buffer_unref(&hwmap->hw_frames_ctx); + av_frame_free(&hwmap->source); + } + av_free(hwmap); + return ret; +} + +int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags) +{ + AVHWFramesContext *src_frames, *dst_frames; + HWMapDescriptor *hwmap; + int ret; + + if (src->hw_frames_ctx && dst->hw_frames_ctx) { + src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; + dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if ((src_frames == dst_frames && + src->format == dst_frames->sw_format && + dst->format == dst_frames->format) || + (src_frames->internal->source_frames && + src_frames->internal->source_frames->data == + (uint8_t*)dst_frames)) { + // This is an unmap operation. We don't need to directly + // do anything here other than fill in the original frame, + // because the real unmap will be invoked when the last + // reference to the mapped frame disappears. + if (!src->buf[0]) { + av_log(src_frames, AV_LOG_ERROR, "Invalid mapping " + "found when attempting unmap.\n"); + return AVERROR(EINVAL); + } + hwmap = (HWMapDescriptor*)src->buf[0]->data; + av_frame_unref(dst); + return av_frame_ref(dst, hwmap->source); + } + } + + if (src->hw_frames_ctx) { + src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; + + if (src_frames->format == src->format && + src_frames->internal->hw_type->map_from) { + ret = src_frames->internal->hw_type->map_from(src_frames, + dst, src, flags); + if (ret != AVERROR(ENOSYS)) + return ret; + } + } + + if (dst->hw_frames_ctx) { + dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if (dst_frames->format == dst->format && + dst_frames->internal->hw_type->map_to) { + ret = dst_frames->internal->hw_type->map_to(dst_frames, + dst, src, flags); + if (ret != AVERROR(ENOSYS)) + return ret; + } + } + + return AVERROR(ENOSYS); +} + +int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, + enum AVPixelFormat format, + AVBufferRef *derived_device_ctx, + AVBufferRef *source_frame_ctx, + int flags) +{ + AVBufferRef *dst_ref = NULL; + AVHWFramesContext *dst = NULL; + AVHWFramesContext *src = (AVHWFramesContext*)source_frame_ctx->data; + int ret; + + if (src->internal->source_frames) { + AVHWFramesContext *src_src = + (AVHWFramesContext*)src->internal->source_frames->data; + AVHWDeviceContext *dst_dev = + (AVHWDeviceContext*)derived_device_ctx->data; + + if (src_src->device_ctx == dst_dev) { + // This is actually an unmapping, so we just return a + // reference to the source frame context. + *derived_frame_ctx = + av_buffer_ref(src->internal->source_frames); + if (!*derived_frame_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + return 0; + } + } + + dst_ref = av_hwframe_ctx_alloc(derived_device_ctx); + if (!dst_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + + dst = (AVHWFramesContext*)dst_ref->data; + + dst->format = format; + dst->sw_format = src->sw_format; + dst->width = src->width; + dst->height = src->height; + + dst->internal->source_frames = av_buffer_ref(source_frame_ctx); + if (!dst->internal->source_frames) { + ret = AVERROR(ENOMEM); + goto fail; + } + + dst->internal->source_allocation_map_flags = + flags & (AV_HWFRAME_MAP_READ | + AV_HWFRAME_MAP_WRITE | + AV_HWFRAME_MAP_OVERWRITE | + AV_HWFRAME_MAP_DIRECT); + + ret = AVERROR(ENOSYS); + if (src->internal->hw_type->frames_derive_from) + ret = src->internal->hw_type->frames_derive_from(dst, src, flags); + if (ret == AVERROR(ENOSYS) && + dst->internal->hw_type->frames_derive_to) + ret = dst->internal->hw_type->frames_derive_to(dst, src, flags); + if (ret == AVERROR(ENOSYS)) + ret = 0; + if (ret) + goto fail; + + *derived_frame_ctx = dst_ref; + return 0; + +fail: + if (dst) + av_buffer_unref(&dst->internal->source_frames); + av_buffer_unref(&dst_ref); + return ret; +} + +int ff_hwframe_map_replace(AVFrame *dst, const AVFrame *src) +{ + HWMapDescriptor *hwmap = (HWMapDescriptor*)dst->buf[0]->data; + av_frame_unref(hwmap->source); + return av_frame_ref(hwmap->source, src); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext.h new file mode 100644 index 000000000..f5a4b6238 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext.h @@ -0,0 +1,584 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_H +#define AVUTIL_HWCONTEXT_H + +#include "buffer.h" +#include "frame.h" +#include "log.h" +#include "pixfmt.h" + +enum AVHWDeviceType { + AV_HWDEVICE_TYPE_NONE, + AV_HWDEVICE_TYPE_VDPAU, + AV_HWDEVICE_TYPE_CUDA, + AV_HWDEVICE_TYPE_VAAPI, + AV_HWDEVICE_TYPE_DXVA2, + AV_HWDEVICE_TYPE_QSV, + AV_HWDEVICE_TYPE_VIDEOTOOLBOX, + AV_HWDEVICE_TYPE_D3D11VA, + AV_HWDEVICE_TYPE_DRM, + AV_HWDEVICE_TYPE_OPENCL, + AV_HWDEVICE_TYPE_MEDIACODEC, +}; + +typedef struct AVHWDeviceInternal AVHWDeviceInternal; + +/** + * This struct aggregates all the (hardware/vendor-specific) "high-level" state, + * i.e. state that is not tied to a concrete processing configuration. + * E.g., in an API that supports hardware-accelerated encoding and decoding, + * this struct will (if possible) wrap the state that is common to both encoding + * and decoding and from which specific instances of encoders or decoders can be + * derived. + * + * This struct is reference-counted with the AVBuffer mechanism. The + * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field + * points to the actual AVHWDeviceContext. Further objects derived from + * AVHWDeviceContext (such as AVHWFramesContext, describing a frame pool with + * specific properties) will hold an internal reference to it. After all the + * references are released, the AVHWDeviceContext itself will be freed, + * optionally invoking a user-specified callback for uninitializing the hardware + * state. + */ +typedef struct AVHWDeviceContext { + /** + * A class for logging. Set by av_hwdevice_ctx_alloc(). + */ + const AVClass *av_class; + + /** + * Private data used internally by libavutil. Must not be accessed in any + * way by the caller. + */ + AVHWDeviceInternal *internal; + + /** + * This field identifies the underlying API used for hardware access. + * + * This field is set when this struct is allocated and never changed + * afterwards. + */ + enum AVHWDeviceType type; + + /** + * The format-specific data, allocated and freed by libavutil along with + * this context. + * + * Should be cast by the user to the format-specific context defined in the + * corresponding header (hwcontext_*.h) and filled as described in the + * documentation before calling av_hwdevice_ctx_init(). + * + * After calling av_hwdevice_ctx_init() this struct should not be modified + * by the caller. + */ + void *hwctx; + + /** + * This field may be set by the caller before calling av_hwdevice_ctx_init(). + * + * If non-NULL, this callback will be called when the last reference to + * this context is unreferenced, immediately before it is freed. + * + * @note when other objects (e.g an AVHWFramesContext) are derived from this + * struct, this callback will be invoked after all such child objects + * are fully uninitialized and their respective destructors invoked. + */ + void (*free)(struct AVHWDeviceContext *ctx); + + /** + * Arbitrary user data, to be used e.g. by the free() callback. + */ + void *user_opaque; +} AVHWDeviceContext; + +typedef struct AVHWFramesInternal AVHWFramesInternal; + +/** + * This struct describes a set or pool of "hardware" frames (i.e. those with + * data not located in normal system memory). All the frames in the pool are + * assumed to be allocated in the same way and interchangeable. + * + * This struct is reference-counted with the AVBuffer mechanism and tied to a + * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor + * yields a reference, whose data field points to the actual AVHWFramesContext + * struct. + */ +typedef struct AVHWFramesContext { + /** + * A class for logging. + */ + const AVClass *av_class; + + /** + * Private data used internally by libavutil. Must not be accessed in any + * way by the caller. + */ + AVHWFramesInternal *internal; + + /** + * A reference to the parent AVHWDeviceContext. This reference is owned and + * managed by the enclosing AVHWFramesContext, but the caller may derive + * additional references from it. + */ + AVBufferRef *device_ref; + + /** + * The parent AVHWDeviceContext. This is simply a pointer to + * device_ref->data provided for convenience. + * + * Set by libavutil in av_hwframe_ctx_init(). + */ + AVHWDeviceContext *device_ctx; + + /** + * The format-specific data, allocated and freed automatically along with + * this context. + * + * Should be cast by the user to the format-specific context defined in the + * corresponding header (hwframe_*.h) and filled as described in the + * documentation before calling av_hwframe_ctx_init(). + * + * After any frames using this context are created, the contents of this + * struct should not be modified by the caller. + */ + void *hwctx; + + /** + * This field may be set by the caller before calling av_hwframe_ctx_init(). + * + * If non-NULL, this callback will be called when the last reference to + * this context is unreferenced, immediately before it is freed. + */ + void (*free)(struct AVHWFramesContext *ctx); + + /** + * Arbitrary user data, to be used e.g. by the free() callback. + */ + void *user_opaque; + + /** + * A pool from which the frames are allocated by av_hwframe_get_buffer(). + * This field may be set by the caller before calling av_hwframe_ctx_init(). + * The buffers returned by calling av_buffer_pool_get() on this pool must + * have the properties described in the documentation in the corresponding hw + * type's header (hwcontext_*.h). The pool will be freed strictly before + * this struct's free() callback is invoked. + * + * This field may be NULL, then libavutil will attempt to allocate a pool + * internally. Note that certain device types enforce pools allocated at + * fixed size (frame count), which cannot be extended dynamically. In such a + * case, initial_pool_size must be set appropriately. + */ + AVBufferPool *pool; + + /** + * Initial size of the frame pool. If a device type does not support + * dynamically resizing the pool, then this is also the maximum pool size. + * + * May be set by the caller before calling av_hwframe_ctx_init(). Must be + * set if pool is NULL and the device type does not support dynamic pools. + */ + int initial_pool_size; + + /** + * The pixel format identifying the underlying HW surface type. + * + * Must be a hwaccel format, i.e. the corresponding descriptor must have the + * AV_PIX_FMT_FLAG_HWACCEL flag set. + * + * Must be set by the user before calling av_hwframe_ctx_init(). + */ + enum AVPixelFormat format; + + /** + * The pixel format identifying the actual data layout of the hardware + * frames. + * + * Must be set by the caller before calling av_hwframe_ctx_init(). + * + * @note when the underlying API does not provide the exact data layout, but + * only the colorspace/bit depth, this field should be set to the fully + * planar version of that format (e.g. for 8-bit 420 YUV it should be + * AV_PIX_FMT_YUV420P, not AV_PIX_FMT_NV12 or anything else). + */ + enum AVPixelFormat sw_format; + + /** + * The allocated dimensions of the frames in this pool. + * + * Must be set by the user before calling av_hwframe_ctx_init(). + */ + int width, height; +} AVHWFramesContext; + +/** + * Look up an AVHWDeviceType by name. + * + * @param name String name of the device type (case-insensitive). + * @return The type from enum AVHWDeviceType, or AV_HWDEVICE_TYPE_NONE if + * not found. + */ +enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name); + +/** Get the string name of an AVHWDeviceType. + * + * @param type Type from enum AVHWDeviceType. + * @return Pointer to a static string containing the name, or NULL if the type + * is not valid. + */ +const char *av_hwdevice_get_type_name(enum AVHWDeviceType type); + +/** + * Iterate over supported device types. + * + * @param type AV_HWDEVICE_TYPE_NONE initially, then the previous type + * returned by this function in subsequent iterations. + * @return The next usable device type from enum AVHWDeviceType, or + * AV_HWDEVICE_TYPE_NONE if there are no more. + */ +enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev); + +/** + * Allocate an AVHWDeviceContext for a given hardware type. + * + * @param type the type of the hardware device to allocate. + * @return a reference to the newly created AVHWDeviceContext on success or NULL + * on failure. + */ +AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type); + +/** + * Finalize the device context before use. This function must be called after + * the context is filled with all the required information and before it is + * used in any way. + * + * @param ref a reference to the AVHWDeviceContext + * @return 0 on success, a negative AVERROR code on failure + */ +int av_hwdevice_ctx_init(AVBufferRef *ref); + +/** + * Open a device of the specified type and create an AVHWDeviceContext for it. + * + * This is a convenience function intended to cover the simple cases. Callers + * who need to fine-tune device creation/management should open the device + * manually and then wrap it in an AVHWDeviceContext using + * av_hwdevice_ctx_alloc()/av_hwdevice_ctx_init(). + * + * The returned context is already initialized and ready for use, the caller + * should not call av_hwdevice_ctx_init() on it. The user_opaque/free fields of + * the created AVHWDeviceContext are set by this function and should not be + * touched by the caller. + * + * @param device_ctx On success, a reference to the newly-created device context + * will be written here. The reference is owned by the caller + * and must be released with av_buffer_unref() when no longer + * needed. On failure, NULL will be written to this pointer. + * @param type The type of the device to create. + * @param device A type-specific string identifying the device to open. + * @param opts A dictionary of additional (type-specific) options to use in + * opening the device. The dictionary remains owned by the caller. + * @param flags currently unused + * + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, + const char *device, AVDictionary *opts, int flags); + +/** + * Create a new device of the specified type from an existing device. + * + * If the source device is a device of the target type or was originally + * derived from such a device (possibly through one or more intermediate + * devices of other types), then this will return a reference to the + * existing device of the same type as is requested. + * + * Otherwise, it will attempt to derive a new device from the given source + * device. If direct derivation to the new type is not implemented, it will + * attempt the same derivation from each ancestor of the source device in + * turn looking for an implemented derivation method. + * + * @param dst_ctx On success, a reference to the newly-created + * AVHWDeviceContext. + * @param type The type of the new device to create. + * @param src_ctx A reference to an existing AVHWDeviceContext which will be + * used to create the new device. + * @param flags Currently unused; should be set to zero. + * @return Zero on success, a negative AVERROR code on failure. + */ +int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ctx, + enum AVHWDeviceType type, + AVBufferRef *src_ctx, int flags); + + +/** + * Allocate an AVHWFramesContext tied to a given device context. + * + * @param device_ctx a reference to a AVHWDeviceContext. This function will make + * a new reference for internal use, the one passed to the + * function remains owned by the caller. + * @return a reference to the newly created AVHWFramesContext on success or NULL + * on failure. + */ +AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ctx); + +/** + * Finalize the context before use. This function must be called after the + * context is filled with all the required information and before it is attached + * to any frames. + * + * @param ref a reference to the AVHWFramesContext + * @return 0 on success, a negative AVERROR code on failure + */ +int av_hwframe_ctx_init(AVBufferRef *ref); + +/** + * Allocate a new frame attached to the given AVHWFramesContext. + * + * @param hwframe_ctx a reference to an AVHWFramesContext + * @param frame an empty (freshly allocated or unreffed) frame to be filled with + * newly allocated buffers. + * @param flags currently unused, should be set to zero + * @return 0 on success, a negative AVERROR code on failure + */ +int av_hwframe_get_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame, int flags); + +/** + * Copy data to or from a hw surface. At least one of dst/src must have an + * AVHWFramesContext attached. + * + * If src has an AVHWFramesContext attached, then the format of dst (if set) + * must use one of the formats returned by av_hwframe_transfer_get_formats(src, + * AV_HWFRAME_TRANSFER_DIRECTION_FROM). + * If dst has an AVHWFramesContext attached, then the format of src must use one + * of the formats returned by av_hwframe_transfer_get_formats(dst, + * AV_HWFRAME_TRANSFER_DIRECTION_TO) + * + * dst may be "clean" (i.e. with data/buf pointers unset), in which case the + * data buffers will be allocated by this function using av_frame_get_buffer(). + * If dst->format is set, then this format will be used, otherwise (when + * dst->format is AV_PIX_FMT_NONE) the first acceptable format will be chosen. + * + * The two frames must have matching allocated dimensions (i.e. equal to + * AVHWFramesContext.width/height), since not all device types support + * transferring a sub-rectangle of the whole surface. The display dimensions + * (i.e. AVFrame.width/height) may be smaller than the allocated dimensions, but + * also have to be equal for both frames. When the display dimensions are + * smaller than the allocated dimensions, the content of the padding in the + * destination frame is unspecified. + * + * @param dst the destination frame. dst is not touched on failure. + * @param src the source frame. + * @param flags currently unused, should be set to zero + * @return 0 on success, a negative AVERROR error code on failure. + */ +int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags); + +enum AVHWFrameTransferDirection { + /** + * Transfer the data from the queried hw frame. + */ + AV_HWFRAME_TRANSFER_DIRECTION_FROM, + + /** + * Transfer the data to the queried hw frame. + */ + AV_HWFRAME_TRANSFER_DIRECTION_TO, +}; + +/** + * Get a list of possible source or target formats usable in + * av_hwframe_transfer_data(). + * + * @param hwframe_ctx the frame context to obtain the information for + * @param dir the direction of the transfer + * @param formats the pointer to the output format list will be written here. + * The list is terminated with AV_PIX_FMT_NONE and must be freed + * by the caller when no longer needed using av_free(). + * If this function returns successfully, the format list will + * have at least one item (not counting the terminator). + * On failure, the contents of this pointer are unspecified. + * @param flags currently unused, should be set to zero + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats, int flags); + + +/** + * This struct describes the constraints on hardware frames attached to + * a given device with a hardware-specific configuration. This is returned + * by av_hwdevice_get_hwframe_constraints() and must be freed by + * av_hwframe_constraints_free() after use. + */ +typedef struct AVHWFramesConstraints { + /** + * A list of possible values for format in the hw_frames_ctx, + * terminated by AV_PIX_FMT_NONE. This member will always be filled. + */ + enum AVPixelFormat *valid_hw_formats; + + /** + * A list of possible values for sw_format in the hw_frames_ctx, + * terminated by AV_PIX_FMT_NONE. Can be NULL if this information is + * not known. + */ + enum AVPixelFormat *valid_sw_formats; + + /** + * The minimum size of frames in this hw_frames_ctx. + * (Zero if not known.) + */ + int min_width; + int min_height; + + /** + * The maximum size of frames in this hw_frames_ctx. + * (INT_MAX if not known / no limit.) + */ + int max_width; + int max_height; +} AVHWFramesConstraints; + +/** + * Allocate a HW-specific configuration structure for a given HW device. + * After use, the user must free all members as required by the specific + * hardware structure being used, then free the structure itself with + * av_free(). + * + * @param device_ctx a reference to the associated AVHWDeviceContext. + * @return The newly created HW-specific configuration structure on + * success or NULL on failure. + */ +void *av_hwdevice_hwconfig_alloc(AVBufferRef *device_ctx); + +/** + * Get the constraints on HW frames given a device and the HW-specific + * configuration to be used with that device. If no HW-specific + * configuration is provided, returns the maximum possible capabilities + * of the device. + * + * @param ref a reference to the associated AVHWDeviceContext. + * @param hwconfig a filled HW-specific configuration structure, or NULL + * to return the maximum possible capabilities of the device. + * @return AVHWFramesConstraints structure describing the constraints + * on the device, or NULL if not available. + */ +AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, + const void *hwconfig); + +/** + * Free an AVHWFrameConstraints structure. + * + * @param constraints The (filled or unfilled) AVHWFrameConstraints structure. + */ +void av_hwframe_constraints_free(AVHWFramesConstraints **constraints); + + +/** + * Flags to apply to frame mappings. + */ +enum { + /** + * The mapping must be readable. + */ + AV_HWFRAME_MAP_READ = 1 << 0, + /** + * The mapping must be writeable. + */ + AV_HWFRAME_MAP_WRITE = 1 << 1, + /** + * The mapped frame will be overwritten completely in subsequent + * operations, so the current frame data need not be loaded. Any values + * which are not overwritten are unspecified. + */ + AV_HWFRAME_MAP_OVERWRITE = 1 << 2, + /** + * The mapping must be direct. That is, there must not be any copying in + * the map or unmap steps. Note that performance of direct mappings may + * be much lower than normal memory. + */ + AV_HWFRAME_MAP_DIRECT = 1 << 3, +}; + +/** + * Map a hardware frame. + * + * This has a number of different possible effects, depending on the format + * and origin of the src and dst frames. On input, src should be a usable + * frame with valid buffers and dst should be blank (typically as just created + * by av_frame_alloc()). src should have an associated hwframe context, and + * dst may optionally have a format and associated hwframe context. + * + * If src was created by mapping a frame from the hwframe context of dst, + * then this function undoes the mapping - dst is replaced by a reference to + * the frame that src was originally mapped from. + * + * If both src and dst have an associated hwframe context, then this function + * attempts to map the src frame from its hardware context to that of dst and + * then fill dst with appropriate data to be usable there. This will only be + * possible if the hwframe contexts and associated devices are compatible - + * given compatible devices, av_hwframe_ctx_create_derived() can be used to + * create a hwframe context for dst in which mapping should be possible. + * + * If src has a hwframe context but dst does not, then the src frame is + * mapped to normal memory and should thereafter be usable as a normal frame. + * If the format is set on dst, then the mapping will attempt to create dst + * with that format and fail if it is not possible. If format is unset (is + * AV_PIX_FMT_NONE) then dst will be mapped with whatever the most appropriate + * format to use is (probably the sw_format of the src hwframe context). + * + * A return value of AVERROR(ENOSYS) indicates that the mapping is not + * possible with the given arguments and hwframe setup, while other return + * values indicate that it failed somehow. + * + * @param dst Destination frame, to contain the mapping. + * @param src Source frame, to be mapped. + * @param flags Some combination of AV_HWFRAME_MAP_* flags. + * @return Zero on success, negative AVERROR code on failure. + */ +int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags); + + +/** + * Create and initialise an AVHWFramesContext as a mapping of another existing + * AVHWFramesContext on a different device. + * + * av_hwframe_ctx_init() should not be called after this. + * + * @param derived_frame_ctx On success, a reference to the newly created + * AVHWFramesContext. + * @param derived_device_ctx A reference to the device to create the new + * AVHWFramesContext on. + * @param source_frame_ctx A reference to an existing AVHWFramesContext + * which will be mapped to the derived context. + * @param flags Some combination of AV_HWFRAME_MAP_* flags, defining the + * mapping parameters to apply to frames which are allocated + * in the derived device. + * @return Zero on success, negative AVERROR code on failure. + */ +int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, + enum AVPixelFormat format, + AVBufferRef *derived_device_ctx, + AVBufferRef *source_frame_ctx, + int flags); + +#endif /* AVUTIL_HWCONTEXT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda.c new file mode 100644 index 000000000..cca39e9fc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda.c @@ -0,0 +1,381 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_cuda_internal.h" +#include "cuda_check.h" +#include "mem.h" +#include "pixdesc.h" +#include "pixfmt.h" +#include "imgutils.h" + +#define CUDA_FRAME_ALIGNMENT 256 + +typedef struct CUDAFramesContext { + int shift_width, shift_height; +} CUDAFramesContext; + +static const enum AVPixelFormat supported_formats[] = { + AV_PIX_FMT_NV12, + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV444P, + AV_PIX_FMT_P010, + AV_PIX_FMT_P016, + AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_0RGB32, + AV_PIX_FMT_0BGR32, +}; + +#define CHECK_CU(x) FF_CUDA_CHECK_DL(device_ctx, cu, x) + +static int cuda_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) + constraints->valid_sw_formats[i] = supported_formats[i]; + constraints->valid_sw_formats[FF_ARRAY_ELEMS(supported_formats)] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_CUDA; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +static void cuda_buffer_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *ctx = opaque; + AVHWDeviceContext *device_ctx = ctx->device_ctx; + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu = hwctx->internal->cuda_dl; + + CUcontext dummy; + + CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx)); + + CHECK_CU(cu->cuMemFree((CUdeviceptr)data)); + + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); +} + +static AVBufferRef *cuda_pool_alloc(void *opaque, int size) +{ + AVHWFramesContext *ctx = opaque; + AVHWDeviceContext *device_ctx = ctx->device_ctx; + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu = hwctx->internal->cuda_dl; + + AVBufferRef *ret = NULL; + CUcontext dummy = NULL; + CUdeviceptr data; + int err; + + err = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx)); + if (err < 0) + return NULL; + + err = CHECK_CU(cu->cuMemAlloc(&data, size)); + if (err < 0) + goto fail; + + ret = av_buffer_create((uint8_t*)data, size, cuda_buffer_free, ctx, 0); + if (!ret) { + CHECK_CU(cu->cuMemFree(data)); + goto fail; + } + +fail: + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + return ret; +} + +static int cuda_frames_init(AVHWFramesContext *ctx) +{ + CUDAFramesContext *priv = ctx->internal->priv; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { + if (ctx->sw_format == supported_formats[i]) + break; + } + if (i == FF_ARRAY_ELEMS(supported_formats)) { + av_log(ctx, AV_LOG_ERROR, "Pixel format '%s' is not supported\n", + av_get_pix_fmt_name(ctx->sw_format)); + return AVERROR(ENOSYS); + } + + av_pix_fmt_get_chroma_sub_sample(ctx->sw_format, &priv->shift_width, &priv->shift_height); + + if (!ctx->pool) { + int size = av_image_get_buffer_size(ctx->sw_format, ctx->width, ctx->height, CUDA_FRAME_ALIGNMENT); + if (size < 0) + return size; + + ctx->internal->pool_internal = av_buffer_pool_init2(size, ctx, cuda_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + } + + return 0; +} + +static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + int res; + + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + res = av_image_fill_arrays(frame->data, frame->linesize, frame->buf[0]->data, + ctx->sw_format, ctx->width, ctx->height, CUDA_FRAME_ALIGNMENT); + if (res < 0) + return res; + + // YUV420P is a special case. + // Nvenc expects the U/V planes in swapped order from how ffmpeg expects them, also chroma is half-aligned + if (ctx->sw_format == AV_PIX_FMT_YUV420P) { + frame->linesize[1] = frame->linesize[2] = frame->linesize[0] / 2; + frame->data[2] = frame->data[1]; + frame->data[1] = frame->data[2] + frame->linesize[2] * ctx->height / 2; + } + + frame->format = AV_PIX_FMT_CUDA; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int cuda_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + + return 0; +} + +static int cuda_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + CUDAFramesContext *priv = ctx->internal->priv; + AVHWDeviceContext *device_ctx = ctx->device_ctx; + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu = hwctx->internal->cuda_dl; + + CUcontext dummy; + int i, ret; + + ret = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx)); + if (ret < 0) + return ret; + + for (i = 0; i < FF_ARRAY_ELEMS(src->data) && src->data[i]; i++) { + CUDA_MEMCPY2D cpy = { + .srcMemoryType = CU_MEMORYTYPE_DEVICE, + .dstMemoryType = CU_MEMORYTYPE_HOST, + .srcDevice = (CUdeviceptr)src->data[i], + .dstHost = dst->data[i], + .srcPitch = src->linesize[i], + .dstPitch = dst->linesize[i], + .WidthInBytes = FFMIN(src->linesize[i], dst->linesize[i]), + .Height = src->height >> (i ? priv->shift_height : 0), + }; + + ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, hwctx->stream)); + if (ret < 0) + goto exit; + } + + ret = CHECK_CU(cu->cuStreamSynchronize(hwctx->stream)); + if (ret < 0) + goto exit; + +exit: + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + + return 0; +} + +static int cuda_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + CUDAFramesContext *priv = ctx->internal->priv; + AVHWDeviceContext *device_ctx = ctx->device_ctx; + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu = hwctx->internal->cuda_dl; + + CUcontext dummy; + int i, ret; + + ret = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx)); + if (ret < 0) + return ret; + + for (i = 0; i < FF_ARRAY_ELEMS(src->data) && src->data[i]; i++) { + CUDA_MEMCPY2D cpy = { + .srcMemoryType = CU_MEMORYTYPE_HOST, + .dstMemoryType = CU_MEMORYTYPE_DEVICE, + .srcHost = src->data[i], + .dstDevice = (CUdeviceptr)dst->data[i], + .srcPitch = src->linesize[i], + .dstPitch = dst->linesize[i], + .WidthInBytes = FFMIN(src->linesize[i], dst->linesize[i]), + .Height = src->height >> (i ? priv->shift_height : 0), + }; + + ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, hwctx->stream)); + if (ret < 0) + goto exit; + } + +exit: + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + + return 0; +} + +static void cuda_device_uninit(AVHWDeviceContext *device_ctx) +{ + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + + if (hwctx->internal) { + CudaFunctions *cu = hwctx->internal->cuda_dl; + if (hwctx->internal->is_allocated && hwctx->cuda_ctx) { + CHECK_CU(cu->cuCtxDestroy(hwctx->cuda_ctx)); + hwctx->cuda_ctx = NULL; + } + cuda_free_functions(&hwctx->internal->cuda_dl); + } + + av_freep(&hwctx->internal); +} + +static int cuda_device_init(AVHWDeviceContext *ctx) +{ + AVCUDADeviceContext *hwctx = ctx->hwctx; + int ret; + + if (!hwctx->internal) { + hwctx->internal = av_mallocz(sizeof(*hwctx->internal)); + if (!hwctx->internal) + return AVERROR(ENOMEM); + } + + if (!hwctx->internal->cuda_dl) { + ret = cuda_load_functions(&hwctx->internal->cuda_dl, ctx); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Could not dynamically load CUDA\n"); + goto error; + } + } + + return 0; + +error: + cuda_device_uninit(ctx); + return ret; +} + +static int cuda_device_create(AVHWDeviceContext *device_ctx, + const char *device, + AVDictionary *opts, int flags) +{ + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu; + CUdevice cu_device; + CUcontext dummy; + int ret, device_idx = 0; + + if (device) + device_idx = strtol(device, NULL, 0); + + if (cuda_device_init(device_ctx) < 0) + goto error; + + cu = hwctx->internal->cuda_dl; + + ret = CHECK_CU(cu->cuInit(0)); + if (ret < 0) + goto error; + + ret = CHECK_CU(cu->cuDeviceGet(&cu_device, device_idx)); + if (ret < 0) + goto error; + + ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, CU_CTX_SCHED_BLOCKING_SYNC, cu_device)); + if (ret < 0) + goto error; + + // Setting stream to NULL will make functions automatically use the default CUstream + hwctx->stream = NULL; + + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + + hwctx->internal->is_allocated = 1; + + return 0; + +error: + cuda_device_uninit(device_ctx); + return AVERROR_UNKNOWN; +} + +const HWContextType ff_hwcontext_type_cuda = { + .type = AV_HWDEVICE_TYPE_CUDA, + .name = "CUDA", + + .device_hwctx_size = sizeof(AVCUDADeviceContext), + .frames_priv_size = sizeof(CUDAFramesContext), + + .device_create = cuda_device_create, + .device_init = cuda_device_init, + .device_uninit = cuda_device_uninit, + .frames_get_constraints = cuda_frames_get_constraints, + .frames_init = cuda_frames_init, + .frames_get_buffer = cuda_get_buffer, + .transfer_get_formats = cuda_transfer_get_formats, + .transfer_data_to = cuda_transfer_data_to, + .transfer_data_from = cuda_transfer_data_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda.h new file mode 100644 index 000000000..81a0552ca --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda.h @@ -0,0 +1,52 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVUTIL_HWCONTEXT_CUDA_H +#define AVUTIL_HWCONTEXT_CUDA_H + +#ifndef CUDA_VERSION +#include +#endif + +#include "pixfmt.h" + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_CUDA. + * + * This API supports dynamic frame pools. AVHWFramesContext.pool must return + * AVBufferRefs whose data pointer is a CUdeviceptr. + */ + +typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal; + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVCUDADeviceContext { + CUcontext cuda_ctx; + CUstream stream; + AVCUDADeviceContextInternal *internal; +} AVCUDADeviceContext; + +/** + * AVHWFramesContext.hwctx is currently not used + */ + +#endif /* AVUTIL_HWCONTEXT_CUDA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda_internal.h new file mode 100644 index 000000000..e1bc6ff35 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_cuda_internal.h @@ -0,0 +1,37 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVUTIL_HWCONTEXT_CUDA_INTERNAL_H +#define AVUTIL_HWCONTEXT_CUDA_INTERNAL_H + +#include "compat/cuda/dynlink_loader.h" +#include "hwcontext_cuda.h" + +/** + * @file + * FFmpeg internal API for CUDA. + */ + +struct AVCUDADeviceContextInternal { + CudaFunctions *cuda_dl; + int is_allocated; +}; + +#endif /* AVUTIL_HWCONTEXT_CUDA_INTERNAL_H */ + diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_d3d11va.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_d3d11va.c new file mode 100644 index 000000000..6670c4757 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_d3d11va.c @@ -0,0 +1,615 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#define COBJMACROS + +#include +#include +#include + +#if HAVE_DXGIDEBUG_H +#include +#endif + +#include "avassert.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_d3d11va.h" +#include "hwcontext_internal.h" +#include "imgutils.h" +#include "pixdesc.h" +#include "pixfmt.h" +#include "thread.h" + +typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory); + +static AVOnce functions_loaded = AV_ONCE_INIT; + +static PFN_CREATE_DXGI_FACTORY mCreateDXGIFactory; +static PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice; + +static av_cold void load_functions(void) +{ +#if !HAVE_UWP + // We let these "leak" - this is fine, as unloading has no great benefit, and + // Windows will mark a DLL as loaded forever if its internal refcount overflows + // from too many LoadLibrary calls. + HANDLE d3dlib, dxgilib; + + d3dlib = LoadLibrary("d3d11.dll"); + dxgilib = LoadLibrary("dxgi.dll"); + if (!d3dlib || !dxgilib) + return; + + mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) GetProcAddress(d3dlib, "D3D11CreateDevice"); + mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) GetProcAddress(dxgilib, "CreateDXGIFactory"); +#else + // In UWP (which lacks LoadLibrary), CreateDXGIFactory isn't available, + // only CreateDXGIFactory1 + mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) D3D11CreateDevice; + mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) CreateDXGIFactory1; +#endif +} + +typedef struct D3D11VAFramesContext { + int nb_surfaces_used; + + DXGI_FORMAT format; + + ID3D11Texture2D *staging_texture; +} D3D11VAFramesContext; + +static const struct { + DXGI_FORMAT d3d_format; + enum AVPixelFormat pix_fmt; +} supported_formats[] = { + { DXGI_FORMAT_NV12, AV_PIX_FMT_NV12 }, + { DXGI_FORMAT_P010, AV_PIX_FMT_P010 }, + // Special opaque formats. The pix_fmt is merely a place holder, as the + // opaque format cannot be accessed directly. + { DXGI_FORMAT_420_OPAQUE, AV_PIX_FMT_YUV420P }, +}; + +static void d3d11va_default_lock(void *ctx) +{ + WaitForSingleObjectEx(ctx, INFINITE, FALSE); +} + +static void d3d11va_default_unlock(void *ctx) +{ + ReleaseMutex(ctx); +} + +static void d3d11va_frames_uninit(AVHWFramesContext *ctx) +{ + AVD3D11VAFramesContext *frames_hwctx = ctx->hwctx; + D3D11VAFramesContext *s = ctx->internal->priv; + + if (frames_hwctx->texture) + ID3D11Texture2D_Release(frames_hwctx->texture); + frames_hwctx->texture = NULL; + + if (s->staging_texture) + ID3D11Texture2D_Release(s->staging_texture); + s->staging_texture = NULL; +} + +static int d3d11va_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + AVD3D11VADeviceContext *device_hwctx = ctx->hwctx; + int nb_sw_formats = 0; + HRESULT hr; + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { + UINT format_support = 0; + hr = ID3D11Device_CheckFormatSupport(device_hwctx->device, supported_formats[i].d3d_format, &format_support); + if (SUCCEEDED(hr) && (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D)) + constraints->valid_sw_formats[nb_sw_formats++] = supported_formats[i].pix_fmt; + } + constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_D3D11; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +static void free_texture(void *opaque, uint8_t *data) +{ + ID3D11Texture2D_Release((ID3D11Texture2D *)opaque); + av_free(data); +} + +static AVBufferRef *wrap_texture_buf(ID3D11Texture2D *tex, int index) +{ + AVBufferRef *buf; + AVD3D11FrameDescriptor *desc = av_mallocz(sizeof(*desc)); + if (!desc) { + ID3D11Texture2D_Release(tex); + return NULL; + } + + desc->texture = tex; + desc->index = index; + + buf = av_buffer_create((uint8_t *)desc, sizeof(desc), free_texture, tex, 0); + if (!buf) { + ID3D11Texture2D_Release(tex); + av_free(desc); + return NULL; + } + + return buf; +} + +static AVBufferRef *d3d11va_alloc_single(AVHWFramesContext *ctx) +{ + D3D11VAFramesContext *s = ctx->internal->priv; + AVD3D11VAFramesContext *hwctx = ctx->hwctx; + AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; + HRESULT hr; + ID3D11Texture2D *tex; + D3D11_TEXTURE2D_DESC texDesc = { + .Width = ctx->width, + .Height = ctx->height, + .MipLevels = 1, + .Format = s->format, + .SampleDesc = { .Count = 1 }, + .ArraySize = 1, + .Usage = D3D11_USAGE_DEFAULT, + .BindFlags = hwctx->BindFlags, + .MiscFlags = hwctx->MiscFlags, + }; + + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &tex); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr); + return NULL; + } + + return wrap_texture_buf(tex, 0); +} + +static AVBufferRef *d3d11va_pool_alloc(void *opaque, int size) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; + D3D11VAFramesContext *s = ctx->internal->priv; + AVD3D11VAFramesContext *hwctx = ctx->hwctx; + D3D11_TEXTURE2D_DESC texDesc; + + if (!hwctx->texture) + return d3d11va_alloc_single(ctx); + + ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc); + + if (s->nb_surfaces_used >= texDesc.ArraySize) { + av_log(ctx, AV_LOG_ERROR, "Static surface pool size exceeded.\n"); + return NULL; + } + + ID3D11Texture2D_AddRef(hwctx->texture); + return wrap_texture_buf(hwctx->texture, s->nb_surfaces_used++); +} + +static int d3d11va_frames_init(AVHWFramesContext *ctx) +{ + AVD3D11VAFramesContext *hwctx = ctx->hwctx; + AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; + D3D11VAFramesContext *s = ctx->internal->priv; + + int i; + HRESULT hr; + D3D11_TEXTURE2D_DESC texDesc; + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { + if (ctx->sw_format == supported_formats[i].pix_fmt) { + s->format = supported_formats[i].d3d_format; + break; + } + } + if (i == FF_ARRAY_ELEMS(supported_formats)) { + av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format: %s\n", + av_get_pix_fmt_name(ctx->sw_format)); + return AVERROR(EINVAL); + } + + texDesc = (D3D11_TEXTURE2D_DESC){ + .Width = ctx->width, + .Height = ctx->height, + .MipLevels = 1, + .Format = s->format, + .SampleDesc = { .Count = 1 }, + .ArraySize = ctx->initial_pool_size, + .Usage = D3D11_USAGE_DEFAULT, + .BindFlags = hwctx->BindFlags, + .MiscFlags = hwctx->MiscFlags, + }; + + if (hwctx->texture) { + D3D11_TEXTURE2D_DESC texDesc2; + ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc2); + + if (texDesc.Width != texDesc2.Width || + texDesc.Height != texDesc2.Height || + texDesc.Format != texDesc2.Format) { + av_log(ctx, AV_LOG_ERROR, "User-provided texture has mismatching parameters\n"); + return AVERROR(EINVAL); + } + } else if (texDesc.ArraySize > 0) { + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &hwctx->texture); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr); + return AVERROR_UNKNOWN; + } + } + + ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(AVD3D11FrameDescriptor), + ctx, d3d11va_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + + return 0; +} + +static int d3d11va_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + AVD3D11FrameDescriptor *desc; + + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + desc = (AVD3D11FrameDescriptor *)frame->buf[0]->data; + + frame->data[0] = (uint8_t *)desc->texture; + frame->data[1] = (uint8_t *)desc->index; + frame->format = AV_PIX_FMT_D3D11; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int d3d11va_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + D3D11VAFramesContext *s = ctx->internal->priv; + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + // Don't signal support for opaque formats. Actual access would fail. + if (s->format == DXGI_FORMAT_420_OPAQUE) + fmts[0] = AV_PIX_FMT_NONE; + + *formats = fmts; + + return 0; +} + +static int d3d11va_create_staging_texture(AVHWFramesContext *ctx) +{ + AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; + D3D11VAFramesContext *s = ctx->internal->priv; + HRESULT hr; + D3D11_TEXTURE2D_DESC texDesc = { + .Width = ctx->width, + .Height = ctx->height, + .MipLevels = 1, + .Format = s->format, + .SampleDesc = { .Count = 1 }, + .ArraySize = 1, + .Usage = D3D11_USAGE_STAGING, + .CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE, + }; + + hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &s->staging_texture); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the staging texture (%lx)\n", (long)hr); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static void fill_texture_ptrs(uint8_t *data[4], int linesize[4], + AVHWFramesContext *ctx, + D3D11_TEXTURE2D_DESC *desc, + D3D11_MAPPED_SUBRESOURCE *map) +{ + int i; + + for (i = 0; i < 4; i++) + linesize[i] = map->RowPitch; + + av_image_fill_pointers(data, ctx->sw_format, desc->Height, + (uint8_t*)map->pData, linesize); +} + +static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; + D3D11VAFramesContext *s = ctx->internal->priv; + int download = src->format == AV_PIX_FMT_D3D11; + const AVFrame *frame = download ? src : dst; + const AVFrame *other = download ? dst : src; + // (The interface types are compatible.) + ID3D11Resource *texture = (ID3D11Resource *)(ID3D11Texture2D *)frame->data[0]; + int index = (intptr_t)frame->data[1]; + ID3D11Resource *staging; + int w = FFMIN(dst->width, src->width); + int h = FFMIN(dst->height, src->height); + uint8_t *map_data[4]; + int map_linesize[4]; + D3D11_TEXTURE2D_DESC desc; + D3D11_MAPPED_SUBRESOURCE map; + HRESULT hr; + + if (frame->hw_frames_ctx->data != (uint8_t *)ctx || other->format != ctx->sw_format) + return AVERROR(EINVAL); + + device_hwctx->lock(device_hwctx->lock_ctx); + + if (!s->staging_texture) { + int res = d3d11va_create_staging_texture(ctx); + if (res < 0) + return res; + } + + staging = (ID3D11Resource *)s->staging_texture; + + ID3D11Texture2D_GetDesc(s->staging_texture, &desc); + + if (download) { + ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context, + staging, 0, 0, 0, 0, + texture, index, NULL); + + hr = ID3D11DeviceContext_Map(device_hwctx->device_context, + staging, 0, D3D11_MAP_READ, 0, &map); + if (FAILED(hr)) + goto map_failed; + + fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); + + av_image_copy(dst->data, dst->linesize, (const uint8_t **)map_data, map_linesize, + ctx->sw_format, w, h); + + ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0); + } else { + hr = ID3D11DeviceContext_Map(device_hwctx->device_context, + staging, 0, D3D11_MAP_WRITE, 0, &map); + if (FAILED(hr)) + goto map_failed; + + fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); + + av_image_copy(map_data, map_linesize, (const uint8_t **)src->data, src->linesize, + ctx->sw_format, w, h); + + ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0); + + ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context, + texture, index, 0, 0, 0, + staging, 0, NULL); + } + + device_hwctx->unlock(device_hwctx->lock_ctx); + return 0; + +map_failed: + av_log(ctx, AV_LOG_ERROR, "Unable to lock D3D11VA surface (%lx)\n", (long)hr); + device_hwctx->unlock(device_hwctx->lock_ctx); + return AVERROR_UNKNOWN; +} + +static int d3d11va_device_init(AVHWDeviceContext *hwdev) +{ + AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx; + HRESULT hr; + + if (!device_hwctx->lock) { + device_hwctx->lock_ctx = CreateMutex(NULL, 0, NULL); + if (device_hwctx->lock_ctx == INVALID_HANDLE_VALUE) { + av_log(NULL, AV_LOG_ERROR, "Failed to create a mutex\n"); + return AVERROR(EINVAL); + } + device_hwctx->lock = d3d11va_default_lock; + device_hwctx->unlock = d3d11va_default_unlock; + } + + if (!device_hwctx->device_context) { + ID3D11Device_GetImmediateContext(device_hwctx->device, &device_hwctx->device_context); + if (!device_hwctx->device_context) + return AVERROR_UNKNOWN; + } + + if (!device_hwctx->video_device) { + hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device, &IID_ID3D11VideoDevice, + (void **)&device_hwctx->video_device); + if (FAILED(hr)) + return AVERROR_UNKNOWN; + } + + if (!device_hwctx->video_context) { + hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device_context, &IID_ID3D11VideoContext, + (void **)&device_hwctx->video_context); + if (FAILED(hr)) + return AVERROR_UNKNOWN; + } + + return 0; +} + +static void d3d11va_device_uninit(AVHWDeviceContext *hwdev) +{ + AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx; + + if (device_hwctx->device) { + ID3D11Device_Release(device_hwctx->device); + device_hwctx->device = NULL; + } + + if (device_hwctx->device_context) { + ID3D11DeviceContext_Release(device_hwctx->device_context); + device_hwctx->device_context = NULL; + } + + if (device_hwctx->video_device) { + ID3D11VideoDevice_Release(device_hwctx->video_device); + device_hwctx->video_device = NULL; + } + + if (device_hwctx->video_context) { + ID3D11VideoContext_Release(device_hwctx->video_context); + device_hwctx->video_context = NULL; + } + + if (device_hwctx->lock == d3d11va_default_lock) { + CloseHandle(device_hwctx->lock_ctx); + device_hwctx->lock_ctx = INVALID_HANDLE_VALUE; + device_hwctx->lock = NULL; + } +} + +static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVD3D11VADeviceContext *device_hwctx = ctx->hwctx; + + HRESULT hr; + IDXGIAdapter *pAdapter = NULL; + ID3D10Multithread *pMultithread; + UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; + int is_debug = !!av_dict_get(opts, "debug", NULL, 0); + int ret; + + // (On UWP we can't check this.) +#if !HAVE_UWP + if (!LoadLibrary("d3d11_1sdklayers.dll")) + is_debug = 0; +#endif + + if (is_debug) + creationFlags |= D3D11_CREATE_DEVICE_DEBUG; + + if ((ret = ff_thread_once(&functions_loaded, load_functions)) != 0) + return AVERROR_UNKNOWN; + if (!mD3D11CreateDevice || !mCreateDXGIFactory) { + av_log(ctx, AV_LOG_ERROR, "Failed to load D3D11 library or its functions\n"); + return AVERROR_UNKNOWN; + } + + if (device) { + IDXGIFactory2 *pDXGIFactory; + hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory); + if (SUCCEEDED(hr)) { + int adapter = atoi(device); + if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter))) + pAdapter = NULL; + IDXGIFactory2_Release(pDXGIFactory); + } + } + + if (pAdapter) { + DXGI_ADAPTER_DESC desc; + hr = IDXGIAdapter2_GetDesc(pAdapter, &desc); + if (!FAILED(hr)) { + av_log(ctx, AV_LOG_INFO, "Using device %04x:%04x (%ls).\n", + desc.VendorId, desc.DeviceId, desc.Description); + } + } + + hr = mD3D11CreateDevice(pAdapter, pAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, NULL, creationFlags, NULL, 0, + D3D11_SDK_VERSION, &device_hwctx->device, NULL, NULL); + if (pAdapter) + IDXGIAdapter_Release(pAdapter); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device (%lx)\n", (long)hr); + return AVERROR_UNKNOWN; + } + + hr = ID3D11Device_QueryInterface(device_hwctx->device, &IID_ID3D10Multithread, (void **)&pMultithread); + if (SUCCEEDED(hr)) { + ID3D10Multithread_SetMultithreadProtected(pMultithread, TRUE); + ID3D10Multithread_Release(pMultithread); + } + +#if !HAVE_UWP && HAVE_DXGIDEBUG_H + if (is_debug) { + HANDLE dxgidebug_dll = LoadLibrary("dxgidebug.dll"); + if (dxgidebug_dll) { + HRESULT (WINAPI * pf_DXGIGetDebugInterface)(const GUID *riid, void **ppDebug) + = (void *)GetProcAddress(dxgidebug_dll, "DXGIGetDebugInterface"); + if (pf_DXGIGetDebugInterface) { + IDXGIDebug *dxgi_debug = NULL; + hr = pf_DXGIGetDebugInterface(&IID_IDXGIDebug, (void**)&dxgi_debug); + if (SUCCEEDED(hr) && dxgi_debug) + IDXGIDebug_ReportLiveObjects(dxgi_debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL); + } + } + } +#endif + + return 0; +} + +const HWContextType ff_hwcontext_type_d3d11va = { + .type = AV_HWDEVICE_TYPE_D3D11VA, + .name = "D3D11VA", + + .device_hwctx_size = sizeof(AVD3D11VADeviceContext), + .frames_hwctx_size = sizeof(AVD3D11VAFramesContext), + .frames_priv_size = sizeof(D3D11VAFramesContext), + + .device_create = d3d11va_device_create, + .device_init = d3d11va_device_init, + .device_uninit = d3d11va_device_uninit, + .frames_get_constraints = d3d11va_frames_get_constraints, + .frames_init = d3d11va_frames_init, + .frames_uninit = d3d11va_frames_uninit, + .frames_get_buffer = d3d11va_get_buffer, + .transfer_get_formats = d3d11va_transfer_get_formats, + .transfer_data_to = d3d11va_transfer_data, + .transfer_data_from = d3d11va_transfer_data, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_D3D11, AV_PIX_FMT_NONE }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_d3d11va.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_d3d11va.h new file mode 100644 index 000000000..9f91e9b1b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_d3d11va.h @@ -0,0 +1,169 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_D3D11VA_H +#define AVUTIL_HWCONTEXT_D3D11VA_H + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_D3D11VA. + * + * The default pool implementation will be fixed-size if initial_pool_size is + * set (and allocate elements from an array texture). Otherwise it will allocate + * individual textures. Be aware that decoding requires a single array texture. + * + * Using sw_format==AV_PIX_FMT_YUV420P has special semantics, and maps to + * DXGI_FORMAT_420_OPAQUE. av_hwframe_transfer_data() is not supported for + * this format. Refer to MSDN for details. + * + * av_hwdevice_ctx_create() for this device type supports a key named "debug" + * for the AVDictionary entry. If this is set to any value, the device creation + * code will try to load various supported D3D debugging layers. + */ + +#include +#include + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVD3D11VADeviceContext { + /** + * Device used for texture creation and access. This can also be used to + * set the libavcodec decoding device. + * + * Must be set by the user. This is the only mandatory field - the other + * device context fields are set from this and are available for convenience. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11Device *device; + + /** + * If unset, this will be set from the device field on init. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11DeviceContext *device_context; + + /** + * If unset, this will be set from the device field on init. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11VideoDevice *video_device; + + /** + * If unset, this will be set from the device_context field on init. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11VideoContext *video_context; + + /** + * Callbacks for locking. They protect accesses to device_context and + * video_context calls. They also protect access to the internal staging + * texture (for av_hwframe_transfer_data() calls). They do NOT protect + * access to hwcontext or decoder state in general. + * + * If unset on init, the hwcontext implementation will set them to use an + * internal mutex. + * + * The underlying lock must be recursive. lock_ctx is for free use by the + * locking implementation. + */ + void (*lock)(void *lock_ctx); + void (*unlock)(void *lock_ctx); + void *lock_ctx; +} AVD3D11VADeviceContext; + +/** + * D3D11 frame descriptor for pool allocation. + * + * In user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer pointing at an object of this type describing the + * planes of the frame. + * + * This has no use outside of custom allocation, and AVFrame AVBufferRef do not + * necessarily point to an instance of this struct. + */ +typedef struct AVD3D11FrameDescriptor { + /** + * The texture in which the frame is located. The reference count is + * managed by the AVBufferRef, and destroying the reference will release + * the interface. + * + * Normally stored in AVFrame.data[0]. + */ + ID3D11Texture2D *texture; + + /** + * The index into the array texture element representing the frame, or 0 + * if the texture is not an array texture. + * + * Normally stored in AVFrame.data[1] (cast from intptr_t). + */ + intptr_t index; +} AVD3D11FrameDescriptor; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + */ +typedef struct AVD3D11VAFramesContext { + /** + * The canonical texture used for pool allocation. If this is set to NULL + * on init, the hwframes implementation will allocate and set an array + * texture if initial_pool_size > 0. + * + * The only situation when the API user should set this is: + * - the user wants to do manual pool allocation (setting + * AVHWFramesContext.pool), instead of letting AVHWFramesContext + * allocate the pool + * - of an array texture + * - and wants it to use it for decoding + * - this has to be done before calling av_hwframe_ctx_init() + * + * Deallocating the AVHWFramesContext will always release this interface, + * and it does not matter whether it was user-allocated. + * + * This is in particular used by the libavcodec D3D11VA hwaccel, which + * requires a single array texture. It will create ID3D11VideoDecoderOutputView + * objects for each array texture element on decoder initialization. + */ + ID3D11Texture2D *texture; + + /** + * D3D11_TEXTURE2D_DESC.BindFlags used for texture creation. The user must + * at least set D3D11_BIND_DECODER if the frames context is to be used for + * video decoding. + * This field is ignored/invalid if a user-allocated texture is provided. + */ + UINT BindFlags; + + /** + * D3D11_TEXTURE2D_DESC.MiscFlags used for texture creation. + * This field is ignored/invalid if a user-allocated texture is provided. + */ + UINT MiscFlags; +} AVD3D11VAFramesContext; + +#endif /* AVUTIL_HWCONTEXT_D3D11VA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_drm.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_drm.c new file mode 100644 index 000000000..32cbde82e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_drm.c @@ -0,0 +1,289 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include +#include + +#include "avassert.h" +#include "hwcontext.h" +#include "hwcontext_drm.h" +#include "hwcontext_internal.h" +#include "imgutils.h" + + +static void drm_device_free(AVHWDeviceContext *hwdev) +{ + AVDRMDeviceContext *hwctx = hwdev->hwctx; + + close(hwctx->fd); +} + +static int drm_device_create(AVHWDeviceContext *hwdev, const char *device, + AVDictionary *opts, int flags) +{ + AVDRMDeviceContext *hwctx = hwdev->hwctx; + drmVersionPtr version; + + hwctx->fd = open(device, O_RDWR); + if (hwctx->fd < 0) + return AVERROR(errno); + + version = drmGetVersion(hwctx->fd); + if (!version) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get version information " + "from %s: probably not a DRM device?\n", device); + close(hwctx->fd); + return AVERROR(EINVAL); + } + + av_log(hwdev, AV_LOG_VERBOSE, "Opened DRM device %s: driver %s " + "version %d.%d.%d.\n", device, version->name, + version->version_major, version->version_minor, + version->version_patchlevel); + + drmFreeVersion(version); + + hwdev->free = &drm_device_free; + + return 0; +} + +static int drm_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(hwfc->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[0] = (uint8_t*)frame->buf[0]->data; + + frame->format = AV_PIX_FMT_DRM_PRIME; + frame->width = hwfc->width; + frame->height = hwfc->height; + + return 0; +} + +typedef struct DRMMapping { + // Address and length of each mmap()ed region. + int nb_regions; + void *address[AV_DRM_MAX_PLANES]; + size_t length[AV_DRM_MAX_PLANES]; +} DRMMapping; + +static void drm_unmap_frame(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + DRMMapping *map = hwmap->priv; + int i; + + for (i = 0; i < map->nb_regions; i++) + munmap(map->address[i], map->length[i]); + + av_free(map); +} + +static int drm_map_frame(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src, int flags) +{ + const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)src->data[0]; + DRMMapping *map; + int err, i, p, plane; + int mmap_prot; + void *addr; + + map = av_mallocz(sizeof(*map)); + if (!map) + return AVERROR(ENOMEM); + + mmap_prot = 0; + if (flags & AV_HWFRAME_MAP_READ) + mmap_prot |= PROT_READ; + if (flags & AV_HWFRAME_MAP_WRITE) + mmap_prot |= PROT_WRITE; + + av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES); + for (i = 0; i < desc->nb_objects; i++) { + addr = mmap(NULL, desc->objects[i].size, mmap_prot, MAP_SHARED, + desc->objects[i].fd, 0); + if (addr == MAP_FAILED) { + err = AVERROR(errno); + av_log(hwfc, AV_LOG_ERROR, "Failed to map DRM object %d to " + "memory: %d.\n", desc->objects[i].fd, errno); + goto fail; + } + + map->address[i] = addr; + map->length[i] = desc->objects[i].size; + } + map->nb_regions = i; + + plane = 0; + for (i = 0; i < desc->nb_layers; i++) { + const AVDRMLayerDescriptor *layer = &desc->layers[i]; + for (p = 0; p < layer->nb_planes; p++) { + dst->data[plane] = + (uint8_t*)map->address[layer->planes[p].object_index] + + layer->planes[p].offset; + dst->linesize[plane] = layer->planes[p].pitch; + ++plane; + } + } + av_assert0(plane <= AV_DRM_MAX_PLANES); + + dst->width = src->width; + dst->height = src->height; + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + &drm_unmap_frame, map); + if (err < 0) + goto fail; + + return 0; + +fail: + for (i = 0; i < desc->nb_objects; i++) { + if (map->address[i]) + munmap(map->address[i], map->length[i]); + } + av_free(map); + return err; +} + +static int drm_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *pix_fmts; + + pix_fmts = av_malloc_array(2, sizeof(*pix_fmts)); + if (!pix_fmts) + return AVERROR(ENOMEM); + + pix_fmts[0] = ctx->sw_format; + pix_fmts[1] = AV_PIX_FMT_NONE; + + *formats = pix_fmts; + return 0; +} + +static int drm_transfer_data_from(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (dst->width > hwfc->width || dst->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + err = drm_map_frame(hwfc, map, src, AV_HWFRAME_MAP_READ); + if (err) + goto fail; + + map->width = dst->width; + map->height = dst->height; + + err = av_frame_copy(dst, map); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int drm_transfer_data_to(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (src->width > hwfc->width || src->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = src->format; + + err = drm_map_frame(hwfc, map, dst, AV_HWFRAME_MAP_WRITE | + AV_HWFRAME_MAP_OVERWRITE); + if (err) + goto fail; + + map->width = src->width; + map->height = src->height; + + err = av_frame_copy(map, src); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int drm_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err; + + if (hwfc->sw_format != dst->format) + return AVERROR(ENOSYS); + + err = drm_map_frame(hwfc, dst, src, flags); + if (err) + return err; + + err = av_frame_copy_props(dst, src); + if (err) + return err; + + return 0; +} + +const HWContextType ff_hwcontext_type_drm = { + .type = AV_HWDEVICE_TYPE_DRM, + .name = "DRM", + + .device_hwctx_size = sizeof(AVDRMDeviceContext), + + .device_create = &drm_device_create, + + .frames_get_buffer = &drm_get_buffer, + + .transfer_get_formats = &drm_transfer_get_formats, + .transfer_data_to = &drm_transfer_data_to, + .transfer_data_from = &drm_transfer_data_from, + .map_from = &drm_map_from, + + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_DRM_PRIME, + AV_PIX_FMT_NONE + }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_drm.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_drm.h new file mode 100644 index 000000000..42709f215 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_drm.h @@ -0,0 +1,169 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_DRM_H +#define AVUTIL_HWCONTEXT_DRM_H + +#include +#include + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_DRM. + * + * Internal frame allocation is not currently supported - all frames + * must be allocated by the user. Thus AVHWFramesContext is always + * NULL, though this may change if support for frame allocation is + * added in future. + */ + +enum { + /** + * The maximum number of layers/planes in a DRM frame. + */ + AV_DRM_MAX_PLANES = 4 +}; + +/** + * DRM object descriptor. + * + * Describes a single DRM object, addressing it as a PRIME file + * descriptor. + */ +typedef struct AVDRMObjectDescriptor { + /** + * DRM PRIME fd for the object. + */ + int fd; + /** + * Total size of the object. + * + * (This includes any parts not which do not contain image data.) + */ + size_t size; + /** + * Format modifier applied to the object (DRM_FORMAT_MOD_*). + * + * If the format modifier is unknown then this should be set to + * DRM_FORMAT_MOD_INVALID. + */ + uint64_t format_modifier; +} AVDRMObjectDescriptor; + +/** + * DRM plane descriptor. + * + * Describes a single plane of a layer, which is contained within + * a single object. + */ +typedef struct AVDRMPlaneDescriptor { + /** + * Index of the object containing this plane in the objects + * array of the enclosing frame descriptor. + */ + int object_index; + /** + * Offset within that object of this plane. + */ + ptrdiff_t offset; + /** + * Pitch (linesize) of this plane. + */ + ptrdiff_t pitch; +} AVDRMPlaneDescriptor; + +/** + * DRM layer descriptor. + * + * Describes a single layer within a frame. This has the structure + * defined by its format, and will contain one or more planes. + */ +typedef struct AVDRMLayerDescriptor { + /** + * Format of the layer (DRM_FORMAT_*). + */ + uint32_t format; + /** + * Number of planes in the layer. + * + * This must match the number of planes required by format. + */ + int nb_planes; + /** + * Array of planes in this layer. + */ + AVDRMPlaneDescriptor planes[AV_DRM_MAX_PLANES]; +} AVDRMLayerDescriptor; + +/** + * DRM frame descriptor. + * + * This is used as the data pointer for AV_PIX_FMT_DRM_PRIME frames. + * It is also used by user-allocated frame pools - allocating in + * AVHWFramesContext.pool must return AVBufferRefs which contain + * an object of this type. + * + * The fields of this structure should be set such it can be + * imported directly by EGL using the EGL_EXT_image_dma_buf_import + * and EGL_EXT_image_dma_buf_import_modifiers extensions. + * (Note that the exact layout of a particular format may vary between + * platforms - we only specify that the same platform should be able + * to import it.) + * + * The total number of planes must not exceed AV_DRM_MAX_PLANES, and + * the order of the planes by increasing layer index followed by + * increasing plane index must be the same as the order which would + * be used for the data pointers in the equivalent software format. + */ +typedef struct AVDRMFrameDescriptor { + /** + * Number of DRM objects making up this frame. + */ + int nb_objects; + /** + * Array of objects making up the frame. + */ + AVDRMObjectDescriptor objects[AV_DRM_MAX_PLANES]; + /** + * Number of layers in the frame. + */ + int nb_layers; + /** + * Array of layers in the frame. + */ + AVDRMLayerDescriptor layers[AV_DRM_MAX_PLANES]; +} AVDRMFrameDescriptor; + +/** + * DRM device. + * + * Allocated as AVHWDeviceContext.hwctx. + */ +typedef struct AVDRMDeviceContext { + /** + * File descriptor of DRM device. + * + * This is used as the device to create frames on, and may also be + * used in some derivation and mapping operations. + * + * If no device is required, set to -1. + */ + int fd; +} AVDRMDeviceContext; + +#endif /* AVUTIL_HWCONTEXT_DRM_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_dxva2.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_dxva2.c new file mode 100644 index 000000000..64366cea8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_dxva2.c @@ -0,0 +1,594 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#define DXVA2API_USE_BITFIELDS +#define COBJMACROS + +#include +#include +#include + +#include "avassert.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_dxva2.h" +#include "hwcontext_internal.h" +#include "imgutils.h" +#include "pixdesc.h" +#include "pixfmt.h" +#include "compat/w32dlfcn.h" + +typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT); +typedef HRESULT WINAPI pDirect3DCreate9Ex(UINT, IDirect3D9Ex **); +typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **); + +#define FF_D3DCREATE_FLAGS (D3DCREATE_SOFTWARE_VERTEXPROCESSING | \ + D3DCREATE_MULTITHREADED | \ + D3DCREATE_FPU_PRESERVE) + +static const D3DPRESENT_PARAMETERS dxva2_present_params = { + .Windowed = TRUE, + .BackBufferWidth = 640, + .BackBufferHeight = 480, + .BackBufferCount = 0, + .SwapEffect = D3DSWAPEFFECT_DISCARD, + .Flags = D3DPRESENTFLAG_VIDEO, +}; + +typedef struct DXVA2Mapping { + uint32_t palette_dummy[256]; +} DXVA2Mapping; + +typedef struct DXVA2FramesContext { + IDirect3DSurface9 **surfaces_internal; + int nb_surfaces_used; + + HANDLE device_handle; + IDirectXVideoAccelerationService *service; + + D3DFORMAT format; +} DXVA2FramesContext; + +typedef struct DXVA2DevicePriv { + HMODULE d3dlib; + HMODULE dxva2lib; + + HANDLE device_handle; + + IDirect3D9 *d3d9; + IDirect3DDevice9 *d3d9device; +} DXVA2DevicePriv; + +static const struct { + D3DFORMAT d3d_format; + enum AVPixelFormat pix_fmt; +} supported_formats[] = { + { MKTAG('N', 'V', '1', '2'), AV_PIX_FMT_NV12 }, + { MKTAG('P', '0', '1', '0'), AV_PIX_FMT_P010 }, + { D3DFMT_P8, AV_PIX_FMT_PAL8 }, +}; + +DEFINE_GUID(video_decoder_service, 0xfc51a551, 0xd5e7, 0x11d9, 0xaf, 0x55, 0x00, 0x05, 0x4e, 0x43, 0xff, 0x02); +DEFINE_GUID(video_processor_service, 0xfc51a552, 0xd5e7, 0x11d9, 0xaf, 0x55, 0x00, 0x05, 0x4e, 0x43, 0xff, 0x02); + +static void dxva2_frames_uninit(AVHWFramesContext *ctx) +{ + AVDXVA2DeviceContext *device_hwctx = ctx->device_ctx->hwctx; + AVDXVA2FramesContext *frames_hwctx = ctx->hwctx; + DXVA2FramesContext *s = ctx->internal->priv; + int i; + + if (frames_hwctx->decoder_to_release) + IDirectXVideoDecoder_Release(frames_hwctx->decoder_to_release); + + if (s->surfaces_internal) { + for (i = 0; i < frames_hwctx->nb_surfaces; i++) { + if (s->surfaces_internal[i]) + IDirect3DSurface9_Release(s->surfaces_internal[i]); + } + } + av_freep(&s->surfaces_internal); + + if (s->service) { + IDirectXVideoAccelerationService_Release(s->service); + s->service = NULL; + } + + if (s->device_handle != INVALID_HANDLE_VALUE) { + IDirect3DDeviceManager9_CloseDeviceHandle(device_hwctx->devmgr, s->device_handle); + s->device_handle = INVALID_HANDLE_VALUE; + } +} + +static void dxva2_pool_release_dummy(void *opaque, uint8_t *data) +{ + // important not to free anything here--data is a surface object + // associated with the call to CreateSurface(), and these surfaces are + // released in dxva2_frames_uninit() +} + +static AVBufferRef *dxva2_pool_alloc(void *opaque, int size) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; + DXVA2FramesContext *s = ctx->internal->priv; + AVDXVA2FramesContext *hwctx = ctx->hwctx; + + if (s->nb_surfaces_used < hwctx->nb_surfaces) { + s->nb_surfaces_used++; + return av_buffer_create((uint8_t*)s->surfaces_internal[s->nb_surfaces_used - 1], + sizeof(*hwctx->surfaces), dxva2_pool_release_dummy, 0, 0); + } + + return NULL; +} + +static int dxva2_init_pool(AVHWFramesContext *ctx) +{ + AVDXVA2FramesContext *frames_hwctx = ctx->hwctx; + AVDXVA2DeviceContext *device_hwctx = ctx->device_ctx->hwctx; + DXVA2FramesContext *s = ctx->internal->priv; + int decode = (frames_hwctx->surface_type == DXVA2_VideoDecoderRenderTarget); + + int i; + HRESULT hr; + + if (ctx->initial_pool_size <= 0) + return 0; + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr, &s->device_handle); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to open device handle\n"); + return AVERROR_UNKNOWN; + } + + hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, + s->device_handle, + decode ? &video_decoder_service : &video_processor_service, + (void **)&s->service); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create the video service\n"); + return AVERROR_UNKNOWN; + } + + for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { + if (ctx->sw_format == supported_formats[i].pix_fmt) { + s->format = supported_formats[i].d3d_format; + break; + } + } + if (i == FF_ARRAY_ELEMS(supported_formats)) { + av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format: %s\n", + av_get_pix_fmt_name(ctx->sw_format)); + return AVERROR(EINVAL); + } + + s->surfaces_internal = av_mallocz_array(ctx->initial_pool_size, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + + hr = IDirectXVideoAccelerationService_CreateSurface(s->service, + ctx->width, ctx->height, + ctx->initial_pool_size - 1, + s->format, D3DPOOL_DEFAULT, 0, + frames_hwctx->surface_type, + s->surfaces_internal, NULL); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Could not create the surfaces\n"); + return AVERROR_UNKNOWN; + } + + ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(*s->surfaces_internal), + ctx, dxva2_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + + frames_hwctx->surfaces = s->surfaces_internal; + frames_hwctx->nb_surfaces = ctx->initial_pool_size; + + return 0; +} + +static int dxva2_frames_init(AVHWFramesContext *ctx) +{ + AVDXVA2FramesContext *hwctx = ctx->hwctx; + DXVA2FramesContext *s = ctx->internal->priv; + int ret; + + if (hwctx->surface_type != DXVA2_VideoDecoderRenderTarget && + hwctx->surface_type != DXVA2_VideoProcessorRenderTarget) { + av_log(ctx, AV_LOG_ERROR, "Unknown surface type: %lu\n", + hwctx->surface_type); + return AVERROR(EINVAL); + } + + s->device_handle = INVALID_HANDLE_VALUE; + + /* init the frame pool if the caller didn't provide one */ + if (!ctx->pool) { + ret = dxva2_init_pool(ctx); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error creating an internal frame pool\n"); + return ret; + } + } + + return 0; +} + +static int dxva2_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_DXVA2_VLD; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int dxva2_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + + return 0; +} + +static void dxva2_unmap_frame(AVHWFramesContext *ctx, HWMapDescriptor *hwmap) +{ + IDirect3DSurface9 *surface = (IDirect3DSurface9*)hwmap->source->data[3]; + IDirect3DSurface9_UnlockRect(surface); + av_freep(&hwmap->priv); +} + +static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, + int flags) +{ + IDirect3DSurface9 *surface = (IDirect3DSurface9*)src->data[3]; + DXVA2Mapping *map; + D3DSURFACE_DESC surfaceDesc; + D3DLOCKED_RECT LockedRect; + HRESULT hr; + int i, err, nb_planes; + int lock_flags = 0; + + nb_planes = av_pix_fmt_count_planes(dst->format); + + hr = IDirect3DSurface9_GetDesc(surface, &surfaceDesc); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error getting a surface description\n"); + return AVERROR_UNKNOWN; + } + + if (!(flags & AV_HWFRAME_MAP_WRITE)) + lock_flags |= D3DLOCK_READONLY; + if (flags & AV_HWFRAME_MAP_OVERWRITE) + lock_flags |= D3DLOCK_DISCARD; + + hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, lock_flags); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n"); + return AVERROR_UNKNOWN; + } + + map = av_mallocz(sizeof(*map)); + if (!map) { + err = AVERROR(ENOMEM); + goto fail; + } + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + dxva2_unmap_frame, map); + if (err < 0) { + av_freep(&map); + goto fail; + } + + for (i = 0; i < nb_planes; i++) + dst->linesize[i] = LockedRect.Pitch; + + av_image_fill_pointers(dst->data, dst->format, surfaceDesc.Height, + (uint8_t*)LockedRect.pBits, dst->linesize); + + if (dst->format == AV_PIX_FMT_PAL8) + dst->data[1] = (uint8_t*)map->palette_dummy; + + return 0; +fail: + IDirect3DSurface9_UnlockRect(surface); + return err; +} + +static int dxva2_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + AVFrame *map; + int ret; + + if (src->format != ctx->sw_format) + return AVERROR(ENOSYS); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + ret = dxva2_map_frame(ctx, map, dst, AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); + if (ret < 0) + goto fail; + + av_image_copy(map->data, map->linesize, (const uint8_t **)src->data, src->linesize, + ctx->sw_format, src->width, src->height); + +fail: + av_frame_free(&map); + return ret; +} + +static int dxva2_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + AVFrame *map; + ptrdiff_t src_linesize[4], dst_linesize[4]; + int ret, i; + + if (dst->format != ctx->sw_format) + return AVERROR(ENOSYS); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + ret = dxva2_map_frame(ctx, map, src, AV_HWFRAME_MAP_READ); + if (ret < 0) + goto fail; + + for (i = 0; i < 4; i++) { + dst_linesize[i] = dst->linesize[i]; + src_linesize[i] = map->linesize[i]; + } + av_image_copy_uc_from(dst->data, dst_linesize, (const uint8_t **)map->data, src_linesize, + ctx->sw_format, src->width, src->height); +fail: + av_frame_free(&map); + return ret; +} + +static int dxva2_map_from(AVHWFramesContext *ctx, + AVFrame *dst, const AVFrame *src, int flags) +{ + int err; + + if (dst->format != AV_PIX_FMT_NONE && dst->format != ctx->sw_format) + return AVERROR(ENOSYS); + dst->format = ctx->sw_format; + + err = dxva2_map_frame(ctx, dst, src, flags); + if (err < 0) + return err; + + err = av_frame_copy_props(dst, src); + if (err < 0) + return err; + + return 0; +} + +static void dxva2_device_free(AVHWDeviceContext *ctx) +{ + AVDXVA2DeviceContext *hwctx = ctx->hwctx; + DXVA2DevicePriv *priv = ctx->user_opaque; + + if (hwctx->devmgr && priv->device_handle != INVALID_HANDLE_VALUE) + IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->devmgr, priv->device_handle); + + if (hwctx->devmgr) + IDirect3DDeviceManager9_Release(hwctx->devmgr); + + if (priv->d3d9device) + IDirect3DDevice9_Release(priv->d3d9device); + + if (priv->d3d9) + IDirect3D9_Release(priv->d3d9); + + if (priv->d3dlib) + dlclose(priv->d3dlib); + + if (priv->dxva2lib) + dlclose(priv->dxva2lib); + + av_freep(&ctx->user_opaque); +} + +static int dxva2_device_create9(AVHWDeviceContext *ctx, UINT adapter) +{ + DXVA2DevicePriv *priv = ctx->user_opaque; + D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; + D3DDISPLAYMODE d3ddm; + HRESULT hr; + pDirect3DCreate9 *createD3D = (pDirect3DCreate9 *)dlsym(priv->d3dlib, "Direct3DCreate9"); + if (!createD3D) { + av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); + return AVERROR_UNKNOWN; + } + + priv->d3d9 = createD3D(D3D_SDK_VERSION); + if (!priv->d3d9) { + av_log(ctx, AV_LOG_ERROR, "Failed to create IDirect3D object\n"); + return AVERROR_UNKNOWN; + } + + IDirect3D9_GetAdapterDisplayMode(priv->d3d9, adapter, &d3ddm); + + d3dpp.BackBufferFormat = d3ddm.Format; + + hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(), + FF_D3DCREATE_FLAGS, + &d3dpp, &priv->d3d9device); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int dxva2_device_create9ex(AVHWDeviceContext *ctx, UINT adapter) +{ + DXVA2DevicePriv *priv = ctx->user_opaque; + D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; + D3DDISPLAYMODEEX modeex = {0}; + IDirect3D9Ex *d3d9ex = NULL; + IDirect3DDevice9Ex *exdev = NULL; + HRESULT hr; + pDirect3DCreate9Ex *createD3DEx = (pDirect3DCreate9Ex *)dlsym(priv->d3dlib, "Direct3DCreate9Ex"); + if (!createD3DEx) + return AVERROR(ENOSYS); + + hr = createD3DEx(D3D_SDK_VERSION, &d3d9ex); + if (FAILED(hr)) + return AVERROR_UNKNOWN; + + modeex.Size = sizeof(D3DDISPLAYMODEEX); + hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, adapter, &modeex, NULL); + if (FAILED(hr)) { + IDirect3D9Ex_Release(d3d9ex); + return AVERROR_UNKNOWN; + } + + d3dpp.BackBufferFormat = modeex.Format; + + hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(), + FF_D3DCREATE_FLAGS, + &d3dpp, NULL, &exdev); + if (FAILED(hr)) { + IDirect3D9Ex_Release(d3d9ex); + return AVERROR_UNKNOWN; + } + + av_log(ctx, AV_LOG_VERBOSE, "Using D3D9Ex device.\n"); + priv->d3d9 = (IDirect3D9 *)d3d9ex; + priv->d3d9device = (IDirect3DDevice9 *)exdev; + return 0; +} + +static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVDXVA2DeviceContext *hwctx = ctx->hwctx; + DXVA2DevicePriv *priv; + pCreateDeviceManager9 *createDeviceManager = NULL; + unsigned resetToken = 0; + UINT adapter = D3DADAPTER_DEFAULT; + HRESULT hr; + int err; + + if (device) + adapter = atoi(device); + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + ctx->user_opaque = priv; + ctx->free = dxva2_device_free; + + priv->device_handle = INVALID_HANDLE_VALUE; + + priv->d3dlib = dlopen("d3d9.dll", 0); + if (!priv->d3dlib) { + av_log(ctx, AV_LOG_ERROR, "Failed to load D3D9 library\n"); + return AVERROR_UNKNOWN; + } + priv->dxva2lib = dlopen("dxva2.dll", 0); + if (!priv->dxva2lib) { + av_log(ctx, AV_LOG_ERROR, "Failed to load DXVA2 library\n"); + return AVERROR_UNKNOWN; + } + + createDeviceManager = (pCreateDeviceManager9 *)dlsym(priv->dxva2lib, + "DXVA2CreateDirect3DDeviceManager9"); + if (!createDeviceManager) { + av_log(ctx, AV_LOG_ERROR, "Failed to locate DXVA2CreateDirect3DDeviceManager9\n"); + return AVERROR_UNKNOWN; + } + + if (dxva2_device_create9ex(ctx, adapter) < 0) { + // Retry with "classic" d3d9 + err = dxva2_device_create9(ctx, adapter); + if (err < 0) + return err; + } + + hr = createDeviceManager(&resetToken, &hwctx->devmgr); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device manager\n"); + return AVERROR_UNKNOWN; + } + + hr = IDirect3DDeviceManager9_ResetDevice(hwctx->devmgr, priv->d3d9device, resetToken); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to bind Direct3D device to device manager\n"); + return AVERROR_UNKNOWN; + } + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(hwctx->devmgr, &priv->device_handle); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to open device handle\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +const HWContextType ff_hwcontext_type_dxva2 = { + .type = AV_HWDEVICE_TYPE_DXVA2, + .name = "DXVA2", + + .device_hwctx_size = sizeof(AVDXVA2DeviceContext), + .frames_hwctx_size = sizeof(AVDXVA2FramesContext), + .frames_priv_size = sizeof(DXVA2FramesContext), + + .device_create = dxva2_device_create, + .frames_init = dxva2_frames_init, + .frames_uninit = dxva2_frames_uninit, + .frames_get_buffer = dxva2_get_buffer, + .transfer_get_formats = dxva2_transfer_get_formats, + .transfer_data_to = dxva2_transfer_data_to, + .transfer_data_from = dxva2_transfer_data_from, + .map_from = dxva2_map_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_DXVA2_VLD, AV_PIX_FMT_NONE }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_dxva2.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_dxva2.h new file mode 100644 index 000000000..e1b79bc0d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_dxva2.h @@ -0,0 +1,75 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVUTIL_HWCONTEXT_DXVA2_H +#define AVUTIL_HWCONTEXT_DXVA2_H + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_DXVA2. + * + * Only fixed-size pools are supported. + * + * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer set to a pointer to IDirect3DSurface9. + */ + +#include +#include + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVDXVA2DeviceContext { + IDirect3DDeviceManager9 *devmgr; +} AVDXVA2DeviceContext; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + */ +typedef struct AVDXVA2FramesContext { + /** + * The surface type (e.g. DXVA2_VideoProcessorRenderTarget or + * DXVA2_VideoDecoderRenderTarget). Must be set by the caller. + */ + DWORD surface_type; + + /** + * The surface pool. When an external pool is not provided by the caller, + * this will be managed (allocated and filled on init, freed on uninit) by + * libavutil. + */ + IDirect3DSurface9 **surfaces; + int nb_surfaces; + + /** + * Certain drivers require the decoder to be destroyed before the surfaces. + * To allow internally managed pools to work properly in such cases, this + * field is provided. + * + * If it is non-NULL, libavutil will call IDirectXVideoDecoder_Release() on + * it just before the internal surface pool is freed. + * + * This is for convenience only. Some code uses other methods to manage the + * decoder reference. + */ + IDirectXVideoDecoder *decoder_to_release; +} AVDXVA2FramesContext; + +#endif /* AVUTIL_HWCONTEXT_DXVA2_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_internal.h new file mode 100644 index 000000000..77dc47ddd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_internal.h @@ -0,0 +1,176 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_INTERNAL_H +#define AVUTIL_HWCONTEXT_INTERNAL_H + +#include + +#include "buffer.h" +#include "hwcontext.h" +#include "frame.h" +#include "pixfmt.h" + +typedef struct HWContextType { + enum AVHWDeviceType type; + const char *name; + + /** + * An array of pixel formats supported by the AVHWFramesContext instances + * Terminated by AV_PIX_FMT_NONE. + */ + const enum AVPixelFormat *pix_fmts; + + /** + * size of the public hardware-specific context, + * i.e. AVHWDeviceContext.hwctx + */ + size_t device_hwctx_size; + /** + * size of the private data, i.e. + * AVHWDeviceInternal.priv + */ + size_t device_priv_size; + + /** + * Size of the hardware-specific device configuration. + * (Used to query hwframe constraints.) + */ + size_t device_hwconfig_size; + + /** + * size of the public frame pool hardware-specific context, + * i.e. AVHWFramesContext.hwctx + */ + size_t frames_hwctx_size; + /** + * size of the private data, i.e. + * AVHWFramesInternal.priv + */ + size_t frames_priv_size; + + int (*device_create)(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags); + int (*device_derive)(AVHWDeviceContext *dst_ctx, + AVHWDeviceContext *src_ctx, int flags); + + int (*device_init)(AVHWDeviceContext *ctx); + void (*device_uninit)(AVHWDeviceContext *ctx); + + int (*frames_get_constraints)(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints); + + int (*frames_init)(AVHWFramesContext *ctx); + void (*frames_uninit)(AVHWFramesContext *ctx); + + int (*frames_get_buffer)(AVHWFramesContext *ctx, AVFrame *frame); + int (*transfer_get_formats)(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats); + int (*transfer_data_to)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src); + int (*transfer_data_from)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src); + + int (*map_to)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src, int flags); + int (*map_from)(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src, int flags); + + int (*frames_derive_to)(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags); + int (*frames_derive_from)(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags); +} HWContextType; + +struct AVHWDeviceInternal { + const HWContextType *hw_type; + void *priv; + + /** + * For a derived device, a reference to the original device + * context it was derived from. + */ + AVBufferRef *source_device; +}; + +struct AVHWFramesInternal { + const HWContextType *hw_type; + void *priv; + + AVBufferPool *pool_internal; + + /** + * For a derived context, a reference to the original frames + * context it was derived from. + */ + AVBufferRef *source_frames; + /** + * Flags to apply to the mapping from the source to the derived + * frame context when trying to allocate in the derived context. + */ + int source_allocation_map_flags; +}; + +typedef struct HWMapDescriptor { + /** + * A reference to the original source of the mapping. + */ + AVFrame *source; + /** + * A reference to the hardware frames context in which this + * mapping was made. May be the same as source->hw_frames_ctx, + * but need not be. + */ + AVBufferRef *hw_frames_ctx; + /** + * Unmap function. + */ + void (*unmap)(AVHWFramesContext *ctx, + struct HWMapDescriptor *hwmap); + /** + * Hardware-specific private data associated with the mapping. + */ + void *priv; +} HWMapDescriptor; + +int ff_hwframe_map_create(AVBufferRef *hwframe_ref, + AVFrame *dst, const AVFrame *src, + void (*unmap)(AVHWFramesContext *ctx, + HWMapDescriptor *hwmap), + void *priv); + +/** + * Replace the current hwmap of dst with the one from src, used for indirect + * mappings like VAAPI->(DRM)->OpenCL/Vulkan where a direct interop is missing + */ +int ff_hwframe_map_replace(AVFrame *dst, const AVFrame *src); + +extern const HWContextType ff_hwcontext_type_cuda; +extern const HWContextType ff_hwcontext_type_d3d11va; +extern const HWContextType ff_hwcontext_type_drm; +extern const HWContextType ff_hwcontext_type_dxva2; +extern const HWContextType ff_hwcontext_type_opencl; +extern const HWContextType ff_hwcontext_type_qsv; +extern const HWContextType ff_hwcontext_type_vaapi; +extern const HWContextType ff_hwcontext_type_vdpau; +extern const HWContextType ff_hwcontext_type_videotoolbox; +extern const HWContextType ff_hwcontext_type_mediacodec; + +#endif /* AVUTIL_HWCONTEXT_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_mediacodec.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_mediacodec.c new file mode 100644 index 000000000..b0d8993e1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_mediacodec.c @@ -0,0 +1,50 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_mediacodec.h" + +static int mc_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + if (device && device[0]) { + av_log(ctx, AV_LOG_ERROR, "Device selection unsupported.\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +const HWContextType ff_hwcontext_type_mediacodec = { + .type = AV_HWDEVICE_TYPE_MEDIACODEC, + .name = "mediacodec", + + .device_hwctx_size = sizeof(AVMediaCodecDeviceContext), + + .device_create = mc_device_create, + + .pix_fmts = (const enum AVPixelFormat[]){ + AV_PIX_FMT_MEDIACODEC, + AV_PIX_FMT_NONE + }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_mediacodec.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_mediacodec.h new file mode 100644 index 000000000..101a9806d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_mediacodec.h @@ -0,0 +1,36 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_MEDIACODEC_H +#define AVUTIL_HWCONTEXT_MEDIACODEC_H + +/** + * MediaCodec details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVMediaCodecDeviceContext { + /** + * android/view/Surface handle, to be filled by the user. + * + * This is the default surface used by decoders on this device. + */ + void *surface; +} AVMediaCodecDeviceContext; + +#endif /* AVUTIL_HWCONTEXT_MEDIACODEC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_opencl.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_opencl.c new file mode 100644 index 000000000..41fdfe96f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_opencl.c @@ -0,0 +1,2942 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define CL_USE_DEPRECATED_OPENCL_1_2_APIS + +#include + +#include "config.h" + +#include "avassert.h" +#include "avstring.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_opencl.h" +#include "mem.h" +#include "pixdesc.h" + +#if HAVE_OPENCL_VAAPI_BEIGNET +#include +#include +#include +#include +#include "hwcontext_vaapi.h" +#endif + +#if HAVE_OPENCL_DRM_BEIGNET +#include +#include +#include "hwcontext_drm.h" +#endif + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA +#if CONFIG_LIBMFX +#include +#endif +#include +#include +#include "hwcontext_vaapi.h" +#endif + +#if HAVE_OPENCL_DXVA2 +#define COBJMACROS +#include +#include +#include "hwcontext_dxva2.h" +#endif + +#if HAVE_OPENCL_D3D11 +#include +#include "hwcontext_d3d11va.h" +#endif + +#if HAVE_OPENCL_DRM_ARM +#include +#include +#include "hwcontext_drm.h" +#endif + + +typedef struct OpenCLDeviceContext { + // Default command queue to use for transfer/mapping operations on + // the device. If the user supplies one, this is a reference to it. + // Otherwise, it is newly-created. + cl_command_queue command_queue; + + // The platform the context exists on. This is needed to query and + // retrieve extension functions. + cl_platform_id platform_id; + + // Platform/device-specific functions. +#if HAVE_OPENCL_DRM_BEIGNET + int beignet_drm_mapping_usable; + clCreateImageFromFdINTEL_fn clCreateImageFromFdINTEL; +#endif + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + int qsv_mapping_usable; + clCreateFromVA_APIMediaSurfaceINTEL_fn + clCreateFromVA_APIMediaSurfaceINTEL; + clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn + clEnqueueAcquireVA_APIMediaSurfacesINTEL; + clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn + clEnqueueReleaseVA_APIMediaSurfacesINTEL; +#endif + +#if HAVE_OPENCL_DXVA2 + int dxva2_mapping_usable; + cl_dx9_media_adapter_type_khr dx9_media_adapter_type; + + clCreateFromDX9MediaSurfaceKHR_fn + clCreateFromDX9MediaSurfaceKHR; + clEnqueueAcquireDX9MediaSurfacesKHR_fn + clEnqueueAcquireDX9MediaSurfacesKHR; + clEnqueueReleaseDX9MediaSurfacesKHR_fn + clEnqueueReleaseDX9MediaSurfacesKHR; +#endif + +#if HAVE_OPENCL_D3D11 + int d3d11_mapping_usable; + clCreateFromD3D11Texture2DKHR_fn + clCreateFromD3D11Texture2DKHR; + clEnqueueAcquireD3D11ObjectsKHR_fn + clEnqueueAcquireD3D11ObjectsKHR; + clEnqueueReleaseD3D11ObjectsKHR_fn + clEnqueueReleaseD3D11ObjectsKHR; +#endif + +#if HAVE_OPENCL_DRM_ARM + int drm_arm_mapping_usable; +#endif +} OpenCLDeviceContext; + +typedef struct OpenCLFramesContext { + // Command queue used for transfer/mapping operations on this frames + // context. If the user supplies one, this is a reference to it. + // Otherwise, it is a reference to the default command queue for the + // device. + cl_command_queue command_queue; + +#if HAVE_OPENCL_DXVA2 || HAVE_OPENCL_D3D11 + // For mapping APIs which have separate creation and acquire/release + // steps, this stores the OpenCL memory objects corresponding to each + // frame. + int nb_mapped_frames; + AVOpenCLFrameDescriptor *mapped_frames; +#endif +} OpenCLFramesContext; + + +static void CL_CALLBACK opencl_error_callback(const char *errinfo, + const void *private_info, + size_t cb, + void *user_data) +{ + AVHWDeviceContext *ctx = user_data; + av_log(ctx, AV_LOG_ERROR, "OpenCL error: %s\n", errinfo); +} + +static void opencl_device_free(AVHWDeviceContext *hwdev) +{ + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + cl_int cle; + + cle = clReleaseContext(hwctx->context); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to release OpenCL " + "context: %d.\n", cle); + } +} + +static struct { + const char *key; + cl_platform_info name; +} opencl_platform_params[] = { + { "platform_profile", CL_PLATFORM_PROFILE }, + { "platform_version", CL_PLATFORM_VERSION }, + { "platform_name", CL_PLATFORM_NAME }, + { "platform_vendor", CL_PLATFORM_VENDOR }, + { "platform_extensions", CL_PLATFORM_EXTENSIONS }, +}; + +static struct { + const char *key; + cl_device_info name; +} opencl_device_params[] = { + { "device_name", CL_DEVICE_NAME }, + { "device_vendor", CL_DEVICE_VENDOR }, + { "driver_version", CL_DRIVER_VERSION }, + { "device_version", CL_DEVICE_VERSION }, + { "device_profile", CL_DEVICE_PROFILE }, + { "device_extensions", CL_DEVICE_EXTENSIONS }, +}; + +static struct { + const char *key; + cl_device_type type; +} opencl_device_types[] = { + { "cpu", CL_DEVICE_TYPE_CPU }, + { "gpu", CL_DEVICE_TYPE_GPU }, + { "accelerator", CL_DEVICE_TYPE_ACCELERATOR }, + { "custom", CL_DEVICE_TYPE_CUSTOM }, + { "default", CL_DEVICE_TYPE_DEFAULT }, + { "all", CL_DEVICE_TYPE_ALL }, +}; + +static char *opencl_get_platform_string(cl_platform_id platform_id, + cl_platform_info key) +{ + char *str; + size_t size; + cl_int cle; + cle = clGetPlatformInfo(platform_id, key, 0, NULL, &size); + if (cle != CL_SUCCESS) + return NULL; + str = av_malloc(size); + if (!str) + return NULL; + cle = clGetPlatformInfo(platform_id, key, size, str, &size); + if (cle != CL_SUCCESS) { + av_free(str); + return NULL; + } + av_assert0(strlen(str) + 1 == size); + return str; +} + +static char *opencl_get_device_string(cl_device_id device_id, + cl_device_info key) +{ + char *str; + size_t size; + cl_int cle; + cle = clGetDeviceInfo(device_id, key, 0, NULL, &size); + if (cle != CL_SUCCESS) + return NULL; + str = av_malloc(size); + if (!str) + return NULL; + cle = clGetDeviceInfo(device_id, key, size, str, &size); + if (cle != CL_SUCCESS) { + av_free(str); + return NULL; + } + av_assert0(strlen(str) + 1== size); + return str; +} + +static int opencl_check_platform_extension(cl_platform_id platform_id, + const char *name) +{ + char *str; + int found = 0; + str = opencl_get_platform_string(platform_id, + CL_PLATFORM_EXTENSIONS); + if (str && strstr(str, name)) + found = 1; + av_free(str); + return found; +} + +static int opencl_check_device_extension(cl_device_id device_id, + const char *name) +{ + char *str; + int found = 0; + str = opencl_get_device_string(device_id, + CL_DEVICE_EXTENSIONS); + if (str && strstr(str, name)) + found = 1; + av_free(str); + return found; +} + +static av_unused int opencl_check_extension(AVHWDeviceContext *hwdev, + const char *name) +{ + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + OpenCLDeviceContext *priv = hwdev->internal->priv; + + if (opencl_check_platform_extension(priv->platform_id, name)) { + av_log(hwdev, AV_LOG_DEBUG, + "%s found as platform extension.\n", name); + return 1; + } + + if (opencl_check_device_extension(hwctx->device_id, name)) { + av_log(hwdev, AV_LOG_DEBUG, + "%s found as device extension.\n", name); + return 1; + } + + return 0; +} + +static int opencl_enumerate_platforms(AVHWDeviceContext *hwdev, + cl_uint *nb_platforms, + cl_platform_id **platforms, + void *context) +{ + cl_int cle; + + cle = clGetPlatformIDs(0, NULL, nb_platforms); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of " + "OpenCL platforms: %d.\n", cle); + return AVERROR(ENODEV); + } + av_log(hwdev, AV_LOG_DEBUG, "%u OpenCL platforms found.\n", + *nb_platforms); + + *platforms = av_malloc_array(*nb_platforms, sizeof(**platforms)); + if (!*platforms) + return AVERROR(ENOMEM); + + cle = clGetPlatformIDs(*nb_platforms, *platforms, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of OpenCL " + "platforms: %d.\n", cle); + av_freep(platforms); + return AVERROR(ENODEV); + } + + return 0; +} + +static int opencl_filter_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + AVDictionary *opts = context; + const AVDictionaryEntry *param; + char *str; + int i, ret = 0; + + for (i = 0; i < FF_ARRAY_ELEMS(opencl_platform_params); i++) { + param = av_dict_get(opts, opencl_platform_params[i].key, + NULL, 0); + if (!param) + continue; + + str = opencl_get_platform_string(platform_id, + opencl_platform_params[i].name); + if (!str) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query %s " + "of platform \"%s\".\n", + opencl_platform_params[i].key, platform_name); + return AVERROR_UNKNOWN; + } + if (!av_stristr(str, param->value)) { + av_log(hwdev, AV_LOG_DEBUG, "%s does not match (\"%s\").\n", + param->key, str); + ret = 1; + } + av_free(str); + } + + return ret; +} + +static int opencl_enumerate_devices(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context) +{ + cl_int cle; + + cle = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_ALL, + 0, NULL, nb_devices); + if (cle == CL_DEVICE_NOT_FOUND) { + av_log(hwdev, AV_LOG_DEBUG, "No devices found " + "on platform \"%s\".\n", platform_name); + *nb_devices = 0; + return 0; + } else if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + return AVERROR(ENODEV); + } + av_log(hwdev, AV_LOG_DEBUG, "%u OpenCL devices found on " + "platform \"%s\".\n", *nb_devices, platform_name); + + *devices = av_malloc_array(*nb_devices, sizeof(**devices)); + if (!*devices) + return AVERROR(ENOMEM); + + cle = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_ALL, + *nb_devices, *devices, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + av_freep(devices); + return AVERROR(ENODEV); + } + + return 0; +} + +static int opencl_filter_device(AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context) +{ + AVDictionary *opts = context; + const AVDictionaryEntry *param; + char *str; + int i, ret = 0; + + param = av_dict_get(opts, "device_type", NULL, 0); + if (param) { + cl_device_type match_type = 0, device_type; + cl_int cle; + + for (i = 0; i < FF_ARRAY_ELEMS(opencl_device_types); i++) { + if (!strcmp(opencl_device_types[i].key, param->value)) { + match_type = opencl_device_types[i].type; + break; + } + } + if (!match_type) { + av_log(hwdev, AV_LOG_ERROR, "Unknown device type %s.\n", + param->value); + return AVERROR(EINVAL); + } + + cle = clGetDeviceInfo(device_id, CL_DEVICE_TYPE, + sizeof(device_type), &device_type, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query device type " + "of device \"%s\".\n", device_name); + return AVERROR_UNKNOWN; + } + + if (!(device_type & match_type)) { + av_log(hwdev, AV_LOG_DEBUG, "device_type does not match.\n"); + return 1; + } + } + + for (i = 0; i < FF_ARRAY_ELEMS(opencl_device_params); i++) { + param = av_dict_get(opts, opencl_device_params[i].key, + NULL, 0); + if (!param) + continue; + + str = opencl_get_device_string(device_id, + opencl_device_params[i].name); + if (!str) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query %s " + "of device \"%s\".\n", + opencl_device_params[i].key, device_name); + return AVERROR_UNKNOWN; + } + if (!av_stristr(str, param->value)) { + av_log(hwdev, AV_LOG_DEBUG, "%s does not match (\"%s\").\n", + param->key, str); + ret = 1; + } + av_free(str); + } + + return ret; +} + +typedef struct OpenCLDeviceSelector { + int platform_index; + int device_index; + void *context; + int (*enumerate_platforms)(AVHWDeviceContext *hwdev, + cl_uint *nb_platforms, + cl_platform_id **platforms, + void *context); + int (*filter_platform) (AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context); + int (*enumerate_devices) (AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context); + int (*filter_device) (AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context); +} OpenCLDeviceSelector; + +static int opencl_device_create_internal(AVHWDeviceContext *hwdev, + const OpenCLDeviceSelector *selector, + cl_context_properties *props) +{ + cl_uint nb_platforms; + cl_platform_id *platforms = NULL; + cl_platform_id platform_id; + cl_uint nb_devices; + cl_device_id *devices = NULL; + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + cl_int cle; + cl_context_properties default_props[3]; + char *platform_name_src = NULL, + *device_name_src = NULL; + int err, found, p, d; + + av_assert0(selector->enumerate_platforms && + selector->enumerate_devices); + + err = selector->enumerate_platforms(hwdev, &nb_platforms, &platforms, + selector->context); + if (err) + return err; + + found = 0; + for (p = 0; p < nb_platforms; p++) { + const char *platform_name; + + if (selector->platform_index >= 0 && + selector->platform_index != p) + continue; + + av_freep(&platform_name_src); + platform_name_src = opencl_get_platform_string(platforms[p], + CL_PLATFORM_NAME); + if (platform_name_src) + platform_name = platform_name_src; + else + platform_name = "Unknown Platform"; + + if (selector->filter_platform) { + err = selector->filter_platform(hwdev, platforms[p], + platform_name, + selector->context); + if (err < 0) + goto fail; + if (err > 0) + continue; + } + + err = selector->enumerate_devices(hwdev, platforms[p], platform_name, + &nb_devices, &devices, + selector->context); + if (err < 0) + continue; + + for (d = 0; d < nb_devices; d++) { + const char *device_name; + + if (selector->device_index >= 0 && + selector->device_index != d) + continue; + + av_freep(&device_name_src); + device_name_src = opencl_get_device_string(devices[d], + CL_DEVICE_NAME); + if (device_name_src) + device_name = device_name_src; + else + device_name = "Unknown Device"; + + if (selector->filter_device) { + err = selector->filter_device(hwdev, devices[d], + device_name, + selector->context); + if (err < 0) + goto fail; + if (err > 0) + continue; + } + + av_log(hwdev, AV_LOG_VERBOSE, "%d.%d: %s / %s\n", p, d, + platform_name, device_name); + + ++found; + platform_id = platforms[p]; + hwctx->device_id = devices[d]; + } + + av_freep(&devices); + } + + if (found == 0) { + av_log(hwdev, AV_LOG_ERROR, "No matching devices found.\n"); + err = AVERROR(ENODEV); + goto fail; + } + if (found > 1) { + av_log(hwdev, AV_LOG_ERROR, "More than one matching device found.\n"); + err = AVERROR(ENODEV); + goto fail; + } + + if (!props) { + props = default_props; + default_props[0] = CL_CONTEXT_PLATFORM; + default_props[1] = (intptr_t)platform_id; + default_props[2] = 0; + } else { + if (props[0] == CL_CONTEXT_PLATFORM && props[1] == 0) + props[1] = (intptr_t)platform_id; + } + + hwctx->context = clCreateContext(props, 1, &hwctx->device_id, + &opencl_error_callback, hwdev, &cle); + if (!hwctx->context) { + av_log(hwdev, AV_LOG_ERROR, "Failed to create OpenCL context: " + "%d.\n", cle); + err = AVERROR(ENODEV); + goto fail; + } + + hwdev->free = &opencl_device_free; + + err = 0; +fail: + av_freep(&platform_name_src); + av_freep(&device_name_src); + av_freep(&platforms); + av_freep(&devices); + return err; +} + +static int opencl_device_create(AVHWDeviceContext *hwdev, const char *device, + AVDictionary *opts, int flags) +{ + OpenCLDeviceSelector selector = { + .context = opts, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_platform, + .enumerate_devices = &opencl_enumerate_devices, + .filter_device = &opencl_filter_device, + }; + + if (device && device[0]) { + // Match one or both indices for platform and device. + int d = -1, p = -1, ret; + if (device[0] == '.') + ret = sscanf(device, ".%d", &d); + else + ret = sscanf(device, "%d.%d", &p, &d); + if (ret < 1) { + av_log(hwdev, AV_LOG_ERROR, "Invalid OpenCL platform/device " + "index specification \"%s\".\n", device); + return AVERROR(EINVAL); + } + selector.platform_index = p; + selector.device_index = d; + } else { + selector.platform_index = -1; + selector.device_index = -1; + } + + return opencl_device_create_internal(hwdev, &selector, NULL); +} + +static int opencl_device_init(AVHWDeviceContext *hwdev) +{ + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + OpenCLDeviceContext *priv = hwdev->internal->priv; + cl_int cle; + + if (hwctx->command_queue) { + cle = clRetainCommandQueue(hwctx->command_queue); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to retain external " + "command queue: %d.\n", cle); + return AVERROR(EIO); + } + priv->command_queue = hwctx->command_queue; + } else { + priv->command_queue = clCreateCommandQueue(hwctx->context, + hwctx->device_id, + 0, &cle); + if (!priv->command_queue) { + av_log(hwdev, AV_LOG_ERROR, "Failed to create internal " + "command queue: %d.\n", cle); + return AVERROR(EIO); + } + } + + cle = clGetDeviceInfo(hwctx->device_id, CL_DEVICE_PLATFORM, + sizeof(priv->platform_id), &priv->platform_id, + NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to determine the OpenCL " + "platform containing the device.\n"); + return AVERROR(EIO); + } + +#define CL_FUNC(name, desc) do { \ + if (fail) \ + break; \ + priv->name = clGetExtensionFunctionAddressForPlatform( \ + priv->platform_id, #name); \ + if (!priv->name) { \ + av_log(hwdev, AV_LOG_VERBOSE, \ + desc " function not found (%s).\n", #name); \ + fail = 1; \ + } else { \ + av_log(hwdev, AV_LOG_VERBOSE, \ + desc " function found (%s).\n", #name); \ + } \ + } while (0) + +#if HAVE_OPENCL_DRM_BEIGNET + { + int fail = 0; + + CL_FUNC(clCreateImageFromFdINTEL, + "Beignet DRM to OpenCL image mapping"); + + if (fail) { + av_log(hwdev, AV_LOG_WARNING, "Beignet DRM to OpenCL " + "mapping not usable.\n"); + priv->beignet_drm_mapping_usable = 0; + } else { + priv->beignet_drm_mapping_usable = 1; + } + } +#endif + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + { + size_t props_size; + cl_context_properties *props = NULL; + VADisplay va_display; + const char *va_ext = "cl_intel_va_api_media_sharing"; + int i, fail = 0; + + if (!opencl_check_extension(hwdev, va_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension is " + "required for QSV to OpenCL mapping.\n", va_ext); + goto no_qsv; + } + + cle = clGetContextInfo(hwctx->context, CL_CONTEXT_PROPERTIES, + 0, NULL, &props_size); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_VERBOSE, "Failed to get context " + "properties: %d.\n", cle); + goto no_qsv; + } + if (props_size == 0) { + av_log(hwdev, AV_LOG_VERBOSE, "Media sharing must be " + "enabled on context creation to use QSV to " + "OpenCL mapping.\n"); + goto no_qsv; + } + + props = av_malloc(props_size); + if (!props) + return AVERROR(ENOMEM); + + cle = clGetContextInfo(hwctx->context, CL_CONTEXT_PROPERTIES, + props_size, props, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_VERBOSE, "Failed to get context " + "properties: %d.\n", cle); + goto no_qsv; + } + + va_display = NULL; + for (i = 0; i < (props_size / sizeof(*props) - 1); i++) { + if (props[i] == CL_CONTEXT_VA_API_DISPLAY_INTEL) { + va_display = (VADisplay)(intptr_t)props[i+1]; + break; + } + } + if (!va_display) { + av_log(hwdev, AV_LOG_VERBOSE, "Media sharing must be " + "enabled on context creation to use QSV to " + "OpenCL mapping.\n"); + goto no_qsv; + } + if (!vaDisplayIsValid(va_display)) { + av_log(hwdev, AV_LOG_VERBOSE, "A valid VADisplay is " + "required on context creation to use QSV to " + "OpenCL mapping.\n"); + goto no_qsv; + } + + CL_FUNC(clCreateFromVA_APIMediaSurfaceINTEL, + "Intel QSV to OpenCL mapping"); + CL_FUNC(clEnqueueAcquireVA_APIMediaSurfacesINTEL, + "Intel QSV in OpenCL acquire"); + CL_FUNC(clEnqueueReleaseVA_APIMediaSurfacesINTEL, + "Intel QSV in OpenCL release"); + + if (fail) { + no_qsv: + av_log(hwdev, AV_LOG_WARNING, "QSV to OpenCL mapping " + "not usable.\n"); + priv->qsv_mapping_usable = 0; + } else { + priv->qsv_mapping_usable = 1; + } + av_free(props); + } +#endif + +#if HAVE_OPENCL_DXVA2 + { + int fail = 0; + + CL_FUNC(clCreateFromDX9MediaSurfaceKHR, + "DXVA2 to OpenCL mapping"); + CL_FUNC(clEnqueueAcquireDX9MediaSurfacesKHR, + "DXVA2 in OpenCL acquire"); + CL_FUNC(clEnqueueReleaseDX9MediaSurfacesKHR, + "DXVA2 in OpenCL release"); + + if (fail) { + av_log(hwdev, AV_LOG_WARNING, "DXVA2 to OpenCL mapping " + "not usable.\n"); + priv->dxva2_mapping_usable = 0; + } else { + priv->dx9_media_adapter_type = CL_ADAPTER_D3D9EX_KHR; + priv->dxva2_mapping_usable = 1; + } + } +#endif + +#if HAVE_OPENCL_D3D11 + { + const char *d3d11_ext = "cl_khr_d3d11_sharing"; + const char *nv12_ext = "cl_intel_d3d11_nv12_media_sharing"; + int fail = 0; + + if (!opencl_check_extension(hwdev, d3d11_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension is " + "required for D3D11 to OpenCL mapping.\n", d3d11_ext); + fail = 1; + } else if (!opencl_check_extension(hwdev, nv12_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension may be " + "required for D3D11 to OpenCL mapping.\n", nv12_ext); + // Not fatal. + } + + CL_FUNC(clCreateFromD3D11Texture2DKHR, + "D3D11 to OpenCL mapping"); + CL_FUNC(clEnqueueAcquireD3D11ObjectsKHR, + "D3D11 in OpenCL acquire"); + CL_FUNC(clEnqueueReleaseD3D11ObjectsKHR, + "D3D11 in OpenCL release"); + + if (fail) { + av_log(hwdev, AV_LOG_WARNING, "D3D11 to OpenCL mapping " + "not usable.\n"); + priv->d3d11_mapping_usable = 0; + } else { + priv->d3d11_mapping_usable = 1; + } + } +#endif + +#if HAVE_OPENCL_DRM_ARM + { + const char *drm_arm_ext = "cl_arm_import_memory"; + const char *image_ext = "cl_khr_image2d_from_buffer"; + int fail = 0; + + if (!opencl_check_extension(hwdev, drm_arm_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension is " + "required for DRM to OpenCL mapping on ARM.\n", + drm_arm_ext); + fail = 1; + } + if (!opencl_check_extension(hwdev, image_ext)) { + av_log(hwdev, AV_LOG_VERBOSE, "The %s extension is " + "required for DRM to OpenCL mapping on ARM.\n", + image_ext); + fail = 1; + } + + // clImportMemoryARM() is linked statically. + + if (fail) { + av_log(hwdev, AV_LOG_WARNING, "DRM to OpenCL mapping on ARM " + "not usable.\n"); + priv->drm_arm_mapping_usable = 0; + } else { + priv->drm_arm_mapping_usable = 1; + } + } +#endif + +#undef CL_FUNC + + return 0; +} + +static void opencl_device_uninit(AVHWDeviceContext *hwdev) +{ + OpenCLDeviceContext *priv = hwdev->internal->priv; + cl_int cle; + + if (priv->command_queue) { + cle = clReleaseCommandQueue(priv->command_queue); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to release internal " + "command queue reference: %d.\n", cle); + } + priv->command_queue = NULL; + } +} + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA +static int opencl_filter_intel_media_vaapi_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + // This doesn't exist as a platform extension, so just test whether + // the function we will use for device enumeration exists. + + if (!clGetExtensionFunctionAddressForPlatform(platform_id, + "clGetDeviceIDsFromVA_APIMediaAdapterINTEL")) { + av_log(hwdev, AV_LOG_DEBUG, "Platform %s does not export the " + "VAAPI device enumeration function.\n", platform_name); + return 1; + } else { + return 0; + } +} + +static int opencl_enumerate_intel_media_vaapi_devices(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context) +{ + VADisplay va_display = context; + clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn + clGetDeviceIDsFromVA_APIMediaAdapterINTEL; + cl_int cle; + + clGetDeviceIDsFromVA_APIMediaAdapterINTEL = + clGetExtensionFunctionAddressForPlatform(platform_id, + "clGetDeviceIDsFromVA_APIMediaAdapterINTEL"); + if (!clGetDeviceIDsFromVA_APIMediaAdapterINTEL) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get address of " + "clGetDeviceIDsFromVA_APIMediaAdapterINTEL().\n"); + return AVERROR_UNKNOWN; + } + + cle = clGetDeviceIDsFromVA_APIMediaAdapterINTEL( + platform_id, CL_VA_API_DISPLAY_INTEL, va_display, + CL_PREFERRED_DEVICES_FOR_VA_API_INTEL, 0, NULL, nb_devices); + if (cle == CL_DEVICE_NOT_FOUND) { + av_log(hwdev, AV_LOG_DEBUG, "No VAAPI-supporting devices found " + "on platform \"%s\".\n", platform_name); + *nb_devices = 0; + return 0; + } else if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + return AVERROR_UNKNOWN; + } + + *devices = av_malloc_array(*nb_devices, sizeof(**devices)); + if (!*devices) + return AVERROR(ENOMEM); + + cle = clGetDeviceIDsFromVA_APIMediaAdapterINTEL( + platform_id, CL_VA_API_DISPLAY_INTEL, va_display, + CL_PREFERRED_DEVICES_FOR_VA_API_INTEL, *nb_devices, *devices, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of VAAPI-supporting " + "devices on platform \"%s\": %d.\n", platform_name, cle); + av_freep(devices); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int opencl_filter_intel_media_vaapi_device(AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context) +{ + const char *va_ext = "cl_intel_va_api_media_sharing"; + + if (opencl_check_device_extension(device_id, va_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Device %s does not support the " + "%s extension.\n", device_name, va_ext); + return 1; + } +} +#endif + +#if HAVE_OPENCL_DXVA2 +static int opencl_filter_dxva2_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + const char *dx9_ext = "cl_khr_dx9_media_sharing"; + + if (opencl_check_platform_extension(platform_id, dx9_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Platform %s does not support the " + "%s extension.\n", platform_name, dx9_ext); + return 1; + } +} + +static int opencl_enumerate_dxva2_devices(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context) +{ + IDirect3DDevice9 *device = context; + clGetDeviceIDsFromDX9MediaAdapterKHR_fn + clGetDeviceIDsFromDX9MediaAdapterKHR; + cl_dx9_media_adapter_type_khr media_adapter_type = CL_ADAPTER_D3D9EX_KHR; + cl_int cle; + + clGetDeviceIDsFromDX9MediaAdapterKHR = + clGetExtensionFunctionAddressForPlatform(platform_id, + "clGetDeviceIDsFromDX9MediaAdapterKHR"); + if (!clGetDeviceIDsFromDX9MediaAdapterKHR) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get address of " + "clGetDeviceIDsFromDX9MediaAdapterKHR().\n"); + return AVERROR_UNKNOWN; + } + + cle = clGetDeviceIDsFromDX9MediaAdapterKHR( + platform_id, 1, &media_adapter_type, (void**)&device, + CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, + 0, NULL, nb_devices); + if (cle == CL_DEVICE_NOT_FOUND) { + av_log(hwdev, AV_LOG_DEBUG, "No DXVA2-supporting devices found " + "on platform \"%s\".\n", platform_name); + *nb_devices = 0; + return 0; + } else if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + return AVERROR_UNKNOWN; + } + + *devices = av_malloc_array(*nb_devices, sizeof(**devices)); + if (!*devices) + return AVERROR(ENOMEM); + + cle = clGetDeviceIDsFromDX9MediaAdapterKHR( + platform_id, 1, &media_adapter_type, (void**)&device, + CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, + *nb_devices, *devices, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of DXVA2-supporting " + "devices on platform \"%s\": %d.\n", platform_name, cle); + av_freep(devices); + return AVERROR_UNKNOWN; + } + + return 0; +} +#endif + +#if HAVE_OPENCL_D3D11 +static int opencl_filter_d3d11_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + const char *d3d11_ext = "cl_khr_d3d11_sharing"; + + if (opencl_check_platform_extension(platform_id, d3d11_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Platform %s does not support the " + "%s extension.\n", platform_name, d3d11_ext); + return 1; + } +} + +static int opencl_enumerate_d3d11_devices(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + cl_uint *nb_devices, + cl_device_id **devices, + void *context) +{ + ID3D11Device *device = context; + clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR; + cl_int cle; + + clGetDeviceIDsFromD3D11KHR = + clGetExtensionFunctionAddressForPlatform(platform_id, + "clGetDeviceIDsFromD3D11KHR"); + if (!clGetDeviceIDsFromD3D11KHR) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get address of " + "clGetDeviceIDsFromD3D11KHR().\n"); + return AVERROR_UNKNOWN; + } + + cle = clGetDeviceIDsFromD3D11KHR(platform_id, + CL_D3D11_DEVICE_KHR, device, + CL_PREFERRED_DEVICES_FOR_D3D11_KHR, + 0, NULL, nb_devices); + if (cle == CL_DEVICE_NOT_FOUND) { + av_log(hwdev, AV_LOG_DEBUG, "No D3D11-supporting devices found " + "on platform \"%s\".\n", platform_name); + *nb_devices = 0; + return 0; + } else if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get number of devices " + "on platform \"%s\": %d.\n", platform_name, cle); + return AVERROR_UNKNOWN; + } + + *devices = av_malloc_array(*nb_devices, sizeof(**devices)); + if (!*devices) + return AVERROR(ENOMEM); + + cle = clGetDeviceIDsFromD3D11KHR(platform_id, + CL_D3D11_DEVICE_KHR, device, + CL_PREFERRED_DEVICES_FOR_D3D11_KHR, + *nb_devices, *devices, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to get list of D3D11-supporting " + "devices on platform \"%s\": %d.\n", platform_name, cle); + av_freep(devices); + return AVERROR_UNKNOWN; + } + + return 0; +} +#endif + +#if HAVE_OPENCL_DXVA2 || HAVE_OPENCL_D3D11 +static int opencl_filter_gpu_device(AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context) +{ + cl_device_type device_type; + cl_int cle; + + cle = clGetDeviceInfo(device_id, CL_DEVICE_TYPE, + sizeof(device_type), &device_type, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query device type " + "of device \"%s\".\n", device_name); + return AVERROR_UNKNOWN; + } + if (!(device_type & CL_DEVICE_TYPE_GPU)) { + av_log(hwdev, AV_LOG_DEBUG, "Device %s skipped (not GPU).\n", + device_name); + return 1; + } + + return 0; +} +#endif + +#if HAVE_OPENCL_DRM_ARM +static int opencl_filter_drm_arm_platform(AVHWDeviceContext *hwdev, + cl_platform_id platform_id, + const char *platform_name, + void *context) +{ + const char *drm_arm_ext = "cl_arm_import_memory"; + + if (opencl_check_platform_extension(platform_id, drm_arm_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Platform %s does not support the " + "%s extension.\n", platform_name, drm_arm_ext); + return 1; + } +} + +static int opencl_filter_drm_arm_device(AVHWDeviceContext *hwdev, + cl_device_id device_id, + const char *device_name, + void *context) +{ + const char *drm_arm_ext = "cl_arm_import_memory"; + + if (opencl_check_device_extension(device_id, drm_arm_ext)) { + return 0; + } else { + av_log(hwdev, AV_LOG_DEBUG, "Device %s does not support the " + "%s extension.\n", device_name, drm_arm_ext); + return 1; + } +} +#endif + +static int opencl_device_derive(AVHWDeviceContext *hwdev, + AVHWDeviceContext *src_ctx, + int flags) +{ + int err; + switch (src_ctx->type) { + +#if HAVE_OPENCL_DRM_BEIGNET + case AV_HWDEVICE_TYPE_DRM: + case AV_HWDEVICE_TYPE_VAAPI: + { + // Surface mapping works via DRM PRIME fds with no special + // initialisation required in advance. This just finds the + // Beignet ICD by name. + AVDictionary *opts = NULL; + + err = av_dict_set(&opts, "platform_vendor", "Intel", 0); + if (err >= 0) + err = av_dict_set(&opts, "platform_version", "beignet", 0); + if (err >= 0) { + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = 0, + .context = opts, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_platform, + .enumerate_devices = &opencl_enumerate_devices, + .filter_device = NULL, + }; + err = opencl_device_create_internal(hwdev, &selector, NULL); + } + av_dict_free(&opts); + } + break; +#endif + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + // The generic code automatically attempts to derive from all + // ancestors of the given device, so we can ignore QSV devices here + // and just consider the inner VAAPI device it was derived from. + case AV_HWDEVICE_TYPE_VAAPI: + { + AVVAAPIDeviceContext *src_hwctx = src_ctx->hwctx; + cl_context_properties props[7] = { + CL_CONTEXT_PLATFORM, + 0, + CL_CONTEXT_VA_API_DISPLAY_INTEL, + (intptr_t)src_hwctx->display, + CL_CONTEXT_INTEROP_USER_SYNC, + CL_FALSE, + 0, + }; + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = -1, + .context = src_hwctx->display, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_intel_media_vaapi_platform, + .enumerate_devices = &opencl_enumerate_intel_media_vaapi_devices, + .filter_device = &opencl_filter_intel_media_vaapi_device, + }; + + err = opencl_device_create_internal(hwdev, &selector, props); + } + break; +#endif + +#if HAVE_OPENCL_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + AVDXVA2DeviceContext *src_hwctx = src_ctx->hwctx; + IDirect3DDevice9 *device; + HANDLE device_handle; + HRESULT hr; + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(src_hwctx->devmgr, + &device_handle); + if (FAILED(hr)) { + av_log(hwdev, AV_LOG_ERROR, "Failed to open device handle " + "for Direct3D9 device: %lx.\n", (unsigned long)hr); + err = AVERROR_UNKNOWN; + break; + } + + hr = IDirect3DDeviceManager9_LockDevice(src_hwctx->devmgr, + device_handle, + &device, FALSE); + if (SUCCEEDED(hr)) { + cl_context_properties props[5] = { + CL_CONTEXT_PLATFORM, + 0, + CL_CONTEXT_ADAPTER_D3D9EX_KHR, + (intptr_t)device, + 0, + }; + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = -1, + .context = device, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_dxva2_platform, + .enumerate_devices = &opencl_enumerate_dxva2_devices, + .filter_device = &opencl_filter_gpu_device, + }; + + err = opencl_device_create_internal(hwdev, &selector, props); + + IDirect3DDeviceManager9_UnlockDevice(src_hwctx->devmgr, + device_handle, FALSE); + } else { + av_log(hwdev, AV_LOG_ERROR, "Failed to lock device handle " + "for Direct3D9 device: %lx.\n", (unsigned long)hr); + err = AVERROR_UNKNOWN; + } + + IDirect3DDeviceManager9_CloseDeviceHandle(src_hwctx->devmgr, + device_handle); + } + break; +#endif + +#if HAVE_OPENCL_D3D11 + case AV_HWDEVICE_TYPE_D3D11VA: + { + AVD3D11VADeviceContext *src_hwctx = src_ctx->hwctx; + cl_context_properties props[5] = { + CL_CONTEXT_PLATFORM, + 0, + CL_CONTEXT_D3D11_DEVICE_KHR, + (intptr_t)src_hwctx->device, + 0, + }; + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = -1, + .context = src_hwctx->device, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_d3d11_platform, + .enumerate_devices = &opencl_enumerate_d3d11_devices, + .filter_device = &opencl_filter_gpu_device, + }; + + err = opencl_device_create_internal(hwdev, &selector, props); + } + break; +#endif + +#if HAVE_OPENCL_DRM_ARM + case AV_HWDEVICE_TYPE_DRM: + { + OpenCLDeviceSelector selector = { + .platform_index = -1, + .device_index = -1, + .context = NULL, + .enumerate_platforms = &opencl_enumerate_platforms, + .filter_platform = &opencl_filter_drm_arm_platform, + .enumerate_devices = &opencl_enumerate_devices, + .filter_device = &opencl_filter_drm_arm_device, + }; + + err = opencl_device_create_internal(hwdev, &selector, NULL); + } + break; +#endif + + default: + err = AVERROR(ENOSYS); + break; + } + + return err; +} + +static int opencl_get_plane_format(enum AVPixelFormat pixfmt, + int plane, int width, int height, + cl_image_format *image_format, + cl_image_desc *image_desc) +{ + const AVPixFmtDescriptor *desc; + const AVComponentDescriptor *comp; + int channels = 0, order = 0, depth = 0, step = 0; + int wsub, hsub, alpha; + int c; + + if (plane >= AV_NUM_DATA_POINTERS) + return AVERROR(ENOENT); + + desc = av_pix_fmt_desc_get(pixfmt); + + // Only normal images are allowed. + if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | + AV_PIX_FMT_FLAG_HWACCEL | + AV_PIX_FMT_FLAG_PAL)) + return AVERROR(EINVAL); + + wsub = 1 << desc->log2_chroma_w; + hsub = 1 << desc->log2_chroma_h; + // Subsampled components must be exact. + if (width & wsub - 1 || height & hsub - 1) + return AVERROR(EINVAL); + + for (c = 0; c < desc->nb_components; c++) { + comp = &desc->comp[c]; + if (comp->plane != plane) + continue; + // The step size must be a power of two. + if (comp->step != 1 && comp->step != 2 && + comp->step != 4 && comp->step != 8) + return AVERROR(EINVAL); + // The bits in each component must be packed in the + // most-significant-bits of the relevant bytes. + if (comp->shift + comp->depth != 8 && + comp->shift + comp->depth != 16) + return AVERROR(EINVAL); + // The depth must not vary between components. + if (depth && comp->depth != depth) + return AVERROR(EINVAL); + // If a single data element crosses multiple bytes then + // it must match the native endianness. + if (comp->depth > 8 && + HAVE_BIGENDIAN == !(desc->flags & AV_PIX_FMT_FLAG_BE)) + return AVERROR(EINVAL); + // A single data element must not contain multiple samples + // from the same component. + if (step && comp->step != step) + return AVERROR(EINVAL); + + depth = comp->depth; + order = order * 10 + comp->offset / ((depth + 7) / 8) + 1; + step = comp->step; + alpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA && + c == desc->nb_components - 1); + ++channels; + } + if (channels == 0) + return AVERROR(ENOENT); + + memset(image_format, 0, sizeof(*image_format)); + memset(image_desc, 0, sizeof(*image_desc)); + image_desc->image_type = CL_MEM_OBJECT_IMAGE2D; + + if (plane == 0 || alpha) { + image_desc->image_width = width; + image_desc->image_height = height; + image_desc->image_row_pitch = step * width; + } else { + image_desc->image_width = width / wsub; + image_desc->image_height = height / hsub; + image_desc->image_row_pitch = step * width / wsub; + } + + if (depth <= 8) { + image_format->image_channel_data_type = CL_UNORM_INT8; + } else { + if (depth <= 16) + image_format->image_channel_data_type = CL_UNORM_INT16; + else + return AVERROR(EINVAL); + } + +#define CHANNEL_ORDER(order, type) \ + case order: image_format->image_channel_order = type; break; + switch (order) { + CHANNEL_ORDER(1, CL_R); + CHANNEL_ORDER(12, CL_RG); + CHANNEL_ORDER(1234, CL_RGBA); + CHANNEL_ORDER(2341, CL_ARGB); + CHANNEL_ORDER(3214, CL_BGRA); +#ifdef CL_ABGR + CHANNEL_ORDER(4321, CL_ABGR); +#endif + default: + return AVERROR(EINVAL); + } +#undef CHANNEL_ORDER + + return 0; +} + +static int opencl_frames_get_constraints(AVHWDeviceContext *hwdev, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + AVOpenCLDeviceContext *hwctx = hwdev->hwctx; + cl_uint nb_image_formats; + cl_image_format *image_formats = NULL; + cl_int cle; + enum AVPixelFormat pix_fmt; + int err, pix_fmts_found; + size_t max_width, max_height; + + cle = clGetDeviceInfo(hwctx->device_id, CL_DEVICE_IMAGE2D_MAX_WIDTH, + sizeof(max_width), &max_width, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query maximum " + "supported image width: %d.\n", cle); + } else { + constraints->max_width = max_width; + } + cle = clGetDeviceInfo(hwctx->device_id, CL_DEVICE_IMAGE2D_MAX_HEIGHT, + sizeof(max_height), &max_height, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query maximum " + "supported image height: %d.\n", cle); + } else { + constraints->max_height = max_height; + } + av_log(hwdev, AV_LOG_DEBUG, "Maximum supported image size %dx%d.\n", + constraints->max_width, constraints->max_height); + + cle = clGetSupportedImageFormats(hwctx->context, + CL_MEM_READ_WRITE, + CL_MEM_OBJECT_IMAGE2D, + 0, NULL, &nb_image_formats); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query supported " + "image formats: %d.\n", cle); + err = AVERROR(ENOSYS); + goto fail; + } + if (nb_image_formats == 0) { + av_log(hwdev, AV_LOG_ERROR, "No image support in OpenCL " + "driver (zero supported image formats).\n"); + err = AVERROR(ENOSYS); + goto fail; + } + + image_formats = + av_malloc_array(nb_image_formats, sizeof(*image_formats)); + if (!image_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + + cle = clGetSupportedImageFormats(hwctx->context, + CL_MEM_READ_WRITE, + CL_MEM_OBJECT_IMAGE2D, + nb_image_formats, + image_formats, NULL); + if (cle != CL_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query supported " + "image formats: %d.\n", cle); + err = AVERROR(ENOSYS); + goto fail; + } + + pix_fmts_found = 0; + for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) { + cl_image_format image_format; + cl_image_desc image_desc; + int plane, i; + + for (plane = 0;; plane++) { + err = opencl_get_plane_format(pix_fmt, plane, 0, 0, + &image_format, + &image_desc); + if (err < 0) + break; + + for (i = 0; i < nb_image_formats; i++) { + if (image_formats[i].image_channel_order == + image_format.image_channel_order && + image_formats[i].image_channel_data_type == + image_format.image_channel_data_type) + break; + } + if (i == nb_image_formats) { + err = AVERROR(EINVAL); + break; + } + } + if (err != AVERROR(ENOENT)) + continue; + + av_log(hwdev, AV_LOG_DEBUG, "Format %s supported.\n", + av_get_pix_fmt_name(pix_fmt)); + + err = av_reallocp_array(&constraints->valid_sw_formats, + pix_fmts_found + 2, + sizeof(*constraints->valid_sw_formats)); + if (err < 0) + goto fail; + constraints->valid_sw_formats[pix_fmts_found] = pix_fmt; + constraints->valid_sw_formats[pix_fmts_found + 1] = + AV_PIX_FMT_NONE; + ++pix_fmts_found; + } + + av_freep(&image_formats); + + constraints->valid_hw_formats = + av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + constraints->valid_hw_formats[0] = AV_PIX_FMT_OPENCL; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; + +fail: + av_freep(&image_formats); + return err; +} + +static void opencl_pool_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *hwfc = opaque; + AVOpenCLFrameDescriptor *desc = (AVOpenCLFrameDescriptor*)data; + cl_int cle; + int p; + + for (p = 0; p < desc->nb_planes; p++) { + cle = clReleaseMemObject(desc->planes[p]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release plane %d: " + "%d.\n", p, cle); + } + } + + av_free(desc); +} + +static AVBufferRef *opencl_pool_alloc(void *opaque, int size) +{ + AVHWFramesContext *hwfc = opaque; + AVOpenCLDeviceContext *hwctx = hwfc->device_ctx->hwctx; + AVOpenCLFrameDescriptor *desc; + cl_int cle; + cl_mem image; + cl_image_format image_format; + cl_image_desc image_desc; + int err, p; + AVBufferRef *ref; + + desc = av_mallocz(sizeof(*desc)); + if (!desc) + return NULL; + + for (p = 0;; p++) { + err = opencl_get_plane_format(hwfc->sw_format, p, + hwfc->width, hwfc->height, + &image_format, &image_desc); + if (err == AVERROR(ENOENT)) + break; + if (err < 0) + goto fail; + + // For generic image objects, the pitch is determined by the + // implementation. + image_desc.image_row_pitch = 0; + + image = clCreateImage(hwctx->context, CL_MEM_READ_WRITE, + &image_format, &image_desc, NULL, &cle); + if (!image) { + av_log(hwfc, AV_LOG_ERROR, "Failed to create image for " + "plane %d: %d.\n", p, cle); + goto fail; + } + + desc->planes[p] = image; + } + + desc->nb_planes = p; + + ref = av_buffer_create((uint8_t*)desc, sizeof(*desc), + &opencl_pool_free, hwfc, 0); + if (!ref) + goto fail; + + return ref; + +fail: + for (p = 0; desc->planes[p]; p++) + clReleaseMemObject(desc->planes[p]); + av_free(desc); + return NULL; +} + +static int opencl_frames_init_command_queue(AVHWFramesContext *hwfc) +{ + AVOpenCLFramesContext *hwctx = hwfc->hwctx; + OpenCLDeviceContext *devpriv = hwfc->device_ctx->internal->priv; + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_int cle; + + priv->command_queue = hwctx->command_queue ? hwctx->command_queue + : devpriv->command_queue; + cle = clRetainCommandQueue(priv->command_queue); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to retain frame " + "command queue: %d.\n", cle); + return AVERROR(EIO); + } + + return 0; +} + +static int opencl_frames_init(AVHWFramesContext *hwfc) +{ + if (!hwfc->pool) { + hwfc->internal->pool_internal = + av_buffer_pool_init2(sizeof(cl_mem), hwfc, + &opencl_pool_alloc, NULL); + if (!hwfc->internal->pool_internal) + return AVERROR(ENOMEM); + } + + return opencl_frames_init_command_queue(hwfc); +} + +static void opencl_frames_uninit(AVHWFramesContext *hwfc) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_int cle; + +#if HAVE_OPENCL_DXVA2 || HAVE_OPENCL_D3D11 + int i, p; + for (i = 0; i < priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &priv->mapped_frames[i]; + for (p = 0; p < desc->nb_planes; p++) { + cle = clReleaseMemObject(desc->planes[p]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release mapped " + "frame object (frame %d plane %d): %d.\n", + i, p, cle); + } + } + } + av_freep(&priv->mapped_frames); +#endif + + if (priv->command_queue) { + cle = clReleaseCommandQueue(priv->command_queue); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release frame " + "command queue: %d.\n", cle); + } + priv->command_queue = NULL; + } +} + +static int opencl_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) +{ + AVOpenCLFrameDescriptor *desc; + int p; + + frame->buf[0] = av_buffer_pool_get(hwfc->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + desc = (AVOpenCLFrameDescriptor*)frame->buf[0]->data; + + for (p = 0; p < desc->nb_planes; p++) + frame->data[p] = (uint8_t*)desc->planes[p]; + + frame->format = AV_PIX_FMT_OPENCL; + frame->width = hwfc->width; + frame->height = hwfc->height; + + return 0; +} + +static int opencl_transfer_get_formats(AVHWFramesContext *hwfc, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = hwfc->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + return 0; +} + +static int opencl_wait_events(AVHWFramesContext *hwfc, + cl_event *events, int nb_events) +{ + cl_int cle; + int i; + + cle = clWaitForEvents(nb_events, events); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to wait for event " + "completion: %d.\n", cle); + return AVERROR(EIO); + } + + for (i = 0; i < nb_events; i++) { + cle = clReleaseEvent(events[i]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release " + "event: %d.\n", cle); + } + } + + return 0; +} + +static int opencl_transfer_data_from(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_image_format image_format; + cl_image_desc image_desc; + cl_int cle; + size_t origin[3] = { 0, 0, 0 }; + size_t region[3]; + cl_event events[AV_NUM_DATA_POINTERS]; + int err, p; + + if (dst->format != hwfc->sw_format) + return AVERROR(EINVAL); + + for (p = 0;; p++) { + err = opencl_get_plane_format(hwfc->sw_format, p, + src->width, src->height, + &image_format, &image_desc); + if (err < 0) { + if (err == AVERROR(ENOENT)) + err = 0; + break; + } + + if (!dst->data[p]) { + av_log(hwfc, AV_LOG_ERROR, "Plane %d missing on " + "destination frame for transfer.\n", p); + err = AVERROR(EINVAL); + break; + } + + region[0] = image_desc.image_width; + region[1] = image_desc.image_height; + region[2] = 1; + + cle = clEnqueueReadImage(priv->command_queue, + (cl_mem)src->data[p], + CL_FALSE, origin, region, + dst->linesize[p], 0, + dst->data[p], + 0, NULL, &events[p]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to enqueue read of " + "OpenCL image plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + break; + } + } + + opencl_wait_events(hwfc, events, p); + + return err; +} + +static int opencl_transfer_data_to(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_image_format image_format; + cl_image_desc image_desc; + cl_int cle; + size_t origin[3] = { 0, 0, 0 }; + size_t region[3]; + cl_event events[AV_NUM_DATA_POINTERS]; + int err, p; + + if (src->format != hwfc->sw_format) + return AVERROR(EINVAL); + + for (p = 0;; p++) { + err = opencl_get_plane_format(hwfc->sw_format, p, + src->width, src->height, + &image_format, &image_desc); + if (err < 0) { + if (err == AVERROR(ENOENT)) + err = 0; + break; + } + + if (!src->data[p]) { + av_log(hwfc, AV_LOG_ERROR, "Plane %d missing on " + "source frame for transfer.\n", p); + err = AVERROR(EINVAL); + break; + } + + region[0] = image_desc.image_width; + region[1] = image_desc.image_height; + region[2] = 1; + + cle = clEnqueueWriteImage(priv->command_queue, + (cl_mem)dst->data[p], + CL_FALSE, origin, region, + src->linesize[p], 0, + src->data[p], + 0, NULL, &events[p]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to enqueue write of " + "OpenCL image plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + break; + } + } + + opencl_wait_events(hwfc, events, p); + + return err; +} + +typedef struct OpenCLMapping { + // The mapped addresses for each plane. + // The destination frame is not available when we unmap, so these + // need to be stored separately. + void *address[AV_NUM_DATA_POINTERS]; +} OpenCLMapping; + +static void opencl_unmap_frame(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + OpenCLMapping *map = hwmap->priv; + cl_event events[AV_NUM_DATA_POINTERS]; + int p, e; + cl_int cle; + + for (p = e = 0; p < FF_ARRAY_ELEMS(map->address); p++) { + if (!map->address[p]) + break; + + cle = clEnqueueUnmapMemObject(priv->command_queue, + (cl_mem)hwmap->source->data[p], + map->address[p], + 0, NULL, &events[e]); + if (cle != CL_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to unmap OpenCL " + "image plane %d: %d.\n", p, cle); + } + ++e; + } + + opencl_wait_events(hwfc, events, e); + + av_free(map); +} + +static int opencl_map_frame(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + OpenCLFramesContext *priv = hwfc->internal->priv; + cl_map_flags map_flags; + cl_image_format image_format; + cl_image_desc image_desc; + cl_int cle; + OpenCLMapping *map; + size_t origin[3] = { 0, 0, 0 }; + size_t region[3]; + size_t row_pitch; + cl_event events[AV_NUM_DATA_POINTERS]; + int err, p; + + av_assert0(hwfc->sw_format == dst->format); + + if (flags & AV_HWFRAME_MAP_OVERWRITE && + !(flags & AV_HWFRAME_MAP_READ)) { + // This is mutually exclusive with the read/write flags, so + // there is no way to map with read here. + map_flags = CL_MAP_WRITE_INVALIDATE_REGION; + } else { + map_flags = 0; + if (flags & AV_HWFRAME_MAP_READ) + map_flags |= CL_MAP_READ; + if (flags & AV_HWFRAME_MAP_WRITE) + map_flags |= CL_MAP_WRITE; + } + + map = av_mallocz(sizeof(*map)); + if (!map) + return AVERROR(ENOMEM); + + for (p = 0;; p++) { + err = opencl_get_plane_format(hwfc->sw_format, p, + src->width, src->height, + &image_format, &image_desc); + if (err == AVERROR(ENOENT)) + break; + if (err < 0) + goto fail; + + region[0] = image_desc.image_width; + region[1] = image_desc.image_height; + region[2] = 1; + + map->address[p] = + clEnqueueMapImage(priv->command_queue, + (cl_mem)src->data[p], + CL_FALSE, map_flags, origin, region, + &row_pitch, NULL, 0, NULL, + &events[p], &cle); + if (!map->address[p]) { + av_log(hwfc, AV_LOG_ERROR, "Failed to map OpenCL " + "image plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + goto fail; + } + + dst->data[p] = map->address[p]; + + av_log(hwfc, AV_LOG_DEBUG, "Map plane %d (%p -> %p).\n", + p, src->data[p], dst->data[p]); + } + + err = opencl_wait_events(hwfc, events, p); + if (err < 0) + goto fail; + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + &opencl_unmap_frame, map); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + for (p = 0; p < AV_NUM_DATA_POINTERS; p++) { + if (!map->address[p]) + break; + clEnqueueUnmapMemObject(priv->command_queue, + (cl_mem)src->data[p], + map->address[p], + 0, NULL, &events[p]); + } + if (p > 0) + opencl_wait_events(hwfc, events, p); + av_freep(&map); + return err; +} + +#if HAVE_OPENCL_DRM_BEIGNET + +typedef struct DRMBeignetToOpenCLMapping { + AVFrame *drm_frame; + AVDRMFrameDescriptor *drm_desc; + + AVOpenCLFrameDescriptor frame; +} DRMBeignetToOpenCLMapping; + +static void opencl_unmap_from_drm_beignet(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + DRMBeignetToOpenCLMapping *mapping = hwmap->priv; + cl_int cle; + int i; + + for (i = 0; i < mapping->frame.nb_planes; i++) { + cle = clReleaseMemObject(mapping->frame.planes[i]); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release CL image " + "of plane %d of DRM frame: %d.\n", i, cle); + } + } + + av_free(mapping); +} + +static int opencl_map_from_drm_beignet(AVHWFramesContext *dst_fc, + AVFrame *dst, const AVFrame *src, + int flags) +{ + AVOpenCLDeviceContext *hwctx = dst_fc->device_ctx->hwctx; + OpenCLDeviceContext *priv = dst_fc->device_ctx->internal->priv; + DRMBeignetToOpenCLMapping *mapping; + const AVDRMFrameDescriptor *desc; + cl_int cle; + int err, i, j, p; + + desc = (const AVDRMFrameDescriptor*)src->data[0]; + + mapping = av_mallocz(sizeof(*mapping)); + if (!mapping) + return AVERROR(ENOMEM); + + p = 0; + for (i = 0; i < desc->nb_layers; i++) { + const AVDRMLayerDescriptor *layer = &desc->layers[i]; + for (j = 0; j < layer->nb_planes; j++) { + const AVDRMPlaneDescriptor *plane = &layer->planes[j]; + const AVDRMObjectDescriptor *object = + &desc->objects[plane->object_index]; + + cl_import_image_info_intel image_info = { + .fd = object->fd, + .size = object->size, + .type = CL_MEM_OBJECT_IMAGE2D, + .offset = plane->offset, + .row_pitch = plane->pitch, + }; + cl_image_desc image_desc; + + err = opencl_get_plane_format(dst_fc->sw_format, p, + src->width, src->height, + &image_info.fmt, + &image_desc); + if (err < 0) { + av_log(dst_fc, AV_LOG_ERROR, "DRM frame layer %d " + "plane %d is not representable in OpenCL: %d.\n", + i, j, err); + goto fail; + } + image_info.width = image_desc.image_width; + image_info.height = image_desc.image_height; + + mapping->frame.planes[p] = + priv->clCreateImageFromFdINTEL(hwctx->context, + &image_info, &cle); + if (!mapping->frame.planes[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL image " + "from layer %d plane %d of DRM frame: %d.\n", + i, j, cle); + err = AVERROR(EIO); + goto fail; + } + + dst->data[p] = (uint8_t*)mapping->frame.planes[p]; + mapping->frame.nb_planes = ++p; + } + } + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_drm_beignet, + mapping); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + for (p = 0; p < mapping->frame.nb_planes; p++) { + if (mapping->frame.planes[p]) + clReleaseMemObject(mapping->frame.planes[p]); + } + av_free(mapping); + return err; +} + +#if HAVE_OPENCL_VAAPI_BEIGNET + +static int opencl_map_from_vaapi(AVHWFramesContext *dst_fc, + AVFrame *dst, const AVFrame *src, + int flags) +{ + AVFrame *tmp; + int err; + + tmp = av_frame_alloc(); + if (!tmp) + return AVERROR(ENOMEM); + + tmp->format = AV_PIX_FMT_DRM_PRIME; + + err = av_hwframe_map(tmp, src, flags); + if (err < 0) + goto fail; + + err = opencl_map_from_drm_beignet(dst_fc, dst, tmp, flags); + if (err < 0) + goto fail; + + err = ff_hwframe_map_replace(dst, src); + +fail: + av_frame_free(&tmp); + return err; +} + +#endif /* HAVE_OPENCL_VAAPI_BEIGNET */ +#endif /* HAVE_OPENCL_DRM_BEIGNET */ + +static inline cl_mem_flags opencl_mem_flags_for_mapping(int map_flags) +{ + if ((map_flags & AV_HWFRAME_MAP_READ) && + (map_flags & AV_HWFRAME_MAP_WRITE)) + return CL_MEM_READ_WRITE; + else if (map_flags & AV_HWFRAME_MAP_READ) + return CL_MEM_READ_ONLY; + else if (map_flags & AV_HWFRAME_MAP_WRITE) + return CL_MEM_WRITE_ONLY; + else + return 0; +} + +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + +static void opencl_unmap_from_qsv(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVOpenCLFrameDescriptor *desc = hwmap->priv; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + cl_event event; + cl_int cle; + int p; + + av_log(dst_fc, AV_LOG_DEBUG, "Unmap QSV/VAAPI surface from OpenCL.\n"); + + cle = device_priv->clEnqueueReleaseVA_APIMediaSurfacesINTEL( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release surface " + "handles: %d.\n", cle); + } + + opencl_wait_events(dst_fc, &event, 1); + + for (p = 0; p < desc->nb_planes; p++) { + cle = clReleaseMemObject(desc->planes[p]); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release CL " + "image of plane %d of QSV/VAAPI surface: %d\n", + p, cle); + } + } + + av_free(desc); +} + +static int opencl_map_from_qsv(AVHWFramesContext *dst_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVHWFramesContext *src_fc = + (AVHWFramesContext*)src->hw_frames_ctx->data; + AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + AVOpenCLFrameDescriptor *desc; + VASurfaceID va_surface; + cl_mem_flags cl_flags; + cl_event event; + cl_int cle; + int err, p; + +#if CONFIG_LIBMFX + if (src->format == AV_PIX_FMT_QSV) { + mfxFrameSurface1 *mfx_surface = (mfxFrameSurface1*)src->data[3]; + va_surface = *(VASurfaceID*)mfx_surface->Data.MemId; + } else +#endif + if (src->format == AV_PIX_FMT_VAAPI) { + va_surface = (VASurfaceID)(uintptr_t)src->data[3]; + } else { + return AVERROR(ENOSYS); + } + + cl_flags = opencl_mem_flags_for_mapping(flags); + if (!cl_flags) + return AVERROR(EINVAL); + + av_log(src_fc, AV_LOG_DEBUG, "Map QSV/VAAPI surface %#x to " + "OpenCL.\n", va_surface); + + desc = av_mallocz(sizeof(*desc)); + if (!desc) + return AVERROR(ENOMEM); + + // The cl_intel_va_api_media_sharing extension only supports NV12 + // surfaces, so for now there are always exactly two planes. + desc->nb_planes = 2; + + for (p = 0; p < desc->nb_planes; p++) { + desc->planes[p] = + device_priv->clCreateFromVA_APIMediaSurfaceINTEL( + dst_dev->context, cl_flags, &va_surface, p, &cle); + if (!desc->planes[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL " + "image from plane %d of QSV/VAAPI surface " + "%#x: %d.\n", p, va_surface, cle); + err = AVERROR(EIO); + goto fail; + } + + dst->data[p] = (uint8_t*)desc->planes[p]; + } + + cle = device_priv->clEnqueueAcquireVA_APIMediaSurfacesINTEL( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to acquire surface " + "handles: %d.\n", cle); + err = AVERROR(EIO); + goto fail; + } + + err = opencl_wait_events(dst_fc, &event, 1); + if (err < 0) + goto fail; + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_qsv, desc); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + for (p = 0; p < desc->nb_planes; p++) + if (desc->planes[p]) + clReleaseMemObject(desc->planes[p]); + av_freep(&desc); + return err; +} + +#endif + +#if HAVE_OPENCL_DXVA2 + +static void opencl_unmap_from_dxva2(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVOpenCLFrameDescriptor *desc = hwmap->priv; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->device_ctx->internal->priv; + cl_event event; + cl_int cle; + + av_log(dst_fc, AV_LOG_DEBUG, "Unmap DXVA2 surface from OpenCL.\n"); + + cle = device_priv->clEnqueueReleaseDX9MediaSurfacesKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release surface " + "handle: %d.\n", cle); + return; + } + + opencl_wait_events(dst_fc, &event, 1); +} + +static int opencl_map_from_dxva2(AVHWFramesContext *dst_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVHWFramesContext *src_fc = + (AVHWFramesContext*)src->hw_frames_ctx->data; + AVDXVA2FramesContext *src_hwctx = src_fc->hwctx; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + AVOpenCLFrameDescriptor *desc; + cl_event event; + cl_int cle; + int err, i; + + av_log(dst_fc, AV_LOG_DEBUG, "Map DXVA2 surface %p to " + "OpenCL.\n", src->data[3]); + + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + if (src_hwctx->surfaces[i] == (IDirect3DSurface9*)src->data[3]) + break; + } + if (i >= src_hwctx->nb_surfaces) { + av_log(dst_fc, AV_LOG_ERROR, "Trying to map from a surface which " + "is not in the mapped frames context.\n"); + return AVERROR(EINVAL); + } + + desc = &frames_priv->mapped_frames[i]; + + cle = device_priv->clEnqueueAcquireDX9MediaSurfacesKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to acquire surface " + "handle: %d.\n", cle); + return AVERROR(EIO); + } + + err = opencl_wait_events(dst_fc, &event, 1); + if (err < 0) + goto fail; + + for (i = 0; i < desc->nb_planes; i++) + dst->data[i] = (uint8_t*)desc->planes[i]; + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_dxva2, desc); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + cle = device_priv->clEnqueueReleaseDX9MediaSurfacesKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle == CL_SUCCESS) + opencl_wait_events(dst_fc, &event, 1); + return err; +} + +static int opencl_frames_derive_from_dxva2(AVHWFramesContext *dst_fc, + AVHWFramesContext *src_fc, int flags) +{ + AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + AVDXVA2FramesContext *src_hwctx = src_fc->hwctx; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + cl_mem_flags cl_flags; + cl_int cle; + int err, i, p, nb_planes; + + if (src_fc->sw_format != AV_PIX_FMT_NV12) { + av_log(dst_fc, AV_LOG_ERROR, "Only NV12 textures are supported " + "for DXVA2 to OpenCL mapping.\n"); + return AVERROR(EINVAL); + } + nb_planes = 2; + + if (src_fc->initial_pool_size == 0) { + av_log(dst_fc, AV_LOG_ERROR, "Only fixed-size pools are supported " + "for DXVA2 to OpenCL mapping.\n"); + return AVERROR(EINVAL); + } + + cl_flags = opencl_mem_flags_for_mapping(flags); + if (!cl_flags) + return AVERROR(EINVAL); + + frames_priv->nb_mapped_frames = src_hwctx->nb_surfaces; + + frames_priv->mapped_frames = + av_mallocz_array(frames_priv->nb_mapped_frames, + sizeof(*frames_priv->mapped_frames)); + if (!frames_priv->mapped_frames) + return AVERROR(ENOMEM); + + for (i = 0; i < frames_priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &frames_priv->mapped_frames[i]; + cl_dx9_surface_info_khr surface_info = { + .resource = src_hwctx->surfaces[i], + .shared_handle = NULL, + }; + desc->nb_planes = nb_planes; + for (p = 0; p < nb_planes; p++) { + desc->planes[p] = + device_priv->clCreateFromDX9MediaSurfaceKHR( + dst_dev->context, cl_flags, + device_priv->dx9_media_adapter_type, + &surface_info, p, &cle); + if (!desc->planes[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL " + "image from plane %d of DXVA2 surface %d: %d.\n", + p, i, cle); + err = AVERROR(EIO); + goto fail; + } + } + } + + return 0; + +fail: + for (i = 0; i < frames_priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &frames_priv->mapped_frames[i]; + for (p = 0; p < desc->nb_planes; p++) { + if (desc->planes[p]) + clReleaseMemObject(desc->planes[p]); + } + } + av_freep(&frames_priv->mapped_frames); + frames_priv->nb_mapped_frames = 0; + return err; +} + +#endif + +#if HAVE_OPENCL_D3D11 + +static void opencl_unmap_from_d3d11(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVOpenCLFrameDescriptor *desc = hwmap->priv; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->device_ctx->internal->priv; + cl_event event; + cl_int cle; + + cle = device_priv->clEnqueueReleaseD3D11ObjectsKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to release surface " + "handle: %d.\n", cle); + } + + opencl_wait_events(dst_fc, &event, 1); +} + +static int opencl_map_from_d3d11(AVHWFramesContext *dst_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + AVOpenCLFrameDescriptor *desc; + cl_event event; + cl_int cle; + int err, index, i; + + index = (intptr_t)src->data[1]; + if (index >= frames_priv->nb_mapped_frames) { + av_log(dst_fc, AV_LOG_ERROR, "Texture array index out of range for " + "mapping: %d >= %d.\n", index, frames_priv->nb_mapped_frames); + return AVERROR(EINVAL); + } + + av_log(dst_fc, AV_LOG_DEBUG, "Map D3D11 texture %d to OpenCL.\n", + index); + + desc = &frames_priv->mapped_frames[index]; + + cle = device_priv->clEnqueueAcquireD3D11ObjectsKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle != CL_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to acquire surface " + "handle: %d.\n", cle); + return AVERROR(EIO); + } + + err = opencl_wait_events(dst_fc, &event, 1); + if (err < 0) + goto fail; + + for (i = 0; i < desc->nb_planes; i++) + dst->data[i] = (uint8_t*)desc->planes[i]; + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_d3d11, desc); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + cle = device_priv->clEnqueueReleaseD3D11ObjectsKHR( + frames_priv->command_queue, desc->nb_planes, desc->planes, + 0, NULL, &event); + if (cle == CL_SUCCESS) + opencl_wait_events(dst_fc, &event, 1); + return err; +} + +static int opencl_frames_derive_from_d3d11(AVHWFramesContext *dst_fc, + AVHWFramesContext *src_fc, int flags) +{ + AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + AVD3D11VAFramesContext *src_hwctx = src_fc->hwctx; + OpenCLDeviceContext *device_priv = dst_fc->device_ctx->internal->priv; + OpenCLFramesContext *frames_priv = dst_fc->internal->priv; + cl_mem_flags cl_flags; + cl_int cle; + int err, i, p, nb_planes; + + if (src_fc->sw_format != AV_PIX_FMT_NV12) { + av_log(dst_fc, AV_LOG_ERROR, "Only NV12 textures are supported " + "for D3D11 to OpenCL mapping.\n"); + return AVERROR(EINVAL); + } + nb_planes = 2; + + if (src_fc->initial_pool_size == 0) { + av_log(dst_fc, AV_LOG_ERROR, "Only fixed-size pools are supported " + "for D3D11 to OpenCL mapping.\n"); + return AVERROR(EINVAL); + } + + cl_flags = opencl_mem_flags_for_mapping(flags); + if (!cl_flags) + return AVERROR(EINVAL); + + frames_priv->nb_mapped_frames = src_fc->initial_pool_size; + + frames_priv->mapped_frames = + av_mallocz_array(frames_priv->nb_mapped_frames, + sizeof(*frames_priv->mapped_frames)); + if (!frames_priv->mapped_frames) + return AVERROR(ENOMEM); + + for (i = 0; i < frames_priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &frames_priv->mapped_frames[i]; + desc->nb_planes = nb_planes; + for (p = 0; p < nb_planes; p++) { + UINT subresource = 2 * i + p; + + desc->planes[p] = + device_priv->clCreateFromD3D11Texture2DKHR( + dst_dev->context, cl_flags, src_hwctx->texture, + subresource, &cle); + if (!desc->planes[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL " + "image from plane %d of D3D texture " + "index %d (subresource %u): %d.\n", + p, i, (unsigned int)subresource, cle); + err = AVERROR(EIO); + goto fail; + } + } + } + + return 0; + +fail: + for (i = 0; i < frames_priv->nb_mapped_frames; i++) { + AVOpenCLFrameDescriptor *desc = &frames_priv->mapped_frames[i]; + for (p = 0; p < desc->nb_planes; p++) { + if (desc->planes[p]) + clReleaseMemObject(desc->planes[p]); + } + } + av_freep(&frames_priv->mapped_frames); + frames_priv->nb_mapped_frames = 0; + return err; +} + +#endif + +#if HAVE_OPENCL_DRM_ARM + +typedef struct DRMARMtoOpenCLMapping { + int nb_objects; + cl_mem object_buffers[AV_DRM_MAX_PLANES]; + int nb_planes; + cl_mem plane_images[AV_DRM_MAX_PLANES]; +} DRMARMtoOpenCLMapping; + +static void opencl_unmap_from_drm_arm(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + DRMARMtoOpenCLMapping *mapping = hwmap->priv; + int i; + + for (i = 0; i < mapping->nb_planes; i++) + clReleaseMemObject(mapping->plane_images[i]); + + for (i = 0; i < mapping->nb_objects; i++) + clReleaseMemObject(mapping->object_buffers[i]); + + av_free(mapping); +} + +static int opencl_map_from_drm_arm(AVHWFramesContext *dst_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVHWFramesContext *src_fc = + (AVHWFramesContext*)src->hw_frames_ctx->data; + AVOpenCLDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + const AVDRMFrameDescriptor *desc; + DRMARMtoOpenCLMapping *mapping = NULL; + cl_mem_flags cl_flags; + const cl_import_properties_arm props[3] = { + CL_IMPORT_TYPE_ARM, CL_IMPORT_TYPE_DMA_BUF_ARM, 0, + }; + cl_int cle; + int err, i, j; + + desc = (const AVDRMFrameDescriptor*)src->data[0]; + + cl_flags = opencl_mem_flags_for_mapping(flags); + if (!cl_flags) + return AVERROR(EINVAL); + + mapping = av_mallocz(sizeof(*mapping)); + if (!mapping) + return AVERROR(ENOMEM); + + mapping->nb_objects = desc->nb_objects; + for (i = 0; i < desc->nb_objects; i++) { + int fd = desc->objects[i].fd; + + av_log(dst_fc, AV_LOG_DEBUG, "Map DRM PRIME fd %d to OpenCL.\n", fd); + + if (desc->objects[i].format_modifier) { + av_log(dst_fc, AV_LOG_DEBUG, "Warning: object %d fd %d has " + "nonzero format modifier %"PRId64", result may not " + "be as expected.\n", i, fd, + desc->objects[i].format_modifier); + } + + mapping->object_buffers[i] = + clImportMemoryARM(dst_dev->context, cl_flags, props, + &fd, desc->objects[i].size, &cle); + if (!mapping->object_buffers[i]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL buffer " + "from object %d (fd %d, size %"SIZE_SPECIFIER") of DRM frame: %d.\n", + i, fd, desc->objects[i].size, cle); + err = AVERROR(EIO); + goto fail; + } + } + + mapping->nb_planes = 0; + for (i = 0; i < desc->nb_layers; i++) { + const AVDRMLayerDescriptor *layer = &desc->layers[i]; + + for (j = 0; j < layer->nb_planes; j++) { + const AVDRMPlaneDescriptor *plane = &layer->planes[j]; + cl_mem plane_buffer; + cl_image_format image_format; + cl_image_desc image_desc; + cl_buffer_region region; + int p = mapping->nb_planes; + + err = opencl_get_plane_format(src_fc->sw_format, p, + src_fc->width, src_fc->height, + &image_format, &image_desc); + if (err < 0) { + av_log(dst_fc, AV_LOG_ERROR, "Invalid plane %d (DRM " + "layer %d plane %d): %d.\n", p, i, j, err); + goto fail; + } + + region.origin = plane->offset; + region.size = image_desc.image_row_pitch * + image_desc.image_height; + + plane_buffer = + clCreateSubBuffer(mapping->object_buffers[plane->object_index], + cl_flags, + CL_BUFFER_CREATE_TYPE_REGION, + ®ion, &cle); + if (!plane_buffer) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create sub-buffer " + "for plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + goto fail; + } + + image_desc.buffer = plane_buffer; + + mapping->plane_images[p] = + clCreateImage(dst_dev->context, cl_flags, + &image_format, &image_desc, NULL, &cle); + + // Unreference the sub-buffer immediately - we don't need it + // directly and a reference is held by the image. + clReleaseMemObject(plane_buffer); + + if (!mapping->plane_images[p]) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create image " + "for plane %d: %d.\n", p, cle); + err = AVERROR(EIO); + goto fail; + } + + ++mapping->nb_planes; + } + } + + for (i = 0; i < mapping->nb_planes; i++) + dst->data[i] = (uint8_t*)mapping->plane_images[i]; + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &opencl_unmap_from_drm_arm, mapping); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail: + for (i = 0; i < mapping->nb_planes; i++) { + clReleaseMemObject(mapping->plane_images[i]); + } + for (i = 0; i < mapping->nb_objects; i++) { + if (mapping->object_buffers[i]) + clReleaseMemObject(mapping->object_buffers[i]); + } + av_free(mapping); + return err; +} + +#endif + +static int opencl_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + av_assert0(src->format == AV_PIX_FMT_OPENCL); + if (hwfc->sw_format != dst->format) + return AVERROR(ENOSYS); + return opencl_map_frame(hwfc, dst, src, flags); +} + +static int opencl_map_to(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + av_unused OpenCLDeviceContext *priv = hwfc->device_ctx->internal->priv; + av_assert0(dst->format == AV_PIX_FMT_OPENCL); + switch (src->format) { +#if HAVE_OPENCL_DRM_BEIGNET + case AV_PIX_FMT_DRM_PRIME: + if (priv->beignet_drm_mapping_usable) + return opencl_map_from_drm_beignet(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_VAAPI_BEIGNET + case AV_PIX_FMT_VAAPI: + if (priv->beignet_drm_mapping_usable) + return opencl_map_from_vaapi(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + case AV_PIX_FMT_QSV: + case AV_PIX_FMT_VAAPI: + if (priv->qsv_mapping_usable) + return opencl_map_from_qsv(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_DXVA2 + case AV_PIX_FMT_DXVA2_VLD: + if (priv->dxva2_mapping_usable) + return opencl_map_from_dxva2(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_D3D11 + case AV_PIX_FMT_D3D11: + if (priv->d3d11_mapping_usable) + return opencl_map_from_d3d11(hwfc, dst, src, flags); +#endif +#if HAVE_OPENCL_DRM_ARM + case AV_PIX_FMT_DRM_PRIME: + if (priv->drm_arm_mapping_usable) + return opencl_map_from_drm_arm(hwfc, dst, src, flags); +#endif + } + return AVERROR(ENOSYS); +} + +static int opencl_frames_derive_to(AVHWFramesContext *dst_fc, + AVHWFramesContext *src_fc, int flags) +{ + av_unused OpenCLDeviceContext *priv = dst_fc->device_ctx->internal->priv; + switch (src_fc->device_ctx->type) { +#if HAVE_OPENCL_DRM_BEIGNET + case AV_HWDEVICE_TYPE_DRM: + if (!priv->beignet_drm_mapping_usable) + return AVERROR(ENOSYS); + break; +#endif +#if HAVE_OPENCL_VAAPI_BEIGNET + case AV_HWDEVICE_TYPE_VAAPI: + if (!priv->beignet_drm_mapping_usable) + return AVERROR(ENOSYS); + break; +#endif +#if HAVE_OPENCL_VAAPI_INTEL_MEDIA + case AV_HWDEVICE_TYPE_QSV: + case AV_HWDEVICE_TYPE_VAAPI: + if (!priv->qsv_mapping_usable) + return AVERROR(ENOSYS); + break; +#endif +#if HAVE_OPENCL_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + if (!priv->dxva2_mapping_usable) + return AVERROR(ENOSYS); + { + int err; + err = opencl_frames_derive_from_dxva2(dst_fc, src_fc, flags); + if (err < 0) + return err; + } + break; +#endif +#if HAVE_OPENCL_D3D11 + case AV_HWDEVICE_TYPE_D3D11VA: + if (!priv->d3d11_mapping_usable) + return AVERROR(ENOSYS); + { + int err; + err = opencl_frames_derive_from_d3d11(dst_fc, src_fc, flags); + if (err < 0) + return err; + } + break; +#endif +#if HAVE_OPENCL_DRM_ARM + case AV_HWDEVICE_TYPE_DRM: + if (!priv->drm_arm_mapping_usable) + return AVERROR(ENOSYS); + break; +#endif + default: + return AVERROR(ENOSYS); + } + return opencl_frames_init_command_queue(dst_fc); +} + +const HWContextType ff_hwcontext_type_opencl = { + .type = AV_HWDEVICE_TYPE_OPENCL, + .name = "OpenCL", + + .device_hwctx_size = sizeof(AVOpenCLDeviceContext), + .device_priv_size = sizeof(OpenCLDeviceContext), + .frames_hwctx_size = sizeof(AVOpenCLFramesContext), + .frames_priv_size = sizeof(OpenCLFramesContext), + + .device_create = &opencl_device_create, + .device_derive = &opencl_device_derive, + .device_init = &opencl_device_init, + .device_uninit = &opencl_device_uninit, + + .frames_get_constraints = &opencl_frames_get_constraints, + .frames_init = &opencl_frames_init, + .frames_uninit = &opencl_frames_uninit, + .frames_get_buffer = &opencl_get_buffer, + + .transfer_get_formats = &opencl_transfer_get_formats, + .transfer_data_to = &opencl_transfer_data_to, + .transfer_data_from = &opencl_transfer_data_from, + + .map_from = &opencl_map_from, + .map_to = &opencl_map_to, + .frames_derive_to = &opencl_frames_derive_to, + + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_OPENCL, + AV_PIX_FMT_NONE + }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_opencl.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_opencl.h new file mode 100644 index 000000000..ef54486c9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_opencl.h @@ -0,0 +1,100 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_OPENCL_H +#define AVUTIL_HWCONTEXT_OPENCL_H + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include "frame.h" + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_OPENCL. + * + * Pools allocated internally are always dynamic, and are primarily intended + * to be used in OpenCL-only cases. If interoperation is required, it is + * typically required to allocate frames in the other API and then map the + * frames context to OpenCL with av_hwframe_ctx_create_derived(). + */ + +/** + * OpenCL frame descriptor for pool allocation. + * + * In user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer pointing at an object of this type describing the + * planes of the frame. + */ +typedef struct AVOpenCLFrameDescriptor { + /** + * Number of planes in the frame. + */ + int nb_planes; + /** + * OpenCL image2d objects for each plane of the frame. + */ + cl_mem planes[AV_NUM_DATA_POINTERS]; +} AVOpenCLFrameDescriptor; + +/** + * OpenCL device details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVOpenCLDeviceContext { + /** + * The primary device ID of the device. If multiple OpenCL devices + * are associated with the context then this is the one which will + * be used for all operations internal to FFmpeg. + */ + cl_device_id device_id; + /** + * The OpenCL context which will contain all operations and frames on + * this device. + */ + cl_context context; + /** + * The default command queue for this device, which will be used by all + * frames contexts which do not have their own command queue. If not + * intialised by the user, a default queue will be created on the + * primary device. + */ + cl_command_queue command_queue; +} AVOpenCLDeviceContext; + +/** + * OpenCL-specific data associated with a frame pool. + * + * Allocated as AVHWFramesContext.hwctx. + */ +typedef struct AVOpenCLFramesContext { + /** + * The command queue used for internal asynchronous operations on this + * device (av_hwframe_transfer_data(), av_hwframe_map()). + * + * If this is not set, the command queue from the associated device is + * used instead. + */ + cl_command_queue command_queue; +} AVOpenCLFramesContext; + +#endif /* AVUTIL_HWCONTEXT_OPENCL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_qsv.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_qsv.c new file mode 100644 index 000000000..59e4ed915 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_qsv.c @@ -0,0 +1,1278 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include + +#include "config.h" + +#if HAVE_PTHREADS +#include +#endif + +#if CONFIG_VAAPI +#include "hwcontext_vaapi.h" +#endif +#if CONFIG_DXVA2 +#include "hwcontext_dxva2.h" +#endif + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_qsv.h" +#include "mem.h" +#include "pixfmt.h" +#include "pixdesc.h" +#include "time.h" + +typedef struct QSVDevicePriv { + AVBufferRef *child_device_ctx; +} QSVDevicePriv; + +typedef struct QSVDeviceContext { + mfxHDL handle; + mfxHandleType handle_type; + mfxVersion ver; + mfxIMPL impl; + + enum AVHWDeviceType child_device_type; + enum AVPixelFormat child_pix_fmt; +} QSVDeviceContext; + +typedef struct QSVFramesContext { + mfxSession session_download; + int session_download_init; + mfxSession session_upload; + int session_upload_init; +#if HAVE_PTHREADS + pthread_mutex_t session_lock; + pthread_cond_t session_cond; +#endif + + AVBufferRef *child_frames_ref; + mfxFrameSurface1 *surfaces_internal; + int nb_surfaces_used; + + // used in the frame allocator for non-opaque surfaces + mfxMemId *mem_ids; + // used in the opaque alloc request for opaque surfaces + mfxFrameSurface1 **surface_ptrs; + + mfxExtOpaqueSurfaceAlloc opaque_alloc; + mfxExtBuffer *ext_buffers[1]; +} QSVFramesContext; + +static const struct { + mfxHandleType handle_type; + enum AVHWDeviceType device_type; + enum AVPixelFormat pix_fmt; +} supported_handle_types[] = { +#if CONFIG_VAAPI + { MFX_HANDLE_VA_DISPLAY, AV_HWDEVICE_TYPE_VAAPI, AV_PIX_FMT_VAAPI }, +#endif +#if CONFIG_DXVA2 + { MFX_HANDLE_D3D9_DEVICE_MANAGER, AV_HWDEVICE_TYPE_DXVA2, AV_PIX_FMT_DXVA2_VLD }, +#endif + { 0 }, +}; + +static const struct { + enum AVPixelFormat pix_fmt; + uint32_t fourcc; +} supported_pixel_formats[] = { + { AV_PIX_FMT_NV12, MFX_FOURCC_NV12 }, + { AV_PIX_FMT_BGRA, MFX_FOURCC_RGB4 }, + { AV_PIX_FMT_P010, MFX_FOURCC_P010 }, + { AV_PIX_FMT_PAL8, MFX_FOURCC_P8 }, +}; + +static uint32_t qsv_fourcc_from_pix_fmt(enum AVPixelFormat pix_fmt) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) { + if (supported_pixel_formats[i].pix_fmt == pix_fmt) + return supported_pixel_formats[i].fourcc; + } + return 0; +} + +static int qsv_device_init(AVHWDeviceContext *ctx) +{ + AVQSVDeviceContext *hwctx = ctx->hwctx; + QSVDeviceContext *s = ctx->internal->priv; + + mfxStatus err; + int i; + + for (i = 0; supported_handle_types[i].handle_type; i++) { + err = MFXVideoCORE_GetHandle(hwctx->session, supported_handle_types[i].handle_type, + &s->handle); + if (err == MFX_ERR_NONE) { + s->handle_type = supported_handle_types[i].handle_type; + s->child_device_type = supported_handle_types[i].device_type; + s->child_pix_fmt = supported_handle_types[i].pix_fmt; + break; + } + } + if (!s->handle) { + av_log(ctx, AV_LOG_VERBOSE, "No supported hw handle could be retrieved " + "from the session\n"); + } + + err = MFXQueryIMPL(hwctx->session, &s->impl); + if (err == MFX_ERR_NONE) + err = MFXQueryVersion(hwctx->session, &s->ver); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static void qsv_frames_uninit(AVHWFramesContext *ctx) +{ + QSVFramesContext *s = ctx->internal->priv; + + if (s->session_download) { + MFXVideoVPP_Close(s->session_download); + MFXClose(s->session_download); + } + s->session_download = NULL; + s->session_download_init = 0; + + if (s->session_upload) { + MFXVideoVPP_Close(s->session_upload); + MFXClose(s->session_upload); + } + s->session_upload = NULL; + s->session_upload_init = 0; + +#if HAVE_PTHREADS + pthread_mutex_destroy(&s->session_lock); + pthread_cond_destroy(&s->session_cond); +#endif + + av_freep(&s->mem_ids); + av_freep(&s->surface_ptrs); + av_freep(&s->surfaces_internal); + av_buffer_unref(&s->child_frames_ref); +} + +static void qsv_pool_release_dummy(void *opaque, uint8_t *data) +{ +} + +static AVBufferRef *qsv_pool_alloc(void *opaque, int size) +{ + AVHWFramesContext *ctx = (AVHWFramesContext*)opaque; + QSVFramesContext *s = ctx->internal->priv; + AVQSVFramesContext *hwctx = ctx->hwctx; + + if (s->nb_surfaces_used < hwctx->nb_surfaces) { + s->nb_surfaces_used++; + return av_buffer_create((uint8_t*)(s->surfaces_internal + s->nb_surfaces_used - 1), + sizeof(*hwctx->surfaces), qsv_pool_release_dummy, NULL, 0); + } + + return NULL; +} + +static int qsv_init_child_ctx(AVHWFramesContext *ctx) +{ + AVQSVFramesContext *hwctx = ctx->hwctx; + QSVFramesContext *s = ctx->internal->priv; + QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv; + + AVBufferRef *child_device_ref = NULL; + AVBufferRef *child_frames_ref = NULL; + + AVHWDeviceContext *child_device_ctx; + AVHWFramesContext *child_frames_ctx; + + int i, ret = 0; + + if (!device_priv->handle) { + av_log(ctx, AV_LOG_ERROR, + "Cannot create a non-opaque internal surface pool without " + "a hardware handle\n"); + return AVERROR(EINVAL); + } + + child_device_ref = av_hwdevice_ctx_alloc(device_priv->child_device_type); + if (!child_device_ref) + return AVERROR(ENOMEM); + child_device_ctx = (AVHWDeviceContext*)child_device_ref->data; + +#if CONFIG_VAAPI + if (child_device_ctx->type == AV_HWDEVICE_TYPE_VAAPI) { + AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx; + child_device_hwctx->display = (VADisplay)device_priv->handle; + } +#endif +#if CONFIG_DXVA2 + if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) { + AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx; + child_device_hwctx->devmgr = (IDirect3DDeviceManager9*)device_priv->handle; + } +#endif + + ret = av_hwdevice_ctx_init(child_device_ref); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error initializing a child device context\n"); + goto fail; + } + + child_frames_ref = av_hwframe_ctx_alloc(child_device_ref); + if (!child_frames_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + child_frames_ctx = (AVHWFramesContext*)child_frames_ref->data; + + child_frames_ctx->format = device_priv->child_pix_fmt; + child_frames_ctx->sw_format = ctx->sw_format; + child_frames_ctx->initial_pool_size = ctx->initial_pool_size; + child_frames_ctx->width = FFALIGN(ctx->width, 16); + child_frames_ctx->height = FFALIGN(ctx->height, 16); + +#if CONFIG_DXVA2 + if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) { + AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx; + if (hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) + child_frames_hwctx->surface_type = DXVA2_VideoProcessorRenderTarget; + else + child_frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget; + } +#endif + + ret = av_hwframe_ctx_init(child_frames_ref); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error initializing a child frames context\n"); + goto fail; + } + +#if CONFIG_VAAPI + if (child_device_ctx->type == AV_HWDEVICE_TYPE_VAAPI) { + AVVAAPIFramesContext *child_frames_hwctx = child_frames_ctx->hwctx; + for (i = 0; i < ctx->initial_pool_size; i++) + s->surfaces_internal[i].Data.MemId = child_frames_hwctx->surface_ids + i; + hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } +#endif +#if CONFIG_DXVA2 + if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) { + AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx; + for (i = 0; i < ctx->initial_pool_size; i++) + s->surfaces_internal[i].Data.MemId = (mfxMemId)child_frames_hwctx->surfaces[i]; + if (child_frames_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget) + hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + else + hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } +#endif + + s->child_frames_ref = child_frames_ref; + child_frames_ref = NULL; + +fail: + av_buffer_unref(&child_device_ref); + av_buffer_unref(&child_frames_ref); + return ret; +} + +static int qsv_init_surface(AVHWFramesContext *ctx, mfxFrameSurface1 *surf) +{ + const AVPixFmtDescriptor *desc; + uint32_t fourcc; + + desc = av_pix_fmt_desc_get(ctx->sw_format); + if (!desc) + return AVERROR(EINVAL); + + fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format); + if (!fourcc) + return AVERROR(EINVAL); + + surf->Info.BitDepthLuma = desc->comp[0].depth; + surf->Info.BitDepthChroma = desc->comp[0].depth; + surf->Info.Shift = desc->comp[0].depth > 8; + + if (desc->log2_chroma_w && desc->log2_chroma_h) + surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420; + else if (desc->log2_chroma_w) + surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV422; + else + surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV444; + + surf->Info.FourCC = fourcc; + surf->Info.Width = FFALIGN(ctx->width, 16); + surf->Info.CropW = ctx->width; + surf->Info.Height = FFALIGN(ctx->height, 16); + surf->Info.CropH = ctx->height; + surf->Info.FrameRateExtN = 25; + surf->Info.FrameRateExtD = 1; + surf->Info.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; + + return 0; +} + +static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc) +{ + QSVFramesContext *s = ctx->internal->priv; + AVQSVFramesContext *frames_hwctx = ctx->hwctx; + + int i, ret = 0; + + if (ctx->initial_pool_size <= 0) { + av_log(ctx, AV_LOG_ERROR, "QSV requires a fixed frame pool size\n"); + return AVERROR(EINVAL); + } + + s->surfaces_internal = av_mallocz_array(ctx->initial_pool_size, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + + for (i = 0; i < ctx->initial_pool_size; i++) { + ret = qsv_init_surface(ctx, &s->surfaces_internal[i]); + if (ret < 0) + return ret; + } + + if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) { + ret = qsv_init_child_ctx(ctx); + if (ret < 0) + return ret; + } + + ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(mfxFrameSurface1), + ctx, qsv_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + + frames_hwctx->surfaces = s->surfaces_internal; + frames_hwctx->nb_surfaces = ctx->initial_pool_size; + + return 0; +} + +static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, + mfxFrameAllocResponse *resp) +{ + AVHWFramesContext *ctx = pthis; + QSVFramesContext *s = ctx->internal->priv; + AVQSVFramesContext *hwctx = ctx->hwctx; + mfxFrameInfo *i = &req->Info; + mfxFrameInfo *i1 = &hwctx->surfaces[0].Info; + + if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) || + !(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) || + !(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME)) + return MFX_ERR_UNSUPPORTED; + if (i->Width > i1->Width || i->Height > i1->Height || + i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) { + av_log(ctx, AV_LOG_ERROR, "Mismatching surface properties in an " + "allocation request: %dx%d %d %d vs %dx%d %d %d\n", + i->Width, i->Height, i->FourCC, i->ChromaFormat, + i1->Width, i1->Height, i1->FourCC, i1->ChromaFormat); + return MFX_ERR_UNSUPPORTED; + } + + resp->mids = s->mem_ids; + resp->NumFrameActual = hwctx->nb_surfaces; + + return MFX_ERR_NONE; +} + +static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) +{ + return MFX_ERR_NONE; +} + +static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) +{ + return MFX_ERR_UNSUPPORTED; +} + +static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) +{ + return MFX_ERR_UNSUPPORTED; +} + +static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) +{ + *hdl = mid; + return MFX_ERR_NONE; +} + +static int qsv_init_internal_session(AVHWFramesContext *ctx, + mfxSession *session, int upload) +{ + QSVFramesContext *s = ctx->internal->priv; + AVQSVFramesContext *frames_hwctx = ctx->hwctx; + QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv; + int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); + + mfxFrameAllocator frame_allocator = { + .pthis = ctx, + .Alloc = frame_alloc, + .Lock = frame_lock, + .Unlock = frame_unlock, + .GetHDL = frame_get_hdl, + .Free = frame_free, + }; + + mfxVideoParam par; + mfxStatus err; + + err = MFXInit(device_priv->impl, &device_priv->ver, session); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error initializing an internal session\n"); + return AVERROR_UNKNOWN; + } + + if (device_priv->handle) { + err = MFXVideoCORE_SetHandle(*session, device_priv->handle_type, + device_priv->handle); + if (err != MFX_ERR_NONE) + return AVERROR_UNKNOWN; + } + + if (!opaque) { + err = MFXVideoCORE_SetFrameAllocator(*session, &frame_allocator); + if (err != MFX_ERR_NONE) + return AVERROR_UNKNOWN; + } + + memset(&par, 0, sizeof(par)); + + if (opaque) { + par.ExtParam = s->ext_buffers; + par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers); + par.IOPattern = upload ? MFX_IOPATTERN_OUT_OPAQUE_MEMORY : + MFX_IOPATTERN_IN_OPAQUE_MEMORY; + } else { + par.IOPattern = upload ? MFX_IOPATTERN_OUT_VIDEO_MEMORY : + MFX_IOPATTERN_IN_VIDEO_MEMORY; + } + + par.IOPattern |= upload ? MFX_IOPATTERN_IN_SYSTEM_MEMORY : + MFX_IOPATTERN_OUT_SYSTEM_MEMORY; + par.AsyncDepth = 1; + + par.vpp.In = frames_hwctx->surfaces[0].Info; + + /* Apparently VPP requires the frame rate to be set to some value, otherwise + * init will fail (probably for the framerate conversion filter). Since we + * are only doing data upload/download here, we just invent an arbitrary + * value */ + par.vpp.In.FrameRateExtN = 25; + par.vpp.In.FrameRateExtD = 1; + par.vpp.Out = par.vpp.In; + + err = MFXVideoVPP_Init(*session, &par); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_VERBOSE, "Error opening the internal VPP session." + "Surface upload/download will not be possible\n"); + MFXClose(*session); + *session = NULL; + } + + return 0; +} + +static int qsv_frames_init(AVHWFramesContext *ctx) +{ + QSVFramesContext *s = ctx->internal->priv; + AVQSVFramesContext *frames_hwctx = ctx->hwctx; + + int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); + + uint32_t fourcc; + int i, ret; + + fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format); + if (!fourcc) { + av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n"); + return AVERROR(ENOSYS); + } + + if (!ctx->pool) { + ret = qsv_init_pool(ctx, fourcc); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error creating an internal frame pool\n"); + return ret; + } + } + + if (opaque) { + s->surface_ptrs = av_mallocz_array(frames_hwctx->nb_surfaces, + sizeof(*s->surface_ptrs)); + if (!s->surface_ptrs) + return AVERROR(ENOMEM); + + for (i = 0; i < frames_hwctx->nb_surfaces; i++) + s->surface_ptrs[i] = frames_hwctx->surfaces + i; + + s->opaque_alloc.In.Surfaces = s->surface_ptrs; + s->opaque_alloc.In.NumSurface = frames_hwctx->nb_surfaces; + s->opaque_alloc.In.Type = frames_hwctx->frame_type; + + s->opaque_alloc.Out = s->opaque_alloc.In; + + s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION; + s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc); + + s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc; + } else { + s->mem_ids = av_mallocz_array(frames_hwctx->nb_surfaces, sizeof(*s->mem_ids)); + if (!s->mem_ids) + return AVERROR(ENOMEM); + + for (i = 0; i < frames_hwctx->nb_surfaces; i++) + s->mem_ids[i] = frames_hwctx->surfaces[i].Data.MemId; + } + + s->session_download = NULL; + s->session_upload = NULL; + + s->session_download_init = 0; + s->session_upload_init = 0; + +#if HAVE_PTHREADS + pthread_mutex_init(&s->session_lock, NULL); + pthread_cond_init(&s->session_cond, NULL); +#endif + + return 0; +} + +static int qsv_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_QSV; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int qsv_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + + return 0; +} + +static int qsv_frames_derive_from(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags) +{ + AVQSVFramesContext *src_hwctx = src_ctx->hwctx; + int i; + + switch (dst_ctx->device_ctx->type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + { + AVVAAPIFramesContext *dst_hwctx = dst_ctx->hwctx; + dst_hwctx->surface_ids = av_mallocz_array(src_hwctx->nb_surfaces, + sizeof(*dst_hwctx->surface_ids)); + if (!dst_hwctx->surface_ids) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) + dst_hwctx->surface_ids[i] = + *(VASurfaceID*)src_hwctx->surfaces[i].Data.MemId; + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + } + break; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + AVDXVA2FramesContext *dst_hwctx = dst_ctx->hwctx; + dst_hwctx->surfaces = av_mallocz_array(src_hwctx->nb_surfaces, + sizeof(*dst_hwctx->surfaces)); + if (!dst_hwctx->surfaces) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) + dst_hwctx->surfaces[i] = + (IDirect3DSurface9*)src_hwctx->surfaces[i].Data.MemId; + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + if (src_hwctx->frame_type == MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET) + dst_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget; + else + dst_hwctx->surface_type = DXVA2_VideoProcessorRenderTarget; + } + break; +#endif + default: + return AVERROR(ENOSYS); + } + + return 0; +} + +static int qsv_map_from(AVHWFramesContext *ctx, + AVFrame *dst, const AVFrame *src, int flags) +{ + QSVFramesContext *s = ctx->internal->priv; + mfxFrameSurface1 *surf = (mfxFrameSurface1*)src->data[3]; + AVHWFramesContext *child_frames_ctx; + const AVPixFmtDescriptor *desc; + uint8_t *child_data; + AVFrame *dummy; + int ret = 0; + + if (!s->child_frames_ref) + return AVERROR(ENOSYS); + child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data; + + switch (child_frames_ctx->device_ctx->type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + child_data = (uint8_t*)(intptr_t)*(VASurfaceID*)surf->Data.MemId; + break; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + child_data = surf->Data.MemId; + break; +#endif + default: + return AVERROR(ENOSYS); + } + + if (dst->format == child_frames_ctx->format) { + ret = ff_hwframe_map_create(s->child_frames_ref, + dst, src, NULL, NULL); + if (ret < 0) + return ret; + + dst->width = src->width; + dst->height = src->height; + dst->data[3] = child_data; + + return 0; + } + + desc = av_pix_fmt_desc_get(dst->format); + if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { + // This only supports mapping to software. + return AVERROR(ENOSYS); + } + + dummy = av_frame_alloc(); + if (!dummy) + return AVERROR(ENOMEM); + + dummy->buf[0] = av_buffer_ref(src->buf[0]); + dummy->hw_frames_ctx = av_buffer_ref(s->child_frames_ref); + if (!dummy->buf[0] || !dummy->hw_frames_ctx) + goto fail; + + dummy->format = child_frames_ctx->format; + dummy->width = src->width; + dummy->height = src->height; + dummy->data[3] = child_data; + + ret = av_hwframe_map(dst, dummy, flags); + +fail: + av_frame_free(&dummy); + + return ret; +} + +static int qsv_transfer_data_child(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + QSVFramesContext *s = ctx->internal->priv; + AVHWFramesContext *child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data; + int download = !!src->hw_frames_ctx; + mfxFrameSurface1 *surf = (mfxFrameSurface1*)(download ? src->data[3] : dst->data[3]); + + AVFrame *dummy; + int ret; + + dummy = av_frame_alloc(); + if (!dummy) + return AVERROR(ENOMEM); + + dummy->format = child_frames_ctx->format; + dummy->width = src->width; + dummy->height = src->height; + dummy->buf[0] = download ? src->buf[0] : dst->buf[0]; + dummy->data[3] = surf->Data.MemId; + dummy->hw_frames_ctx = s->child_frames_ref; + + ret = download ? av_hwframe_transfer_data(dst, dummy, 0) : + av_hwframe_transfer_data(dummy, src, 0); + + dummy->buf[0] = NULL; + dummy->data[3] = NULL; + dummy->hw_frames_ctx = NULL; + + av_frame_free(&dummy); + + return ret; +} + +static int map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface) +{ + switch (frame->format) { + case AV_PIX_FMT_NV12: + case AV_PIX_FMT_P010: + surface->Data.Y = frame->data[0]; + surface->Data.UV = frame->data[1]; + break; + + case AV_PIX_FMT_YUV420P: + surface->Data.Y = frame->data[0]; + surface->Data.U = frame->data[1]; + surface->Data.V = frame->data[2]; + break; + + case AV_PIX_FMT_BGRA: + surface->Data.B = frame->data[0]; + surface->Data.G = frame->data[0] + 1; + surface->Data.R = frame->data[0] + 2; + surface->Data.A = frame->data[0] + 3; + break; + + default: + return MFX_ERR_UNSUPPORTED; + } + surface->Data.Pitch = frame->linesize[0]; + surface->Data.TimeStamp = frame->pts; + + return 0; +} + +static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + QSVFramesContext *s = ctx->internal->priv; + mfxFrameSurface1 out = {{ 0 }}; + mfxFrameSurface1 *in = (mfxFrameSurface1*)src->data[3]; + + mfxSyncPoint sync = NULL; + mfxStatus err; + int ret = 0; + + while (!s->session_download_init && !s->session_download && !ret) { +#if HAVE_PTHREADS + if (pthread_mutex_trylock(&s->session_lock) == 0) { +#endif + if (!s->session_download_init) { + ret = qsv_init_internal_session(ctx, &s->session_download, 0); + if (s->session_download) + s->session_download_init = 1; + } +#if HAVE_PTHREADS + pthread_mutex_unlock(&s->session_lock); + pthread_cond_signal(&s->session_cond); + } else { + pthread_mutex_lock(&s->session_lock); + while (!s->session_download_init && !s->session_download) { + pthread_cond_wait(&s->session_cond, &s->session_lock); + } + pthread_mutex_unlock(&s->session_lock); + } +#endif + } + + if (ret < 0) + return ret; + + if (!s->session_download) { + if (s->child_frames_ref) + return qsv_transfer_data_child(ctx, dst, src); + + av_log(ctx, AV_LOG_ERROR, "Surface download not possible\n"); + return AVERROR(ENOSYS); + } + + out.Info = in->Info; + map_frame_to_surface(dst, &out); + + do { + err = MFXVideoVPP_RunFrameVPPAsync(s->session_download, in, &out, NULL, &sync); + if (err == MFX_WRN_DEVICE_BUSY) + av_usleep(1); + } while (err == MFX_WRN_DEVICE_BUSY); + + if (err < 0 || !sync) { + av_log(ctx, AV_LOG_ERROR, "Error downloading the surface\n"); + return AVERROR_UNKNOWN; + } + + do { + err = MFXVideoCORE_SyncOperation(s->session_download, sync, 1000); + } while (err == MFX_WRN_IN_EXECUTION); + if (err < 0) { + av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + QSVFramesContext *s = ctx->internal->priv; + mfxFrameSurface1 in = {{ 0 }}; + mfxFrameSurface1 *out = (mfxFrameSurface1*)dst->data[3]; + + mfxSyncPoint sync = NULL; + mfxStatus err; + int ret = 0; + /* make a copy if the input is not padded as libmfx requires */ + AVFrame tmp_frame; + const AVFrame *src_frame; + int realigned = 0; + + + while (!s->session_upload_init && !s->session_upload && !ret) { +#if HAVE_PTHREADS + if (pthread_mutex_trylock(&s->session_lock) == 0) { +#endif + if (!s->session_upload_init) { + ret = qsv_init_internal_session(ctx, &s->session_upload, 1); + if (s->session_upload) + s->session_upload_init = 1; + } +#if HAVE_PTHREADS + pthread_mutex_unlock(&s->session_lock); + pthread_cond_signal(&s->session_cond); + } else { + pthread_mutex_lock(&s->session_lock); + while (!s->session_upload_init && !s->session_upload) { + pthread_cond_wait(&s->session_cond, &s->session_lock); + } + pthread_mutex_unlock(&s->session_lock); + } +#endif + } + if (ret < 0) + return ret; + + if (src->height & 15 || src->linesize[0] & 15) { + realigned = 1; + memset(&tmp_frame, 0, sizeof(tmp_frame)); + tmp_frame.format = src->format; + tmp_frame.width = FFALIGN(src->width, 16); + tmp_frame.height = FFALIGN(src->height, 16); + ret = av_frame_get_buffer(&tmp_frame, 32); + if (ret < 0) + return ret; + + ret = av_frame_copy(&tmp_frame, src); + if (ret < 0) { + av_frame_unref(&tmp_frame); + return ret; + } + } + + src_frame = realigned ? &tmp_frame : src; + + if (!s->session_upload) { + if (s->child_frames_ref) + return qsv_transfer_data_child(ctx, dst, src_frame); + + av_log(ctx, AV_LOG_ERROR, "Surface upload not possible\n"); + return AVERROR(ENOSYS); + } + + in.Info = out->Info; + map_frame_to_surface(src_frame, &in); + + do { + err = MFXVideoVPP_RunFrameVPPAsync(s->session_upload, &in, out, NULL, &sync); + if (err == MFX_WRN_DEVICE_BUSY) + av_usleep(1); + } while (err == MFX_WRN_DEVICE_BUSY); + + if (err < 0 || !sync) { + av_log(ctx, AV_LOG_ERROR, "Error uploading the surface\n"); + return AVERROR_UNKNOWN; + } + + do { + err = MFXVideoCORE_SyncOperation(s->session_upload, sync, 1000); + } while (err == MFX_WRN_IN_EXECUTION); + if (err < 0) { + av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation\n"); + return AVERROR_UNKNOWN; + } + + if (realigned) + av_frame_unref(&tmp_frame); + + return 0; +} + +static int qsv_frames_derive_to(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags) +{ + QSVFramesContext *s = dst_ctx->internal->priv; + AVQSVFramesContext *dst_hwctx = dst_ctx->hwctx; + int i; + + switch (src_ctx->device_ctx->type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + { + AVVAAPIFramesContext *src_hwctx = src_ctx->hwctx; + s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); + s->surfaces_internal[i].Data.MemId = src_hwctx->surface_ids + i; + } + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } + break; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + AVDXVA2FramesContext *src_hwctx = src_ctx->hwctx; + s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); + s->surfaces_internal[i].Data.MemId = (mfxMemId)src_hwctx->surfaces[i]; + } + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + if (src_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget) + dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + else + dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } + break; +#endif + default: + return AVERROR(ENOSYS); + } + + dst_hwctx->surfaces = s->surfaces_internal; + + return 0; +} + +static int qsv_map_to(AVHWFramesContext *dst_ctx, + AVFrame *dst, const AVFrame *src, int flags) +{ + AVQSVFramesContext *hwctx = dst_ctx->hwctx; + int i, err; + + for (i = 0; i < hwctx->nb_surfaces; i++) { +#if CONFIG_VAAPI + if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId == + (VASurfaceID)(uintptr_t)src->data[3]) + break; +#endif +#if CONFIG_DXVA2 + if ((IDirect3DSurface9*)hwctx->surfaces[i].Data.MemId == + (IDirect3DSurface9*)(uintptr_t)src->data[3]) + break; +#endif + } + if (i >= hwctx->nb_surfaces) { + av_log(dst_ctx, AV_LOG_ERROR, "Trying to map from a surface which " + "is not in the mapped frames context.\n"); + return AVERROR(EINVAL); + } + + err = ff_hwframe_map_create(dst->hw_frames_ctx, + dst, src, NULL, NULL); + if (err) + return err; + + dst->width = src->width; + dst->height = src->height; + dst->data[3] = (uint8_t*)&hwctx->surfaces[i]; + + return 0; +} + +static int qsv_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_pixel_formats) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) + constraints->valid_sw_formats[i] = supported_pixel_formats[i].pix_fmt; + constraints->valid_sw_formats[FF_ARRAY_ELEMS(supported_pixel_formats)] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_QSV; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +static void qsv_device_free(AVHWDeviceContext *ctx) +{ + AVQSVDeviceContext *hwctx = ctx->hwctx; + QSVDevicePriv *priv = ctx->user_opaque; + + if (hwctx->session) + MFXClose(hwctx->session); + + av_buffer_unref(&priv->child_device_ctx); + av_freep(&priv); +} + +static mfxIMPL choose_implementation(const char *device) +{ + static const struct { + const char *name; + mfxIMPL impl; + } impl_map[] = { + { "auto", MFX_IMPL_AUTO }, + { "sw", MFX_IMPL_SOFTWARE }, + { "hw", MFX_IMPL_HARDWARE }, + { "auto_any", MFX_IMPL_AUTO_ANY }, + { "hw_any", MFX_IMPL_HARDWARE_ANY }, + { "hw2", MFX_IMPL_HARDWARE2 }, + { "hw3", MFX_IMPL_HARDWARE3 }, + { "hw4", MFX_IMPL_HARDWARE4 }, + }; + + mfxIMPL impl = MFX_IMPL_AUTO_ANY; + int i; + + if (device) { + for (i = 0; i < FF_ARRAY_ELEMS(impl_map); i++) + if (!strcmp(device, impl_map[i].name)) { + impl = impl_map[i].impl; + break; + } + if (i == FF_ARRAY_ELEMS(impl_map)) + impl = strtol(device, NULL, 0); + } + + return impl; +} + +static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, + mfxIMPL implementation, + AVHWDeviceContext *child_device_ctx, + int flags) +{ + AVQSVDeviceContext *hwctx = ctx->hwctx; + + mfxVersion ver = { { 3, 1 } }; + mfxHDL handle; + mfxHandleType handle_type; + mfxStatus err; + int ret; + + switch (child_device_ctx->type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + { + AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx; + handle_type = MFX_HANDLE_VA_DISPLAY; + handle = (mfxHDL)child_device_hwctx->display; + } + break; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx; + handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER; + handle = (mfxHDL)child_device_hwctx->devmgr; + } + break; +#endif + default: + ret = AVERROR(ENOSYS); + goto fail; + } + + err = MFXInit(implementation, &ver, &hwctx->session); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: " + "%d.\n", err); + ret = AVERROR_UNKNOWN; + goto fail; + } + + err = MFXQueryVersion(hwctx->session, &ver); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error querying an MFX session: %d.\n", err); + ret = AVERROR_UNKNOWN; + goto fail; + } + + av_log(ctx, AV_LOG_VERBOSE, + "Initialize MFX session: API version is %d.%d, implementation version is %d.%d\n", + MFX_VERSION_MAJOR, MFX_VERSION_MINOR, ver.Major, ver.Minor); + + MFXClose(hwctx->session); + + err = MFXInit(implementation, &ver, &hwctx->session); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, + "Error initializing an MFX session: %d.\n", err); + ret = AVERROR_UNKNOWN; + goto fail; + } + + err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle); + if (err != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error setting child device handle: " + "%d\n", err); + ret = AVERROR_UNKNOWN; + goto fail; + } + + ret = MFXQueryVersion(hwctx->session,&ver); + if (ret == MFX_ERR_NONE) { + av_log(ctx, AV_LOG_VERBOSE, "MFX compile/runtime API: %d.%d/%d.%d\n", + MFX_VERSION_MAJOR, MFX_VERSION_MINOR, ver.Major, ver.Minor); + } + return 0; + +fail: + if (hwctx->session) + MFXClose(hwctx->session); + return ret; +} + +static int qsv_device_derive(AVHWDeviceContext *ctx, + AVHWDeviceContext *child_device_ctx, int flags) +{ + return qsv_device_derive_from_child(ctx, MFX_IMPL_HARDWARE_ANY, + child_device_ctx, flags); +} + +static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + QSVDevicePriv *priv; + enum AVHWDeviceType child_device_type; + AVHWDeviceContext *child_device; + AVDictionary *child_device_opts; + AVDictionaryEntry *e; + + mfxIMPL impl; + int ret; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + ctx->user_opaque = priv; + ctx->free = qsv_device_free; + + e = av_dict_get(opts, "child_device", NULL, 0); + + child_device_opts = NULL; + if (CONFIG_VAAPI) { + child_device_type = AV_HWDEVICE_TYPE_VAAPI; + // libmfx does not actually implement VAAPI properly, rather it + // depends on the specific behaviour of a matching iHD driver when + // used on recent Intel hardware. Set options to the VAAPI device + // creation so that we should pick a usable setup by default if + // possible, even when multiple devices and drivers are available. + av_dict_set(&child_device_opts, "kernel_driver", "i915", 0); + av_dict_set(&child_device_opts, "driver", "iHD", 0); + } else if (CONFIG_DXVA2) + child_device_type = AV_HWDEVICE_TYPE_DXVA2; + else { + av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n"); + return AVERROR(ENOSYS); + } + + ret = av_hwdevice_ctx_create(&priv->child_device_ctx, child_device_type, + e ? e->value : NULL, child_device_opts, 0); + if (ret < 0) + return ret; + + child_device = (AVHWDeviceContext*)priv->child_device_ctx->data; + + impl = choose_implementation(device); + + return qsv_device_derive_from_child(ctx, impl, child_device, 0); +} + +const HWContextType ff_hwcontext_type_qsv = { + .type = AV_HWDEVICE_TYPE_QSV, + .name = "QSV", + + .device_hwctx_size = sizeof(AVQSVDeviceContext), + .device_priv_size = sizeof(QSVDeviceContext), + .frames_hwctx_size = sizeof(AVQSVFramesContext), + .frames_priv_size = sizeof(QSVFramesContext), + + .device_create = qsv_device_create, + .device_derive = qsv_device_derive, + .device_init = qsv_device_init, + .frames_get_constraints = qsv_frames_get_constraints, + .frames_init = qsv_frames_init, + .frames_uninit = qsv_frames_uninit, + .frames_get_buffer = qsv_get_buffer, + .transfer_get_formats = qsv_transfer_get_formats, + .transfer_data_to = qsv_transfer_data_to, + .transfer_data_from = qsv_transfer_data_from, + .map_to = qsv_map_to, + .map_from = qsv_map_from, + .frames_derive_to = qsv_frames_derive_to, + .frames_derive_from = qsv_frames_derive_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_qsv.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_qsv.h new file mode 100644 index 000000000..b98d611cf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_qsv.h @@ -0,0 +1,53 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_QSV_H +#define AVUTIL_HWCONTEXT_QSV_H + +#include + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_QSV. + * + * This API does not support dynamic frame pools. AVHWFramesContext.pool must + * contain AVBufferRefs whose data pointer points to an mfxFrameSurface1 struct. + */ + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVQSVDeviceContext { + mfxSession session; +} AVQSVDeviceContext; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + */ +typedef struct AVQSVFramesContext { + mfxFrameSurface1 *surfaces; + int nb_surfaces; + + /** + * A combination of MFX_MEMTYPE_* describing the frame pool. + */ + int frame_type; +} AVQSVFramesContext; + +#endif /* AVUTIL_HWCONTEXT_QSV_H */ + diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vaapi.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vaapi.c new file mode 100644 index 000000000..cf117640f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vaapi.c @@ -0,0 +1,1689 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#if HAVE_VAAPI_X11 +# include +#endif +#if HAVE_VAAPI_DRM +# include +#endif + +#if CONFIG_LIBDRM +# include +# include +# include +# ifndef DRM_FORMAT_MOD_INVALID +# define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) +# endif +#endif + +#include +#if HAVE_UNISTD_H +# include +#endif + + +#include "avassert.h" +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_drm.h" +#include "hwcontext_internal.h" +#include "hwcontext_vaapi.h" +#include "mem.h" +#include "pixdesc.h" +#include "pixfmt.h" + + +typedef struct VAAPIDevicePriv { +#if HAVE_VAAPI_X11 + Display *x11_display; +#endif + + int drm_fd; +} VAAPIDevicePriv; + +typedef struct VAAPISurfaceFormat { + enum AVPixelFormat pix_fmt; + VAImageFormat image_format; +} VAAPISurfaceFormat; + +typedef struct VAAPIDeviceContext { + // Surface formats which can be used with this device. + VAAPISurfaceFormat *formats; + int nb_formats; +} VAAPIDeviceContext; + +typedef struct VAAPIFramesContext { + // Surface attributes set at create time. + VASurfaceAttrib *attributes; + int nb_attributes; + // RT format of the underlying surface (Intel driver ignores this anyway). + unsigned int rt_format; + // Whether vaDeriveImage works. + int derive_works; +} VAAPIFramesContext; + +typedef struct VAAPIMapping { + // Handle to the derived or copied image which is mapped. + VAImage image; + // The mapping flags actually used. + int flags; +} VAAPIMapping; + +typedef struct VAAPIFormat { + unsigned int fourcc; + unsigned int rt_format; + enum AVPixelFormat pix_fmt; + int chroma_planes_swapped; +} VAAPIFormatDescriptor; + +#define MAP(va, rt, av, swap_uv) { \ + VA_FOURCC_ ## va, \ + VA_RT_FORMAT_ ## rt, \ + AV_PIX_FMT_ ## av, \ + swap_uv, \ + } +// The map fourcc <-> pix_fmt isn't bijective because of the annoying U/V +// plane swap cases. The frame handling below tries to hide these. +static const VAAPIFormatDescriptor vaapi_format_map[] = { + MAP(NV12, YUV420, NV12, 0), +#ifdef VA_FOURCC_I420 + MAP(I420, YUV420, YUV420P, 0), +#endif + MAP(YV12, YUV420, YUV420P, 1), + MAP(IYUV, YUV420, YUV420P, 0), + MAP(422H, YUV422, YUV422P, 0), +#ifdef VA_FOURCC_YV16 + MAP(YV16, YUV422, YUV422P, 1), +#endif + MAP(UYVY, YUV422, UYVY422, 0), + MAP(YUY2, YUV422, YUYV422, 0), + MAP(411P, YUV411, YUV411P, 0), + MAP(422V, YUV422, YUV440P, 0), + MAP(444P, YUV444, YUV444P, 0), + MAP(Y800, YUV400, GRAY8, 0), +#ifdef VA_FOURCC_P010 + MAP(P010, YUV420_10BPP, P010, 0), +#endif + MAP(BGRA, RGB32, BGRA, 0), + MAP(BGRX, RGB32, BGR0, 0), + MAP(RGBA, RGB32, RGBA, 0), + MAP(RGBX, RGB32, RGB0, 0), +#ifdef VA_FOURCC_ABGR + MAP(ABGR, RGB32, ABGR, 0), + MAP(XBGR, RGB32, 0BGR, 0), +#endif + MAP(ARGB, RGB32, ARGB, 0), + MAP(XRGB, RGB32, 0RGB, 0), +}; +#undef MAP + +static const VAAPIFormatDescriptor * + vaapi_format_from_fourcc(unsigned int fourcc) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_format_map); i++) + if (vaapi_format_map[i].fourcc == fourcc) + return &vaapi_format_map[i]; + return NULL; +} + +static const VAAPIFormatDescriptor * + vaapi_format_from_pix_fmt(enum AVPixelFormat pix_fmt) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_format_map); i++) + if (vaapi_format_map[i].pix_fmt == pix_fmt) + return &vaapi_format_map[i]; + return NULL; +} + +static enum AVPixelFormat vaapi_pix_fmt_from_fourcc(unsigned int fourcc) +{ + const VAAPIFormatDescriptor *desc; + desc = vaapi_format_from_fourcc(fourcc); + if (desc) + return desc->pix_fmt; + else + return AV_PIX_FMT_NONE; +} + +static int vaapi_get_image_format(AVHWDeviceContext *hwdev, + enum AVPixelFormat pix_fmt, + VAImageFormat **image_format) +{ + VAAPIDeviceContext *ctx = hwdev->internal->priv; + int i; + + for (i = 0; i < ctx->nb_formats; i++) { + if (ctx->formats[i].pix_fmt == pix_fmt) { + if (image_format) + *image_format = &ctx->formats[i].image_format; + return 0; + } + } + return AVERROR(EINVAL); +} + +static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + AVVAAPIDeviceContext *hwctx = hwdev->hwctx; + const AVVAAPIHWConfig *config = hwconfig; + VAAPIDeviceContext *ctx = hwdev->internal->priv; + VASurfaceAttrib *attr_list = NULL; + VAStatus vas; + enum AVPixelFormat pix_fmt; + unsigned int fourcc; + int err, i, j, attr_count, pix_fmt_count; + + if (config && + !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) { + attr_count = 0; + vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id, + 0, &attr_count); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(ENOSYS); + goto fail; + } + + attr_list = av_malloc(attr_count * sizeof(*attr_list)); + if (!attr_list) { + err = AVERROR(ENOMEM); + goto fail; + } + + vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id, + attr_list, &attr_count); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: " + "%d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR(ENOSYS); + goto fail; + } + + pix_fmt_count = 0; + for (i = 0; i < attr_count; i++) { + switch (attr_list[i].type) { + case VASurfaceAttribPixelFormat: + fourcc = attr_list[i].value.value.i; + pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); + if (pix_fmt != AV_PIX_FMT_NONE) { + ++pix_fmt_count; + } else { + // Something unsupported - ignore. + } + break; + case VASurfaceAttribMinWidth: + constraints->min_width = attr_list[i].value.value.i; + break; + case VASurfaceAttribMinHeight: + constraints->min_height = attr_list[i].value.value.i; + break; + case VASurfaceAttribMaxWidth: + constraints->max_width = attr_list[i].value.value.i; + break; + case VASurfaceAttribMaxHeight: + constraints->max_height = attr_list[i].value.value.i; + break; + } + } + if (pix_fmt_count == 0) { + // Nothing usable found. Presumably there exists something which + // works, so leave the set null to indicate unknown. + constraints->valid_sw_formats = NULL; + } else { + constraints->valid_sw_formats = av_malloc_array(pix_fmt_count + 1, + sizeof(pix_fmt)); + if (!constraints->valid_sw_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + + for (i = j = 0; i < attr_count; i++) { + if (attr_list[i].type != VASurfaceAttribPixelFormat) + continue; + fourcc = attr_list[i].value.value.i; + pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); + if (pix_fmt != AV_PIX_FMT_NONE) + constraints->valid_sw_formats[j++] = pix_fmt; + } + av_assert0(j == pix_fmt_count); + constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE; + } + } else { + // No configuration supplied. + // Return the full set of image formats known by the implementation. + constraints->valid_sw_formats = av_malloc_array(ctx->nb_formats + 1, + sizeof(pix_fmt)); + if (!constraints->valid_sw_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + for (i = 0; i < ctx->nb_formats; i++) + constraints->valid_sw_formats[i] = ctx->formats[i].pix_fmt; + constraints->valid_sw_formats[i] = AV_PIX_FMT_NONE; + } + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(pix_fmt)); + if (!constraints->valid_hw_formats) { + err = AVERROR(ENOMEM); + goto fail; + } + constraints->valid_hw_formats[0] = AV_PIX_FMT_VAAPI; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + err = 0; +fail: + av_freep(&attr_list); + return err; +} + +static const struct { + const char *friendly_name; + const char *match_string; + unsigned int quirks; +} vaapi_driver_quirks_table[] = { +#if !VA_CHECK_VERSION(1, 0, 0) + // The i965 driver did not conform before version 2.0. + { + "Intel i965 (Quick Sync)", + "i965", + AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS, + }, +#endif + { + "Intel iHD", + "ubit", + AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE, + }, + { + "VDPAU wrapper", + "Splitted-Desktop Systems VDPAU backend for VA-API", + AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES, + }, +}; + +static int vaapi_device_init(AVHWDeviceContext *hwdev) +{ + VAAPIDeviceContext *ctx = hwdev->internal->priv; + AVVAAPIDeviceContext *hwctx = hwdev->hwctx; + VAImageFormat *image_list = NULL; + VAStatus vas; + const char *vendor_string; + int err, i, image_count; + enum AVPixelFormat pix_fmt; + unsigned int fourcc; + + image_count = vaMaxNumImageFormats(hwctx->display); + if (image_count <= 0) { + err = AVERROR(EIO); + goto fail; + } + image_list = av_malloc(image_count * sizeof(*image_list)); + if (!image_list) { + err = AVERROR(ENOMEM); + goto fail; + } + vas = vaQueryImageFormats(hwctx->display, image_list, &image_count); + if (vas != VA_STATUS_SUCCESS) { + err = AVERROR(EIO); + goto fail; + } + + ctx->formats = av_malloc(image_count * sizeof(*ctx->formats)); + if (!ctx->formats) { + err = AVERROR(ENOMEM); + goto fail; + } + ctx->nb_formats = 0; + for (i = 0; i < image_count; i++) { + fourcc = image_list[i].fourcc; + pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); + if (pix_fmt == AV_PIX_FMT_NONE) { + av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> unknown.\n", + fourcc); + } else { + av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n", + fourcc, av_get_pix_fmt_name(pix_fmt)); + ctx->formats[ctx->nb_formats].pix_fmt = pix_fmt; + ctx->formats[ctx->nb_formats].image_format = image_list[i]; + ++ctx->nb_formats; + } + } + + vendor_string = vaQueryVendorString(hwctx->display); + if (vendor_string) + av_log(hwdev, AV_LOG_VERBOSE, "VAAPI driver: %s.\n", vendor_string); + + if (hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_USER_SET) { + av_log(hwdev, AV_LOG_VERBOSE, "Using quirks set by user (%#x).\n", + hwctx->driver_quirks); + } else { + // Detect the driver in use and set quirk flags if necessary. + hwctx->driver_quirks = 0; + if (vendor_string) { + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_driver_quirks_table); i++) { + if (strstr(vendor_string, + vaapi_driver_quirks_table[i].match_string)) { + av_log(hwdev, AV_LOG_VERBOSE, "Matched driver string " + "as known nonstandard driver \"%s\", setting " + "quirks (%#x).\n", + vaapi_driver_quirks_table[i].friendly_name, + vaapi_driver_quirks_table[i].quirks); + hwctx->driver_quirks |= + vaapi_driver_quirks_table[i].quirks; + break; + } + } + if (!(i < FF_ARRAY_ELEMS(vaapi_driver_quirks_table))) { + av_log(hwdev, AV_LOG_VERBOSE, "Driver not found in known " + "nonstandard list, using standard behaviour.\n"); + } + } else { + av_log(hwdev, AV_LOG_VERBOSE, "Driver has no vendor string, " + "assuming standard behaviour.\n"); + } + } + + av_free(image_list); + return 0; +fail: + av_freep(&ctx->formats); + av_free(image_list); + return err; +} + +static void vaapi_device_uninit(AVHWDeviceContext *hwdev) +{ + VAAPIDeviceContext *ctx = hwdev->internal->priv; + + av_freep(&ctx->formats); +} + +static void vaapi_buffer_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *hwfc = opaque; + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VASurfaceID surface_id; + VAStatus vas; + + surface_id = (VASurfaceID)(uintptr_t)data; + + vas = vaDestroySurfaces(hwctx->display, &surface_id, 1); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to destroy surface %#x: " + "%d (%s).\n", surface_id, vas, vaErrorStr(vas)); + } +} + +static AVBufferRef *vaapi_pool_alloc(void *opaque, int size) +{ + AVHWFramesContext *hwfc = opaque; + VAAPIFramesContext *ctx = hwfc->internal->priv; + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + AVVAAPIFramesContext *avfc = hwfc->hwctx; + VASurfaceID surface_id; + VAStatus vas; + AVBufferRef *ref; + + if (hwfc->initial_pool_size > 0 && + avfc->nb_surfaces >= hwfc->initial_pool_size) + return NULL; + + vas = vaCreateSurfaces(hwctx->display, ctx->rt_format, + hwfc->width, hwfc->height, + &surface_id, 1, + ctx->attributes, ctx->nb_attributes); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to create surface: " + "%d (%s).\n", vas, vaErrorStr(vas)); + return NULL; + } + av_log(hwfc, AV_LOG_DEBUG, "Created surface %#x.\n", surface_id); + + ref = av_buffer_create((uint8_t*)(uintptr_t)surface_id, + sizeof(surface_id), &vaapi_buffer_free, + hwfc, AV_BUFFER_FLAG_READONLY); + if (!ref) { + vaDestroySurfaces(hwctx->display, &surface_id, 1); + return NULL; + } + + if (hwfc->initial_pool_size > 0) { + // This is a fixed-size pool, so we must still be in the initial + // allocation sequence. + av_assert0(avfc->nb_surfaces < hwfc->initial_pool_size); + avfc->surface_ids[avfc->nb_surfaces] = surface_id; + ++avfc->nb_surfaces; + } + + return ref; +} + +static int vaapi_frames_init(AVHWFramesContext *hwfc) +{ + AVVAAPIFramesContext *avfc = hwfc->hwctx; + VAAPIFramesContext *ctx = hwfc->internal->priv; + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + const VAAPIFormatDescriptor *desc; + VAImageFormat *expected_format; + AVBufferRef *test_surface = NULL; + VASurfaceID test_surface_id; + VAImage test_image; + VAStatus vas; + int err, i; + + desc = vaapi_format_from_pix_fmt(hwfc->sw_format); + if (!desc) { + av_log(hwfc, AV_LOG_ERROR, "Unsupported format: %s.\n", + av_get_pix_fmt_name(hwfc->sw_format)); + return AVERROR(EINVAL); + } + + if (!hwfc->pool) { + if (!(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) { + int need_memory_type = !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE); + int need_pixel_format = 1; + for (i = 0; i < avfc->nb_attributes; i++) { + if (avfc->attributes[i].type == VASurfaceAttribMemoryType) + need_memory_type = 0; + if (avfc->attributes[i].type == VASurfaceAttribPixelFormat) + need_pixel_format = 0; + } + ctx->nb_attributes = + avfc->nb_attributes + need_memory_type + need_pixel_format; + + ctx->attributes = av_malloc(ctx->nb_attributes * + sizeof(*ctx->attributes)); + if (!ctx->attributes) { + err = AVERROR(ENOMEM); + goto fail; + } + + for (i = 0; i < avfc->nb_attributes; i++) + ctx->attributes[i] = avfc->attributes[i]; + if (need_memory_type) { + ctx->attributes[i++] = (VASurfaceAttrib) { + .type = VASurfaceAttribMemoryType, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA, + }; + } + if (need_pixel_format) { + ctx->attributes[i++] = (VASurfaceAttrib) { + .type = VASurfaceAttribPixelFormat, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = desc->fourcc, + }; + } + av_assert0(i == ctx->nb_attributes); + } else { + ctx->attributes = NULL; + ctx->nb_attributes = 0; + } + + ctx->rt_format = desc->rt_format; + + if (hwfc->initial_pool_size > 0) { + // This pool will be usable as a render target, so we need to store + // all of the surface IDs somewhere that vaCreateContext() calls + // will be able to access them. + avfc->nb_surfaces = 0; + avfc->surface_ids = av_malloc(hwfc->initial_pool_size * + sizeof(*avfc->surface_ids)); + if (!avfc->surface_ids) { + err = AVERROR(ENOMEM); + goto fail; + } + } else { + // This pool allows dynamic sizing, and will not be usable as a + // render target. + avfc->nb_surfaces = 0; + avfc->surface_ids = NULL; + } + + hwfc->internal->pool_internal = + av_buffer_pool_init2(sizeof(VASurfaceID), hwfc, + &vaapi_pool_alloc, NULL); + if (!hwfc->internal->pool_internal) { + av_log(hwfc, AV_LOG_ERROR, "Failed to create VAAPI surface pool.\n"); + err = AVERROR(ENOMEM); + goto fail; + } + } + + // Allocate a single surface to test whether vaDeriveImage() is going + // to work for the specific configuration. + if (hwfc->pool) { + test_surface = av_buffer_pool_get(hwfc->pool); + if (!test_surface) { + av_log(hwfc, AV_LOG_ERROR, "Unable to allocate a surface from " + "user-configured buffer pool.\n"); + err = AVERROR(ENOMEM); + goto fail; + } + } else { + test_surface = av_buffer_pool_get(hwfc->internal->pool_internal); + if (!test_surface) { + av_log(hwfc, AV_LOG_ERROR, "Unable to allocate a surface from " + "internal buffer pool.\n"); + err = AVERROR(ENOMEM); + goto fail; + } + } + test_surface_id = (VASurfaceID)(uintptr_t)test_surface->data; + + ctx->derive_works = 0; + + err = vaapi_get_image_format(hwfc->device_ctx, + hwfc->sw_format, &expected_format); + if (err == 0) { + vas = vaDeriveImage(hwctx->display, test_surface_id, &test_image); + if (vas == VA_STATUS_SUCCESS) { + if (expected_format->fourcc == test_image.format.fourcc) { + av_log(hwfc, AV_LOG_DEBUG, "Direct mapping possible.\n"); + ctx->derive_works = 1; + } else { + av_log(hwfc, AV_LOG_DEBUG, "Direct mapping disabled: " + "derived image format %08x does not match " + "expected format %08x.\n", + expected_format->fourcc, test_image.format.fourcc); + } + vaDestroyImage(hwctx->display, test_image.image_id); + } else { + av_log(hwfc, AV_LOG_DEBUG, "Direct mapping disabled: " + "deriving image does not work: " + "%d (%s).\n", vas, vaErrorStr(vas)); + } + } else { + av_log(hwfc, AV_LOG_DEBUG, "Direct mapping disabled: " + "image format is not supported.\n"); + } + + av_buffer_unref(&test_surface); + return 0; + +fail: + av_buffer_unref(&test_surface); + av_freep(&avfc->surface_ids); + av_freep(&ctx->attributes); + return err; +} + +static void vaapi_frames_uninit(AVHWFramesContext *hwfc) +{ + AVVAAPIFramesContext *avfc = hwfc->hwctx; + VAAPIFramesContext *ctx = hwfc->internal->priv; + + av_freep(&avfc->surface_ids); + av_freep(&ctx->attributes); +} + +static int vaapi_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(hwfc->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_VAAPI; + frame->width = hwfc->width; + frame->height = hwfc->height; + + return 0; +} + +static int vaapi_transfer_get_formats(AVHWFramesContext *hwfc, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + VAAPIDeviceContext *ctx = hwfc->device_ctx->internal->priv; + enum AVPixelFormat *pix_fmts; + int i, k, sw_format_available; + + sw_format_available = 0; + for (i = 0; i < ctx->nb_formats; i++) { + if (ctx->formats[i].pix_fmt == hwfc->sw_format) + sw_format_available = 1; + } + + pix_fmts = av_malloc((ctx->nb_formats + 1) * sizeof(*pix_fmts)); + if (!pix_fmts) + return AVERROR(ENOMEM); + + if (sw_format_available) { + pix_fmts[0] = hwfc->sw_format; + k = 1; + } else { + k = 0; + } + for (i = 0; i < ctx->nb_formats; i++) { + if (ctx->formats[i].pix_fmt == hwfc->sw_format) + continue; + av_assert0(k < ctx->nb_formats); + pix_fmts[k++] = ctx->formats[i].pix_fmt; + } + pix_fmts[k] = AV_PIX_FMT_NONE; + + *formats = pix_fmts; + return 0; +} + +static void vaapi_unmap_frame(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIMapping *map = hwmap->priv; + VASurfaceID surface_id; + VAStatus vas; + + surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Unmap surface %#x.\n", surface_id); + + vas = vaUnmapBuffer(hwctx->display, map->image.buf); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to unmap image from surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + } + + if ((map->flags & AV_HWFRAME_MAP_WRITE) && + !(map->flags & AV_HWFRAME_MAP_DIRECT)) { + vas = vaPutImage(hwctx->display, surface_id, map->image.image_id, + 0, 0, hwfc->width, hwfc->height, + 0, 0, hwfc->width, hwfc->height); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to write image to surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + } + } + + vas = vaDestroyImage(hwctx->display, map->image.image_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image from surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + } + + av_free(map); +} + +static int vaapi_map_frame(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src, int flags) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIFramesContext *ctx = hwfc->internal->priv; + VASurfaceID surface_id; + const VAAPIFormatDescriptor *desc; + VAImageFormat *image_format; + VAAPIMapping *map; + VAStatus vas; + void *address = NULL; + int err, i; + + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Map surface %#x.\n", surface_id); + + if (!ctx->derive_works && (flags & AV_HWFRAME_MAP_DIRECT)) { + // Requested direct mapping but it is not possible. + return AVERROR(EINVAL); + } + if (dst->format == AV_PIX_FMT_NONE) + dst->format = hwfc->sw_format; + if (dst->format != hwfc->sw_format && (flags & AV_HWFRAME_MAP_DIRECT)) { + // Requested direct mapping but the formats do not match. + return AVERROR(EINVAL); + } + + err = vaapi_get_image_format(hwfc->device_ctx, dst->format, &image_format); + if (err < 0) { + // Requested format is not a valid output format. + return AVERROR(EINVAL); + } + + map = av_malloc(sizeof(*map)); + if (!map) + return AVERROR(ENOMEM); + map->flags = flags; + map->image.image_id = VA_INVALID_ID; + + vas = vaSyncSurface(hwctx->display, surface_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to sync surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + // The memory which we map using derive need not be connected to the CPU + // in a way conducive to fast access. On Gen7-Gen9 Intel graphics, the + // memory is mappable but not cached, so normal memcpy()-like access is + // very slow to read it (but writing is ok). It is possible to read much + // faster with a copy routine which is aware of the limitation, but we + // assume for now that the user is not aware of that and would therefore + // prefer not to be given direct-mapped memory if they request read access. + if (ctx->derive_works && dst->format == hwfc->sw_format && + ((flags & AV_HWFRAME_MAP_DIRECT) || !(flags & AV_HWFRAME_MAP_READ))) { + vas = vaDeriveImage(hwctx->display, surface_id, &map->image); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + if (map->image.format.fourcc != image_format->fourcc) { + av_log(hwfc, AV_LOG_ERROR, "Derive image of surface %#x " + "is in wrong format: expected %#08x, got %#08x.\n", + surface_id, image_format->fourcc, map->image.format.fourcc); + err = AVERROR(EIO); + goto fail; + } + map->flags |= AV_HWFRAME_MAP_DIRECT; + } else { + vas = vaCreateImage(hwctx->display, image_format, + hwfc->width, hwfc->height, &map->image); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to create image for " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + if (!(flags & AV_HWFRAME_MAP_OVERWRITE)) { + vas = vaGetImage(hwctx->display, surface_id, 0, 0, + hwfc->width, hwfc->height, map->image.image_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to read image from " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + } + } + + vas = vaMapBuffer(hwctx->display, map->image.buf, &address); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to map image from surface " + "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + err = ff_hwframe_map_create(src->hw_frames_ctx, + dst, src, &vaapi_unmap_frame, map); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + + for (i = 0; i < map->image.num_planes; i++) { + dst->data[i] = (uint8_t*)address + map->image.offsets[i]; + dst->linesize[i] = map->image.pitches[i]; + } + + desc = vaapi_format_from_fourcc(map->image.format.fourcc); + if (desc && desc->chroma_planes_swapped) { + // Chroma planes are YVU rather than YUV, so swap them. + FFSWAP(uint8_t*, dst->data[1], dst->data[2]); + } + + return 0; + +fail: + if (map) { + if (address) + vaUnmapBuffer(hwctx->display, map->image.buf); + if (map->image.image_id != VA_INVALID_ID) + vaDestroyImage(hwctx->display, map->image.image_id); + av_free(map); + } + return err; +} + +static int vaapi_transfer_data_from(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (dst->width > hwfc->width || dst->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + err = vaapi_map_frame(hwfc, map, src, AV_HWFRAME_MAP_READ); + if (err) + goto fail; + + map->width = dst->width; + map->height = dst->height; + + err = av_frame_copy(dst, map); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int vaapi_transfer_data_to(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (src->width > hwfc->width || src->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = src->format; + + err = vaapi_map_frame(hwfc, map, dst, AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); + if (err) + goto fail; + + map->width = src->width; + map->height = src->height; + + err = av_frame_copy(map, src); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int vaapi_map_to_memory(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + int err; + + if (dst->format != AV_PIX_FMT_NONE) { + err = vaapi_get_image_format(hwfc->device_ctx, dst->format, NULL); + if (err < 0) + return AVERROR(ENOSYS); + } + + err = vaapi_map_frame(hwfc, dst, src, flags); + if (err) + return err; + + err = av_frame_copy_props(dst, src); + if (err) + return err; + + return 0; +} + +#if CONFIG_LIBDRM + +#define DRM_MAP(va, layers, ...) { \ + VA_FOURCC_ ## va, \ + layers, \ + { __VA_ARGS__ } \ + } +static const struct { + uint32_t va_fourcc; + int nb_layer_formats; + uint32_t layer_formats[AV_DRM_MAX_PLANES]; +} vaapi_drm_format_map[] = { +#ifdef DRM_FORMAT_R8 + DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_RG88), +#endif + DRM_MAP(NV12, 1, DRM_FORMAT_NV12), +#if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16) + DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616), +#endif + DRM_MAP(BGRA, 1, DRM_FORMAT_ARGB8888), + DRM_MAP(BGRX, 1, DRM_FORMAT_XRGB8888), + DRM_MAP(RGBA, 1, DRM_FORMAT_ABGR8888), + DRM_MAP(RGBX, 1, DRM_FORMAT_XBGR8888), +#ifdef VA_FOURCC_ABGR + DRM_MAP(ABGR, 1, DRM_FORMAT_RGBA8888), + DRM_MAP(XBGR, 1, DRM_FORMAT_RGBX8888), +#endif + DRM_MAP(ARGB, 1, DRM_FORMAT_BGRA8888), + DRM_MAP(XRGB, 1, DRM_FORMAT_BGRX8888), +}; +#undef DRM_MAP + +static void vaapi_unmap_from_drm(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + + VASurfaceID surface_id = (VASurfaceID)(uintptr_t)hwmap->priv; + + av_log(dst_fc, AV_LOG_DEBUG, "Destroy surface %#x.\n", surface_id); + + vaDestroySurfaces(dst_dev->display, &surface_id, 1); +} + +static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVHWFramesContext *dst_fc = + (AVHWFramesContext*)dst->hw_frames_ctx->data; + AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + const AVDRMFrameDescriptor *desc; + const VAAPIFormatDescriptor *format_desc; + VASurfaceID surface_id; + VAStatus vas; + uint32_t va_fourcc; + int err, i, j, k; + + unsigned long buffer_handle; + VASurfaceAttribExternalBuffers buffer_desc; + VASurfaceAttrib attrs[2] = { + { + .type = VASurfaceAttribMemoryType, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME, + }, + { + .type = VASurfaceAttribExternalBufferDescriptor, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypePointer, + .value.value.p = &buffer_desc, + } + }; + + desc = (AVDRMFrameDescriptor*)src->data[0]; + + if (desc->nb_objects != 1) { + av_log(dst_fc, AV_LOG_ERROR, "VAAPI can only map frames " + "made from a single DRM object.\n"); + return AVERROR(EINVAL); + } + + va_fourcc = 0; + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { + if (desc->nb_layers != vaapi_drm_format_map[i].nb_layer_formats) + continue; + for (j = 0; j < desc->nb_layers; j++) { + if (desc->layers[j].format != + vaapi_drm_format_map[i].layer_formats[j]) + break; + } + if (j != desc->nb_layers) + continue; + va_fourcc = vaapi_drm_format_map[i].va_fourcc; + break; + } + if (!va_fourcc) { + av_log(dst_fc, AV_LOG_ERROR, "DRM format not supported " + "by VAAPI.\n"); + return AVERROR(EINVAL); + } + + av_log(dst_fc, AV_LOG_DEBUG, "Map DRM object %d to VAAPI as " + "%08x.\n", desc->objects[0].fd, va_fourcc); + + format_desc = vaapi_format_from_fourcc(va_fourcc); + av_assert0(format_desc); + + buffer_handle = desc->objects[0].fd; + buffer_desc.pixel_format = va_fourcc; + buffer_desc.width = src_fc->width; + buffer_desc.height = src_fc->height; + buffer_desc.data_size = desc->objects[0].size; + buffer_desc.buffers = &buffer_handle; + buffer_desc.num_buffers = 1; + buffer_desc.flags = 0; + + k = 0; + for (i = 0; i < desc->nb_layers; i++) { + for (j = 0; j < desc->layers[i].nb_planes; j++) { + buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch; + buffer_desc.offsets[k] = desc->layers[i].planes[j].offset; + ++k; + } + } + buffer_desc.num_planes = k; + + if (format_desc->chroma_planes_swapped && + buffer_desc.num_planes == 3) { + FFSWAP(uint32_t, buffer_desc.pitches[1], buffer_desc.pitches[2]); + FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]); + } + + vas = vaCreateSurfaces(dst_dev->display, format_desc->rt_format, + src->width, src->height, + &surface_id, 1, + attrs, FF_ARRAY_ELEMS(attrs)); + if (vas != VA_STATUS_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create surface from DRM " + "object: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + av_log(dst_fc, AV_LOG_DEBUG, "Create surface %#x.\n", surface_id); + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &vaapi_unmap_from_drm, + (void*)(uintptr_t)surface_id); + if (err < 0) + return err; + + dst->width = src->width; + dst->height = src->height; + dst->data[3] = (uint8_t*)(uintptr_t)surface_id; + + av_log(dst_fc, AV_LOG_DEBUG, "Mapped DRM object %d to " + "surface %#x.\n", desc->objects[0].fd, surface_id); + + return 0; +} + +#if VA_CHECK_VERSION(1, 1, 0) +static void vaapi_unmap_to_drm_esh(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + AVDRMFrameDescriptor *drm_desc = hwmap->priv; + int i; + + for (i = 0; i < drm_desc->nb_objects; i++) + close(drm_desc->objects[i].fd); + + av_freep(&drm_desc); +} + +static int vaapi_map_to_drm_esh(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VASurfaceID surface_id; + VAStatus vas; + VADRMPRIMESurfaceDescriptor va_desc; + AVDRMFrameDescriptor *drm_desc = NULL; + uint32_t export_flags; + int err, i, j; + + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + + export_flags = VA_EXPORT_SURFACE_SEPARATE_LAYERS; + if (flags & AV_HWFRAME_MAP_READ) + export_flags |= VA_EXPORT_SURFACE_READ_ONLY; + if (flags & AV_HWFRAME_MAP_WRITE) + export_flags |= VA_EXPORT_SURFACE_WRITE_ONLY; + + vas = vaExportSurfaceHandle(hwctx->display, surface_id, + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, + export_flags, &va_desc); + if (vas != VA_STATUS_SUCCESS) { + if (vas == VA_STATUS_ERROR_UNIMPLEMENTED) + return AVERROR(ENOSYS); + av_log(hwfc, AV_LOG_ERROR, "Failed to export surface %#x: " + "%d (%s).\n", surface_id, vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + drm_desc = av_mallocz(sizeof(*drm_desc)); + if (!drm_desc) { + err = AVERROR(ENOMEM); + goto fail; + } + + // By some bizarre coincidence, these structures are very similar... + drm_desc->nb_objects = va_desc.num_objects; + for (i = 0; i < va_desc.num_objects; i++) { + drm_desc->objects[i].fd = va_desc.objects[i].fd; + drm_desc->objects[i].size = va_desc.objects[i].size; + drm_desc->objects[i].format_modifier = + va_desc.objects[i].drm_format_modifier; + } + drm_desc->nb_layers = va_desc.num_layers; + for (i = 0; i < va_desc.num_layers; i++) { + drm_desc->layers[i].format = va_desc.layers[i].drm_format; + drm_desc->layers[i].nb_planes = va_desc.layers[i].num_planes; + for (j = 0; j < va_desc.layers[i].num_planes; j++) { + drm_desc->layers[i].planes[j].object_index = + va_desc.layers[i].object_index[j]; + drm_desc->layers[i].planes[j].offset = + va_desc.layers[i].offset[j]; + drm_desc->layers[i].planes[j].pitch = + va_desc.layers[i].pitch[j]; + } + } + + err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, + &vaapi_unmap_to_drm_esh, drm_desc); + if (err < 0) + goto fail; + + dst->width = src->width; + dst->height = src->height; + dst->data[0] = (uint8_t*)drm_desc; + + return 0; + +fail: + for (i = 0; i < va_desc.num_objects; i++) + close(va_desc.objects[i].fd); + av_freep(&drm_desc); + return err; +} +#endif + +#if VA_CHECK_VERSION(0, 36, 0) +typedef struct VAAPIDRMImageBufferMapping { + VAImage image; + VABufferInfo buffer_info; + + AVDRMFrameDescriptor drm_desc; +} VAAPIDRMImageBufferMapping; + +static void vaapi_unmap_to_drm_abh(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIDRMImageBufferMapping *mapping = hwmap->priv; + VASurfaceID surface_id; + VAStatus vas; + + surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Unmap VAAPI surface %#x from DRM.\n", + surface_id); + + // DRM PRIME file descriptors are closed by vaReleaseBufferHandle(), + // so we shouldn't close them separately. + + vas = vaReleaseBufferHandle(hwctx->display, mapping->image.buf); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release buffer " + "handle of image %#x (derived from surface %#x): " + "%d (%s).\n", mapping->image.buf, surface_id, + vas, vaErrorStr(vas)); + } + + vas = vaDestroyImage(hwctx->display, mapping->image.image_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image " + "derived from surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + } + + av_free(mapping); +} + +static int vaapi_map_to_drm_abh(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIDRMImageBufferMapping *mapping = NULL; + VASurfaceID surface_id; + VAStatus vas; + int err, i, p; + + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Map VAAPI surface %#x to DRM.\n", + surface_id); + + mapping = av_mallocz(sizeof(*mapping)); + if (!mapping) + return AVERROR(ENOMEM); + + vas = vaDeriveImage(hwctx->display, surface_id, + &mapping->image); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { + if (vaapi_drm_format_map[i].va_fourcc == + mapping->image.format.fourcc) + break; + } + if (i >= FF_ARRAY_ELEMS(vaapi_drm_format_map)) { + av_log(hwfc, AV_LOG_ERROR, "No matching DRM format for " + "VAAPI format %#x.\n", mapping->image.format.fourcc); + err = AVERROR(EINVAL); + goto fail_derived; + } + + mapping->buffer_info.mem_type = + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; + + mapping->drm_desc.nb_layers = + vaapi_drm_format_map[i].nb_layer_formats; + if (mapping->drm_desc.nb_layers > 1) { + if (mapping->drm_desc.nb_layers != mapping->image.num_planes) { + av_log(hwfc, AV_LOG_ERROR, "Image properties do not match " + "expected format: got %d planes, but expected %d.\n", + mapping->image.num_planes, mapping->drm_desc.nb_layers); + err = AVERROR(EINVAL); + goto fail_derived; + } + + for(p = 0; p < mapping->drm_desc.nb_layers; p++) { + mapping->drm_desc.layers[p] = (AVDRMLayerDescriptor) { + .format = vaapi_drm_format_map[i].layer_formats[p], + .nb_planes = 1, + .planes[0] = { + .object_index = 0, + .offset = mapping->image.offsets[p], + .pitch = mapping->image.pitches[p], + }, + }; + } + } else { + mapping->drm_desc.layers[0].format = + vaapi_drm_format_map[i].layer_formats[0]; + mapping->drm_desc.layers[0].nb_planes = mapping->image.num_planes; + for (p = 0; p < mapping->image.num_planes; p++) { + mapping->drm_desc.layers[0].planes[p] = (AVDRMPlaneDescriptor) { + .object_index = 0, + .offset = mapping->image.offsets[p], + .pitch = mapping->image.pitches[p], + }; + } + } + + vas = vaAcquireBufferHandle(hwctx->display, mapping->image.buf, + &mapping->buffer_info); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to get buffer " + "handle from image %#x (derived from surface %#x): " + "%d (%s).\n", mapping->image.buf, surface_id, + vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_derived; + } + + av_log(hwfc, AV_LOG_DEBUG, "DRM PRIME fd is %ld.\n", + mapping->buffer_info.handle); + + mapping->drm_desc.nb_objects = 1; + mapping->drm_desc.objects[0] = (AVDRMObjectDescriptor) { + .fd = mapping->buffer_info.handle, + .size = mapping->image.data_size, + // There is no way to get the format modifier with this API. + .format_modifier = DRM_FORMAT_MOD_INVALID, + }; + + err = ff_hwframe_map_create(src->hw_frames_ctx, + dst, src, &vaapi_unmap_to_drm_abh, + mapping); + if (err < 0) + goto fail_mapped; + + dst->data[0] = (uint8_t*)&mapping->drm_desc; + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail_mapped: + vaReleaseBufferHandle(hwctx->display, mapping->image.buf); +fail_derived: + vaDestroyImage(hwctx->display, mapping->image.image_id); +fail: + av_freep(&mapping); + return err; +} +#endif + +static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ +#if VA_CHECK_VERSION(1, 1, 0) + int err; + err = vaapi_map_to_drm_esh(hwfc, dst, src, flags); + if (err != AVERROR(ENOSYS)) + return err; +#endif +#if VA_CHECK_VERSION(0, 36, 0) + return vaapi_map_to_drm_abh(hwfc, dst, src, flags); +#endif + return AVERROR(ENOSYS); +} + +#endif /* CONFIG_LIBDRM */ + +static int vaapi_map_to(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + switch (src->format) { +#if CONFIG_LIBDRM + case AV_PIX_FMT_DRM_PRIME: + return vaapi_map_from_drm(hwfc, dst, src, flags); +#endif + default: + return AVERROR(ENOSYS); + } +} + +static int vaapi_map_from(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + switch (dst->format) { +#if CONFIG_LIBDRM + case AV_PIX_FMT_DRM_PRIME: + return vaapi_map_to_drm(hwfc, dst, src, flags); +#endif + default: + return vaapi_map_to_memory(hwfc, dst, src, flags); + } +} + +static void vaapi_device_free(AVHWDeviceContext *ctx) +{ + AVVAAPIDeviceContext *hwctx = ctx->hwctx; + VAAPIDevicePriv *priv = ctx->user_opaque; + + if (hwctx->display) + vaTerminate(hwctx->display); + +#if HAVE_VAAPI_X11 + if (priv->x11_display) + XCloseDisplay(priv->x11_display); +#endif + + if (priv->drm_fd >= 0) + close(priv->drm_fd); + + av_freep(&priv); +} + +#if CONFIG_VAAPI_1 +static void vaapi_device_log_error(void *context, const char *message) +{ + AVHWDeviceContext *ctx = context; + + av_log(ctx, AV_LOG_ERROR, "libva: %s", message); +} + +static void vaapi_device_log_info(void *context, const char *message) +{ + AVHWDeviceContext *ctx = context; + + av_log(ctx, AV_LOG_VERBOSE, "libva: %s", message); +} +#endif + +static int vaapi_device_connect(AVHWDeviceContext *ctx, + VADisplay display) +{ + AVVAAPIDeviceContext *hwctx = ctx->hwctx; + int major, minor; + VAStatus vas; + +#if CONFIG_VAAPI_1 + vaSetErrorCallback(display, &vaapi_device_log_error, ctx); + vaSetInfoCallback (display, &vaapi_device_log_info, ctx); +#endif + + hwctx->display = display; + + vas = vaInitialize(display, &major, &minor); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI " + "connection: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + av_log(ctx, AV_LOG_VERBOSE, "Initialised VAAPI connection: " + "version %d.%d\n", major, minor); + + return 0; +} + +static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + VAAPIDevicePriv *priv; + VADisplay display = NULL; + const AVDictionaryEntry *ent; + int try_drm, try_x11, try_all; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + priv->drm_fd = -1; + + ctx->user_opaque = priv; + ctx->free = vaapi_device_free; + + ent = av_dict_get(opts, "connection_type", NULL, 0); + if (ent) { + try_all = try_drm = try_x11 = 0; + if (!strcmp(ent->value, "drm")) { + try_drm = 1; + } else if (!strcmp(ent->value, "x11")) { + try_x11 = 1; + } else { + av_log(ctx, AV_LOG_ERROR, "Invalid connection type %s.\n", + ent->value); + return AVERROR(EINVAL); + } + } else { + try_all = 1; + try_drm = HAVE_VAAPI_DRM; + try_x11 = HAVE_VAAPI_X11; + } + +#if HAVE_VAAPI_DRM + while (!display && try_drm) { + // If the device is specified, try to open it as a DRM device node. + // If not, look for a usable render node, possibly restricted to those + // using a specified kernel driver. + int loglevel = try_all ? AV_LOG_VERBOSE : AV_LOG_ERROR; + if (device) { + priv->drm_fd = open(device, O_RDWR); + if (priv->drm_fd < 0) { + av_log(ctx, loglevel, "Failed to open %s as " + "DRM device node.\n", device); + break; + } + } else { + char path[64]; + int n, max_devices = 8; +#if CONFIG_LIBDRM + const AVDictionaryEntry *kernel_driver; + kernel_driver = av_dict_get(opts, "kernel_driver", NULL, 0); +#endif + for (n = 0; n < max_devices; n++) { + snprintf(path, sizeof(path), + "/dev/dri/renderD%d", 128 + n); + priv->drm_fd = open(path, O_RDWR); + if (priv->drm_fd < 0) { + av_log(ctx, AV_LOG_VERBOSE, "Cannot open " + "DRM render node for device %d.\n", n); + break; + } +#if CONFIG_LIBDRM + if (kernel_driver) { + drmVersion *info; + info = drmGetVersion(priv->drm_fd); + if (strcmp(kernel_driver->value, info->name)) { + av_log(ctx, AV_LOG_VERBOSE, "Ignoring device %d " + "with non-matching kernel driver (%s).\n", + n, info->name); + drmFreeVersion(info); + close(priv->drm_fd); + priv->drm_fd = -1; + continue; + } + av_log(ctx, AV_LOG_VERBOSE, "Trying to use " + "DRM render node for device %d, " + "with matching kernel driver (%s).\n", + n, info->name); + drmFreeVersion(info); + } else +#endif + { + av_log(ctx, AV_LOG_VERBOSE, "Trying to use " + "DRM render node for device %d.\n", n); + } + break; + } + if (n >= max_devices) + break; + } + + display = vaGetDisplayDRM(priv->drm_fd); + if (!display) { + av_log(ctx, AV_LOG_VERBOSE, "Cannot open a VA display " + "from DRM device %s.\n", device); + return AVERROR_EXTERNAL; + } + break; + } +#endif + +#if HAVE_VAAPI_X11 + if (!display && try_x11) { + // Try to open the device as an X11 display. + priv->x11_display = XOpenDisplay(device); + if (!priv->x11_display) { + av_log(ctx, AV_LOG_VERBOSE, "Cannot open X11 display " + "%s.\n", XDisplayName(device)); + } else { + display = vaGetDisplay(priv->x11_display); + if (!display) { + av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display " + "from X11 display %s.\n", XDisplayName(device)); + return AVERROR_UNKNOWN; + } + + av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via " + "X11 display %s.\n", XDisplayName(device)); + } + } +#endif + + if (!display) { + if (device) + av_log(ctx, AV_LOG_ERROR, "No VA display found for " + "device %s.\n", device); + else + av_log(ctx, AV_LOG_ERROR, "No VA display found for " + "any default device.\n"); + return AVERROR(EINVAL); + } + + ent = av_dict_get(opts, "driver", NULL, 0); + if (ent) { +#if VA_CHECK_VERSION(0, 38, 0) + VAStatus vas; + vas = vaSetDriverName(display, ent->value); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to set driver name to " + "%s: %d (%s).\n", ent->value, vas, vaErrorStr(vas)); + vaTerminate(display); + return AVERROR_EXTERNAL; + } +#else + av_log(ctx, AV_LOG_WARNING, "Driver name setting is not " + "supported with this VAAPI version.\n"); +#endif + } + + return vaapi_device_connect(ctx, display); +} + +static int vaapi_device_derive(AVHWDeviceContext *ctx, + AVHWDeviceContext *src_ctx, int flags) +{ +#if HAVE_VAAPI_DRM + if (src_ctx->type == AV_HWDEVICE_TYPE_DRM) { + AVDRMDeviceContext *src_hwctx = src_ctx->hwctx; + VADisplay *display; + VAAPIDevicePriv *priv; + + if (src_hwctx->fd < 0) { + av_log(ctx, AV_LOG_ERROR, "DRM instance requires an associated " + "device to derive a VA display from.\n"); + return AVERROR(EINVAL); + } + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + // Inherits the fd from the source context, which will close it. + priv->drm_fd = -1; + + ctx->user_opaque = priv; + ctx->free = &vaapi_device_free; + + display = vaGetDisplayDRM(src_hwctx->fd); + if (!display) { + av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from " + "DRM device.\n"); + return AVERROR(EIO); + } + + return vaapi_device_connect(ctx, display); + } +#endif + return AVERROR(ENOSYS); +} + +const HWContextType ff_hwcontext_type_vaapi = { + .type = AV_HWDEVICE_TYPE_VAAPI, + .name = "VAAPI", + + .device_hwctx_size = sizeof(AVVAAPIDeviceContext), + .device_priv_size = sizeof(VAAPIDeviceContext), + .device_hwconfig_size = sizeof(AVVAAPIHWConfig), + .frames_hwctx_size = sizeof(AVVAAPIFramesContext), + .frames_priv_size = sizeof(VAAPIFramesContext), + + .device_create = &vaapi_device_create, + .device_derive = &vaapi_device_derive, + .device_init = &vaapi_device_init, + .device_uninit = &vaapi_device_uninit, + .frames_get_constraints = &vaapi_frames_get_constraints, + .frames_init = &vaapi_frames_init, + .frames_uninit = &vaapi_frames_uninit, + .frames_get_buffer = &vaapi_get_buffer, + .transfer_get_formats = &vaapi_transfer_get_formats, + .transfer_data_to = &vaapi_transfer_data_to, + .transfer_data_from = &vaapi_transfer_data_from, + .map_to = &vaapi_map_to, + .map_from = &vaapi_map_from, + + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_VAAPI, + AV_PIX_FMT_NONE + }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vaapi.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vaapi.h new file mode 100644 index 000000000..0b2e071cb --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vaapi.h @@ -0,0 +1,117 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VAAPI_H +#define AVUTIL_HWCONTEXT_VAAPI_H + +#include + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_VAAPI. + * + * Dynamic frame pools are supported, but note that any pool used as a render + * target is required to be of fixed size in order to be be usable as an + * argument to vaCreateContext(). + * + * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer set to a VASurfaceID. + */ + +enum { + /** + * The quirks field has been set by the user and should not be detected + * automatically by av_hwdevice_ctx_init(). + */ + AV_VAAPI_DRIVER_QUIRK_USER_SET = (1 << 0), + /** + * The driver does not destroy parameter buffers when they are used by + * vaRenderPicture(). Additional code will be required to destroy them + * separately afterwards. + */ + AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS = (1 << 1), + + /** + * The driver does not support the VASurfaceAttribMemoryType attribute, + * so the surface allocation code will not try to use it. + */ + AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE = (1 << 2), + + /** + * The driver does not support surface attributes at all. + * The surface allocation code will never pass them to surface allocation, + * and the results of the vaQuerySurfaceAttributes() call will be faked. + */ + AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES = (1 << 3), +}; + +/** + * VAAPI connection details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVVAAPIDeviceContext { + /** + * The VADisplay handle, to be filled by the user. + */ + VADisplay display; + /** + * Driver quirks to apply - this is filled by av_hwdevice_ctx_init(), + * with reference to a table of known drivers, unless the + * AV_VAAPI_DRIVER_QUIRK_USER_SET bit is already present. The user + * may need to refer to this field when performing any later + * operations using VAAPI with the same VADisplay. + */ + unsigned int driver_quirks; +} AVVAAPIDeviceContext; + +/** + * VAAPI-specific data associated with a frame pool. + * + * Allocated as AVHWFramesContext.hwctx. + */ +typedef struct AVVAAPIFramesContext { + /** + * Set by the user to apply surface attributes to all surfaces in + * the frame pool. If null, default settings are used. + */ + VASurfaceAttrib *attributes; + int nb_attributes; + /** + * The surfaces IDs of all surfaces in the pool after creation. + * Only valid if AVHWFramesContext.initial_pool_size was positive. + * These are intended to be used as the render_targets arguments to + * vaCreateContext(). + */ + VASurfaceID *surface_ids; + int nb_surfaces; +} AVVAAPIFramesContext; + +/** + * VAAPI hardware pipeline configuration details. + * + * Allocated with av_hwdevice_hwconfig_alloc(). + */ +typedef struct AVVAAPIHWConfig { + /** + * ID of a VAAPI pipeline configuration. + */ + VAConfigID config_id; +} AVVAAPIHWConfig; + +#endif /* AVUTIL_HWCONTEXT_VAAPI_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vdpau.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vdpau.c new file mode 100644 index 000000000..6b8c1d5f7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vdpau.c @@ -0,0 +1,511 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include + +#include + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_vdpau.h" +#include "mem.h" +#include "pixfmt.h" +#include "pixdesc.h" + +typedef struct VDPAUDeviceContext { + VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *get_transfer_caps; + VdpVideoSurfaceGetBitsYCbCr *get_data; + VdpVideoSurfacePutBitsYCbCr *put_data; + VdpVideoSurfaceCreate *surf_create; + VdpVideoSurfaceDestroy *surf_destroy; + + enum AVPixelFormat *pix_fmts[3]; + int nb_pix_fmts[3]; +} VDPAUDeviceContext; + +typedef struct VDPAUFramesContext { + VdpVideoSurfaceGetBitsYCbCr *get_data; + VdpVideoSurfacePutBitsYCbCr *put_data; + VdpChromaType chroma_type; + int chroma_idx; + + const enum AVPixelFormat *pix_fmts; + int nb_pix_fmts; +} VDPAUFramesContext; + +typedef struct VDPAUPixFmtMap { + VdpYCbCrFormat vdpau_fmt; + enum AVPixelFormat pix_fmt; +} VDPAUPixFmtMap; + +static const VDPAUPixFmtMap pix_fmts_420[] = { + { VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV12 }, + { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV420P }, + { 0, AV_PIX_FMT_NONE, }, +}; + +static const VDPAUPixFmtMap pix_fmts_422[] = { + { VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV16 }, + { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV422P }, + { VDP_YCBCR_FORMAT_UYVY, AV_PIX_FMT_UYVY422 }, + { VDP_YCBCR_FORMAT_YUYV, AV_PIX_FMT_YUYV422 }, + { 0, AV_PIX_FMT_NONE, }, +}; + +static const VDPAUPixFmtMap pix_fmts_444[] = { +#ifdef VDP_YCBCR_FORMAT_Y_U_V_444 + { VDP_YCBCR_FORMAT_Y_U_V_444, AV_PIX_FMT_YUV444P }, +#endif + { 0, AV_PIX_FMT_NONE, }, +}; + +static const struct { + VdpChromaType chroma_type; + enum AVPixelFormat frames_sw_format; + const VDPAUPixFmtMap *map; +} vdpau_pix_fmts[] = { + { VDP_CHROMA_TYPE_420, AV_PIX_FMT_YUV420P, pix_fmts_420 }, + { VDP_CHROMA_TYPE_422, AV_PIX_FMT_YUV422P, pix_fmts_422 }, + { VDP_CHROMA_TYPE_444, AV_PIX_FMT_YUV444P, pix_fmts_444 }, +}; + +static int count_pixfmts(const VDPAUPixFmtMap *map) +{ + int count = 0; + while (map->pix_fmt != AV_PIX_FMT_NONE) { + map++; + count++; + } + return count; +} + +static int vdpau_init_pixmfts(AVHWDeviceContext *ctx) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + VDPAUDeviceContext *priv = ctx->internal->priv; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(priv->pix_fmts); i++) { + const VDPAUPixFmtMap *map = vdpau_pix_fmts[i].map; + int nb_pix_fmts; + + nb_pix_fmts = count_pixfmts(map); + priv->pix_fmts[i] = av_malloc_array(nb_pix_fmts + 1, sizeof(*priv->pix_fmts[i])); + if (!priv->pix_fmts[i]) + return AVERROR(ENOMEM); + + nb_pix_fmts = 0; + while (map->pix_fmt != AV_PIX_FMT_NONE) { + VdpBool supported; + VdpStatus err = priv->get_transfer_caps(hwctx->device, vdpau_pix_fmts[i].chroma_type, + map->vdpau_fmt, &supported); + if (err == VDP_STATUS_OK && supported) + priv->pix_fmts[i][nb_pix_fmts++] = map->pix_fmt; + map++; + } + priv->pix_fmts[i][nb_pix_fmts++] = AV_PIX_FMT_NONE; + priv->nb_pix_fmts[i] = nb_pix_fmts; + } + + return 0; +} + +#define GET_CALLBACK(id, result) \ +do { \ + void *tmp; \ + err = hwctx->get_proc_address(hwctx->device, id, &tmp); \ + if (err != VDP_STATUS_OK) { \ + av_log(ctx, AV_LOG_ERROR, "Error getting the " #id " callback.\n"); \ + return AVERROR_UNKNOWN; \ + } \ + result = tmp; \ +} while (0) + +static int vdpau_device_init(AVHWDeviceContext *ctx) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + VDPAUDeviceContext *priv = ctx->internal->priv; + VdpStatus err; + int ret; + + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, + priv->get_transfer_caps); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, priv->get_data); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, priv->put_data); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_CREATE, priv->surf_create); + GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, priv->surf_destroy); + + ret = vdpau_init_pixmfts(ctx); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error querying the supported pixel formats\n"); + return ret; + } + + return 0; +} + +static void vdpau_device_uninit(AVHWDeviceContext *ctx) +{ + VDPAUDeviceContext *priv = ctx->internal->priv; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(priv->pix_fmts); i++) + av_freep(&priv->pix_fmts[i]); +} + +static int vdpau_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + VDPAUDeviceContext *priv = ctx->internal->priv; + int nb_sw_formats = 0; + int i; + + constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(vdpau_pix_fmts) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(vdpau_pix_fmts); i++) { + if (priv->nb_pix_fmts[i] > 1) + constraints->valid_sw_formats[nb_sw_formats++] = vdpau_pix_fmts[i].frames_sw_format; + } + constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) + return AVERROR(ENOMEM); + + constraints->valid_hw_formats[0] = AV_PIX_FMT_VDPAU; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + return 0; +} + +static void vdpau_buffer_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *ctx = opaque; + VDPAUDeviceContext *device_priv = ctx->device_ctx->internal->priv; + VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)data; + + device_priv->surf_destroy(surf); +} + +static AVBufferRef *vdpau_pool_alloc(void *opaque, int size) +{ + AVHWFramesContext *ctx = opaque; + VDPAUFramesContext *priv = ctx->internal->priv; + AVVDPAUDeviceContext *device_hwctx = ctx->device_ctx->hwctx; + VDPAUDeviceContext *device_priv = ctx->device_ctx->internal->priv; + + AVBufferRef *ret; + VdpVideoSurface surf; + VdpStatus err; + + err = device_priv->surf_create(device_hwctx->device, priv->chroma_type, + ctx->width, ctx->height, &surf); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "Error allocating a VDPAU video surface\n"); + return NULL; + } + + ret = av_buffer_create((uint8_t*)(uintptr_t)surf, sizeof(surf), + vdpau_buffer_free, ctx, AV_BUFFER_FLAG_READONLY); + if (!ret) { + device_priv->surf_destroy(surf); + return NULL; + } + + return ret; +} + +static int vdpau_frames_init(AVHWFramesContext *ctx) +{ + VDPAUDeviceContext *device_priv = ctx->device_ctx->internal->priv; + VDPAUFramesContext *priv = ctx->internal->priv; + + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(vdpau_pix_fmts); i++) { + if (vdpau_pix_fmts[i].frames_sw_format == ctx->sw_format) { + priv->chroma_type = vdpau_pix_fmts[i].chroma_type; + priv->chroma_idx = i; + priv->pix_fmts = device_priv->pix_fmts[i]; + priv->nb_pix_fmts = device_priv->nb_pix_fmts[i]; + break; + } + } + if (priv->nb_pix_fmts < 2) { + av_log(ctx, AV_LOG_ERROR, "Unsupported sw format: %s\n", + av_get_pix_fmt_name(ctx->sw_format)); + return AVERROR(ENOSYS); + } + + if (!ctx->pool) { + ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(VdpVideoSurface), ctx, + vdpau_pool_alloc, NULL); + if (!ctx->internal->pool_internal) + return AVERROR(ENOMEM); + } + + priv->get_data = device_priv->get_data; + priv->put_data = device_priv->put_data; + + return 0; +} + +static int vdpau_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_VDPAU; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int vdpau_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + VDPAUFramesContext *priv = ctx->internal->priv; + + enum AVPixelFormat *fmts; + + if (priv->nb_pix_fmts == 1) { + av_log(ctx, AV_LOG_ERROR, + "No target formats are supported for this chroma type\n"); + return AVERROR(ENOSYS); + } + + fmts = av_malloc_array(priv->nb_pix_fmts, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + memcpy(fmts, priv->pix_fmts, sizeof(*fmts) * (priv->nb_pix_fmts)); + *formats = fmts; + + return 0; +} + +static int vdpau_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + VDPAUFramesContext *priv = ctx->internal->priv; + VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)src->data[3]; + + void *data[3]; + uint32_t linesize[3]; + + const VDPAUPixFmtMap *map; + VdpYCbCrFormat vdpau_format; + VdpStatus err; + int i; + + for (i = 0; i< FF_ARRAY_ELEMS(data) && dst->data[i]; i++) { + data[i] = dst->data[i]; + if (dst->linesize[i] < 0 || dst->linesize[i] > UINT32_MAX) { + av_log(ctx, AV_LOG_ERROR, + "The linesize %d cannot be represented as uint32\n", + dst->linesize[i]); + return AVERROR(ERANGE); + } + linesize[i] = dst->linesize[i]; + } + + map = vdpau_pix_fmts[priv->chroma_idx].map; + for (i = 0; map[i].pix_fmt != AV_PIX_FMT_NONE; i++) { + if (map[i].pix_fmt == dst->format) { + vdpau_format = map[i].vdpau_fmt; + break; + } + } + if (map[i].pix_fmt == AV_PIX_FMT_NONE) { + av_log(ctx, AV_LOG_ERROR, + "Unsupported target pixel format: %s\n", + av_get_pix_fmt_name(dst->format)); + return AVERROR(EINVAL); + } + + if ((vdpau_format == VDP_YCBCR_FORMAT_YV12) +#ifdef VDP_YCBCR_FORMAT_Y_U_V_444 + || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444) +#endif + ) + FFSWAP(void*, data[1], data[2]); + + err = priv->get_data(surf, vdpau_format, data, linesize); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "Error retrieving the data from a VDPAU surface\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +static int vdpau_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + VDPAUFramesContext *priv = ctx->internal->priv; + VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)dst->data[3]; + + const void *data[3]; + uint32_t linesize[3]; + + const VDPAUPixFmtMap *map; + VdpYCbCrFormat vdpau_format; + VdpStatus err; + int i; + + for (i = 0; i< FF_ARRAY_ELEMS(data) && src->data[i]; i++) { + data[i] = src->data[i]; + if (src->linesize[i] < 0 || src->linesize[i] > UINT32_MAX) { + av_log(ctx, AV_LOG_ERROR, + "The linesize %d cannot be represented as uint32\n", + src->linesize[i]); + return AVERROR(ERANGE); + } + linesize[i] = src->linesize[i]; + } + + map = vdpau_pix_fmts[priv->chroma_idx].map; + for (i = 0; map[i].pix_fmt != AV_PIX_FMT_NONE; i++) { + if (map[i].pix_fmt == src->format) { + vdpau_format = map[i].vdpau_fmt; + break; + } + } + if (map[i].pix_fmt == AV_PIX_FMT_NONE) { + av_log(ctx, AV_LOG_ERROR, + "Unsupported source pixel format: %s\n", + av_get_pix_fmt_name(src->format)); + return AVERROR(EINVAL); + } + + if ((vdpau_format == VDP_YCBCR_FORMAT_YV12) +#ifdef VDP_YCBCR_FORMAT_Y_U_V_444 + || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444) +#endif + ) + FFSWAP(const void*, data[1], data[2]); + + err = priv->put_data(surf, vdpau_format, data, linesize); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "Error uploading the data to a VDPAU surface\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +#if HAVE_VDPAU_X11 +#include +#include + +typedef struct VDPAUDevicePriv { + VdpDeviceDestroy *device_destroy; + Display *dpy; +} VDPAUDevicePriv; + +static void vdpau_device_free(AVHWDeviceContext *ctx) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + VDPAUDevicePriv *priv = ctx->user_opaque; + + if (priv->device_destroy) + priv->device_destroy(hwctx->device); + if (priv->dpy) + XCloseDisplay(priv->dpy); + av_freep(&priv); +} + +static int vdpau_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + + VDPAUDevicePriv *priv; + VdpStatus err; + VdpGetInformationString *get_information_string; + const char *display, *vendor; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + ctx->user_opaque = priv; + ctx->free = vdpau_device_free; + + priv->dpy = XOpenDisplay(device); + if (!priv->dpy) { + av_log(ctx, AV_LOG_ERROR, "Cannot open the X11 display %s.\n", + XDisplayName(device)); + return AVERROR_UNKNOWN; + } + display = XDisplayString(priv->dpy); + + err = vdp_device_create_x11(priv->dpy, XDefaultScreen(priv->dpy), + &hwctx->device, &hwctx->get_proc_address); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "VDPAU device creation on X11 display %s failed.\n", + display); + return AVERROR_UNKNOWN; + } + + GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string); + GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, priv->device_destroy); + + get_information_string(&vendor); + av_log(ctx, AV_LOG_VERBOSE, "Successfully created a VDPAU device (%s) on " + "X11 display %s\n", vendor, display); + + return 0; +} +#endif + +const HWContextType ff_hwcontext_type_vdpau = { + .type = AV_HWDEVICE_TYPE_VDPAU, + .name = "VDPAU", + + .device_hwctx_size = sizeof(AVVDPAUDeviceContext), + .device_priv_size = sizeof(VDPAUDeviceContext), + .frames_priv_size = sizeof(VDPAUFramesContext), + +#if HAVE_VDPAU_X11 + .device_create = vdpau_device_create, +#endif + .device_init = vdpau_device_init, + .device_uninit = vdpau_device_uninit, + .frames_get_constraints = vdpau_frames_get_constraints, + .frames_init = vdpau_frames_init, + .frames_get_buffer = vdpau_get_buffer, + .transfer_get_formats = vdpau_transfer_get_formats, + .transfer_data_to = vdpau_transfer_data_to, + .transfer_data_from = vdpau_transfer_data_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU, AV_PIX_FMT_NONE }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vdpau.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vdpau.h new file mode 100644 index 000000000..1b7ea1e44 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_vdpau.h @@ -0,0 +1,44 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VDPAU_H +#define AVUTIL_HWCONTEXT_VDPAU_H + +#include + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_VDPAU. + * + * This API supports dynamic frame pools. AVHWFramesContext.pool must return + * AVBufferRefs whose data pointer is a VdpVideoSurface. + */ + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVVDPAUDeviceContext { + VdpDevice device; + VdpGetProcAddress *get_proc_address; +} AVVDPAUDeviceContext; + +/** + * AVHWFramesContext.hwctx is currently not used + */ + +#endif /* AVUTIL_HWCONTEXT_VDPAU_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_videotoolbox.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_videotoolbox.c new file mode 100644 index 000000000..6eac2c077 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_videotoolbox.c @@ -0,0 +1,246 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include + +#include + +#include "buffer.h" +#include "common.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_videotoolbox.h" +#include "mem.h" +#include "pixfmt.h" +#include "pixdesc.h" + +static const struct { + uint32_t cv_fmt; + enum AVPixelFormat pix_fmt; +} cv_pix_fmts[] = { + { kCVPixelFormatType_420YpCbCr8Planar, AV_PIX_FMT_YUV420P }, + { kCVPixelFormatType_422YpCbCr8, AV_PIX_FMT_UYVY422 }, + { kCVPixelFormatType_32BGRA, AV_PIX_FMT_BGRA }, +#ifdef kCFCoreFoundationVersionNumber10_7 + { kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, AV_PIX_FMT_NV12 }, +#endif +#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE + { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange, AV_PIX_FMT_P010 }, +#endif +}; + +enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(cv_pix_fmts); i++) { + if (cv_pix_fmts[i].cv_fmt == cv_fmt) + return cv_pix_fmts[i].pix_fmt; + } + return AV_PIX_FMT_NONE; +} + +uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(cv_pix_fmts); i++) { + if (cv_pix_fmts[i].pix_fmt == pix_fmt) + return cv_pix_fmts[i].cv_fmt; + } + return 0; +} + +static int vt_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) +{ + frame->buf[0] = av_buffer_pool_get(ctx->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[3] = frame->buf[0]->data; + frame->format = AV_PIX_FMT_VIDEOTOOLBOX; + frame->width = ctx->width; + frame->height = ctx->height; + + return 0; +} + +static int vt_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + return 0; +} + +static void vt_unmap(AVHWFramesContext *ctx, HWMapDescriptor *hwmap) +{ + CVPixelBufferRef pixbuf = (CVPixelBufferRef)hwmap->source->data[3]; + + CVPixelBufferUnlockBaseAddress(pixbuf, (uintptr_t)hwmap->priv); +} + +static int vt_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, + int flags) +{ + CVPixelBufferRef pixbuf = (CVPixelBufferRef)src->data[3]; + OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf); + CVReturn err; + uint32_t map_flags = 0; + int ret; + int i; + enum AVPixelFormat format; + + format = av_map_videotoolbox_format_to_pixfmt(pixel_format); + if (dst->format != format) { + av_log(ctx, AV_LOG_ERROR, "Unsupported or mismatching pixel format: %s\n", + av_fourcc2str(pixel_format)); + return AVERROR_UNKNOWN; + } + + if (CVPixelBufferGetWidth(pixbuf) != ctx->width || + CVPixelBufferGetHeight(pixbuf) != ctx->height) { + av_log(ctx, AV_LOG_ERROR, "Inconsistent frame dimensions.\n"); + return AVERROR_UNKNOWN; + } + + if (flags == AV_HWFRAME_MAP_READ) + map_flags = kCVPixelBufferLock_ReadOnly; + + err = CVPixelBufferLockBaseAddress(pixbuf, map_flags); + if (err != kCVReturnSuccess) { + av_log(ctx, AV_LOG_ERROR, "Error locking the pixel buffer.\n"); + return AVERROR_UNKNOWN; + } + + if (CVPixelBufferIsPlanar(pixbuf)) { + int planes = CVPixelBufferGetPlaneCount(pixbuf); + for (i = 0; i < planes; i++) { + dst->data[i] = CVPixelBufferGetBaseAddressOfPlane(pixbuf, i); + dst->linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(pixbuf, i); + } + } else { + dst->data[0] = CVPixelBufferGetBaseAddress(pixbuf); + dst->linesize[0] = CVPixelBufferGetBytesPerRow(pixbuf); + } + + ret = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, vt_unmap, + (void *)(uintptr_t)map_flags); + if (ret < 0) + goto unlock; + + return 0; + +unlock: + CVPixelBufferUnlockBaseAddress(pixbuf, map_flags); + return ret; +} + +static int vt_transfer_data_from(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (dst->width > hwfc->width || dst->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = dst->format; + + err = vt_map_frame(hwfc, map, src, AV_HWFRAME_MAP_READ); + if (err) + goto fail; + + map->width = dst->width; + map->height = dst->height; + + err = av_frame_copy(dst, map); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int vt_transfer_data_to(AVHWFramesContext *hwfc, + AVFrame *dst, const AVFrame *src) +{ + AVFrame *map; + int err; + + if (src->width > hwfc->width || src->height > hwfc->height) + return AVERROR(EINVAL); + + map = av_frame_alloc(); + if (!map) + return AVERROR(ENOMEM); + map->format = src->format; + + err = vt_map_frame(hwfc, map, dst, AV_HWFRAME_MAP_WRITE | AV_HWFRAME_MAP_OVERWRITE); + if (err) + goto fail; + + map->width = src->width; + map->height = src->height; + + err = av_frame_copy(map, src); + if (err) + goto fail; + + err = 0; +fail: + av_frame_free(&map); + return err; +} + +static int vt_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + if (device && device[0]) { + av_log(ctx, AV_LOG_ERROR, "Device selection unsupported.\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + +const HWContextType ff_hwcontext_type_videotoolbox = { + .type = AV_HWDEVICE_TYPE_VIDEOTOOLBOX, + .name = "videotoolbox", + + .device_create = vt_device_create, + .frames_get_buffer = vt_get_buffer, + .transfer_get_formats = vt_transfer_get_formats, + .transfer_data_to = vt_transfer_data_to, + .transfer_data_from = vt_transfer_data_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VIDEOTOOLBOX, AV_PIX_FMT_NONE }, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_videotoolbox.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_videotoolbox.h new file mode 100644 index 000000000..380918d92 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/hwcontext_videotoolbox.h @@ -0,0 +1,54 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H +#define AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H + +#include + +#include + +#include "pixfmt.h" + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_VIDEOTOOLBOX. + * + * This API currently does not support frame allocation, as the raw VideoToolbox + * API does allocation, and FFmpeg itself never has the need to allocate frames. + * + * If the API user sets a custom pool, AVHWFramesContext.pool must return + * AVBufferRefs whose data pointer is a CVImageBufferRef or CVPixelBufferRef. + * + * Currently AVHWDeviceContext.hwctx and AVHWFramesContext.hwctx are always + * NULL. + */ + +/** + * Convert a VideoToolbox (actually CoreVideo) format to AVPixelFormat. + * Returns AV_PIX_FMT_NONE if no known equivalent was found. + */ +enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt); + +/** + * Convert an AVPixelFormat to a VideoToolbox (actually CoreVideo) format. + * Returns 0 if no known equivalent was found. + */ +uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt); + +#endif /* AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils.c new file mode 100644 index 000000000..c733cb5cf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils.c @@ -0,0 +1,645 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * misc image utilities + */ + +#include "avassert.h" +#include "common.h" +#include "imgutils.h" +#include "imgutils_internal.h" +#include "internal.h" +#include "intreadwrite.h" +#include "log.h" +#include "mathematics.h" +#include "pixdesc.h" +#include "rational.h" + +void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], + const AVPixFmtDescriptor *pixdesc) +{ + int i; + memset(max_pixsteps, 0, 4*sizeof(max_pixsteps[0])); + if (max_pixstep_comps) + memset(max_pixstep_comps, 0, 4*sizeof(max_pixstep_comps[0])); + + for (i = 0; i < 4; i++) { + const AVComponentDescriptor *comp = &(pixdesc->comp[i]); + if (comp->step > max_pixsteps[comp->plane]) { + max_pixsteps[comp->plane] = comp->step; + if (max_pixstep_comps) + max_pixstep_comps[comp->plane] = i; + } + } +} + +static inline +int image_get_linesize(int width, int plane, + int max_step, int max_step_comp, + const AVPixFmtDescriptor *desc) +{ + int s, shifted_w, linesize; + + if (!desc) + return AVERROR(EINVAL); + + if (width < 0) + return AVERROR(EINVAL); + s = (max_step_comp == 1 || max_step_comp == 2) ? desc->log2_chroma_w : 0; + shifted_w = ((width + (1 << s) - 1)) >> s; + if (shifted_w && max_step > INT_MAX / shifted_w) + return AVERROR(EINVAL); + linesize = max_step * shifted_w; + + if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) + linesize = (linesize + 7) >> 3; + return linesize; +} + +int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int max_step [4]; /* max pixel step for each plane */ + int max_step_comp[4]; /* the component for each plane which has the max pixel step */ + + if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return AVERROR(EINVAL); + + av_image_fill_max_pixsteps(max_step, max_step_comp, desc); + return image_get_linesize(width, plane, max_step[plane], max_step_comp[plane], desc); +} + +int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width) +{ + int i, ret; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int max_step [4]; /* max pixel step for each plane */ + int max_step_comp[4]; /* the component for each plane which has the max pixel step */ + + memset(linesizes, 0, 4*sizeof(linesizes[0])); + + if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return AVERROR(EINVAL); + + av_image_fill_max_pixsteps(max_step, max_step_comp, desc); + for (i = 0; i < 4; i++) { + if ((ret = image_get_linesize(width, i, max_step[i], max_step_comp[i], desc)) < 0) + return ret; + linesizes[i] = ret; + } + + return 0; +} + +int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, + uint8_t *ptr, const int linesizes[4]) +{ + int i, total_size, size[4] = { 0 }, has_plane[4] = { 0 }; + + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + memset(data , 0, sizeof(data[0])*4); + + if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return AVERROR(EINVAL); + + data[0] = ptr; + if (linesizes[0] > (INT_MAX - 1024) / height) + return AVERROR(EINVAL); + size[0] = linesizes[0] * height; + + if (desc->flags & AV_PIX_FMT_FLAG_PAL || + desc->flags & FF_PSEUDOPAL) { + data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */ + return size[0] + 256 * 4; + } + + for (i = 0; i < 4; i++) + has_plane[desc->comp[i].plane] = 1; + + total_size = size[0]; + for (i = 1; i < 4 && has_plane[i]; i++) { + int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; + data[i] = data[i-1] + size[i-1]; + h = (height + (1 << s) - 1) >> s; + if (linesizes[i] > INT_MAX / h) + return AVERROR(EINVAL); + size[i] = h * linesizes[i]; + if (total_size > INT_MAX - size[i]) + return AVERROR(EINVAL); + total_size += size[i]; + } + + return total_size; +} + +int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt) +{ + int i; + + for (i = 0; i < 256; i++) { + int r, g, b; + + switch (pix_fmt) { + case AV_PIX_FMT_RGB8: + r = (i>>5 )*36; + g = ((i>>2)&7)*36; + b = (i&3 )*85; + break; + case AV_PIX_FMT_BGR8: + b = (i>>6 )*85; + g = ((i>>3)&7)*36; + r = (i&7 )*36; + break; + case AV_PIX_FMT_RGB4_BYTE: + r = (i>>3 )*255; + g = ((i>>1)&3)*85; + b = (i&1 )*255; + break; + case AV_PIX_FMT_BGR4_BYTE: + b = (i>>3 )*255; + g = ((i>>1)&3)*85; + r = (i&1 )*255; + break; + case AV_PIX_FMT_GRAY8: + r = b = g = i; + break; + default: + return AVERROR(EINVAL); + } + pal[i] = b + (g << 8) + (r << 16) + (0xFFU << 24); + } + + return 0; +} + +int av_image_alloc(uint8_t *pointers[4], int linesizes[4], + int w, int h, enum AVPixelFormat pix_fmt, int align) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int i, ret; + uint8_t *buf; + + if (!desc) + return AVERROR(EINVAL); + + if ((ret = av_image_check_size(w, h, 0, NULL)) < 0) + return ret; + if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, align>7 ? FFALIGN(w, 8) : w)) < 0) + return ret; + + for (i = 0; i < 4; i++) + linesizes[i] = FFALIGN(linesizes[i], align); + + if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, NULL, linesizes)) < 0) + return ret; + buf = av_malloc(ret + align); + if (!buf) + return AVERROR(ENOMEM); + if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, buf, linesizes)) < 0) { + av_free(buf); + return ret; + } + if (desc->flags & AV_PIX_FMT_FLAG_PAL || (desc->flags & FF_PSEUDOPAL && pointers[1])) { + avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt); + if (align < 4) { + av_log(NULL, AV_LOG_ERROR, "Formats with a palette require a minimum alignment of 4\n"); + return AVERROR(EINVAL); + } + } + + if ((desc->flags & AV_PIX_FMT_FLAG_PAL || + desc->flags & FF_PSEUDOPAL) && pointers[1] && + pointers[1] - pointers[0] > linesizes[0] * h) { + /* zero-initialize the padding before the palette */ + memset(pointers[0] + linesizes[0] * h, 0, + pointers[1] - pointers[0] - linesizes[0] * h); + } + + return ret; +} + +typedef struct ImgUtils { + const AVClass *class; + int log_offset; + void *log_ctx; +} ImgUtils; + +static const AVClass imgutils_class = { + .class_name = "IMGUTILS", + .item_name = av_default_item_name, + .option = NULL, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = offsetof(ImgUtils, log_offset), + .parent_log_context_offset = offsetof(ImgUtils, log_ctx), +}; + +int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx) +{ + ImgUtils imgutils = { + .class = &imgutils_class, + .log_offset = log_offset, + .log_ctx = log_ctx, + }; + int64_t stride = av_image_get_linesize(pix_fmt, w, 0); + if (stride <= 0) + stride = 8LL*w; + stride += 128*8; + + if ((int)w<=0 || (int)h<=0 || stride >= INT_MAX || stride*(uint64_t)(h+128) >= INT_MAX) { + av_log(&imgutils, AV_LOG_ERROR, "Picture size %ux%u is invalid\n", w, h); + return AVERROR(EINVAL); + } + + if (max_pixels < INT64_MAX) { + if (w*(int64_t)h > max_pixels) { + av_log(&imgutils, AV_LOG_ERROR, + "Picture size %ux%u exceeds specified max pixel count %"PRId64", see the documentation if you wish to increase it\n", + w, h, max_pixels); + return AVERROR(EINVAL); + } + } + + return 0; +} + +int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx) +{ + return av_image_check_size2(w, h, INT64_MAX, AV_PIX_FMT_NONE, log_offset, log_ctx); +} + +int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar) +{ + int64_t scaled_dim; + + if (sar.den <= 0 || sar.num < 0) + return AVERROR(EINVAL); + + if (!sar.num || sar.num == sar.den) + return 0; + + if (sar.num < sar.den) + scaled_dim = av_rescale_rnd(w, sar.num, sar.den, AV_ROUND_ZERO); + else + scaled_dim = av_rescale_rnd(h, sar.den, sar.num, AV_ROUND_ZERO); + + if (scaled_dim > 0) + return 0; + + return AVERROR(EINVAL); +} + +static void image_copy_plane(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) +{ + if (!dst || !src) + return; + av_assert0(FFABS(src_linesize) >= bytewidth); + av_assert0(FFABS(dst_linesize) >= bytewidth); + for (;height > 0; height--) { + memcpy(dst, src, bytewidth); + dst += dst_linesize; + src += src_linesize; + } +} + +static void image_copy_plane_uc_from(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) +{ + int ret = -1; + +#if ARCH_X86 + ret = ff_image_copy_plane_uc_from_x86(dst, dst_linesize, src, src_linesize, + bytewidth, height); +#endif + + if (ret < 0) + image_copy_plane(dst, dst_linesize, src, src_linesize, bytewidth, height); +} + +void av_image_copy_plane(uint8_t *dst, int dst_linesize, + const uint8_t *src, int src_linesize, + int bytewidth, int height) +{ + image_copy_plane(dst, dst_linesize, src, src_linesize, bytewidth, height); +} + +static void image_copy(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height, + void (*copy_plane)(uint8_t *, ptrdiff_t, const uint8_t *, + ptrdiff_t, ptrdiff_t, int)) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + + if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return; + + if (desc->flags & AV_PIX_FMT_FLAG_PAL || + desc->flags & FF_PSEUDOPAL) { + copy_plane(dst_data[0], dst_linesizes[0], + src_data[0], src_linesizes[0], + width, height); + /* copy the palette */ + if ((desc->flags & AV_PIX_FMT_FLAG_PAL) || (dst_data[1] && src_data[1])) + memcpy(dst_data[1], src_data[1], 4*256); + } else { + int i, planes_nb = 0; + + for (i = 0; i < desc->nb_components; i++) + planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1); + + for (i = 0; i < planes_nb; i++) { + int h = height; + ptrdiff_t bwidth = av_image_get_linesize(pix_fmt, width, i); + if (bwidth < 0) { + av_log(NULL, AV_LOG_ERROR, "av_image_get_linesize failed\n"); + return; + } + if (i == 1 || i == 2) { + h = AV_CEIL_RSHIFT(height, desc->log2_chroma_h); + } + copy_plane(dst_data[i], dst_linesizes[i], + src_data[i], src_linesizes[i], + bwidth, h); + } + } +} + +void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], + const uint8_t *src_data[4], const int src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height) +{ + ptrdiff_t dst_linesizes1[4], src_linesizes1[4]; + int i; + + for (i = 0; i < 4; i++) { + dst_linesizes1[i] = dst_linesizes[i]; + src_linesizes1[i] = src_linesizes[i]; + } + + image_copy(dst_data, dst_linesizes1, src_data, src_linesizes1, pix_fmt, + width, height, image_copy_plane); +} + +void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height) +{ + image_copy(dst_data, dst_linesizes, src_data, src_linesizes, pix_fmt, + width, height, image_copy_plane_uc_from); +} + +int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], + const uint8_t *src, enum AVPixelFormat pix_fmt, + int width, int height, int align) +{ + int ret, i; + + ret = av_image_check_size(width, height, 0, NULL); + if (ret < 0) + return ret; + + ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width); + if (ret < 0) + return ret; + + for (i = 0; i < 4; i++) + dst_linesize[i] = FFALIGN(dst_linesize[i], align); + + return av_image_fill_pointers(dst_data, pix_fmt, height, (uint8_t *)src, dst_linesize); +} + +int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, + int width, int height, int align) +{ + uint8_t *data[4]; + int linesize[4]; + int ret; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + if (!desc) + return AVERROR(EINVAL); + + ret = av_image_check_size(width, height, 0, NULL); + if (ret < 0) + return ret; + + // do not include palette for these pseudo-paletted formats + if (desc->flags & FF_PSEUDOPAL) + return FFALIGN(width, align) * height; + + return av_image_fill_arrays(data, linesize, NULL, pix_fmt, + width, height, align); +} + +int av_image_copy_to_buffer(uint8_t *dst, int dst_size, + const uint8_t * const src_data[4], + const int src_linesize[4], + enum AVPixelFormat pix_fmt, + int width, int height, int align) +{ + int i, j, nb_planes = 0, linesize[4]; + int size = av_image_get_buffer_size(pix_fmt, width, height, align); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int ret; + + if (size > dst_size || size < 0 || !desc) + return AVERROR(EINVAL); + + for (i = 0; i < desc->nb_components; i++) + nb_planes = FFMAX(desc->comp[i].plane, nb_planes); + + nb_planes++; + + ret = av_image_fill_linesizes(linesize, pix_fmt, width); + av_assert0(ret >= 0); // was checked previously + + for (i = 0; i < nb_planes; i++) { + int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; + const uint8_t *src = src_data[i]; + h = (height + (1 << shift) - 1) >> shift; + + for (j = 0; j < h; j++) { + memcpy(dst, src, linesize[i]); + dst += FFALIGN(linesize[i], align); + src += src_linesize[i]; + } + } + + if (desc->flags & AV_PIX_FMT_FLAG_PAL) { + uint32_t *d32 = (uint32_t *)dst; + + for (i = 0; i<256; i++) + AV_WL32(d32 + i, AV_RN32(src_data[1] + 4*i)); + } + + return size; +} + +// Fill dst[0..dst_size] with the bytes in clear[0..clear_size]. The clear +// bytes are repeated until dst_size is reached. If dst_size is unaligned (i.e. +// dst_size%clear_size!=0), the remaining data will be filled with the beginning +// of the clear data only. +static void memset_bytes(uint8_t *dst, size_t dst_size, uint8_t *clear, + size_t clear_size) +{ + int same = 1; + int i; + + if (!clear_size) + return; + + // Reduce to memset() if possible. + for (i = 0; i < clear_size; i++) { + if (clear[i] != clear[0]) { + same = 0; + break; + } + } + if (same) + clear_size = 1; + + if (clear_size == 1) { + memset(dst, clear[0], dst_size); + dst_size = 0; + } else { + if (clear_size > dst_size) + clear_size = dst_size; + memcpy(dst, clear, clear_size); + av_memcpy_backptr(dst + clear_size, clear_size, dst_size - clear_size); + } +} + +// Maximum size in bytes of a plane element (usually a pixel, or multiple pixels +// if it's a subsampled packed format). +#define MAX_BLOCK_SIZE 32 + +int av_image_fill_black(uint8_t *dst_data[4], const ptrdiff_t dst_linesize[4], + enum AVPixelFormat pix_fmt, enum AVColorRange range, + int width, int height) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int nb_planes = av_pix_fmt_count_planes(pix_fmt); + // A pixel or a group of pixels on each plane, with a value that represents black. + // Consider e.g. AV_PIX_FMT_UYVY422 for non-trivial cases. + uint8_t clear_block[4][MAX_BLOCK_SIZE] = {{0}}; // clear padding with 0 + int clear_block_size[4] = {0}; + ptrdiff_t plane_line_bytes[4] = {0}; + int rgb, limited; + int plane, c; + + if (!desc || nb_planes < 1 || nb_planes > 4 || desc->flags & AV_PIX_FMT_FLAG_HWACCEL) + return AVERROR(EINVAL); + + rgb = !!(desc->flags & AV_PIX_FMT_FLAG_RGB); + limited = !rgb && range != AVCOL_RANGE_JPEG; + + if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) { + ptrdiff_t bytewidth = av_image_get_linesize(pix_fmt, width, 0); + uint8_t *data; + int mono = pix_fmt == AV_PIX_FMT_MONOWHITE || pix_fmt == AV_PIX_FMT_MONOBLACK; + int fill = pix_fmt == AV_PIX_FMT_MONOWHITE ? 0xFF : 0; + if (nb_planes != 1 || !(rgb || mono) || bytewidth < 1) + return AVERROR(EINVAL); + + if (!dst_data) + return 0; + + data = dst_data[0]; + + // (Bitstream + alpha will be handled incorrectly - it'll remain transparent.) + for (;height > 0; height--) { + memset(data, fill, bytewidth); + data += dst_linesize[0]; + } + return 0; + } + + for (c = 0; c < desc->nb_components; c++) { + const AVComponentDescriptor comp = desc->comp[c]; + + // We try to operate on entire non-subsampled pixel groups (for + // AV_PIX_FMT_UYVY422 this would mean two consecutive pixels). + clear_block_size[comp.plane] = FFMAX(clear_block_size[comp.plane], comp.step); + + if (clear_block_size[comp.plane] > MAX_BLOCK_SIZE) + return AVERROR(EINVAL); + } + + // Create a byte array for clearing 1 pixel (sometimes several pixels). + for (c = 0; c < desc->nb_components; c++) { + const AVComponentDescriptor comp = desc->comp[c]; + // (Multiple pixels happen e.g. with AV_PIX_FMT_UYVY422.) + int w = clear_block_size[comp.plane] / comp.step; + uint8_t *c_data[4]; + const int c_linesize[4] = {0}; + uint16_t src_array[MAX_BLOCK_SIZE]; + uint16_t src = 0; + int x; + + if (comp.depth > 16) + return AVERROR(EINVAL); + if (!rgb && comp.depth < 8) + return AVERROR(EINVAL); + if (w < 1) + return AVERROR(EINVAL); + + if (c == 0 && limited) { + src = 16 << (comp.depth - 8); + } else if ((c == 1 || c == 2) && !rgb) { + src = 128 << (comp.depth - 8); + } else if (c == 3) { + // (Assume even limited YUV uses full range alpha.) + src = (1 << comp.depth) - 1; + } + + for (x = 0; x < w; x++) + src_array[x] = src; + + for (x = 0; x < 4; x++) + c_data[x] = &clear_block[x][0]; + + av_write_image_line(src_array, c_data, c_linesize, desc, 0, 0, c, w); + } + + for (plane = 0; plane < nb_planes; plane++) { + plane_line_bytes[plane] = av_image_get_linesize(pix_fmt, width, plane); + if (plane_line_bytes[plane] < 0) + return AVERROR(EINVAL); + } + + if (!dst_data) + return 0; + + for (plane = 0; plane < nb_planes; plane++) { + size_t bytewidth = plane_line_bytes[plane]; + uint8_t *data = dst_data[plane]; + int chroma_div = plane == 1 || plane == 2 ? desc->log2_chroma_h : 0; + int plane_h = ((height + ( 1 << chroma_div) - 1)) >> chroma_div; + + for (; plane_h > 0; plane_h--) { + memset_bytes(data, bytewidth, &clear_block[plane][0], clear_block_size[plane]); + data += dst_linesize[plane]; + } + } + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils.h new file mode 100644 index 000000000..5b790ecf0 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils.h @@ -0,0 +1,277 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_IMGUTILS_H +#define AVUTIL_IMGUTILS_H + +/** + * @file + * misc image utilities + * + * @addtogroup lavu_picture + * @{ + */ + +#include "avutil.h" +#include "pixdesc.h" +#include "rational.h" + +/** + * Compute the max pixel step for each plane of an image with a + * format described by pixdesc. + * + * The pixel step is the distance in bytes between the first byte of + * the group of bytes which describe a pixel component and the first + * byte of the successive group in the same plane for the same + * component. + * + * @param max_pixsteps an array which is filled with the max pixel step + * for each plane. Since a plane may contain different pixel + * components, the computed max_pixsteps[plane] is relative to the + * component in the plane with the max pixel step. + * @param max_pixstep_comps an array which is filled with the component + * for each plane which has the max pixel step. May be NULL. + */ +void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], + const AVPixFmtDescriptor *pixdesc); + +/** + * Compute the size of an image line with format pix_fmt and width + * width for the plane plane. + * + * @return the computed size in bytes + */ +int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane); + +/** + * Fill plane linesizes for an image with pixel format pix_fmt and + * width width. + * + * @param linesizes array to be filled with the linesize for each plane + * @return >= 0 in case of success, a negative error code otherwise + */ +int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width); + +/** + * Fill plane data pointers for an image with pixel format pix_fmt and + * height height. + * + * @param data pointers array to be filled with the pointer for each image plane + * @param ptr the pointer to a buffer which will contain the image + * @param linesizes the array containing the linesize for each + * plane, should be filled by av_image_fill_linesizes() + * @return the size in bytes required for the image buffer, a negative + * error code in case of failure + */ +int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, + uint8_t *ptr, const int linesizes[4]); + +/** + * Allocate an image with size w and h and pixel format pix_fmt, and + * fill pointers and linesizes accordingly. + * The allocated image buffer has to be freed by using + * av_freep(&pointers[0]). + * + * @param align the value to use for buffer size alignment + * @return the size in bytes required for the image buffer, a negative + * error code in case of failure + */ +int av_image_alloc(uint8_t *pointers[4], int linesizes[4], + int w, int h, enum AVPixelFormat pix_fmt, int align); + +/** + * Copy image plane from src to dst. + * That is, copy "height" number of lines of "bytewidth" bytes each. + * The first byte of each successive line is separated by *_linesize + * bytes. + * + * bytewidth must be contained by both absolute values of dst_linesize + * and src_linesize, otherwise the function behavior is undefined. + * + * @param dst_linesize linesize for the image plane in dst + * @param src_linesize linesize for the image plane in src + */ +void av_image_copy_plane(uint8_t *dst, int dst_linesize, + const uint8_t *src, int src_linesize, + int bytewidth, int height); + +/** + * Copy image in src_data to dst_data. + * + * @param dst_linesizes linesizes for the image in dst_data + * @param src_linesizes linesizes for the image in src_data + */ +void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], + const uint8_t *src_data[4], const int src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * Copy image data located in uncacheable (e.g. GPU mapped) memory. Where + * available, this function will use special functionality for reading from such + * memory, which may result in greatly improved performance compared to plain + * av_image_copy(). + * + * The data pointers and the linesizes must be aligned to the maximum required + * by the CPU architecture. + * + * @note The linesize parameters have the type ptrdiff_t here, while they are + * int for av_image_copy(). + * @note On x86, the linesizes currently need to be aligned to the cacheline + * size (i.e. 64) to get improved performance. + */ +void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * Setup the data pointers and linesizes based on the specified image + * parameters and the provided array. + * + * The fields of the given image are filled in by using the src + * address which points to the image data buffer. Depending on the + * specified pixel format, one or multiple image data pointers and + * line sizes will be set. If a planar format is specified, several + * pointers will be set pointing to the different picture planes and + * the line sizes of the different planes will be stored in the + * lines_sizes array. Call with src == NULL to get the required + * size for the src buffer. + * + * To allocate the buffer and fill in the dst_data and dst_linesize in + * one call, use av_image_alloc(). + * + * @param dst_data data pointers to be filled in + * @param dst_linesize linesizes for the image in dst_data to be filled in + * @param src buffer which will contain or contains the actual image data, can be NULL + * @param pix_fmt the pixel format of the image + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @param align the value used in src for linesize alignment + * @return the size in bytes required for src, a negative error code + * in case of failure + */ +int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], + const uint8_t *src, + enum AVPixelFormat pix_fmt, int width, int height, int align); + +/** + * Return the size in bytes of the amount of data required to store an + * image with the given parameters. + * + * @param pix_fmt the pixel format of the image + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @param align the assumed linesize alignment + * @return the buffer size in bytes, a negative error code in case of failure + */ +int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align); + +/** + * Copy image data from an image into a buffer. + * + * av_image_get_buffer_size() can be used to compute the required size + * for the buffer to fill. + * + * @param dst a buffer into which picture data will be copied + * @param dst_size the size in bytes of dst + * @param src_data pointers containing the source image data + * @param src_linesize linesizes for the image in src_data + * @param pix_fmt the pixel format of the source image + * @param width the width of the source image in pixels + * @param height the height of the source image in pixels + * @param align the assumed linesize alignment for dst + * @return the number of bytes written to dst, or a negative value + * (error code) on error + */ +int av_image_copy_to_buffer(uint8_t *dst, int dst_size, + const uint8_t * const src_data[4], const int src_linesize[4], + enum AVPixelFormat pix_fmt, int width, int height, int align); + +/** + * Check if the given dimension of an image is valid, meaning that all + * bytes of the image can be addressed with a signed int. + * + * @param w the width of the picture + * @param h the height of the picture + * @param log_offset the offset to sum to the log level for logging with log_ctx + * @param log_ctx the parent logging context, it may be NULL + * @return >= 0 if valid, a negative error code otherwise + */ +int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx); + +/** + * Check if the given dimension of an image is valid, meaning that all + * bytes of a plane of an image with the specified pix_fmt can be addressed + * with a signed int. + * + * @param w the width of the picture + * @param h the height of the picture + * @param max_pixels the maximum number of pixels the user wants to accept + * @param pix_fmt the pixel format, can be AV_PIX_FMT_NONE if unknown. + * @param log_offset the offset to sum to the log level for logging with log_ctx + * @param log_ctx the parent logging context, it may be NULL + * @return >= 0 if valid, a negative error code otherwise + */ +int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx); + +/** + * Check if the given sample aspect ratio of an image is valid. + * + * It is considered invalid if the denominator is 0 or if applying the ratio + * to the image size would make the smaller dimension less than 1. If the + * sar numerator is 0, it is considered unknown and will return as valid. + * + * @param w width of the image + * @param h height of the image + * @param sar sample aspect ratio of the image + * @return 0 if valid, a negative AVERROR code otherwise + */ +int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar); + +/** + * Overwrite the image data with black. This is suitable for filling a + * sub-rectangle of an image, meaning the padding between the right most pixel + * and the left most pixel on the next line will not be overwritten. For some + * formats, the image size might be rounded up due to inherent alignment. + * + * If the pixel format has alpha, the alpha is cleared to opaque. + * + * This can return an error if the pixel format is not supported. Normally, all + * non-hwaccel pixel formats should be supported. + * + * Passing NULL for dst_data is allowed. Then the function returns whether the + * operation would have succeeded. (It can return an error if the pix_fmt is + * not supported.) + * + * @param dst_data data pointers to destination image + * @param dst_linesize linesizes for the destination image + * @param pix_fmt the pixel format of the image + * @param range the color range of the image (important for colorspaces such as YUV) + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return 0 if the image data was cleared, a negative AVERROR code otherwise + */ +int av_image_fill_black(uint8_t *dst_data[4], const ptrdiff_t dst_linesize[4], + enum AVPixelFormat pix_fmt, enum AVColorRange range, + int width, int height); + +/** + * @} + */ + + +#endif /* AVUTIL_IMGUTILS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils_internal.h new file mode 100644 index 000000000..d51585841 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/imgutils_internal.h @@ -0,0 +1,30 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_IMGUTILS_INTERNAL_H +#define AVUTIL_IMGUTILS_INTERNAL_H + +#include +#include + +int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height); + + +#endif /* AVUTIL_IMGUTILS_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/integer.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/integer.c new file mode 100644 index 000000000..78e252fbd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/integer.c @@ -0,0 +1,166 @@ +/* + * arbitrary precision integers + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * arbitrary precision integers + * @author Michael Niedermayer + */ + +#include "common.h" +#include "integer.h" +#include "avassert.h" + +static const AVInteger zero_i; + +AVInteger av_add_i(AVInteger a, AVInteger b){ + int i, carry=0; + + for(i=0; i>16) + a.v[i] + b.v[i]; + a.v[i]= carry; + } + return a; +} + +AVInteger av_sub_i(AVInteger a, AVInteger b){ + int i, carry=0; + + for(i=0; i>16) + a.v[i] - b.v[i]; + a.v[i]= carry; + } + return a; +} + +int av_log2_i(AVInteger a){ + int i; + + for(i=AV_INTEGER_SIZE-1; i>=0; i--){ + if(a.v[i]) + return av_log2_16bit(a.v[i]) + 16*i; + } + return -1; +} + +AVInteger av_mul_i(AVInteger a, AVInteger b){ + AVInteger out; + int i, j; + int na= (av_log2_i(a)+16) >> 4; + int nb= (av_log2_i(b)+16) >> 4; + + memset(&out, 0, sizeof(out)); + + for(i=0; i>16) + out.v[j] + a.v[i]*(unsigned)b.v[j-i]; + out.v[j]= carry; + } + } + + return out; +} + +int av_cmp_i(AVInteger a, AVInteger b){ + int i; + int v= (int16_t)a.v[AV_INTEGER_SIZE-1] - (int16_t)b.v[AV_INTEGER_SIZE-1]; + if(v) return (v>>16)|1; + + for(i=AV_INTEGER_SIZE-2; i>=0; i--){ + int v= a.v[i] - b.v[i]; + if(v) return (v>>16)|1; + } + return 0; +} + +AVInteger av_shr_i(AVInteger a, int s){ + AVInteger out; + int i; + + for(i=0; i>4); + unsigned int v=0; + if(index+1> (s&15); + } + return out; +} + +AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b){ + int i= av_log2_i(a) - av_log2_i(b); + AVInteger quot_temp; + if(!quot) quot = "_temp; + + if ((int16_t)a.v[AV_INTEGER_SIZE-1] < 0) { + a = av_mod_i(quot, av_sub_i(zero_i, a), b); + *quot = av_sub_i(zero_i, *quot); + return av_sub_i(zero_i, a); + } + + av_assert2((int16_t)a.v[AV_INTEGER_SIZE-1] >= 0 && (int16_t)b.v[AV_INTEGER_SIZE-1] >= 0); + av_assert2(av_log2_i(b)>=0); + + if(i > 0) + b= av_shr_i(b, -i); + + memset(quot, 0, sizeof(AVInteger)); + + while(i-- >= 0){ + *quot= av_shr_i(*quot, -1); + if(av_cmp_i(a, b) >= 0){ + a= av_sub_i(a, b); + quot->v[0] += 1; + } + b= av_shr_i(b, 1); + } + return a; +} + +AVInteger av_div_i(AVInteger a, AVInteger b){ + AVInteger quot; + av_mod_i(", a, b); + return quot; +} + +AVInteger av_int2i(int64_t a){ + AVInteger out; + int i; + + for(i=0; i>=16; + } + return out; +} + +int64_t av_i2int(AVInteger a){ + int i; + int64_t out=(int8_t)a.v[AV_INTEGER_SIZE-1]; + + for(i= AV_INTEGER_SIZE-2; i>=0; i--){ + out = (out<<16) + a.v[i]; + } + return out; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/integer.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/integer.h new file mode 100644 index 000000000..45f733c04 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/integer.h @@ -0,0 +1,86 @@ +/* + * arbitrary precision integers + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * arbitrary precision integers + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_INTEGER_H +#define AVUTIL_INTEGER_H + +#include +#include "common.h" + +#define AV_INTEGER_SIZE 8 + +typedef struct AVInteger{ + uint16_t v[AV_INTEGER_SIZE]; +} AVInteger; + +AVInteger av_add_i(AVInteger a, AVInteger b) av_const; +AVInteger av_sub_i(AVInteger a, AVInteger b) av_const; + +/** + * Return the rounded-down value of the base 2 logarithm of the given + * AVInteger. This is simply the index of the most significant bit + * which is 1, or 0 if all bits are 0. + */ +int av_log2_i(AVInteger a) av_const; +AVInteger av_mul_i(AVInteger a, AVInteger b) av_const; + +/** + * Return 0 if a==b, 1 if a>b and -1 if a + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * common internal API header + */ + +#ifndef AVUTIL_INTERNAL_H +#define AVUTIL_INTERNAL_H + +#if !defined(DEBUG) && !defined(NDEBUG) +# define NDEBUG +#endif + +// This can be enabled to allow detection of additional integer overflows with ubsan +//#define CHECKED + +#include +#include +#include +#include +#include "config.h" +#include "attributes.h" +#include "timer.h" +#include "cpu.h" +#include "dict.h" +#include "macros.h" +#include "mem.h" +#include "pixfmt.h" +#include "version.h" + +#if ARCH_X86 +# include "x86/emms.h" +#endif + +#ifndef emms_c +# define emms_c() do {} while(0) +#endif + +#ifndef attribute_align_arg +#if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2) +# define attribute_align_arg __attribute__((force_align_arg_pointer)) +#else +# define attribute_align_arg +#endif +#endif + +#if defined(_WIN32) && CONFIG_SHARED && !defined(BUILDING_avutil) +# define av_export_avutil __declspec(dllimport) +#else +# define av_export_avutil +#endif + +#if HAVE_PRAGMA_DEPRECATED +# if defined(__ICL) || defined (__INTEL_COMPILER) +# define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:1478)) +# define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop)) +# elif defined(_MSC_VER) +# define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:4996)) +# define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop)) +# else +# define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define FF_ENABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic pop") +# endif +#else +# define FF_DISABLE_DEPRECATION_WARNINGS +# define FF_ENABLE_DEPRECATION_WARNINGS +#endif + + +#define FF_MEMORY_POISON 0x2a + +#define MAKE_ACCESSORS(str, name, type, field) \ + type av_##name##_get_##field(const str *s) { return s->field; } \ + void av_##name##_set_##field(str *s, type v) { s->field = v; } + +// Some broken preprocessors need a second expansion +// to be forced to tokenize __VA_ARGS__ +#define E1(x) x + +/* Check if the hard coded offset of a struct member still matches reality. + * Induce a compilation failure if not. + */ +#define AV_CHECK_OFFSET(s, m, o) struct check_##o { \ + int x_##o[offsetof(s, m) == o? 1: -1]; \ + } + +#define LOCAL_ALIGNED_A(a, t, v, s, o, ...) \ + uint8_t la_##v[sizeof(t s o) + (a)]; \ + t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a) + +#define LOCAL_ALIGNED_D(a, t, v, s, o, ...) \ + DECLARE_ALIGNED(a, t, la_##v) s o; \ + t (*v) o = la_##v + +#define LOCAL_ALIGNED(a, t, v, ...) LOCAL_ALIGNED_##a(t, v, __VA_ARGS__) + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_D(4, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_4(t, v, ...) E1(LOCAL_ALIGNED_A(4, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_A(8, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_A(16, t, v, __VA_ARGS__,,)) +#endif + +#if HAVE_LOCAL_ALIGNED +# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,)) +#else +# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,)) +#endif + +#define FF_ALLOC_OR_GOTO(ctx, p, size, label)\ +{\ + p = av_malloc(size);\ + if (!(p) && (size) != 0) {\ + av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ + goto label;\ + }\ +} + +#define FF_ALLOCZ_OR_GOTO(ctx, p, size, label)\ +{\ + p = av_mallocz(size);\ + if (!(p) && (size) != 0) {\ + av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ + goto label;\ + }\ +} + +#define FF_ALLOC_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\ +{\ + p = av_malloc_array(nelem, elsize);\ + if (!p) {\ + av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ + goto label;\ + }\ +} + +#define FF_ALLOCZ_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\ +{\ + p = av_mallocz_array(nelem, elsize);\ + if (!p) {\ + av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ + goto label;\ + }\ +} + +#include "libm.h" + +/** + * Return NULL if CONFIG_SMALL is true, otherwise the argument + * without modification. Used to disable the definition of strings + * (for example AVCodec long_names). + */ +#if CONFIG_SMALL +# define NULL_IF_CONFIG_SMALL(x) NULL +#else +# define NULL_IF_CONFIG_SMALL(x) x +#endif + +/** + * Define a function with only the non-default version specified. + * + * On systems with ELF shared libraries, all symbols exported from + * FFmpeg libraries are tagged with the name and major version of the + * library to which they belong. If a function is moved from one + * library to another, a wrapper must be retained in the original + * location to preserve binary compatibility. + * + * Functions defined with this macro will never be used to resolve + * symbols by the build-time linker. + * + * @param type return type of function + * @param name name of function + * @param args argument list of function + * @param ver version tag to assign function + */ +#if HAVE_SYMVER_ASM_LABEL +# define FF_SYMVER(type, name, args, ver) \ + type ff_##name args __asm__ (EXTERN_PREFIX #name "@" ver); \ + type ff_##name args +#elif HAVE_SYMVER_GNU_ASM +# define FF_SYMVER(type, name, args, ver) \ + __asm__ (".symver ff_" #name "," EXTERN_PREFIX #name "@" ver); \ + type ff_##name args; \ + type ff_##name args +#endif + +/** + * Return NULL if a threading library has not been enabled. + * Used to disable threading functions in AVCodec definitions + * when not needed. + */ +#if HAVE_THREADS +# define ONLY_IF_THREADS_ENABLED(x) x +#else +# define ONLY_IF_THREADS_ENABLED(x) NULL +#endif + +/** + * Log a generic warning message about a missing feature. + * + * @param[in] avc a pointer to an arbitrary struct of which the first + * field is a pointer to an AVClass struct + * @param[in] msg string containing the name of the missing feature + */ +void avpriv_report_missing_feature(void *avc, + const char *msg, ...) av_printf_format(2, 3); + +/** + * Log a generic warning message about a missing feature. + * Additionally request that a sample showcasing the feature be uploaded. + * + * @param[in] avc a pointer to an arbitrary struct of which the first field is + * a pointer to an AVClass struct + * @param[in] msg string containing the name of the missing feature + */ +void avpriv_request_sample(void *avc, + const char *msg, ...) av_printf_format(2, 3); + +#if HAVE_LIBC_MSVCRT +#include +#if defined(_VC_CRT_MAJOR_VERSION) && _VC_CRT_MAJOR_VERSION < 14 +#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_strtod") +#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_snprintf") +#endif + +#define avpriv_open ff_open +#define avpriv_tempfile ff_tempfile +#define PTRDIFF_SPECIFIER "Id" +#define SIZE_SPECIFIER "Iu" +#else +#define PTRDIFF_SPECIFIER "td" +#define SIZE_SPECIFIER "zu" +#endif + +#ifdef DEBUG +# define ff_dlog(ctx, ...) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__) +#else +# define ff_dlog(ctx, ...) do { if (0) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0) +#endif + +// For debuging we use signed operations so overflows can be detected (by ubsan) +// For production we use unsigned so there are no undefined operations +#ifdef CHECKED +#define SUINT int +#define SUINT32 int32_t +#else +#define SUINT unsigned +#define SUINT32 uint32_t +#endif + +/** + * Clip and convert a double value into the long long amin-amax range. + * This function is needed because conversion of floating point to integers when + * it does not fit in the integer's representation does not necessarily saturate + * correctly (usually converted to a cvttsd2si on x86) which saturates numbers + * > INT64_MAX to INT64_MIN. The standard marks such conversions as undefined + * behavior, allowing this sort of mathematically bogus conversions. This provides + * a safe alternative that is slower obviously but assures safety and better + * mathematical behavior. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const int64_t ff_rint64_clip(double a, int64_t amin, int64_t amax) +{ + int64_t res; +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + // INT64_MAX+1,INT64_MIN are exactly representable as IEEE doubles + // do range checks first + if (a >= 9223372036854775808.0) + return amax; + if (a <= -9223372036854775808.0) + return amin; + + // safe to call llrint and clip accordingly + res = llrint(a); + if (res > amax) + return amax; + if (res < amin) + return amin; + return res; +} + +/** + * A wrapper for open() setting O_CLOEXEC. + */ +av_warn_unused_result +int avpriv_open(const char *filename, int flags, ...); + +/** + * Wrapper to work around the lack of mkstemp() on mingw. + * Also, tries to create file in /tmp first, if possible. + * *prefix can be a character constant; *filename will be allocated internally. + * @return file descriptor of opened file (or negative value corresponding to an + * AVERROR code on error) + * and opened file name in **filename. + * @note On very old libcs it is necessary to set a secure umask before + * calling this, av_tempfile() can't call umask itself as it is used in + * libraries and could interfere with the calling application. + */ +int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx); + +int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt); + +static av_always_inline av_const int avpriv_mirror(int x, int w) +{ + if (!w) + return 0; + + while ((unsigned)x > (unsigned)w) { + x = -x; + if (x < 0) + x += 2 * w; + } + return x; +} + +void ff_check_pixfmt_descriptors(void); + +/** + * Set a dictionary value to an ISO-8601 compliant timestamp string. + * + * @param s AVFormatContext + * @param key metadata key + * @param timestamp unix timestamp in microseconds + * @return <0 on error + */ +int avpriv_dict_set_timestamp(AVDictionary **dict, const char *key, int64_t timestamp); + +// Helper macro for AV_PIX_FMT_FLAG_PSEUDOPAL deprecation. Code inside FFmpeg +// should always use FF_PSEUDOPAL. Once the public API flag gets removed, all +// code using it is dead code. +#if FF_API_PSEUDOPAL +#define FF_PSEUDOPAL AV_PIX_FMT_FLAG_PSEUDOPAL +#else +#define FF_PSEUDOPAL 0 +#endif + +#endif /* AVUTIL_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intfloat.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intfloat.h new file mode 100644 index 000000000..fe3d7ec4a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intfloat.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTFLOAT_H +#define AVUTIL_INTFLOAT_H + +#include +#include "attributes.h" + +union av_intfloat32 { + uint32_t i; + float f; +}; + +union av_intfloat64 { + uint64_t i; + double f; +}; + +/** + * Reinterpret a 32-bit integer as a float. + */ +static av_always_inline float av_int2float(uint32_t i) +{ + union av_intfloat32 v; + v.i = i; + return v.f; +} + +/** + * Reinterpret a float as a 32-bit integer. + */ +static av_always_inline uint32_t av_float2int(float f) +{ + union av_intfloat32 v; + v.f = f; + return v.i; +} + +/** + * Reinterpret a 64-bit integer as a double. + */ +static av_always_inline double av_int2double(uint64_t i) +{ + union av_intfloat64 v; + v.i = i; + return v.f; +} + +/** + * Reinterpret a double as a 64-bit integer. + */ +static av_always_inline uint64_t av_double2int(double f) +{ + union av_intfloat64 v; + v.f = f; + return v.i; +} + +#endif /* AVUTIL_INTFLOAT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intmath.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intmath.c new file mode 100644 index 000000000..b0c00e1ca --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intmath.c @@ -0,0 +1,34 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "intmath.h" + +/* undef these to get the function prototypes from common.h */ +#undef av_log2 +#undef av_log2_16bit +#include "common.h" + +int av_log2(unsigned v) +{ + return ff_log2(v); +} + +int av_log2_16bit(unsigned v) +{ + return ff_log2_16bit(v); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intmath.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intmath.h new file mode 100644 index 000000000..9573109e9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intmath.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2010 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTMATH_H +#define AVUTIL_INTMATH_H + +#include + +#include "config.h" +#include "attributes.h" + +#if ARCH_ARM +# include "arm/intmath.h" +#endif +#if ARCH_X86 +# include "x86/intmath.h" +#endif + +#if HAVE_FAST_CLZ +#if AV_GCC_VERSION_AT_LEAST(3,4) +#ifndef ff_log2 +# define ff_log2(x) (31 - __builtin_clz((x)|1)) +# ifndef ff_log2_16bit +# define ff_log2_16bit av_log2 +# endif +#endif /* ff_log2 */ +#endif /* AV_GCC_VERSION_AT_LEAST(3,4) */ +#endif + +extern const uint8_t ff_log2_tab[256]; + +#ifndef ff_log2 +#define ff_log2 ff_log2_c +static av_always_inline av_const int ff_log2_c(unsigned int v) +{ + int n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} +#endif + +#ifndef ff_log2_16bit +#define ff_log2_16bit ff_log2_16bit_c +static av_always_inline av_const int ff_log2_16bit_c(unsigned int v) +{ + int n = 0; + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} +#endif + +#define av_log2 ff_log2 +#define av_log2_16bit ff_log2_16bit + +/** + * @addtogroup lavu_math + * @{ + */ + +#if HAVE_FAST_CLZ +#if AV_GCC_VERSION_AT_LEAST(3,4) +#ifndef ff_ctz +#define ff_ctz(v) __builtin_ctz(v) +#endif +#ifndef ff_ctzll +#define ff_ctzll(v) __builtin_ctzll(v) +#endif +#ifndef ff_clz +#define ff_clz(v) __builtin_clz(v) +#endif +#endif +#endif + +#ifndef ff_ctz +#define ff_ctz ff_ctz_c +/** + * Trailing zero bit count. + * + * @param v input value. If v is 0, the result is undefined. + * @return the number of trailing 0-bits + */ +/* We use the De-Bruijn method outlined in: + * http://supertech.csail.mit.edu/papers/debruijn.pdf. */ +static av_always_inline av_const int ff_ctz_c(int v) +{ + static const uint8_t debruijn_ctz32[32] = { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + return debruijn_ctz32[(uint32_t)((v & -v) * 0x077CB531U) >> 27]; +} +#endif + +#ifndef ff_ctzll +#define ff_ctzll ff_ctzll_c +/* We use the De-Bruijn method outlined in: + * http://supertech.csail.mit.edu/papers/debruijn.pdf. */ +static av_always_inline av_const int ff_ctzll_c(long long v) +{ + static const uint8_t debruijn_ctz64[64] = { + 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, + 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, + 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, + 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12 + }; + return debruijn_ctz64[(uint64_t)((v & -v) * 0x022FDD63CC95386DU) >> 58]; +} +#endif + +#ifndef ff_clz +#define ff_clz ff_clz_c +static av_always_inline av_const unsigned ff_clz_c(unsigned x) +{ + unsigned i = sizeof(x) * 8; + + while (x) { + x >>= 1; + i--; + } + + return i; +} +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,4) +#ifndef av_parity +#define av_parity __builtin_parity +#endif +#endif + +/** + * @} + */ +#endif /* AVUTIL_INTMATH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intreadwrite.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intreadwrite.h new file mode 100644 index 000000000..4c8413a53 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/intreadwrite.h @@ -0,0 +1,644 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTREADWRITE_H +#define AVUTIL_INTREADWRITE_H + +#include +#include "libavutil/avconfig.h" +#include "attributes.h" +#include "bswap.h" + +typedef union { + uint64_t u64; + uint32_t u32[2]; + uint16_t u16[4]; + uint8_t u8 [8]; + double f64; + float f32[2]; +} av_alias av_alias64; + +typedef union { + uint32_t u32; + uint16_t u16[2]; + uint8_t u8 [4]; + float f32; +} av_alias av_alias32; + +typedef union { + uint16_t u16; + uint8_t u8 [2]; +} av_alias av_alias16; + +/* + * Arch-specific headers can provide any combination of + * AV_[RW][BLN](16|24|32|48|64) and AV_(COPY|SWAP|ZERO)(64|128) macros. + * Preprocessor symbols must be defined, even if these are implemented + * as inline functions. + * + * R/W means read/write, B/L/N means big/little/native endianness. + * The following macros require aligned access, compared to their + * unaligned variants: AV_(COPY|SWAP|ZERO)(64|128), AV_[RW]N[8-64]A. + * Incorrect usage may range from abysmal performance to crash + * depending on the platform. + * + * The unaligned variants are AV_[RW][BLN][8-64] and AV_COPY*U. + */ + +#ifdef HAVE_AV_CONFIG_H + +#include "config.h" + +#if ARCH_ARM +# include "arm/intreadwrite.h" +#elif ARCH_AVR32 +# include "avr32/intreadwrite.h" +#elif ARCH_MIPS +# include "mips/intreadwrite.h" +#elif ARCH_PPC +# include "ppc/intreadwrite.h" +#elif ARCH_TOMI +# include "tomi/intreadwrite.h" +#elif ARCH_X86 +# include "x86/intreadwrite.h" +#endif + +#endif /* HAVE_AV_CONFIG_H */ + +/* + * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers. + */ + +#if AV_HAVE_BIGENDIAN + +# if defined(AV_RN16) && !defined(AV_RB16) +# define AV_RB16(p) AV_RN16(p) +# elif !defined(AV_RN16) && defined(AV_RB16) +# define AV_RN16(p) AV_RB16(p) +# endif + +# if defined(AV_WN16) && !defined(AV_WB16) +# define AV_WB16(p, v) AV_WN16(p, v) +# elif !defined(AV_WN16) && defined(AV_WB16) +# define AV_WN16(p, v) AV_WB16(p, v) +# endif + +# if defined(AV_RN24) && !defined(AV_RB24) +# define AV_RB24(p) AV_RN24(p) +# elif !defined(AV_RN24) && defined(AV_RB24) +# define AV_RN24(p) AV_RB24(p) +# endif + +# if defined(AV_WN24) && !defined(AV_WB24) +# define AV_WB24(p, v) AV_WN24(p, v) +# elif !defined(AV_WN24) && defined(AV_WB24) +# define AV_WN24(p, v) AV_WB24(p, v) +# endif + +# if defined(AV_RN32) && !defined(AV_RB32) +# define AV_RB32(p) AV_RN32(p) +# elif !defined(AV_RN32) && defined(AV_RB32) +# define AV_RN32(p) AV_RB32(p) +# endif + +# if defined(AV_WN32) && !defined(AV_WB32) +# define AV_WB32(p, v) AV_WN32(p, v) +# elif !defined(AV_WN32) && defined(AV_WB32) +# define AV_WN32(p, v) AV_WB32(p, v) +# endif + +# if defined(AV_RN48) && !defined(AV_RB48) +# define AV_RB48(p) AV_RN48(p) +# elif !defined(AV_RN48) && defined(AV_RB48) +# define AV_RN48(p) AV_RB48(p) +# endif + +# if defined(AV_WN48) && !defined(AV_WB48) +# define AV_WB48(p, v) AV_WN48(p, v) +# elif !defined(AV_WN48) && defined(AV_WB48) +# define AV_WN48(p, v) AV_WB48(p, v) +# endif + +# if defined(AV_RN64) && !defined(AV_RB64) +# define AV_RB64(p) AV_RN64(p) +# elif !defined(AV_RN64) && defined(AV_RB64) +# define AV_RN64(p) AV_RB64(p) +# endif + +# if defined(AV_WN64) && !defined(AV_WB64) +# define AV_WB64(p, v) AV_WN64(p, v) +# elif !defined(AV_WN64) && defined(AV_WB64) +# define AV_WN64(p, v) AV_WB64(p, v) +# endif + +#else /* AV_HAVE_BIGENDIAN */ + +# if defined(AV_RN16) && !defined(AV_RL16) +# define AV_RL16(p) AV_RN16(p) +# elif !defined(AV_RN16) && defined(AV_RL16) +# define AV_RN16(p) AV_RL16(p) +# endif + +# if defined(AV_WN16) && !defined(AV_WL16) +# define AV_WL16(p, v) AV_WN16(p, v) +# elif !defined(AV_WN16) && defined(AV_WL16) +# define AV_WN16(p, v) AV_WL16(p, v) +# endif + +# if defined(AV_RN24) && !defined(AV_RL24) +# define AV_RL24(p) AV_RN24(p) +# elif !defined(AV_RN24) && defined(AV_RL24) +# define AV_RN24(p) AV_RL24(p) +# endif + +# if defined(AV_WN24) && !defined(AV_WL24) +# define AV_WL24(p, v) AV_WN24(p, v) +# elif !defined(AV_WN24) && defined(AV_WL24) +# define AV_WN24(p, v) AV_WL24(p, v) +# endif + +# if defined(AV_RN32) && !defined(AV_RL32) +# define AV_RL32(p) AV_RN32(p) +# elif !defined(AV_RN32) && defined(AV_RL32) +# define AV_RN32(p) AV_RL32(p) +# endif + +# if defined(AV_WN32) && !defined(AV_WL32) +# define AV_WL32(p, v) AV_WN32(p, v) +# elif !defined(AV_WN32) && defined(AV_WL32) +# define AV_WN32(p, v) AV_WL32(p, v) +# endif + +# if defined(AV_RN48) && !defined(AV_RL48) +# define AV_RL48(p) AV_RN48(p) +# elif !defined(AV_RN48) && defined(AV_RL48) +# define AV_RN48(p) AV_RL48(p) +# endif + +# if defined(AV_WN48) && !defined(AV_WL48) +# define AV_WL48(p, v) AV_WN48(p, v) +# elif !defined(AV_WN48) && defined(AV_WL48) +# define AV_WN48(p, v) AV_WL48(p, v) +# endif + +# if defined(AV_RN64) && !defined(AV_RL64) +# define AV_RL64(p) AV_RN64(p) +# elif !defined(AV_RN64) && defined(AV_RL64) +# define AV_RN64(p) AV_RL64(p) +# endif + +# if defined(AV_WN64) && !defined(AV_WL64) +# define AV_WL64(p, v) AV_WN64(p, v) +# elif !defined(AV_WN64) && defined(AV_WL64) +# define AV_WN64(p, v) AV_WL64(p, v) +# endif + +#endif /* !AV_HAVE_BIGENDIAN */ + +/* + * Define AV_[RW]N helper macros to simplify definitions not provided + * by per-arch headers. + */ + +#if defined(__GNUC__) + +union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias; +union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias; +union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; + +# define AV_RN(s, p) (((const union unaligned_##s *) (p))->l) +# define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v)) + +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64) || defined(_M_ARM64)) && AV_HAVE_FAST_UNALIGNED + +# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) +# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) + +#elif AV_HAVE_FAST_UNALIGNED + +# define AV_RN(s, p) (((const av_alias##s*)(p))->u##s) +# define AV_WN(s, p, v) (((av_alias##s*)(p))->u##s = (v)) + +#else + +#ifndef AV_RB16 +# define AV_RB16(x) \ + ((((const uint8_t*)(x))[0] << 8) | \ + ((const uint8_t*)(x))[1]) +#endif +#ifndef AV_WB16 +# define AV_WB16(p, val) do { \ + uint16_t d = (val); \ + ((uint8_t*)(p))[1] = (d); \ + ((uint8_t*)(p))[0] = (d)>>8; \ + } while(0) +#endif + +#ifndef AV_RL16 +# define AV_RL16(x) \ + ((((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL16 +# define AV_WL16(p, val) do { \ + uint16_t d = (val); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + } while(0) +#endif + +#ifndef AV_RB32 +# define AV_RB32(x) \ + (((uint32_t)((const uint8_t*)(x))[0] << 24) | \ + (((const uint8_t*)(x))[1] << 16) | \ + (((const uint8_t*)(x))[2] << 8) | \ + ((const uint8_t*)(x))[3]) +#endif +#ifndef AV_WB32 +# define AV_WB32(p, val) do { \ + uint32_t d = (val); \ + ((uint8_t*)(p))[3] = (d); \ + ((uint8_t*)(p))[2] = (d)>>8; \ + ((uint8_t*)(p))[1] = (d)>>16; \ + ((uint8_t*)(p))[0] = (d)>>24; \ + } while(0) +#endif + +#ifndef AV_RL32 +# define AV_RL32(x) \ + (((uint32_t)((const uint8_t*)(x))[3] << 24) | \ + (((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL32 +# define AV_WL32(p, val) do { \ + uint32_t d = (val); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + } while(0) +#endif + +#ifndef AV_RB64 +# define AV_RB64(x) \ + (((uint64_t)((const uint8_t*)(x))[0] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 8) | \ + (uint64_t)((const uint8_t*)(x))[7]) +#endif +#ifndef AV_WB64 +# define AV_WB64(p, val) do { \ + uint64_t d = (val); \ + ((uint8_t*)(p))[7] = (d); \ + ((uint8_t*)(p))[6] = (d)>>8; \ + ((uint8_t*)(p))[5] = (d)>>16; \ + ((uint8_t*)(p))[4] = (d)>>24; \ + ((uint8_t*)(p))[3] = (d)>>32; \ + ((uint8_t*)(p))[2] = (d)>>40; \ + ((uint8_t*)(p))[1] = (d)>>48; \ + ((uint8_t*)(p))[0] = (d)>>56; \ + } while(0) +#endif + +#ifndef AV_RL64 +# define AV_RL64(x) \ + (((uint64_t)((const uint8_t*)(x))[7] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ + (uint64_t)((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL64 +# define AV_WL64(p, val) do { \ + uint64_t d = (val); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + ((uint8_t*)(p))[4] = (d)>>32; \ + ((uint8_t*)(p))[5] = (d)>>40; \ + ((uint8_t*)(p))[6] = (d)>>48; \ + ((uint8_t*)(p))[7] = (d)>>56; \ + } while(0) +#endif + +#if AV_HAVE_BIGENDIAN +# define AV_RN(s, p) AV_RB##s(p) +# define AV_WN(s, p, v) AV_WB##s(p, v) +#else +# define AV_RN(s, p) AV_RL##s(p) +# define AV_WN(s, p, v) AV_WL##s(p, v) +#endif + +#endif /* HAVE_FAST_UNALIGNED */ + +#ifndef AV_RN16 +# define AV_RN16(p) AV_RN(16, p) +#endif + +#ifndef AV_RN32 +# define AV_RN32(p) AV_RN(32, p) +#endif + +#ifndef AV_RN64 +# define AV_RN64(p) AV_RN(64, p) +#endif + +#ifndef AV_WN16 +# define AV_WN16(p, v) AV_WN(16, p, v) +#endif + +#ifndef AV_WN32 +# define AV_WN32(p, v) AV_WN(32, p, v) +#endif + +#ifndef AV_WN64 +# define AV_WN64(p, v) AV_WN(64, p, v) +#endif + +#if AV_HAVE_BIGENDIAN +# define AV_RB(s, p) AV_RN##s(p) +# define AV_WB(s, p, v) AV_WN##s(p, v) +# define AV_RL(s, p) av_bswap##s(AV_RN##s(p)) +# define AV_WL(s, p, v) AV_WN##s(p, av_bswap##s(v)) +#else +# define AV_RB(s, p) av_bswap##s(AV_RN##s(p)) +# define AV_WB(s, p, v) AV_WN##s(p, av_bswap##s(v)) +# define AV_RL(s, p) AV_RN##s(p) +# define AV_WL(s, p, v) AV_WN##s(p, v) +#endif + +#define AV_RB8(x) (((const uint8_t*)(x))[0]) +#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0) + +#define AV_RL8(x) AV_RB8(x) +#define AV_WL8(p, d) AV_WB8(p, d) + +#ifndef AV_RB16 +# define AV_RB16(p) AV_RB(16, p) +#endif +#ifndef AV_WB16 +# define AV_WB16(p, v) AV_WB(16, p, v) +#endif + +#ifndef AV_RL16 +# define AV_RL16(p) AV_RL(16, p) +#endif +#ifndef AV_WL16 +# define AV_WL16(p, v) AV_WL(16, p, v) +#endif + +#ifndef AV_RB32 +# define AV_RB32(p) AV_RB(32, p) +#endif +#ifndef AV_WB32 +# define AV_WB32(p, v) AV_WB(32, p, v) +#endif + +#ifndef AV_RL32 +# define AV_RL32(p) AV_RL(32, p) +#endif +#ifndef AV_WL32 +# define AV_WL32(p, v) AV_WL(32, p, v) +#endif + +#ifndef AV_RB64 +# define AV_RB64(p) AV_RB(64, p) +#endif +#ifndef AV_WB64 +# define AV_WB64(p, v) AV_WB(64, p, v) +#endif + +#ifndef AV_RL64 +# define AV_RL64(p) AV_RL(64, p) +#endif +#ifndef AV_WL64 +# define AV_WL64(p, v) AV_WL(64, p, v) +#endif + +#ifndef AV_RB24 +# define AV_RB24(x) \ + ((((const uint8_t*)(x))[0] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[2]) +#endif +#ifndef AV_WB24 +# define AV_WB24(p, d) do { \ + ((uint8_t*)(p))[2] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[0] = (d)>>16; \ + } while(0) +#endif + +#ifndef AV_RL24 +# define AV_RL24(x) \ + ((((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL24 +# define AV_WL24(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + } while(0) +#endif + +#ifndef AV_RB48 +# define AV_RB48(x) \ + (((uint64_t)((const uint8_t*)(x))[0] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 8) | \ + (uint64_t)((const uint8_t*)(x))[5]) +#endif +#ifndef AV_WB48 +# define AV_WB48(p, darg) do { \ + uint64_t d = (darg); \ + ((uint8_t*)(p))[5] = (d); \ + ((uint8_t*)(p))[4] = (d)>>8; \ + ((uint8_t*)(p))[3] = (d)>>16; \ + ((uint8_t*)(p))[2] = (d)>>24; \ + ((uint8_t*)(p))[1] = (d)>>32; \ + ((uint8_t*)(p))[0] = (d)>>40; \ + } while(0) +#endif + +#ifndef AV_RL48 +# define AV_RL48(x) \ + (((uint64_t)((const uint8_t*)(x))[5] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ + (uint64_t)((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL48 +# define AV_WL48(p, darg) do { \ + uint64_t d = (darg); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + ((uint8_t*)(p))[4] = (d)>>32; \ + ((uint8_t*)(p))[5] = (d)>>40; \ + } while(0) +#endif + +/* + * The AV_[RW]NA macros access naturally aligned data + * in a type-safe way. + */ + +#define AV_RNA(s, p) (((const av_alias##s*)(p))->u##s) +#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v)) + +#ifndef AV_RN16A +# define AV_RN16A(p) AV_RNA(16, p) +#endif + +#ifndef AV_RN32A +# define AV_RN32A(p) AV_RNA(32, p) +#endif + +#ifndef AV_RN64A +# define AV_RN64A(p) AV_RNA(64, p) +#endif + +#ifndef AV_WN16A +# define AV_WN16A(p, v) AV_WNA(16, p, v) +#endif + +#ifndef AV_WN32A +# define AV_WN32A(p, v) AV_WNA(32, p, v) +#endif + +#ifndef AV_WN64A +# define AV_WN64A(p, v) AV_WNA(64, p, v) +#endif + +#if AV_HAVE_BIGENDIAN +# define AV_RLA(s, p) av_bswap##s(AV_RN##s##A(p)) +# define AV_WLA(s, p, v) AV_WN##s##A(p, av_bswap##s(v)) +#else +# define AV_RLA(s, p) AV_RN##s##A(p) +# define AV_WLA(s, p, v) AV_WN##s##A(p, v) +#endif + +#ifndef AV_RL64A +# define AV_RL64A(p) AV_RLA(64, p) +#endif +#ifndef AV_WL64A +# define AV_WL64A(p, v) AV_WLA(64, p, v) +#endif + +/* + * The AV_COPYxxU macros are suitable for copying data to/from unaligned + * memory locations. + */ + +#define AV_COPYU(n, d, s) AV_WN##n(d, AV_RN##n(s)); + +#ifndef AV_COPY16U +# define AV_COPY16U(d, s) AV_COPYU(16, d, s) +#endif + +#ifndef AV_COPY32U +# define AV_COPY32U(d, s) AV_COPYU(32, d, s) +#endif + +#ifndef AV_COPY64U +# define AV_COPY64U(d, s) AV_COPYU(64, d, s) +#endif + +#ifndef AV_COPY128U +# define AV_COPY128U(d, s) \ + do { \ + AV_COPY64U(d, s); \ + AV_COPY64U((char *)(d) + 8, (const char *)(s) + 8); \ + } while(0) +#endif + +/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be + * naturally aligned. They may be implemented using MMX, + * so emms_c() must be called before using any float code + * afterwards. + */ + +#define AV_COPY(n, d, s) \ + (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n) + +#ifndef AV_COPY16 +# define AV_COPY16(d, s) AV_COPY(16, d, s) +#endif + +#ifndef AV_COPY32 +# define AV_COPY32(d, s) AV_COPY(32, d, s) +#endif + +#ifndef AV_COPY64 +# define AV_COPY64(d, s) AV_COPY(64, d, s) +#endif + +#ifndef AV_COPY128 +# define AV_COPY128(d, s) \ + do { \ + AV_COPY64(d, s); \ + AV_COPY64((char*)(d)+8, (char*)(s)+8); \ + } while(0) +#endif + +#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b)) + +#ifndef AV_SWAP64 +# define AV_SWAP64(a, b) AV_SWAP(64, a, b) +#endif + +#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0) + +#ifndef AV_ZERO16 +# define AV_ZERO16(d) AV_ZERO(16, d) +#endif + +#ifndef AV_ZERO32 +# define AV_ZERO32(d) AV_ZERO(32, d) +#endif + +#ifndef AV_ZERO64 +# define AV_ZERO64(d) AV_ZERO(64, d) +#endif + +#ifndef AV_ZERO128 +# define AV_ZERO128(d) \ + do { \ + AV_ZERO64(d); \ + AV_ZERO64((char*)(d)+8); \ + } while(0) +#endif + +#endif /* AVUTIL_INTREADWRITE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.c new file mode 100644 index 000000000..46b04d240 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.c @@ -0,0 +1,87 @@ +/* + * Lagged Fibonacci PRNG + * Copyright (c) 2008 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include "lfg.h" +#include "crc.h" +#include "md5.h" +#include "error.h" +#include "intreadwrite.h" +#include "attributes.h" + +av_cold void av_lfg_init(AVLFG *c, unsigned int seed) +{ + uint8_t tmp[16] = { 0 }; + int i; + + for (i = 8; i < 64; i += 4) { + AV_WL32(tmp, seed); + tmp[4] = i; + av_md5_sum(tmp, tmp, 16); + c->state[i ] = AV_RL32(tmp); + c->state[i + 1] = AV_RL32(tmp + 4); + c->state[i + 2] = AV_RL32(tmp + 8); + c->state[i + 3] = AV_RL32(tmp + 12); + } + c->index = 0; +} + +void av_bmg_get(AVLFG *lfg, double out[2]) +{ + double x1, x2, w; + + do { + x1 = 2.0 / UINT_MAX * av_lfg_get(lfg) - 1.0; + x2 = 2.0 / UINT_MAX * av_lfg_get(lfg) - 1.0; + w = x1 * x1 + x2 * x2; + } while (w >= 1.0); + + w = sqrt((-2.0 * log(w)) / w); + out[0] = x1 * w; + out[1] = x2 * w; +} + +int av_lfg_init_from_data(AVLFG *c, const uint8_t *data, unsigned int length) { + unsigned int beg, end, segm; + const AVCRC *avcrc; + uint32_t crc = 1; + + /* avoid integer overflow in the loop below. */ + if (length > (UINT_MAX / 128U)) return AVERROR(EINVAL); + + c->index = 0; + avcrc = av_crc_get_table(AV_CRC_32_IEEE); /* This can't fail. It's a well-defined table in crc.c */ + + /* across 64 segments of the incoming data, + * do a running crc of each segment and store the crc as the state for that slot. + * this works even if the length of the segment is 0 bytes. */ + beg = 0; + for (segm = 0;segm < 64;segm++) { + end = (((segm + 1) * length) / 64); + crc = av_crc(avcrc, crc, data + beg, end - beg); + c->state[segm] = (unsigned int)crc; + beg = end; + } + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.h new file mode 100644 index 000000000..03f779ad8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lfg.h @@ -0,0 +1,71 @@ +/* + * Lagged Fibonacci PRNG + * Copyright (c) 2008 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LFG_H +#define AVUTIL_LFG_H + +#include + +typedef struct AVLFG { + unsigned int state[64]; + int index; +} AVLFG; + +void av_lfg_init(AVLFG *c, unsigned int seed); + +/** + * Seed the state of the ALFG using binary data. + * + * Return value: 0 on success, negative value (AVERROR) on failure. + */ +int av_lfg_init_from_data(AVLFG *c, const uint8_t *data, unsigned int length); + +/** + * Get the next random unsigned 32-bit number using an ALFG. + * + * Please also consider a simple LCG like state= state*1664525+1013904223, + * it may be good enough and faster for your specific use case. + */ +static inline unsigned int av_lfg_get(AVLFG *c){ + c->state[c->index & 63] = c->state[(c->index-24) & 63] + c->state[(c->index-55) & 63]; + return c->state[c->index++ & 63]; +} + +/** + * Get the next random unsigned 32-bit number using a MLFG. + * + * Please also consider av_lfg_get() above, it is faster. + */ +static inline unsigned int av_mlfg_get(AVLFG *c){ + unsigned int a= c->state[(c->index-55) & 63]; + unsigned int b= c->state[(c->index-24) & 63]; + return c->state[c->index++ & 63] = 2*a*b+a+b; +} + +/** + * Get the next two numbers generated by a Box-Muller Gaussian + * generator using the random numbers issued by lfg. + * + * @param out array where the two generated numbers are placed + */ +void av_bmg_get(AVLFG *lfg, double out[2]); + +#endif /* AVUTIL_LFG_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/libm.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/libm.h new file mode 100644 index 000000000..a81996239 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/libm.h @@ -0,0 +1,471 @@ +/* + * erf function: Copyright (c) 2006 John Maddock + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Replacements for frequently missing libm functions + */ + +#ifndef AVUTIL_LIBM_H +#define AVUTIL_LIBM_H + +#include +#include "config.h" +#include "attributes.h" +#include "intfloat.h" +#include "mathematics.h" + +#if HAVE_MIPSFPU && HAVE_INLINE_ASM +#include "libavutil/mips/libm_mips.h" +#endif /* HAVE_MIPSFPU && HAVE_INLINE_ASM*/ + +#if !HAVE_ATANF +#undef atanf +#define atanf(x) ((float)atan(x)) +#endif /* HAVE_ATANF */ + +#if !HAVE_ATAN2F +#undef atan2f +#define atan2f(y, x) ((float)atan2(y, x)) +#endif /* HAVE_ATAN2F */ + +#if !HAVE_POWF +#undef powf +#define powf(x, y) ((float)pow(x, y)) +#endif /* HAVE_POWF */ + +#if !HAVE_CBRT +static av_always_inline double cbrt(double x) +{ + return x < 0 ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0); +} +#endif /* HAVE_CBRT */ + +#if !HAVE_CBRTF +static av_always_inline float cbrtf(float x) +{ + return x < 0 ? -powf(-x, 1.0 / 3.0) : powf(x, 1.0 / 3.0); +} +#endif /* HAVE_CBRTF */ + +#if !HAVE_COPYSIGN +static av_always_inline double copysign(double x, double y) +{ + uint64_t vx = av_double2int(x); + uint64_t vy = av_double2int(y); + return av_int2double((vx & UINT64_C(0x7fffffffffffffff)) | (vy & UINT64_C(0x8000000000000000))); +} +#endif /* HAVE_COPYSIGN */ + +#if !HAVE_COSF +#undef cosf +#define cosf(x) ((float)cos(x)) +#endif /* HAVE_COSF */ + +#if !HAVE_ERF +static inline double ff_eval_poly(const double *coeff, int size, double x) { + double sum = coeff[size-1]; + int i; + for (i = size-2; i >= 0; --i) { + sum *= x; + sum += coeff[i]; + } + return sum; +} + +/** + * erf function + * Algorithm taken from the Boost project, source: + * http://www.boost.org/doc/libs/1_46_1/boost/math/special_functions/erf.hpp + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0 (see notice below). + * Boost Software License - Version 1.0 - August 17th, 2003 +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + */ +static inline double erf(double z) +{ +#ifndef FF_ARRAY_ELEMS +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) +#endif + double result; + + /* handle the symmetry: erf(-x) = -erf(x) */ + if (z < 0) + return -erf(-z); + + /* branch based on range of z, and pick appropriate approximation */ + if (z == 0) + return 0; + else if (z < 1e-10) + return z * 1.125 + z * 0.003379167095512573896158903121545171688; + else if (z < 0.5) { + // Maximum Deviation Found: 1.561e-17 + // Expected Error Term: 1.561e-17 + // Maximum Relative Change in Control Points: 1.155e-04 + // Max Error found at double precision = 2.961182e-17 + + static const double y = 1.044948577880859375; + static const double p[] = { + 0.0834305892146531832907, + -0.338165134459360935041, + -0.0509990735146777432841, + -0.00772758345802133288487, + -0.000322780120964605683831, + }; + static const double q[] = { + 1, + 0.455004033050794024546, + 0.0875222600142252549554, + 0.00858571925074406212772, + 0.000370900071787748000569, + }; + double zz = z * z; + return z * (y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), zz) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), zz)); + } + /* here onwards compute erfc */ + else if (z < 1.5) { + // Maximum Deviation Found: 3.702e-17 + // Expected Error Term: 3.702e-17 + // Maximum Relative Change in Control Points: 2.845e-04 + // Max Error found at double precision = 4.841816e-17 + static const double y = 0.405935764312744140625; + static const double p[] = { + -0.098090592216281240205, + 0.178114665841120341155, + 0.191003695796775433986, + 0.0888900368967884466578, + 0.0195049001251218801359, + 0.00180424538297014223957, + }; + static const double q[] = { + 1, + 1.84759070983002217845, + 1.42628004845511324508, + 0.578052804889902404909, + 0.12385097467900864233, + 0.0113385233577001411017, + 0.337511472483094676155e-5, + }; + result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 0.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 0.5); + result *= exp(-z * z) / z; + return 1 - result; + } + else if (z < 2.5) { + // Max Error found at double precision = 6.599585e-18 + // Maximum Deviation Found: 3.909e-18 + // Expected Error Term: 3.909e-18 + // Maximum Relative Change in Control Points: 9.886e-05 + static const double y = 0.50672817230224609375; + static const double p[] = { + -0.0243500476207698441272, + 0.0386540375035707201728, + 0.04394818964209516296, + 0.0175679436311802092299, + 0.00323962406290842133584, + 0.000235839115596880717416, + }; + static const double q[] = { + 1, + 1.53991494948552447182, + 0.982403709157920235114, + 0.325732924782444448493, + 0.0563921837420478160373, + 0.00410369723978904575884, + }; + result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 1.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 1.5); + result *= exp(-z * z) / z; + return 1 - result; + } + else if (z < 4.5) { + // Maximum Deviation Found: 1.512e-17 + // Expected Error Term: 1.512e-17 + // Maximum Relative Change in Control Points: 2.222e-04 + // Max Error found at double precision = 2.062515e-17 + static const double y = 0.5405750274658203125; + static const double p[] = { + 0.00295276716530971662634, + 0.0137384425896355332126, + 0.00840807615555585383007, + 0.00212825620914618649141, + 0.000250269961544794627958, + 0.113212406648847561139e-4, + }; + static const double q[] = { + 1, + 1.04217814166938418171, + 0.442597659481563127003, + 0.0958492726301061423444, + 0.0105982906484876531489, + 0.000479411269521714493907, + }; + result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 3.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 3.5); + result *= exp(-z * z) / z; + return 1 - result; + } + /* differ from Boost here, the claim of underflow of erfc(x) past 5.8 is + * slightly incorrect, change to 5.92 + * (really somewhere between 5.9125 and 5.925 is when it saturates) */ + else if (z < 5.92) { + // Max Error found at double precision = 2.997958e-17 + // Maximum Deviation Found: 2.860e-17 + // Expected Error Term: 2.859e-17 + // Maximum Relative Change in Control Points: 1.357e-05 + static const double y = 0.5579090118408203125; + static const double p[] = { + 0.00628057170626964891937, + 0.0175389834052493308818, + -0.212652252872804219852, + -0.687717681153649930619, + -2.5518551727311523996, + -3.22729451764143718517, + -2.8175401114513378771, + }; + static const double q[] = { + 1, + 2.79257750980575282228, + 11.0567237927800161565, + 15.930646027911794143, + 22.9367376522880577224, + 13.5064170191802889145, + 5.48409182238641741584, + }; + result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), 1 / z) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), 1 / z); + result *= exp(-z * z) / z; + return 1 - result; + } + /* handle the nan case, but don't use isnan for max portability */ + else if (z != z) + return z; + /* finally return saturated result */ + else + return 1; +} +#endif /* HAVE_ERF */ + +#if !HAVE_EXPF +#undef expf +#define expf(x) ((float)exp(x)) +#endif /* HAVE_EXPF */ + +#if !HAVE_EXP2 +#undef exp2 +#define exp2(x) exp((x) * M_LN2) +#endif /* HAVE_EXP2 */ + +#if !HAVE_EXP2F +#undef exp2f +#define exp2f(x) ((float)exp2(x)) +#endif /* HAVE_EXP2F */ + +#if !HAVE_ISINF +#undef isinf +/* Note: these do not follow the BSD/Apple/GNU convention of returning -1 for +-Inf, +1 for Inf, 0 otherwise, but merely follow the POSIX/ISO mandated spec of +returning a non-zero value for +/-Inf, 0 otherwise. */ +static av_always_inline av_const int avpriv_isinff(float x) +{ + uint32_t v = av_float2int(x); + if ((v & 0x7f800000) != 0x7f800000) + return 0; + return !(v & 0x007fffff); +} + +static av_always_inline av_const int avpriv_isinf(double x) +{ + uint64_t v = av_double2int(x); + if ((v & 0x7ff0000000000000) != 0x7ff0000000000000) + return 0; + return !(v & 0x000fffffffffffff); +} + +#define isinf(x) \ + (sizeof(x) == sizeof(float) \ + ? avpriv_isinff(x) \ + : avpriv_isinf(x)) +#endif /* HAVE_ISINF */ + +#if !HAVE_ISNAN +static av_always_inline av_const int avpriv_isnanf(float x) +{ + uint32_t v = av_float2int(x); + if ((v & 0x7f800000) != 0x7f800000) + return 0; + return v & 0x007fffff; +} + +static av_always_inline av_const int avpriv_isnan(double x) +{ + uint64_t v = av_double2int(x); + if ((v & 0x7ff0000000000000) != 0x7ff0000000000000) + return 0; + return (v & 0x000fffffffffffff) && 1; +} + +#define isnan(x) \ + (sizeof(x) == sizeof(float) \ + ? avpriv_isnanf(x) \ + : avpriv_isnan(x)) +#endif /* HAVE_ISNAN */ + +#if !HAVE_ISFINITE +static av_always_inline av_const int avpriv_isfinitef(float x) +{ + uint32_t v = av_float2int(x); + return (v & 0x7f800000) != 0x7f800000; +} + +static av_always_inline av_const int avpriv_isfinite(double x) +{ + uint64_t v = av_double2int(x); + return (v & 0x7ff0000000000000) != 0x7ff0000000000000; +} + +#define isfinite(x) \ + (sizeof(x) == sizeof(float) \ + ? avpriv_isfinitef(x) \ + : avpriv_isfinite(x)) +#endif /* HAVE_ISFINITE */ + +#if !HAVE_HYPOT +static inline av_const double hypot(double x, double y) +{ + double ret, temp; + x = fabs(x); + y = fabs(y); + + if (isinf(x) || isinf(y)) + return av_int2double(0x7ff0000000000000); + if (x == 0 || y == 0) + return x + y; + if (x < y) { + temp = x; + x = y; + y = temp; + } + + y = y/x; + return x*sqrt(1 + y*y); +} +#endif /* HAVE_HYPOT */ + +#if !HAVE_LDEXPF +#undef ldexpf +#define ldexpf(x, exp) ((float)ldexp(x, exp)) +#endif /* HAVE_LDEXPF */ + +#if !HAVE_LLRINT +#undef llrint +#define llrint(x) ((long long)rint(x)) +#endif /* HAVE_LLRINT */ + +#if !HAVE_LLRINTF +#undef llrintf +#define llrintf(x) ((long long)rint(x)) +#endif /* HAVE_LLRINT */ + +#if !HAVE_LOG2 +#undef log2 +#define log2(x) (log(x) * 1.44269504088896340736) +#endif /* HAVE_LOG2 */ + +#if !HAVE_LOG2F +#undef log2f +#define log2f(x) ((float)log2(x)) +#endif /* HAVE_LOG2F */ + +#if !HAVE_LOG10F +#undef log10f +#define log10f(x) ((float)log10(x)) +#endif /* HAVE_LOG10F */ + +#if !HAVE_SINF +#undef sinf +#define sinf(x) ((float)sin(x)) +#endif /* HAVE_SINF */ + +#if !HAVE_RINT +static inline double rint(double x) +{ + return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); +} +#endif /* HAVE_RINT */ + +#if !HAVE_LRINT +static av_always_inline av_const long int lrint(double x) +{ + return rint(x); +} +#endif /* HAVE_LRINT */ + +#if !HAVE_LRINTF +static av_always_inline av_const long int lrintf(float x) +{ + return (int)(rint(x)); +} +#endif /* HAVE_LRINTF */ + +#if !HAVE_ROUND +static av_always_inline av_const double round(double x) +{ + return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); +} +#endif /* HAVE_ROUND */ + +#if !HAVE_ROUNDF +static av_always_inline av_const float roundf(float x) +{ + return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); +} +#endif /* HAVE_ROUNDF */ + +#if !HAVE_TRUNC +static av_always_inline av_const double trunc(double x) +{ + return (x > 0) ? floor(x) : ceil(x); +} +#endif /* HAVE_TRUNC */ + +#if !HAVE_TRUNCF +static av_always_inline av_const float truncf(float x) +{ + return (x > 0) ? floor(x) : ceil(x); +} +#endif /* HAVE_TRUNCF */ + +#endif /* AVUTIL_LIBM_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.c new file mode 100644 index 000000000..0560b6a79 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.c @@ -0,0 +1,123 @@ +/* + * linear least squares model + * + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * linear least squares model + */ + +#include +#include + +#include "attributes.h" +#include "internal.h" +#include "version.h" +#include "lls.h" + +static void update_lls(LLSModel *m, const double *var) +{ + int i, j; + + for (i = 0; i <= m->indep_count; i++) { + for (j = i; j <= m->indep_count; j++) { + m->covariance[i][j] += var[i] * var[j]; + } + } +} + +void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order) +{ + int i, j, k; + double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0]; + double (*covar) [MAX_VARS_ALIGN] = (void *) &m->covariance[1][1]; + double *covar_y = m->covariance[0]; + int count = m->indep_count; + + for (i = 0; i < count; i++) { + for (j = i; j < count; j++) { + double sum = covar[i][j]; + + for (k = 0; k <= i-1; k++) + sum -= factor[i][k] * factor[j][k]; + + if (i == j) { + if (sum < threshold) + sum = 1.0; + factor[i][i] = sqrt(sum); + } else { + factor[j][i] = sum / factor[i][i]; + } + } + } + + for (i = 0; i < count; i++) { + double sum = covar_y[i + 1]; + + for (k = 0; k <= i-1; k++) + sum -= factor[i][k] * m->coeff[0][k]; + + m->coeff[0][i] = sum / factor[i][i]; + } + + for (j = count - 1; j >= min_order; j--) { + for (i = j; i >= 0; i--) { + double sum = m->coeff[0][i]; + + for (k = i + 1; k <= j; k++) + sum -= factor[k][i] * m->coeff[j][k]; + + m->coeff[j][i] = sum / factor[i][i]; + } + + m->variance[j] = covar_y[0]; + + for (i = 0; i <= j; i++) { + double sum = m->coeff[j][i] * covar[i][i] - 2 * covar_y[i + 1]; + + for (k = 0; k < i; k++) + sum += 2 * m->coeff[j][k] * covar[k][i]; + + m->variance[j] += m->coeff[j][i] * sum; + } + } +} + +static double evaluate_lls(LLSModel *m, const double *param, int order) +{ + int i; + double out = 0; + + for (i = 0; i <= order; i++) + out += param[i] * m->coeff[order][i]; + + return out; +} + +av_cold void avpriv_init_lls(LLSModel *m, int indep_count) +{ + memset(m, 0, sizeof(LLSModel)); + m->indep_count = indep_count; + m->update_lls = update_lls; + m->evaluate_lls = evaluate_lls; + if (ARCH_X86) + ff_init_lls_x86(m); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.h new file mode 100644 index 000000000..1a276d537 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/lls.h @@ -0,0 +1,64 @@ +/* + * linear least squares model + * + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LLS_H +#define AVUTIL_LLS_H + +#include "macros.h" +#include "mem.h" +#include "version.h" + +#define MAX_VARS 32 +#define MAX_VARS_ALIGN FFALIGN(MAX_VARS+1,4) + +//FIXME avoid direct access to LLSModel from outside + +/** + * Linear least squares model. + */ +typedef struct LLSModel { + DECLARE_ALIGNED(32, double, covariance[MAX_VARS_ALIGN][MAX_VARS_ALIGN]); + DECLARE_ALIGNED(32, double, coeff[MAX_VARS][MAX_VARS]); + double variance[MAX_VARS]; + int indep_count; + /** + * Take the outer-product of var[] with itself, and add to the covariance matrix. + * @param m this context + * @param var training samples, starting with the value to be predicted + * 32-byte aligned, and any padding elements must be initialized + * (i.e not denormal/nan). + */ + void (*update_lls)(struct LLSModel *m, const double *var); + /** + * Inner product of var[] and the LPC coefs. + * @param m this context + * @param var training samples, excluding the value to be predicted. unaligned. + * @param order lpc order + */ + double (*evaluate_lls)(struct LLSModel *m, const double *var, int order); +} LLSModel; + +void avpriv_init_lls(LLSModel *m, int indep_count); +void ff_init_lls_x86(LLSModel *m); +void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order); + +#endif /* AVUTIL_LLS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.c new file mode 100644 index 000000000..93a156b8e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.c @@ -0,0 +1,435 @@ +/* + * log functions + * Copyright (c) 2003 Michel Bardiaux + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * logging functions + */ + +#include "config.h" + +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_IO_H +#include +#endif +#include +#include +#include "avutil.h" +#include "bprint.h" +#include "common.h" +#include "internal.h" +#include "log.h" +#include "thread.h" + +static AVMutex mutex = AV_MUTEX_INITIALIZER; + +#define LINE_SZ 1024 + +#if HAVE_VALGRIND_VALGRIND_H +#include +/* this is the log level at which valgrind will output a full backtrace */ +#define BACKTRACE_LOGLEVEL AV_LOG_ERROR +#endif + +static int av_log_level = AV_LOG_INFO; +static int flags; + +#define NB_LEVELS 8 +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE +#include +static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = { + [AV_LOG_PANIC /8] = 12, + [AV_LOG_FATAL /8] = 12, + [AV_LOG_ERROR /8] = 12, + [AV_LOG_WARNING/8] = 14, + [AV_LOG_INFO /8] = 7, + [AV_LOG_VERBOSE/8] = 10, + [AV_LOG_DEBUG /8] = 10, + [AV_LOG_TRACE /8] = 8, + [16+AV_CLASS_CATEGORY_NA ] = 7, + [16+AV_CLASS_CATEGORY_INPUT ] = 13, + [16+AV_CLASS_CATEGORY_OUTPUT ] = 5, + [16+AV_CLASS_CATEGORY_MUXER ] = 13, + [16+AV_CLASS_CATEGORY_DEMUXER ] = 5, + [16+AV_CLASS_CATEGORY_ENCODER ] = 11, + [16+AV_CLASS_CATEGORY_DECODER ] = 3, + [16+AV_CLASS_CATEGORY_FILTER ] = 10, + [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 9, + [16+AV_CLASS_CATEGORY_SWSCALER ] = 7, + [16+AV_CLASS_CATEGORY_SWRESAMPLER ] = 7, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 13, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT ] = 5, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 13, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT ] = 5, + [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT ] = 13, + [16+AV_CLASS_CATEGORY_DEVICE_INPUT ] = 5, +}; + +static int16_t background, attr_orig; +static HANDLE con; +#else + +static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = { + [AV_LOG_PANIC /8] = 52 << 16 | 196 << 8 | 0x41, + [AV_LOG_FATAL /8] = 208 << 8 | 0x41, + [AV_LOG_ERROR /8] = 196 << 8 | 0x11, + [AV_LOG_WARNING/8] = 226 << 8 | 0x03, + [AV_LOG_INFO /8] = 253 << 8 | 0x09, + [AV_LOG_VERBOSE/8] = 40 << 8 | 0x02, + [AV_LOG_DEBUG /8] = 34 << 8 | 0x02, + [AV_LOG_TRACE /8] = 34 << 8 | 0x07, + [16+AV_CLASS_CATEGORY_NA ] = 250 << 8 | 0x09, + [16+AV_CLASS_CATEGORY_INPUT ] = 219 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_OUTPUT ] = 201 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_MUXER ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEMUXER ] = 207 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_ENCODER ] = 51 << 8 | 0x16, + [16+AV_CLASS_CATEGORY_DECODER ] = 39 << 8 | 0x06, + [16+AV_CLASS_CATEGORY_FILTER ] = 155 << 8 | 0x12, + [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 192 << 8 | 0x14, + [16+AV_CLASS_CATEGORY_SWSCALER ] = 153 << 8 | 0x14, + [16+AV_CLASS_CATEGORY_SWRESAMPLER ] = 147 << 8 | 0x14, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT ] = 207 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT ] = 207 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEVICE_INPUT ] = 207 << 8 | 0x05, +}; + +#endif +static int use_color = -1; + +static void check_color_terminal(void) +{ +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE + CONSOLE_SCREEN_BUFFER_INFO con_info; + con = GetStdHandle(STD_ERROR_HANDLE); + use_color = (con != INVALID_HANDLE_VALUE) && !getenv("NO_COLOR") && + !getenv("AV_LOG_FORCE_NOCOLOR"); + if (use_color) { + GetConsoleScreenBufferInfo(con, &con_info); + attr_orig = con_info.wAttributes; + background = attr_orig & 0xF0; + } +#elif HAVE_ISATTY + char *term = getenv("TERM"); + use_color = !getenv("NO_COLOR") && !getenv("AV_LOG_FORCE_NOCOLOR") && + (getenv("TERM") && isatty(2) || getenv("AV_LOG_FORCE_COLOR")); + if ( getenv("AV_LOG_FORCE_256COLOR") + || (term && strstr(term, "256color"))) + use_color *= 256; +#else + use_color = getenv("AV_LOG_FORCE_COLOR") && !getenv("NO_COLOR") && + !getenv("AV_LOG_FORCE_NOCOLOR"); +#endif +} + +static void colored_fputs(int level, int tint, const char *str) +{ + int local_use_color; + if (!*str) + return; + + if (use_color < 0) + check_color_terminal(); + + if (level == AV_LOG_INFO/8) local_use_color = 0; + else local_use_color = use_color; + +#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE + if (local_use_color) + SetConsoleTextAttribute(con, background | color[level]); + fputs(str, stderr); + if (local_use_color) + SetConsoleTextAttribute(con, attr_orig); +#else + if (local_use_color == 1) { + fprintf(stderr, + "\033[%"PRIu32";3%"PRIu32"m%s\033[0m", + (color[level] >> 4) & 15, + color[level] & 15, + str); + } else if (tint && use_color == 256) { + fprintf(stderr, + "\033[48;5;%"PRIu32"m\033[38;5;%dm%s\033[0m", + (color[level] >> 16) & 0xff, + tint, + str); + } else if (local_use_color == 256) { + fprintf(stderr, + "\033[48;5;%"PRIu32"m\033[38;5;%"PRIu32"m%s\033[0m", + (color[level] >> 16) & 0xff, + (color[level] >> 8) & 0xff, + str); + } else + fputs(str, stderr); +#endif + +} + +const char *av_default_item_name(void *ptr) +{ + return (*(AVClass **) ptr)->class_name; +} + +AVClassCategory av_default_get_category(void *ptr) +{ + return (*(AVClass **) ptr)->category; +} + +static void sanitize(uint8_t *line){ + while(*line){ + if(*line < 0x08 || (*line > 0x0D && *line < 0x20)) + *line='?'; + line++; + } +} + +static int get_category(void *ptr){ + AVClass *avc = *(AVClass **) ptr; + if( !avc + || (avc->version&0xFF)<100 + || avc->version < (51 << 16 | 59 << 8) + || avc->category >= AV_CLASS_CATEGORY_NB) return AV_CLASS_CATEGORY_NA + 16; + + if(avc->get_category) + return avc->get_category(ptr) + 16; + + return avc->category + 16; +} + +static const char *get_level_str(int level) +{ + switch (level) { + case AV_LOG_QUIET: + return "quiet"; + case AV_LOG_DEBUG: + return "debug"; + case AV_LOG_VERBOSE: + return "verbose"; + case AV_LOG_INFO: + return "info"; + case AV_LOG_WARNING: + return "warning"; + case AV_LOG_ERROR: + return "error"; + case AV_LOG_FATAL: + return "fatal"; + case AV_LOG_PANIC: + return "panic"; + default: + return ""; + } +} + +static void format_line(void *avcl, int level, const char *fmt, va_list vl, + AVBPrint part[4], int *print_prefix, int type[2]) +{ + AVClass* avc = avcl ? *(AVClass **) avcl : NULL; + av_bprint_init(part+0, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprint_init(part+1, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprint_init(part+2, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprint_init(part+3, 0, 65536); + + if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16; + if (*print_prefix && avc) { + if (avc->parent_log_context_offset) { + AVClass** parent = *(AVClass ***) (((uint8_t *) avcl) + + avc->parent_log_context_offset); + if (parent && *parent) { + av_bprintf(part+0, "[%s @ %p] ", + (*parent)->item_name(parent), parent); + if(type) type[0] = get_category(parent); + } + } + av_bprintf(part+1, "[%s @ %p] ", + avc->item_name(avcl), avcl); + if(type) type[1] = get_category(avcl); + } + + if (*print_prefix && (level > AV_LOG_QUIET) && (flags & AV_LOG_PRINT_LEVEL)) + av_bprintf(part+2, "[%s] ", get_level_str(level)); + + av_vbprintf(part+3, fmt, vl); + + if(*part[0].str || *part[1].str || *part[2].str || *part[3].str) { + char lastc = part[3].len && part[3].len <= part[3].size ? part[3].str[part[3].len - 1] : 0; + *print_prefix = lastc == '\n' || lastc == '\r'; + } +} + +void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix) +{ + av_log_format_line2(ptr, level, fmt, vl, line, line_size, print_prefix); +} + +int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix) +{ + AVBPrint part[4]; + int ret; + + format_line(ptr, level, fmt, vl, part, print_prefix, NULL); + ret = snprintf(line, line_size, "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str); + av_bprint_finalize(part+3, NULL); + return ret; +} + +void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) +{ + static int print_prefix = 1; + static int count; + static char prev[LINE_SZ]; + AVBPrint part[4]; + char line[LINE_SZ]; + static int is_atty; + int type[2]; + unsigned tint = 0; + + if (level >= 0) { + tint = level & 0xff00; + level &= 0xff; + } + + if (level > av_log_level) + return; + ff_mutex_lock(&mutex); + + format_line(ptr, level, fmt, vl, part, &print_prefix, type); + snprintf(line, sizeof(line), "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str); + +#if HAVE_ISATTY + if (!is_atty) + is_atty = isatty(2) ? 1 : -1; +#endif + + if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev) && + *line && line[strlen(line) - 1] != '\r'){ + count++; + if (is_atty == 1) + fprintf(stderr, " Last message repeated %d times\r", count); + goto end; + } + if (count > 0) { + fprintf(stderr, " Last message repeated %d times\n", count); + count = 0; + } + strcpy(prev, line); + sanitize(part[0].str); + colored_fputs(type[0], 0, part[0].str); + sanitize(part[1].str); + colored_fputs(type[1], 0, part[1].str); + sanitize(part[2].str); + colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[2].str); + sanitize(part[3].str); + colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[3].str); + +#if CONFIG_VALGRIND_BACKTRACE + if (level <= BACKTRACE_LOGLEVEL) + VALGRIND_PRINTF_BACKTRACE("%s", ""); +#endif +end: + av_bprint_finalize(part+3, NULL); + ff_mutex_unlock(&mutex); +} + +static void (*av_log_callback)(void*, int, const char*, va_list) = + av_log_default_callback; + +void av_log(void* avcl, int level, const char *fmt, ...) +{ + AVClass* avc = avcl ? *(AVClass **) avcl : NULL; + va_list vl; + va_start(vl, fmt); + if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) && + avc->log_level_offset_offset && level >= AV_LOG_FATAL) + level += *(int *) (((uint8_t *) avcl) + avc->log_level_offset_offset); + av_vlog(avcl, level, fmt, vl); + va_end(vl); +} + +void av_vlog(void* avcl, int level, const char *fmt, va_list vl) +{ + void (*log_callback)(void*, int, const char*, va_list) = av_log_callback; + if (log_callback) + log_callback(avcl, level, fmt, vl); +} + +int av_log_get_level(void) +{ + return av_log_level; +} + +void av_log_set_level(int level) +{ + av_log_level = level; +} + +void av_log_set_flags(int arg) +{ + flags = arg; +} + +int av_log_get_flags(void) +{ + return flags; +} + +void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)) +{ + av_log_callback = callback; +} + +static void missing_feature_sample(int sample, void *avc, const char *msg, + va_list argument_list) +{ + av_vlog(avc, AV_LOG_WARNING, msg, argument_list); + av_log(avc, AV_LOG_WARNING, " is not implemented. Update your FFmpeg " + "version to the newest one from Git. If the problem still " + "occurs, it means that your file has a feature which has not " + "been implemented.\n"); + if (sample) + av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample " + "of this file to ftp://upload.ffmpeg.org/incoming/ " + "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)\n"); +} + +void avpriv_request_sample(void *avc, const char *msg, ...) +{ + va_list argument_list; + + va_start(argument_list, msg); + missing_feature_sample(1, avc, msg, argument_list); + va_end(argument_list); +} + +void avpriv_report_missing_feature(void *avc, const char *msg, ...) +{ + va_list argument_list; + + va_start(argument_list, msg); + missing_feature_sample(0, avc, msg, argument_list); + va_end(argument_list); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.h new file mode 100644 index 000000000..d9554e609 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log.h @@ -0,0 +1,362 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LOG_H +#define AVUTIL_LOG_H + +#include +#include "avutil.h" +#include "attributes.h" +#include "version.h" + +typedef enum { + AV_CLASS_CATEGORY_NA = 0, + AV_CLASS_CATEGORY_INPUT, + AV_CLASS_CATEGORY_OUTPUT, + AV_CLASS_CATEGORY_MUXER, + AV_CLASS_CATEGORY_DEMUXER, + AV_CLASS_CATEGORY_ENCODER, + AV_CLASS_CATEGORY_DECODER, + AV_CLASS_CATEGORY_FILTER, + AV_CLASS_CATEGORY_BITSTREAM_FILTER, + AV_CLASS_CATEGORY_SWSCALER, + AV_CLASS_CATEGORY_SWRESAMPLER, + AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT = 40, + AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, + AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, + AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, + AV_CLASS_CATEGORY_DEVICE_OUTPUT, + AV_CLASS_CATEGORY_DEVICE_INPUT, + AV_CLASS_CATEGORY_NB ///< not part of ABI/API +}AVClassCategory; + +#define AV_IS_INPUT_DEVICE(category) \ + (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_INPUT)) + +#define AV_IS_OUTPUT_DEVICE(category) \ + (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_OUTPUT)) + +struct AVOptionRanges; + +/** + * Describe the class of an AVClass context structure. That is an + * arbitrary struct of which the first field is a pointer to an + * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). + */ +typedef struct AVClass { + /** + * The name of the class; usually it is the same name as the + * context structure type to which the AVClass is associated. + */ + const char* class_name; + + /** + * A pointer to a function which returns the name of a context + * instance ctx associated with the class. + */ + const char* (*item_name)(void* ctx); + + /** + * a pointer to the first option specified in the class if any or NULL + * + * @see av_set_default_options() + */ + const struct AVOption *option; + + /** + * LIBAVUTIL_VERSION with which this structure was created. + * This is used to allow fields to be added without requiring major + * version bumps everywhere. + */ + + int version; + + /** + * Offset in the structure where log_level_offset is stored. + * 0 means there is no such variable + */ + int log_level_offset_offset; + + /** + * Offset in the structure where a pointer to the parent context for + * logging is stored. For example a decoder could pass its AVCodecContext + * to eval as such a parent context, which an av_log() implementation + * could then leverage to display the parent context. + * The offset can be NULL. + */ + int parent_log_context_offset; + + /** + * Return next AVOptions-enabled child or NULL + */ + void* (*child_next)(void *obj, void *prev); + + /** + * Return an AVClass corresponding to the next potential + * AVOptions-enabled child. + * + * The difference between child_next and this is that + * child_next iterates over _already existing_ objects, while + * child_class_next iterates over _all possible_ children. + */ + const struct AVClass* (*child_class_next)(const struct AVClass *prev); + + /** + * Category used for visualization (like color) + * This is only set if the category is equal for all objects using this class. + * available since version (51 << 16 | 56 << 8 | 100) + */ + AVClassCategory category; + + /** + * Callback to return the category. + * available since version (51 << 16 | 59 << 8 | 100) + */ + AVClassCategory (*get_category)(void* ctx); + + /** + * Callback to return the supported/allowed ranges. + * available since version (52.12) + */ + int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); +} AVClass; + +/** + * @addtogroup lavu_log + * + * @{ + * + * @defgroup lavu_log_constants Logging Constants + * + * @{ + */ + +/** + * Print no output. + */ +#define AV_LOG_QUIET -8 + +/** + * Something went really wrong and we will crash now. + */ +#define AV_LOG_PANIC 0 + +/** + * Something went wrong and recovery is not possible. + * For example, no header was found for a format which depends + * on headers or an illegal combination of parameters is used. + */ +#define AV_LOG_FATAL 8 + +/** + * Something went wrong and cannot losslessly be recovered. + * However, not all future data is affected. + */ +#define AV_LOG_ERROR 16 + +/** + * Something somehow does not look correct. This may or may not + * lead to problems. An example would be the use of '-vstrict -2'. + */ +#define AV_LOG_WARNING 24 + +/** + * Standard information. + */ +#define AV_LOG_INFO 32 + +/** + * Detailed information. + */ +#define AV_LOG_VERBOSE 40 + +/** + * Stuff which is only useful for libav* developers. + */ +#define AV_LOG_DEBUG 48 + +/** + * Extremely verbose debugging, useful for libav* development. + */ +#define AV_LOG_TRACE 56 + +#define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET) + +/** + * @} + */ + +/** + * Sets additional colors for extended debugging sessions. + * @code + av_log(ctx, AV_LOG_DEBUG|AV_LOG_C(134), "Message in purple\n"); + @endcode + * Requires 256color terminal support. Uses outside debugging is not + * recommended. + */ +#define AV_LOG_C(x) ((x) << 8) + +/** + * Send the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different logging callback + * function. + * @see av_log_set_callback + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct or NULL if general log. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + */ +void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4); + + +/** + * Send the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different logging callback + * function. + * @see av_log_set_callback + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param vl The arguments referenced by the format string. + */ +void av_vlog(void *avcl, int level, const char *fmt, va_list vl); + +/** + * Get the current log level + * + * @see lavu_log_constants + * + * @return Current log level + */ +int av_log_get_level(void); + +/** + * Set the log level + * + * @see lavu_log_constants + * + * @param level Logging level + */ +void av_log_set_level(int level); + +/** + * Set the logging callback + * + * @note The callback must be thread safe, even if the application does not use + * threads itself as some codecs are multithreaded. + * + * @see av_log_default_callback + * + * @param callback A logging function with a compatible signature. + */ +void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)); + +/** + * Default logging callback + * + * It prints the message to stderr, optionally colorizing it. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param vl The arguments referenced by the format string. + */ +void av_log_default_callback(void *avcl, int level, const char *fmt, + va_list vl); + +/** + * Return the context name + * + * @param ctx The AVClass context + * + * @return The AVClass class_name + */ +const char* av_default_item_name(void* ctx); +AVClassCategory av_default_get_category(void *ptr); + +/** + * Format a line of log the same way as the default callback. + * @param line buffer to receive the formatted line + * @param line_size size of the buffer + * @param print_prefix used to store whether the prefix must be printed; + * must point to a persistent integer initially set to 1 + */ +void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix); + +/** + * Format a line of log the same way as the default callback. + * @param line buffer to receive the formatted line; + * may be NULL if line_size is 0 + * @param line_size size of the buffer; at most line_size-1 characters will + * be written to the buffer, plus one null terminator + * @param print_prefix used to store whether the prefix must be printed; + * must point to a persistent integer initially set to 1 + * @return Returns a negative value if an error occurred, otherwise returns + * the number of characters that would have been written for a + * sufficiently large buffer, not including the terminating null + * character. If the return value is not less than line_size, it means + * that the log message was truncated to fit the buffer. + */ +int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix); + +/** + * Skip repeated messages, this requires the user app to use av_log() instead of + * (f)printf as the 2 would otherwise interfere and lead to + * "Last message repeated x times" messages below (f)printf messages with some + * bad luck. + * Also to receive the last, "last repeated" line if any, the user app must + * call av_log(NULL, AV_LOG_QUIET, "%s", ""); at the end + */ +#define AV_LOG_SKIP_REPEATED 1 + +/** + * Include the log severity in messages originating from codecs. + * + * Results in messages such as: + * [rawvideo @ 0xDEADBEEF] [error] encode did not produce valid pts + */ +#define AV_LOG_PRINT_LEVEL 2 + +void av_log_set_flags(int arg); +int av_log_get_flags(void); + +/** + * @} + */ + +#endif /* AVUTIL_LOG_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log2_tab.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log2_tab.c new file mode 100644 index 000000000..0dbf07d74 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/log2_tab.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2003-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +const uint8_t ff_log2_tab[256]={ + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 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, + 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, + 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, + 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 +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/macros.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/macros.h new file mode 100644 index 000000000..2007ee561 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/macros.h @@ -0,0 +1,50 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu + * Utility Preprocessor macros + */ + +#ifndef AVUTIL_MACROS_H +#define AVUTIL_MACROS_H + +/** + * @addtogroup preproc_misc Preprocessor String Macros + * + * String manipulation macros + * + * @{ + */ + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define AV_GLUE(a, b) a ## b +#define AV_JOIN(a, b) AV_GLUE(a, b) + +/** + * @} + */ + +#define AV_PRAGMA(s) _Pragma(#s) + +#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1)) + +#endif /* AVUTIL_MACROS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mastering_display_metadata.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mastering_display_metadata.c new file mode 100644 index 000000000..606934761 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mastering_display_metadata.c @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2016 Neil Birkbeck + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "mastering_display_metadata.h" +#include "mem.h" + +AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc(void) +{ + return av_mallocz(sizeof(AVMasteringDisplayMetadata)); +} + +AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, + sizeof(AVMasteringDisplayMetadata)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVMasteringDisplayMetadata)); + + return (AVMasteringDisplayMetadata *)side_data->data; +} + +AVContentLightMetadata *av_content_light_metadata_alloc(size_t *size) +{ + AVContentLightMetadata *metadata = av_mallocz(sizeof(AVContentLightMetadata)); + + if (size) + *size = sizeof(*metadata); + + return metadata; +} + +AVContentLightMetadata *av_content_light_metadata_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, + sizeof(AVContentLightMetadata)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVContentLightMetadata)); + + return (AVContentLightMetadata *)side_data->data; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mastering_display_metadata.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mastering_display_metadata.h new file mode 100644 index 000000000..c23b07c3c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mastering_display_metadata.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016 Neil Birkbeck + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MASTERING_DISPLAY_METADATA_H +#define AVUTIL_MASTERING_DISPLAY_METADATA_H + +#include "frame.h" +#include "rational.h" + + +/** + * Mastering display metadata capable of representing the color volume of + * the display used to master the content (SMPTE 2086:2014). + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with av_mastering_display_metadata_alloc() + * and its size is not a part of the public ABI. + */ +typedef struct AVMasteringDisplayMetadata { + /** + * CIE 1931 xy chromaticity coords of color primaries (r, g, b order). + */ + AVRational display_primaries[3][2]; + + /** + * CIE 1931 xy chromaticity coords of white point. + */ + AVRational white_point[2]; + + /** + * Min luminance of mastering display (cd/m^2). + */ + AVRational min_luminance; + + /** + * Max luminance of mastering display (cd/m^2). + */ + AVRational max_luminance; + + /** + * Flag indicating whether the display primaries (and white point) are set. + */ + int has_primaries; + + /** + * Flag indicating whether the luminance (min_ and max_) have been set. + */ + int has_luminance; + +} AVMasteringDisplayMetadata; + +/** + * Allocate an AVMasteringDisplayMetadata structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVMasteringDisplayMetadata filled with default values or NULL + * on failure. + */ +AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc(void); + +/** + * Allocate a complete AVMasteringDisplayMetadata and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVMasteringDisplayMetadata structure to be filled by caller. + */ +AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFrame *frame); + +/** + * Content light level needed by to transmit HDR over HDMI (CTA-861.3). + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with av_content_light_metadata_alloc() + * and its size is not a part of the public ABI. + */ +typedef struct AVContentLightMetadata { + /** + * Max content light level (cd/m^2). + */ + unsigned MaxCLL; + + /** + * Max average light level per frame (cd/m^2). + */ + unsigned MaxFALL; +} AVContentLightMetadata; + +/** + * Allocate an AVContentLightMetadata structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVContentLightMetadata filled with default values or NULL + * on failure. + */ +AVContentLightMetadata *av_content_light_metadata_alloc(size_t *size); + +/** + * Allocate a complete AVContentLightMetadata and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVContentLightMetadata structure to be filled by caller. + */ +AVContentLightMetadata *av_content_light_metadata_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_MASTERING_DISPLAY_METADATA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mathematics.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mathematics.c new file mode 100644 index 000000000..1bf044cdf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mathematics.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2005-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * miscellaneous math routines and tables + */ + +#include +#include + +#include "mathematics.h" +#include "libavutil/intmath.h" +#include "libavutil/common.h" +#include "avassert.h" +#include "version.h" + +/* Stein's binary GCD algorithm: + * https://en.wikipedia.org/wiki/Binary_GCD_algorithm */ +int64_t av_gcd(int64_t a, int64_t b) { + int za, zb, k; + int64_t u, v; + if (a == 0) + return b; + if (b == 0) + return a; + za = ff_ctzll(a); + zb = ff_ctzll(b); + k = FFMIN(za, zb); + u = llabs(a >> za); + v = llabs(b >> zb); + while (u != v) { + if (u > v) + FFSWAP(int64_t, v, u); + v -= u; + v >>= ff_ctzll(v); + } + return (uint64_t)u << k; +} + +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) +{ + int64_t r = 0; + av_assert2(c > 0); + av_assert2(b >=0); + av_assert2((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4); + + if (c <= 0 || b < 0 || !((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4)) + return INT64_MIN; + + if (rnd & AV_ROUND_PASS_MINMAX) { + if (a == INT64_MIN || a == INT64_MAX) + return a; + rnd -= AV_ROUND_PASS_MINMAX; + } + + if (a < 0) + return -(uint64_t)av_rescale_rnd(-FFMAX(a, -INT64_MAX), b, c, rnd ^ ((rnd >> 1) & 1)); + + if (rnd == AV_ROUND_NEAR_INF) + r = c / 2; + else if (rnd & 1) + r = c - 1; + + if (b <= INT_MAX && c <= INT_MAX) { + if (a <= INT_MAX) + return (a * b + r) / c; + else { + int64_t ad = a / c; + int64_t a2 = (a % c * b + r) / c; + if (ad >= INT32_MAX && b && ad > (INT64_MAX - a2) / b) + return INT64_MIN; + return ad * b + a2; + } + } else { +#if 1 + uint64_t a0 = a & 0xFFFFFFFF; + uint64_t a1 = a >> 32; + uint64_t b0 = b & 0xFFFFFFFF; + uint64_t b1 = b >> 32; + uint64_t t1 = a0 * b1 + a1 * b0; + uint64_t t1a = t1 << 32; + int i; + + a0 = a0 * b0 + t1a; + a1 = a1 * b1 + (t1 >> 32) + (a0 < t1a); + a0 += r; + a1 += a0 < r; + + for (i = 63; i >= 0; i--) { + a1 += a1 + ((a0 >> i) & 1); + t1 += t1; + if (c <= a1) { + a1 -= c; + t1++; + } + } + if (t1 > INT64_MAX) + return INT64_MIN; + return t1; +#else + /* reference code doing (a*b + r) / c, requires libavutil/integer.h */ + AVInteger ai; + ai = av_mul_i(av_int2i(a), av_int2i(b)); + ai = av_add_i(ai, av_int2i(r)); + + return av_i2int(av_div_i(ai, av_int2i(c))); +#endif + } +} + +int64_t av_rescale(int64_t a, int64_t b, int64_t c) +{ + return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); +} + +int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, + enum AVRounding rnd) +{ + int64_t b = bq.num * (int64_t)cq.den; + int64_t c = cq.num * (int64_t)bq.den; + return av_rescale_rnd(a, b, c, rnd); +} + +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) +{ + return av_rescale_q_rnd(a, bq, cq, AV_ROUND_NEAR_INF); +} + +int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b) +{ + int64_t a = tb_a.num * (int64_t)tb_b.den; + int64_t b = tb_b.num * (int64_t)tb_a.den; + if ((FFABS(ts_a)|a|FFABS(ts_b)|b) <= INT_MAX) + return (ts_a*a > ts_b*b) - (ts_a*a < ts_b*b); + if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b) + return -1; + if (av_rescale_rnd(ts_b, b, a, AV_ROUND_DOWN) < ts_a) + return 1; + return 0; +} + +int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod) +{ + int64_t c = (a - b) & (mod - 1); + if (c > (mod >> 1)) + c -= mod; + return c; +} + +int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb){ + int64_t a, b, this; + + av_assert0(in_ts != AV_NOPTS_VALUE); + av_assert0(duration >= 0); + + if (*last == AV_NOPTS_VALUE || !duration || in_tb.num*(int64_t)out_tb.den <= out_tb.num*(int64_t)in_tb.den) { +simple_round: + *last = av_rescale_q(in_ts, in_tb, fs_tb) + duration; + return av_rescale_q(in_ts, in_tb, out_tb); + } + + a = av_rescale_q_rnd(2*in_ts-1, in_tb, fs_tb, AV_ROUND_DOWN) >>1; + b = (av_rescale_q_rnd(2*in_ts+1, in_tb, fs_tb, AV_ROUND_UP )+1)>>1; + if (*last < 2*a - b || *last > 2*b - a) + goto simple_round; + + this = av_clip64(*last, a, b); + *last = this + duration; + + return av_rescale_q(this, fs_tb, out_tb); +} + +int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc) +{ + int64_t m, d; + + if (inc != 1) + inc_tb = av_mul_q(inc_tb, (AVRational) {inc, 1}); + + m = inc_tb.num * (int64_t)ts_tb.den; + d = inc_tb.den * (int64_t)ts_tb.num; + + if (m % d == 0) + return ts + m / d; + if (m < d) + return ts; + + { + int64_t old = av_rescale_q(ts, ts_tb, inc_tb); + int64_t old_ts = av_rescale_q(old, inc_tb, ts_tb); + return av_rescale_q(old + 1, inc_tb, ts_tb) + (ts - old_ts); + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mathematics.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mathematics.h new file mode 100644 index 000000000..54901800b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mathematics.h @@ -0,0 +1,242 @@ +/* + * copyright (c) 2005-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @addtogroup lavu_math + * Mathematical utilities for working with timestamp and time base. + */ + +#ifndef AVUTIL_MATHEMATICS_H +#define AVUTIL_MATHEMATICS_H + +#include +#include +#include "attributes.h" +#include "rational.h" +#include "intfloat.h" + +#ifndef M_E +#define M_E 2.7182818284590452354 /* e */ +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#endif +#ifndef M_LOG2_10 +#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */ +#endif +#ifndef M_PHI +#define M_PHI 1.61803398874989484820 /* phi / golden ratio */ +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#endif +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#endif +#ifndef NAN +#define NAN av_int2float(0x7fc00000) +#endif +#ifndef INFINITY +#define INFINITY av_int2float(0x7f800000) +#endif + +/** + * @addtogroup lavu_math + * + * @{ + */ + +/** + * Rounding methods. + */ +enum AVRounding { + AV_ROUND_ZERO = 0, ///< Round toward zero. + AV_ROUND_INF = 1, ///< Round away from zero. + AV_ROUND_DOWN = 2, ///< Round toward -infinity. + AV_ROUND_UP = 3, ///< Round toward +infinity. + AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. + /** + * Flag telling rescaling functions to pass `INT64_MIN`/`MAX` through + * unchanged, avoiding special cases for #AV_NOPTS_VALUE. + * + * Unlike other values of the enumeration AVRounding, this value is a + * bitmask that must be used in conjunction with another value of the + * enumeration through a bitwise OR, in order to set behavior for normal + * cases. + * + * @code{.c} + * av_rescale_rnd(3, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); + * // Rescaling 3: + * // Calculating 3 * 1 / 2 + * // 3 / 2 is rounded up to 2 + * // => 2 + * + * av_rescale_rnd(AV_NOPTS_VALUE, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); + * // Rescaling AV_NOPTS_VALUE: + * // AV_NOPTS_VALUE == INT64_MIN + * // AV_NOPTS_VALUE is passed through + * // => AV_NOPTS_VALUE + * @endcode + */ + AV_ROUND_PASS_MINMAX = 8192, +}; + +/** + * Compute the greatest common divisor of two integer operands. + * + * @param a,b Operands + * @return GCD of a and b up to sign; if a >= 0 and b >= 0, return value is >= 0; + * if a == 0 and b == 0, returns 0. + */ +int64_t av_const av_gcd(int64_t a, int64_t b); + +/** + * Rescale a 64-bit integer with rounding to nearest. + * + * The operation is mathematically equivalent to `a * b / c`, but writing that + * directly can overflow. + * + * This function is equivalent to av_rescale_rnd() with #AV_ROUND_NEAR_INF. + * + * @see av_rescale_rnd(), av_rescale_q(), av_rescale_q_rnd() + */ +int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; + +/** + * Rescale a 64-bit integer with specified rounding. + * + * The operation is mathematically equivalent to `a * b / c`, but writing that + * directly can overflow, and does not support different rounding methods. + * + * @see av_rescale(), av_rescale_q(), av_rescale_q_rnd() + */ +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) av_const; + +/** + * Rescale a 64-bit integer by 2 rational numbers. + * + * The operation is mathematically equivalent to `a * bq / cq`. + * + * This function is equivalent to av_rescale_q_rnd() with #AV_ROUND_NEAR_INF. + * + * @see av_rescale(), av_rescale_rnd(), av_rescale_q_rnd() + */ +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; + +/** + * Rescale a 64-bit integer by 2 rational numbers with specified rounding. + * + * The operation is mathematically equivalent to `a * bq / cq`. + * + * @see av_rescale(), av_rescale_rnd(), av_rescale_q() + */ +int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, + enum AVRounding rnd) av_const; + +/** + * Compare two timestamps each in its own time base. + * + * @return One of the following values: + * - -1 if `ts_a` is before `ts_b` + * - 1 if `ts_a` is after `ts_b` + * - 0 if they represent the same position + * + * @warning + * The result of the function is undefined if one of the timestamps is outside + * the `int64_t` range when represented in the other's timebase. + */ +int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); + +/** + * Compare the remainders of two integer operands divided by a common divisor. + * + * In other words, compare the least significant `log2(mod)` bits of integers + * `a` and `b`. + * + * @code{.c} + * av_compare_mod(0x11, 0x02, 0x10) < 0 // since 0x11 % 0x10 (0x1) < 0x02 % 0x10 (0x2) + * av_compare_mod(0x11, 0x02, 0x20) > 0 // since 0x11 % 0x20 (0x11) > 0x02 % 0x20 (0x02) + * @endcode + * + * @param a,b Operands + * @param mod Divisor; must be a power of 2 + * @return + * - a negative value if `a % mod < b % mod` + * - a positive value if `a % mod > b % mod` + * - zero if `a % mod == b % mod` + */ +int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod); + +/** + * Rescale a timestamp while preserving known durations. + * + * This function is designed to be called per audio packet to scale the input + * timestamp to a different time base. Compared to a simple av_rescale_q() + * call, this function is robust against possible inconsistent frame durations. + * + * The `last` parameter is a state variable that must be preserved for all + * subsequent calls for the same stream. For the first call, `*last` should be + * initialized to #AV_NOPTS_VALUE. + * + * @param[in] in_tb Input time base + * @param[in] in_ts Input timestamp + * @param[in] fs_tb Duration time base; typically this is finer-grained + * (greater) than `in_tb` and `out_tb` + * @param[in] duration Duration till the next call to this function (i.e. + * duration of the current packet/frame) + * @param[in,out] last Pointer to a timestamp expressed in terms of + * `fs_tb`, acting as a state variable + * @param[in] out_tb Output timebase + * @return Timestamp expressed in terms of `out_tb` + * + * @note In the context of this function, "duration" is in term of samples, not + * seconds. + */ +int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb); + +/** + * Add a value to a timestamp. + * + * This function guarantees that when the same value is repeatly added that + * no accumulation of rounding errors occurs. + * + * @param[in] ts Input timestamp + * @param[in] ts_tb Input timestamp time base + * @param[in] inc Value to be added + * @param[in] inc_tb Time base of `inc` + */ +int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc); + + +/** + * @} + */ + +#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.c new file mode 100644 index 000000000..31e69925a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2006 Michael Niedermayer (michaelni@gmx.at) + * Copyright (C) 2003-2005 by Christopher R. Hertel (crh@ubiqx.mn.org) + * + * References: + * IETF RFC 1321: The MD5 Message-Digest Algorithm + * Ron Rivest. IETF, April, 1992 + * + * based on http://ubiqx.org/libcifs/source/Auth/MD5.c + * from Christopher R. Hertel (crh@ubiqx.mn.org) + * Simplified, cleaned and IMO redundant comments removed by Michael. + * + * If you use gcc, then version 4.1 or later and -fomit-frame-pointer is + * strongly recommended. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "bswap.h" +#include "intreadwrite.h" +#include "mem.h" +#include "md5.h" + +typedef struct AVMD5 { + uint64_t len; + uint8_t block[64]; + uint32_t ABCD[4]; +} AVMD5; + +const int av_md5_size = sizeof(AVMD5); + +struct AVMD5 *av_md5_alloc(void) +{ + return av_mallocz(sizeof(struct AVMD5)); +} + +static const uint8_t S[4][4] = { + { 7, 12, 17, 22 }, /* round 1 */ + { 5, 9, 14, 20 }, /* round 2 */ + { 4, 11, 16, 23 }, /* round 3 */ + { 6, 10, 15, 21 } /* round 4 */ +}; + +static const uint32_t T[64] = { // T[i]= fabs(sin(i+1)<<32) + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* round 1 */ + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* round 2 */ + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* round 3 */ + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* round 4 */ + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, +}; + +#define CORE(i, a, b, c, d) \ + do { \ + t = S[i >> 4][i & 3]; \ + a += T[i]; \ + \ + if (i < 32) { \ + if (i < 16) \ + a += (d ^ (b & (c ^ d))) + AV_RL32(X+( i & 15));\ + else \ + a += ((d & b) | (~d & c)) + AV_RL32(X+((1 + 5*i) & 15));\ + } else { \ + if (i < 48) \ + a += (b ^ c ^ d) + AV_RL32(X+((5 + 3*i) & 15));\ + else \ + a += (c ^ (b | ~d)) + AV_RL32(X+(( 7*i) & 15));\ + } \ + a = b + (a << t | a >> (32 - t)); \ + } while (0) + +static void body(uint32_t ABCD[4], const uint8_t *src, int nblocks) +{ + int i av_unused; + int n; + const uint32_t *X; + uint32_t a, b, c, d, t; + + for (n = 0; n < nblocks; n++) { + a = ABCD[3]; + b = ABCD[2]; + c = ABCD[1]; + d = ABCD[0]; + + X = (const uint32_t *)src + n * 16; + +#if CONFIG_SMALL + for (i = 0; i < 64; i++) { + CORE(i, a, b, c, d); + t = d; + d = c; + c = b; + b = a; + a = t; + } +#else +#define CORE2(i) \ + CORE(i, a, b, c, d); CORE((i + 1), d, a, b, c); \ + CORE((i + 2), c, d, a, b); CORE((i + 3), b, c, d, a) +#define CORE4(i) CORE2(i); CORE2((i + 4)); CORE2((i + 8)); CORE2((i + 12)) + CORE4(0); + CORE4(16); + CORE4(32); + CORE4(48); +#endif + + ABCD[0] += d; + ABCD[1] += c; + ABCD[2] += b; + ABCD[3] += a; + } +} + +void av_md5_init(AVMD5 *ctx) +{ + ctx->len = 0; + + ctx->ABCD[0] = 0x10325476; + ctx->ABCD[1] = 0x98badcfe; + ctx->ABCD[2] = 0xefcdab89; + ctx->ABCD[3] = 0x67452301; +} + +#if FF_API_CRYPTO_SIZE_T +void av_md5_update(AVMD5 *ctx, const uint8_t *src, int len) +#else +void av_md5_update(AVMD5 *ctx, const uint8_t *src, size_t len) +#endif +{ + const uint8_t *end; + int j; + + j = ctx->len & 63; + ctx->len += len; + + if (j) { + int cnt = FFMIN(len, 64 - j); + memcpy(ctx->block + j, src, cnt); + src += cnt; + len -= cnt; + if (j + cnt < 64) + return; + body(ctx->ABCD, ctx->block, 1); + } + + end = src + (len & ~63); + if (!HAVE_FAST_UNALIGNED && ((intptr_t)src & 3)) { + while (src < end) { + memcpy(ctx->block, src, 64); + body(ctx->ABCD, ctx->block, 1); + src += 64; + } + } else { + int nblocks = len / 64; + body(ctx->ABCD, src, nblocks); + src = end; + } + len &= 63; + if (len > 0) + memcpy(ctx->block, src, len); +} + +void av_md5_final(AVMD5 *ctx, uint8_t *dst) +{ + int i; + uint64_t finalcount = av_le2ne64(ctx->len << 3); + + av_md5_update(ctx, "\200", 1); + while ((ctx->len & 63) != 56) + av_md5_update(ctx, "", 1); + + av_md5_update(ctx, (uint8_t *) &finalcount, 8); + + for (i = 0; i < 4; i++) + AV_WL32(dst + 4 * i, ctx->ABCD[3 - i]); +} + +#if FF_API_CRYPTO_SIZE_T +void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len) +#else +void av_md5_sum(uint8_t *dst, const uint8_t *src, size_t len) +#endif +{ + AVMD5 ctx; + + av_md5_init(&ctx); + av_md5_update(&ctx, src, len); + av_md5_final(&ctx, dst); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.h new file mode 100644 index 000000000..ca72ccbf8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/md5.h @@ -0,0 +1,98 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_md5 + * Public header for MD5 hash function implementation. + */ + +#ifndef AVUTIL_MD5_H +#define AVUTIL_MD5_H + +#include +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_md5 MD5 + * @ingroup lavu_hash + * MD5 hash function implementation. + * + * @{ + */ + +extern const int av_md5_size; + +struct AVMD5; + +/** + * Allocate an AVMD5 context. + */ +struct AVMD5 *av_md5_alloc(void); + +/** + * Initialize MD5 hashing. + * + * @param ctx pointer to the function context (of size av_md5_size) + */ +void av_md5_init(struct AVMD5 *ctx); + +/** + * Update hash value. + * + * @param ctx hash function context + * @param src input data to update hash with + * @param len input data length + */ +#if FF_API_CRYPTO_SIZE_T +void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, int len); +#else +void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param ctx hash function context + * @param dst buffer where output digest value is stored + */ +void av_md5_final(struct AVMD5 *ctx, uint8_t *dst); + +/** + * Hash an array of data. + * + * @param dst The output buffer to write the digest into + * @param src The data to hash + * @param len The length of the data, in bytes + */ +#if FF_API_CRYPTO_SIZE_T +void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len); +#else +void av_md5_sum(uint8_t *dst, const uint8_t *src, size_t len); +#endif + +/** + * @} + */ + +#endif /* AVUTIL_MD5_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.c new file mode 100644 index 000000000..88fe09b17 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.c @@ -0,0 +1,508 @@ +/* + * default memory allocator for libavutil + * Copyright (c) 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * default memory allocator for libavutil + */ + +#define _XOPEN_SOURCE 600 + +#include "config.h" + +#include +#include +#include +#include +#if HAVE_MALLOC_H +#include +#endif + +#include "avassert.h" +#include "avutil.h" +#include "common.h" +#include "dynarray.h" +#include "intreadwrite.h" +#include "mem.h" + +#ifdef MALLOC_PREFIX + +#define malloc AV_JOIN(MALLOC_PREFIX, malloc) +#define memalign AV_JOIN(MALLOC_PREFIX, memalign) +#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign) +#define realloc AV_JOIN(MALLOC_PREFIX, realloc) +#define free AV_JOIN(MALLOC_PREFIX, free) + +void *malloc(size_t size); +void *memalign(size_t align, size_t size); +int posix_memalign(void **ptr, size_t align, size_t size); +void *realloc(void *ptr, size_t size); +void free(void *ptr); + +#endif /* MALLOC_PREFIX */ + +#include "mem_internal.h" + +#define ALIGN (HAVE_AVX512 ? 64 : (HAVE_AVX ? 32 : 16)) + +/* NOTE: if you want to override these functions with your own + * implementations (not recommended) you have to link libav* as + * dynamic libraries and remove -Wl,-Bsymbolic from the linker flags. + * Note that this will cost performance. */ + +static size_t max_alloc_size= INT_MAX; + +void av_max_alloc(size_t max){ + max_alloc_size = max; +} + +void *av_malloc(size_t size) +{ + void *ptr = NULL; + + /* let's disallow possibly ambiguous cases */ + if (size > (max_alloc_size - 32)) + return NULL; + +#if HAVE_POSIX_MEMALIGN + if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation + if (posix_memalign(&ptr, ALIGN, size)) + ptr = NULL; +#elif HAVE_ALIGNED_MALLOC + ptr = _aligned_malloc(size, ALIGN); +#elif HAVE_MEMALIGN +#ifndef __DJGPP__ + ptr = memalign(ALIGN, size); +#else + ptr = memalign(size, ALIGN); +#endif + /* Why 64? + * Indeed, we should align it: + * on 4 for 386 + * on 16 for 486 + * on 32 for 586, PPro - K6-III + * on 64 for K7 (maybe for P3 too). + * Because L1 and L2 caches are aligned on those values. + * But I don't want to code such logic here! + */ + /* Why 32? + * For AVX ASM. SSE / NEON needs only 16. + * Why not larger? Because I did not see a difference in benchmarks ... + */ + /* benchmarks with P3 + * memalign(64) + 1 3071, 3051, 3032 + * memalign(64) + 2 3051, 3032, 3041 + * memalign(64) + 4 2911, 2896, 2915 + * memalign(64) + 8 2545, 2554, 2550 + * memalign(64) + 16 2543, 2572, 2563 + * memalign(64) + 32 2546, 2545, 2571 + * memalign(64) + 64 2570, 2533, 2558 + * + * BTW, malloc seems to do 8-byte alignment by default here. + */ +#else + ptr = malloc(size); +#endif + if(!ptr && !size) { + size = 1; + ptr= av_malloc(1); + } +#if CONFIG_MEMORY_POISONING + if (ptr) + memset(ptr, FF_MEMORY_POISON, size); +#endif + return ptr; +} + +void *av_realloc(void *ptr, size_t size) +{ + /* let's disallow possibly ambiguous cases */ + if (size > (max_alloc_size - 32)) + return NULL; + +#if HAVE_ALIGNED_MALLOC + return _aligned_realloc(ptr, size + !size, ALIGN); +#else + return realloc(ptr, size + !size); +#endif +} + +void *av_realloc_f(void *ptr, size_t nelem, size_t elsize) +{ + size_t size; + void *r; + + if (av_size_mult(elsize, nelem, &size)) { + av_free(ptr); + return NULL; + } + r = av_realloc(ptr, size); + if (!r) + av_free(ptr); + return r; +} + +int av_reallocp(void *ptr, size_t size) +{ + void *val; + + if (!size) { + av_freep(ptr); + return 0; + } + + memcpy(&val, ptr, sizeof(val)); + val = av_realloc(val, size); + + if (!val) { + av_freep(ptr); + return AVERROR(ENOMEM); + } + + memcpy(ptr, &val, sizeof(val)); + return 0; +} + +void *av_malloc_array(size_t nmemb, size_t size) +{ + if (!size || nmemb >= INT_MAX / size) + return NULL; + return av_malloc(nmemb * size); +} + +void *av_mallocz_array(size_t nmemb, size_t size) +{ + if (!size || nmemb >= INT_MAX / size) + return NULL; + return av_mallocz(nmemb * size); +} + +void *av_realloc_array(void *ptr, size_t nmemb, size_t size) +{ + if (!size || nmemb >= INT_MAX / size) + return NULL; + return av_realloc(ptr, nmemb * size); +} + +int av_reallocp_array(void *ptr, size_t nmemb, size_t size) +{ + void *val; + + memcpy(&val, ptr, sizeof(val)); + val = av_realloc_f(val, nmemb, size); + memcpy(ptr, &val, sizeof(val)); + if (!val && nmemb && size) + return AVERROR(ENOMEM); + + return 0; +} + +void av_free(void *ptr) +{ +#if HAVE_ALIGNED_MALLOC + _aligned_free(ptr); +#else + free(ptr); +#endif +} + +void av_freep(void *arg) +{ + void *val; + + memcpy(&val, arg, sizeof(val)); + memcpy(arg, &(void *){ NULL }, sizeof(val)); + av_free(val); +} + +void *av_mallocz(size_t size) +{ + void *ptr = av_malloc(size); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +void *av_calloc(size_t nmemb, size_t size) +{ + if (size <= 0 || nmemb >= INT_MAX / size) + return NULL; + return av_mallocz(nmemb * size); +} + +char *av_strdup(const char *s) +{ + char *ptr = NULL; + if (s) { + size_t len = strlen(s) + 1; + ptr = av_realloc(NULL, len); + if (ptr) + memcpy(ptr, s, len); + } + return ptr; +} + +char *av_strndup(const char *s, size_t len) +{ + char *ret = NULL, *end; + + if (!s) + return NULL; + + end = memchr(s, 0, len); + if (end) + len = end - s; + + ret = av_realloc(NULL, len + 1); + if (!ret) + return NULL; + + memcpy(ret, s, len); + ret[len] = 0; + return ret; +} + +void *av_memdup(const void *p, size_t size) +{ + void *ptr = NULL; + if (p) { + ptr = av_malloc(size); + if (ptr) + memcpy(ptr, p, size); + } + return ptr; +} + +int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem) +{ + void **tab; + memcpy(&tab, tab_ptr, sizeof(tab)); + + FF_DYNARRAY_ADD(INT_MAX, sizeof(*tab), tab, *nb_ptr, { + tab[*nb_ptr] = elem; + memcpy(tab_ptr, &tab, sizeof(tab)); + }, { + return AVERROR(ENOMEM); + }); + return 0; +} + +void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem) +{ + void **tab; + memcpy(&tab, tab_ptr, sizeof(tab)); + + FF_DYNARRAY_ADD(INT_MAX, sizeof(*tab), tab, *nb_ptr, { + tab[*nb_ptr] = elem; + memcpy(tab_ptr, &tab, sizeof(tab)); + }, { + *nb_ptr = 0; + av_freep(tab_ptr); + }); +} + +void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, + const uint8_t *elem_data) +{ + uint8_t *tab_elem_data = NULL; + + FF_DYNARRAY_ADD(INT_MAX, elem_size, *tab_ptr, *nb_ptr, { + tab_elem_data = (uint8_t *)*tab_ptr + (*nb_ptr) * elem_size; + if (elem_data) + memcpy(tab_elem_data, elem_data, elem_size); + else if (CONFIG_MEMORY_POISONING) + memset(tab_elem_data, FF_MEMORY_POISON, elem_size); + }, { + av_freep(tab_ptr); + *nb_ptr = 0; + }); + return tab_elem_data; +} + +static void fill16(uint8_t *dst, int len) +{ + uint32_t v = AV_RN16(dst - 2); + + v |= v << 16; + + while (len >= 4) { + AV_WN32(dst, v); + dst += 4; + len -= 4; + } + + while (len--) { + *dst = dst[-2]; + dst++; + } +} + +static void fill24(uint8_t *dst, int len) +{ +#if HAVE_BIGENDIAN + uint32_t v = AV_RB24(dst - 3); + uint32_t a = v << 8 | v >> 16; + uint32_t b = v << 16 | v >> 8; + uint32_t c = v << 24 | v; +#else + uint32_t v = AV_RL24(dst - 3); + uint32_t a = v | v << 24; + uint32_t b = v >> 8 | v << 16; + uint32_t c = v >> 16 | v << 8; +#endif + + while (len >= 12) { + AV_WN32(dst, a); + AV_WN32(dst + 4, b); + AV_WN32(dst + 8, c); + dst += 12; + len -= 12; + } + + if (len >= 4) { + AV_WN32(dst, a); + dst += 4; + len -= 4; + } + + if (len >= 4) { + AV_WN32(dst, b); + dst += 4; + len -= 4; + } + + while (len--) { + *dst = dst[-3]; + dst++; + } +} + +static void fill32(uint8_t *dst, int len) +{ + uint32_t v = AV_RN32(dst - 4); + +#if HAVE_FAST_64BIT + uint64_t v2= v + ((uint64_t)v<<32); + while (len >= 32) { + AV_WN64(dst , v2); + AV_WN64(dst+ 8, v2); + AV_WN64(dst+16, v2); + AV_WN64(dst+24, v2); + dst += 32; + len -= 32; + } +#endif + + while (len >= 4) { + AV_WN32(dst, v); + dst += 4; + len -= 4; + } + + while (len--) { + *dst = dst[-4]; + dst++; + } +} + +void av_memcpy_backptr(uint8_t *dst, int back, int cnt) +{ + const uint8_t *src = &dst[-back]; + if (!back) + return; + + if (back == 1) { + memset(dst, *src, cnt); + } else if (back == 2) { + fill16(dst, cnt); + } else if (back == 3) { + fill24(dst, cnt); + } else if (back == 4) { + fill32(dst, cnt); + } else { + if (cnt >= 16) { + int blocklen = back; + while (cnt > blocklen) { + memcpy(dst, src, blocklen); + dst += blocklen; + cnt -= blocklen; + blocklen <<= 1; + } + memcpy(dst, src, cnt); + return; + } + if (cnt >= 8) { + AV_COPY32U(dst, src); + AV_COPY32U(dst + 4, src + 4); + src += 8; + dst += 8; + cnt -= 8; + } + if (cnt >= 4) { + AV_COPY32U(dst, src); + src += 4; + dst += 4; + cnt -= 4; + } + if (cnt >= 2) { + AV_COPY16U(dst, src); + src += 2; + dst += 2; + cnt -= 2; + } + if (cnt) + *dst = *src; + } +} + +void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) +{ + if (min_size <= *size) + return ptr; + + if (min_size > max_alloc_size - 32) { + *size = 0; + return NULL; + } + + min_size = FFMIN(max_alloc_size - 32, FFMAX(min_size + min_size / 16 + 32, min_size)); + + ptr = av_realloc(ptr, min_size); + /* we could set this to the unmodified min_size but this is safer + * if the user lost the ptr and uses NULL now + */ + if (!ptr) + min_size = 0; + + *size = min_size; + + return ptr; +} + +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) +{ + ff_fast_malloc(ptr, size, min_size, 0); +} + +void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size) +{ + ff_fast_malloc(ptr, size, min_size, 1); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.h new file mode 100644 index 000000000..5fb1a02dd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem.h @@ -0,0 +1,700 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_mem + * Memory handling functions + */ + +#ifndef AVUTIL_MEM_H +#define AVUTIL_MEM_H + +#include +#include + +#include "attributes.h" +#include "error.h" +#include "avutil.h" + +/** + * @addtogroup lavu_mem + * Utilities for manipulating memory. + * + * FFmpeg has several applications of memory that are not required of a typical + * program. For example, the computing-heavy components like video decoding and + * encoding can be sped up significantly through the use of aligned memory. + * + * However, for each of FFmpeg's applications of memory, there might not be a + * recognized or standardized API for that specific use. Memory alignment, for + * instance, varies wildly depending on operating systems, architectures, and + * compilers. Hence, this component of @ref libavutil is created to make + * dealing with memory consistently possible on all platforms. + * + * @{ + * + * @defgroup lavu_mem_macros Alignment Macros + * Helper macros for declaring aligned variables. + * @{ + */ + +/** + * @def DECLARE_ALIGNED(n,t,v) + * Declare a variable that is aligned in memory. + * + * @code{.c} + * DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42; + * DECLARE_ALIGNED(32, uint8_t, aligned_array)[128]; + * + * // The default-alignment equivalent would be + * uint16_t aligned_int = 42; + * uint8_t aligned_array[128]; + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_ALIGNED(n,t,v) + * Declare an aligned variable appropriate for use in inline assembly code. + * + * @code{.c} + * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_CONST(n,t,v) + * Declare a static constant aligned variable appropriate for use in inline + * assembly code. + * + * @code{.c} + * DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__DJGPP__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v +#elif defined(__GNUC__) || defined(__clang__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif + +/** + * @} + */ + +/** + * @defgroup lavu_mem_attrs Function Attributes + * Function attributes applicable to memory handling functions. + * + * These function attributes can help compilers emit more useful warnings, or + * generate better code. + * @{ + */ + +/** + * @def av_malloc_attrib + * Function attribute denoting a malloc-like function. + * + * @see
      Function attribute `malloc` in GCC's documentation + */ + +#if AV_GCC_VERSION_AT_LEAST(3,1) + #define av_malloc_attrib __attribute__((__malloc__)) +#else + #define av_malloc_attrib +#endif + +/** + * @def av_alloc_size(...) + * Function attribute used on a function that allocates memory, whose size is + * given by the specified parameter(s). + * + * @code{.c} + * void *av_malloc(size_t size) av_alloc_size(1); + * void *av_calloc(size_t nmemb, size_t size) av_alloc_size(1, 2); + * @endcode + * + * @param ... One or two parameter indexes, separated by a comma + * + * @see Function attribute `alloc_size` in GCC's documentation + */ + +#if AV_GCC_VERSION_AT_LEAST(4,3) + #define av_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__))) +#else + #define av_alloc_size(...) +#endif + +/** + * @} + */ + +/** + * @defgroup lavu_mem_funcs Heap Management + * Functions responsible for allocating, freeing, and copying memory. + * + * All memory allocation functions have a built-in upper limit of `INT_MAX` + * bytes. This may be changed with av_max_alloc(), although exercise extreme + * caution when doing so. + * + * @{ + */ + +/** + * Allocate a memory block with alignment suitable for all memory accesses + * (including vectors if available on the CPU). + * + * @param size Size in bytes for the memory block to be allocated + * @return Pointer to the allocated block, or `NULL` if the block cannot + * be allocated + * @see av_mallocz() + */ +void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocate a memory block with alignment suitable for all memory accesses + * (including vectors if available on the CPU) and zero all the bytes of the + * block. + * + * @param size Size in bytes for the memory block to be allocated + * @return Pointer to the allocated block, or `NULL` if it cannot be allocated + * @see av_malloc() + */ +void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocate a memory block for an array with av_malloc(). + * + * The allocated memory will have size `size * nmemb` bytes. + * + * @param nmemb Number of element + * @param size Size of a single element + * @return Pointer to the allocated block, or `NULL` if the block cannot + * be allocated + * @see av_malloc() + */ +av_alloc_size(1, 2) void *av_malloc_array(size_t nmemb, size_t size); + +/** + * Allocate a memory block for an array with av_mallocz(). + * + * The allocated memory will have size `size * nmemb` bytes. + * + * @param nmemb Number of elements + * @param size Size of the single element + * @return Pointer to the allocated block, or `NULL` if the block cannot + * be allocated + * + * @see av_mallocz() + * @see av_malloc_array() + */ +av_alloc_size(1, 2) void *av_mallocz_array(size_t nmemb, size_t size); + +/** + * Non-inlined equivalent of av_mallocz_array(). + * + * Created for symmetry with the calloc() C function. + */ +void *av_calloc(size_t nmemb, size_t size) av_malloc_attrib; + +/** + * Allocate, reallocate, or free a block of memory. + * + * If `ptr` is `NULL` and `size` > 0, allocate a new block. If `size` is + * zero, free the memory block pointed to by `ptr`. Otherwise, expand or + * shrink that block of memory according to `size`. + * + * @param ptr Pointer to a memory block already allocated with + * av_realloc() or `NULL` + * @param size Size in bytes of the memory block to be allocated or + * reallocated + * + * @return Pointer to a newly-reallocated block or `NULL` if the block + * cannot be reallocated or the function is used to free the memory block + * + * @warning Unlike av_malloc(), the returned pointer is not guaranteed to be + * correctly aligned. + * @see av_fast_realloc() + * @see av_reallocp() + */ +void *av_realloc(void *ptr, size_t size) av_alloc_size(2); + +/** + * Allocate, reallocate, or free a block of memory through a pointer to a + * pointer. + * + * If `*ptr` is `NULL` and `size` > 0, allocate a new block. If `size` is + * zero, free the memory block pointed to by `*ptr`. Otherwise, expand or + * shrink that block of memory according to `size`. + * + * @param[in,out] ptr Pointer to a pointer to a memory block already allocated + * with av_realloc(), or a pointer to `NULL`. The pointer + * is updated on success, or freed on failure. + * @param[in] size Size in bytes for the memory block to be allocated or + * reallocated + * + * @return Zero on success, an AVERROR error code on failure + * + * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be + * correctly aligned. + */ +av_warn_unused_result +int av_reallocp(void *ptr, size_t size); + +/** + * Allocate, reallocate, or free a block of memory. + * + * This function does the same thing as av_realloc(), except: + * - It takes two size arguments and allocates `nelem * elsize` bytes, + * after checking the result of the multiplication for integer overflow. + * - It frees the input block in case of failure, thus avoiding the memory + * leak with the classic + * @code{.c} + * buf = realloc(buf); + * if (!buf) + * return -1; + * @endcode + * pattern. + */ +void *av_realloc_f(void *ptr, size_t nelem, size_t elsize); + +/** + * Allocate, reallocate, or free an array. + * + * If `ptr` is `NULL` and `nmemb` > 0, allocate a new block. If + * `nmemb` is zero, free the memory block pointed to by `ptr`. + * + * @param ptr Pointer to a memory block already allocated with + * av_realloc() or `NULL` + * @param nmemb Number of elements in the array + * @param size Size of the single element of the array + * + * @return Pointer to a newly-reallocated block or NULL if the block + * cannot be reallocated or the function is used to free the memory block + * + * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be + * correctly aligned. + * @see av_reallocp_array() + */ +av_alloc_size(2, 3) void *av_realloc_array(void *ptr, size_t nmemb, size_t size); + +/** + * Allocate, reallocate, or free an array through a pointer to a pointer. + * + * If `*ptr` is `NULL` and `nmemb` > 0, allocate a new block. If `nmemb` is + * zero, free the memory block pointed to by `*ptr`. + * + * @param[in,out] ptr Pointer to a pointer to a memory block already + * allocated with av_realloc(), or a pointer to `NULL`. + * The pointer is updated on success, or freed on failure. + * @param[in] nmemb Number of elements + * @param[in] size Size of the single element + * + * @return Zero on success, an AVERROR error code on failure + * + * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be + * correctly aligned. + */ +int av_reallocp_array(void *ptr, size_t nmemb, size_t size); + +/** + * Reallocate the given buffer if it is not large enough, otherwise do nothing. + * + * If the given buffer is `NULL`, then a new uninitialized buffer is allocated. + * + * If the given buffer is not large enough, and reallocation fails, `NULL` is + * returned and `*size` is set to 0, but the original buffer is not changed or + * freed. + * + * A typical use pattern follows: + * + * @code{.c} + * uint8_t *buf = ...; + * uint8_t *new_buf = av_fast_realloc(buf, ¤t_size, size_needed); + * if (!new_buf) { + * // Allocation failed; clean up original buffer + * av_freep(&buf); + * return AVERROR(ENOMEM); + * } + * @endcode + * + * @param[in,out] ptr Already allocated buffer, or `NULL` + * @param[in,out] size Pointer to the size of buffer `ptr`. `*size` is + * updated to the new allocated size, in particular 0 + * in case of failure. + * @param[in] min_size Desired minimal size of buffer `ptr` + * @return `ptr` if the buffer is large enough, a pointer to newly reallocated + * buffer if the buffer was not large enough, or `NULL` in case of + * error + * @see av_realloc() + * @see av_fast_malloc() + */ +void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); + +/** + * Allocate a buffer, reusing the given one if large enough. + * + * Contrary to av_fast_realloc(), the current buffer contents might not be + * preserved and on error the old buffer is freed, thus no special handling to + * avoid memleaks is necessary. + * + * `*ptr` is allowed to be `NULL`, in which case allocation always happens if + * `size_needed` is greater than 0. + * + * @code{.c} + * uint8_t *buf = ...; + * av_fast_malloc(&buf, ¤t_size, size_needed); + * if (!buf) { + * // Allocation failed; buf already freed + * return AVERROR(ENOMEM); + * } + * @endcode + * + * @param[in,out] ptr Pointer to pointer to an already allocated buffer. + * `*ptr` will be overwritten with pointer to new + * buffer on success or `NULL` on failure + * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is + * updated to the new allocated size, in particular 0 + * in case of failure. + * @param[in] min_size Desired minimal size of buffer `*ptr` + * @see av_realloc() + * @see av_fast_mallocz() + */ +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size); + +/** + * Allocate and clear a buffer, reusing the given one if large enough. + * + * Like av_fast_malloc(), but all newly allocated space is initially cleared. + * Reused buffer is not cleared. + * + * `*ptr` is allowed to be `NULL`, in which case allocation always happens if + * `size_needed` is greater than 0. + * + * @param[in,out] ptr Pointer to pointer to an already allocated buffer. + * `*ptr` will be overwritten with pointer to new + * buffer on success or `NULL` on failure + * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is + * updated to the new allocated size, in particular 0 + * in case of failure. + * @param[in] min_size Desired minimal size of buffer `*ptr` + * @see av_fast_malloc() + */ +void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size); + +/** + * Free a memory block which has been allocated with a function of av_malloc() + * or av_realloc() family. + * + * @param ptr Pointer to the memory block which should be freed. + * + * @note `ptr = NULL` is explicitly allowed. + * @note It is recommended that you use av_freep() instead, to prevent leaving + * behind dangling pointers. + * @see av_freep() + */ +void av_free(void *ptr); + +/** + * Free a memory block which has been allocated with a function of av_malloc() + * or av_realloc() family, and set the pointer pointing to it to `NULL`. + * + * @code{.c} + * uint8_t *buf = av_malloc(16); + * av_free(buf); + * // buf now contains a dangling pointer to freed memory, and accidental + * // dereference of buf will result in a use-after-free, which may be a + * // security risk. + * + * uint8_t *buf = av_malloc(16); + * av_freep(&buf); + * // buf is now NULL, and accidental dereference will only result in a + * // NULL-pointer dereference. + * @endcode + * + * @param ptr Pointer to the pointer to the memory block which should be freed + * @note `*ptr = NULL` is safe and leads to no action. + * @see av_free() + */ +void av_freep(void *ptr); + +/** + * Duplicate a string. + * + * @param s String to be duplicated + * @return Pointer to a newly-allocated string containing a + * copy of `s` or `NULL` if the string cannot be allocated + * @see av_strndup() + */ +char *av_strdup(const char *s) av_malloc_attrib; + +/** + * Duplicate a substring of a string. + * + * @param s String to be duplicated + * @param len Maximum length of the resulting string (not counting the + * terminating byte) + * @return Pointer to a newly-allocated string containing a + * substring of `s` or `NULL` if the string cannot be allocated + */ +char *av_strndup(const char *s, size_t len) av_malloc_attrib; + +/** + * Duplicate a buffer with av_malloc(). + * + * @param p Buffer to be duplicated + * @param size Size in bytes of the buffer copied + * @return Pointer to a newly allocated buffer containing a + * copy of `p` or `NULL` if the buffer cannot be allocated + */ +void *av_memdup(const void *p, size_t size); + +/** + * Overlapping memcpy() implementation. + * + * @param dst Destination buffer + * @param back Number of bytes back to start copying (i.e. the initial size of + * the overlapping window); must be > 0 + * @param cnt Number of bytes to copy; must be >= 0 + * + * @note `cnt > back` is valid, this will copy the bytes we just copied, + * thus creating a repeating pattern with a period length of `back`. + */ +void av_memcpy_backptr(uint8_t *dst, int back, int cnt); + +/** + * @} + */ + +/** + * @defgroup lavu_mem_dynarray Dynamic Array + * + * Utilities to make an array grow when needed. + * + * Sometimes, the programmer would want to have an array that can grow when + * needed. The libavutil dynamic array utilities fill that need. + * + * libavutil supports two systems of appending elements onto a dynamically + * allocated array, the first one storing the pointer to the value in the + * array, and the second storing the value directly. In both systems, the + * caller is responsible for maintaining a variable containing the length of + * the array, as well as freeing of the array after use. + * + * The first system stores pointers to values in a block of dynamically + * allocated memory. Since only pointers are stored, the function does not need + * to know the size of the type. Both av_dynarray_add() and + * av_dynarray_add_nofree() implement this system. + * + * @code + * type **array = NULL; //< an array of pointers to values + * int nb = 0; //< a variable to keep track of the length of the array + * + * type to_be_added = ...; + * type to_be_added2 = ...; + * + * av_dynarray_add(&array, &nb, &to_be_added); + * if (nb == 0) + * return AVERROR(ENOMEM); + * + * av_dynarray_add(&array, &nb, &to_be_added2); + * if (nb == 0) + * return AVERROR(ENOMEM); + * + * // Now: + * // nb == 2 + * // &to_be_added == array[0] + * // &to_be_added2 == array[1] + * + * av_freep(&array); + * @endcode + * + * The second system stores the value directly in a block of memory. As a + * result, the function has to know the size of the type. av_dynarray2_add() + * implements this mechanism. + * + * @code + * type *array = NULL; //< an array of values + * int nb = 0; //< a variable to keep track of the length of the array + * + * type to_be_added = ...; + * type to_be_added2 = ...; + * + * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), NULL); + * if (!addr) + * return AVERROR(ENOMEM); + * memcpy(addr, &to_be_added, sizeof(to_be_added)); + * + * // Shortcut of the above. + * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), + * (const void *)&to_be_added2); + * if (!addr) + * return AVERROR(ENOMEM); + * + * // Now: + * // nb == 2 + * // to_be_added == array[0] + * // to_be_added2 == array[1] + * + * av_freep(&array); + * @endcode + * + * @{ + */ + +/** + * Add the pointer to an element to a dynamic array. + * + * The array to grow is supposed to be an array of pointers to + * structures, and the element to add must be a pointer to an already + * allocated structure. + * + * The array is reallocated when its size reaches powers of 2. + * Therefore, the amortized cost of adding an element is constant. + * + * In case of success, the pointer to the array is updated in order to + * point to the new grown array, and the number pointed to by `nb_ptr` + * is incremented. + * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and + * `*nb_ptr` is set to 0. + * + * @param[in,out] tab_ptr Pointer to the array to grow + * @param[in,out] nb_ptr Pointer to the number of elements in the array + * @param[in] elem Element to add + * @see av_dynarray_add_nofree(), av_dynarray2_add() + */ +void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem); + +/** + * Add an element to a dynamic array. + * + * Function has the same functionality as av_dynarray_add(), + * but it doesn't free memory on fails. It returns error code + * instead and leave current buffer untouched. + * + * @return >=0 on success, negative otherwise + * @see av_dynarray_add(), av_dynarray2_add() + */ +av_warn_unused_result +int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem); + +/** + * Add an element of size `elem_size` to a dynamic array. + * + * The array is reallocated when its number of elements reaches powers of 2. + * Therefore, the amortized cost of adding an element is constant. + * + * In case of success, the pointer to the array is updated in order to + * point to the new grown array, and the number pointed to by `nb_ptr` + * is incremented. + * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and + * `*nb_ptr` is set to 0. + * + * @param[in,out] tab_ptr Pointer to the array to grow + * @param[in,out] nb_ptr Pointer to the number of elements in the array + * @param[in] elem_size Size in bytes of an element in the array + * @param[in] elem_data Pointer to the data of the element to add. If + * `NULL`, the space of the newly added element is + * allocated but left uninitialized. + * + * @return Pointer to the data of the element to copy in the newly allocated + * space + * @see av_dynarray_add(), av_dynarray_add_nofree() + */ +void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, + const uint8_t *elem_data); + +/** + * @} + */ + +/** + * @defgroup lavu_mem_misc Miscellaneous Functions + * + * Other functions related to memory allocation. + * + * @{ + */ + +/** + * Multiply two `size_t` values checking for overflow. + * + * @param[in] a,b Operands of multiplication + * @param[out] r Pointer to the result of the operation + * @return 0 on success, AVERROR(EINVAL) on overflow + */ +static inline int av_size_mult(size_t a, size_t b, size_t *r) +{ + size_t t = a * b; + /* Hack inspired from glibc: don't try the division if nelem and elsize + * are both less than sqrt(SIZE_MAX). */ + if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b) + return AVERROR(EINVAL); + *r = t; + return 0; +} + +/** + * Set the maximum size that may be allocated in one block. + * + * The value specified with this function is effective for all libavutil's @ref + * lavu_mem_funcs "heap management functions." + * + * By default, the max value is defined as `INT_MAX`. + * + * @param max Value to be set as the new maximum size + * + * @warning Exercise extreme caution when using this function. Don't touch + * this if you do not understand the full consequence of doing so. + */ +void av_max_alloc(size_t max); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_MEM_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem_internal.h new file mode 100644 index 000000000..6fdbcb016 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/mem_internal.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MEM_INTERNAL_H +#define AVUTIL_MEM_INTERNAL_H + +#include "avassert.h" +#include "mem.h" + +static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc) +{ + void *val; + + memcpy(&val, ptr, sizeof(val)); + if (min_size <= *size) { + av_assert0(val || !min_size); + return 0; + } + min_size = FFMAX(min_size + min_size / 16 + 32, min_size); + av_freep(ptr); + val = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size); + memcpy(ptr, &val, sizeof(val)); + if (!val) + min_size = 0; + *size = min_size; + return 1; +} +#endif /* AVUTIL_MEM_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/motion_vector.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/motion_vector.h new file mode 100644 index 000000000..ec2955638 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/motion_vector.h @@ -0,0 +1,57 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MOTION_VECTOR_H +#define AVUTIL_MOTION_VECTOR_H + +#include + +typedef struct AVMotionVector { + /** + * Where the current macroblock comes from; negative value when it comes + * from the past, positive value when it comes from the future. + * XXX: set exact relative ref frame reference instead of a +/- 1 "direction". + */ + int32_t source; + /** + * Width and height of the block. + */ + uint8_t w, h; + /** + * Absolute source position. Can be outside the frame area. + */ + int16_t src_x, src_y; + /** + * Absolute destination position. Can be outside the frame area. + */ + int16_t dst_x, dst_y; + /** + * Extra flag information. + * Currently unused. + */ + uint64_t flags; + /** + * Motion vector + * src_x = dst_x + motion_x / motion_scale + * src_y = dst_y + motion_y / motion_scale + */ + int32_t motion_x, motion_y; + uint16_t motion_scale; +} AVMotionVector; + +#endif /* AVUTIL_MOTION_VECTOR_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/murmur3.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/murmur3.c new file mode 100644 index 000000000..796175251 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/murmur3.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include "mem.h" +#include "intreadwrite.h" +#include "murmur3.h" + +typedef struct AVMurMur3 { + uint64_t h1, h2; + uint8_t state[16]; + int state_pos; + uint64_t len; +} AVMurMur3; + +AVMurMur3 *av_murmur3_alloc(void) +{ + return av_mallocz(sizeof(AVMurMur3)); +} + +void av_murmur3_init_seeded(AVMurMur3 *c, uint64_t seed) +{ + memset(c, 0, sizeof(*c)); + c->h1 = c->h2 = seed; +} + +void av_murmur3_init(AVMurMur3 *c) +{ + // arbitrary random number as seed + av_murmur3_init_seeded(c, 0x725acc55daddca55); +} + +static const uint64_t c1 = UINT64_C(0x87c37b91114253d5); +static const uint64_t c2 = UINT64_C(0x4cf5ad432745937f); + +#define ROT(a, b) (((a) << (b)) | ((a) >> (64 - (b)))) + +static uint64_t inline get_k1(const uint8_t *src) +{ + uint64_t k = AV_RL64(src); + k *= c1; + k = ROT(k, 31); + k *= c2; + return k; +} + +static inline uint64_t get_k2(const uint8_t *src) +{ + uint64_t k = AV_RL64(src + 8); + k *= c2; + k = ROT(k, 33); + k *= c1; + return k; +} + +static inline uint64_t update_h1(uint64_t k, uint64_t h1, uint64_t h2) +{ + k ^= h1; + k = ROT(k, 27); + k += h2; + k *= 5; + k += 0x52dce729; + return k; +} + +static inline uint64_t update_h2(uint64_t k, uint64_t h1, uint64_t h2) +{ + k ^= h2; + k = ROT(k, 31); + k += h1; + k *= 5; + k += 0x38495ab5; + return k; +} + +#if FF_API_CRYPTO_SIZE_T +void av_murmur3_update(AVMurMur3 *c, const uint8_t *src, int len) +#else +void av_murmur3_update(AVMurMur3 *c, const uint8_t *src, size_t len) +#endif +{ + const uint8_t *end; + uint64_t h1 = c->h1, h2 = c->h2; + uint64_t k1, k2; + if (len <= 0) return; + c->len += len; + if (c->state_pos > 0) { + while (c->state_pos < 16) { + c->state[c->state_pos++] = *src++; + if (--len <= 0) return; + } + c->state_pos = 0; + k1 = get_k1(c->state); + k2 = get_k2(c->state); + h1 = update_h1(k1, h1, h2); + h2 = update_h2(k2, h1, h2); + } + + end = src + (len & ~15); + while (src < end) { + // These could be done sequentially instead + // of interleaved, but like this is over 10% faster + k1 = get_k1(src); + k2 = get_k2(src); + h1 = update_h1(k1, h1, h2); + h2 = update_h2(k2, h1, h2); + src += 16; + } + c->h1 = h1; + c->h2 = h2; + + len &= 15; + if (len > 0) { + memcpy(c->state, src, len); + c->state_pos = len; + } +} + +static inline uint64_t fmix(uint64_t k) +{ + k ^= k >> 33; + k *= UINT64_C(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= UINT64_C(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + return k; +} + +void av_murmur3_final(AVMurMur3 *c, uint8_t dst[16]) +{ + uint64_t h1 = c->h1, h2 = c->h2; + memset(c->state + c->state_pos, 0, sizeof(c->state) - c->state_pos); + h1 ^= get_k1(c->state) ^ c->len; + h2 ^= get_k2(c->state) ^ c->len; + h1 += h2; + h2 += h1; + h1 = fmix(h1); + h2 = fmix(h2); + h1 += h2; + h2 += h1; + AV_WL64(dst, h1); + AV_WL64(dst + 8, h2); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/murmur3.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/murmur3.h new file mode 100644 index 000000000..1b09175c1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/murmur3.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_murmur3 + * Public header for MurmurHash3 hash function implementation. + */ + +#ifndef AVUTIL_MURMUR3_H +#define AVUTIL_MURMUR3_H + +#include + +#include "version.h" + +/** + * @defgroup lavu_murmur3 Murmur3 + * @ingroup lavu_hash + * MurmurHash3 hash function implementation. + * + * MurmurHash3 is a non-cryptographic hash function, of which three + * incompatible versions were created by its inventor Austin Appleby: + * + * - 32-bit output + * - 128-bit output for 32-bit platforms + * - 128-bit output for 64-bit platforms + * + * FFmpeg only implements the last variant: 128-bit output designed for 64-bit + * platforms. Even though the hash function was designed for 64-bit platforms, + * the function in reality works on 32-bit systems too, only with reduced + * performance. + * + * @anchor lavu_murmur3_seedinfo + * By design, MurmurHash3 requires a seed to operate. In response to this, + * libavutil provides two functions for hash initiation, one that requires a + * seed (av_murmur3_init_seeded()) and one that uses a fixed arbitrary integer + * as the seed, and therefore does not (av_murmur3_init()). + * + * To make hashes comparable, you should provide the same seed for all calls to + * this hash function -- if you are supplying one yourself, that is. + * + * @{ + */ + +/** + * Allocate an AVMurMur3 hash context. + * + * @return Uninitialized hash context or `NULL` in case of error + */ +struct AVMurMur3 *av_murmur3_alloc(void); + +/** + * Initialize or reinitialize an AVMurMur3 hash context with a seed. + * + * @param[out] c Hash context + * @param[in] seed Random seed + * + * @see av_murmur3_init() + * @see @ref lavu_murmur3_seedinfo "Detailed description" on a discussion of + * seeds for MurmurHash3. + */ +void av_murmur3_init_seeded(struct AVMurMur3 *c, uint64_t seed); + +/** + * Initialize or reinitialize an AVMurMur3 hash context. + * + * Equivalent to av_murmur3_init_seeded() with a built-in seed. + * + * @param[out] c Hash context + * + * @see av_murmur3_init_seeded() + * @see @ref lavu_murmur3_seedinfo "Detailed description" on a discussion of + * seeds for MurmurHash3. + */ +void av_murmur3_init(struct AVMurMur3 *c); + +/** + * Update hash context with new data. + * + * @param[out] c Hash context + * @param[in] src Input data to update hash with + * @param[in] len Number of bytes to read from `src` + */ +#if FF_API_CRYPTO_SIZE_T +void av_murmur3_update(struct AVMurMur3 *c, const uint8_t *src, int len); +#else +void av_murmur3_update(struct AVMurMur3 *c, const uint8_t *src, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param[in,out] c Hash context + * @param[out] dst Buffer where output digest value is stored + */ +void av_murmur3_final(struct AVMurMur3 *c, uint8_t dst[16]); + +/** + * @} + */ + +#endif /* AVUTIL_MURMUR3_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.c new file mode 100644 index 000000000..93d6c26c1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.c @@ -0,0 +1,2039 @@ +/* + * AVOptions + * Copyright (c) 2005 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AVOptions + * @author Michael Niedermayer + */ + +#include "avutil.h" +#include "avassert.h" +#include "avstring.h" +#include "channel_layout.h" +#include "common.h" +#include "dict.h" +#include "eval.h" +#include "log.h" +#include "parseutils.h" +#include "pixdesc.h" +#include "mathematics.h" +#include "opt.h" +#include "samplefmt.h" +#include "bprint.h" + +#include + +const AVOption *av_opt_next(const void *obj, const AVOption *last) +{ + const AVClass *class; + if (!obj) + return NULL; + class = *(const AVClass**)obj; + if (!last && class && class->option && class->option[0].name) + return class->option; + if (last && last[1].name) + return ++last; + return NULL; +} + +static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum) +{ + switch (o->type) { + case AV_OPT_TYPE_FLAGS: + *intnum = *(unsigned int*)dst; + return 0; + case AV_OPT_TYPE_PIXEL_FMT: + *intnum = *(enum AVPixelFormat *)dst; + return 0; + case AV_OPT_TYPE_SAMPLE_FMT: + *intnum = *(enum AVSampleFormat *)dst; + return 0; + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_INT: + *intnum = *(int *)dst; + return 0; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + *intnum = *(int64_t *)dst; + return 0; + case AV_OPT_TYPE_FLOAT: + *num = *(float *)dst; + return 0; + case AV_OPT_TYPE_DOUBLE: + *num = *(double *)dst; + return 0; + case AV_OPT_TYPE_RATIONAL: + *intnum = ((AVRational *)dst)->num; + *den = ((AVRational *)dst)->den; + return 0; + case AV_OPT_TYPE_CONST: + *num = o->default_val.dbl; + return 0; + } + return AVERROR(EINVAL); +} + +static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) +{ + if (o->type != AV_OPT_TYPE_FLAGS && + (!den || o->max * den < num * intnum || o->min * den > num * intnum)) { + num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN); + av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", + num, o->name, o->min, o->max); + return AVERROR(ERANGE); + } + if (o->type == AV_OPT_TYPE_FLAGS) { + double d = num*intnum/den; + if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) { + av_log(obj, AV_LOG_ERROR, + "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n", + num*intnum/den, o->name); + return AVERROR(ERANGE); + } + } + + switch (o->type) { + case AV_OPT_TYPE_PIXEL_FMT: + *(enum AVPixelFormat *)dst = llrint(num / den) * intnum; + break; + case AV_OPT_TYPE_SAMPLE_FMT: + *(enum AVSampleFormat *)dst = llrint(num / den) * intnum; + break; + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_FLAGS: + case AV_OPT_TYPE_INT: + *(int *)dst = llrint(num / den) * intnum; + break; + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_CHANNEL_LAYOUT: + case AV_OPT_TYPE_INT64:{ + double d = num / den; + if (intnum == 1 && d == (double)INT64_MAX) { + *(int64_t *)dst = INT64_MAX; + } else + *(int64_t *)dst = llrint(d) * intnum; + break;} + case AV_OPT_TYPE_UINT64:{ + double d = num / den; + // We must special case uint64_t here as llrint() does not support values + // outside the int64_t range and there is no portable function which does + // "INT64_MAX + 1ULL" is used as it is representable exactly as IEEE double + // while INT64_MAX is not + if (intnum == 1 && d == (double)UINT64_MAX) { + *(uint64_t *)dst = UINT64_MAX; + } else if (d > INT64_MAX + 1ULL) { + *(uint64_t *)dst = (llrint(d - (INT64_MAX + 1ULL)) + (INT64_MAX + 1ULL))*intnum; + } else { + *(uint64_t *)dst = llrint(d) * intnum; + } + break;} + case AV_OPT_TYPE_FLOAT: + *(float *)dst = num * intnum / den; + break; + case AV_OPT_TYPE_DOUBLE: + *(double *)dst = num * intnum / den; + break; + case AV_OPT_TYPE_RATIONAL: + case AV_OPT_TYPE_VIDEO_RATE: + if ((int) num == num) + *(AVRational *)dst = (AVRational) { num *intnum, den }; + else + *(AVRational *)dst = av_d2q(num * intnum / den, 1 << 24); + break; + default: + return AVERROR(EINVAL); + } + return 0; +} + +static int hexchar2int(char c) { + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst) +{ + int *lendst = (int *)(dst + 1); + uint8_t *bin, *ptr; + int len; + + av_freep(dst); + *lendst = 0; + + if (!val || !(len = strlen(val))) + return 0; + + if (len & 1) + return AVERROR(EINVAL); + len /= 2; + + ptr = bin = av_malloc(len); + if (!ptr) + return AVERROR(ENOMEM); + while (*val) { + int a = hexchar2int(*val++); + int b = hexchar2int(*val++); + if (a < 0 || b < 0) { + av_free(bin); + return AVERROR(EINVAL); + } + *ptr++ = (a << 4) | b; + } + *dst = bin; + *lendst = len; + + return 0; +} + +static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst) +{ + av_freep(dst); + *dst = av_strdup(val); + return *dst ? 0 : AVERROR(ENOMEM); +} + +#define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \ + opt->type == AV_OPT_TYPE_UINT64 || \ + opt->type == AV_OPT_TYPE_CONST || \ + opt->type == AV_OPT_TYPE_FLAGS || \ + opt->type == AV_OPT_TYPE_INT) \ + ? opt->default_val.i64 \ + : opt->default_val.dbl) + +static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst) +{ + int ret = 0; + int num, den; + char c; + + if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) { + if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0) + return ret; + ret = 0; + } + + for (;;) { + int i = 0; + char buf[256]; + int cmd = 0; + double d; + int64_t intnum = 1; + + if (o->type == AV_OPT_TYPE_FLAGS) { + if (*val == '+' || *val == '-') + cmd = *(val++); + for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++) + buf[i] = val[i]; + buf[i] = 0; + } + + { + const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, 0); + int res; + int ci = 0; + double const_values[64]; + const char * const_names[64]; + if (o_named && o_named->type == AV_OPT_TYPE_CONST) + d = DEFAULT_NUMVAL(o_named); + else { + if (o->unit) { + for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) { + if (o_named->type == AV_OPT_TYPE_CONST && + o_named->unit && + !strcmp(o_named->unit, o->unit)) { + if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) { + av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit); + return AVERROR_PATCHWELCOME; + } + const_names [ci ] = o_named->name; + const_values[ci++] = DEFAULT_NUMVAL(o_named); + } + } + } + const_names [ci ] = "default"; + const_values[ci++] = DEFAULT_NUMVAL(o); + const_names [ci ] = "max"; + const_values[ci++] = o->max; + const_names [ci ] = "min"; + const_values[ci++] = o->min; + const_names [ci ] = "none"; + const_values[ci++] = 0; + const_names [ci ] = "all"; + const_values[ci++] = ~0; + const_names [ci] = NULL; + const_values[ci] = 0; + + res = av_expr_parse_and_eval(&d, i ? buf : val, const_names, + const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); + if (res < 0) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); + return res; + } + } + } + if (o->type == AV_OPT_TYPE_FLAGS) { + read_number(o, dst, NULL, NULL, &intnum); + if (cmd == '+') + d = intnum | (int64_t)d; + else if (cmd == '-') + d = intnum &~(int64_t)d; + } + + if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0) + return ret; + val += i; + if (!i || !*val) + return 0; + } +} + +static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst) +{ + int ret; + + if (!val || !strcmp(val, "none")) { + dst[0] = + dst[1] = 0; + return 0; + } + ret = av_parse_video_size(dst, dst + 1, val); + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val); + return ret; +} + +static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst) +{ + int ret; + if (!val) { + ret = AVERROR(EINVAL); + } else { + ret = av_parse_video_rate(dst, val); + } + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); + return ret; +} + +static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + int ret; + + if (!val) { + return 0; + } else { + ret = av_parse_color(dst, val, -1, obj); + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val); + return ret; + } + return 0; +} + +static const char *get_bool_name(int val) +{ + if (val < 0) + return "auto"; + return val ? "true" : "false"; +} + +static int set_string_bool(void *obj, const AVOption *o, const char *val, int *dst) +{ + int n; + + if (!val) + return 0; + + if (!strcmp(val, "auto")) { + n = -1; + } else if (av_match_name(val, "true,y,yes,enable,enabled,on")) { + n = 1; + } else if (av_match_name(val, "false,n,no,disable,disabled,off")) { + n = 0; + } else { + char *end = NULL; + n = strtol(val, &end, 10); + if (val + strlen(val) != end) + goto fail; + } + + if (n < o->min || n > o->max) + goto fail; + + *dst = n; + return 0; + +fail: + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as boolean\n", val); + return AVERROR(EINVAL); +} + +static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst, + int fmt_nb, int ((*get_fmt)(const char *)), const char *desc) +{ + int fmt, min, max; + + if (!val || !strcmp(val, "none")) { + fmt = -1; + } else { + fmt = get_fmt(val); + if (fmt == -1) { + char *tail; + fmt = strtol(val, &tail, 0); + if (*tail || (unsigned)fmt >= fmt_nb) { + av_log(obj, AV_LOG_ERROR, + "Unable to parse option value \"%s\" as %s\n", val, desc); + return AVERROR(EINVAL); + } + } + } + + min = FFMAX(o->min, -1); + max = FFMIN(o->max, fmt_nb-1); + + // hack for compatibility with old ffmpeg + if(min == 0 && max == 0) { + min = -1; + max = fmt_nb-1; + } + + if (fmt < min || fmt > max) { + av_log(obj, AV_LOG_ERROR, + "Value %d for parameter '%s' out of %s format range [%d - %d]\n", + fmt, o->name, desc, min, max); + return AVERROR(ERANGE); + } + + *(int *)dst = fmt; + return 0; +} + +static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + return set_string_fmt(obj, o, val, dst, + AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format"); +} + +static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + return set_string_fmt(obj, o, val, dst, + AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format"); +} + +int av_opt_set(void *obj, const char *name, const char *val, int search_flags) +{ + int ret = 0; + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (!val && (o->type != AV_OPT_TYPE_STRING && + o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT && + o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE && + o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR && + o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && o->type != AV_OPT_TYPE_BOOL)) + return AVERROR(EINVAL); + + if (o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + + if (o->flags & AV_OPT_FLAG_DEPRECATED) + av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help); + + dst = ((uint8_t *)target_obj) + o->offset; + switch (o->type) { + case AV_OPT_TYPE_BOOL: + return set_string_bool(obj, o, val, dst); + case AV_OPT_TYPE_STRING: + return set_string(obj, o, val, dst); + case AV_OPT_TYPE_BINARY: + return set_string_binary(obj, o, val, dst); + case AV_OPT_TYPE_FLAGS: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_FLOAT: + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_RATIONAL: + return set_string_number(obj, target_obj, o, val, dst); + case AV_OPT_TYPE_IMAGE_SIZE: + return set_string_image_size(obj, o, val, dst); + case AV_OPT_TYPE_VIDEO_RATE: { + AVRational tmp; + ret = set_string_video_rate(obj, o, val, &tmp); + if (ret < 0) + return ret; + return write_number(obj, o, dst, 1, tmp.den, tmp.num); + } + case AV_OPT_TYPE_PIXEL_FMT: + return set_string_pixel_fmt(obj, o, val, dst); + case AV_OPT_TYPE_SAMPLE_FMT: + return set_string_sample_fmt(obj, o, val, dst); + case AV_OPT_TYPE_DURATION: + { + int64_t usecs = 0; + if (val) { + if ((ret = av_parse_time(&usecs, val, 1)) < 0) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val); + return ret; + } + } + if (usecs < o->min || usecs > o->max) { + av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", + usecs / 1000000.0, o->name, o->min / 1000000.0, o->max / 1000000.0); + return AVERROR(ERANGE); + } + *(int64_t *)dst = usecs; + return 0; + } + case AV_OPT_TYPE_COLOR: + return set_string_color(obj, o, val, dst); + case AV_OPT_TYPE_CHANNEL_LAYOUT: + if (!val || !strcmp(val, "none")) { + *(int64_t *)dst = 0; + } else { + int64_t cl = av_get_channel_layout(val); + if (!cl) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); + ret = AVERROR(EINVAL); + } + *(int64_t *)dst = cl; + return ret; + } + break; + } + + av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); + return AVERROR(EINVAL); +} + +#define OPT_EVAL_NUMBER(name, opttype, vartype) \ +int av_opt_eval_ ## name(void *obj, const AVOption *o, \ + const char *val, vartype *name ## _out) \ +{ \ + if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY) \ + return AVERROR(EINVAL); \ + return set_string_number(obj, obj, o, val, name ## _out); \ +} + +OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int) +OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int) +OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t) +OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float) +OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double) +OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational) + +static int set_number(void *obj, const char *name, double num, int den, int64_t intnum, + int search_flags) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + + if (o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + + dst = ((uint8_t *)target_obj) + o->offset; + return write_number(obj, o, dst, num, den, intnum); +} + +int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags) +{ + return set_number(obj, name, 1, 1, val, search_flags); +} + +int av_opt_set_double(void *obj, const char *name, double val, int search_flags) +{ + return set_number(obj, name, val, 1, 1, search_flags); +} + +int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags) +{ + return set_number(obj, name, val.num, val.den, 1, search_flags); +} + +int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + uint8_t *ptr; + uint8_t **dst; + int *lendst; + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + + if (o->type != AV_OPT_TYPE_BINARY || o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + + ptr = len ? av_malloc(len) : NULL; + if (len && !ptr) + return AVERROR(ENOMEM); + + dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset); + lendst = (int *)(dst + 1); + + av_free(*dst); + *dst = ptr; + *lendst = len; + if (len) + memcpy(ptr, val, len); + + return 0; +} + +int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_IMAGE_SIZE) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not an image size.\n", o->name); + return AVERROR(EINVAL); + } + if (w<0 || h<0) { + av_log(obj, AV_LOG_ERROR, + "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name); + return AVERROR(EINVAL); + } + *(int *)(((uint8_t *)target_obj) + o->offset) = w; + *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h; + return 0; +} + +int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_VIDEO_RATE) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not a video rate.\n", o->name); + return AVERROR(EINVAL); + } + if (val.num <= 0 || val.den <= 0) + return AVERROR(EINVAL); + return set_number(obj, name, val.num, val.den, 1, search_flags); +} + +static int set_format(void *obj, const char *name, int fmt, int search_flags, + enum AVOptionType type, const char *desc, int nb_fmts) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, + search_flags, &target_obj); + int min, max; + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != type) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not a %s format", name, desc); + return AVERROR(EINVAL); + } + + min = FFMAX(o->min, -1); + max = FFMIN(o->max, nb_fmts-1); + + if (fmt < min || fmt > max) { + av_log(obj, AV_LOG_ERROR, + "Value %d for parameter '%s' out of %s format range [%d - %d]\n", + fmt, name, desc, min, max); + return AVERROR(ERANGE); + } + *(int *)(((uint8_t *)target_obj) + o->offset) = fmt; + return 0; +} + +int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags) +{ + return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB); +} + +int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags) +{ + return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB); +} + +int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not a channel layout.\n", o->name); + return AVERROR(EINVAL); + } + *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl; + return 0; +} + +int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, + int search_flags) +{ + void *target_obj; + AVDictionary **dst; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + + dst = (AVDictionary **)(((uint8_t *)target_obj) + o->offset); + av_dict_free(dst); + av_dict_copy(dst, val, 0); + + return 0; +} + +static void format_duration(char *buf, size_t size, int64_t d) +{ + char *e; + + av_assert0(size >= 25); + if (d < 0 && d != INT64_MIN) { + *(buf++) = '-'; + size--; + d = -d; + } + if (d == INT64_MAX) + snprintf(buf, size, "INT64_MAX"); + else if (d == INT64_MIN) + snprintf(buf, size, "INT64_MIN"); + else if (d > (int64_t)3600*1000000) + snprintf(buf, size, "%"PRId64":%02d:%02d.%06d", d / 3600000000, + (int)((d / 60000000) % 60), + (int)((d / 1000000) % 60), + (int)(d % 1000000)); + else if (d > 60*1000000) + snprintf(buf, size, "%d:%02d.%06d", + (int)(d / 60000000), + (int)((d / 1000000) % 60), + (int)(d % 1000000)); + else + snprintf(buf, size, "%d.%06d", + (int)(d / 1000000), + (int)(d % 1000000)); + e = buf + strlen(buf); + while (e > buf && e[-1] == '0') + *(--e) = 0; + if (e > buf && e[-1] == '.') + *(--e) = 0; +} + +int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + uint8_t *bin, buf[128]; + int len, i, ret; + int64_t i64; + + if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST)) + return AVERROR_OPTION_NOT_FOUND; + + if (o->flags & AV_OPT_FLAG_DEPRECATED) + av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help); + + dst = (uint8_t *)target_obj + o->offset; + + buf[0] = 0; + switch (o->type) { + case AV_OPT_TYPE_BOOL: + ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(get_bool_name(*(int *)dst), "invalid")); + break; + case AV_OPT_TYPE_FLAGS: + ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst); + break; + case AV_OPT_TYPE_INT: + ret = snprintf(buf, sizeof(buf), "%d", *(int *)dst); + break; + case AV_OPT_TYPE_INT64: + ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t *)dst); + break; + case AV_OPT_TYPE_UINT64: + ret = snprintf(buf, sizeof(buf), "%"PRIu64, *(uint64_t *)dst); + break; + case AV_OPT_TYPE_FLOAT: + ret = snprintf(buf, sizeof(buf), "%f", *(float *)dst); + break; + case AV_OPT_TYPE_DOUBLE: + ret = snprintf(buf, sizeof(buf), "%f", *(double *)dst); + break; + case AV_OPT_TYPE_VIDEO_RATE: + case AV_OPT_TYPE_RATIONAL: + ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den); + break; + case AV_OPT_TYPE_CONST: + ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl); + break; + case AV_OPT_TYPE_STRING: + if (*(uint8_t **)dst) { + *out_val = av_strdup(*(uint8_t **)dst); + } else if (search_flags & AV_OPT_ALLOW_NULL) { + *out_val = NULL; + return 0; + } else { + *out_val = av_strdup(""); + } + return *out_val ? 0 : AVERROR(ENOMEM); + case AV_OPT_TYPE_BINARY: + if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) { + *out_val = NULL; + return 0; + } + len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *)); + if ((uint64_t)len * 2 + 1 > INT_MAX) + return AVERROR(EINVAL); + if (!(*out_val = av_malloc(len * 2 + 1))) + return AVERROR(ENOMEM); + if (!len) { + *out_val[0] = '\0'; + return 0; + } + bin = *(uint8_t **)dst; + for (i = 0; i < len; i++) + snprintf(*out_val + i * 2, 3, "%02X", bin[i]); + return 0; + case AV_OPT_TYPE_IMAGE_SIZE: + ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]); + break; + case AV_OPT_TYPE_PIXEL_FMT: + ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none")); + break; + case AV_OPT_TYPE_SAMPLE_FMT: + ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none")); + break; + case AV_OPT_TYPE_DURATION: + i64 = *(int64_t *)dst; + format_duration(buf, sizeof(buf), i64); + ret = strlen(buf); // no overflow possible, checked by an assert + break; + case AV_OPT_TYPE_COLOR: + ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", + (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1], + (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]); + break; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + i64 = *(int64_t *)dst; + ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64); + break; + default: + return AVERROR(EINVAL); + } + + if (ret >= sizeof(buf)) + return AVERROR(EINVAL); + *out_val = av_strdup(buf); + return *out_val ? 0 : AVERROR(ENOMEM); +} + +static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum, + int search_flags) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + goto error; + + dst = ((uint8_t *)target_obj) + o->offset; + + if (o_out) *o_out= o; + + return read_number(o, dst, num, den, intnum); + +error: + *den = + *intnum = 0; + return -1; +} + +int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + *out_val = num * intnum / den; + return 0; +} + +int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + *out_val = num * intnum / den; + return 0; +} + +int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + + if (num == 1.0 && (int)intnum == intnum) + *out_val = (AVRational){intnum, den}; + else + *out_val = av_d2q(num*intnum/den, 1<<24); + return 0; +} + +int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_IMAGE_SIZE) { + av_log(obj, AV_LOG_ERROR, + "The value for option '%s' is not an image size.\n", name); + return AVERROR(EINVAL); + } + + dst = ((uint8_t*)target_obj) + o->offset; + if (w_out) *w_out = *(int *)dst; + if (h_out) *h_out = *((int *)dst+1); + return 0; +} + +int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val) +{ + int64_t intnum = 1; + double num = 1; + int ret, den = 1; + + if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0) + return ret; + + if (num == 1.0 && (int)intnum == intnum) + *out_val = (AVRational) { intnum, den }; + else + *out_val = av_d2q(num * intnum / den, 1 << 24); + return 0; +} + +static int get_format(void *obj, const char *name, int search_flags, int *out_fmt, + enum AVOptionType type, const char *desc) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != type) { + av_log(obj, AV_LOG_ERROR, + "The value for option '%s' is not a %s format.\n", desc, name); + return AVERROR(EINVAL); + } + + dst = ((uint8_t*)target_obj) + o->offset; + *out_fmt = *(int *)dst; + return 0; +} + +int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt) +{ + return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel"); +} + +int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt) +{ + return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample"); +} + +int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { + av_log(obj, AV_LOG_ERROR, + "The value for option '%s' is not a channel layout.\n", name); + return AVERROR(EINVAL); + } + + dst = ((uint8_t*)target_obj) + o->offset; + *cl = *(int64_t *)dst; + return 0; +} + +int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val) +{ + void *target_obj; + AVDictionary *src; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_DICT) + return AVERROR(EINVAL); + + src = *(AVDictionary **)(((uint8_t *)target_obj) + o->offset); + av_dict_copy(out_val, src, 0); + + return 0; +} + +int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) +{ + const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); + const AVOption *flag = av_opt_find(obj, flag_name, + field ? field->unit : NULL, 0, 0); + int64_t res; + + if (!field || !flag || flag->type != AV_OPT_TYPE_CONST || + av_opt_get_int(obj, field_name, 0, &res) < 0) + return 0; + return res & flag->default_val.i64; +} + +static void log_value(void *av_log_obj, int level, double d) +{ + if (d == INT_MAX) { + av_log(av_log_obj, level, "INT_MAX"); + } else if (d == INT_MIN) { + av_log(av_log_obj, level, "INT_MIN"); + } else if (d == UINT32_MAX) { + av_log(av_log_obj, level, "UINT32_MAX"); + } else if (d == (double)INT64_MAX) { + av_log(av_log_obj, level, "I64_MAX"); + } else if (d == INT64_MIN) { + av_log(av_log_obj, level, "I64_MIN"); + } else if (d == FLT_MAX) { + av_log(av_log_obj, level, "FLT_MAX"); + } else if (d == FLT_MIN) { + av_log(av_log_obj, level, "FLT_MIN"); + } else if (d == -FLT_MAX) { + av_log(av_log_obj, level, "-FLT_MAX"); + } else if (d == -FLT_MIN) { + av_log(av_log_obj, level, "-FLT_MIN"); + } else if (d == DBL_MAX) { + av_log(av_log_obj, level, "DBL_MAX"); + } else if (d == DBL_MIN) { + av_log(av_log_obj, level, "DBL_MIN"); + } else if (d == -DBL_MAX) { + av_log(av_log_obj, level, "-DBL_MAX"); + } else if (d == -DBL_MIN) { + av_log(av_log_obj, level, "-DBL_MIN"); + } else { + av_log(av_log_obj, level, "%g", d); + } +} + +static const char *get_opt_const_name(void *obj, const char *unit, int64_t value) +{ + const AVOption *opt = NULL; + + if (!unit) + return NULL; + while ((opt = av_opt_next(obj, opt))) + if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) && + opt->default_val.i64 == value) + return opt->name; + return NULL; +} + +static char *get_opt_flags_string(void *obj, const char *unit, int64_t value) +{ + const AVOption *opt = NULL; + char flags[512]; + + flags[0] = 0; + if (!unit) + return NULL; + while ((opt = av_opt_next(obj, opt))) { + if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) && + opt->default_val.i64 & value) { + if (flags[0]) + av_strlcatf(flags, sizeof(flags), "+"); + av_strlcatf(flags, sizeof(flags), "%s", opt->name); + } + } + if (flags[0]) + return av_strdup(flags); + return NULL; +} + +static void opt_list(void *obj, void *av_log_obj, const char *unit, + int req_flags, int rej_flags) +{ + const AVOption *opt = NULL; + AVOptionRanges *r; + int i; + + while ((opt = av_opt_next(obj, opt))) { + if (!(opt->flags & req_flags) || (opt->flags & rej_flags)) + continue; + + /* Don't print CONST's on level one. + * Don't print anything but CONST's on level two. + * Only print items from the requested unit. + */ + if (!unit && opt->type == AV_OPT_TYPE_CONST) + continue; + else if (unit && opt->type != AV_OPT_TYPE_CONST) + continue; + else if (unit && opt->type == AV_OPT_TYPE_CONST && strcmp(unit, opt->unit)) + continue; + else if (unit && opt->type == AV_OPT_TYPE_CONST) + av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); + else + av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ", + (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? "" : "-", + opt->name); + + switch (opt->type) { + case AV_OPT_TYPE_FLAGS: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_INT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_INT64: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_UINT64: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_DOUBLE: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_FLOAT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_STRING: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_RATIONAL: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_BINARY: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_IMAGE_SIZE: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_VIDEO_RATE: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_PIXEL_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_SAMPLE_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_DURATION: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_COLOR: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_BOOL: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_CONST: + default: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + } + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.'); + + if (opt->help) + av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); + + if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) { + switch (opt->type) { + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_FLOAT: + case AV_OPT_TYPE_RATIONAL: + for (i = 0; i < r->nb_ranges; i++) { + av_log(av_log_obj, AV_LOG_INFO, " (from "); + log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min); + av_log(av_log_obj, AV_LOG_INFO, " to "); + log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max); + av_log(av_log_obj, AV_LOG_INFO, ")"); + } + break; + } + av_opt_freep_ranges(&r); + } + + if (opt->type != AV_OPT_TYPE_CONST && + opt->type != AV_OPT_TYPE_BINARY && + !((opt->type == AV_OPT_TYPE_COLOR || + opt->type == AV_OPT_TYPE_IMAGE_SIZE || + opt->type == AV_OPT_TYPE_STRING || + opt->type == AV_OPT_TYPE_VIDEO_RATE) && + !opt->default_val.str)) { + av_log(av_log_obj, AV_LOG_INFO, " (default "); + switch (opt->type) { + case AV_OPT_TYPE_BOOL: + av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(get_bool_name(opt->default_val.i64), "invalid")); + break; + case AV_OPT_TYPE_FLAGS: { + char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64); + if (def_flags) { + av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags); + av_freep(&def_flags); + } else { + av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64); + } + break; + } + case AV_OPT_TYPE_DURATION: { + char buf[25]; + format_duration(buf, sizeof(buf), opt->default_val.i64); + av_log(av_log_obj, AV_LOG_INFO, "%s", buf); + break; + } + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_INT64: { + const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64); + if (def_const) + av_log(av_log_obj, AV_LOG_INFO, "%s", def_const); + else + log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64); + break; + } + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_FLOAT: + log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl); + break; + case AV_OPT_TYPE_RATIONAL: { + AVRational q = av_d2q(opt->default_val.dbl, INT_MAX); + av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); } + break; + case AV_OPT_TYPE_PIXEL_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none")); + break; + case AV_OPT_TYPE_SAMPLE_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none")); + break; + case AV_OPT_TYPE_COLOR: + case AV_OPT_TYPE_IMAGE_SIZE: + case AV_OPT_TYPE_STRING: + case AV_OPT_TYPE_VIDEO_RATE: + av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str); + break; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64); + break; + } + av_log(av_log_obj, AV_LOG_INFO, ")"); + } + + av_log(av_log_obj, AV_LOG_INFO, "\n"); + if (opt->unit && opt->type != AV_OPT_TYPE_CONST) + opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags); + } +} + +int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags) +{ + if (!obj) + return -1; + + av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name); + + opt_list(obj, av_log_obj, NULL, req_flags, rej_flags); + + return 0; +} + +void av_opt_set_defaults(void *s) +{ + av_opt_set_defaults2(s, 0, 0); +} + +void av_opt_set_defaults2(void *s, int mask, int flags) +{ + const AVOption *opt = NULL; + while ((opt = av_opt_next(s, opt))) { + void *dst = ((uint8_t*)s) + opt->offset; + + if ((opt->flags & mask) != flags) + continue; + + if (opt->flags & AV_OPT_FLAG_READONLY) + continue; + + switch (opt->type) { + case AV_OPT_TYPE_CONST: + /* Nothing to be done here */ + break; + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_FLAGS: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_CHANNEL_LAYOUT: + case AV_OPT_TYPE_PIXEL_FMT: + case AV_OPT_TYPE_SAMPLE_FMT: + write_number(s, opt, dst, 1, 1, opt->default_val.i64); + break; + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_FLOAT: { + double val; + val = opt->default_val.dbl; + write_number(s, opt, dst, val, 1, 1); + } + break; + case AV_OPT_TYPE_RATIONAL: { + AVRational val; + val = av_d2q(opt->default_val.dbl, INT_MAX); + write_number(s, opt, dst, 1, val.den, val.num); + } + break; + case AV_OPT_TYPE_COLOR: + set_string_color(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_STRING: + set_string(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_IMAGE_SIZE: + set_string_image_size(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_VIDEO_RATE: + set_string_video_rate(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_BINARY: + set_string_binary(s, opt, opt->default_val.str, dst); + break; + case AV_OPT_TYPE_DICT: + /* Cannot set defaults for these types */ + break; + default: + av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", + opt->type, opt->name); + } + } +} + +/** + * Store the value in the field in ctx that is named like key. + * ctx must be an AVClass context, storing is done using AVOptions. + * + * @param buf the string to parse, buf will be updated to point at the + * separator just after the parsed key/value pair + * @param key_val_sep a 0-terminated list of characters used to + * separate key from value + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other + * @return 0 if the key/value pair has been successfully parsed and + * set, or a negative value corresponding to an AVERROR code in case + * of error: + * AVERROR(EINVAL) if the key/value pair cannot be parsed, + * the error code issued by av_opt_set() if the key/value pair + * cannot be set + */ +static int parse_key_value_pair(void *ctx, const char **buf, + const char *key_val_sep, const char *pairs_sep) +{ + char *key = av_get_token(buf, key_val_sep); + char *val; + int ret; + + if (!key) + return AVERROR(ENOMEM); + + if (*key && strspn(*buf, key_val_sep)) { + (*buf)++; + val = av_get_token(buf, pairs_sep); + if (!val) { + av_freep(&key); + return AVERROR(ENOMEM); + } + } else { + av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); + av_free(key); + return AVERROR(EINVAL); + } + + av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val); + + ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN); + if (ret == AVERROR_OPTION_NOT_FOUND) + av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); + + av_free(key); + av_free(val); + return ret; +} + +int av_set_options_string(void *ctx, const char *opts, + const char *key_val_sep, const char *pairs_sep) +{ + int ret, count = 0; + + if (!opts) + return 0; + + while (*opts) { + if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) + return ret; + count++; + + if (*opts) + opts++; + } + + return count; +} + +#define WHITESPACES " \n\t\r" + +static int is_key_char(char c) +{ + return (unsigned)((c | 32) - 'a') < 26 || + (unsigned)(c - '0') < 10 || + c == '-' || c == '_' || c == '/' || c == '.'; +} + +/** + * Read a key from a string. + * + * The key consists of is_key_char characters and must be terminated by a + * character from the delim string; spaces are ignored. + * + * @return 0 for success (even with ellipsis), <0 for failure + */ +static int get_key(const char **ropts, const char *delim, char **rkey) +{ + const char *opts = *ropts; + const char *key_start, *key_end; + + key_start = opts += strspn(opts, WHITESPACES); + while (is_key_char(*opts)) + opts++; + key_end = opts; + opts += strspn(opts, WHITESPACES); + if (!*opts || !strchr(delim, *opts)) + return AVERROR(EINVAL); + opts++; + if (!(*rkey = av_malloc(key_end - key_start + 1))) + return AVERROR(ENOMEM); + memcpy(*rkey, key_start, key_end - key_start); + (*rkey)[key_end - key_start] = 0; + *ropts = opts; + return 0; +} + +int av_opt_get_key_value(const char **ropts, + const char *key_val_sep, const char *pairs_sep, + unsigned flags, + char **rkey, char **rval) +{ + int ret; + char *key = NULL, *val; + const char *opts = *ropts; + + if ((ret = get_key(&opts, key_val_sep, &key)) < 0 && + !(flags & AV_OPT_FLAG_IMPLICIT_KEY)) + return AVERROR(EINVAL); + if (!(val = av_get_token(&opts, pairs_sep))) { + av_free(key); + return AVERROR(ENOMEM); + } + *ropts = opts; + *rkey = key; + *rval = val; + return 0; +} + +int av_opt_set_from_string(void *ctx, const char *opts, + const char *const *shorthand, + const char *key_val_sep, const char *pairs_sep) +{ + int ret, count = 0; + const char *dummy_shorthand = NULL; + char *av_uninit(parsed_key), *av_uninit(value); + const char *key; + + if (!opts) + return 0; + if (!shorthand) + shorthand = &dummy_shorthand; + + while (*opts) { + ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep, + *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0, + &parsed_key, &value); + if (ret < 0) { + if (ret == AVERROR(EINVAL)) + av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts); + else + av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts, + av_err2str(ret)); + return ret; + } + if (*opts) + opts++; + if (parsed_key) { + key = parsed_key; + while (*shorthand) /* discard all remaining shorthand */ + shorthand++; + } else { + key = *(shorthand++); + } + + av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value); + if ((ret = av_opt_set(ctx, key, value, 0)) < 0) { + if (ret == AVERROR_OPTION_NOT_FOUND) + av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); + av_free(value); + av_free(parsed_key); + return ret; + } + + av_free(value); + av_free(parsed_key); + count++; + } + return count; +} + +void av_opt_free(void *obj) +{ + const AVOption *o = NULL; + while ((o = av_opt_next(obj, o))) { + switch (o->type) { + case AV_OPT_TYPE_STRING: + case AV_OPT_TYPE_BINARY: + av_freep((uint8_t *)obj + o->offset); + break; + + case AV_OPT_TYPE_DICT: + av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset)); + break; + + default: + break; + } + } +} + +int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags) +{ + AVDictionaryEntry *t = NULL; + AVDictionary *tmp = NULL; + int ret = 0; + + if (!options) + return 0; + + while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) { + ret = av_opt_set(obj, t->key, t->value, search_flags); + if (ret == AVERROR_OPTION_NOT_FOUND) + ret = av_dict_set(&tmp, t->key, t->value, 0); + if (ret < 0) { + av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value); + av_dict_free(&tmp); + return ret; + } + ret = 0; + } + av_dict_free(options); + *options = tmp; + return ret; +} + +int av_opt_set_dict(void *obj, AVDictionary **options) +{ + return av_opt_set_dict2(obj, options, 0); +} + +const AVOption *av_opt_find(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags) +{ + return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL); +} + +const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags, void **target_obj) +{ + const AVClass *c; + const AVOption *o = NULL; + + if(!obj) + return NULL; + + c= *(AVClass**)obj; + + if (!c) + return NULL; + + if (search_flags & AV_OPT_SEARCH_CHILDREN) { + if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { + const AVClass *child = NULL; + while (child = av_opt_child_class_next(c, child)) + if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) + return o; + } else { + void *child = NULL; + while (child = av_opt_child_next(obj, child)) + if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj)) + return o; + } + } + + while (o = av_opt_next(obj, o)) { + if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags && + ((!unit && o->type != AV_OPT_TYPE_CONST) || + (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) { + if (target_obj) { + if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ)) + *target_obj = obj; + else + *target_obj = NULL; + } + return o; + } + } + return NULL; +} + +void *av_opt_child_next(void *obj, void *prev) +{ + const AVClass *c = *(AVClass **)obj; + if (c->child_next) + return c->child_next(obj, prev); + return NULL; +} + +const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev) +{ + if (parent->child_class_next) + return parent->child_class_next(prev); + return NULL; +} + +void *av_opt_ptr(const AVClass *class, void *obj, const char *name) +{ + const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL); + if(!opt) + return NULL; + return (uint8_t*)obj + opt->offset; +} + +static int opt_size(enum AVOptionType type) +{ + switch(type) { + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_FLAGS: + return sizeof(int); + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_CHANNEL_LAYOUT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + return sizeof(int64_t); + case AV_OPT_TYPE_DOUBLE: + return sizeof(double); + case AV_OPT_TYPE_FLOAT: + return sizeof(float); + case AV_OPT_TYPE_STRING: + return sizeof(uint8_t*); + case AV_OPT_TYPE_VIDEO_RATE: + case AV_OPT_TYPE_RATIONAL: + return sizeof(AVRational); + case AV_OPT_TYPE_BINARY: + return sizeof(uint8_t*) + sizeof(int); + case AV_OPT_TYPE_IMAGE_SIZE: + return sizeof(int[2]); + case AV_OPT_TYPE_PIXEL_FMT: + return sizeof(enum AVPixelFormat); + case AV_OPT_TYPE_SAMPLE_FMT: + return sizeof(enum AVSampleFormat); + case AV_OPT_TYPE_COLOR: + return 4; + } + return AVERROR(EINVAL); +} + +int av_opt_copy(void *dst, const void *src) +{ + const AVOption *o = NULL; + const AVClass *c; + int ret = 0; + + if (!src) + return AVERROR(EINVAL); + + c = *(AVClass **)src; + if (!c || c != *(AVClass **)dst) + return AVERROR(EINVAL); + + while ((o = av_opt_next(src, o))) { + void *field_dst = (uint8_t *)dst + o->offset; + void *field_src = (uint8_t *)src + o->offset; + uint8_t **field_dst8 = (uint8_t **)field_dst; + uint8_t **field_src8 = (uint8_t **)field_src; + + if (o->type == AV_OPT_TYPE_STRING) { + if (*field_dst8 != *field_src8) + av_freep(field_dst8); + *field_dst8 = av_strdup(*field_src8); + if (*field_src8 && !*field_dst8) + ret = AVERROR(ENOMEM); + } else if (o->type == AV_OPT_TYPE_BINARY) { + int len = *(int *)(field_src8 + 1); + if (*field_dst8 != *field_src8) + av_freep(field_dst8); + *field_dst8 = av_memdup(*field_src8, len); + if (len && !*field_dst8) { + ret = AVERROR(ENOMEM); + len = 0; + } + *(int *)(field_dst8 + 1) = len; + } else if (o->type == AV_OPT_TYPE_CONST) { + // do nothing + } else if (o->type == AV_OPT_TYPE_DICT) { + AVDictionary **sdict = (AVDictionary **) field_src; + AVDictionary **ddict = (AVDictionary **) field_dst; + if (*sdict != *ddict) + av_dict_free(ddict); + *ddict = NULL; + av_dict_copy(ddict, *sdict, 0); + if (av_dict_count(*sdict) != av_dict_count(*ddict)) + ret = AVERROR(ENOMEM); + } else { + int size = opt_size(o->type); + if (size < 0) + ret = size; + else + memcpy(field_dst, field_src, size); + } + } + return ret; +} + +int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) +{ + int ret; + const AVClass *c = *(AVClass**)obj; + int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL; + + if (c->version > (52 << 16 | 11 << 8)) + callback = c->query_ranges; + + if (!callback) + callback = av_opt_query_ranges_default; + + ret = callback(ranges_arg, obj, key, flags); + if (ret >= 0) { + if (!(flags & AV_OPT_MULTI_COMPONENT_RANGE)) + ret = 1; + (*ranges_arg)->nb_components = ret; + } + return ret; +} + +int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags) +{ + AVOptionRanges *ranges = av_mallocz(sizeof(*ranges)); + AVOptionRange **range_array = av_mallocz(sizeof(void*)); + AVOptionRange *range = av_mallocz(sizeof(*range)); + const AVOption *field = av_opt_find(obj, key, NULL, 0, flags); + int ret; + + *ranges_arg = NULL; + + if (!ranges || !range || !range_array || !field) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ranges->range = range_array; + ranges->range[0] = range; + ranges->nb_ranges = 1; + ranges->nb_components = 1; + range->is_range = 1; + range->value_min = field->min; + range->value_max = field->max; + + switch (field->type) { + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + case AV_OPT_TYPE_PIXEL_FMT: + case AV_OPT_TYPE_SAMPLE_FMT: + case AV_OPT_TYPE_FLOAT: + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_COLOR: + case AV_OPT_TYPE_CHANNEL_LAYOUT: + break; + case AV_OPT_TYPE_STRING: + range->component_min = 0; + range->component_max = 0x10FFFF; // max unicode value + range->value_min = -1; + range->value_max = INT_MAX; + break; + case AV_OPT_TYPE_RATIONAL: + range->component_min = INT_MIN; + range->component_max = INT_MAX; + break; + case AV_OPT_TYPE_IMAGE_SIZE: + range->component_min = 0; + range->component_max = INT_MAX/128/8; + range->value_min = 0; + range->value_max = INT_MAX/8; + break; + case AV_OPT_TYPE_VIDEO_RATE: + range->component_min = 1; + range->component_max = INT_MAX; + range->value_min = 1; + range->value_max = INT_MAX; + break; + default: + ret = AVERROR(ENOSYS); + goto fail; + } + + *ranges_arg = ranges; + return 1; +fail: + av_free(ranges); + av_free(range); + av_free(range_array); + return ret; +} + +void av_opt_freep_ranges(AVOptionRanges **rangesp) +{ + int i; + AVOptionRanges *ranges = *rangesp; + + if (!ranges) + return; + + for (i = 0; i < ranges->nb_ranges * ranges->nb_components; i++) { + AVOptionRange *range = ranges->range[i]; + if (range) { + av_freep(&range->str); + av_freep(&ranges->range[i]); + } + } + av_freep(&ranges->range); + av_freep(rangesp); +} + +int av_opt_is_set_to_default(void *obj, const AVOption *o) +{ + int64_t i64; + double d, d2; + float f; + AVRational q; + int ret, w, h; + char *str; + void *dst; + + if (!o || !obj) + return AVERROR(EINVAL); + + dst = ((uint8_t*)obj) + o->offset; + + switch (o->type) { + case AV_OPT_TYPE_CONST: + return 1; + case AV_OPT_TYPE_BOOL: + case AV_OPT_TYPE_FLAGS: + case AV_OPT_TYPE_PIXEL_FMT: + case AV_OPT_TYPE_SAMPLE_FMT: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_CHANNEL_LAYOUT: + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_INT64: + case AV_OPT_TYPE_UINT64: + read_number(o, dst, NULL, NULL, &i64); + return o->default_val.i64 == i64; + case AV_OPT_TYPE_STRING: + str = *(char **)dst; + if (str == o->default_val.str) //2 NULLs + return 1; + if (!str || !o->default_val.str) //1 NULL + return 0; + return !strcmp(str, o->default_val.str); + case AV_OPT_TYPE_DOUBLE: + read_number(o, dst, &d, NULL, NULL); + return o->default_val.dbl == d; + case AV_OPT_TYPE_FLOAT: + read_number(o, dst, &d, NULL, NULL); + f = o->default_val.dbl; + d2 = f; + return d2 == d; + case AV_OPT_TYPE_RATIONAL: + q = av_d2q(o->default_val.dbl, INT_MAX); + return !av_cmp_q(*(AVRational*)dst, q); + case AV_OPT_TYPE_BINARY: { + struct { + uint8_t *data; + int size; + } tmp = {0}; + int opt_size = *(int *)((void **)dst + 1); + void *opt_ptr = *(void **)dst; + if (!opt_size && (!o->default_val.str || !strlen(o->default_val.str))) + return 1; + if (!opt_size || !o->default_val.str || !strlen(o->default_val.str )) + return 0; + if (opt_size != strlen(o->default_val.str) / 2) + return 0; + ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data); + if (!ret) + ret = !memcmp(opt_ptr, tmp.data, tmp.size); + av_free(tmp.data); + return ret; + } + case AV_OPT_TYPE_DICT: + /* Binary and dict have not default support yet. Any pointer is not default. */ + return !!(*(void **)dst); + case AV_OPT_TYPE_IMAGE_SIZE: + if (!o->default_val.str || !strcmp(o->default_val.str, "none")) + w = h = 0; + else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0) + return ret; + return (w == *(int *)dst) && (h == *((int *)dst+1)); + case AV_OPT_TYPE_VIDEO_RATE: + q = (AVRational){0, 0}; + if (o->default_val.str) { + if ((ret = av_parse_video_rate(&q, o->default_val.str)) < 0) + return ret; + } + return !av_cmp_q(*(AVRational*)dst, q); + case AV_OPT_TYPE_COLOR: { + uint8_t color[4] = {0, 0, 0, 0}; + if (o->default_val.str) { + if ((ret = av_parse_color(color, o->default_val.str, -1, NULL)) < 0) + return ret; + } + return !memcmp(color, dst, sizeof(color)); + } + default: + av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name); + break; + } + return AVERROR_PATCHWELCOME; +} + +int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags) +{ + const AVOption *o; + void *target; + if (!obj) + return AVERROR(EINVAL); + o = av_opt_find2(obj, name, NULL, 0, search_flags, &target); + if (!o) + return AVERROR_OPTION_NOT_FOUND; + return av_opt_is_set_to_default(target, o); +} + +int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, + const char key_val_sep, const char pairs_sep) +{ + const AVOption *o = NULL; + uint8_t *buf; + AVBPrint bprint; + int ret, cnt = 0; + const char special_chars[] = {pairs_sep, key_val_sep, '\0'}; + + if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep || + pairs_sep == '\\' || key_val_sep == '\\') { + av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found."); + return AVERROR(EINVAL); + } + + if (!obj || !buffer) + return AVERROR(EINVAL); + + *buffer = NULL; + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); + + while (o = av_opt_next(obj, o)) { + if (o->type == AV_OPT_TYPE_CONST) + continue; + if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags) + continue; + else if (((o->flags & opt_flags) != opt_flags)) + continue; + if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0) + continue; + if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) { + av_bprint_finalize(&bprint, NULL); + return ret; + } + if (buf) { + if (cnt++) + av_bprint_append_data(&bprint, &pairs_sep, 1); + av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + av_bprint_append_data(&bprint, &key_val_sep, 1); + av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0); + av_freep(&buf); + } + } + av_bprint_finalize(&bprint, buffer); + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.h new file mode 100644 index 000000000..39f4a8dda --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/opt.h @@ -0,0 +1,865 @@ +/* + * AVOptions + * copyright (c) 2005 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_OPT_H +#define AVUTIL_OPT_H + +/** + * @file + * AVOptions + */ + +#include "rational.h" +#include "avutil.h" +#include "dict.h" +#include "log.h" +#include "pixfmt.h" +#include "samplefmt.h" +#include "version.h" + +/** + * @defgroup avoptions AVOptions + * @ingroup lavu_data + * @{ + * AVOptions provide a generic system to declare options on arbitrary structs + * ("objects"). An option can have a help text, a type and a range of possible + * values. Options may then be enumerated, read and written to. + * + * @section avoptions_implement Implementing AVOptions + * This section describes how to add AVOptions capabilities to a struct. + * + * All AVOptions-related information is stored in an AVClass. Therefore + * the first member of the struct should be a pointer to an AVClass describing it. + * The option field of the AVClass must be set to a NULL-terminated static array + * of AVOptions. Each AVOption must have a non-empty name, a type, a default + * value and for number-type AVOptions also a range of allowed values. It must + * also declare an offset in bytes from the start of the struct, where the field + * associated with this AVOption is located. Other fields in the AVOption struct + * should also be set when applicable, but are not required. + * + * The following example illustrates an AVOptions-enabled struct: + * @code + * typedef struct test_struct { + * const AVClass *class; + * int int_opt; + * char *str_opt; + * uint8_t *bin_opt; + * int bin_len; + * } test_struct; + * + * static const AVOption test_options[] = { + * { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt), + * AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX }, + * { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt), + * AV_OPT_TYPE_STRING }, + * { "test_bin", "This is a test option of binary type.", offsetof(test_struct, bin_opt), + * AV_OPT_TYPE_BINARY }, + * { NULL }, + * }; + * + * static const AVClass test_class = { + * .class_name = "test class", + * .item_name = av_default_item_name, + * .option = test_options, + * .version = LIBAVUTIL_VERSION_INT, + * }; + * @endcode + * + * Next, when allocating your struct, you must ensure that the AVClass pointer + * is set to the correct value. Then, av_opt_set_defaults() can be called to + * initialize defaults. After that the struct is ready to be used with the + * AVOptions API. + * + * When cleaning up, you may use the av_opt_free() function to automatically + * free all the allocated string and binary options. + * + * Continuing with the above example: + * + * @code + * test_struct *alloc_test_struct(void) + * { + * test_struct *ret = av_mallocz(sizeof(*ret)); + * ret->class = &test_class; + * av_opt_set_defaults(ret); + * return ret; + * } + * void free_test_struct(test_struct **foo) + * { + * av_opt_free(*foo); + * av_freep(foo); + * } + * @endcode + * + * @subsection avoptions_implement_nesting Nesting + * It may happen that an AVOptions-enabled struct contains another + * AVOptions-enabled struct as a member (e.g. AVCodecContext in + * libavcodec exports generic options, while its priv_data field exports + * codec-specific options). In such a case, it is possible to set up the + * parent struct to export a child's options. To do that, simply + * implement AVClass.child_next() and AVClass.child_class_next() in the + * parent struct's AVClass. + * Assuming that the test_struct from above now also contains a + * child_struct field: + * + * @code + * typedef struct child_struct { + * AVClass *class; + * int flags_opt; + * } child_struct; + * static const AVOption child_opts[] = { + * { "test_flags", "This is a test option of flags type.", + * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX }, + * { NULL }, + * }; + * static const AVClass child_class = { + * .class_name = "child class", + * .item_name = av_default_item_name, + * .option = child_opts, + * .version = LIBAVUTIL_VERSION_INT, + * }; + * + * void *child_next(void *obj, void *prev) + * { + * test_struct *t = obj; + * if (!prev && t->child_struct) + * return t->child_struct; + * return NULL + * } + * const AVClass child_class_next(const AVClass *prev) + * { + * return prev ? NULL : &child_class; + * } + * @endcode + * Putting child_next() and child_class_next() as defined above into + * test_class will now make child_struct's options accessible through + * test_struct (again, proper setup as described above needs to be done on + * child_struct right after it is created). + * + * From the above example it might not be clear why both child_next() + * and child_class_next() are needed. The distinction is that child_next() + * iterates over actually existing objects, while child_class_next() + * iterates over all possible child classes. E.g. if an AVCodecContext + * was initialized to use a codec which has private options, then its + * child_next() will return AVCodecContext.priv_data and finish + * iterating. OTOH child_class_next() on AVCodecContext.av_class will + * iterate over all available codecs with private options. + * + * @subsection avoptions_implement_named_constants Named constants + * It is possible to create named constants for options. Simply set the unit + * field of the option the constants should apply to a string and + * create the constants themselves as options of type AV_OPT_TYPE_CONST + * with their unit field set to the same string. + * Their default_val field should contain the value of the named + * constant. + * For example, to add some named constants for the test_flags option + * above, put the following into the child_opts array: + * @code + * { "test_flags", "This is a test option of flags type.", + * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, "test_unit" }, + * { "flag1", "This is a flag with value 16", 0, AV_OPT_TYPE_CONST, { .i64 = 16 }, 0, 0, "test_unit" }, + * @endcode + * + * @section avoptions_use Using AVOptions + * This section deals with accessing options in an AVOptions-enabled struct. + * Such structs in FFmpeg are e.g. AVCodecContext in libavcodec or + * AVFormatContext in libavformat. + * + * @subsection avoptions_use_examine Examining AVOptions + * The basic functions for examining options are av_opt_next(), which iterates + * over all options defined for one object, and av_opt_find(), which searches + * for an option with the given name. + * + * The situation is more complicated with nesting. An AVOptions-enabled struct + * may have AVOptions-enabled children. Passing the AV_OPT_SEARCH_CHILDREN flag + * to av_opt_find() will make the function search children recursively. + * + * For enumerating there are basically two cases. The first is when you want to + * get all options that may potentially exist on the struct and its children + * (e.g. when constructing documentation). In that case you should call + * av_opt_child_class_next() recursively on the parent struct's AVClass. The + * second case is when you have an already initialized struct with all its + * children and you want to get all options that can be actually written or read + * from it. In that case you should call av_opt_child_next() recursively (and + * av_opt_next() on each result). + * + * @subsection avoptions_use_get_set Reading and writing AVOptions + * When setting options, you often have a string read directly from the + * user. In such a case, simply passing it to av_opt_set() is enough. For + * non-string type options, av_opt_set() will parse the string according to the + * option type. + * + * Similarly av_opt_get() will read any option type and convert it to a string + * which will be returned. Do not forget that the string is allocated, so you + * have to free it with av_free(). + * + * In some cases it may be more convenient to put all options into an + * AVDictionary and call av_opt_set_dict() on it. A specific case of this + * are the format/codec open functions in lavf/lavc which take a dictionary + * filled with option as a parameter. This makes it possible to set some options + * that cannot be set otherwise, since e.g. the input file format is not known + * before the file is actually opened. + */ + +enum AVOptionType{ + AV_OPT_TYPE_FLAGS, + AV_OPT_TYPE_INT, + AV_OPT_TYPE_INT64, + AV_OPT_TYPE_DOUBLE, + AV_OPT_TYPE_FLOAT, + AV_OPT_TYPE_STRING, + AV_OPT_TYPE_RATIONAL, + AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length + AV_OPT_TYPE_DICT, + AV_OPT_TYPE_UINT64, + AV_OPT_TYPE_CONST, + AV_OPT_TYPE_IMAGE_SIZE, ///< offset must point to two consecutive integers + AV_OPT_TYPE_PIXEL_FMT, + AV_OPT_TYPE_SAMPLE_FMT, + AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational + AV_OPT_TYPE_DURATION, + AV_OPT_TYPE_COLOR, + AV_OPT_TYPE_CHANNEL_LAYOUT, + AV_OPT_TYPE_BOOL, +}; + +/** + * AVOption + */ +typedef struct AVOption { + const char *name; + + /** + * short English help text + * @todo What about other languages? + */ + const char *help; + + /** + * The offset relative to the context structure where the option + * value is stored. It should be 0 for named constants. + */ + int offset; + enum AVOptionType type; + + /** + * the default value for scalar options + */ + union { + int64_t i64; + double dbl; + const char *str; + /* TODO those are unused now */ + AVRational q; + } default_val; + double min; ///< minimum valid value for the option + double max; ///< maximum valid value for the option + + int flags; +#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding +#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding +#define AV_OPT_FLAG_AUDIO_PARAM 8 +#define AV_OPT_FLAG_VIDEO_PARAM 16 +#define AV_OPT_FLAG_SUBTITLE_PARAM 32 +/** + * The option is intended for exporting values to the caller. + */ +#define AV_OPT_FLAG_EXPORT 64 +/** + * The option may not be set through the AVOptions API, only read. + * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set. + */ +#define AV_OPT_FLAG_READONLY 128 +#define AV_OPT_FLAG_BSF_PARAM (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering +#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering +#define AV_OPT_FLAG_DEPRECATED (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information +//FIXME think about enc-audio, ... style flags + + /** + * The logical unit to which the option belongs. Non-constant + * options and corresponding named constants share the same + * unit. May be NULL. + */ + const char *unit; +} AVOption; + +/** + * A single allowed range of values, or a single allowed value. + */ +typedef struct AVOptionRange { + const char *str; + /** + * Value range. + * For string ranges this represents the min/max length. + * For dimensions this represents the min/max pixel count or width/height in multi-component case. + */ + double value_min, value_max; + /** + * Value's component range. + * For string this represents the unicode range for chars, 0-127 limits to ASCII. + */ + double component_min, component_max; + /** + * Range flag. + * If set to 1 the struct encodes a range, if set to 0 a single value. + */ + int is_range; +} AVOptionRange; + +/** + * List of AVOptionRange structs. + */ +typedef struct AVOptionRanges { + /** + * Array of option ranges. + * + * Most of option types use just one component. + * Following describes multi-component option types: + * + * AV_OPT_TYPE_IMAGE_SIZE: + * component index 0: range of pixel count (width * height). + * component index 1: range of width. + * component index 2: range of height. + * + * @note To obtain multi-component version of this structure, user must + * provide AV_OPT_MULTI_COMPONENT_RANGE to av_opt_query_ranges or + * av_opt_query_ranges_default function. + * + * Multi-component range can be read as in following example: + * + * @code + * int range_index, component_index; + * AVOptionRanges *ranges; + * AVOptionRange *range[3]; //may require more than 3 in the future. + * av_opt_query_ranges(&ranges, obj, key, AV_OPT_MULTI_COMPONENT_RANGE); + * for (range_index = 0; range_index < ranges->nb_ranges; range_index++) { + * for (component_index = 0; component_index < ranges->nb_components; component_index++) + * range[component_index] = ranges->range[ranges->nb_ranges * component_index + range_index]; + * //do something with range here. + * } + * av_opt_freep_ranges(&ranges); + * @endcode + */ + AVOptionRange **range; + /** + * Number of ranges per component. + */ + int nb_ranges; + /** + * Number of componentes. + */ + int nb_components; +} AVOptionRanges; + +/** + * Show the obj options. + * + * @param req_flags requested flags for the options to show. Show only the + * options for which it is opt->flags & req_flags. + * @param rej_flags rejected flags for the options to show. Show only the + * options for which it is !(opt->flags & req_flags). + * @param av_log_obj log context to use for showing the options + */ +int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags); + +/** + * Set the values of all AVOption fields to their default values. + * + * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass) + */ +void av_opt_set_defaults(void *s); + +/** + * Set the values of all AVOption fields to their default values. Only these + * AVOption fields for which (opt->flags & mask) == flags will have their + * default applied to s. + * + * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass) + * @param mask combination of AV_OPT_FLAG_* + * @param flags combination of AV_OPT_FLAG_* + */ +void av_opt_set_defaults2(void *s, int mask, int flags); + +/** + * Parse the key/value pairs list in opts. For each key/value pair + * found, stores the value in the field in ctx that is named like the + * key. ctx must be an AVClass context, storing is done using + * AVOptions. + * + * @param opts options string to parse, may be NULL + * @param key_val_sep a 0-terminated list of characters used to + * separate key from value + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other + * @return the number of successfully set key/value pairs, or a negative + * value corresponding to an AVERROR code in case of error: + * AVERROR(EINVAL) if opts cannot be parsed, + * the error code issued by av_opt_set() if a key/value pair + * cannot be set + */ +int av_set_options_string(void *ctx, const char *opts, + const char *key_val_sep, const char *pairs_sep); + +/** + * Parse the key-value pairs list in opts. For each key=value pair found, + * set the value of the corresponding option in ctx. + * + * @param ctx the AVClass object to set options on + * @param opts the options string, key-value pairs separated by a + * delimiter + * @param shorthand a NULL-terminated array of options names for shorthand + * notation: if the first field in opts has no key part, + * the key is taken from the first element of shorthand; + * then again for the second, etc., until either opts is + * finished, shorthand is finished or a named option is + * found; after that, all options must be named + * @param key_val_sep a 0-terminated list of characters used to separate + * key from value, for example '=' + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other, for example ':' or ',' + * @return the number of successfully set key=value pairs, or a negative + * value corresponding to an AVERROR code in case of error: + * AVERROR(EINVAL) if opts cannot be parsed, + * the error code issued by av_set_string3() if a key/value pair + * cannot be set + * + * Options names must use only the following characters: a-z A-Z 0-9 - . / _ + * Separators must use characters distinct from option names and from each + * other. + */ +int av_opt_set_from_string(void *ctx, const char *opts, + const char *const *shorthand, + const char *key_val_sep, const char *pairs_sep); +/** + * Free all allocated objects in obj. + */ +void av_opt_free(void *obj); + +/** + * Check whether a particular flag is set in a flags field. + * + * @param field_name the name of the flag field option + * @param flag_name the name of the flag to check + * @return non-zero if the flag is set, zero if the flag isn't set, + * isn't of the right type, or the flags field doesn't exist. + */ +int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name); + +/** + * Set all the options from a given dictionary on an object. + * + * @param obj a struct whose first element is a pointer to AVClass + * @param options options to process. This dictionary will be freed and replaced + * by a new one containing all options not found in obj. + * Of course this new dictionary needs to be freed by caller + * with av_dict_free(). + * + * @return 0 on success, a negative AVERROR if some option was found in obj, + * but could not be set. + * + * @see av_dict_copy() + */ +int av_opt_set_dict(void *obj, struct AVDictionary **options); + + +/** + * Set all the options from a given dictionary on an object. + * + * @param obj a struct whose first element is a pointer to AVClass + * @param options options to process. This dictionary will be freed and replaced + * by a new one containing all options not found in obj. + * Of course this new dictionary needs to be freed by caller + * with av_dict_free(). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * + * @return 0 on success, a negative AVERROR if some option was found in obj, + * but could not be set. + * + * @see av_dict_copy() + */ +int av_opt_set_dict2(void *obj, struct AVDictionary **options, int search_flags); + +/** + * Extract a key-value pair from the beginning of a string. + * + * @param ropts pointer to the options string, will be updated to + * point to the rest of the string (one of the pairs_sep + * or the final NUL) + * @param key_val_sep a 0-terminated list of characters used to separate + * key from value, for example '=' + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other, for example ':' or ',' + * @param flags flags; see the AV_OPT_FLAG_* values below + * @param rkey parsed key; must be freed using av_free() + * @param rval parsed value; must be freed using av_free() + * + * @return >=0 for success, or a negative value corresponding to an + * AVERROR code in case of error; in particular: + * AVERROR(EINVAL) if no key is present + * + */ +int av_opt_get_key_value(const char **ropts, + const char *key_val_sep, const char *pairs_sep, + unsigned flags, + char **rkey, char **rval); + +enum { + + /** + * Accept to parse a value without a key; the key will then be returned + * as NULL. + */ + AV_OPT_FLAG_IMPLICIT_KEY = 1, +}; + +/** + * @defgroup opt_eval_funcs Evaluating option strings + * @{ + * This group of functions can be used to evaluate option strings + * and get numbers out of them. They do the same thing as av_opt_set(), + * except the result is written into the caller-supplied pointer. + * + * @param obj a struct whose first element is a pointer to AVClass. + * @param o an option for which the string is to be evaluated. + * @param val string to be evaluated. + * @param *_out value of the string will be written here. + * + * @return 0 on success, a negative number on failure. + */ +int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int *flags_out); +int av_opt_eval_int (void *obj, const AVOption *o, const char *val, int *int_out); +int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t *int64_out); +int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float *float_out); +int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double *double_out); +int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational *q_out); +/** + * @} + */ + +#define AV_OPT_SEARCH_CHILDREN (1 << 0) /**< Search in possible children of the + given object first. */ +/** + * The obj passed to av_opt_find() is fake -- only a double pointer to AVClass + * instead of a required pointer to a struct containing AVClass. This is + * useful for searching for options without needing to allocate the corresponding + * object. + */ +#define AV_OPT_SEARCH_FAKE_OBJ (1 << 1) + +/** + * In av_opt_get, return NULL if the option has a pointer type and is set to NULL, + * rather than returning an empty string. + */ +#define AV_OPT_ALLOW_NULL (1 << 2) + +/** + * Allows av_opt_query_ranges and av_opt_query_ranges_default to return more than + * one component for certain option types. + * @see AVOptionRanges for details. + */ +#define AV_OPT_MULTI_COMPONENT_RANGE (1 << 12) + +/** + * Look for an option in an object. Consider only options which + * have all the specified flags set. + * + * @param[in] obj A pointer to a struct whose first element is a + * pointer to an AVClass. + * Alternatively a double pointer to an AVClass, if + * AV_OPT_SEARCH_FAKE_OBJ search flag is set. + * @param[in] name The name of the option to look for. + * @param[in] unit When searching for named constants, name of the unit + * it belongs to. + * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * + * @return A pointer to the option found, or NULL if no option + * was found. + * + * @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable + * directly with av_opt_set(). Use special calls which take an options + * AVDictionary (e.g. avformat_open_input()) to set options found with this + * flag. + */ +const AVOption *av_opt_find(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags); + +/** + * Look for an option in an object. Consider only options which + * have all the specified flags set. + * + * @param[in] obj A pointer to a struct whose first element is a + * pointer to an AVClass. + * Alternatively a double pointer to an AVClass, if + * AV_OPT_SEARCH_FAKE_OBJ search flag is set. + * @param[in] name The name of the option to look for. + * @param[in] unit When searching for named constants, name of the unit + * it belongs to. + * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * @param[out] target_obj if non-NULL, an object to which the option belongs will be + * written here. It may be different from obj if AV_OPT_SEARCH_CHILDREN is present + * in search_flags. This parameter is ignored if search_flags contain + * AV_OPT_SEARCH_FAKE_OBJ. + * + * @return A pointer to the option found, or NULL if no option + * was found. + */ +const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags, void **target_obj); + +/** + * Iterate over all AVOptions belonging to obj. + * + * @param obj an AVOptions-enabled struct or a double pointer to an + * AVClass describing it. + * @param prev result of the previous call to av_opt_next() on this object + * or NULL + * @return next AVOption or NULL + */ +const AVOption *av_opt_next(const void *obj, const AVOption *prev); + +/** + * Iterate over AVOptions-enabled children of obj. + * + * @param prev result of a previous call to this function or NULL + * @return next AVOptions-enabled child or NULL + */ +void *av_opt_child_next(void *obj, void *prev); + +/** + * Iterate over potential AVOptions-enabled children of parent. + * + * @param prev result of a previous call to this function or NULL + * @return AVClass corresponding to next potential child or NULL + */ +const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev); + +/** + * @defgroup opt_set_funcs Option setting functions + * @{ + * Those functions set the field of obj with the given name to value. + * + * @param[in] obj A struct whose first element is a pointer to an AVClass. + * @param[in] name the name of the field to set + * @param[in] val The value to set. In case of av_opt_set() if the field is not + * of a string type, then the given string is parsed. + * SI postfixes and some named scalars are supported. + * If the field is of a numeric type, it has to be a numeric or named + * scalar. Behavior with more than one scalar and +- infix operators + * is undefined. + * If the field is of a flags type, it has to be a sequence of numeric + * scalars or named flags separated by '+' or '-'. Prefixing a flag + * with '+' causes it to be set without affecting the other flags; + * similarly, '-' unsets a flag. + * @param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN + * is passed here, then the option may be set on a child of obj. + * + * @return 0 if the value has been set, or an AVERROR code in case of + * error: + * AVERROR_OPTION_NOT_FOUND if no matching option exists + * AVERROR(ERANGE) if the value is out of range + * AVERROR(EINVAL) if the value is not valid + */ +int av_opt_set (void *obj, const char *name, const char *val, int search_flags); +int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags); +int av_opt_set_double (void *obj, const char *name, double val, int search_flags); +int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags); +int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags); +int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags); +int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags); +int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags); +int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags); +int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags); +/** + * @note Any old dictionary present is discarded and replaced with a copy of the new one. The + * caller still owns val is and responsible for freeing it. + */ +int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags); + +/** + * Set a binary option to an integer list. + * + * @param obj AVClass object to set options on + * @param name name of the binary option + * @param val pointer to an integer list (must have the correct type with + * regard to the contents of the list) + * @param term list terminator (usually 0 or -1) + * @param flags search flags + */ +#define av_opt_set_int_list(obj, name, val, term, flags) \ + (av_int_list_length(val, term) > INT_MAX / sizeof(*(val)) ? \ + AVERROR(EINVAL) : \ + av_opt_set_bin(obj, name, (const uint8_t *)(val), \ + av_int_list_length(val, term) * sizeof(*(val)), flags)) + +/** + * @} + */ + +/** + * @defgroup opt_get_funcs Option getting functions + * @{ + * Those functions get a value of the option with the given name from an object. + * + * @param[in] obj a struct whose first element is a pointer to an AVClass. + * @param[in] name name of the option to get. + * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN + * is passed here, then the option may be found in a child of obj. + * @param[out] out_val value of the option will be written here + * @return >=0 on success, a negative error code otherwise + */ +/** + * @note the returned string will be av_malloc()ed and must be av_free()ed by the caller + * + * @note if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the option has + * AV_OPT_TYPE_STRING or AV_OPT_TYPE_BINARY and is set to NULL, *out_val will be set + * to NULL instead of an allocated empty string. + */ +int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val); +int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val); +int av_opt_get_double (void *obj, const char *name, int search_flags, double *out_val); +int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val); +int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out); +int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt); +int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt); +int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val); +int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout); +/** + * @param[out] out_val The returned dictionary is a copy of the actual value and must + * be freed with av_dict_free() by the caller + */ +int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val); +/** + * @} + */ +/** + * Gets a pointer to the requested field in a struct. + * This function allows accessing a struct even when its fields are moved or + * renamed since the application making the access has been compiled, + * + * @returns a pointer to the field, it can be cast to the correct type and read + * or written to. + */ +void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name); + +/** + * Free an AVOptionRanges struct and set it to NULL. + */ +void av_opt_freep_ranges(AVOptionRanges **ranges); + +/** + * Get a list of allowed ranges for the given option. + * + * The returned list may depend on other fields in obj like for example profile. + * + * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored + * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance + * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges + * + * The result must be freed with av_opt_freep_ranges. + * + * @return number of compontents returned on success, a negative errro code otherwise + */ +int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags); + +/** + * Copy options from src object into dest object. + * + * Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object. + * Original memory allocated for such options is freed unless both src and dest options points to the same memory. + * + * @param dest Object to copy from + * @param src Object to copy into + * @return 0 on success, negative on error + */ +int av_opt_copy(void *dest, const void *src); + +/** + * Get a default list of allowed ranges for the given option. + * + * This list is constructed without using the AVClass.query_ranges() callback + * and can be used as fallback from within the callback. + * + * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored + * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance + * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges + * + * The result must be freed with av_opt_free_ranges. + * + * @return number of compontents returned on success, a negative errro code otherwise + */ +int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags); + +/** + * Check if given option is set to its default value. + * + * Options o must belong to the obj. This function must not be called to check child's options state. + * @see av_opt_is_set_to_default_by_name(). + * + * @param obj AVClass object to check option on + * @param o option to be checked + * @return >0 when option is set to its default, + * 0 when option is not set its default, + * <0 on error + */ +int av_opt_is_set_to_default(void *obj, const AVOption *o); + +/** + * Check if given option is set to its default value. + * + * @param obj AVClass object to check option on + * @param name option name + * @param search_flags combination of AV_OPT_SEARCH_* + * @return >0 when option is set to its default, + * 0 when option is not set its default, + * <0 on error + */ +int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags); + + +#define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 ///< Serialize options that are not set to default values only. +#define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 ///< Serialize options that exactly match opt_flags only. + +/** + * Serialize object's options. + * + * Create a string containing object's serialized options. + * Such string may be passed back to av_opt_set_from_string() in order to restore option values. + * A key/value or pairs separator occurring in the serialized value or + * name string are escaped through the av_escape() function. + * + * @param[in] obj AVClass object to serialize + * @param[in] opt_flags serialize options with all the specified flags set (AV_OPT_FLAG) + * @param[in] flags combination of AV_OPT_SERIALIZE_* flags + * @param[out] buffer Pointer to buffer that will be allocated with string containg serialized options. + * Buffer must be freed by the caller when is no longer needed. + * @param[in] key_val_sep character used to separate key from value + * @param[in] pairs_sep character used to separate two pairs from each other + * @return >= 0 on success, negative on error + * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same. + */ +int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, + const char key_val_sep, const char pairs_sep); +/** + * @} + */ + +#endif /* AVUTIL_OPT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/parseutils.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/parseutils.c new file mode 100644 index 000000000..167e82264 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/parseutils.c @@ -0,0 +1,786 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * misc parsing utilities + */ + +#include + +#include "avstring.h" +#include "avutil.h" +#include "common.h" +#include "eval.h" +#include "log.h" +#include "random_seed.h" +#include "time_internal.h" +#include "parseutils.h" +#include "time.h" + +#ifdef TEST + +#define av_get_random_seed av_get_random_seed_deterministic +static uint32_t av_get_random_seed_deterministic(void); + +#define av_gettime() 1331972053200000 + +#endif + +int av_parse_ratio(AVRational *q, const char *str, int max, + int log_offset, void *log_ctx) +{ + char c; + int ret; + + if (sscanf(str, "%d:%d%c", &q->num, &q->den, &c) != 2) { + double d; + ret = av_expr_parse_and_eval(&d, str, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, log_offset, log_ctx); + if (ret < 0) + return ret; + *q = av_d2q(d, max); + } else { + av_reduce(&q->num, &q->den, q->num, q->den, max); + } + + return 0; +} + +typedef struct VideoSizeAbbr { + const char *abbr; + int width, height; +} VideoSizeAbbr; + +typedef struct VideoRateAbbr { + const char *abbr; + AVRational rate; +} VideoRateAbbr; + +static const VideoSizeAbbr video_size_abbrs[] = { + { "ntsc", 720, 480 }, + { "pal", 720, 576 }, + { "qntsc", 352, 240 }, /* VCD compliant NTSC */ + { "qpal", 352, 288 }, /* VCD compliant PAL */ + { "sntsc", 640, 480 }, /* square pixel NTSC */ + { "spal", 768, 576 }, /* square pixel PAL */ + { "film", 352, 240 }, + { "ntsc-film", 352, 240 }, + { "sqcif", 128, 96 }, + { "qcif", 176, 144 }, + { "cif", 352, 288 }, + { "4cif", 704, 576 }, + { "16cif", 1408,1152 }, + { "qqvga", 160, 120 }, + { "qvga", 320, 240 }, + { "vga", 640, 480 }, + { "svga", 800, 600 }, + { "xga", 1024, 768 }, + { "uxga", 1600,1200 }, + { "qxga", 2048,1536 }, + { "sxga", 1280,1024 }, + { "qsxga", 2560,2048 }, + { "hsxga", 5120,4096 }, + { "wvga", 852, 480 }, + { "wxga", 1366, 768 }, + { "wsxga", 1600,1024 }, + { "wuxga", 1920,1200 }, + { "woxga", 2560,1600 }, + { "wqsxga", 3200,2048 }, + { "wquxga", 3840,2400 }, + { "whsxga", 6400,4096 }, + { "whuxga", 7680,4800 }, + { "cga", 320, 200 }, + { "ega", 640, 350 }, + { "hd480", 852, 480 }, + { "hd720", 1280, 720 }, + { "hd1080", 1920,1080 }, + { "2k", 2048,1080 }, /* Digital Cinema System Specification */ + { "2kdci", 2048,1080 }, + { "2kflat", 1998,1080 }, + { "2kscope", 2048, 858 }, + { "4k", 4096,2160 }, /* Digital Cinema System Specification */ + { "4kdci", 4096,2160 }, + { "4kflat", 3996,2160 }, + { "4kscope", 4096,1716 }, + { "nhd", 640,360 }, + { "hqvga", 240,160 }, + { "wqvga", 400,240 }, + { "fwqvga", 432,240 }, + { "hvga", 480,320 }, + { "qhd", 960,540 }, + { "uhd2160", 3840,2160 }, + { "uhd4320", 7680,4320 }, +}; + +static const VideoRateAbbr video_rate_abbrs[]= { + { "ntsc", { 30000, 1001 } }, + { "pal", { 25, 1 } }, + { "qntsc", { 30000, 1001 } }, /* VCD compliant NTSC */ + { "qpal", { 25, 1 } }, /* VCD compliant PAL */ + { "sntsc", { 30000, 1001 } }, /* square pixel NTSC */ + { "spal", { 25, 1 } }, /* square pixel PAL */ + { "film", { 24, 1 } }, + { "ntsc-film", { 24000, 1001 } }, +}; + +static const char *months[12] = { + "january", "february", "march", "april", "may", "june", "july", "august", + "september", "october", "november", "december" +}; + +int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str) +{ + int i; + int n = FF_ARRAY_ELEMS(video_size_abbrs); + const char *p; + int width = 0, height = 0; + + for (i = 0; i < n; i++) { + if (!strcmp(video_size_abbrs[i].abbr, str)) { + width = video_size_abbrs[i].width; + height = video_size_abbrs[i].height; + break; + } + } + if (i == n) { + width = strtol(str, (void*)&p, 10); + if (*p) + p++; + height = strtol(p, (void*)&p, 10); + + /* trailing extraneous data detected, like in 123x345foobar */ + if (*p) + return AVERROR(EINVAL); + } + if (width <= 0 || height <= 0) + return AVERROR(EINVAL); + *width_ptr = width; + *height_ptr = height; + return 0; +} + +int av_parse_video_rate(AVRational *rate, const char *arg) +{ + int i, ret; + int n = FF_ARRAY_ELEMS(video_rate_abbrs); + + /* First, we check our abbreviation table */ + for (i = 0; i < n; ++i) + if (!strcmp(video_rate_abbrs[i].abbr, arg)) { + *rate = video_rate_abbrs[i].rate; + return 0; + } + + /* Then, we try to parse it as fraction */ + if ((ret = av_parse_ratio_quiet(rate, arg, 1001000)) < 0) + return ret; + if (rate->num <= 0 || rate->den <= 0) + return AVERROR(EINVAL); + return 0; +} + +typedef struct ColorEntry { + const char *name; ///< a string representing the name of the color + uint8_t rgb_color[3]; ///< RGB values for the color +} ColorEntry; + +static const ColorEntry color_table[] = { + { "AliceBlue", { 0xF0, 0xF8, 0xFF } }, + { "AntiqueWhite", { 0xFA, 0xEB, 0xD7 } }, + { "Aqua", { 0x00, 0xFF, 0xFF } }, + { "Aquamarine", { 0x7F, 0xFF, 0xD4 } }, + { "Azure", { 0xF0, 0xFF, 0xFF } }, + { "Beige", { 0xF5, 0xF5, 0xDC } }, + { "Bisque", { 0xFF, 0xE4, 0xC4 } }, + { "Black", { 0x00, 0x00, 0x00 } }, + { "BlanchedAlmond", { 0xFF, 0xEB, 0xCD } }, + { "Blue", { 0x00, 0x00, 0xFF } }, + { "BlueViolet", { 0x8A, 0x2B, 0xE2 } }, + { "Brown", { 0xA5, 0x2A, 0x2A } }, + { "BurlyWood", { 0xDE, 0xB8, 0x87 } }, + { "CadetBlue", { 0x5F, 0x9E, 0xA0 } }, + { "Chartreuse", { 0x7F, 0xFF, 0x00 } }, + { "Chocolate", { 0xD2, 0x69, 0x1E } }, + { "Coral", { 0xFF, 0x7F, 0x50 } }, + { "CornflowerBlue", { 0x64, 0x95, 0xED } }, + { "Cornsilk", { 0xFF, 0xF8, 0xDC } }, + { "Crimson", { 0xDC, 0x14, 0x3C } }, + { "Cyan", { 0x00, 0xFF, 0xFF } }, + { "DarkBlue", { 0x00, 0x00, 0x8B } }, + { "DarkCyan", { 0x00, 0x8B, 0x8B } }, + { "DarkGoldenRod", { 0xB8, 0x86, 0x0B } }, + { "DarkGray", { 0xA9, 0xA9, 0xA9 } }, + { "DarkGreen", { 0x00, 0x64, 0x00 } }, + { "DarkKhaki", { 0xBD, 0xB7, 0x6B } }, + { "DarkMagenta", { 0x8B, 0x00, 0x8B } }, + { "DarkOliveGreen", { 0x55, 0x6B, 0x2F } }, + { "Darkorange", { 0xFF, 0x8C, 0x00 } }, + { "DarkOrchid", { 0x99, 0x32, 0xCC } }, + { "DarkRed", { 0x8B, 0x00, 0x00 } }, + { "DarkSalmon", { 0xE9, 0x96, 0x7A } }, + { "DarkSeaGreen", { 0x8F, 0xBC, 0x8F } }, + { "DarkSlateBlue", { 0x48, 0x3D, 0x8B } }, + { "DarkSlateGray", { 0x2F, 0x4F, 0x4F } }, + { "DarkTurquoise", { 0x00, 0xCE, 0xD1 } }, + { "DarkViolet", { 0x94, 0x00, 0xD3 } }, + { "DeepPink", { 0xFF, 0x14, 0x93 } }, + { "DeepSkyBlue", { 0x00, 0xBF, 0xFF } }, + { "DimGray", { 0x69, 0x69, 0x69 } }, + { "DodgerBlue", { 0x1E, 0x90, 0xFF } }, + { "FireBrick", { 0xB2, 0x22, 0x22 } }, + { "FloralWhite", { 0xFF, 0xFA, 0xF0 } }, + { "ForestGreen", { 0x22, 0x8B, 0x22 } }, + { "Fuchsia", { 0xFF, 0x00, 0xFF } }, + { "Gainsboro", { 0xDC, 0xDC, 0xDC } }, + { "GhostWhite", { 0xF8, 0xF8, 0xFF } }, + { "Gold", { 0xFF, 0xD7, 0x00 } }, + { "GoldenRod", { 0xDA, 0xA5, 0x20 } }, + { "Gray", { 0x80, 0x80, 0x80 } }, + { "Green", { 0x00, 0x80, 0x00 } }, + { "GreenYellow", { 0xAD, 0xFF, 0x2F } }, + { "HoneyDew", { 0xF0, 0xFF, 0xF0 } }, + { "HotPink", { 0xFF, 0x69, 0xB4 } }, + { "IndianRed", { 0xCD, 0x5C, 0x5C } }, + { "Indigo", { 0x4B, 0x00, 0x82 } }, + { "Ivory", { 0xFF, 0xFF, 0xF0 } }, + { "Khaki", { 0xF0, 0xE6, 0x8C } }, + { "Lavender", { 0xE6, 0xE6, 0xFA } }, + { "LavenderBlush", { 0xFF, 0xF0, 0xF5 } }, + { "LawnGreen", { 0x7C, 0xFC, 0x00 } }, + { "LemonChiffon", { 0xFF, 0xFA, 0xCD } }, + { "LightBlue", { 0xAD, 0xD8, 0xE6 } }, + { "LightCoral", { 0xF0, 0x80, 0x80 } }, + { "LightCyan", { 0xE0, 0xFF, 0xFF } }, + { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } }, + { "LightGreen", { 0x90, 0xEE, 0x90 } }, + { "LightGrey", { 0xD3, 0xD3, 0xD3 } }, + { "LightPink", { 0xFF, 0xB6, 0xC1 } }, + { "LightSalmon", { 0xFF, 0xA0, 0x7A } }, + { "LightSeaGreen", { 0x20, 0xB2, 0xAA } }, + { "LightSkyBlue", { 0x87, 0xCE, 0xFA } }, + { "LightSlateGray", { 0x77, 0x88, 0x99 } }, + { "LightSteelBlue", { 0xB0, 0xC4, 0xDE } }, + { "LightYellow", { 0xFF, 0xFF, 0xE0 } }, + { "Lime", { 0x00, 0xFF, 0x00 } }, + { "LimeGreen", { 0x32, 0xCD, 0x32 } }, + { "Linen", { 0xFA, 0xF0, 0xE6 } }, + { "Magenta", { 0xFF, 0x00, 0xFF } }, + { "Maroon", { 0x80, 0x00, 0x00 } }, + { "MediumAquaMarine", { 0x66, 0xCD, 0xAA } }, + { "MediumBlue", { 0x00, 0x00, 0xCD } }, + { "MediumOrchid", { 0xBA, 0x55, 0xD3 } }, + { "MediumPurple", { 0x93, 0x70, 0xD8 } }, + { "MediumSeaGreen", { 0x3C, 0xB3, 0x71 } }, + { "MediumSlateBlue", { 0x7B, 0x68, 0xEE } }, + { "MediumSpringGreen", { 0x00, 0xFA, 0x9A } }, + { "MediumTurquoise", { 0x48, 0xD1, 0xCC } }, + { "MediumVioletRed", { 0xC7, 0x15, 0x85 } }, + { "MidnightBlue", { 0x19, 0x19, 0x70 } }, + { "MintCream", { 0xF5, 0xFF, 0xFA } }, + { "MistyRose", { 0xFF, 0xE4, 0xE1 } }, + { "Moccasin", { 0xFF, 0xE4, 0xB5 } }, + { "NavajoWhite", { 0xFF, 0xDE, 0xAD } }, + { "Navy", { 0x00, 0x00, 0x80 } }, + { "OldLace", { 0xFD, 0xF5, 0xE6 } }, + { "Olive", { 0x80, 0x80, 0x00 } }, + { "OliveDrab", { 0x6B, 0x8E, 0x23 } }, + { "Orange", { 0xFF, 0xA5, 0x00 } }, + { "OrangeRed", { 0xFF, 0x45, 0x00 } }, + { "Orchid", { 0xDA, 0x70, 0xD6 } }, + { "PaleGoldenRod", { 0xEE, 0xE8, 0xAA } }, + { "PaleGreen", { 0x98, 0xFB, 0x98 } }, + { "PaleTurquoise", { 0xAF, 0xEE, 0xEE } }, + { "PaleVioletRed", { 0xD8, 0x70, 0x93 } }, + { "PapayaWhip", { 0xFF, 0xEF, 0xD5 } }, + { "PeachPuff", { 0xFF, 0xDA, 0xB9 } }, + { "Peru", { 0xCD, 0x85, 0x3F } }, + { "Pink", { 0xFF, 0xC0, 0xCB } }, + { "Plum", { 0xDD, 0xA0, 0xDD } }, + { "PowderBlue", { 0xB0, 0xE0, 0xE6 } }, + { "Purple", { 0x80, 0x00, 0x80 } }, + { "Red", { 0xFF, 0x00, 0x00 } }, + { "RosyBrown", { 0xBC, 0x8F, 0x8F } }, + { "RoyalBlue", { 0x41, 0x69, 0xE1 } }, + { "SaddleBrown", { 0x8B, 0x45, 0x13 } }, + { "Salmon", { 0xFA, 0x80, 0x72 } }, + { "SandyBrown", { 0xF4, 0xA4, 0x60 } }, + { "SeaGreen", { 0x2E, 0x8B, 0x57 } }, + { "SeaShell", { 0xFF, 0xF5, 0xEE } }, + { "Sienna", { 0xA0, 0x52, 0x2D } }, + { "Silver", { 0xC0, 0xC0, 0xC0 } }, + { "SkyBlue", { 0x87, 0xCE, 0xEB } }, + { "SlateBlue", { 0x6A, 0x5A, 0xCD } }, + { "SlateGray", { 0x70, 0x80, 0x90 } }, + { "Snow", { 0xFF, 0xFA, 0xFA } }, + { "SpringGreen", { 0x00, 0xFF, 0x7F } }, + { "SteelBlue", { 0x46, 0x82, 0xB4 } }, + { "Tan", { 0xD2, 0xB4, 0x8C } }, + { "Teal", { 0x00, 0x80, 0x80 } }, + { "Thistle", { 0xD8, 0xBF, 0xD8 } }, + { "Tomato", { 0xFF, 0x63, 0x47 } }, + { "Turquoise", { 0x40, 0xE0, 0xD0 } }, + { "Violet", { 0xEE, 0x82, 0xEE } }, + { "Wheat", { 0xF5, 0xDE, 0xB3 } }, + { "White", { 0xFF, 0xFF, 0xFF } }, + { "WhiteSmoke", { 0xF5, 0xF5, 0xF5 } }, + { "Yellow", { 0xFF, 0xFF, 0x00 } }, + { "YellowGreen", { 0x9A, 0xCD, 0x32 } }, +}; + +static int color_table_compare(const void *lhs, const void *rhs) +{ + return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name); +} + +#define ALPHA_SEP '@' + +int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, + void *log_ctx) +{ + char *tail, color_string2[128]; + const ColorEntry *entry; + int len, hex_offset = 0; + + if (color_string[0] == '#') { + hex_offset = 1; + } else if (!strncmp(color_string, "0x", 2)) + hex_offset = 2; + + if (slen < 0) + slen = strlen(color_string); + av_strlcpy(color_string2, color_string + hex_offset, + FFMIN(slen-hex_offset+1, sizeof(color_string2))); + if ((tail = strchr(color_string2, ALPHA_SEP))) + *tail++ = 0; + len = strlen(color_string2); + rgba_color[3] = 255; + + if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) { + int rgba = av_get_random_seed(); + rgba_color[0] = rgba >> 24; + rgba_color[1] = rgba >> 16; + rgba_color[2] = rgba >> 8; + rgba_color[3] = rgba; + } else if (hex_offset || + strspn(color_string2, "0123456789ABCDEFabcdef") == len) { + char *tail; + unsigned int rgba = strtoul(color_string2, &tail, 16); + + if (*tail || (len != 6 && len != 8)) { + av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2); + return AVERROR(EINVAL); + } + if (len == 8) { + rgba_color[3] = rgba; + rgba >>= 8; + } + rgba_color[0] = rgba >> 16; + rgba_color[1] = rgba >> 8; + rgba_color[2] = rgba; + } else { + entry = bsearch(color_string2, + color_table, + FF_ARRAY_ELEMS(color_table), + sizeof(ColorEntry), + color_table_compare); + if (!entry) { + av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2); + return AVERROR(EINVAL); + } + memcpy(rgba_color, entry->rgb_color, 3); + } + + if (tail) { + double alpha; + const char *alpha_string = tail; + if (!strncmp(alpha_string, "0x", 2)) { + alpha = strtoul(alpha_string, &tail, 16); + } else { + double norm_alpha = strtod(alpha_string, &tail); + if (norm_alpha < 0.0 || norm_alpha > 1.0) + alpha = 256; + else + alpha = 255 * norm_alpha; + } + + if (tail == alpha_string || *tail || alpha > 255 || alpha < 0) { + av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n", + alpha_string, color_string); + return AVERROR(EINVAL); + } + rgba_color[3] = alpha; + } + + return 0; +} + +const char *av_get_known_color_name(int color_idx, const uint8_t **rgbp) +{ + const ColorEntry *color; + + if ((unsigned)color_idx >= FF_ARRAY_ELEMS(color_table)) + return NULL; + + color = &color_table[color_idx]; + if (rgbp) + *rgbp = color->rgb_color; + + return color->name; +} + +/* get a positive number between n_min and n_max, for a maximum length + of len_max. Return -1 if error. */ +static int date_get_num(const char **pp, + int n_min, int n_max, int len_max) +{ + int i, val, c; + const char *p; + + p = *pp; + val = 0; + for(i = 0; i < len_max; i++) { + c = *p; + if (!av_isdigit(c)) + break; + val = (val * 10) + c - '0'; + p++; + } + /* no number read ? */ + if (p == *pp) + return -1; + if (val < n_min || val > n_max) + return -1; + *pp = p; + return val; +} + +static int date_get_month(const char **pp) { + int i = 0; + for (; i < 12; i++) { + if (!av_strncasecmp(*pp, months[i], 3)) { + const char *mo_full = months[i] + 3; + int len = strlen(mo_full); + *pp += 3; + if (len > 0 && !av_strncasecmp(*pp, mo_full, len)) + *pp += len; + return i; + } + } + return -1; +} + +char *av_small_strptime(const char *p, const char *fmt, struct tm *dt) +{ + int c, val; + + while((c = *fmt++)) { + if (c != '%') { + if (av_isspace(c)) + for (; *p && av_isspace(*p); p++); + else if (*p != c) + return NULL; + else p++; + continue; + } + + c = *fmt++; + switch(c) { + case 'H': + case 'J': + val = date_get_num(&p, 0, c == 'H' ? 23 : INT_MAX, c == 'H' ? 2 : 4); + + if (val == -1) + return NULL; + dt->tm_hour = val; + break; + case 'M': + val = date_get_num(&p, 0, 59, 2); + if (val == -1) + return NULL; + dt->tm_min = val; + break; + case 'S': + val = date_get_num(&p, 0, 59, 2); + if (val == -1) + return NULL; + dt->tm_sec = val; + break; + case 'Y': + val = date_get_num(&p, 0, 9999, 4); + if (val == -1) + return NULL; + dt->tm_year = val - 1900; + break; + case 'm': + val = date_get_num(&p, 1, 12, 2); + if (val == -1) + return NULL; + dt->tm_mon = val - 1; + break; + case 'd': + val = date_get_num(&p, 1, 31, 2); + if (val == -1) + return NULL; + dt->tm_mday = val; + break; + case 'T': + p = av_small_strptime(p, "%H:%M:%S", dt); + if (!p) + return NULL; + break; + case 'b': + case 'B': + case 'h': + val = date_get_month(&p); + if (val == -1) + return NULL; + dt->tm_mon = val; + break; + case '%': + if (*p++ != '%') + return NULL; + break; + default: + return NULL; + } + } + + return (char*)p; +} + +time_t av_timegm(struct tm *tm) +{ + time_t t; + + int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday; + + if (m < 3) { + m += 12; + y--; + } + + t = 86400LL * + (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469); + + t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; + + return t; +} + +int av_parse_time(int64_t *timeval, const char *timestr, int duration) +{ + const char *p, *q; + int64_t t, now64; + time_t now; + struct tm dt = { 0 }, tmbuf; + int today = 0, negative = 0, microseconds = 0, suffix = 1000000; + int i; + static const char * const date_fmt[] = { + "%Y - %m - %d", + "%Y%m%d", + }; + static const char * const time_fmt[] = { + "%H:%M:%S", + "%H%M%S", + }; + static const char * const tz_fmt[] = { + "%H:%M", + "%H%M", + "%H", + }; + + p = timestr; + q = NULL; + *timeval = INT64_MIN; + if (!duration) { + now64 = av_gettime(); + now = now64 / 1000000; + + if (!av_strcasecmp(timestr, "now")) { + *timeval = now64; + return 0; + } + + /* parse the year-month-day part */ + for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) { + q = av_small_strptime(p, date_fmt[i], &dt); + if (q) + break; + } + + /* if the year-month-day part is missing, then take the + * current year-month-day time */ + if (!q) { + today = 1; + q = p; + } + p = q; + + if (*p == 'T' || *p == 't') + p++; + else + while (av_isspace(*p)) + p++; + + /* parse the hour-minute-second part */ + for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) { + q = av_small_strptime(p, time_fmt[i], &dt); + if (q) + break; + } + } else { + /* parse timestr as a duration */ + if (p[0] == '-') { + negative = 1; + ++p; + } + /* parse timestr as HH:MM:SS */ + q = av_small_strptime(p, "%J:%M:%S", &dt); + if (!q) { + /* parse timestr as MM:SS */ + q = av_small_strptime(p, "%M:%S", &dt); + dt.tm_hour = 0; + } + if (!q) { + char *o; + /* parse timestr as S+ */ + errno = 0; + t = strtoll(p, &o, 10); + if (o == p) /* the parsing didn't succeed */ + return AVERROR(EINVAL); + if (errno == ERANGE) + return AVERROR(ERANGE); + q = o; + } else { + t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec; + } + } + + /* Now we have all the fields that we can get */ + if (!q) + return AVERROR(EINVAL); + + /* parse the .m... part */ + if (*q == '.') { + int n; + q++; + for (n = 100000; n >= 1; n /= 10, q++) { + if (!av_isdigit(*q)) + break; + microseconds += n * (*q - '0'); + } + while (av_isdigit(*q)) + q++; + } + + if (duration) { + if (q[0] == 'm' && q[1] == 's') { + suffix = 1000; + microseconds /= 1000; + q += 2; + } else if (q[0] == 'u' && q[1] == 's') { + suffix = 1; + microseconds = 0; + q += 2; + } else if (*q == 's') + q++; + } else { + int is_utc = *q == 'Z' || *q == 'z'; + int tzoffset = 0; + q += is_utc; + if (!today && !is_utc && (*q == '+' || *q == '-')) { + struct tm tz = { 0 }; + int sign = (*q == '+' ? -1 : 1); + q++; + p = q; + for (i = 0; i < FF_ARRAY_ELEMS(tz_fmt); i++) { + q = av_small_strptime(p, tz_fmt[i], &tz); + if (q) + break; + } + if (!q) + return AVERROR(EINVAL); + tzoffset = sign * (tz.tm_hour * 60 + tz.tm_min) * 60; + is_utc = 1; + } + if (today) { /* fill in today's date */ + struct tm dt2 = is_utc ? *gmtime_r(&now, &tmbuf) : *localtime_r(&now, &tmbuf); + dt2.tm_hour = dt.tm_hour; + dt2.tm_min = dt.tm_min; + dt2.tm_sec = dt.tm_sec; + dt = dt2; + } + dt.tm_isdst = is_utc ? 0 : -1; + t = is_utc ? av_timegm(&dt) : mktime(&dt); + t += tzoffset; + } + + /* Check that we are at the end of the string */ + if (*q) + return AVERROR(EINVAL); + + if (INT64_MAX / suffix < t) + return AVERROR(ERANGE); + t *= suffix; + if (INT64_MAX - microseconds < t) + return AVERROR(ERANGE); + t += microseconds; + *timeval = negative ? -t : t; + return 0; +} + +int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info) +{ + const char *p; + char tag[128], *q; + + p = info; + if (*p == '?') + p++; + for(;;) { + q = tag; + while (*p != '\0' && *p != '=' && *p != '&') { + if ((q - tag) < sizeof(tag) - 1) + *q++ = *p; + p++; + } + *q = '\0'; + q = arg; + if (*p == '=') { + p++; + while (*p != '&' && *p != '\0') { + if ((q - arg) < arg_size - 1) { + if (*p == '+') + *q++ = ' '; + else + *q++ = *p; + } + p++; + } + } + *q = '\0'; + if (!strcmp(tag, tag1)) + return 1; + if (*p != '&') + break; + p++; + } + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/parseutils.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/parseutils.h new file mode 100644 index 000000000..e66d24b76 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/parseutils.h @@ -0,0 +1,193 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PARSEUTILS_H +#define AVUTIL_PARSEUTILS_H + +#include + +#include "rational.h" + +/** + * @file + * misc parsing utilities + */ + +/** + * Parse str and store the parsed ratio in q. + * + * Note that a ratio with infinite (1/0) or negative value is + * considered valid, so you should check on the returned value if you + * want to exclude those values. + * + * The undefined value can be expressed using the "0:0" string. + * + * @param[in,out] q pointer to the AVRational which will contain the ratio + * @param[in] str the string to parse: it has to be a string in the format + * num:den, a float number or an expression + * @param[in] max the maximum allowed numerator and denominator + * @param[in] log_offset log level offset which is applied to the log + * level of log_ctx + * @param[in] log_ctx parent logging context + * @return >= 0 on success, a negative error code otherwise + */ +int av_parse_ratio(AVRational *q, const char *str, int max, + int log_offset, void *log_ctx); + +#define av_parse_ratio_quiet(rate, str, max) \ + av_parse_ratio(rate, str, max, AV_LOG_MAX_OFFSET, NULL) + +/** + * Parse str and put in width_ptr and height_ptr the detected values. + * + * @param[in,out] width_ptr pointer to the variable which will contain the detected + * width value + * @param[in,out] height_ptr pointer to the variable which will contain the detected + * height value + * @param[in] str the string to parse: it has to be a string in the format + * width x height or a valid video size abbreviation. + * @return >= 0 on success, a negative error code otherwise + */ +int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * Parse str and store the detected values in *rate. + * + * @param[in,out] rate pointer to the AVRational which will contain the detected + * frame rate + * @param[in] str the string to parse: it has to be a string in the format + * rate_num / rate_den, a float number or a valid video rate abbreviation + * @return >= 0 on success, a negative error code otherwise + */ +int av_parse_video_rate(AVRational *rate, const char *str); + +/** + * Put the RGBA values that correspond to color_string in rgba_color. + * + * @param color_string a string specifying a color. It can be the name of + * a color (case insensitive match) or a [0x|#]RRGGBB[AA] sequence, + * possibly followed by "@" and a string representing the alpha + * component. + * The alpha component may be a string composed by "0x" followed by an + * hexadecimal number or a decimal number between 0.0 and 1.0, which + * represents the opacity value (0x00/0.0 means completely transparent, + * 0xff/1.0 completely opaque). + * If the alpha component is not specified then 0xff is assumed. + * The string "random" will result in a random color. + * @param slen length of the initial part of color_string containing the + * color. It can be set to -1 if color_string is a null terminated string + * containing nothing else than the color. + * @return >= 0 in case of success, a negative value in case of + * failure (for example if color_string cannot be parsed). + */ +int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, + void *log_ctx); + +/** + * Get the name of a color from the internal table of hard-coded named + * colors. + * + * This function is meant to enumerate the color names recognized by + * av_parse_color(). + * + * @param color_idx index of the requested color, starting from 0 + * @param rgbp if not NULL, will point to a 3-elements array with the color value in RGB + * @return the color name string or NULL if color_idx is not in the array + */ +const char *av_get_known_color_name(int color_idx, const uint8_t **rgb); + +/** + * Parse timestr and return in *time a corresponding number of + * microseconds. + * + * @param timeval puts here the number of microseconds corresponding + * to the string in timestr. If the string represents a duration, it + * is the number of microseconds contained in the time interval. If + * the string is a date, is the number of microseconds since 1st of + * January, 1970 up to the time of the parsed date. If timestr cannot + * be successfully parsed, set *time to INT64_MIN. + + * @param timestr a string representing a date or a duration. + * - If a date the syntax is: + * @code + * [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH:MM:SS[.m...]]]}|{HHMMSS[.m...]]]}}[Z] + * now + * @endcode + * If the value is "now" it takes the current time. + * Time is local time unless Z is appended, in which case it is + * interpreted as UTC. + * If the year-month-day part is not specified it takes the current + * year-month-day. + * - If a duration the syntax is: + * @code + * [-][HH:]MM:SS[.m...] + * [-]S+[.m...] + * @endcode + * @param duration flag which tells how to interpret timestr, if not + * zero timestr is interpreted as a duration, otherwise as a date + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code otherwise + */ +int av_parse_time(int64_t *timeval, const char *timestr, int duration); + +/** + * Attempt to find a specific tag in a URL. + * + * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. + * Return 1 if found. + */ +int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); + +/** + * Simplified version of strptime + * + * Parse the input string p according to the format string fmt and + * store its results in the structure dt. + * This implementation supports only a subset of the formats supported + * by the standard strptime(). + * + * The supported input field descriptors are listed below. + * - %H: the hour as a decimal number, using a 24-hour clock, in the + * range '00' through '23' + * - %J: hours as a decimal number, in the range '0' through INT_MAX + * - %M: the minute as a decimal number, using a 24-hour clock, in the + * range '00' through '59' + * - %S: the second as a decimal number, using a 24-hour clock, in the + * range '00' through '59' + * - %Y: the year as a decimal number, using the Gregorian calendar + * - %m: the month as a decimal number, in the range '1' through '12' + * - %d: the day of the month as a decimal number, in the range '1' + * through '31' + * - %T: alias for '%H:%M:%S' + * - %%: a literal '%' + * + * @return a pointer to the first character not processed in this function + * call. In case the input string contains more characters than + * required by the format string the return value points right after + * the last consumed input character. In case the whole input string + * is consumed the return value points to the null byte at the end of + * the string. On failure NULL is returned. + */ +char *av_small_strptime(const char *p, const char *fmt, struct tm *dt); + +/** + * Convert the decomposed UTC time in tm to a time_t value. + */ +time_t av_timegm(struct tm *tm); + +#endif /* AVUTIL_PARSEUTILS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixdesc.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixdesc.c new file mode 100644 index 000000000..b97b0665b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixdesc.c @@ -0,0 +1,2961 @@ +/* + * pixel format descriptor + * Copyright (c) 2009 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "avassert.h" +#include "avstring.h" +#include "common.h" +#include "pixfmt.h" +#include "pixdesc.h" +#include "internal.h" +#include "intreadwrite.h" +#include "version.h" + +void av_read_image_line2(void *dst, + const uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, + int read_pal_component, + int dst_element_size) +{ + AVComponentDescriptor comp = desc->comp[c]; + int plane = comp.plane; + int depth = comp.depth; + unsigned mask = (1ULL << depth) - 1; + int shift = comp.shift; + int step = comp.step; + int flags = desc->flags; + uint16_t *dst16 = dst; + uint32_t *dst32 = dst; + + if (flags & AV_PIX_FMT_FLAG_BITSTREAM) { + int skip = x * step + comp.offset; + const uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3); + int shift = 8 - depth - (skip & 7); + + while (w--) { + int val = (*p >> shift) & mask; + if (read_pal_component) + val = data[1][4*val + c]; + shift -= step; + p -= shift >> 3; + shift &= 7; + if (dst_element_size == 4) *dst32++ = val; + else *dst16++ = val; + } + } else { + const uint8_t *p = data[plane] + y * linesize[plane] + + x * step + comp.offset; + int is_8bit = shift + depth <= 8; + int is_16bit= shift + depth <=16; + + if (is_8bit) + p += !!(flags & AV_PIX_FMT_FLAG_BE); + + while (w--) { + unsigned val; + if (is_8bit) val = *p; + else if(is_16bit) val = flags & AV_PIX_FMT_FLAG_BE ? AV_RB16(p) : AV_RL16(p); + else val = flags & AV_PIX_FMT_FLAG_BE ? AV_RB32(p) : AV_RL32(p); + val = (val >> shift) & mask; + if (read_pal_component) + val = data[1][4 * val + c]; + p += step; + if (dst_element_size == 4) *dst32++ = val; + else *dst16++ = val; + } + } +} + +void av_read_image_line(uint16_t *dst, + const uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, + int read_pal_component) +{ + av_read_image_line2(dst, data, linesize, desc,x, y, c, w, + read_pal_component, + 2); +} + +void av_write_image_line2(const void *src, + uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int src_element_size) +{ + AVComponentDescriptor comp = desc->comp[c]; + int plane = comp.plane; + int depth = comp.depth; + int step = comp.step; + int flags = desc->flags; + const uint32_t *src32 = src; + const uint16_t *src16 = src; + + if (flags & AV_PIX_FMT_FLAG_BITSTREAM) { + int skip = x * step + comp.offset; + uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3); + int shift = 8 - depth - (skip & 7); + + while (w--) { + *p |= (src_element_size == 4 ? *src32++ : *src16++) << shift; + shift -= step; + p -= shift >> 3; + shift &= 7; + } + } else { + int shift = comp.shift; + uint8_t *p = data[plane] + y * linesize[plane] + + x * step + comp.offset; + + if (shift + depth <= 8) { + p += !!(flags & AV_PIX_FMT_FLAG_BE); + while (w--) { + *p |= ((src_element_size == 4 ? *src32++ : *src16++) << shift); + p += step; + } + } else { + while (w--) { + unsigned s = (src_element_size == 4 ? *src32++ : *src16++); + if (shift + depth <= 16) { + if (flags & AV_PIX_FMT_FLAG_BE) { + uint16_t val = AV_RB16(p) | (s << shift); + AV_WB16(p, val); + } else { + uint16_t val = AV_RL16(p) | (s << shift); + AV_WL16(p, val); + } + } else { + if (flags & AV_PIX_FMT_FLAG_BE) { + uint32_t val = AV_RB32(p) | (s << shift); + AV_WB32(p, val); + } else { + uint32_t val = AV_RL32(p) | (s << shift); + AV_WL32(p, val); + } + } + p += step; + } + } + } +} + +void av_write_image_line(const uint16_t *src, + uint8_t *data[4], const int linesize[4], + const AVPixFmtDescriptor *desc, + int x, int y, int c, int w) +{ + av_write_image_line2(src, data, linesize, desc, x, y, c, w, 2); +} + +#if FF_API_PLUS1_MINUS1 +FF_DISABLE_DEPRECATION_WARNINGS +#endif +static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { + [AV_PIX_FMT_YUV420P] = { + .name = "yuv420p", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUYV422] = { + .name = "yuyv422", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 8, 1, 7, 1 }, /* Y */ + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* U */ + { 0, 4, 3, 0, 8, 3, 7, 4 }, /* V */ + }, + }, + [AV_PIX_FMT_YVYU422] = { + .name = "yvyu422", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 8, 1, 7, 1 }, /* Y */ + { 0, 4, 3, 0, 8, 3, 7, 4 }, /* U */ + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* V */ + }, + }, + [AV_PIX_FMT_RGB24] = { + .name = "rgb24", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 3, 0, 0, 8, 2, 7, 1 }, /* R */ + { 0, 3, 1, 0, 8, 2, 7, 2 }, /* G */ + { 0, 3, 2, 0, 8, 2, 7, 3 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR24] = { + .name = "bgr24", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 3, 2, 0, 8, 2, 7, 3 }, /* R */ + { 0, 3, 1, 0, 8, 2, 7, 2 }, /* G */ + { 0, 3, 0, 0, 8, 2, 7, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_YUV422P] = { + .name = "yuv422p", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P] = { + .name = "yuv444p", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV410P] = { + .name = "yuv410p", + .nb_components = 3, + .log2_chroma_w = 2, + .log2_chroma_h = 2, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV411P] = { + .name = "yuv411p", + .nb_components = 3, + .log2_chroma_w = 2, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVJ411P] = { + .name = "yuvj411p", + .nb_components = 3, + .log2_chroma_w = 2, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_GRAY8] = { + .name = "gray", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + }, + .flags = FF_PSEUDOPAL, + .alias = "gray8,y8", + }, + [AV_PIX_FMT_MONOWHITE] = { + .name = "monow", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 1, 0, 0, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BITSTREAM, + }, + [AV_PIX_FMT_MONOBLACK] = { + .name = "monob", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 7, 1, 0, 0, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BITSTREAM, + }, + [AV_PIX_FMT_PAL8] = { + .name = "pal8", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, + }, + .flags = AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVJ420P] = { + .name = "yuvj420p", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVJ422P] = { + .name = "yuvj422p", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVJ444P] = { + .name = "yuvj444p", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_XVMC] = { + .name = "xvmc", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_UYVY422] = { + .name = "uyvy422", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 1, 0, 8, 1, 7, 2 }, /* Y */ + { 0, 4, 0, 0, 8, 3, 7, 1 }, /* U */ + { 0, 4, 2, 0, 8, 3, 7, 3 }, /* V */ + }, + }, + [AV_PIX_FMT_UYYVYY411] = { + .name = "uyyvyy411", + .nb_components = 3, + .log2_chroma_w = 2, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* Y */ + { 0, 6, 0, 0, 8, 5, 7, 1 }, /* U */ + { 0, 6, 3, 0, 8, 5, 7, 4 }, /* V */ + }, + }, + [AV_PIX_FMT_BGR8] = { + .name = "bgr8", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 3, 0, 2, 1 }, /* R */ + { 0, 1, 0, 3, 3, 0, 2, 1 }, /* G */ + { 0, 1, 0, 6, 2, 0, 1, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, + }, + [AV_PIX_FMT_BGR4] = { + .name = "bgr4", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 3, 0, 1, 3, 0, 4 }, /* R */ + { 0, 4, 1, 0, 2, 3, 1, 2 }, /* G */ + { 0, 4, 0, 0, 1, 3, 0, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR4_BYTE] = { + .name = "bgr4_byte", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 1, 0, 0, 1 }, /* R */ + { 0, 1, 0, 1, 2, 0, 1, 1 }, /* G */ + { 0, 1, 0, 3, 1, 0, 0, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, + }, + [AV_PIX_FMT_RGB8] = { + .name = "rgb8", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 6, 2, 0, 1, 1 }, /* R */ + { 0, 1, 0, 3, 3, 0, 2, 1 }, /* G */ + { 0, 1, 0, 0, 3, 0, 2, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, + }, + [AV_PIX_FMT_RGB4] = { + .name = "rgb4", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 0, 1, 3, 0, 1 }, /* R */ + { 0, 4, 1, 0, 2, 3, 1, 2 }, /* G */ + { 0, 4, 3, 0, 1, 3, 0, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB4_BYTE] = { + .name = "rgb4_byte", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 3, 1, 0, 0, 1 }, /* R */ + { 0, 1, 0, 1, 2, 0, 1, 1 }, /* G */ + { 0, 1, 0, 0, 1, 0, 0, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | FF_PSEUDOPAL, + }, + [AV_PIX_FMT_NV12] = { + .name = "nv12", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 2, 0, 0, 8, 1, 7, 1 }, /* U */ + { 1, 2, 1, 0, 8, 1, 7, 2 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_NV21] = { + .name = "nv21", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 2, 1, 0, 8, 1, 7, 2 }, /* U */ + { 1, 2, 0, 0, 8, 1, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_ARGB] = { + .name = "argb", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* R */ + { 0, 4, 2, 0, 8, 3, 7, 3 }, /* G */ + { 0, 4, 3, 0, 8, 3, 7, 4 }, /* B */ + { 0, 4, 0, 0, 8, 3, 7, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_RGBA] = { + .name = "rgba", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 0, 8, 3, 7, 1 }, /* R */ + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* G */ + { 0, 4, 2, 0, 8, 3, 7, 3 }, /* B */ + { 0, 4, 3, 0, 8, 3, 7, 4 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_ABGR] = { + .name = "abgr", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 3, 0, 8, 3, 7, 4 }, /* R */ + { 0, 4, 2, 0, 8, 3, 7, 3 }, /* G */ + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* B */ + { 0, 4, 0, 0, 8, 3, 7, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_BGRA] = { + .name = "bgra", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 2, 0, 8, 3, 7, 3 }, /* R */ + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* G */ + { 0, 4, 0, 0, 8, 3, 7, 1 }, /* B */ + { 0, 4, 3, 0, 8, 3, 7, 4 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_0RGB] = { + .name = "0rgb", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* R */ + { 0, 4, 2, 0, 8, 3, 7, 3 }, /* G */ + { 0, 4, 3, 0, 8, 3, 7, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB0] = { + .name = "rgb0", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 0, 0, 8, 3, 7, 1 }, /* R */ + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* G */ + { 0, 4, 2, 0, 8, 3, 7, 3 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_0BGR] = { + .name = "0bgr", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 3, 0, 8, 3, 7, 4 }, /* R */ + { 0, 4, 2, 0, 8, 3, 7, 3 }, /* G */ + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR0] = { + .name = "bgr0", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 2, 0, 8, 3, 7, 3 }, /* R */ + { 0, 4, 1, 0, 8, 3, 7, 2 }, /* G */ + { 0, 4, 0, 0, 8, 3, 7, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GRAY9BE] = { + .name = "gray9be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y9be", + }, + [AV_PIX_FMT_GRAY9LE] = { + .name = "gray9le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + }, + .alias = "y9le", + }, + [AV_PIX_FMT_GRAY10BE] = { + .name = "gray10be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y10be", + }, + [AV_PIX_FMT_GRAY10LE] = { + .name = "gray10le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + }, + .alias = "y10le", + }, + [AV_PIX_FMT_GRAY12BE] = { + .name = "gray12be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y12be", + }, + [AV_PIX_FMT_GRAY12LE] = { + .name = "gray12le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + }, + .alias = "y12le", + }, + [AV_PIX_FMT_GRAY14BE] = { + .name = "gray14be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y14be", + }, + [AV_PIX_FMT_GRAY14LE] = { + .name = "gray14le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* Y */ + }, + .alias = "y14le", + }, + [AV_PIX_FMT_GRAY16BE] = { + .name = "gray16be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + .alias = "y16be", + }, + [AV_PIX_FMT_GRAY16LE] = { + .name = "gray16le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + }, + .alias = "y16le", + }, + [AV_PIX_FMT_YUV440P] = { + .name = "yuv440p", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVJ440P] = { + .name = "yuvj440p", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV440P10LE] = { + .name = "yuv440p10le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV440P10BE] = { + .name = "yuv440p10be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV440P12LE] = { + .name = "yuv440p12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV440P12BE] = { + .name = "yuv440p12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUVA420P] = { + .name = "yuva420p", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + { 3, 1, 0, 0, 8, 0, 7, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P] = { + .name = "yuva422p", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + { 3, 1, 0, 0, 8, 0, 7, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P] = { + .name = "yuva444p", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* U */ + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* V */ + { 3, 1, 0, 0, 8, 0, 7, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P9BE] = { + .name = "yuva420p9be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + { 3, 2, 0, 0, 9, 1, 8, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P9LE] = { + .name = "yuva420p9le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + { 3, 2, 0, 0, 9, 1, 8, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P9BE] = { + .name = "yuva422p9be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + { 3, 2, 0, 0, 9, 1, 8, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P9LE] = { + .name = "yuva422p9le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + { 3, 2, 0, 0, 9, 1, 8, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P9BE] = { + .name = "yuva444p9be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + { 3, 2, 0, 0, 9, 1, 8, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P9LE] = { + .name = "yuva444p9le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + { 3, 2, 0, 0, 9, 1, 8, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P10BE] = { + .name = "yuva420p10be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + { 3, 2, 0, 0, 10, 1, 9, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P10LE] = { + .name = "yuva420p10le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + { 3, 2, 0, 0, 10, 1, 9, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P10BE] = { + .name = "yuva422p10be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + { 3, 2, 0, 0, 10, 1, 9, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P10LE] = { + .name = "yuva422p10le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + { 3, 2, 0, 0, 10, 1, 9, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P10BE] = { + .name = "yuva444p10be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + { 3, 2, 0, 0, 10, 1, 9, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P10LE] = { + .name = "yuva444p10le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + { 3, 2, 0, 0, 10, 1, 9, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P16BE] = { + .name = "yuva420p16be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + { 3, 2, 0, 0, 16, 1, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA420P16LE] = { + .name = "yuva420p16le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + { 3, 2, 0, 0, 16, 1, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P16BE] = { + .name = "yuva422p16be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + { 3, 2, 0, 0, 16, 1, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P16LE] = { + .name = "yuva422p16le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + { 3, 2, 0, 0, 16, 1, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P16BE] = { + .name = "yuva444p16be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + { 3, 2, 0, 0, 16, 1, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P16LE] = { + .name = "yuva444p16le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + { 3, 2, 0, 0, 16, 1, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_RGB48BE] = { + .name = "rgb48be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 0, 0, 16, 5, 15, 1 }, /* R */ + { 0, 6, 2, 0, 16, 5, 15, 3 }, /* G */ + { 0, 6, 4, 0, 16, 5, 15, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_RGB48LE] = { + .name = "rgb48le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 0, 0, 16, 5, 15, 1 }, /* R */ + { 0, 6, 2, 0, 16, 5, 15, 3 }, /* G */ + { 0, 6, 4, 0, 16, 5, 15, 5 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGBA64BE] = { + .name = "rgba64be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 0, 0, 16, 7, 15, 1 }, /* R */ + { 0, 8, 2, 0, 16, 7, 15, 3 }, /* G */ + { 0, 8, 4, 0, 16, 7, 15, 5 }, /* B */ + { 0, 8, 6, 0, 16, 7, 15, 7 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_RGBA64LE] = { + .name = "rgba64le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 0, 0, 16, 7, 15, 1 }, /* R */ + { 0, 8, 2, 0, 16, 7, 15, 3 }, /* G */ + { 0, 8, 4, 0, 16, 7, 15, 5 }, /* B */ + { 0, 8, 6, 0, 16, 7, 15, 7 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_RGB565BE] = { + .name = "rgb565be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, -1, 3, 5, 1, 4, 0 }, /* R */ + { 0, 2, 0, 5, 6, 1, 5, 1 }, /* G */ + { 0, 2, 0, 0, 5, 1, 4, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB565LE] = { + .name = "rgb565le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 1, 3, 5, 1, 4, 2 }, /* R */ + { 0, 2, 0, 5, 6, 1, 5, 1 }, /* G */ + { 0, 2, 0, 0, 5, 1, 4, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB555BE] = { + .name = "rgb555be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, -1, 2, 5, 1, 4, 0 }, /* R */ + { 0, 2, 0, 5, 5, 1, 4, 1 }, /* G */ + { 0, 2, 0, 0, 5, 1, 4, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB555LE] = { + .name = "rgb555le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 1, 2, 5, 1, 4, 2 }, /* R */ + { 0, 2, 0, 5, 5, 1, 4, 1 }, /* G */ + { 0, 2, 0, 0, 5, 1, 4, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB444BE] = { + .name = "rgb444be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, -1, 0, 4, 1, 3, 0 }, /* R */ + { 0, 2, 0, 4, 4, 1, 3, 1 }, /* G */ + { 0, 2, 0, 0, 4, 1, 3, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_RGB444LE] = { + .name = "rgb444le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 1, 0, 4, 1, 3, 2 }, /* R */ + { 0, 2, 0, 4, 4, 1, 3, 1 }, /* G */ + { 0, 2, 0, 0, 4, 1, 3, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR48BE] = { + .name = "bgr48be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 4, 0, 16, 5, 15, 5 }, /* R */ + { 0, 6, 2, 0, 16, 5, 15, 3 }, /* G */ + { 0, 6, 0, 0, 16, 5, 15, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR48LE] = { + .name = "bgr48le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 4, 0, 16, 5, 15, 5 }, /* R */ + { 0, 6, 2, 0, 16, 5, 15, 3 }, /* G */ + { 0, 6, 0, 0, 16, 5, 15, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGRA64BE] = { + .name = "bgra64be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 4, 0, 16, 7, 15, 5 }, /* R */ + { 0, 8, 2, 0, 16, 7, 15, 3 }, /* G */ + { 0, 8, 0, 0, 16, 7, 15, 1 }, /* B */ + { 0, 8, 6, 0, 16, 7, 15, 7 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_BGRA64LE] = { + .name = "bgra64le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 4, 0, 16, 7, 15, 5 }, /* R */ + { 0, 8, 2, 0, 16, 7, 15, 3 }, /* G */ + { 0, 8, 0, 0, 16, 7, 15, 1 }, /* B */ + { 0, 8, 6, 0, 16, 7, 15, 7 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_BGR565BE] = { + .name = "bgr565be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 5, 1, 4, 1 }, /* R */ + { 0, 2, 0, 5, 6, 1, 5, 1 }, /* G */ + { 0, 2, -1, 3, 5, 1, 4, 0 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR565LE] = { + .name = "bgr565le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 5, 1, 4, 1 }, /* R */ + { 0, 2, 0, 5, 6, 1, 5, 1 }, /* G */ + { 0, 2, 1, 3, 5, 1, 4, 2 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR555BE] = { + .name = "bgr555be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 5, 1, 4, 1 }, /* R */ + { 0, 2, 0, 5, 5, 1, 4, 1 }, /* G */ + { 0, 2, -1, 2, 5, 1, 4, 0 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR555LE] = { + .name = "bgr555le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 5, 1, 4, 1 }, /* R */ + { 0, 2, 0, 5, 5, 1, 4, 1 }, /* G */ + { 0, 2, 1, 2, 5, 1, 4, 2 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR444BE] = { + .name = "bgr444be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 4, 1, 3, 1 }, /* R */ + { 0, 2, 0, 4, 4, 1, 3, 1 }, /* G */ + { 0, 2, -1, 0, 4, 1, 3, 0 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_BGR444LE] = { + .name = "bgr444le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 4, 1, 3, 1 }, /* R */ + { 0, 2, 0, 4, 4, 1, 3, 1 }, /* G */ + { 0, 2, 1, 0, 4, 1, 3, 2 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, +#if FF_API_VAAPI + [AV_PIX_FMT_VAAPI_MOCO] = { + .name = "vaapi_moco", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_VAAPI_IDCT] = { + .name = "vaapi_idct", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_VAAPI_VLD] = { + .name = "vaapi_vld", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, +#else + [AV_PIX_FMT_VAAPI] = { + .name = "vaapi", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, +#endif + [AV_PIX_FMT_YUV420P9LE] = { + .name = "yuv420p9le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P9BE] = { + .name = "yuv420p9be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P10LE] = { + .name = "yuv420p10le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P10BE] = { + .name = "yuv420p10be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P12LE] = { + .name = "yuv420p12le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P12BE] = { + .name = "yuv420p12be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P14LE] = { + .name = "yuv420p14le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* Y */ + { 1, 2, 0, 0, 14, 1, 13, 1 }, /* U */ + { 2, 2, 0, 0, 14, 1, 13, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P14BE] = { + .name = "yuv420p14be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* Y */ + { 1, 2, 0, 0, 14, 1, 13, 1 }, /* U */ + { 2, 2, 0, 0, 14, 1, 13, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P16LE] = { + .name = "yuv420p16le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV420P16BE] = { + .name = "yuv420p16be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P9LE] = { + .name = "yuv422p9le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P9BE] = { + .name = "yuv422p9be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P10LE] = { + .name = "yuv422p10le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P10BE] = { + .name = "yuv422p10be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P12LE] = { + .name = "yuv422p12le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P12BE] = { + .name = "yuv422p12be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P14LE] = { + .name = "yuv422p14le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* Y */ + { 1, 2, 0, 0, 14, 1, 13, 1 }, /* U */ + { 2, 2, 0, 0, 14, 1, 13, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P14BE] = { + .name = "yuv422p14be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* Y */ + { 1, 2, 0, 0, 14, 1, 13, 1 }, /* U */ + { 2, 2, 0, 0, 14, 1, 13, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P16LE] = { + .name = "yuv422p16le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV422P16BE] = { + .name = "yuv422p16be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P16LE] = { + .name = "yuv444p16le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P16BE] = { + .name = "yuv444p16be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* U */ + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P10LE] = { + .name = "yuv444p10le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P10BE] = { + .name = "yuv444p10be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* U */ + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P9LE] = { + .name = "yuv444p9le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P9BE] = { + .name = "yuv444p9be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* Y */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* U */ + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P12LE] = { + .name = "yuv444p12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P12BE] = { + .name = "yuv444p12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P14LE] = { + .name = "yuv444p14le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* Y */ + { 1, 2, 0, 0, 14, 1, 13, 1 }, /* U */ + { 2, 2, 0, 0, 14, 1, 13, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_YUV444P14BE] = { + .name = "yuv444p14be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* Y */ + { 1, 2, 0, 0, 14, 1, 13, 1 }, /* U */ + { 2, 2, 0, 0, 14, 1, 13, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_D3D11VA_VLD] = { + .name = "d3d11va_vld", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_DXVA2_VLD] = { + .name = "dxva2_vld", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_YA8] = { + .name = "ya8", + .nb_components = 2, + .comp = { + { 0, 2, 0, 0, 8, 1, 7, 1 }, /* Y */ + { 0, 2, 1, 0, 8, 1, 7, 2 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_ALPHA, + .alias = "gray8a", + }, + [AV_PIX_FMT_YA16LE] = { + .name = "ya16le", + .nb_components = 2, + .comp = { + { 0, 4, 0, 0, 16, 3, 15, 1 }, /* Y */ + { 0, 4, 2, 0, 16, 3, 15, 3 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YA16BE] = { + .name = "ya16be", + .nb_components = 2, + .comp = { + { 0, 4, 0, 0, 16, 3, 15, 1 }, /* Y */ + { 0, 4, 2, 0, 16, 3, 15, 3 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_VIDEOTOOLBOX] = { + .name = "videotoolbox_vld", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_GBRP] = { + .name = "gbrp", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* R */ + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* G */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP9LE] = { + .name = "gbrp9le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* R */ + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* G */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP9BE] = { + .name = "gbrp9be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 9, 1, 8, 1 }, /* R */ + { 0, 2, 0, 0, 9, 1, 8, 1 }, /* G */ + { 1, 2, 0, 0, 9, 1, 8, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP10LE] = { + .name = "gbrp10le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* R */ + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* G */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP10BE] = { + .name = "gbrp10be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* R */ + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* G */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP12LE] = { + .name = "gbrp12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* R */ + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* G */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP12BE] = { + .name = "gbrp12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* R */ + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* G */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP14LE] = { + .name = "gbrp14le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 14, 1, 13, 1 }, /* R */ + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* G */ + { 1, 2, 0, 0, 14, 1, 13, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP14BE] = { + .name = "gbrp14be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 14, 1, 13, 1 }, /* R */ + { 0, 2, 0, 0, 14, 1, 13, 1 }, /* G */ + { 1, 2, 0, 0, 14, 1, 13, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP16LE] = { + .name = "gbrp16le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* R */ + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* G */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRP16BE] = { + .name = "gbrp16be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* R */ + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* G */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRAP] = { + .name = "gbrap", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 1, 0, 0, 8, 0, 7, 1 }, /* R */ + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* G */ + { 1, 1, 0, 0, 8, 0, 7, 1 }, /* B */ + { 3, 1, 0, 0, 8, 0, 7, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP16LE] = { + .name = "gbrap16le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* R */ + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* G */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* B */ + { 3, 2, 0, 0, 16, 1, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP16BE] = { + .name = "gbrap16be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 16, 1, 15, 1 }, /* R */ + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* G */ + { 1, 2, 0, 0, 16, 1, 15, 1 }, /* B */ + { 3, 2, 0, 0, 16, 1, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_VDPAU] = { + .name = "vdpau", + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_XYZ12LE] = { + .name = "xyz12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 0, 4, 12, 5, 11, 1 }, /* X */ + { 0, 6, 2, 4, 12, 5, 11, 3 }, /* Y */ + { 0, 6, 4, 4, 12, 5, 11, 5 }, /* Z */ + }, + /*.flags = -- not used*/ + }, + [AV_PIX_FMT_XYZ12BE] = { + .name = "xyz12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 6, 0, 4, 12, 5, 11, 1 }, /* X */ + { 0, 6, 2, 4, 12, 5, 11, 3 }, /* Y */ + { 0, 6, 4, 4, 12, 5, 11, 5 }, /* Z */ + }, + .flags = AV_PIX_FMT_FLAG_BE, + }, + +#define BAYER8_DESC_COMMON \ + .nb_components= 3, \ + .log2_chroma_w= 0, \ + .log2_chroma_h= 0, \ + .comp = { \ + {0,1,0,0,2,0,1,1},\ + {0,1,0,0,4,0,3,1},\ + {0,1,0,0,2,0,1,1},\ + }, \ + +#define BAYER16_DESC_COMMON \ + .nb_components= 3, \ + .log2_chroma_w= 0, \ + .log2_chroma_h= 0, \ + .comp = { \ + {0,2,0,0,4,1,3,1},\ + {0,2,0,0,8,1,7,1},\ + {0,2,0,0,4,1,3,1},\ + }, \ + + [AV_PIX_FMT_BAYER_BGGR8] = { + .name = "bayer_bggr8", + BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_BGGR16LE] = { + .name = "bayer_bggr16le", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_BGGR16BE] = { + .name = "bayer_bggr16be", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_RGGB8] = { + .name = "bayer_rggb8", + BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_RGGB16LE] = { + .name = "bayer_rggb16le", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_RGGB16BE] = { + .name = "bayer_rggb16be", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GBRG8] = { + .name = "bayer_gbrg8", + BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GBRG16LE] = { + .name = "bayer_gbrg16le", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GBRG16BE] = { + .name = "bayer_gbrg16be", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GRBG8] = { + .name = "bayer_grbg8", + BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GRBG16LE] = { + .name = "bayer_grbg16le", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_BAYER_GRBG16BE] = { + .name = "bayer_grbg16be", + BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BAYER, + }, + [AV_PIX_FMT_NV16] = { + .name = "nv16", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 2, 0, 0, 8, 1, 7, 1 }, /* U */ + { 1, 2, 1, 0, 8, 1, 7, 2 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_NV20LE] = { + .name = "nv20le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 4, 0, 0, 10, 3, 9, 1 }, /* U */ + { 1, 4, 2, 0, 10, 3, 9, 3 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_NV20BE] = { + .name = "nv20be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* Y */ + { 1, 4, 0, 0, 10, 3, 9, 1 }, /* U */ + { 1, 4, 2, 0, 10, 3, 9, 3 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_QSV] = { + .name = "qsv", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_MEDIACODEC] = { + .name = "mediacodec", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_MMAL] = { + .name = "mmal", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_CUDA] = { + .name = "cuda", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_AYUV64LE] = { + .name = "ayuv64le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 2, 0, 16, 7, 15, 3 }, /* Y */ + { 0, 8, 4, 0, 16, 7, 15, 5 }, /* U */ + { 0, 8, 6, 0, 16, 7, 15, 7 }, /* V */ + { 0, 8, 0, 0, 16, 7, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_AYUV64BE] = { + .name = "ayuv64be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 8, 2, 0, 16, 7, 15, 3 }, /* Y */ + { 0, 8, 4, 0, 16, 7, 15, 5 }, /* U */ + { 0, 8, 6, 0, 16, 7, 15, 7 }, /* V */ + { 0, 8, 0, 0, 16, 7, 15, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_P010LE] = { + .name = "p010le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 6, 10, 1, 9, 1 }, /* Y */ + { 1, 4, 0, 6, 10, 3, 9, 1 }, /* U */ + { 1, 4, 2, 6, 10, 3, 9, 3 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_P010BE] = { + .name = "p010be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 6, 10, 1, 9, 1 }, /* Y */ + { 1, 4, 0, 6, 10, 3, 9, 1 }, /* U */ + { 1, 4, 2, 6, 10, 3, 9, 3 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_P016LE] = { + .name = "p016le", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 4, 0, 0, 16, 3, 15, 1 }, /* U */ + { 1, 4, 2, 0, 16, 3, 15, 3 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_P016BE] = { + .name = "p016be", + .nb_components = 3, + .log2_chroma_w = 1, + .log2_chroma_h = 1, + .comp = { + { 0, 2, 0, 0, 16, 1, 15, 1 }, /* Y */ + { 1, 4, 0, 0, 16, 3, 15, 1 }, /* U */ + { 1, 4, 2, 0, 16, 3, 15, 3 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, + }, + [AV_PIX_FMT_GBRAP12LE] = { + .name = "gbrap12le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* R */ + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* G */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* B */ + { 3, 2, 0, 0, 12, 1, 11, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP12BE] = { + .name = "gbrap12be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* R */ + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* G */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* B */ + { 3, 2, 0, 0, 12, 1, 11, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP10LE] = { + .name = "gbrap10le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* R */ + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* G */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* B */ + { 3, 2, 0, 0, 10, 1, 9, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_GBRAP10BE] = { + .name = "gbrap10be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 2, 0, 0, 10, 1, 9, 1 }, /* R */ + { 0, 2, 0, 0, 10, 1, 9, 1 }, /* G */ + { 1, 2, 0, 0, 10, 1, 9, 1 }, /* B */ + { 3, 2, 0, 0, 10, 1, 9, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_D3D11] = { + .name = "d3d11", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_GBRPF32BE] = { + .name = "gbrpf32be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32, 3, 31, 1 }, /* R */ + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* G */ + { 1, 4, 0, 0, 32, 3, 31, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_GBRPF32LE] = { + .name = "gbrpf32le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32, 3, 31, 1 }, /* R */ + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* G */ + { 1, 4, 0, 0, 32, 3, 31, 1 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_FLOAT | AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_GBRAPF32BE] = { + .name = "gbrapf32be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32, 3, 31, 1 }, /* R */ + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* G */ + { 1, 4, 0, 0, 32, 3, 31, 1 }, /* B */ + { 3, 4, 0, 0, 32, 3, 31, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | + AV_PIX_FMT_FLAG_ALPHA | AV_PIX_FMT_FLAG_RGB | + AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_GBRAPF32LE] = { + .name = "gbrapf32le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 2, 4, 0, 0, 32, 3, 31, 1 }, /* R */ + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* G */ + { 1, 4, 0, 0, 32, 3, 31, 1 }, /* B */ + { 3, 4, 0, 0, 32, 3, 31, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA | + AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_FLOAT, + }, + [AV_PIX_FMT_DRM_PRIME] = { + .name = "drm_prime", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_OPENCL] = { + .name = "opencl", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_GRAYF32BE] = { + .name = "grayf32be", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_FLOAT, + .alias = "yf32be", + }, + [AV_PIX_FMT_GRAYF32LE] = { + .name = "grayf32le", + .nb_components = 1, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 4, 0, 0, 32, 3, 31, 1 }, /* Y */ + }, + .flags = AV_PIX_FMT_FLAG_FLOAT, + .alias = "yf32le", + }, + [AV_PIX_FMT_YUVA422P12BE] = { + .name = "yuva422p12be", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + { 3, 2, 0, 0, 12, 1, 11, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA422P12LE] = { + .name = "yuva422p12le", + .nb_components = 4, + .log2_chroma_w = 1, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + { 3, 2, 0, 0, 12, 1, 11, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P12BE] = { + .name = "yuva444p12be", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + { 3, 2, 0, 0, 12, 1, 11, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_YUVA444P12LE] = { + .name = "yuva444p12le", + .nb_components = 4, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 0, 12, 1, 11, 1 }, /* Y */ + { 1, 2, 0, 0, 12, 1, 11, 1 }, /* U */ + { 2, 2, 0, 0, 12, 1, 11, 1 }, /* V */ + { 3, 2, 0, 0, 12, 1, 11, 1 }, /* A */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA, + }, + [AV_PIX_FMT_NV24] = { + .name = "nv24", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 2, 0, 0, 8, 1, 7, 1 }, /* U */ + { 1, 2, 1, 0, 8, 1, 7, 2 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, + [AV_PIX_FMT_NV42] = { + .name = "nv42", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 1, 0, 0, 8, 0, 7, 1 }, /* Y */ + { 1, 2, 1, 0, 8, 1, 7, 2 }, /* U */ + { 1, 2, 0, 0, 8, 1, 7, 1 }, /* V */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR, + }, +}; +#if FF_API_PLUS1_MINUS1 +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +static const char * const color_range_names[] = { + [AVCOL_RANGE_UNSPECIFIED] = "unknown", + [AVCOL_RANGE_MPEG] = "tv", + [AVCOL_RANGE_JPEG] = "pc", +}; + +static const char * const color_primaries_names[AVCOL_PRI_NB] = { + [AVCOL_PRI_RESERVED0] = "reserved", + [AVCOL_PRI_BT709] = "bt709", + [AVCOL_PRI_UNSPECIFIED] = "unknown", + [AVCOL_PRI_RESERVED] = "reserved", + [AVCOL_PRI_BT470M] = "bt470m", + [AVCOL_PRI_BT470BG] = "bt470bg", + [AVCOL_PRI_SMPTE170M] = "smpte170m", + [AVCOL_PRI_SMPTE240M] = "smpte240m", + [AVCOL_PRI_FILM] = "film", + [AVCOL_PRI_BT2020] = "bt2020", + [AVCOL_PRI_SMPTE428] = "smpte428", + [AVCOL_PRI_SMPTE431] = "smpte431", + [AVCOL_PRI_SMPTE432] = "smpte432", + [AVCOL_PRI_JEDEC_P22] = "jedec-p22", +}; + +static const char * const color_transfer_names[] = { + [AVCOL_TRC_RESERVED0] = "reserved", + [AVCOL_TRC_BT709] = "bt709", + [AVCOL_TRC_UNSPECIFIED] = "unknown", + [AVCOL_TRC_RESERVED] = "reserved", + [AVCOL_TRC_GAMMA22] = "bt470m", + [AVCOL_TRC_GAMMA28] = "bt470bg", + [AVCOL_TRC_SMPTE170M] = "smpte170m", + [AVCOL_TRC_SMPTE240M] = "smpte240m", + [AVCOL_TRC_LINEAR] = "linear", + [AVCOL_TRC_LOG] = "log100", + [AVCOL_TRC_LOG_SQRT] = "log316", + [AVCOL_TRC_IEC61966_2_4] = "iec61966-2-4", + [AVCOL_TRC_BT1361_ECG] = "bt1361e", + [AVCOL_TRC_IEC61966_2_1] = "iec61966-2-1", + [AVCOL_TRC_BT2020_10] = "bt2020-10", + [AVCOL_TRC_BT2020_12] = "bt2020-12", + [AVCOL_TRC_SMPTE2084] = "smpte2084", + [AVCOL_TRC_SMPTE428] = "smpte428", + [AVCOL_TRC_ARIB_STD_B67] = "arib-std-b67", +}; + +static const char * const color_space_names[] = { + [AVCOL_SPC_RGB] = "gbr", + [AVCOL_SPC_BT709] = "bt709", + [AVCOL_SPC_UNSPECIFIED] = "unknown", + [AVCOL_SPC_RESERVED] = "reserved", + [AVCOL_SPC_FCC] = "fcc", + [AVCOL_SPC_BT470BG] = "bt470bg", + [AVCOL_SPC_SMPTE170M] = "smpte170m", + [AVCOL_SPC_SMPTE240M] = "smpte240m", + [AVCOL_SPC_YCGCO] = "ycgco", + [AVCOL_SPC_BT2020_NCL] = "bt2020nc", + [AVCOL_SPC_BT2020_CL] = "bt2020c", + [AVCOL_SPC_SMPTE2085] = "smpte2085", + [AVCOL_SPC_CHROMA_DERIVED_NCL] = "chroma-derived-nc", + [AVCOL_SPC_CHROMA_DERIVED_CL] = "chroma-derived-c", + [AVCOL_SPC_ICTCP] = "ictcp", +}; + +static const char * const chroma_location_names[] = { + [AVCHROMA_LOC_UNSPECIFIED] = "unspecified", + [AVCHROMA_LOC_LEFT] = "left", + [AVCHROMA_LOC_CENTER] = "center", + [AVCHROMA_LOC_TOPLEFT] = "topleft", + [AVCHROMA_LOC_TOP] = "top", + [AVCHROMA_LOC_BOTTOMLEFT] = "bottomleft", + [AVCHROMA_LOC_BOTTOM] = "bottom", +}; + +static enum AVPixelFormat get_pix_fmt_internal(const char *name) +{ + enum AVPixelFormat pix_fmt; + + for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) + if (av_pix_fmt_descriptors[pix_fmt].name && + (!strcmp(av_pix_fmt_descriptors[pix_fmt].name, name) || + av_match_name(name, av_pix_fmt_descriptors[pix_fmt].alias))) + return pix_fmt; + + return AV_PIX_FMT_NONE; +} + +const char *av_get_pix_fmt_name(enum AVPixelFormat pix_fmt) +{ + return (unsigned)pix_fmt < AV_PIX_FMT_NB ? + av_pix_fmt_descriptors[pix_fmt].name : NULL; +} + +#if HAVE_BIGENDIAN +# define X_NE(be, le) be +#else +# define X_NE(be, le) le +#endif + +enum AVPixelFormat av_get_pix_fmt(const char *name) +{ + enum AVPixelFormat pix_fmt; + + if (!strcmp(name, "rgb32")) + name = X_NE("argb", "bgra"); + else if (!strcmp(name, "bgr32")) + name = X_NE("abgr", "rgba"); + + pix_fmt = get_pix_fmt_internal(name); + if (pix_fmt == AV_PIX_FMT_NONE) { + char name2[32]; + + snprintf(name2, sizeof(name2), "%s%s", name, X_NE("be", "le")); + pix_fmt = get_pix_fmt_internal(name2); + } + +#if FF_API_VAAPI + if (pix_fmt == AV_PIX_FMT_NONE && !strcmp(name, "vaapi")) + pix_fmt = AV_PIX_FMT_VAAPI; +#endif + return pix_fmt; +} + +int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc) +{ + int c, bits = 0; + int log2_pixels = pixdesc->log2_chroma_w + pixdesc->log2_chroma_h; + + for (c = 0; c < pixdesc->nb_components; c++) { + int s = c == 1 || c == 2 ? 0 : log2_pixels; + bits += pixdesc->comp[c].depth << s; + } + + return bits >> log2_pixels; +} + +int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc) +{ + int c, bits = 0; + int log2_pixels = pixdesc->log2_chroma_w + pixdesc->log2_chroma_h; + int steps[4] = {0}; + + for (c = 0; c < pixdesc->nb_components; c++) { + const AVComponentDescriptor *comp = &pixdesc->comp[c]; + int s = c == 1 || c == 2 ? 0 : log2_pixels; + steps[comp->plane] = comp->step << s; + } + for (c = 0; c < 4; c++) + bits += steps[c]; + + if(!(pixdesc->flags & AV_PIX_FMT_FLAG_BITSTREAM)) + bits *= 8; + + return bits >> log2_pixels; +} + +char *av_get_pix_fmt_string(char *buf, int buf_size, + enum AVPixelFormat pix_fmt) +{ + /* print header */ + if (pix_fmt < 0) { + snprintf (buf, buf_size, "name" " nb_components" " nb_bits"); + } else { + const AVPixFmtDescriptor *pixdesc = &av_pix_fmt_descriptors[pix_fmt]; + snprintf(buf, buf_size, "%-11s %7d %10d", pixdesc->name, + pixdesc->nb_components, av_get_bits_per_pixel(pixdesc)); + } + + return buf; +} + +const AVPixFmtDescriptor *av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt) +{ + if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB) + return NULL; + return &av_pix_fmt_descriptors[pix_fmt]; +} + +const AVPixFmtDescriptor *av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev) +{ + if (!prev) + return &av_pix_fmt_descriptors[0]; + while (prev - av_pix_fmt_descriptors < FF_ARRAY_ELEMS(av_pix_fmt_descriptors) - 1) { + prev++; + if (prev->name) + return prev; + } + return NULL; +} + +enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc) +{ + if (desc < av_pix_fmt_descriptors || + desc >= av_pix_fmt_descriptors + FF_ARRAY_ELEMS(av_pix_fmt_descriptors)) + return AV_PIX_FMT_NONE; + + return desc - av_pix_fmt_descriptors; +} + +int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, + int *h_shift, int *v_shift) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + if (!desc) + return AVERROR(ENOSYS); + *h_shift = desc->log2_chroma_w; + *v_shift = desc->log2_chroma_h; + + return 0; +} + +int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int i, planes[4] = { 0 }, ret = 0; + + if (!desc) + return AVERROR(EINVAL); + + for (i = 0; i < desc->nb_components; i++) + planes[desc->comp[i].plane] = 1; + for (i = 0; i < FF_ARRAY_ELEMS(planes); i++) + ret += planes[i]; + return ret; +} + +void ff_check_pixfmt_descriptors(void){ + int i, j; + + for (i=0; iname && !d->nb_components && !d->log2_chroma_w && !d->log2_chroma_h && !d->flags) + continue; +// av_log(NULL, AV_LOG_DEBUG, "Checking: %s\n", d->name); + av_assert0(d->log2_chroma_w <= 3); + av_assert0(d->log2_chroma_h <= 3); + av_assert0(d->nb_components <= 4); + av_assert0(d->name && d->name[0]); + av_assert2(av_get_pix_fmt(d->name) == i); + + for (j=0; jcomp); j++) { + const AVComponentDescriptor *c = &d->comp[j]; + if(j>=d->nb_components) { + av_assert0(!c->plane && !c->step && !c->offset && !c->shift && !c->depth); + continue; + } + if (d->flags & AV_PIX_FMT_FLAG_BITSTREAM) { + av_assert0(c->step >= c->depth); + } else { + av_assert0(8*c->step >= c->depth); + } + if (d->flags & AV_PIX_FMT_FLAG_BAYER) + continue; + av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 0); + av_assert0(tmp[0] == 0 && tmp[1] == 0); + tmp[0] = tmp[1] = (1<depth) - 1; + av_write_image_line(tmp, data, linesize, d, 0, 0, j, 2); + } + } +} + + +enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + char name[16]; + int i; + + if (!desc || strlen(desc->name) < 2) + return AV_PIX_FMT_NONE; + av_strlcpy(name, desc->name, sizeof(name)); + i = strlen(name) - 2; + if (strcmp(name + i, "be") && strcmp(name + i, "le")) + return AV_PIX_FMT_NONE; + + name[i] ^= 'b' ^ 'l'; + + return get_pix_fmt_internal(name); +} + +#define FF_COLOR_NA -1 +#define FF_COLOR_RGB 0 /**< RGB color space */ +#define FF_COLOR_GRAY 1 /**< gray color space */ +#define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ +#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ +#define FF_COLOR_XYZ 4 + +#define pixdesc_has_alpha(pixdesc) \ + ((pixdesc)->flags & AV_PIX_FMT_FLAG_ALPHA) + + +static int get_color_type(const AVPixFmtDescriptor *desc) { + if (desc->flags & AV_PIX_FMT_FLAG_PAL) + return FF_COLOR_RGB; + + if(desc->nb_components == 1 || desc->nb_components == 2) + return FF_COLOR_GRAY; + + if(desc->name && !strncmp(desc->name, "yuvj", 4)) + return FF_COLOR_YUV_JPEG; + + if(desc->name && !strncmp(desc->name, "xyz", 3)) + return FF_COLOR_XYZ; + + if(desc->flags & AV_PIX_FMT_FLAG_RGB) + return FF_COLOR_RGB; + + if(desc->nb_components == 0) + return FF_COLOR_NA; + + return FF_COLOR_YUV; +} + +static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + int i; + + if (!desc || !desc->nb_components) { + *min = *max = 0; + return AVERROR(EINVAL); + } + + *min = INT_MAX, *max = -INT_MAX; + for (i = 0; i < desc->nb_components; i++) { + *min = FFMIN(desc->comp[i].depth, *min); + *max = FFMAX(desc->comp[i].depth, *max); + } + return 0; +} + +static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt, + enum AVPixelFormat src_pix_fmt, + unsigned *lossp, unsigned consider) +{ + const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt); + const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt); + int src_color, dst_color; + int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth; + int ret, loss, i, nb_components; + int score = INT_MAX - 1; + + if (!src_desc || !dst_desc) + return -4; + + if ((src_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) || + (dst_desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { + if (dst_pix_fmt == src_pix_fmt) + return -1; + else + return -2; + } + + /* compute loss */ + *lossp = loss = 0; + + if (dst_pix_fmt == src_pix_fmt) + return INT_MAX; + + if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0) + return -3; + if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0) + return -3; + + src_color = get_color_type(src_desc); + dst_color = get_color_type(dst_desc); + if (dst_pix_fmt == AV_PIX_FMT_PAL8) + nb_components = FFMIN(src_desc->nb_components, 4); + else + nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components); + + for (i = 0; i < nb_components; i++) { + int depth_minus1 = (dst_pix_fmt == AV_PIX_FMT_PAL8) ? 7/nb_components : (dst_desc->comp[i].depth - 1); + if (src_desc->comp[i].depth - 1 > depth_minus1 && (consider & FF_LOSS_DEPTH)) { + loss |= FF_LOSS_DEPTH; + score -= 65536 >> depth_minus1; + } + } + + if (consider & FF_LOSS_RESOLUTION) { + if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) { + loss |= FF_LOSS_RESOLUTION; + score -= 256 << dst_desc->log2_chroma_w; + } + if (dst_desc->log2_chroma_h > src_desc->log2_chroma_h) { + loss |= FF_LOSS_RESOLUTION; + score -= 256 << dst_desc->log2_chroma_h; + } + // don't favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side + if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 && + dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) { + score += 512; + } + } + + if(consider & FF_LOSS_COLORSPACE) + switch(dst_color) { + case FF_COLOR_RGB: + if (src_color != FF_COLOR_RGB && + src_color != FF_COLOR_GRAY) + loss |= FF_LOSS_COLORSPACE; + break; + case FF_COLOR_GRAY: + if (src_color != FF_COLOR_GRAY) + loss |= FF_LOSS_COLORSPACE; + break; + case FF_COLOR_YUV: + if (src_color != FF_COLOR_YUV) + loss |= FF_LOSS_COLORSPACE; + break; + case FF_COLOR_YUV_JPEG: + if (src_color != FF_COLOR_YUV_JPEG && + src_color != FF_COLOR_YUV && + src_color != FF_COLOR_GRAY) + loss |= FF_LOSS_COLORSPACE; + break; + default: + /* fail safe test */ + if (src_color != dst_color) + loss |= FF_LOSS_COLORSPACE; + break; + } + if(loss & FF_LOSS_COLORSPACE) + score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth - 1, src_desc->comp[0].depth - 1); + + if (dst_color == FF_COLOR_GRAY && + src_color != FF_COLOR_GRAY && (consider & FF_LOSS_CHROMA)) { + loss |= FF_LOSS_CHROMA; + score -= 2 * 65536; + } + if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))) { + loss |= FF_LOSS_ALPHA; + score -= 65536; + } + if (dst_pix_fmt == AV_PIX_FMT_PAL8 && (consider & FF_LOSS_COLORQUANT) && + (src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))))) { + loss |= FF_LOSS_COLORQUANT; + score -= 65536; + } + + *lossp = loss; + return score; +} + +int av_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, + enum AVPixelFormat src_pix_fmt, + int has_alpha) +{ + int loss; + int ret = get_pix_fmt_score(dst_pix_fmt, src_pix_fmt, &loss, has_alpha ? ~0 : ~FF_LOSS_ALPHA); + if (ret < 0) + return ret; + return loss; +} + +enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) +{ + enum AVPixelFormat dst_pix_fmt; + int loss1, loss2, loss_mask; + const AVPixFmtDescriptor *desc1 = av_pix_fmt_desc_get(dst_pix_fmt1); + const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2); + int score1, score2; + + if (!desc1) { + dst_pix_fmt = dst_pix_fmt2; + } else if (!desc2) { + dst_pix_fmt = dst_pix_fmt1; + } else { + loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */ + if(!has_alpha) + loss_mask &= ~FF_LOSS_ALPHA; + + score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask); + score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask); + + if (score1 == score2) { + if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) { + dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1; + } else { + dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1; + } + } else { + dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1; + } + } + + if (loss_ptr) + *loss_ptr = av_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); + return dst_pix_fmt; +} + +const char *av_color_range_name(enum AVColorRange range) +{ + return (unsigned) range < AVCOL_RANGE_NB ? + color_range_names[range] : NULL; +} + +int av_color_range_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_range_names); i++) { + size_t len = strlen(color_range_names[i]); + if (!strncmp(color_range_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} + +const char *av_color_primaries_name(enum AVColorPrimaries primaries) +{ + return (unsigned) primaries < AVCOL_PRI_NB ? + color_primaries_names[primaries] : NULL; +} + +int av_color_primaries_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_primaries_names); i++) { + size_t len; + + if (!color_primaries_names[i]) + continue; + + len = strlen(color_primaries_names[i]); + if (!strncmp(color_primaries_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} + +const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer) +{ + return (unsigned) transfer < AVCOL_TRC_NB ? + color_transfer_names[transfer] : NULL; +} + +int av_color_transfer_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_transfer_names); i++) { + size_t len; + + if (!color_transfer_names[i]) + continue; + + len = strlen(color_transfer_names[i]); + if (!strncmp(color_transfer_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} + +const char *av_color_space_name(enum AVColorSpace space) +{ + return (unsigned) space < AVCOL_SPC_NB ? + color_space_names[space] : NULL; +} + +int av_color_space_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(color_space_names); i++) { + size_t len; + + if (!color_space_names[i]) + continue; + + len = strlen(color_space_names[i]); + if (!strncmp(color_space_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} + +const char *av_chroma_location_name(enum AVChromaLocation location) +{ + return (unsigned) location < AVCHROMA_LOC_NB ? + chroma_location_names[location] : NULL; +} + +int av_chroma_location_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(chroma_location_names); i++) { + size_t len; + + if (!chroma_location_names[i]) + continue; + + len = strlen(chroma_location_names[i]); + if (!strncmp(chroma_location_names[i], name, len)) + return i; + } + + return AVERROR(EINVAL); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixdesc.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixdesc.h new file mode 100644 index 000000000..c055810ae --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixdesc.h @@ -0,0 +1,440 @@ +/* + * pixel format descriptor + * Copyright (c) 2009 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXDESC_H +#define AVUTIL_PIXDESC_H + +#include + +#include "attributes.h" +#include "pixfmt.h" +#include "version.h" + +typedef struct AVComponentDescriptor { + /** + * Which of the 4 planes contains the component. + */ + int plane; + + /** + * Number of elements between 2 horizontally consecutive pixels. + * Elements are bits for bitstream formats, bytes otherwise. + */ + int step; + + /** + * Number of elements before the component of the first pixel. + * Elements are bits for bitstream formats, bytes otherwise. + */ + int offset; + + /** + * Number of least significant bits that must be shifted away + * to get the value. + */ + int shift; + + /** + * Number of bits in the component. + */ + int depth; + +#if FF_API_PLUS1_MINUS1 + /** deprecated, use step instead */ + attribute_deprecated int step_minus1; + + /** deprecated, use depth instead */ + attribute_deprecated int depth_minus1; + + /** deprecated, use offset instead */ + attribute_deprecated int offset_plus1; +#endif +} AVComponentDescriptor; + +/** + * Descriptor that unambiguously describes how the bits of a pixel are + * stored in the up to 4 data planes of an image. It also stores the + * subsampling factors and number of components. + * + * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV + * and all the YUV variants) AVPixFmtDescriptor just stores how values + * are stored not what these values represent. + */ +typedef struct AVPixFmtDescriptor { + const char *name; + uint8_t nb_components; ///< The number of components each pixel has, (1-4) + + /** + * Amount to shift the luma width right to find the chroma width. + * For YV12 this is 1 for example. + * chroma_width = AV_CEIL_RSHIFT(luma_width, log2_chroma_w) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + uint8_t log2_chroma_w; + + /** + * Amount to shift the luma height right to find the chroma height. + * For YV12 this is 1 for example. + * chroma_height= AV_CEIL_RSHIFT(luma_height, log2_chroma_h) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + uint8_t log2_chroma_h; + + /** + * Combination of AV_PIX_FMT_FLAG_... flags. + */ + uint64_t flags; + + /** + * Parameters that describe how pixels are packed. + * If the format has 1 or 2 components, then luma is 0. + * If the format has 3 or 4 components: + * if the RGB flag is set then 0 is red, 1 is green and 2 is blue; + * otherwise 0 is luma, 1 is chroma-U and 2 is chroma-V. + * + * If present, the Alpha channel is always the last component. + */ + AVComponentDescriptor comp[4]; + + /** + * Alternative comma-separated names. + */ + const char *alias; +} AVPixFmtDescriptor; + +/** + * Pixel format is big-endian. + */ +#define AV_PIX_FMT_FLAG_BE (1 << 0) +/** + * Pixel format has a palette in data[1], values are indexes in this palette. + */ +#define AV_PIX_FMT_FLAG_PAL (1 << 1) +/** + * All values of a component are bit-wise packed end to end. + */ +#define AV_PIX_FMT_FLAG_BITSTREAM (1 << 2) +/** + * Pixel format is an HW accelerated format. + */ +#define AV_PIX_FMT_FLAG_HWACCEL (1 << 3) +/** + * At least one pixel component is not in the first data plane. + */ +#define AV_PIX_FMT_FLAG_PLANAR (1 << 4) +/** + * The pixel format contains RGB-like data (as opposed to YUV/grayscale). + */ +#define AV_PIX_FMT_FLAG_RGB (1 << 5) + +/** + * The pixel format is "pseudo-paletted". This means that it contains a + * fixed palette in the 2nd plane but the palette is fixed/constant for each + * PIX_FMT. This allows interpreting the data as if it was PAL8, which can + * in some cases be simpler. Or the data can be interpreted purely based on + * the pixel format without using the palette. + * An example of a pseudo-paletted format is AV_PIX_FMT_GRAY8 + * + * @deprecated This flag is deprecated, and will be removed. When it is removed, + * the extra palette allocation in AVFrame.data[1] is removed as well. Only + * actual paletted formats (as indicated by AV_PIX_FMT_FLAG_PAL) will have a + * palette. Starting with FFmpeg versions which have this flag deprecated, the + * extra "pseudo" palette is already ignored, and API users are not required to + * allocate a palette for AV_PIX_FMT_FLAG_PSEUDOPAL formats (it was required + * before the deprecation, though). + */ +#define AV_PIX_FMT_FLAG_PSEUDOPAL (1 << 6) + +/** + * The pixel format has an alpha channel. This is set on all formats that + * support alpha in some way, including AV_PIX_FMT_PAL8. The alpha is always + * straight, never pre-multiplied. + * + * If a codec or a filter does not support alpha, it should set all alpha to + * opaque, or use the equivalent pixel formats without alpha component, e.g. + * AV_PIX_FMT_RGB0 (or AV_PIX_FMT_RGB24 etc.) instead of AV_PIX_FMT_RGBA. + */ +#define AV_PIX_FMT_FLAG_ALPHA (1 << 7) + +/** + * The pixel format is following a Bayer pattern + */ +#define AV_PIX_FMT_FLAG_BAYER (1 << 8) + +/** + * The pixel format contains IEEE-754 floating point values. Precision (double, + * single, or half) should be determined by the pixel size (64, 32, or 16 bits). + */ +#define AV_PIX_FMT_FLAG_FLOAT (1 << 9) + +/** + * Return the number of bits per pixel used by the pixel format + * described by pixdesc. Note that this is not the same as the number + * of bits per sample. + * + * The returned number of bits refers to the number of bits actually + * used for storing the pixel information, that is padding bits are + * not counted. + */ +int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); + +/** + * Return the number of bits per pixel for the pixel format + * described by pixdesc, including any padding or unused bits. + */ +int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); + +/** + * @return a pixel format descriptor for provided pixel format or NULL if + * this pixel format is unknown. + */ +const AVPixFmtDescriptor *av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt); + +/** + * Iterate over all pixel format descriptors known to libavutil. + * + * @param prev previous descriptor. NULL to get the first descriptor. + * + * @return next descriptor or NULL after the last descriptor + */ +const AVPixFmtDescriptor *av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev); + +/** + * @return an AVPixelFormat id described by desc, or AV_PIX_FMT_NONE if desc + * is not a valid pointer to a pixel format descriptor. + */ +enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc); + +/** + * Utility function to access log2_chroma_w log2_chroma_h from + * the pixel format AVPixFmtDescriptor. + * + * @param[in] pix_fmt the pixel format + * @param[out] h_shift store log2_chroma_w (horizontal/width shift) + * @param[out] v_shift store log2_chroma_h (vertical/height shift) + * + * @return 0 on success, AVERROR(ENOSYS) on invalid or unknown pixel format + */ +int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, + int *h_shift, int *v_shift); + +/** + * @return number of planes in pix_fmt, a negative AVERROR if pix_fmt is not a + * valid pixel format. + */ +int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt); + +/** + * @return the name for provided color range or NULL if unknown. + */ +const char *av_color_range_name(enum AVColorRange range); + +/** + * @return the AVColorRange value for name or an AVError if not found. + */ +int av_color_range_from_name(const char *name); + +/** + * @return the name for provided color primaries or NULL if unknown. + */ +const char *av_color_primaries_name(enum AVColorPrimaries primaries); + +/** + * @return the AVColorPrimaries value for name or an AVError if not found. + */ +int av_color_primaries_from_name(const char *name); + +/** + * @return the name for provided color transfer or NULL if unknown. + */ +const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer); + +/** + * @return the AVColorTransferCharacteristic value for name or an AVError if not found. + */ +int av_color_transfer_from_name(const char *name); + +/** + * @return the name for provided color space or NULL if unknown. + */ +const char *av_color_space_name(enum AVColorSpace space); + +/** + * @return the AVColorSpace value for name or an AVError if not found. + */ +int av_color_space_from_name(const char *name); + +/** + * @return the name for provided chroma location or NULL if unknown. + */ +const char *av_chroma_location_name(enum AVChromaLocation location); + +/** + * @return the AVChromaLocation value for name or an AVError if not found. + */ +int av_chroma_location_from_name(const char *name); + +/** + * Return the pixel format corresponding to name. + * + * If there is no pixel format with name name, then looks for a + * pixel format with the name corresponding to the native endian + * format of name. + * For example in a little-endian system, first looks for "gray16", + * then for "gray16le". + * + * Finally if no pixel format has been found, returns AV_PIX_FMT_NONE. + */ +enum AVPixelFormat av_get_pix_fmt(const char *name); + +/** + * Return the short name for a pixel format, NULL in case pix_fmt is + * unknown. + * + * @see av_get_pix_fmt(), av_get_pix_fmt_string() + */ +const char *av_get_pix_fmt_name(enum AVPixelFormat pix_fmt); + +/** + * Print in buf the string corresponding to the pixel format with + * number pix_fmt, or a header if pix_fmt is negative. + * + * @param buf the buffer where to write the string + * @param buf_size the size of buf + * @param pix_fmt the number of the pixel format to print the + * corresponding info string, or a negative value to print the + * corresponding header. + */ +char *av_get_pix_fmt_string(char *buf, int buf_size, + enum AVPixelFormat pix_fmt); + +/** + * Read a line from an image, and write the values of the + * pixel format component c to dst. + * + * @param data the array containing the pointers to the planes of the image + * @param linesize the array containing the linesizes of the image + * @param desc the pixel format descriptor for the image + * @param x the horizontal coordinate of the first pixel to read + * @param y the vertical coordinate of the first pixel to read + * @param w the width of the line to read, that is the number of + * values to write to dst + * @param read_pal_component if not zero and the format is a paletted + * format writes the values corresponding to the palette + * component c in data[1] to dst, rather than the palette indexes in + * data[0]. The behavior is undefined if the format is not paletted. + * @param dst_element_size size of elements in dst array (2 or 4 byte) + */ +void av_read_image_line2(void *dst, const uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int read_pal_component, + int dst_element_size); + +void av_read_image_line(uint16_t *dst, const uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int read_pal_component); + +/** + * Write the values from src to the pixel format component c of an + * image line. + * + * @param src array containing the values to write + * @param data the array containing the pointers to the planes of the + * image to write into. It is supposed to be zeroed. + * @param linesize the array containing the linesizes of the image + * @param desc the pixel format descriptor for the image + * @param x the horizontal coordinate of the first pixel to write + * @param y the vertical coordinate of the first pixel to write + * @param w the width of the line to write, that is the number of + * values to write to the image line + * @param src_element_size size of elements in src array (2 or 4 byte) + */ +void av_write_image_line2(const void *src, uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int src_element_size); + +void av_write_image_line(const uint16_t *src, uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w); + +/** + * Utility function to swap the endianness of a pixel format. + * + * @param[in] pix_fmt the pixel format + * + * @return pixel format with swapped endianness if it exists, + * otherwise AV_PIX_FMT_NONE + */ +enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt); + +#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */ + +/** + * Compute what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * av_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur + * (maximum loss for an invalid dst_pix_fmt). + */ +int av_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, + enum AVPixelFormat src_pix_fmt, + int has_alpha); + +/** + * Compute what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * av_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur + * (maximum loss for an invalid dst_pix_fmt). + */ +enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); + +#endif /* AVUTIL_PIXDESC_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixelutils.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixelutils.c new file mode 100644 index 000000000..ebee3d6f9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixelutils.c @@ -0,0 +1,89 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "common.h" +#include "pixelutils.h" +#include "internal.h" + +#if CONFIG_PIXELUTILS + +#include "x86/pixelutils.h" + +static av_always_inline int sad_wxh(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2, + int w, int h) +{ + int x, y, sum = 0; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) + sum += abs(src1[x] - src2[x]); + src1 += stride1; + src2 += stride2; + } + return sum; +} + +#define DECLARE_BLOCK_FUNCTIONS(size) \ +static int block_sad_##size##x##size##_c(const uint8_t *src1, ptrdiff_t stride1, \ + const uint8_t *src2, ptrdiff_t stride2) \ +{ \ + return sad_wxh(src1, stride1, src2, stride2, size, size); \ +} + +DECLARE_BLOCK_FUNCTIONS(2) +DECLARE_BLOCK_FUNCTIONS(4) +DECLARE_BLOCK_FUNCTIONS(8) +DECLARE_BLOCK_FUNCTIONS(16) +DECLARE_BLOCK_FUNCTIONS(32) + +static const av_pixelutils_sad_fn sad_c[] = { + block_sad_2x2_c, + block_sad_4x4_c, + block_sad_8x8_c, + block_sad_16x16_c, + block_sad_32x32_c, +}; + +#endif /* CONFIG_PIXELUTILS */ + +av_pixelutils_sad_fn av_pixelutils_get_sad_fn(int w_bits, int h_bits, int aligned, void *log_ctx) +{ +#if !CONFIG_PIXELUTILS + av_log(log_ctx, AV_LOG_ERROR, "pixelutils support is required " + "but libavutil is not compiled with it\n"); + return NULL; +#else + av_pixelutils_sad_fn sad[FF_ARRAY_ELEMS(sad_c)]; + + memcpy(sad, sad_c, sizeof(sad)); + + if (w_bits < 1 || w_bits > FF_ARRAY_ELEMS(sad) || + h_bits < 1 || h_bits > FF_ARRAY_ELEMS(sad)) + return NULL; + if (w_bits != h_bits) // only squared sad for now + return NULL; + +#if ARCH_X86 + ff_pixelutils_sad_init_x86(sad, aligned); +#endif + + return sad[w_bits - 1]; +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixelutils.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixelutils.h new file mode 100644 index 000000000..a8dbc157e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/pixelutils.h @@ -0,0 +1,52 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXELUTILS_H +#define AVUTIL_PIXELUTILS_H + +#include +#include +#include "common.h" + +/** + * Sum of abs(src1[x] - src2[x]) + */ +typedef int (*av_pixelutils_sad_fn)(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +/** + * Get a potentially optimized pointer to a Sum-of-absolute-differences + * function (see the av_pixelutils_sad_fn prototype). + * + * @param w_bits 1< + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXFMT_H +#define AVUTIL_PIXFMT_H + +/** + * @file + * pixel format definitions + */ + +#include "libavutil/avconfig.h" +#include "version.h" + +#define AVPALETTE_SIZE 1024 +#define AVPALETTE_COUNT 256 + +/** + * Pixel format. + * + * @note + * AV_PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA + * color is put together as: + * (A << 24) | (R << 16) | (G << 8) | B + * This is stored as BGRA on little-endian CPU architectures and ARGB on + * big-endian CPUs. + * + * @note + * If the resolution is not a multiple of the chroma subsampling factor + * then the chroma plane resolution must be rounded up. + * + * @par + * When the pixel format is palettized RGB32 (AV_PIX_FMT_PAL8), the palettized + * image data is stored in AVFrame.data[0]. The palette is transported in + * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is + * formatted the same as in AV_PIX_FMT_RGB32 described above (i.e., it is + * also endian-specific). Note also that the individual RGB32 palette + * components stored in AVFrame.data[1] should be in the range 0..255. + * This is important as many custom PAL8 video codecs that were designed + * to run on the IBM VGA graphics adapter use 6-bit palette components. + * + * @par + * For all the 8 bits per pixel formats, an RGB32 palette is in data[1] like + * for pal8. This palette is filled in automatically by the function + * allocating the picture. + */ +enum AVPixelFormat { + AV_PIX_FMT_NONE = -1, + AV_PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) + AV_PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr + AV_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... + AV_PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... + AV_PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + AV_PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) + AV_PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) + AV_PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) + AV_PIX_FMT_GRAY8, ///< Y , 8bpp + AV_PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb + AV_PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb + AV_PIX_FMT_PAL8, ///< 8 bits with AV_PIX_FMT_RGB32 palette + AV_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range + AV_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range + AV_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range + AV_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 + AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 + AV_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) + AV_PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + AV_PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) + AV_PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) + AV_PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + AV_PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) + AV_PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) + AV_PIX_FMT_NV21, ///< as above, but U and V bytes are swapped + + AV_PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... + AV_PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... + AV_PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... + AV_PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... + + AV_PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian + AV_PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian + AV_PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) + AV_PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range + AV_PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) + AV_PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian + AV_PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian + + AV_PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian + AV_PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian + AV_PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined + AV_PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined + + AV_PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian + AV_PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian + AV_PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), big-endian , X=unused/undefined + AV_PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), little-endian, X=unused/undefined + +#if FF_API_VAAPI + /** @name Deprecated pixel formats */ + /**@{*/ + AV_PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers + AV_PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers + AV_PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a VASurfaceID + /**@}*/ + AV_PIX_FMT_VAAPI = AV_PIX_FMT_VAAPI_VLD, +#else + /** + * Hardware acceleration through VA-API, data[3] contains a + * VASurfaceID. + */ + AV_PIX_FMT_VAAPI, +#endif + + AV_PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer + + AV_PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), little-endian, X=unused/undefined + AV_PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), big-endian, X=unused/undefined + AV_PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), little-endian, X=unused/undefined + AV_PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), big-endian, X=unused/undefined + AV_PIX_FMT_YA8, ///< 8 bits gray, 8 bits alpha + + AV_PIX_FMT_Y400A = AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 + AV_PIX_FMT_GRAY8A= AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 + + AV_PIX_FMT_BGR48BE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian + AV_PIX_FMT_BGR48LE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian + + /** + * The following 12 formats have the disadvantage of needing 1 format for each bit depth. + * Notice that each 9/10 bits sample is stored in 16 bits with extra padding. + * If you want to support multiple bit depths, then using AV_PIX_FMT_YUV420P16* with the bpp stored separately is better. + */ + AV_PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_GBRP, ///< planar GBR 4:4:4 24bpp + AV_PIX_FMT_GBR24P = AV_PIX_FMT_GBRP, // alias for #AV_PIX_FMT_GBRP + AV_PIX_FMT_GBRP9BE, ///< planar GBR 4:4:4 27bpp, big-endian + AV_PIX_FMT_GBRP9LE, ///< planar GBR 4:4:4 27bpp, little-endian + AV_PIX_FMT_GBRP10BE, ///< planar GBR 4:4:4 30bpp, big-endian + AV_PIX_FMT_GBRP10LE, ///< planar GBR 4:4:4 30bpp, little-endian + AV_PIX_FMT_GBRP16BE, ///< planar GBR 4:4:4 48bpp, big-endian + AV_PIX_FMT_GBRP16LE, ///< planar GBR 4:4:4 48bpp, little-endian + AV_PIX_FMT_YUVA422P, ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples) + AV_PIX_FMT_YUVA444P, ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples) + AV_PIX_FMT_YUVA420P9BE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big-endian + AV_PIX_FMT_YUVA420P9LE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian + AV_PIX_FMT_YUVA422P9BE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), big-endian + AV_PIX_FMT_YUVA422P9LE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian + AV_PIX_FMT_YUVA444P9BE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big-endian + AV_PIX_FMT_YUVA444P9LE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian + AV_PIX_FMT_YUVA420P10BE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian) + AV_PIX_FMT_YUVA420P10LE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian) + AV_PIX_FMT_YUVA422P10BE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA422P10LE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian) + AV_PIX_FMT_YUVA444P10BE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA444P10LE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian) + AV_PIX_FMT_YUVA420P16BE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian) + AV_PIX_FMT_YUVA420P16LE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian) + AV_PIX_FMT_YUVA422P16BE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA422P16LE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian) + AV_PIX_FMT_YUVA444P16BE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA444P16LE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian) + + AV_PIX_FMT_VDPAU, ///< HW acceleration through VDPAU, Picture.data[3] contains a VdpVideoSurface + + AV_PIX_FMT_XYZ12LE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as little-endian, the 4 lower bits are set to 0 + AV_PIX_FMT_XYZ12BE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as big-endian, the 4 lower bits are set to 0 + AV_PIX_FMT_NV16, ///< interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + AV_PIX_FMT_NV20LE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_NV20BE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + + AV_PIX_FMT_RGBA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian + AV_PIX_FMT_RGBA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian + AV_PIX_FMT_BGRA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian + AV_PIX_FMT_BGRA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian + + AV_PIX_FMT_YVYU422, ///< packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb + + AV_PIX_FMT_YA16BE, ///< 16 bits gray, 16 bits alpha (big-endian) + AV_PIX_FMT_YA16LE, ///< 16 bits gray, 16 bits alpha (little-endian) + + AV_PIX_FMT_GBRAP, ///< planar GBRA 4:4:4:4 32bpp + AV_PIX_FMT_GBRAP16BE, ///< planar GBRA 4:4:4:4 64bpp, big-endian + AV_PIX_FMT_GBRAP16LE, ///< planar GBRA 4:4:4:4 64bpp, little-endian + /** + * HW acceleration through QSV, data[3] contains a pointer to the + * mfxFrameSurface1 structure. + */ + AV_PIX_FMT_QSV, + /** + * HW acceleration though MMAL, data[3] contains a pointer to the + * MMAL_BUFFER_HEADER_T structure. + */ + AV_PIX_FMT_MMAL, + + AV_PIX_FMT_D3D11VA_VLD, ///< HW decoding through Direct3D11 via old API, Picture.data[3] contains a ID3D11VideoDecoderOutputView pointer + + /** + * HW acceleration through CUDA. data[i] contain CUdeviceptr pointers + * exactly as for system memory frames. + */ + AV_PIX_FMT_CUDA, + + AV_PIX_FMT_0RGB, ///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined + AV_PIX_FMT_RGB0, ///< packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined + AV_PIX_FMT_0BGR, ///< packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined + AV_PIX_FMT_BGR0, ///< packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined + + AV_PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV420P14BE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P14LE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV422P14BE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P14LE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV444P14BE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P14LE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_GBRP12BE, ///< planar GBR 4:4:4 36bpp, big-endian + AV_PIX_FMT_GBRP12LE, ///< planar GBR 4:4:4 36bpp, little-endian + AV_PIX_FMT_GBRP14BE, ///< planar GBR 4:4:4 42bpp, big-endian + AV_PIX_FMT_GBRP14LE, ///< planar GBR 4:4:4 42bpp, little-endian + AV_PIX_FMT_YUVJ411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV411P and setting color_range + + AV_PIX_FMT_BAYER_BGGR8, ///< bayer, BGBG..(odd line), GRGR..(even line), 8-bit samples */ + AV_PIX_FMT_BAYER_RGGB8, ///< bayer, RGRG..(odd line), GBGB..(even line), 8-bit samples */ + AV_PIX_FMT_BAYER_GBRG8, ///< bayer, GBGB..(odd line), RGRG..(even line), 8-bit samples */ + AV_PIX_FMT_BAYER_GRBG8, ///< bayer, GRGR..(odd line), BGBG..(even line), 8-bit samples */ + AV_PIX_FMT_BAYER_BGGR16LE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, little-endian */ + AV_PIX_FMT_BAYER_BGGR16BE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, big-endian */ + AV_PIX_FMT_BAYER_RGGB16LE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, little-endian */ + AV_PIX_FMT_BAYER_RGGB16BE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, big-endian */ + AV_PIX_FMT_BAYER_GBRG16LE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, little-endian */ + AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian */ + AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian */ + AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian */ + + AV_PIX_FMT_XVMC,///< XVideo Motion Acceleration via common packet passing + + AV_PIX_FMT_YUV440P10LE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian + AV_PIX_FMT_YUV440P10BE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian + AV_PIX_FMT_YUV440P12LE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian + AV_PIX_FMT_YUV440P12BE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian + AV_PIX_FMT_AYUV64LE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), little-endian + AV_PIX_FMT_AYUV64BE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), big-endian + + AV_PIX_FMT_VIDEOTOOLBOX, ///< hardware decoding through Videotoolbox + + AV_PIX_FMT_P010LE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, little-endian + AV_PIX_FMT_P010BE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, big-endian + + AV_PIX_FMT_GBRAP12BE, ///< planar GBR 4:4:4:4 48bpp, big-endian + AV_PIX_FMT_GBRAP12LE, ///< planar GBR 4:4:4:4 48bpp, little-endian + + AV_PIX_FMT_GBRAP10BE, ///< planar GBR 4:4:4:4 40bpp, big-endian + AV_PIX_FMT_GBRAP10LE, ///< planar GBR 4:4:4:4 40bpp, little-endian + + AV_PIX_FMT_MEDIACODEC, ///< hardware decoding through MediaCodec + + AV_PIX_FMT_GRAY12BE, ///< Y , 12bpp, big-endian + AV_PIX_FMT_GRAY12LE, ///< Y , 12bpp, little-endian + AV_PIX_FMT_GRAY10BE, ///< Y , 10bpp, big-endian + AV_PIX_FMT_GRAY10LE, ///< Y , 10bpp, little-endian + + AV_PIX_FMT_P016LE, ///< like NV12, with 16bpp per component, little-endian + AV_PIX_FMT_P016BE, ///< like NV12, with 16bpp per component, big-endian + + /** + * Hardware surfaces for Direct3D11. + * + * This is preferred over the legacy AV_PIX_FMT_D3D11VA_VLD. The new D3D11 + * hwaccel API and filtering support AV_PIX_FMT_D3D11 only. + * + * data[0] contains a ID3D11Texture2D pointer, and data[1] contains the + * texture array index of the frame as intptr_t if the ID3D11Texture2D is + * an array texture (or always 0 if it's a normal texture). + */ + AV_PIX_FMT_D3D11, + + AV_PIX_FMT_GRAY9BE, ///< Y , 9bpp, big-endian + AV_PIX_FMT_GRAY9LE, ///< Y , 9bpp, little-endian + + AV_PIX_FMT_GBRPF32BE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, big-endian + AV_PIX_FMT_GBRPF32LE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, little-endian + AV_PIX_FMT_GBRAPF32BE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, big-endian + AV_PIX_FMT_GBRAPF32LE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, little-endian + + /** + * DRM-managed buffers exposed through PRIME buffer sharing. + * + * data[0] points to an AVDRMFrameDescriptor. + */ + AV_PIX_FMT_DRM_PRIME, + /** + * Hardware surfaces for OpenCL. + * + * data[i] contain 2D image objects (typed in C as cl_mem, used + * in OpenCL as image2d_t) for each plane of the surface. + */ + AV_PIX_FMT_OPENCL, + + AV_PIX_FMT_GRAY14BE, ///< Y , 14bpp, big-endian + AV_PIX_FMT_GRAY14LE, ///< Y , 14bpp, little-endian + + AV_PIX_FMT_GRAYF32BE, ///< IEEE-754 single precision Y, 32bpp, big-endian + AV_PIX_FMT_GRAYF32LE, ///< IEEE-754 single precision Y, 32bpp, little-endian + + AV_PIX_FMT_YUVA422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), 12b alpha, big-endian + AV_PIX_FMT_YUVA422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), 12b alpha, little-endian + AV_PIX_FMT_YUVA444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, big-endian + AV_PIX_FMT_YUVA444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, little-endian + + AV_PIX_FMT_NV24, ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) + AV_PIX_FMT_NV42, ///< as above, but U and V bytes are swapped + + AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions +}; + +#if AV_HAVE_BIGENDIAN +# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##be +#else +# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##le +#endif + +#define AV_PIX_FMT_RGB32 AV_PIX_FMT_NE(ARGB, BGRA) +#define AV_PIX_FMT_RGB32_1 AV_PIX_FMT_NE(RGBA, ABGR) +#define AV_PIX_FMT_BGR32 AV_PIX_FMT_NE(ABGR, RGBA) +#define AV_PIX_FMT_BGR32_1 AV_PIX_FMT_NE(BGRA, ARGB) +#define AV_PIX_FMT_0RGB32 AV_PIX_FMT_NE(0RGB, BGR0) +#define AV_PIX_FMT_0BGR32 AV_PIX_FMT_NE(0BGR, RGB0) + +#define AV_PIX_FMT_GRAY9 AV_PIX_FMT_NE(GRAY9BE, GRAY9LE) +#define AV_PIX_FMT_GRAY10 AV_PIX_FMT_NE(GRAY10BE, GRAY10LE) +#define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE) +#define AV_PIX_FMT_GRAY14 AV_PIX_FMT_NE(GRAY14BE, GRAY14LE) +#define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE) +#define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE) +#define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE) +#define AV_PIX_FMT_RGB565 AV_PIX_FMT_NE(RGB565BE, RGB565LE) +#define AV_PIX_FMT_RGB555 AV_PIX_FMT_NE(RGB555BE, RGB555LE) +#define AV_PIX_FMT_RGB444 AV_PIX_FMT_NE(RGB444BE, RGB444LE) +#define AV_PIX_FMT_RGBA64 AV_PIX_FMT_NE(RGBA64BE, RGBA64LE) +#define AV_PIX_FMT_BGR48 AV_PIX_FMT_NE(BGR48BE, BGR48LE) +#define AV_PIX_FMT_BGR565 AV_PIX_FMT_NE(BGR565BE, BGR565LE) +#define AV_PIX_FMT_BGR555 AV_PIX_FMT_NE(BGR555BE, BGR555LE) +#define AV_PIX_FMT_BGR444 AV_PIX_FMT_NE(BGR444BE, BGR444LE) +#define AV_PIX_FMT_BGRA64 AV_PIX_FMT_NE(BGRA64BE, BGRA64LE) + +#define AV_PIX_FMT_YUV420P9 AV_PIX_FMT_NE(YUV420P9BE , YUV420P9LE) +#define AV_PIX_FMT_YUV422P9 AV_PIX_FMT_NE(YUV422P9BE , YUV422P9LE) +#define AV_PIX_FMT_YUV444P9 AV_PIX_FMT_NE(YUV444P9BE , YUV444P9LE) +#define AV_PIX_FMT_YUV420P10 AV_PIX_FMT_NE(YUV420P10BE, YUV420P10LE) +#define AV_PIX_FMT_YUV422P10 AV_PIX_FMT_NE(YUV422P10BE, YUV422P10LE) +#define AV_PIX_FMT_YUV440P10 AV_PIX_FMT_NE(YUV440P10BE, YUV440P10LE) +#define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE) +#define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE) +#define AV_PIX_FMT_YUV422P12 AV_PIX_FMT_NE(YUV422P12BE, YUV422P12LE) +#define AV_PIX_FMT_YUV440P12 AV_PIX_FMT_NE(YUV440P12BE, YUV440P12LE) +#define AV_PIX_FMT_YUV444P12 AV_PIX_FMT_NE(YUV444P12BE, YUV444P12LE) +#define AV_PIX_FMT_YUV420P14 AV_PIX_FMT_NE(YUV420P14BE, YUV420P14LE) +#define AV_PIX_FMT_YUV422P14 AV_PIX_FMT_NE(YUV422P14BE, YUV422P14LE) +#define AV_PIX_FMT_YUV444P14 AV_PIX_FMT_NE(YUV444P14BE, YUV444P14LE) +#define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE) +#define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) +#define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) + +#define AV_PIX_FMT_GBRP9 AV_PIX_FMT_NE(GBRP9BE , GBRP9LE) +#define AV_PIX_FMT_GBRP10 AV_PIX_FMT_NE(GBRP10BE, GBRP10LE) +#define AV_PIX_FMT_GBRP12 AV_PIX_FMT_NE(GBRP12BE, GBRP12LE) +#define AV_PIX_FMT_GBRP14 AV_PIX_FMT_NE(GBRP14BE, GBRP14LE) +#define AV_PIX_FMT_GBRP16 AV_PIX_FMT_NE(GBRP16BE, GBRP16LE) +#define AV_PIX_FMT_GBRAP10 AV_PIX_FMT_NE(GBRAP10BE, GBRAP10LE) +#define AV_PIX_FMT_GBRAP12 AV_PIX_FMT_NE(GBRAP12BE, GBRAP12LE) +#define AV_PIX_FMT_GBRAP16 AV_PIX_FMT_NE(GBRAP16BE, GBRAP16LE) + +#define AV_PIX_FMT_BAYER_BGGR16 AV_PIX_FMT_NE(BAYER_BGGR16BE, BAYER_BGGR16LE) +#define AV_PIX_FMT_BAYER_RGGB16 AV_PIX_FMT_NE(BAYER_RGGB16BE, BAYER_RGGB16LE) +#define AV_PIX_FMT_BAYER_GBRG16 AV_PIX_FMT_NE(BAYER_GBRG16BE, BAYER_GBRG16LE) +#define AV_PIX_FMT_BAYER_GRBG16 AV_PIX_FMT_NE(BAYER_GRBG16BE, BAYER_GRBG16LE) + +#define AV_PIX_FMT_GBRPF32 AV_PIX_FMT_NE(GBRPF32BE, GBRPF32LE) +#define AV_PIX_FMT_GBRAPF32 AV_PIX_FMT_NE(GBRAPF32BE, GBRAPF32LE) + +#define AV_PIX_FMT_GRAYF32 AV_PIX_FMT_NE(GRAYF32BE, GRAYF32LE) + +#define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE) +#define AV_PIX_FMT_YUVA422P9 AV_PIX_FMT_NE(YUVA422P9BE , YUVA422P9LE) +#define AV_PIX_FMT_YUVA444P9 AV_PIX_FMT_NE(YUVA444P9BE , YUVA444P9LE) +#define AV_PIX_FMT_YUVA420P10 AV_PIX_FMT_NE(YUVA420P10BE, YUVA420P10LE) +#define AV_PIX_FMT_YUVA422P10 AV_PIX_FMT_NE(YUVA422P10BE, YUVA422P10LE) +#define AV_PIX_FMT_YUVA444P10 AV_PIX_FMT_NE(YUVA444P10BE, YUVA444P10LE) +#define AV_PIX_FMT_YUVA422P12 AV_PIX_FMT_NE(YUVA422P12BE, YUVA422P12LE) +#define AV_PIX_FMT_YUVA444P12 AV_PIX_FMT_NE(YUVA444P12BE, YUVA444P12LE) +#define AV_PIX_FMT_YUVA420P16 AV_PIX_FMT_NE(YUVA420P16BE, YUVA420P16LE) +#define AV_PIX_FMT_YUVA422P16 AV_PIX_FMT_NE(YUVA422P16BE, YUVA422P16LE) +#define AV_PIX_FMT_YUVA444P16 AV_PIX_FMT_NE(YUVA444P16BE, YUVA444P16LE) + +#define AV_PIX_FMT_XYZ12 AV_PIX_FMT_NE(XYZ12BE, XYZ12LE) +#define AV_PIX_FMT_NV20 AV_PIX_FMT_NE(NV20BE, NV20LE) +#define AV_PIX_FMT_AYUV64 AV_PIX_FMT_NE(AYUV64BE, AYUV64LE) +#define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE) +#define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE) + +/** + * Chromaticity coordinates of the source primaries. + * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1. + */ +enum AVColorPrimaries { + AVCOL_PRI_RESERVED0 = 0, + AVCOL_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B + AVCOL_PRI_UNSPECIFIED = 2, + AVCOL_PRI_RESERVED = 3, + AVCOL_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + + AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM + AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above + AVCOL_PRI_FILM = 8, ///< colour filters using Illuminant C + AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020 + AVCOL_PRI_SMPTE428 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ) + AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, + AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 + AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 + AVCOL_PRI_JEDEC_P22 = 22, ///< JEDEC P22 phosphors + AVCOL_PRI_NB ///< Not part of ABI +}; + +/** + * Color Transfer Characteristic. + * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.2. + */ +enum AVColorTransferCharacteristic { + AVCOL_TRC_RESERVED0 = 0, + AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 + AVCOL_TRC_UNSPECIFIED = 2, + AVCOL_TRC_RESERVED = 3, + AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM + AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG + AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC + AVCOL_TRC_SMPTE240M = 7, + AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics" + AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" + AVCOL_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)" + AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 + AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut + AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) + AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10-bit system + AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12-bit system + AVCOL_TRC_SMPTE2084 = 16, ///< SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems + AVCOL_TRC_SMPTEST2084 = AVCOL_TRC_SMPTE2084, + AVCOL_TRC_SMPTE428 = 17, ///< SMPTE ST 428-1 + AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428, + AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma" + AVCOL_TRC_NB ///< Not part of ABI +}; + +/** + * YUV colorspace type. + * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.3. + */ +enum AVColorSpace { + AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) + AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B + AVCOL_SPC_UNSPECIFIED = 2, + AVCOL_SPC_RESERVED = 3, + AVCOL_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + AVCOL_SPC_SMPTE240M = 7, ///< functionally identical to above + AVCOL_SPC_YCGCO = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + AVCOL_SPC_YCOCG = AVCOL_SPC_YCGCO, + AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system + AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system + AVCOL_SPC_SMPTE2085 = 11, ///< SMPTE 2085, Y'D'zD'x + AVCOL_SPC_CHROMA_DERIVED_NCL = 12, ///< Chromaticity-derived non-constant luminance system + AVCOL_SPC_CHROMA_DERIVED_CL = 13, ///< Chromaticity-derived constant luminance system + AVCOL_SPC_ICTCP = 14, ///< ITU-R BT.2100-0, ICtCp + AVCOL_SPC_NB ///< Not part of ABI +}; + +/** + * MPEG vs JPEG YUV range. + */ +enum AVColorRange { + AVCOL_RANGE_UNSPECIFIED = 0, + AVCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges + AVCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges + AVCOL_RANGE_NB ///< Not part of ABI +}; + +/** + * Location of chroma samples. + * + * Illustration showing the location of the first (top left) chroma sample of the + * image, the left shows only luma, the right + * shows the location of the chroma sample, the 2 could be imagined to overlay + * each other but are drawn separately due to limitations of ASCII + * + * 1st 2nd 1st 2nd horizontal luma sample positions + * v v v v + * ______ ______ + *1st luma line > |X X ... |3 4 X ... X are luma samples, + * | |1 2 1-6 are possible chroma positions + *2nd luma line > |X X ... |5 6 X ... 0 is undefined/unknown position + */ +enum AVChromaLocation { + AVCHROMA_LOC_UNSPECIFIED = 0, + AVCHROMA_LOC_LEFT = 1, ///< MPEG-2/4 4:2:0, H.264 default for 4:2:0 + AVCHROMA_LOC_CENTER = 2, ///< MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0 + AVCHROMA_LOC_TOPLEFT = 3, ///< ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2 + AVCHROMA_LOC_TOP = 4, + AVCHROMA_LOC_BOTTOMLEFT = 5, + AVCHROMA_LOC_BOTTOM = 6, + AVCHROMA_LOC_NB ///< Not part of ABI +}; + +#endif /* AVUTIL_PIXFMT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/qsort.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/qsort.h new file mode 100644 index 000000000..39b7a0885 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/qsort.h @@ -0,0 +1,122 @@ +/* + * copyright (c) 2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_QSORT_H +#define AVUTIL_QSORT_H + +#include "common.h" + + +/** + * Quicksort + * This sort is fast, and fully inplace but not stable and it is possible + * to construct input that requires O(n^2) time but this is very unlikely to + * happen with non constructed input. + */ +#define AV_QSORT(p, num, type, cmp) do {\ + void *stack[64][2];\ + int sp= 1;\ + stack[0][0] = p;\ + stack[0][1] = (p)+(num)-1;\ + while(sp){\ + type *start= stack[--sp][0];\ + type *end = stack[ sp][1];\ + while(start < end){\ + if(start < end-1) {\ + int checksort=0;\ + type *right = end-2;\ + type *left = start+1;\ + type *mid = start + ((end-start)>>1);\ + if(cmp(start, end) > 0) {\ + if(cmp( end, mid) > 0) FFSWAP(type, *start, *mid);\ + else FFSWAP(type, *start, *end);\ + }else{\ + if(cmp(start, mid) > 0) FFSWAP(type, *start, *mid);\ + else checksort= 1;\ + }\ + if(cmp(mid, end) > 0){ \ + FFSWAP(type, *mid, *end);\ + checksort=0;\ + }\ + if(start == end-2) break;\ + FFSWAP(type, end[-1], *mid);\ + while(left <= right){\ + while(left<=right && cmp(left, end-1) < 0)\ + left++;\ + while(left<=right && cmp(right, end-1) > 0)\ + right--;\ + if(left <= right){\ + FFSWAP(type, *left, *right);\ + left++;\ + right--;\ + }\ + }\ + FFSWAP(type, end[-1], *left);\ + if(checksort && (mid == left-1 || mid == left)){\ + mid= start;\ + while(mid 0)\ + FFSWAP(type, *start, *end);\ + break;\ + }\ + }\ + }\ +} while (0) + +/** + * Merge sort, this sort requires a temporary buffer and is stable, its worst + * case time is O(n log n) + * @param p must be a lvalue pointer, this function may exchange it with tmp + * @param tmp must be a lvalue pointer, this function may exchange it with p + */ +#define AV_MSORT(p, tmp, num, type, cmp) do {\ + unsigned i, j, step;\ + for(step=1; step<(num); step+=step){\ + for(i=0; i<(num); i+=2*step){\ + unsigned a[2] = {i, i+step};\ + unsigned end = FFMIN(i+2*step, (num));\ + for(j=i; a[0] 0;\ + tmp[j] = p[ a[idx]++ ];\ + }\ + if(a[0]>=i+step) a[0] = a[1];\ + for(; j + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_IO_H +#include +#endif +#if HAVE_BCRYPT +#include +#include +#endif +#include +#include +#include +#include +#include "avassert.h" +#include "internal.h" +#include "intreadwrite.h" +#include "timer.h" +#include "random_seed.h" +#include "sha.h" + +#ifndef TEST +#define TEST 0 +#endif + +static int read_random(uint32_t *dst, const char *file) +{ +#if HAVE_UNISTD_H + int fd = avpriv_open(file, O_RDONLY); + int err = -1; + + if (fd == -1) + return -1; + err = read(fd, dst, sizeof(*dst)); + close(fd); + + return err; +#else + return -1; +#endif +} + +static uint32_t get_generic_seed(void) +{ + uint64_t tmp[120/8]; + struct AVSHA *sha = (void*)tmp; + clock_t last_t = 0; + clock_t last_td = 0; + clock_t init_t = 0; + static uint64_t i = 0; + static uint32_t buffer[512] = { 0 }; + unsigned char digest[20]; + uint64_t last_i = i; + + av_assert0(sizeof(tmp) >= av_sha_size); + + if(TEST){ + memset(buffer, 0, sizeof(buffer)); + last_i = i = 0; + }else{ +#ifdef AV_READ_TIME + buffer[13] ^= AV_READ_TIME(); + buffer[41] ^= AV_READ_TIME()>>32; +#endif + } + + for (;;) { + clock_t t = clock(); + if (last_t + 2*last_td + (CLOCKS_PER_SEC > 1000) >= t) { + last_td = t - last_t; + buffer[i & 511] = 1664525*buffer[i & 511] + 1013904223 + (last_td % 3294638521U); + } else { + last_td = t - last_t; + buffer[++i & 511] += last_td % 3294638521U; + if ((t - init_t) >= CLOCKS_PER_SEC>>5) + if (last_i && i - last_i > 4 || i - last_i > 64 || TEST && i - last_i > 8) + break; + } + last_t = t; + if (!init_t) + init_t = t; + } + + if(TEST) { + buffer[0] = buffer[1] = 0; + } else { +#ifdef AV_READ_TIME + buffer[111] += AV_READ_TIME(); +#endif + } + + av_sha_init(sha, 160); + av_sha_update(sha, (const uint8_t *)buffer, sizeof(buffer)); + av_sha_final(sha, digest); + return AV_RB32(digest) + AV_RB32(digest + 16); +} + +uint32_t av_get_random_seed(void) +{ + uint32_t seed; + +#if HAVE_BCRYPT + BCRYPT_ALG_HANDLE algo_handle; + NTSTATUS ret = BCryptOpenAlgorithmProvider(&algo_handle, BCRYPT_RNG_ALGORITHM, + MS_PRIMITIVE_PROVIDER, 0); + if (BCRYPT_SUCCESS(ret)) { + NTSTATUS ret = BCryptGenRandom(algo_handle, (UCHAR*)&seed, sizeof(seed), 0); + BCryptCloseAlgorithmProvider(algo_handle, 0); + if (BCRYPT_SUCCESS(ret)) + return seed; + } +#endif + +#if HAVE_ARC4RANDOM + return arc4random(); +#endif + + if (read_random(&seed, "/dev/urandom") == sizeof(seed)) + return seed; + if (read_random(&seed, "/dev/random") == sizeof(seed)) + return seed; + return get_generic_seed(); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/random_seed.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/random_seed.h new file mode 100644 index 000000000..0462a048e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/random_seed.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2009 Baptiste Coudurier + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RANDOM_SEED_H +#define AVUTIL_RANDOM_SEED_H + +#include +/** + * @addtogroup lavu_crypto + * @{ + */ + +/** + * Get a seed to use in conjunction with random functions. + * This function tries to provide a good seed at a best effort bases. + * Its possible to call this function multiple times if more bits are needed. + * It can be quite slow, which is why it should only be used as seed for a faster + * PRNG. The quality of the seed depends on the platform. + */ +uint32_t av_get_random_seed(void); + +/** + * @} + */ + +#endif /* AVUTIL_RANDOM_SEED_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rational.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rational.c new file mode 100644 index 000000000..35ee08877 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rational.c @@ -0,0 +1,184 @@ +/* + * rational numbers + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * rational numbers + * @author Michael Niedermayer + */ + +#include "avassert.h" +#include + +#include "common.h" +#include "mathematics.h" +#include "rational.h" + +int av_reduce(int *dst_num, int *dst_den, + int64_t num, int64_t den, int64_t max) +{ + AVRational a0 = { 0, 1 }, a1 = { 1, 0 }; + int sign = (num < 0) ^ (den < 0); + int64_t gcd = av_gcd(FFABS(num), FFABS(den)); + + if (gcd) { + num = FFABS(num) / gcd; + den = FFABS(den) / gcd; + } + if (num <= max && den <= max) { + a1 = (AVRational) { num, den }; + den = 0; + } + + while (den) { + uint64_t x = num / den; + int64_t next_den = num - den * x; + int64_t a2n = x * a1.num + a0.num; + int64_t a2d = x * a1.den + a0.den; + + if (a2n > max || a2d > max) { + if (a1.num) x = (max - a0.num) / a1.num; + if (a1.den) x = FFMIN(x, (max - a0.den) / a1.den); + + if (den * (2 * x * a1.den + a0.den) > num * a1.den) + a1 = (AVRational) { x * a1.num + a0.num, x * a1.den + a0.den }; + break; + } + + a0 = a1; + a1 = (AVRational) { a2n, a2d }; + num = den; + den = next_den; + } + av_assert2(av_gcd(a1.num, a1.den) <= 1U); + av_assert2(a1.num <= max && a1.den <= max); + + *dst_num = sign ? -a1.num : a1.num; + *dst_den = a1.den; + + return den == 0; +} + +AVRational av_mul_q(AVRational b, AVRational c) +{ + av_reduce(&b.num, &b.den, + b.num * (int64_t) c.num, + b.den * (int64_t) c.den, INT_MAX); + return b; +} + +AVRational av_div_q(AVRational b, AVRational c) +{ + return av_mul_q(b, (AVRational) { c.den, c.num }); +} + +AVRational av_add_q(AVRational b, AVRational c) { + av_reduce(&b.num, &b.den, + b.num * (int64_t) c.den + + c.num * (int64_t) b.den, + b.den * (int64_t) c.den, INT_MAX); + return b; +} + +AVRational av_sub_q(AVRational b, AVRational c) +{ + return av_add_q(b, (AVRational) { -c.num, c.den }); +} + +AVRational av_d2q(double d, int max) +{ + AVRational a; + int exponent; + int64_t den; + if (isnan(d)) + return (AVRational) { 0,0 }; + if (fabs(d) > INT_MAX + 3LL) + return (AVRational) { d < 0 ? -1 : 1, 0 }; + frexp(d, &exponent); + exponent = FFMAX(exponent-1, 0); + den = 1LL << (61 - exponent); + // (int64_t)rint() and llrint() do not work with gcc on ia64 and sparc64, + // see Ticket2713 for affected gcc/glibc versions + av_reduce(&a.num, &a.den, floor(d * den + 0.5), den, max); + if ((!a.num || !a.den) && d && max>0 && max n => a*d/b > n */ + int64_t x_up = av_rescale_rnd(a, q.den, b, AV_ROUND_UP); + + /* rnd_down(a*d/b) < n => a*d/b < n */ + int64_t x_down = av_rescale_rnd(a, q.den, b, AV_ROUND_DOWN); + + return ((x_up > q.num) - (x_down < q.num)) * av_cmp_q(q2, q1); +} + +int av_find_nearest_q_idx(AVRational q, const AVRational* q_list) +{ + int i, nearest_q_idx = 0; + for (i = 0; q_list[i].den; i++) + if (av_nearer_q(q, q_list[i], q_list[nearest_q_idx]) > 0) + nearest_q_idx = i; + + return nearest_q_idx; +} + +uint32_t av_q2intfloat(AVRational q) { + int64_t n; + int shift; + int sign = 0; + + if (q.den < 0) { + q.den *= -1; + q.num *= -1; + } + if (q.num < 0) { + q.num *= -1; + sign = 1; + } + + if (!q.num && !q.den) return 0xFFC00000; + if (!q.num) return 0; + if (!q.den) return 0x7F800000 | (q.num & 0x80000000); + + shift = 23 + av_log2(q.den) - av_log2(q.num); + if (shift >= 0) n = av_rescale(q.num, 1LL<= (1<<24); + shift += n < (1<<23); + + if (shift >= 0) n = av_rescale(q.num, 1LL<= (1<<23)); + + return sign<<31 | (150-shift)<<23 | (n - (1<<23)); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rational.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rational.h new file mode 100644 index 000000000..5c6b67b4e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rational.h @@ -0,0 +1,214 @@ +/* + * rational numbers + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_math_rational + * Utilties for rational number calculation. + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_RATIONAL_H +#define AVUTIL_RATIONAL_H + +#include +#include +#include "attributes.h" + +/** + * @defgroup lavu_math_rational AVRational + * @ingroup lavu_math + * Rational number calculation. + * + * While rational numbers can be expressed as floating-point numbers, the + * conversion process is a lossy one, so are floating-point operations. On the + * other hand, the nature of FFmpeg demands highly accurate calculation of + * timestamps. This set of rational number utilities serves as a generic + * interface for manipulating rational numbers as pairs of numerators and + * denominators. + * + * Many of the functions that operate on AVRational's have the suffix `_q`, in + * reference to the mathematical symbol "â„š" (Q) which denotes the set of all + * rational numbers. + * + * @{ + */ + +/** + * Rational number (pair of numerator and denominator). + */ +typedef struct AVRational{ + int num; ///< Numerator + int den; ///< Denominator +} AVRational; + +/** + * Create an AVRational. + * + * Useful for compilers that do not support compound literals. + * + * @note The return value is not reduced. + * @see av_reduce() + */ +static inline AVRational av_make_q(int num, int den) +{ + AVRational r = { num, den }; + return r; +} + +/** + * Compare two rationals. + * + * @param a First rational + * @param b Second rational + * + * @return One of the following values: + * - 0 if `a == b` + * - 1 if `a > b` + * - -1 if `a < b` + * - `INT_MIN` if one of the values is of the form `0 / 0` + */ +static inline int av_cmp_q(AVRational a, AVRational b){ + const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den; + + if(tmp) return (int)((tmp ^ a.den ^ b.den)>>63)|1; + else if(b.den && a.den) return 0; + else if(a.num && b.num) return (a.num>>31) - (b.num>>31); + else return INT_MIN; +} + +/** + * Convert an AVRational to a `double`. + * @param a AVRational to convert + * @return `a` in floating-point form + * @see av_d2q() + */ +static inline double av_q2d(AVRational a){ + return a.num / (double) a.den; +} + +/** + * Reduce a fraction. + * + * This is useful for framerate calculations. + * + * @param[out] dst_num Destination numerator + * @param[out] dst_den Destination denominator + * @param[in] num Source numerator + * @param[in] den Source denominator + * @param[in] max Maximum allowed values for `dst_num` & `dst_den` + * @return 1 if the operation is exact, 0 otherwise + */ +int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max); + +/** + * Multiply two rationals. + * @param b First rational + * @param c Second rational + * @return b*c + */ +AVRational av_mul_q(AVRational b, AVRational c) av_const; + +/** + * Divide one rational by another. + * @param b First rational + * @param c Second rational + * @return b/c + */ +AVRational av_div_q(AVRational b, AVRational c) av_const; + +/** + * Add two rationals. + * @param b First rational + * @param c Second rational + * @return b+c + */ +AVRational av_add_q(AVRational b, AVRational c) av_const; + +/** + * Subtract one rational from another. + * @param b First rational + * @param c Second rational + * @return b-c + */ +AVRational av_sub_q(AVRational b, AVRational c) av_const; + +/** + * Invert a rational. + * @param q value + * @return 1 / q + */ +static av_always_inline AVRational av_inv_q(AVRational q) +{ + AVRational r = { q.den, q.num }; + return r; +} + +/** + * Convert a double precision floating point number to a rational. + * + * In case of infinity, the returned value is expressed as `{1, 0}` or + * `{-1, 0}` depending on the sign. + * + * @param d `double` to convert + * @param max Maximum allowed numerator and denominator + * @return `d` in AVRational form + * @see av_q2d() + */ +AVRational av_d2q(double d, int max) av_const; + +/** + * Find which of the two rationals is closer to another rational. + * + * @param q Rational to be compared against + * @param q1,q2 Rationals to be tested + * @return One of the following values: + * - 1 if `q1` is nearer to `q` than `q2` + * - -1 if `q2` is nearer to `q` than `q1` + * - 0 if they have the same distance + */ +int av_nearer_q(AVRational q, AVRational q1, AVRational q2); + +/** + * Find the value in a list of rationals nearest a given reference rational. + * + * @param q Reference rational + * @param q_list Array of rationals terminated by `{0, 0}` + * @return Index of the nearest value found in the array + */ +int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); + +/** + * Convert an AVRational to a IEEE 32-bit `float` expressed in fixed-point + * format. + * + * @param q Rational to be converted + * @return Equivalent floating-point value, expressed as an unsigned 32-bit + * integer. + * @note The returned value is platform-indepedant. + */ +uint32_t av_q2intfloat(AVRational q); + +/** + * @} + */ + +#endif /* AVUTIL_RATIONAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.c new file mode 100644 index 000000000..ffcb11214 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.c @@ -0,0 +1,65 @@ +/* + * RC4 encryption/decryption/pseudo-random number generator + * Copyright (c) 2007 Reimar Doeffinger + * + * loosely based on LibTomCrypt by Tom St Denis + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avutil.h" +#include "common.h" +#include "mem.h" +#include "rc4.h" + +AVRC4 *av_rc4_alloc(void) +{ + return av_mallocz(sizeof(struct AVRC4)); +} + +int av_rc4_init(AVRC4 *r, const uint8_t *key, int key_bits, int decrypt) { + int i, j; + uint8_t y; + uint8_t *state = r->state; + int keylen = key_bits >> 3; + if (key_bits & 7) + return AVERROR(EINVAL); + for (i = 0; i < 256; i++) + state[i] = i; + y = 0; + // j is i % keylen + for (j = 0, i = 0; i < 256; i++, j++) { + if (j == keylen) j = 0; + y += state[i] + key[j]; + FFSWAP(uint8_t, state[i], state[y]); + } + r->x = 1; + r->y = state[1]; + return 0; +} + +void av_rc4_crypt(AVRC4 *r, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) { + uint8_t x = r->x, y = r->y; + uint8_t *state = r->state; + while (count-- > 0) { + uint8_t sum = state[x] + state[y]; + FFSWAP(uint8_t, state[x], state[y]); + *dst++ = src ? *src++ ^ state[sum] : state[sum]; + x++; + y += state[x]; + } + r->x = x; r->y = y; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.h new file mode 100644 index 000000000..029cd2ad5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/rc4.h @@ -0,0 +1,66 @@ +/* + * RC4 encryption/decryption/pseudo-random number generator + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RC4_H +#define AVUTIL_RC4_H + +#include + +/** + * @defgroup lavu_rc4 RC4 + * @ingroup lavu_crypto + * @{ + */ + +typedef struct AVRC4 { + uint8_t state[256]; + int x, y; +} AVRC4; + +/** + * Allocate an AVRC4 context. + */ +AVRC4 *av_rc4_alloc(void); + +/** + * @brief Initializes an AVRC4 context. + * + * @param key_bits must be a multiple of 8 + * @param decrypt 0 for encryption, 1 for decryption, currently has no effect + * @return zero on success, negative value otherwise + */ +int av_rc4_init(struct AVRC4 *d, const uint8_t *key, int key_bits, int decrypt); + +/** + * @brief Encrypts / decrypts using the RC4 algorithm. + * + * @param count number of bytes + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst, may be NULL + * @param iv not (yet) used for RC4, should be NULL + * @param decrypt 0 for encryption, 1 for decryption, not (yet) used + */ +void av_rc4_crypt(struct AVRC4 *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_RC4_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/replaygain.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/replaygain.h new file mode 100644 index 000000000..b49bf1a3d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/replaygain.h @@ -0,0 +1,50 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_REPLAYGAIN_H +#define AVUTIL_REPLAYGAIN_H + +#include + +/** + * ReplayGain information (see + * http://wiki.hydrogenaudio.org/index.php?title=ReplayGain_1.0_specification). + * The size of this struct is a part of the public ABI. + */ +typedef struct AVReplayGain { + /** + * Track replay gain in microbels (divide by 100000 to get the value in dB). + * Should be set to INT32_MIN when unknown. + */ + int32_t track_gain; + /** + * Peak track amplitude, with 100000 representing full scale (but values + * may overflow). 0 when unknown. + */ + uint32_t track_peak; + /** + * Same as track_gain, but for the whole album. + */ + int32_t album_gain; + /** + * Same as track_peak, but for the whole album, + */ + uint32_t album_peak; +} AVReplayGain; + +#endif /* AVUTIL_REPLAYGAIN_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/reverse.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/reverse.c new file mode 100644 index 000000000..105eb03dd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/reverse.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +const uint8_t ff_reverse[256] = { +0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0, +0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8, +0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4, +0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC, +0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2, +0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA, +0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6, +0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE, +0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1, +0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9, +0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5, +0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD, +0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3, +0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB, +0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7, +0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/reverse.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/reverse.h new file mode 100644 index 000000000..4eb612393 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/reverse.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_REVERSE_H +#define AVUTIL_REVERSE_H + +#include + +extern const uint8_t ff_reverse[256]; + +#endif /* AVUTIL_REVERSE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ripemd.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ripemd.c new file mode 100644 index 000000000..4f1c4ea89 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ripemd.c @@ -0,0 +1,555 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2013 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "attributes.h" +#include "avutil.h" +#include "bswap.h" +#include "intreadwrite.h" +#include "ripemd.h" +#include "mem.h" + +/** hash context */ +typedef struct AVRIPEMD { + uint8_t digest_len; ///< digest length in 32-bit words + uint64_t count; ///< number of bytes in buffer + uint8_t buffer[64]; ///< 512-bit buffer of input values used in hash updating + uint32_t state[10]; ///< current hash value + /** function used to update hash for 512-bit input block */ + void (*transform)(uint32_t *state, const uint8_t buffer[64]); +} AVRIPEMD; + +const int av_ripemd_size = sizeof(AVRIPEMD); + +struct AVRIPEMD *av_ripemd_alloc(void) +{ + return av_mallocz(sizeof(struct AVRIPEMD)); +} + +static const uint32_t KA[4] = { + 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e +}; + +static const uint32_t KB[4] = { + 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9 +}; + +static const int ROTA[80] = { + 11, 14, 15, 12, 5, 8, 7 , 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7 , 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 +}; + +static const int ROTB[80] = { + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 +}; + +static const int WA[80] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 +}; + +static const int WB[80] = { + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 +}; + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +#define ROUND128_0_TO_15(a,b,c,d,e,f,g,h) \ + a = rol(a + (( b ^ c ^ d) + block[WA[n]]), ROTA[n]); \ + e = rol(e + ((((f ^ g) & h) ^ g) + block[WB[n]] + KB[0]), ROTB[n]); \ + n++ + +#define ROUND128_16_TO_31(a,b,c,d,e,f,g,h) \ + a = rol(a + ((((c ^ d) & b) ^ d) + block[WA[n]] + KA[0]), ROTA[n]); \ + e = rol(e + (((~g | f) ^ h) + block[WB[n]] + KB[1]), ROTB[n]); \ + n++ + +#define ROUND128_32_TO_47(a,b,c,d,e,f,g,h) \ + a = rol(a + (((~c | b) ^ d) + block[WA[n]] + KA[1]), ROTA[n]); \ + e = rol(e + ((((g ^ h) & f) ^ h) + block[WB[n]] + KB[2]), ROTB[n]); \ + n++ + +#define ROUND128_48_TO_63(a,b,c,d,e,f,g,h) \ + a = rol(a + ((((b ^ c) & d) ^ c) + block[WA[n]] + KA[2]), ROTA[n]); \ + e = rol(e + (( f ^ g ^ h) + block[WB[n]]), ROTB[n]); \ + n++ + +#define R128_0 \ + ROUND128_0_TO_15(a,b,c,d,e,f,g,h); \ + ROUND128_0_TO_15(d,a,b,c,h,e,f,g); \ + ROUND128_0_TO_15(c,d,a,b,g,h,e,f); \ + ROUND128_0_TO_15(b,c,d,a,f,g,h,e) + +#define R128_16 \ + ROUND128_16_TO_31(a,b,c,d,e,f,g,h); \ + ROUND128_16_TO_31(d,a,b,c,h,e,f,g); \ + ROUND128_16_TO_31(c,d,a,b,g,h,e,f); \ + ROUND128_16_TO_31(b,c,d,a,f,g,h,e) + +#define R128_32 \ + ROUND128_32_TO_47(a,b,c,d,e,f,g,h); \ + ROUND128_32_TO_47(d,a,b,c,h,e,f,g); \ + ROUND128_32_TO_47(c,d,a,b,g,h,e,f); \ + ROUND128_32_TO_47(b,c,d,a,f,g,h,e) + +#define R128_48 \ + ROUND128_48_TO_63(a,b,c,d,e,f,g,h); \ + ROUND128_48_TO_63(d,a,b,c,h,e,f,g); \ + ROUND128_48_TO_63(c,d,a,b,g,h,e,f); \ + ROUND128_48_TO_63(b,c,d,a,f,g,h,e) + +static void ripemd128_transform(uint32_t *state, const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e, f, g, h, av_unused t; + uint32_t block[16]; + int n; + + a = e = state[0]; + b = f = state[1]; + c = g = state[2]; + d = h = state[3]; + + for (n = 0; n < 16; n++) + block[n] = AV_RL32(buffer + 4 * n); + n = 0; + +#if CONFIG_SMALL + for (; n < 16;) { + ROUND128_0_TO_15(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + + for (; n < 32;) { + ROUND128_16_TO_31(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + + for (; n < 48;) { + ROUND128_32_TO_47(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + + for (; n < 64;) { + ROUND128_48_TO_63(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } +#else + + R128_0; R128_0; R128_0; R128_0; + + R128_16; R128_16; R128_16; R128_16; + + R128_32; R128_32; R128_32; R128_32; + + R128_48; R128_48; R128_48; R128_48; +#endif + + h += c + state[1]; + state[1] = state[2] + d + e; + state[2] = state[3] + a + f; + state[3] = state[0] + b + g; + state[0] = h; +} + +static void ripemd256_transform(uint32_t *state, const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e, f, g, h, av_unused t; + uint32_t block[16]; + int n; + + a = state[0]; b = state[1]; c = state[2]; d = state[3]; + e = state[4]; f = state[5]; g = state[6]; h = state[7]; + + for (n = 0; n < 16; n++) + block[n] = AV_RL32(buffer + 4 * n); + n = 0; + +#if CONFIG_SMALL + for (; n < 16;) { + ROUND128_0_TO_15(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + FFSWAP(uint32_t, a, e); + + for (; n < 32;) { + ROUND128_16_TO_31(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + FFSWAP(uint32_t, b, f); + + for (; n < 48;) { + ROUND128_32_TO_47(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + FFSWAP(uint32_t, c, g); + + for (; n < 64;) { + ROUND128_48_TO_63(a,b,c,d,e,f,g,h); + t = d; d = c; c = b; b = a; a = t; + t = h; h = g; g = f; f = e; e = t; + } + FFSWAP(uint32_t, d, h); +#else + + R128_0; R128_0; R128_0; R128_0; + FFSWAP(uint32_t, a, e); + + R128_16; R128_16; R128_16; R128_16; + FFSWAP(uint32_t, b, f); + + R128_32; R128_32; R128_32; R128_32; + FFSWAP(uint32_t, c, g); + + R128_48; R128_48; R128_48; R128_48; + FFSWAP(uint32_t, d, h); +#endif + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; + state[4] += e; state[5] += f; state[6] += g; state[7] += h; +} + +#define ROTATE(x,y) \ + x = rol(x, 10); \ + y = rol(y, 10); \ + n++ + +#define ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + (( b ^ c ^ d) + block[WA[n]]), ROTA[n]) + e; \ + f = rol(f + (((~i | h) ^ g) + block[WB[n]] + KB[0]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + ((((c ^ d) & b) ^ d) + block[WA[n]] + KA[0]), ROTA[n]) + e; \ + f = rol(f + ((((g ^ h) & i) ^ h) + block[WB[n]] + KB[1]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + (((~c | b) ^ d) + block[WA[n]] + KA[1]), ROTA[n]) + e; \ + f = rol(f + (((~h | g) ^ i) + block[WB[n]] + KB[2]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + ((((b ^ c) & d) ^ c) + block[WA[n]] + KA[2]), ROTA[n]) + e; \ + f = rol(f + ((((h ^ i) & g) ^ i) + block[WB[n]] + KB[3]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j) \ + a = rol(a + (((~d | c) ^ b) + block[WA[n]] + KA[3]), ROTA[n]) + e; \ + f = rol(f + (( g ^ h ^ i) + block[WB[n]]), ROTB[n]) + j; \ + ROTATE(c,h) + +#define R160_0 \ + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); \ + ROUND160_0_TO_15(e,a,b,c,d,j,f,g,h,i); \ + ROUND160_0_TO_15(d,e,a,b,c,i,j,f,g,h); \ + ROUND160_0_TO_15(c,d,e,a,b,h,i,j,f,g); \ + ROUND160_0_TO_15(b,c,d,e,a,g,h,i,j,f) + +#define R160_16 \ + ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i); \ + ROUND160_16_TO_31(d,e,a,b,c,i,j,f,g,h); \ + ROUND160_16_TO_31(c,d,e,a,b,h,i,j,f,g); \ + ROUND160_16_TO_31(b,c,d,e,a,g,h,i,j,f); \ + ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j) + +#define R160_32 \ + ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h); \ + ROUND160_32_TO_47(c,d,e,a,b,h,i,j,f,g); \ + ROUND160_32_TO_47(b,c,d,e,a,g,h,i,j,f); \ + ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j); \ + ROUND160_32_TO_47(e,a,b,c,d,j,f,g,h,i) + +#define R160_48 \ + ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g); \ + ROUND160_48_TO_63(b,c,d,e,a,g,h,i,j,f); \ + ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j); \ + ROUND160_48_TO_63(e,a,b,c,d,j,f,g,h,i); \ + ROUND160_48_TO_63(d,e,a,b,c,i,j,f,g,h) + +#define R160_64 \ + ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f); \ + ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j); \ + ROUND160_64_TO_79(e,a,b,c,d,j,f,g,h,i); \ + ROUND160_64_TO_79(d,e,a,b,c,i,j,f,g,h); \ + ROUND160_64_TO_79(c,d,e,a,b,h,i,j,f,g) + +static void ripemd160_transform(uint32_t *state, const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e, f, g, h, i, j, av_unused t; + uint32_t block[16]; + int n; + + a = f = state[0]; + b = g = state[1]; + c = h = state[2]; + d = i = state[3]; + e = j = state[4]; + + for (n = 0; n < 16; n++) + block[n] = AV_RL32(buffer + 4 * n); + n = 0; + +#if CONFIG_SMALL + for (; n < 16;) { + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + + for (; n < 32;) { + ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + + for (; n < 48;) { + ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + + for (; n < 64;) { + ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + + for (; n < 80;) { + ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } +#else + + R160_0; R160_0; R160_0; + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); + + R160_16; R160_16; R160_16; + ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i); + + R160_32; R160_32; R160_32; + ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h); + + R160_48; R160_48; R160_48; + ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g); + + R160_64; R160_64; R160_64; + ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f); +#endif + + i += c + state[1]; + state[1] = state[2] + d + j; + state[2] = state[3] + e + f; + state[3] = state[4] + a + g; + state[4] = state[0] + b + h; + state[0] = i; +} + +static void ripemd320_transform(uint32_t *state, const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e, f, g, h, i, j, av_unused t; + uint32_t block[16]; + int n; + + a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; + f = state[5]; g = state[6]; h = state[7]; i = state[8]; j = state[9]; + + for (n = 0; n < 16; n++) + block[n] = AV_RL32(buffer + 4 * n); + n = 0; + +#if CONFIG_SMALL + for (; n < 16;) { + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, b, g); + + for (; n < 32;) { + ROUND160_16_TO_31(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, d, i); + + for (; n < 48;) { + ROUND160_32_TO_47(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, a, f); + + for (; n < 64;) { + ROUND160_48_TO_63(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, c, h); + + for (; n < 80;) { + ROUND160_64_TO_79(a,b,c,d,e,f,g,h,i,j); + t = e; e = d; d = c; c = b; b = a; a = t; + t = j; j = i; i = h; h = g; g = f; f = t; + } + FFSWAP(uint32_t, e, j); +#else + + R160_0; R160_0; R160_0; + ROUND160_0_TO_15(a,b,c,d,e,f,g,h,i,j); + FFSWAP(uint32_t, a, f); + + R160_16; R160_16; R160_16; + ROUND160_16_TO_31(e,a,b,c,d,j,f,g,h,i); + FFSWAP(uint32_t, b, g); + + R160_32; R160_32; R160_32; + ROUND160_32_TO_47(d,e,a,b,c,i,j,f,g,h); + FFSWAP(uint32_t, c, h); + + R160_48; R160_48; R160_48; + ROUND160_48_TO_63(c,d,e,a,b,h,i,j,f,g); + FFSWAP(uint32_t, d, i); + + R160_64; R160_64; R160_64; + ROUND160_64_TO_79(b,c,d,e,a,g,h,i,j,f); + FFSWAP(uint32_t, e, j); +#endif + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; + state[5] += f; state[6] += g; state[7] += h; state[8] += i; state[9] += j; +} + +av_cold int av_ripemd_init(AVRIPEMD *ctx, int bits) +{ + ctx->digest_len = bits >> 5; + switch (bits) { + case 128: // RIPEMD-128 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->transform = ripemd128_transform; + break; + case 160: // RIPEMD-160 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + ctx->transform = ripemd160_transform; + break; + case 256: // RIPEMD-256 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0x76543210; + ctx->state[5] = 0xFEDCBA98; + ctx->state[6] = 0x89ABCDEF; + ctx->state[7] = 0x01234567; + ctx->transform = ripemd256_transform; + break; + case 320: // RIPEMD-320 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + ctx->state[5] = 0x76543210; + ctx->state[6] = 0xFEDCBA98; + ctx->state[7] = 0x89ABCDEF; + ctx->state[8] = 0x01234567; + ctx->state[9] = 0x3C2D1E0F; + ctx->transform = ripemd320_transform; + break; + default: + return AVERROR(EINVAL); + } + ctx->count = 0; + return 0; +} + +#if FF_API_CRYPTO_SIZE_T +void av_ripemd_update(AVRIPEMD* ctx, const uint8_t* data, unsigned int len) +#else +void av_ripemd_update(AVRIPEMD* ctx, const uint8_t* data, size_t len) +#endif +{ + unsigned int i, j; + + j = ctx->count & 63; + ctx->count += len; +#if CONFIG_SMALL + for (i = 0; i < len; i++) { + ctx->buffer[j++] = data[i]; + if (64 == j) { + ctx->transform(ctx->state, ctx->buffer); + j = 0; + } + } +#else + if ((j + len) > 63) { + memcpy(&ctx->buffer[j], data, (i = 64 - j)); + ctx->transform(ctx->state, ctx->buffer); + for (; i + 63 < len; i += 64) + ctx->transform(ctx->state, &data[i]); + j = 0; + } else + i = 0; + memcpy(&ctx->buffer[j], &data[i], len - i); +#endif +} + +void av_ripemd_final(AVRIPEMD* ctx, uint8_t *digest) +{ + int i; + uint64_t finalcount = av_le2ne64(ctx->count << 3); + + av_ripemd_update(ctx, "\200", 1); + while ((ctx->count & 63) != 56) + av_ripemd_update(ctx, "", 1); + av_ripemd_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ + for (i = 0; i < ctx->digest_len; i++) + AV_WL32(digest + i*4, ctx->state[i]); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ripemd.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ripemd.h new file mode 100644 index 000000000..0db6858ff --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ripemd.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2013 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_ripemd + * Public header for RIPEMD hash function implementation. + */ + +#ifndef AVUTIL_RIPEMD_H +#define AVUTIL_RIPEMD_H + +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_ripemd RIPEMD + * @ingroup lavu_hash + * RIPEMD hash function implementation. + * + * @{ + */ + +extern const int av_ripemd_size; + +struct AVRIPEMD; + +/** + * Allocate an AVRIPEMD context. + */ +struct AVRIPEMD *av_ripemd_alloc(void); + +/** + * Initialize RIPEMD hashing. + * + * @param context pointer to the function context (of size av_ripemd_size) + * @param bits number of bits in digest (128, 160, 256 or 320 bits) + * @return zero if initialization succeeded, -1 otherwise + */ +int av_ripemd_init(struct AVRIPEMD* context, int bits); + +/** + * Update hash value. + * + * @param context hash function context + * @param data input data to update hash with + * @param len input data length + */ +#if FF_API_CRYPTO_SIZE_T +void av_ripemd_update(struct AVRIPEMD* context, const uint8_t* data, unsigned int len); +#else +void av_ripemd_update(struct AVRIPEMD* context, const uint8_t* data, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + */ +void av_ripemd_final(struct AVRIPEMD* context, uint8_t *digest); + +/** + * @} + */ + +#endif /* AVUTIL_RIPEMD_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/samplefmt.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/samplefmt.c new file mode 100644 index 000000000..fc077f644 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/samplefmt.c @@ -0,0 +1,254 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "common.h" +#include "samplefmt.h" + +#include +#include +#include + +typedef struct SampleFmtInfo { + char name[8]; + int bits; + int planar; + enum AVSampleFormat altform; ///< planar<->packed alternative form +} SampleFmtInfo; + +/** this table gives more information about formats */ +static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB] = { + [AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8, .planar = 0, .altform = AV_SAMPLE_FMT_U8P }, + [AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16, .planar = 0, .altform = AV_SAMPLE_FMT_S16P }, + [AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_S32P }, + [AV_SAMPLE_FMT_S64] = { .name = "s64", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_S64P }, + [AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_FLTP }, + [AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_DBLP }, + [AV_SAMPLE_FMT_U8P] = { .name = "u8p", .bits = 8, .planar = 1, .altform = AV_SAMPLE_FMT_U8 }, + [AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1, .altform = AV_SAMPLE_FMT_S16 }, + [AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_S32 }, + [AV_SAMPLE_FMT_S64P] = { .name = "s64p", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_S64 }, + [AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_FLT }, + [AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_DBL }, +}; + +const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return NULL; + return sample_fmt_info[sample_fmt].name; +} + +enum AVSampleFormat av_get_sample_fmt(const char *name) +{ + int i; + + for (i = 0; i < AV_SAMPLE_FMT_NB; i++) + if (!strcmp(sample_fmt_info[i].name, name)) + return i; + return AV_SAMPLE_FMT_NONE; +} + +enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return AV_SAMPLE_FMT_NONE; + if (sample_fmt_info[sample_fmt].planar == planar) + return sample_fmt; + return sample_fmt_info[sample_fmt].altform; +} + +enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return AV_SAMPLE_FMT_NONE; + if (sample_fmt_info[sample_fmt].planar) + return sample_fmt_info[sample_fmt].altform; + return sample_fmt; +} + +enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return AV_SAMPLE_FMT_NONE; + if (sample_fmt_info[sample_fmt].planar) + return sample_fmt; + return sample_fmt_info[sample_fmt].altform; +} + +char *av_get_sample_fmt_string (char *buf, int buf_size, enum AVSampleFormat sample_fmt) +{ + /* print header */ + if (sample_fmt < 0) + snprintf(buf, buf_size, "name " " depth"); + else if (sample_fmt < AV_SAMPLE_FMT_NB) { + SampleFmtInfo info = sample_fmt_info[sample_fmt]; + snprintf (buf, buf_size, "%-6s" " %2d ", info.name, info.bits); + } + + return buf; +} + +int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt) +{ + return sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB ? + 0 : sample_fmt_info[sample_fmt].bits >> 3; +} + +int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return 0; + return sample_fmt_info[sample_fmt].planar; +} + +int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align) +{ + int line_size; + int sample_size = av_get_bytes_per_sample(sample_fmt); + int planar = av_sample_fmt_is_planar(sample_fmt); + + /* validate parameter ranges */ + if (!sample_size || nb_samples <= 0 || nb_channels <= 0) + return AVERROR(EINVAL); + + /* auto-select alignment if not specified */ + if (!align) { + if (nb_samples > INT_MAX - 31) + return AVERROR(EINVAL); + align = 1; + nb_samples = FFALIGN(nb_samples, 32); + } + + /* check for integer overflow */ + if (nb_channels > INT_MAX / align || + (int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size) + return AVERROR(EINVAL); + + line_size = planar ? FFALIGN(nb_samples * sample_size, align) : + FFALIGN(nb_samples * sample_size * nb_channels, align); + if (linesize) + *linesize = line_size; + + return planar ? line_size * nb_channels : line_size; +} + +int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, + const uint8_t *buf, int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align) +{ + int ch, planar, buf_size, line_size; + + planar = av_sample_fmt_is_planar(sample_fmt); + buf_size = av_samples_get_buffer_size(&line_size, nb_channels, nb_samples, + sample_fmt, align); + if (buf_size < 0) + return buf_size; + + audio_data[0] = (uint8_t *)buf; + for (ch = 1; planar && ch < nb_channels; ch++) + audio_data[ch] = audio_data[ch-1] + line_size; + + if (linesize) + *linesize = line_size; + + return buf_size; +} + +int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align) +{ + uint8_t *buf; + int size = av_samples_get_buffer_size(NULL, nb_channels, nb_samples, + sample_fmt, align); + if (size < 0) + return size; + + buf = av_malloc(size); + if (!buf) + return AVERROR(ENOMEM); + + size = av_samples_fill_arrays(audio_data, linesize, buf, nb_channels, + nb_samples, sample_fmt, align); + if (size < 0) { + av_free(buf); + return size; + } + + av_samples_set_silence(audio_data, 0, nb_samples, nb_channels, sample_fmt); + + return size; +} + +int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align) +{ + int ret, nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1; + + *audio_data = av_calloc(nb_planes, sizeof(**audio_data)); + if (!*audio_data) + return AVERROR(ENOMEM); + ret = av_samples_alloc(*audio_data, linesize, nb_channels, + nb_samples, sample_fmt, align); + if (ret < 0) + av_freep(audio_data); + return ret; +} + +int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, + int src_offset, int nb_samples, int nb_channels, + enum AVSampleFormat sample_fmt) +{ + int planar = av_sample_fmt_is_planar(sample_fmt); + int planes = planar ? nb_channels : 1; + int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels); + int data_size = nb_samples * block_align; + int i; + + dst_offset *= block_align; + src_offset *= block_align; + + if((dst[0] < src[0] ? src[0] - dst[0] : dst[0] - src[0]) >= data_size) { + for (i = 0; i < planes; i++) + memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size); + } else { + for (i = 0; i < planes; i++) + memmove(dst[i] + dst_offset, src[i] + src_offset, data_size); + } + + return 0; +} + +int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, + int nb_channels, enum AVSampleFormat sample_fmt) +{ + int planar = av_sample_fmt_is_planar(sample_fmt); + int planes = planar ? nb_channels : 1; + int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels); + int data_size = nb_samples * block_align; + int fill_char = (sample_fmt == AV_SAMPLE_FMT_U8 || + sample_fmt == AV_SAMPLE_FMT_U8P) ? 0x80 : 0x00; + int i; + + offset *= block_align; + + for (i = 0; i < planes; i++) + memset(audio_data[i] + offset, fill_char, data_size); + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/samplefmt.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/samplefmt.h new file mode 100644 index 000000000..8cd43ae85 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/samplefmt.h @@ -0,0 +1,272 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SAMPLEFMT_H +#define AVUTIL_SAMPLEFMT_H + +#include + +#include "avutil.h" +#include "attributes.h" + +/** + * @addtogroup lavu_audio + * @{ + * + * @defgroup lavu_sampfmts Audio sample formats + * + * Audio sample format enumeration and related convenience functions. + * @{ + */ + +/** + * Audio sample formats + * + * - The data described by the sample format is always in native-endian order. + * Sample values can be expressed by native C types, hence the lack of a signed + * 24-bit sample format even though it is a common raw audio data format. + * + * - The floating-point formats are based on full volume being in the range + * [-1.0, 1.0]. Any values outside this range are beyond full volume level. + * + * - The data layout as used in av_samples_fill_arrays() and elsewhere in FFmpeg + * (such as AVFrame in libavcodec) is as follows: + * + * @par + * For planar sample formats, each audio channel is in a separate data plane, + * and linesize is the buffer size, in bytes, for a single plane. All data + * planes must be the same size. For packed sample formats, only the first data + * plane is used, and samples for each channel are interleaved. In this case, + * linesize is the buffer size, in bytes, for the 1 plane. + * + */ +enum AVSampleFormat { + AV_SAMPLE_FMT_NONE = -1, + AV_SAMPLE_FMT_U8, ///< unsigned 8 bits + AV_SAMPLE_FMT_S16, ///< signed 16 bits + AV_SAMPLE_FMT_S32, ///< signed 32 bits + AV_SAMPLE_FMT_FLT, ///< float + AV_SAMPLE_FMT_DBL, ///< double + + AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar + AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar + AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar + AV_SAMPLE_FMT_FLTP, ///< float, planar + AV_SAMPLE_FMT_DBLP, ///< double, planar + AV_SAMPLE_FMT_S64, ///< signed 64 bits + AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar + + AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically +}; + +/** + * Return the name of sample_fmt, or NULL if sample_fmt is not + * recognized. + */ +const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt); + +/** + * Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE + * on error. + */ +enum AVSampleFormat av_get_sample_fmt(const char *name); + +/** + * Return the planar<->packed alternative form of the given sample format, or + * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the + * requested planar/packed format, the format returned is the same as the + * input. + */ +enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar); + +/** + * Get the packed alternative form of the given sample format. + * + * If the passed sample_fmt is already in packed format, the format returned is + * the same as the input. + * + * @return the packed alternative form of the given sample format or + AV_SAMPLE_FMT_NONE on error. + */ +enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt); + +/** + * Get the planar alternative form of the given sample format. + * + * If the passed sample_fmt is already in planar format, the format returned is + * the same as the input. + * + * @return the planar alternative form of the given sample format or + AV_SAMPLE_FMT_NONE on error. + */ +enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt); + +/** + * Generate a string corresponding to the sample format with + * sample_fmt, or a header if sample_fmt is negative. + * + * @param buf the buffer where to write the string + * @param buf_size the size of buf + * @param sample_fmt the number of the sample format to print the + * corresponding info string, or a negative value to print the + * corresponding header. + * @return the pointer to the filled buffer or NULL if sample_fmt is + * unknown or in case of other errors + */ +char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt); + +/** + * Return number of bytes per sample. + * + * @param sample_fmt the sample format + * @return number of bytes per sample or zero if unknown for the given + * sample format + */ +int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt); + +/** + * Check if the sample format is planar. + * + * @param sample_fmt the sample format to inspect + * @return 1 if the sample format is planar, 0 if it is interleaved + */ +int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt); + +/** + * Get the required buffer size for the given audio parameters. + * + * @param[out] linesize calculated linesize, may be NULL + * @param nb_channels the number of channels + * @param nb_samples the number of samples in a single channel + * @param sample_fmt the sample format + * @param align buffer size alignment (0 = default, 1 = no alignment) + * @return required buffer size, or negative error code on failure + */ +int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align); + +/** + * @} + * + * @defgroup lavu_sampmanip Samples manipulation + * + * Functions that manipulate audio samples + * @{ + */ + +/** + * Fill plane data pointers and linesize for samples with sample + * format sample_fmt. + * + * The audio_data array is filled with the pointers to the samples data planes: + * for planar, set the start point of each channel's data within the buffer, + * for packed, set the start point of the entire buffer only. + * + * The value pointed to by linesize is set to the aligned size of each + * channel's data buffer for planar layout, or to the aligned size of the + * buffer for all channels for packed layout. + * + * The buffer in buf must be big enough to contain all the samples + * (use av_samples_get_buffer_size() to compute its minimum size), + * otherwise the audio_data pointers will point to invalid data. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param[out] audio_data array to be filled with the pointer for each channel + * @param[out] linesize calculated linesize, may be NULL + * @param buf the pointer to a buffer containing the samples + * @param nb_channels the number of channels + * @param nb_samples the number of samples in a single channel + * @param sample_fmt the sample format + * @param align buffer size alignment (0 = default, 1 = no alignment) + * @return >=0 on success or a negative error code on failure + * @todo return minimum size in bytes required for the buffer in case + * of success at the next bump + */ +int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, + const uint8_t *buf, + int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align); + +/** + * Allocate a samples buffer for nb_samples samples, and fill data pointers and + * linesize accordingly. + * The allocated samples buffer can be freed by using av_freep(&audio_data[0]) + * Allocated data will be initialized to silence. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param[out] audio_data array to be filled with the pointer for each channel + * @param[out] linesize aligned size for audio buffer(s), may be NULL + * @param nb_channels number of audio channels + * @param nb_samples number of samples per channel + * @param align buffer size alignment (0 = default, 1 = no alignment) + * @return >=0 on success or a negative error code on failure + * @todo return the size of the allocated buffer in case of success at the next bump + * @see av_samples_fill_arrays() + * @see av_samples_alloc_array_and_samples() + */ +int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align); + +/** + * Allocate a data pointers array, samples buffer for nb_samples + * samples, and fill data pointers and linesize accordingly. + * + * This is the same as av_samples_alloc(), but also allocates the data + * pointers array. + * + * @see av_samples_alloc() + */ +int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align); + +/** + * Copy samples from src to dst. + * + * @param dst destination array of pointers to data planes + * @param src source array of pointers to data planes + * @param dst_offset offset in samples at which the data will be written to dst + * @param src_offset offset in samples at which the data will be read from src + * @param nb_samples number of samples to be copied + * @param nb_channels number of audio channels + * @param sample_fmt audio sample format + */ +int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, + int src_offset, int nb_samples, int nb_channels, + enum AVSampleFormat sample_fmt); + +/** + * Fill an audio buffer with silence. + * + * @param audio_data array of pointers to data planes + * @param offset offset in samples at which to start filling + * @param nb_samples number of samples to fill + * @param nb_channels number of audio channels + * @param sample_fmt audio sample format + */ +int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, + int nb_channels, enum AVSampleFormat sample_fmt); + +/** + * @} + * @} + */ +#endif /* AVUTIL_SAMPLEFMT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.c new file mode 100644 index 000000000..ef6fa4422 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.c @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2009 Konstantin Shishkov + * based on public domain SHA-1 code by Steve Reid + * and on BSD-licensed SHA-2 code by Aaron D. Gifford + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "attributes.h" +#include "avutil.h" +#include "bswap.h" +#include "sha.h" +#include "intreadwrite.h" +#include "mem.h" + +/** hash context */ +typedef struct AVSHA { + uint8_t digest_len; ///< digest length in 32-bit words + uint64_t count; ///< number of bytes in buffer + uint8_t buffer[64]; ///< 512-bit buffer of input values used in hash updating + uint32_t state[8]; ///< current hash value + /** function used to update hash for 512-bit input block */ + void (*transform)(uint32_t *state, const uint8_t buffer[64]); +} AVSHA; + +const int av_sha_size = sizeof(AVSHA); + +struct AVSHA *av_sha_alloc(void) +{ + return av_mallocz(sizeof(struct AVSHA)); +} + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define blk0(i) (block[i] = AV_RB32(buffer + 4 * (i))) +#define blk(i) (block[i] = rol(block[(i)-3] ^ block[(i)-8] ^ block[(i)-14] ^ block[(i)-16], 1)) + +#define R0(v,w,x,y,z,i) z += (((w)&((x)^(y)))^(y)) + blk0(i) + 0x5A827999 + rol(v, 5); w = rol(w, 30); +#define R1(v,w,x,y,z,i) z += (((w)&((x)^(y)))^(y)) + blk (i) + 0x5A827999 + rol(v, 5); w = rol(w, 30); +#define R2(v,w,x,y,z,i) z += ( (w)^(x) ^(y)) + blk (i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30); +#define R3(v,w,x,y,z,i) z += ((((w)|(x))&(y))|((w)&(x))) + blk (i) + 0x8F1BBCDC + rol(v, 5); w = rol(w, 30); +#define R4(v,w,x,y,z,i) z += ( (w)^(x) ^(y)) + blk (i) + 0xCA62C1D6 + rol(v, 5); w = rol(w, 30); + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +static void sha1_transform(uint32_t state[5], const uint8_t buffer[64]) +{ + uint32_t block[80]; + unsigned int i, a, b, c, d, e; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; +#if CONFIG_SMALL + for (i = 0; i < 80; i++) { + int t; + if (i < 16) + t = AV_RB32(buffer + 4 * i); + else + t = rol(block[i-3] ^ block[i-8] ^ block[i-14] ^ block[i-16], 1); + block[i] = t; + t += e + rol(a, 5); + if (i < 40) { + if (i < 20) + t += ((b&(c^d))^d) + 0x5A827999; + else + t += ( b^c ^d) + 0x6ED9EBA1; + } else { + if (i < 60) + t += (((b|c)&d)|(b&c)) + 0x8F1BBCDC; + else + t += ( b^c ^d) + 0xCA62C1D6; + } + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } +#else + +#define R1_0 \ + R0(a, b, c, d, e, 0 + i); \ + R0(e, a, b, c, d, 1 + i); \ + R0(d, e, a, b, c, 2 + i); \ + R0(c, d, e, a, b, 3 + i); \ + R0(b, c, d, e, a, 4 + i); \ + i += 5 + + i = 0; + R1_0; R1_0; R1_0; + R0(a, b, c, d, e, 15); + R1(e, a, b, c, d, 16); + R1(d, e, a, b, c, 17); + R1(c, d, e, a, b, 18); + R1(b, c, d, e, a, 19); + +#define R1_20 \ + R2(a, b, c, d, e, 0 + i); \ + R2(e, a, b, c, d, 1 + i); \ + R2(d, e, a, b, c, 2 + i); \ + R2(c, d, e, a, b, 3 + i); \ + R2(b, c, d, e, a, 4 + i); \ + i += 5 + + i = 20; + R1_20; R1_20; R1_20; R1_20; + +#define R1_40 \ + R3(a, b, c, d, e, 0 + i); \ + R3(e, a, b, c, d, 1 + i); \ + R3(d, e, a, b, c, 2 + i); \ + R3(c, d, e, a, b, 3 + i); \ + R3(b, c, d, e, a, 4 + i); \ + i += 5 + + R1_40; R1_40; R1_40; R1_40; + +#define R1_60 \ + R4(a, b, c, d, e, 0 + i); \ + R4(e, a, b, c, d, 1 + i); \ + R4(d, e, a, b, c, 2 + i); \ + R4(c, d, e, a, b, 3 + i); \ + R4(b, c, d, e, a, 4 + i); \ + i += 5 + + R1_60; R1_60; R1_60; R1_60; +#endif + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + +static const uint32_t K256[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + + +#define Ch(x,y,z) (((x) & ((y) ^ (z))) ^ (z)) +#define Maj(z,y,x) ((((x) | (y)) & (z)) | ((x) & (y))) + +#define Sigma0_256(x) (rol((x), 30) ^ rol((x), 19) ^ rol((x), 10)) +#define Sigma1_256(x) (rol((x), 26) ^ rol((x), 21) ^ rol((x), 7)) +#define sigma0_256(x) (rol((x), 25) ^ rol((x), 14) ^ ((x) >> 3)) +#define sigma1_256(x) (rol((x), 15) ^ rol((x), 13) ^ ((x) >> 10)) + +#undef blk +#define blk(i) (block[i] = block[i - 16] + sigma0_256(block[i - 15]) + \ + sigma1_256(block[i - 2]) + block[i - 7]) + +#define ROUND256(a,b,c,d,e,f,g,h) \ + T1 += (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[i]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + i++ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = blk0(i); \ + ROUND256(a,b,c,d,e,f,g,h) + +#define ROUND256_16_TO_63(a,b,c,d,e,f,g,h) \ + T1 = blk(i); \ + ROUND256(a,b,c,d,e,f,g,h) + +static void sha256_transform(uint32_t *state, const uint8_t buffer[64]) +{ + unsigned int i, a, b, c, d, e, f, g, h; + uint32_t block[64]; + uint32_t T1; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; +#if CONFIG_SMALL + for (i = 0; i < 64; i++) { + uint32_t T2; + if (i < 16) + T1 = blk0(i); + else + T1 = blk(i); + T1 += h + Sigma1_256(e) + Ch(e, f, g) + K256[i]; + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } +#else + + i = 0; +#define R256_0 \ + ROUND256_0_TO_15(a, b, c, d, e, f, g, h); \ + ROUND256_0_TO_15(h, a, b, c, d, e, f, g); \ + ROUND256_0_TO_15(g, h, a, b, c, d, e, f); \ + ROUND256_0_TO_15(f, g, h, a, b, c, d, e); \ + ROUND256_0_TO_15(e, f, g, h, a, b, c, d); \ + ROUND256_0_TO_15(d, e, f, g, h, a, b, c); \ + ROUND256_0_TO_15(c, d, e, f, g, h, a, b); \ + ROUND256_0_TO_15(b, c, d, e, f, g, h, a) + + R256_0; R256_0; + +#define R256_16 \ + ROUND256_16_TO_63(a, b, c, d, e, f, g, h); \ + ROUND256_16_TO_63(h, a, b, c, d, e, f, g); \ + ROUND256_16_TO_63(g, h, a, b, c, d, e, f); \ + ROUND256_16_TO_63(f, g, h, a, b, c, d, e); \ + ROUND256_16_TO_63(e, f, g, h, a, b, c, d); \ + ROUND256_16_TO_63(d, e, f, g, h, a, b, c); \ + ROUND256_16_TO_63(c, d, e, f, g, h, a, b); \ + ROUND256_16_TO_63(b, c, d, e, f, g, h, a) + + R256_16; R256_16; R256_16; + R256_16; R256_16; R256_16; +#endif + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; +} + + +av_cold int av_sha_init(AVSHA *ctx, int bits) +{ + ctx->digest_len = bits >> 5; + switch (bits) { + case 160: // SHA-1 + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + ctx->transform = sha1_transform; + break; + case 224: // SHA-224 + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; + ctx->transform = sha256_transform; + break; + case 256: // SHA-256 + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; + ctx->transform = sha256_transform; + break; + default: + return AVERROR(EINVAL); + } + ctx->count = 0; + return 0; +} + +#if FF_API_CRYPTO_SIZE_T +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, unsigned int len) +#else +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len) +#endif +{ + unsigned int i, j; + + j = ctx->count & 63; + ctx->count += len; +#if CONFIG_SMALL + for (i = 0; i < len; i++) { + ctx->buffer[j++] = data[i]; + if (64 == j) { + ctx->transform(ctx->state, ctx->buffer); + j = 0; + } + } +#else + if ((j + len) > 63) { + memcpy(&ctx->buffer[j], data, (i = 64 - j)); + ctx->transform(ctx->state, ctx->buffer); + for (; i + 63 < len; i += 64) + ctx->transform(ctx->state, &data[i]); + j = 0; + } else + i = 0; + memcpy(&ctx->buffer[j], &data[i], len - i); +#endif +} + +void av_sha_final(AVSHA* ctx, uint8_t *digest) +{ + int i; + uint64_t finalcount = av_be2ne64(ctx->count << 3); + + av_sha_update(ctx, "\200", 1); + while ((ctx->count & 63) != 56) + av_sha_update(ctx, "", 1); + av_sha_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ + for (i = 0; i < ctx->digest_len; i++) + AV_WB32(digest + i*4, ctx->state[i]); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.h new file mode 100644 index 000000000..c0180e572 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_sha + * Public header for SHA-1 & SHA-256 hash function implementations. + */ + +#ifndef AVUTIL_SHA_H +#define AVUTIL_SHA_H + +#include +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_sha SHA + * @ingroup lavu_hash + * SHA-1 and SHA-256 (Secure Hash Algorithm) hash function implementations. + * + * This module supports the following SHA hash functions: + * + * - SHA-1: 160 bits + * - SHA-224: 224 bits, as a variant of SHA-2 + * - SHA-256: 256 bits, as a variant of SHA-2 + * + * @see For SHA-384, SHA-512, and variants thereof, see @ref lavu_sha512. + * + * @{ + */ + +extern const int av_sha_size; + +struct AVSHA; + +/** + * Allocate an AVSHA context. + */ +struct AVSHA *av_sha_alloc(void); + +/** + * Initialize SHA-1 or SHA-2 hashing. + * + * @param context pointer to the function context (of size av_sha_size) + * @param bits number of bits in digest (SHA-1 - 160 bits, SHA-2 224 or 256 bits) + * @return zero if initialization succeeded, -1 otherwise + */ +int av_sha_init(struct AVSHA* context, int bits); + +/** + * Update hash value. + * + * @param ctx hash function context + * @param data input data to update hash with + * @param len input data length + */ +#if FF_API_CRYPTO_SIZE_T +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, unsigned int len); +#else +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + */ +void av_sha_final(struct AVSHA* context, uint8_t *digest); + +/** + * @} + */ + +#endif /* AVUTIL_SHA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha512.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha512.c new file mode 100644 index 000000000..6d092a7c5 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha512.c @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2009 Konstantin Shishkov + * Copyright (C) 2013 James Almer + * based on BSD-licensed SHA-2 code by Aaron D. Gifford + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "attributes.h" +#include "avutil.h" +#include "bswap.h" +#include "sha512.h" +#include "intreadwrite.h" +#include "mem.h" + +/** hash context */ +typedef struct AVSHA512 { + uint8_t digest_len; ///< digest length in 64-bit words + uint64_t count; ///< number of bytes in buffer + uint8_t buffer[128]; ///< 1024-bit buffer of input values used in hash updating + uint64_t state[8]; ///< current hash value +} AVSHA512; + +const int av_sha512_size = sizeof(AVSHA512); + +struct AVSHA512 *av_sha512_alloc(void) +{ + return av_mallocz(sizeof(struct AVSHA512)); +} + +static const uint64_t K512[80] = { + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817), +}; + +#define ror(value, bits) (((value) >> (bits)) | ((value) << (64 - (bits)))) + +#define Ch(x,y,z) (((x) & ((y) ^ (z))) ^ (z)) +#define Maj(z,y,x) ((((x) | (y)) & (z)) | ((x) & (y))) + +#define Sigma0_512(x) (ror((x), 28) ^ ror((x), 34) ^ ror((x), 39)) +#define Sigma1_512(x) (ror((x), 14) ^ ror((x), 18) ^ ror((x), 41)) +#define sigma0_512(x) (ror((x), 1) ^ ror((x), 8) ^ ((x) >> 7)) +#define sigma1_512(x) (ror((x), 19) ^ ror((x), 61) ^ ((x) >> 6)) + +#define blk0(i) (block[i] = AV_RB64(buffer + 8 * (i))) +#define blk(i) (block[i] = block[i - 16] + sigma0_512(block[i - 15]) + \ + sigma1_512(block[i - 2]) + block[i - 7]) + +#define ROUND512(a,b,c,d,e,f,g,h) \ + T1 += (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[i]; \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + i++ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = blk0(i); \ + ROUND512(a,b,c,d,e,f,g,h) + +#define ROUND512_16_TO_80(a,b,c,d,e,f,g,h) \ + T1 = blk(i); \ + ROUND512(a,b,c,d,e,f,g,h) + +static void sha512_transform(uint64_t *state, const uint8_t buffer[128]) +{ + uint64_t a, b, c, d, e, f, g, h; + uint64_t block[80]; + uint64_t T1; + int i; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; +#if CONFIG_SMALL + for (i = 0; i < 80; i++) { + uint64_t T2; + if (i < 16) + T1 = blk0(i); + else + T1 = blk(i); + T1 += h + Sigma1_512(e) + Ch(e, f, g) + K512[i]; + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } +#else + +#define R512_0 \ + ROUND512_0_TO_15(a, b, c, d, e, f, g, h); \ + ROUND512_0_TO_15(h, a, b, c, d, e, f, g); \ + ROUND512_0_TO_15(g, h, a, b, c, d, e, f); \ + ROUND512_0_TO_15(f, g, h, a, b, c, d, e); \ + ROUND512_0_TO_15(e, f, g, h, a, b, c, d); \ + ROUND512_0_TO_15(d, e, f, g, h, a, b, c); \ + ROUND512_0_TO_15(c, d, e, f, g, h, a, b); \ + ROUND512_0_TO_15(b, c, d, e, f, g, h, a) + + i = 0; + R512_0; R512_0; + +#define R512_16 \ + ROUND512_16_TO_80(a, b, c, d, e, f, g, h); \ + ROUND512_16_TO_80(h, a, b, c, d, e, f, g); \ + ROUND512_16_TO_80(g, h, a, b, c, d, e, f); \ + ROUND512_16_TO_80(f, g, h, a, b, c, d, e); \ + ROUND512_16_TO_80(e, f, g, h, a, b, c, d); \ + ROUND512_16_TO_80(d, e, f, g, h, a, b, c); \ + ROUND512_16_TO_80(c, d, e, f, g, h, a, b); \ + ROUND512_16_TO_80(b, c, d, e, f, g, h, a) + + R512_16; R512_16; R512_16; R512_16; + R512_16; R512_16; R512_16; R512_16; +#endif + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; +} + + +av_cold int av_sha512_init(AVSHA512 *ctx, int bits) +{ + ctx->digest_len = bits >> 6; + switch (bits) { + case 224: // SHA-512/224 + ctx->state[0] = UINT64_C(0x8C3D37C819544DA2); + ctx->state[1] = UINT64_C(0x73E1996689DCD4D6); + ctx->state[2] = UINT64_C(0x1DFAB7AE32FF9C82); + ctx->state[3] = UINT64_C(0x679DD514582F9FCF); + ctx->state[4] = UINT64_C(0x0F6D2B697BD44DA8); + ctx->state[5] = UINT64_C(0x77E36F7304C48942); + ctx->state[6] = UINT64_C(0x3F9D85A86A1D36C8); + ctx->state[7] = UINT64_C(0x1112E6AD91D692A1); + break; + case 256: // SHA-512/256 + ctx->state[0] = UINT64_C(0x22312194FC2BF72C); + ctx->state[1] = UINT64_C(0x9F555FA3C84C64C2); + ctx->state[2] = UINT64_C(0x2393B86B6F53B151); + ctx->state[3] = UINT64_C(0x963877195940EABD); + ctx->state[4] = UINT64_C(0x96283EE2A88EFFE3); + ctx->state[5] = UINT64_C(0xBE5E1E2553863992); + ctx->state[6] = UINT64_C(0x2B0199FC2C85B8AA); + ctx->state[7] = UINT64_C(0x0EB72DDC81C52CA2); + break; + case 384: // SHA-384 + ctx->state[0] = UINT64_C(0xCBBB9D5DC1059ED8); + ctx->state[1] = UINT64_C(0x629A292A367CD507); + ctx->state[2] = UINT64_C(0x9159015A3070DD17); + ctx->state[3] = UINT64_C(0x152FECD8F70E5939); + ctx->state[4] = UINT64_C(0x67332667FFC00B31); + ctx->state[5] = UINT64_C(0x8EB44A8768581511); + ctx->state[6] = UINT64_C(0xDB0C2E0D64F98FA7); + ctx->state[7] = UINT64_C(0x47B5481DBEFA4FA4); + break; + case 512: // SHA-512 + ctx->state[0] = UINT64_C(0x6A09E667F3BCC908); + ctx->state[1] = UINT64_C(0xBB67AE8584CAA73B); + ctx->state[2] = UINT64_C(0x3C6EF372FE94F82B); + ctx->state[3] = UINT64_C(0xA54FF53A5F1D36F1); + ctx->state[4] = UINT64_C(0x510E527FADE682D1); + ctx->state[5] = UINT64_C(0x9B05688C2B3E6C1F); + ctx->state[6] = UINT64_C(0x1F83D9ABFB41BD6B); + ctx->state[7] = UINT64_C(0x5BE0CD19137E2179); + break; + default: + return AVERROR(EINVAL); + } + ctx->count = 0; + return 0; +} + +#if FF_API_CRYPTO_SIZE_T +void av_sha512_update(AVSHA512* ctx, const uint8_t* data, unsigned int len) +#else +void av_sha512_update(AVSHA512* ctx, const uint8_t* data, size_t len) +#endif +{ + unsigned int i, j; + + j = ctx->count & 127; + ctx->count += len; +#if CONFIG_SMALL + for (i = 0; i < len; i++) { + ctx->buffer[j++] = data[i]; + if (128 == j) { + sha512_transform(ctx->state, ctx->buffer); + j = 0; + } + } +#else + if ((j + len) > 127) { + memcpy(&ctx->buffer[j], data, (i = 128 - j)); + sha512_transform(ctx->state, ctx->buffer); + for (; i + 127 < len; i += 128) + sha512_transform(ctx->state, &data[i]); + j = 0; + } else + i = 0; + memcpy(&ctx->buffer[j], &data[i], len - i); +#endif +} + +void av_sha512_final(AVSHA512* ctx, uint8_t *digest) +{ + uint64_t i = 0; + uint64_t finalcount = av_be2ne64(ctx->count << 3); + + av_sha512_update(ctx, "\200", 1); + while ((ctx->count & 127) != 112) + av_sha512_update(ctx, "", 1); + av_sha512_update(ctx, (uint8_t *)&i, 8); + av_sha512_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ + for (i = 0; i < ctx->digest_len; i++) + AV_WB64(digest + i*8, ctx->state[i]); + if (ctx->digest_len & 1) /* SHA512/224 is 28 bytes, and is not divisible by 8. */ + AV_WB32(digest + i*8, ctx->state[i] >> 32); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha512.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha512.h new file mode 100644 index 000000000..bef714b41 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/sha512.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2013 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_sha512 + * Public header for SHA-512 implementation. + */ + +#ifndef AVUTIL_SHA512_H +#define AVUTIL_SHA512_H + +#include +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_sha512 SHA-512 + * @ingroup lavu_hash + * SHA-512 (Secure Hash Algorithm) hash function implementations. + * + * This module supports the following SHA-2 hash functions: + * + * - SHA-512/224: 224 bits + * - SHA-512/256: 256 bits + * - SHA-384: 384 bits + * - SHA-512: 512 bits + * + * @see For SHA-1, SHA-256, and variants thereof, see @ref lavu_sha. + * + * @{ + */ + +extern const int av_sha512_size; + +struct AVSHA512; + +/** + * Allocate an AVSHA512 context. + */ +struct AVSHA512 *av_sha512_alloc(void); + +/** + * Initialize SHA-2 512 hashing. + * + * @param context pointer to the function context (of size av_sha512_size) + * @param bits number of bits in digest (224, 256, 384 or 512 bits) + * @return zero if initialization succeeded, -1 otherwise + */ +int av_sha512_init(struct AVSHA512* context, int bits); + +/** + * Update hash value. + * + * @param context hash function context + * @param data input data to update hash with + * @param len input data length + */ +#if FF_API_CRYPTO_SIZE_T +void av_sha512_update(struct AVSHA512* context, const uint8_t* data, unsigned int len); +#else +void av_sha512_update(struct AVSHA512* context, const uint8_t* data, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + */ +void av_sha512_final(struct AVSHA512* context, uint8_t *digest); + +/** + * @} + */ + +#endif /* AVUTIL_SHA512_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/slicethread.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/slicethread.c new file mode 100644 index 000000000..dfbe551ef --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/slicethread.c @@ -0,0 +1,255 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "slicethread.h" +#include "mem.h" +#include "thread.h" +#include "avassert.h" + +#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS + +typedef struct WorkerContext { + AVSliceThread *ctx; + pthread_mutex_t mutex; + pthread_cond_t cond; + pthread_t thread; + int done; +} WorkerContext; + +struct AVSliceThread { + WorkerContext *workers; + int nb_threads; + int nb_active_threads; + int nb_jobs; + + atomic_uint first_job; + atomic_uint current_job; + pthread_mutex_t done_mutex; + pthread_cond_t done_cond; + int done; + int finished; + + void *priv; + void (*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads); + void (*main_func)(void *priv); +}; + +static int run_jobs(AVSliceThread *ctx) +{ + unsigned nb_jobs = ctx->nb_jobs; + unsigned nb_active_threads = ctx->nb_active_threads; + unsigned first_job = atomic_fetch_add_explicit(&ctx->first_job, 1, memory_order_acq_rel); + unsigned current_job = first_job; + + do { + ctx->worker_func(ctx->priv, current_job, first_job, nb_jobs, nb_active_threads); + } while ((current_job = atomic_fetch_add_explicit(&ctx->current_job, 1, memory_order_acq_rel)) < nb_jobs); + + return current_job == nb_jobs + nb_active_threads - 1; +} + +static void *attribute_align_arg thread_worker(void *v) +{ + WorkerContext *w = v; + AVSliceThread *ctx = w->ctx; + + pthread_mutex_lock(&w->mutex); + pthread_cond_signal(&w->cond); + + while (1) { + w->done = 1; + while (w->done) + pthread_cond_wait(&w->cond, &w->mutex); + + if (ctx->finished) { + pthread_mutex_unlock(&w->mutex); + return NULL; + } + + if (run_jobs(ctx)) { + pthread_mutex_lock(&ctx->done_mutex); + ctx->done = 1; + pthread_cond_signal(&ctx->done_cond); + pthread_mutex_unlock(&ctx->done_mutex); + } + } +} + +int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, + void (*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), + void (*main_func)(void *priv), + int nb_threads) +{ + AVSliceThread *ctx; + int nb_workers, i; + + av_assert0(nb_threads >= 0); + if (!nb_threads) { + int nb_cpus = av_cpu_count(); + if (nb_cpus > 1) + nb_threads = nb_cpus + 1; + else + nb_threads = 1; + } + + nb_workers = nb_threads; + if (!main_func) + nb_workers--; + + *pctx = ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return AVERROR(ENOMEM); + + if (nb_workers && !(ctx->workers = av_calloc(nb_workers, sizeof(*ctx->workers)))) { + av_freep(pctx); + return AVERROR(ENOMEM); + } + + ctx->priv = priv; + ctx->worker_func = worker_func; + ctx->main_func = main_func; + ctx->nb_threads = nb_threads; + ctx->nb_active_threads = 0; + ctx->nb_jobs = 0; + ctx->finished = 0; + + atomic_init(&ctx->first_job, 0); + atomic_init(&ctx->current_job, 0); + pthread_mutex_init(&ctx->done_mutex, NULL); + pthread_cond_init(&ctx->done_cond, NULL); + ctx->done = 0; + + for (i = 0; i < nb_workers; i++) { + WorkerContext *w = &ctx->workers[i]; + int ret; + w->ctx = ctx; + pthread_mutex_init(&w->mutex, NULL); + pthread_cond_init(&w->cond, NULL); + pthread_mutex_lock(&w->mutex); + w->done = 0; + + if (ret = pthread_create(&w->thread, NULL, thread_worker, w)) { + ctx->nb_threads = main_func ? i : i + 1; + pthread_mutex_unlock(&w->mutex); + pthread_cond_destroy(&w->cond); + pthread_mutex_destroy(&w->mutex); + avpriv_slicethread_free(pctx); + return AVERROR(ret); + } + + while (!w->done) + pthread_cond_wait(&w->cond, &w->mutex); + pthread_mutex_unlock(&w->mutex); + } + + return nb_threads; +} + +void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main) +{ + int nb_workers, i, is_last = 0; + + av_assert0(nb_jobs > 0); + ctx->nb_jobs = nb_jobs; + ctx->nb_active_threads = FFMIN(nb_jobs, ctx->nb_threads); + atomic_store_explicit(&ctx->first_job, 0, memory_order_relaxed); + atomic_store_explicit(&ctx->current_job, ctx->nb_active_threads, memory_order_relaxed); + nb_workers = ctx->nb_active_threads; + if (!ctx->main_func || !execute_main) + nb_workers--; + + for (i = 0; i < nb_workers; i++) { + WorkerContext *w = &ctx->workers[i]; + pthread_mutex_lock(&w->mutex); + w->done = 0; + pthread_cond_signal(&w->cond); + pthread_mutex_unlock(&w->mutex); + } + + if (ctx->main_func && execute_main) + ctx->main_func(ctx->priv); + else + is_last = run_jobs(ctx); + + if (!is_last) { + pthread_mutex_lock(&ctx->done_mutex); + while (!ctx->done) + pthread_cond_wait(&ctx->done_cond, &ctx->done_mutex); + ctx->done = 0; + pthread_mutex_unlock(&ctx->done_mutex); + } +} + +void avpriv_slicethread_free(AVSliceThread **pctx) +{ + AVSliceThread *ctx; + int nb_workers, i; + + if (!pctx || !*pctx) + return; + + ctx = *pctx; + nb_workers = ctx->nb_threads; + if (!ctx->main_func) + nb_workers--; + + ctx->finished = 1; + for (i = 0; i < nb_workers; i++) { + WorkerContext *w = &ctx->workers[i]; + pthread_mutex_lock(&w->mutex); + w->done = 0; + pthread_cond_signal(&w->cond); + pthread_mutex_unlock(&w->mutex); + } + + for (i = 0; i < nb_workers; i++) { + WorkerContext *w = &ctx->workers[i]; + pthread_join(w->thread, NULL); + pthread_cond_destroy(&w->cond); + pthread_mutex_destroy(&w->mutex); + } + + pthread_cond_destroy(&ctx->done_cond); + pthread_mutex_destroy(&ctx->done_mutex); + av_freep(&ctx->workers); + av_freep(pctx); +} + +#else /* HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS32THREADS */ + +int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, + void (*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), + void (*main_func)(void *priv), + int nb_threads) +{ + *pctx = NULL; + return AVERROR(EINVAL); +} + +void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main) +{ + av_assert0(0); +} + +void avpriv_slicethread_free(AVSliceThread **pctx) +{ + av_assert0(!pctx || !*pctx); +} + +#endif /* HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS32THREADS */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/slicethread.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/slicethread.h new file mode 100644 index 000000000..f6f6f302c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/slicethread.h @@ -0,0 +1,52 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SLICETHREAD_H +#define AVUTIL_SLICETHREAD_H + +typedef struct AVSliceThread AVSliceThread; + +/** + * Create slice threading context. + * @param pctx slice threading context returned here + * @param priv private pointer to be passed to callback function + * @param worker_func callback function to be executed + * @param main_func special callback function, called from main thread, may be NULL + * @param nb_threads number of threads, 0 for automatic, must be >= 0 + * @return return number of threads or negative AVERROR on failure + */ +int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, + void (*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), + void (*main_func)(void *priv), + int nb_threads); + +/** + * Execute slice threading. + * @param ctx slice threading context + * @param nb_jobs number of jobs, must be > 0 + * @param execute_main also execute main_func + */ +void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main); + +/** + * Destroy slice threading context. + * @param pctx pointer to context + */ +void avpriv_slicethread_free(AVSliceThread **pctx); + +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat.h new file mode 100644 index 000000000..a651406f7 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat.h @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SOFTFLOAT_H +#define AVUTIL_SOFTFLOAT_H + +#include +#include "common.h" + +#include "avassert.h" +#include "softfloat_tables.h" + +#define MIN_EXP -149 +#define MAX_EXP 126 +#define ONE_BITS 29 + +typedef struct SoftFloat{ + int32_t mant; + int32_t exp; +}SoftFloat; + +static const SoftFloat FLOAT_0 = { 0, MIN_EXP}; ///< 0.0 +static const SoftFloat FLOAT_05 = { 0x20000000, 0}; ///< 0.5 +static const SoftFloat FLOAT_1 = { 0x20000000, 1}; ///< 1.0 +static const SoftFloat FLOAT_EPSILON = { 0x29F16B12, -16}; ///< A small value +static const SoftFloat FLOAT_1584893192 = { 0x32B771ED, 1}; ///< 1.584893192 (10^.2) +static const SoftFloat FLOAT_100000 = { 0x30D40000, 17}; ///< 100000 +static const SoftFloat FLOAT_0999999 = { 0x3FFFFBCE, 0}; ///< 0.999999 +static const SoftFloat FLOAT_MIN = { 0x20000000, MIN_EXP}; + + +/** + * Convert a SoftFloat to a double precision float. + */ +static inline av_const double av_sf2double(SoftFloat v) { + v.exp -= ONE_BITS +1; + return ldexp(v.mant, v.exp); +} + +static av_const SoftFloat av_normalize_sf(SoftFloat a){ + if(a.mant){ +#if 1 + while((a.mant + 0x1FFFFFFFU)<0x3FFFFFFFU){ + a.mant += a.mant; + a.exp -= 1; + } +#else + int s=ONE_BITS - av_log2(FFABS(a.mant)); + a.exp -= s; + a.mant <<= s; +#endif + if(a.exp < MIN_EXP){ + a.exp = MIN_EXP; + a.mant= 0; + } + }else{ + a.exp= MIN_EXP; + } + return a; +} + +static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){ +#if 1 + if((int32_t)(a.mant + 0x40000000U) <= 0){ + a.exp++; + a.mant>>=1; + } + av_assert2(a.mant < 0x40000000 && a.mant > -0x40000000); + av_assert2(a.exp <= MAX_EXP); + return a; +#elif 1 + int t= a.mant + 0x40000000 < 0; + return (SoftFloat){ a.mant>>t, a.exp+t}; +#else + int t= (a.mant + 0x3FFFFFFFU)>>31; + return (SoftFloat){a.mant>>t, a.exp+t}; +#endif +} + +/** + * @return Will not be more denormalized than a*b. So if either input is + * normalized, then the output will not be worse then the other input. + * If both are normalized, then the output will be normalized. + */ +static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){ + a.exp += b.exp; + av_assert2((int32_t)((a.mant * (int64_t)b.mant) >> ONE_BITS) == (a.mant * (int64_t)b.mant) >> ONE_BITS); + a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS; + a = av_normalize1_sf((SoftFloat){a.mant, a.exp - 1}); + if (!a.mant || a.exp < MIN_EXP) + return FLOAT_0; + return a; +} + +/** + * b has to be normalized and not zero. + * @return Will not be more denormalized than a. + */ +static inline av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){ + int64_t temp = (int64_t)a.mant * (1<<(ONE_BITS+1)); + temp /= b.mant; + a.exp -= b.exp; + a.mant = temp; + while (a.mant != temp) { + temp /= 2; + a.exp--; + a.mant = temp; + } + a = av_normalize1_sf(a); + if (!a.mant || a.exp < MIN_EXP) + return FLOAT_0; + return a; +} + +/** + * Compares two SoftFloats. + * @returns < 0 if the first is less + * > 0 if the first is greater + * 0 if they are equal + */ +static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){ + int t= a.exp - b.exp; + if (t <-31) return - b.mant ; + else if (t < 0) return (a.mant >> (-t)) - b.mant ; + else if (t < 32) return a.mant - (b.mant >> t); + else return a.mant ; +} + +/** + * Compares two SoftFloats. + * @returns 1 if a is greater than b, 0 otherwise + */ +static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b) +{ + int t= a.exp - b.exp; + if (t <-31) return 0 > b.mant ; + else if (t < 0) return (a.mant >> (-t)) > b.mant ; + else if (t < 32) return a.mant > (b.mant >> t); + else return a.mant > 0 ; +} + +/** + * @returns the sum of 2 SoftFloats. + */ +static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){ + int t= a.exp - b.exp; + if (t <-31) return b; + else if (t < 0) return av_normalize_sf(av_normalize1_sf((SoftFloat){ b.mant + (a.mant >> (-t)), b.exp})); + else if (t < 32) return av_normalize_sf(av_normalize1_sf((SoftFloat){ a.mant + (b.mant >> t ), a.exp})); + else return a; +} + +/** + * @returns the difference of 2 SoftFloats. + */ +static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){ + return av_add_sf(a, (SoftFloat){ -b.mant, b.exp}); +} + +//FIXME log, exp, pow + +/** + * Converts a mantisse and exponent to a SoftFloat. + * This converts a fixed point value v with frac_bits fractional bits to a + * SoftFloat. + * @returns a SoftFloat with value v * 2^-frac_bits + */ +static inline av_const SoftFloat av_int2sf(int v, int frac_bits){ + int exp_offset = 0; + if(v <= INT_MIN + 1){ + exp_offset = 1; + v>>=1; + } + return av_normalize_sf(av_normalize1_sf((SoftFloat){v, ONE_BITS + 1 - frac_bits + exp_offset})); +} + +/** + * Converts a SoftFloat to an integer. + * Rounding is to -inf. + */ +static inline av_const int av_sf2int(SoftFloat v, int frac_bits){ + v.exp += frac_bits - (ONE_BITS + 1); + if(v.exp >= 0) return v.mant << v.exp ; + else return v.mant >>(-v.exp); +} + +/** + * Rounding-to-nearest used. + */ +static av_always_inline SoftFloat av_sqrt_sf(SoftFloat val) +{ + int tabIndex, rem; + + if (val.mant == 0) + val.exp = MIN_EXP; + else if (val.mant < 0) + abort(); + else + { + tabIndex = (val.mant - 0x20000000) >> 20; + + rem = val.mant & 0xFFFFF; + val.mant = (int)(((int64_t)av_sqrttbl_sf[tabIndex] * (0x100000 - rem) + + (int64_t)av_sqrttbl_sf[tabIndex + 1] * rem + + 0x80000) >> 20); + val.mant = (int)(((int64_t)av_sqr_exp_multbl_sf[val.exp & 1] * val.mant + + 0x10000000) >> 29); + + if (val.mant < 0x40000000) + val.exp -= 2; + else + val.mant >>= 1; + + val.exp = (val.exp >> 1) + 1; + } + + return val; +} + +/** + * Rounding-to-nearest used. + */ +static av_unused void av_sincos_sf(int a, int *s, int *c) +{ + int idx, sign; + int sv, cv; + int st, ct; + + idx = a >> 26; + sign = (int32_t)((unsigned)idx << 27) >> 31; + cv = av_costbl_1_sf[idx & 0xf]; + cv = (cv ^ sign) - sign; + + idx -= 8; + sign = (int32_t)((unsigned)idx << 27) >> 31; + sv = av_costbl_1_sf[idx & 0xf]; + sv = (sv ^ sign) - sign; + + idx = a >> 21; + ct = av_costbl_2_sf[idx & 0x1f]; + st = av_sintbl_2_sf[idx & 0x1f]; + + idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30); + + sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30); + + cv = idx; + + idx = a >> 16; + ct = av_costbl_3_sf[idx & 0x1f]; + st = av_sintbl_3_sf[idx & 0x1f]; + + idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30); + + sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30); + cv = idx; + + idx = a >> 11; + + ct = (int)(((int64_t)av_costbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) + + (int64_t)av_costbl_4_sf[(idx & 0x1f)+1]*(a & 0x7ff) + + 0x400) >> 11); + st = (int)(((int64_t)av_sintbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) + + (int64_t)av_sintbl_4_sf[(idx & 0x1f) + 1] * (a & 0x7ff) + + 0x400) >> 11); + + *c = (int)(((int64_t)cv * ct + (int64_t)sv * st + 0x20000000) >> 30); + + *s = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30); +} + +#endif /* AVUTIL_SOFTFLOAT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat_ieee754.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat_ieee754.h new file mode 100644 index 000000000..3398aa18b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat_ieee754.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016 Umair Khan + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SOFTFLOAT_IEEE754_H +#define AVUTIL_SOFTFLOAT_IEEE754_H + +#include + +#define EXP_BIAS 127 +#define MANT_BITS 23 + +typedef struct SoftFloat_IEEE754 { + int32_t sign; + uint64_t mant; + int32_t exp; +} SoftFloat_IEEE754; + +static const SoftFloat_IEEE754 FLOAT_0 = {0, 0, -126}; +static const SoftFloat_IEEE754 FLOAT_1 = {0, 0, 0}; + +/** Normalize the softfloat as defined by IEEE 754 single-recision floating + * point specification + */ +static inline SoftFloat_IEEE754 av_normalize_sf_ieee754(SoftFloat_IEEE754 sf) { + while( sf.mant >= 0x1000000UL ) { + sf.exp++; + sf.mant >>= 1; + } + sf.mant &= 0x007fffffUL; + return sf; +} + +/** Convert integer to softfloat. + * @return softfloat with value n * 2^e + */ +static inline SoftFloat_IEEE754 av_int2sf_ieee754(int64_t n, int e) { + int sign = 0; + + if (n < 0) { + sign = 1; + n *= -1; + } + return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, n << MANT_BITS, 0 + e}); +} + +/** Make a softfloat out of the bitstream. Assumes the bits are in the form as defined + * by the IEEE 754 spec. + */ +static inline SoftFloat_IEEE754 av_bits2sf_ieee754(uint32_t n) { + return ((SoftFloat_IEEE754) { (n & 0x80000000UL) >> 31, (n & 0x7FFFFFUL), (int8_t)((n & 0x7F800000UL) >> 23)}); +} + +/** Convert the softfloat to integer + */ +static inline int av_sf2int_ieee754(SoftFloat_IEEE754 a) { + if(a.exp >= 0) return a.mant << a.exp ; + else return a.mant >>(-a.exp); +} + +/** Divide a by b. b should not be zero. + * @return normalized result + */ +static inline SoftFloat_IEEE754 av_div_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) { + int32_t mant, exp, sign; + a = av_normalize_sf_ieee754(a); + b = av_normalize_sf_ieee754(b); + sign = a.sign ^ b.sign; + mant = ((((uint64_t) (a.mant | 0x00800000UL)) << MANT_BITS) / (b.mant| 0x00800000UL)); + exp = a.exp - b.exp; + return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp}); +} + +/** Multiply a with b + * #return normalized result + */ +static inline SoftFloat_IEEE754 av_mul_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) { + int32_t sign, mant, exp; + a = av_normalize_sf_ieee754(a); + b = av_normalize_sf_ieee754(b); + sign = a.sign ^ b.sign; + mant = (((uint64_t)(a.mant|0x00800000UL) * (uint64_t)(b.mant|0x00800000UL))>>MANT_BITS); + exp = a.exp + b.exp; + return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp}); +} + +/** Compare a with b strictly + * @returns 1 if the a and b are equal, 0 otherwise. + */ +static inline int av_cmp_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) { + a = av_normalize_sf_ieee754(a); + b = av_normalize_sf_ieee754(b); + if (a.sign != b.sign) return 0; + if (a.mant != b.mant) return 0; + if (a.exp != b.exp ) return 0; + return 1; +} + +#endif /*AVUTIL_SOFTFLOAT_IEEE754_H*/ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat_tables.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat_tables.h new file mode 100644 index 000000000..461f2b221 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/softfloat_tables.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of is + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Stanislav Ocovaj (stanislav.ocovaj imgtec com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVUTIL_SOFTFLOAT_TABLES_H +#define AVUTIL_SOFTFLOAT_TABLES_H + +#include + +static const int32_t av_sqrttbl_sf[512+1] = { /* sqrt(x), 0.5<=x<1 */ + 0x2d413ccd,0x2d4c8bb3,0x2d57d7c6,0x2d63210a, + 0x2d6e677f,0x2d79ab2a,0x2d84ec0b,0x2d902a23, + 0x2d9b6578,0x2da69e08,0x2db1d3d6,0x2dbd06e6, + 0x2dc83738,0x2dd364ce,0x2dde8fac,0x2de9b7d2, + 0x2df4dd43,0x2e000000,0x2e0b200c,0x2e163d68, + 0x2e215816,0x2e2c701a,0x2e378573,0x2e429824, + 0x2e4da830,0x2e58b598,0x2e63c05d,0x2e6ec883, + 0x2e79ce0a,0x2e84d0f5,0x2e8fd144,0x2e9acefb, + 0x2ea5ca1b,0x2eb0c2a7,0x2ebbb89e,0x2ec6ac04, + 0x2ed19cda,0x2edc8b23,0x2ee776df,0x2ef26012, + 0x2efd46bb,0x2f082add,0x2f130c7b,0x2f1deb95, + 0x2f28c82e,0x2f33a246,0x2f3e79e1,0x2f494eff, + 0x2f5421a3,0x2f5ef1ce,0x2f69bf81,0x2f748abe, + 0x2f7f5388,0x2f8a19e0,0x2f94ddc7,0x2f9f9f3e, + 0x2faa5e48,0x2fb51ae8,0x2fbfd51c,0x2fca8ce9, + 0x2fd5424e,0x2fdff54e,0x2feaa5eb,0x2ff55426, + 0x30000000,0x300aa97b,0x3015509a,0x301ff55c, + 0x302a97c5,0x303537d5,0x303fd58e,0x304a70f2, + 0x30550a01,0x305fa0be,0x306a352a,0x3074c747, + 0x307f5716,0x3089e499,0x30946fd2,0x309ef8c0, + 0x30a97f67,0x30b403c7,0x30be85e2,0x30c905bb, + 0x30d38351,0x30ddfea6,0x30e877bc,0x30f2ee96, + 0x30fd6332,0x3107d594,0x311245bc,0x311cb3ad, + 0x31271f67,0x313188ec,0x313bf03d,0x3146555c, + 0x3150b84a,0x315b1909,0x31657798,0x316fd3fc, + 0x317a2e34,0x31848642,0x318edc28,0x31992fe5, + 0x31a3817d,0x31add0f0,0x31b81e40,0x31c2696e, + 0x31ccb27b,0x31d6f969,0x31e13e38,0x31eb80eb, + 0x31f5c182,0x32000000,0x320a3c65,0x321476b1, + 0x321eaee8,0x3228e50a,0x32331917,0x323d4b13, + 0x32477afc,0x3251a8d6,0x325bd4a2,0x3265fe5f, + 0x32702611,0x327a4bb8,0x32846f55,0x328e90e9, + 0x3298b076,0x32a2cdfd,0x32ace97e,0x32b702fd, + 0x32c11a79,0x32cb2ff3,0x32d5436d,0x32df54e9, + 0x32e96466,0x32f371e8,0x32fd7d6d,0x330786f9, + 0x33118e8c,0x331b9426,0x332597cb,0x332f9979, + 0x33399933,0x334396fa,0x334d92cf,0x33578cb2, + 0x336184a6,0x336b7aab,0x33756ec3,0x337f60ed, + 0x3389512d,0x33933f83,0x339d2bef,0x33a71672, + 0x33b0ff10,0x33bae5c7,0x33c4ca99,0x33cead88, + 0x33d88e95,0x33e26dbf,0x33ec4b09,0x33f62673, + 0x34000000,0x3409d7af,0x3413ad82,0x341d817a, + 0x34275397,0x343123db,0x343af248,0x3444bedd, + 0x344e899d,0x34585288,0x3462199f,0x346bdee3, + 0x3475a254,0x347f63f5,0x348923c6,0x3492e1c9, + 0x349c9dfe,0x34a65865,0x34b01101,0x34b9c7d2, + 0x34c37cda,0x34cd3018,0x34d6e18f,0x34e0913f, + 0x34ea3f29,0x34f3eb4d,0x34fd95ae,0x35073e4c, + 0x3510e528,0x351a8a43,0x35242d9d,0x352dcf39, + 0x35376f16,0x35410d36,0x354aa99a,0x35544442, + 0x355ddd2f,0x35677463,0x357109df,0x357a9da2, + 0x35842fb0,0x358dc007,0x35974ea9,0x35a0db98, + 0x35aa66d3,0x35b3f05c,0x35bd7833,0x35c6fe5a, + 0x35d082d3,0x35da059c,0x35e386b7,0x35ed0626, + 0x35f683e8,0x36000000,0x36097a6e,0x3612f331, + 0x361c6a4d,0x3625dfc1,0x362f538f,0x3638c5b7, + 0x36423639,0x364ba518,0x36551252,0x365e7deb, + 0x3667e7e2,0x36715039,0x367ab6f0,0x36841c07, + 0x368d7f81,0x3696e15d,0x36a0419d,0x36a9a040, + 0x36b2fd49,0x36bc58b8,0x36c5b28e,0x36cf0acb, + 0x36d86170,0x36e1b680,0x36eb09f8,0x36f45bdc, + 0x36fdac2b,0x3706fae7,0x37104810,0x371993a7, + 0x3722ddad,0x372c2622,0x37356d08,0x373eb25f, + 0x3747f629,0x37513865,0x375a7914,0x3763b838, + 0x376cf5d0,0x377631e0,0x377f6c64,0x3788a561, + 0x3791dcd6,0x379b12c4,0x37a4472c,0x37ad7a0e, + 0x37b6ab6a,0x37bfdb44,0x37c90999,0x37d2366d, + 0x37db61be,0x37e48b8e,0x37edb3de,0x37f6daae, + 0x38000000,0x380923d3,0x3812462a,0x381b6703, + 0x38248660,0x382da442,0x3836c0aa,0x383fdb97, + 0x3848f50c,0x38520d09,0x385b238d,0x3864389b, + 0x386d4c33,0x38765e55,0x387f6f01,0x38887e3b, + 0x38918c00,0x389a9853,0x38a3a334,0x38acaca3, + 0x38b5b4a3,0x38bebb32,0x38c7c051,0x38d0c402, + 0x38d9c645,0x38e2c71b,0x38ebc685,0x38f4c482, + 0x38fdc114,0x3906bc3c,0x390fb5fa,0x3918ae4f, + 0x3921a53a,0x392a9abe,0x39338edb,0x393c8192, + 0x394572e2,0x394e62ce,0x39575155,0x39603e77, + 0x39692a36,0x39721494,0x397afd8f,0x3983e527, + 0x398ccb60,0x3995b039,0x399e93b2,0x39a775cc, + 0x39b05689,0x39b935e8,0x39c213e9,0x39caf08e, + 0x39d3cbd9,0x39dca5c7,0x39e57e5b,0x39ee5596, + 0x39f72b77,0x3a000000,0x3a08d331,0x3a11a50a, + 0x3a1a758d,0x3a2344ba,0x3a2c1291,0x3a34df13, + 0x3a3daa41,0x3a46741b,0x3a4f3ca3,0x3a5803d7, + 0x3a60c9ba,0x3a698e4b,0x3a72518b,0x3a7b137c, + 0x3a83d41d,0x3a8c936f,0x3a955173,0x3a9e0e29, + 0x3aa6c992,0x3aaf83ae,0x3ab83c7e,0x3ac0f403, + 0x3ac9aa3c,0x3ad25f2c,0x3adb12d1,0x3ae3c52d, + 0x3aec7642,0x3af5260e,0x3afdd492,0x3b0681d0, + 0x3b0f2dc6,0x3b17d878,0x3b2081e4,0x3b292a0c, + 0x3b31d0f0,0x3b3a7690,0x3b431aec,0x3b4bbe06, + 0x3b545fdf,0x3b5d0077,0x3b659fcd,0x3b6e3de4, + 0x3b76daba,0x3b7f7651,0x3b8810aa,0x3b90a9c4, + 0x3b9941a1,0x3ba1d842,0x3baa6da5,0x3bb301cd, + 0x3bbb94b9,0x3bc4266a,0x3bccb6e2,0x3bd5461f, + 0x3bddd423,0x3be660ee,0x3beeec81,0x3bf776dc, + 0x3c000000,0x3c0887ed,0x3c110ea4,0x3c199426, + 0x3c221872,0x3c2a9b8a,0x3c331d6e,0x3c3b9e1d, + 0x3c441d9a,0x3c4c9be5,0x3c5518fd,0x3c5d94e3, + 0x3c660f98,0x3c6e891d,0x3c770172,0x3c7f7898, + 0x3c87ee8e,0x3c906356,0x3c98d6ef,0x3ca1495b, + 0x3ca9ba9a,0x3cb22aac,0x3cba9992,0x3cc3074c, + 0x3ccb73dc,0x3cd3df41,0x3cdc497b,0x3ce4b28c, + 0x3ced1a73,0x3cf58132,0x3cfde6c8,0x3d064b37, + 0x3d0eae7f,0x3d17109f,0x3d1f719a,0x3d27d16e, + 0x3d30301d,0x3d388da8,0x3d40ea0d,0x3d49454f, + 0x3d519f6d,0x3d59f867,0x3d625040,0x3d6aa6f6, + 0x3d72fc8b,0x3d7b50fe,0x3d83a451,0x3d8bf683, + 0x3d944796,0x3d9c9788,0x3da4e65c,0x3dad3412, + 0x3db580a9,0x3dbdcc24,0x3dc61680,0x3dce5fc0, + 0x3dd6a7e4,0x3ddeeeed,0x3de734d9,0x3def79ab, + 0x3df7bd62,0x3e000000,0x3e084184,0x3e1081ee, + 0x3e18c140,0x3e20ff7a,0x3e293c9c,0x3e3178a7, + 0x3e39b39a,0x3e41ed77,0x3e4a263d,0x3e525def, + 0x3e5a948b,0x3e62ca12,0x3e6afe85,0x3e7331e4, + 0x3e7b642f,0x3e839567,0x3e8bc58c,0x3e93f49f, + 0x3e9c22a1,0x3ea44f91,0x3eac7b6f,0x3eb4a63e, + 0x3ebccffb,0x3ec4f8aa,0x3ecd2049,0x3ed546d9, + 0x3edd6c5a,0x3ee590cd,0x3eedb433,0x3ef5d68c, + 0x3efdf7d7,0x3f061816,0x3f0e3749,0x3f165570, + 0x3f1e728c,0x3f268e9d,0x3f2ea9a4,0x3f36c3a0, + 0x3f3edc93,0x3f46f47c,0x3f4f0b5d,0x3f572135, + 0x3f5f3606,0x3f6749cf,0x3f6f5c90,0x3f776e4a, + 0x3f7f7efe,0x3f878eab,0x3f8f9d53,0x3f97aaf6, + 0x3f9fb793,0x3fa7c32c,0x3fafcdc1,0x3fb7d752, + 0x3fbfdfe0,0x3fc7e76b,0x3fcfedf3,0x3fd7f378, + 0x3fdff7fc,0x3fe7fb7f,0x3feffe00,0x3ff7ff80, + 0x3fffffff, +}; + +static const int32_t av_sqr_exp_multbl_sf[2] = { + 0x20000000,0x2d413ccd, +}; + +static const int32_t av_costbl_1_sf[16] = { + 0x40000000,0x3ec52fa0,0x3b20d79e,0x3536cc52, + 0x2d413ccd,0x238e7673,0x187de2a7,0x0c7c5c1e, + 0x00000000,0xf383a3e3,0xe7821d5a,0xdc71898e, + 0xd2bec334,0xcac933af,0xc4df2863,0xc13ad061, +}; + +static const int32_t av_costbl_2_sf[32] = { + 0x40000000,0x3fffb10b,0x3ffec42d,0x3ffd3969, + 0x3ffb10c1,0x3ff84a3c,0x3ff4e5e0,0x3ff0e3b6, + 0x3fec43c7,0x3fe7061f,0x3fe12acb,0x3fdab1d9, + 0x3fd39b5a,0x3fcbe75e,0x3fc395f9,0x3fbaa740, + 0x3fb11b48,0x3fa6f228,0x3f9c2bfb,0x3f90c8da, + 0x3f84c8e2,0x3f782c30,0x3f6af2e3,0x3f5d1d1d, + 0x3f4eaafe,0x3f3f9cab,0x3f2ff24a,0x3f1fabff, + 0x3f0ec9f5,0x3efd4c54,0x3eeb3347,0x3ed87efc, +}; + +static const int32_t av_sintbl_2_sf[32] = { + 0x00000000,0x006487c4,0x00c90e90,0x012d936c, + 0x0192155f,0x01f69373,0x025b0caf,0x02bf801a, + 0x0323ecbe,0x038851a2,0x03ecadcf,0x0451004d, + 0x04b54825,0x0519845e,0x057db403,0x05e1d61b, + 0x0645e9af,0x06a9edc9,0x070de172,0x0771c3b3, + 0x07d59396,0x08395024,0x089cf867,0x09008b6a, + 0x09640837,0x09c76dd8,0x0a2abb59,0x0a8defc3, + 0x0af10a22,0x0b540982,0x0bb6ecef,0x0c19b374, +}; + +static const int32_t av_costbl_3_sf[32] = { + 0x40000000,0x3fffffec,0x3fffffb1,0x3fffff4e, + 0x3ffffec4,0x3ffffe13,0x3ffffd39,0x3ffffc39, + 0x3ffffb11,0x3ffff9c1,0x3ffff84a,0x3ffff6ac, + 0x3ffff4e6,0x3ffff2f8,0x3ffff0e3,0x3fffeea7, + 0x3fffec43,0x3fffe9b7,0x3fffe705,0x3fffe42a, + 0x3fffe128,0x3fffddff,0x3fffdaae,0x3fffd736, + 0x3fffd396,0x3fffcfcf,0x3fffcbe0,0x3fffc7ca, + 0x3fffc38c,0x3fffbf27,0x3fffba9b,0x3fffb5e7, +}; + +static const int32_t av_sintbl_3_sf[32] = { + 0x00000000,0x0003243f,0x0006487f,0x00096cbe, + 0x000c90fe,0x000fb53d,0x0012d97c,0x0015fdbb, + 0x001921fb,0x001c463a,0x001f6a79,0x00228eb8, + 0x0025b2f7,0x0028d736,0x002bfb74,0x002f1fb3, + 0x003243f1,0x00356830,0x00388c6e,0x003bb0ac, + 0x003ed4ea,0x0041f928,0x00451d66,0x004841a3, + 0x004b65e1,0x004e8a1e,0x0051ae5b,0x0054d297, + 0x0057f6d4,0x005b1b10,0x005e3f4c,0x00616388, +}; + +static const int32_t av_costbl_4_sf[33] = { + 0x40000000,0x40000000,0x40000000,0x40000000, + 0x40000000,0x40000000,0x3fffffff,0x3fffffff, + 0x3fffffff,0x3ffffffe,0x3ffffffe,0x3ffffffe, + 0x3ffffffd,0x3ffffffd,0x3ffffffc,0x3ffffffc, + 0x3ffffffb,0x3ffffffa,0x3ffffffa,0x3ffffff9, + 0x3ffffff8,0x3ffffff7,0x3ffffff7,0x3ffffff6, + 0x3ffffff5,0x3ffffff4,0x3ffffff3,0x3ffffff2, + 0x3ffffff1,0x3ffffff0,0x3fffffef,0x3fffffed, + 0x3fffffec, +}; + +static const int32_t av_sintbl_4_sf[33] = { + 0x00000000,0x00001922,0x00003244,0x00004b66, + 0x00006488,0x00007daa,0x000096cc,0x0000afee, + 0x0000c910,0x0000e232,0x0000fb54,0x00011476, + 0x00012d98,0x000146ba,0x00015fdc,0x000178fe, + 0x00019220,0x0001ab42,0x0001c464,0x0001dd86, + 0x0001f6a8,0x00020fca,0x000228ec,0x0002420e, + 0x00025b30,0x00027452,0x00028d74,0x0002a696, + 0x0002bfb7,0x0002d8d9,0x0002f1fb,0x00030b1d, + 0x0003243f, +}; +#endif /* AVUTIL_SOFTFLOAT_TABLES_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/spherical.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/spherical.c new file mode 100644 index 000000000..4be55f36c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/spherical.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "mem.h" +#include "spherical.h" + +AVSphericalMapping *av_spherical_alloc(size_t *size) +{ + AVSphericalMapping *spherical = av_mallocz(sizeof(AVSphericalMapping)); + if (!spherical) + return NULL; + + if (size) + *size = sizeof(*spherical); + + return spherical; +} + +void av_spherical_tile_bounds(const AVSphericalMapping *map, + size_t width, size_t height, + size_t *left, size_t *top, + size_t *right, size_t *bottom) +{ + /* conversion from 0.32 coordinates to pixels */ + uint64_t orig_width = (uint64_t) width * UINT32_MAX / + (UINT32_MAX - map->bound_right - map->bound_left); + uint64_t orig_height = (uint64_t) height * UINT32_MAX / + (UINT32_MAX - map->bound_bottom - map->bound_top); + + /* add a (UINT32_MAX - 1) to round up integer division */ + *left = (orig_width * map->bound_left + UINT32_MAX - 1) / UINT32_MAX; + *top = (orig_height * map->bound_top + UINT32_MAX - 1) / UINT32_MAX; + *right = orig_width - width - *left; + *bottom = orig_height - height - *top; +} + +static const char *spherical_projection_names[] = { + [AV_SPHERICAL_EQUIRECTANGULAR] = "equirectangular", + [AV_SPHERICAL_CUBEMAP] = "cubemap", + [AV_SPHERICAL_EQUIRECTANGULAR_TILE] = "tiled equirectangular", +}; + +const char *av_spherical_projection_name(enum AVSphericalProjection projection) +{ + if ((unsigned)projection >= FF_ARRAY_ELEMS(spherical_projection_names)) + return "unknown"; + + return spherical_projection_names[projection]; +} + +int av_spherical_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(spherical_projection_names); i++) { + size_t len = strlen(spherical_projection_names[i]); + if (!strncmp(spherical_projection_names[i], name, len)) + return i; + } + + return -1; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/spherical.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/spherical.h new file mode 100644 index 000000000..cef759cf2 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/spherical.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2016 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Spherical video + */ + +#ifndef AVUTIL_SPHERICAL_H +#define AVUTIL_SPHERICAL_H + +#include +#include + +/** + * @addtogroup lavu_video + * @{ + * + * @defgroup lavu_video_spherical Spherical video mapping + * @{ + */ + +/** + * @addtogroup lavu_video_spherical + * A spherical video file contains surfaces that need to be mapped onto a + * sphere. Depending on how the frame was converted, a different distortion + * transformation or surface recomposition function needs to be applied before + * the video should be mapped and displayed. + */ + +/** + * Projection of the video surface(s) on a sphere. + */ +enum AVSphericalProjection { + /** + * Video represents a sphere mapped on a flat surface using + * equirectangular projection. + */ + AV_SPHERICAL_EQUIRECTANGULAR, + + /** + * Video frame is split into 6 faces of a cube, and arranged on a + * 3x2 layout. Faces are oriented upwards for the front, left, right, + * and back faces. The up face is oriented so the top of the face is + * forwards and the down face is oriented so the top of the face is + * to the back. + */ + AV_SPHERICAL_CUBEMAP, + + /** + * Video represents a portion of a sphere mapped on a flat surface + * using equirectangular projection. The @ref bounding fields indicate + * the position of the current video in a larger surface. + */ + AV_SPHERICAL_EQUIRECTANGULAR_TILE, +}; + +/** + * This structure describes how to handle spherical videos, outlining + * information about projection, initial layout, and any other view modifier. + * + * @note The struct must be allocated with av_spherical_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVSphericalMapping { + /** + * Projection type. + */ + enum AVSphericalProjection projection; + + /** + * @name Initial orientation + * @{ + * There fields describe additional rotations applied to the sphere after + * the video frame is mapped onto it. The sphere is rotated around the + * viewer, who remains stationary. The order of transformation is always + * yaw, followed by pitch, and finally by roll. + * + * The coordinate system matches the one defined in OpenGL, where the + * forward vector (z) is coming out of screen, and it is equivalent to + * a rotation matrix of R = r_y(yaw) * r_x(pitch) * r_z(roll). + * + * A positive yaw rotates the portion of the sphere in front of the viewer + * toward their right. A positive pitch rotates the portion of the sphere + * in front of the viewer upwards. A positive roll tilts the portion of + * the sphere in front of the viewer to the viewer's right. + * + * These values are exported as 16.16 fixed point. + * + * See this equirectangular projection as example: + * + * @code{.unparsed} + * Yaw + * -180 0 180 + * 90 +-------------+-------------+ 180 + * | | | up + * P | | | y| forward + * i | ^ | | /z + * t 0 +-------------X-------------+ 0 Roll | / + * c | | | | / + * h | | | 0|/_____right + * | | | x + * -90 +-------------+-------------+ -180 + * + * X - the default camera center + * ^ - the default up vector + * @endcode + */ + int32_t yaw; ///< Rotation around the up vector [-180, 180]. + int32_t pitch; ///< Rotation around the right vector [-90, 90]. + int32_t roll; ///< Rotation around the forward vector [-180, 180]. + /** + * @} + */ + + /** + * @name Bounding rectangle + * @anchor bounding + * @{ + * These fields indicate the location of the current tile, and where + * it should be mapped relative to the original surface. They are + * exported as 0.32 fixed point, and can be converted to classic + * pixel values with av_spherical_bounds(). + * + * @code{.unparsed} + * +----------------+----------+ + * | |bound_top | + * | +--------+ | + * | bound_left |tile | | + * +<---------->| |<--->+bound_right + * | +--------+ | + * | | | + * | bound_bottom| | + * +----------------+----------+ + * @endcode + * + * If needed, the original video surface dimensions can be derived + * by adding the current stream or frame size to the related bounds, + * like in the following example: + * + * @code{c} + * original_width = tile->width + bound_left + bound_right; + * original_height = tile->height + bound_top + bound_bottom; + * @endcode + * + * @note These values are valid only for the tiled equirectangular + * projection type (@ref AV_SPHERICAL_EQUIRECTANGULAR_TILE), + * and should be ignored in all other cases. + */ + uint32_t bound_left; ///< Distance from the left edge + uint32_t bound_top; ///< Distance from the top edge + uint32_t bound_right; ///< Distance from the right edge + uint32_t bound_bottom; ///< Distance from the bottom edge + /** + * @} + */ + + /** + * Number of pixels to pad from the edge of each cube face. + * + * @note This value is valid for only for the cubemap projection type + * (@ref AV_SPHERICAL_CUBEMAP), and should be ignored in all other + * cases. + */ + uint32_t padding; +} AVSphericalMapping; + +/** + * Allocate a AVSphericalVideo structure and initialize its fields to default + * values. + * + * @return the newly allocated struct or NULL on failure + */ +AVSphericalMapping *av_spherical_alloc(size_t *size); + +/** + * Convert the @ref bounding fields from an AVSphericalVideo + * from 0.32 fixed point to pixels. + * + * @param map The AVSphericalVideo map to read bound values from. + * @param width Width of the current frame or stream. + * @param height Height of the current frame or stream. + * @param left Pixels from the left edge. + * @param top Pixels from the top edge. + * @param right Pixels from the right edge. + * @param bottom Pixels from the bottom edge. + */ +void av_spherical_tile_bounds(const AVSphericalMapping *map, + size_t width, size_t height, + size_t *left, size_t *top, + size_t *right, size_t *bottom); + +/** + * Provide a human-readable name of a given AVSphericalProjection. + * + * @param projection The input AVSphericalProjection. + * + * @return The name of the AVSphericalProjection, or "unknown". + */ +const char *av_spherical_projection_name(enum AVSphericalProjection projection); + +/** + * Get the AVSphericalProjection form a human-readable name. + * + * @param name The input string. + * + * @return The AVSphericalProjection value, or -1 if not found. + */ +int av_spherical_from_name(const char *name); +/** + * @} + * @} + */ + +#endif /* AVUTIL_SPHERICAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/stereo3d.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/stereo3d.c new file mode 100644 index 000000000..6edcdb179 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/stereo3d.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "common.h" +#include "mem.h" +#include "stereo3d.h" + +AVStereo3D *av_stereo3d_alloc(void) +{ + return av_mallocz(sizeof(AVStereo3D)); +} + +AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = av_frame_new_side_data(frame, + AV_FRAME_DATA_STEREO3D, + sizeof(AVStereo3D)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, sizeof(AVStereo3D)); + + return (AVStereo3D *)side_data->data; +} + +static const char * const stereo3d_type_names[] = { + [AV_STEREO3D_2D] = "2D", + [AV_STEREO3D_SIDEBYSIDE] = "side by side", + [AV_STEREO3D_TOPBOTTOM] = "top and bottom", + [AV_STEREO3D_FRAMESEQUENCE] = "frame alternate", + [AV_STEREO3D_CHECKERBOARD] = "checkerboard", + [AV_STEREO3D_SIDEBYSIDE_QUINCUNX] = "side by side (quincunx subsampling)", + [AV_STEREO3D_LINES] = "interleaved lines", + [AV_STEREO3D_COLUMNS] = "interleaved columns", +}; + +const char *av_stereo3d_type_name(unsigned int type) +{ + if (type >= FF_ARRAY_ELEMS(stereo3d_type_names)) + return "unknown"; + + return stereo3d_type_names[type]; +} + +int av_stereo3d_from_name(const char *name) +{ + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(stereo3d_type_names); i++) { + size_t len = strlen(stereo3d_type_names[i]); + if (!strncmp(stereo3d_type_names[i], name, len)) + return i; + } + + return -1; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/stereo3d.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/stereo3d.h new file mode 100644 index 000000000..d421aac2a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/stereo3d.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2013 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Stereoscopic video + */ + +#ifndef AVUTIL_STEREO3D_H +#define AVUTIL_STEREO3D_H + +#include + +#include "frame.h" + +/** + * @addtogroup lavu_video + * @{ + * + * @defgroup lavu_video_stereo3d Stereo3D types and functions + * @{ + */ + +/** + * @addtogroup lavu_video_stereo3d + * A stereoscopic video file consists in multiple views embedded in a single + * frame, usually describing two views of a scene. This file describes all + * possible codec-independent view arrangements. + * */ + +/** + * List of possible 3D Types + */ +enum AVStereo3DType { + /** + * Video is not stereoscopic (and metadata has to be there). + */ + AV_STEREO3D_2D, + + /** + * Views are next to each other. + * + * @code{.unparsed} + * LLLLRRRR + * LLLLRRRR + * LLLLRRRR + * ... + * @endcode + */ + AV_STEREO3D_SIDEBYSIDE, + + /** + * Views are on top of each other. + * + * @code{.unparsed} + * LLLLLLLL + * LLLLLLLL + * RRRRRRRR + * RRRRRRRR + * @endcode + */ + AV_STEREO3D_TOPBOTTOM, + + /** + * Views are alternated temporally. + * + * @code{.unparsed} + * frame0 frame1 frame2 ... + * LLLLLLLL RRRRRRRR LLLLLLLL + * LLLLLLLL RRRRRRRR LLLLLLLL + * LLLLLLLL RRRRRRRR LLLLLLLL + * ... ... ... + * @endcode + */ + AV_STEREO3D_FRAMESEQUENCE, + + /** + * Views are packed in a checkerboard-like structure per pixel. + * + * @code{.unparsed} + * LRLRLRLR + * RLRLRLRL + * LRLRLRLR + * ... + * @endcode + */ + AV_STEREO3D_CHECKERBOARD, + + /** + * Views are next to each other, but when upscaling + * apply a checkerboard pattern. + * + * @code{.unparsed} + * LLLLRRRR L L L L R R R R + * LLLLRRRR => L L L L R R R R + * LLLLRRRR L L L L R R R R + * LLLLRRRR L L L L R R R R + * @endcode + */ + AV_STEREO3D_SIDEBYSIDE_QUINCUNX, + + /** + * Views are packed per line, as if interlaced. + * + * @code{.unparsed} + * LLLLLLLL + * RRRRRRRR + * LLLLLLLL + * ... + * @endcode + */ + AV_STEREO3D_LINES, + + /** + * Views are packed per column. + * + * @code{.unparsed} + * LRLRLRLR + * LRLRLRLR + * LRLRLRLR + * ... + * @endcode + */ + AV_STEREO3D_COLUMNS, +}; + +/** + * List of possible view types. + */ +enum AVStereo3DView { + /** + * Frame contains two packed views. + */ + AV_STEREO3D_VIEW_PACKED, + + /** + * Frame contains only the left view. + */ + AV_STEREO3D_VIEW_LEFT, + + /** + * Frame contains only the right view. + */ + AV_STEREO3D_VIEW_RIGHT, +}; + +/** + * Inverted views, Right/Bottom represents the left view. + */ +#define AV_STEREO3D_FLAG_INVERT (1 << 0) + +/** + * Stereo 3D type: this structure describes how two videos are packed + * within a single video surface, with additional information as needed. + * + * @note The struct must be allocated with av_stereo3d_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVStereo3D { + /** + * How views are packed within the video. + */ + enum AVStereo3DType type; + + /** + * Additional information about the frame packing. + */ + int flags; + + /** + * Determines which views are packed. + */ + enum AVStereo3DView view; +} AVStereo3D; + +/** + * Allocate an AVStereo3D structure and set its fields to default values. + * The resulting struct can be freed using av_freep(). + * + * @return An AVStereo3D filled with default values or NULL on failure. + */ +AVStereo3D *av_stereo3d_alloc(void); + +/** + * Allocate a complete AVFrameSideData and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVStereo3D structure to be filled by caller. + */ +AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame); + +/** + * Provide a human-readable name of a given stereo3d type. + * + * @param type The input stereo3d type value. + * + * @return The name of the stereo3d value, or "unknown". + */ +const char *av_stereo3d_type_name(unsigned int type); + +/** + * Get the AVStereo3DType form a human-readable name. + * + * @param name The input string. + * + * @return The AVStereo3DType value, or -1 if not found. + */ +int av_stereo3d_from_name(const char *name); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_STEREO3D_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.c new file mode 100644 index 000000000..b138f8bea --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.c @@ -0,0 +1,121 @@ +/* + * A 32-bit implementation of the TEA algorithm + * Copyright (c) 2015 Vesselin Bontchev + * + * Loosely based on the implementation of David Wheeler and Roger Needham, + * https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm#Reference_code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avutil.h" +#include "common.h" +#include "intreadwrite.h" +#include "tea.h" + +typedef struct AVTEA { + uint32_t key[16]; + int rounds; +} AVTEA; + +struct AVTEA *av_tea_alloc(void) +{ + return av_mallocz(sizeof(struct AVTEA)); +} + +const int av_tea_size = sizeof(AVTEA); + +void av_tea_init(AVTEA *ctx, const uint8_t key[16], int rounds) +{ + int i; + + for (i = 0; i < 4; i++) + ctx->key[i] = AV_RB32(key + (i << 2)); + + ctx->rounds = rounds; +} + +static void tea_crypt_ecb(AVTEA *ctx, uint8_t *dst, const uint8_t *src, + int decrypt, uint8_t *iv) +{ + uint32_t v0, v1; + int rounds = ctx->rounds; + uint32_t k0, k1, k2, k3; + k0 = ctx->key[0]; + k1 = ctx->key[1]; + k2 = ctx->key[2]; + k3 = ctx->key[3]; + + v0 = AV_RB32(src); + v1 = AV_RB32(src + 4); + + if (decrypt) { + int i; + uint32_t delta = 0x9E3779B9U, sum = delta * (rounds / 2); + + for (i = 0; i < rounds / 2; i++) { + v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); + v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); + sum -= delta; + } + if (iv) { + v0 ^= AV_RB32(iv); + v1 ^= AV_RB32(iv + 4); + memcpy(iv, src, 8); + } + } else { + int i; + uint32_t sum = 0, delta = 0x9E3779B9U; + + for (i = 0; i < rounds / 2; i++) { + sum += delta; + v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); + v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); + } + } + + AV_WB32(dst, v0); + AV_WB32(dst + 4, v1); +} + +void av_tea_crypt(AVTEA *ctx, uint8_t *dst, const uint8_t *src, int count, + uint8_t *iv, int decrypt) +{ + int i; + + if (decrypt) { + while (count--) { + tea_crypt_ecb(ctx, dst, src, decrypt, iv); + + src += 8; + dst += 8; + } + } else { + while (count--) { + if (iv) { + for (i = 0; i < 8; i++) + dst[i] = src[i] ^ iv[i]; + tea_crypt_ecb(ctx, dst, dst, decrypt, NULL); + memcpy(iv, dst, 8); + } else { + tea_crypt_ecb(ctx, dst, src, decrypt, NULL); + } + src += 8; + dst += 8; + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.h new file mode 100644 index 000000000..dd929bdaf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tea.h @@ -0,0 +1,71 @@ +/* + * A 32-bit implementation of the TEA algorithm + * Copyright (c) 2015 Vesselin Bontchev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TEA_H +#define AVUTIL_TEA_H + +#include + +/** + * @file + * @brief Public header for libavutil TEA algorithm + * @defgroup lavu_tea TEA + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_tea_size; + +struct AVTEA; + +/** + * Allocate an AVTEA context + * To free the struct: av_free(ptr) + */ +struct AVTEA *av_tea_alloc(void); + +/** + * Initialize an AVTEA context. + * + * @param ctx an AVTEA context + * @param key a key of 16 bytes used for encryption/decryption + * @param rounds the number of rounds in TEA (64 is the "standard") + */ +void av_tea_init(struct AVTEA *ctx, const uint8_t key[16], int rounds); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param ctx an AVTEA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_tea_crypt(struct AVTEA *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_TEA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/thread.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/thread.h new file mode 100644 index 000000000..cc5272d37 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/thread.h @@ -0,0 +1,173 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// This header should only be used to simplify code where +// threading is optional, not as a generic threading abstraction. + +#ifndef AVUTIL_THREAD_H +#define AVUTIL_THREAD_H + +#include "config.h" + +#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS + +#if HAVE_PTHREADS +#include + +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 + +#include "log.h" + +#define ASSERT_PTHREAD_NORET(func, ...) do { \ + int ret = func(__VA_ARGS__); \ + if (ret) { \ + char errbuf[AV_ERROR_MAX_STRING_SIZE] = ""; \ + av_log(NULL, AV_LOG_FATAL, AV_STRINGIFY(func) \ + " failed with error: %s\n", \ + av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, \ + AVERROR(ret))); \ + abort(); \ + } \ +} while (0) + +#define ASSERT_PTHREAD(func, ...) do { \ + ASSERT_PTHREAD_NORET(func, __VA_ARGS__); \ + return 0; \ +} while (0) + +static inline int strict_pthread_join(pthread_t thread, void **value_ptr) +{ + ASSERT_PTHREAD(pthread_join, thread, value_ptr); +} + +static inline int strict_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + if (attr) { + ASSERT_PTHREAD_NORET(pthread_mutex_init, mutex, attr); + } else { + pthread_mutexattr_t local_attr; + ASSERT_PTHREAD_NORET(pthread_mutexattr_init, &local_attr); + ASSERT_PTHREAD_NORET(pthread_mutexattr_settype, &local_attr, PTHREAD_MUTEX_ERRORCHECK); + ASSERT_PTHREAD_NORET(pthread_mutex_init, mutex, &local_attr); + ASSERT_PTHREAD_NORET(pthread_mutexattr_destroy, &local_attr); + } + return 0; +} + +static inline int strict_pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + ASSERT_PTHREAD(pthread_mutex_destroy, mutex); +} + +static inline int strict_pthread_mutex_lock(pthread_mutex_t *mutex) +{ + ASSERT_PTHREAD(pthread_mutex_lock, mutex); +} + +static inline int strict_pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + ASSERT_PTHREAD(pthread_mutex_unlock, mutex); +} + +static inline int strict_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) +{ + ASSERT_PTHREAD(pthread_cond_init, cond, attr); +} + +static inline int strict_pthread_cond_destroy(pthread_cond_t *cond) +{ + ASSERT_PTHREAD(pthread_cond_destroy, cond); +} + +static inline int strict_pthread_cond_signal(pthread_cond_t *cond) +{ + ASSERT_PTHREAD(pthread_cond_signal, cond); +} + +static inline int strict_pthread_cond_broadcast(pthread_cond_t *cond) +{ + ASSERT_PTHREAD(pthread_cond_broadcast, cond); +} + +static inline int strict_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + ASSERT_PTHREAD(pthread_cond_wait, cond, mutex); +} + +static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + ASSERT_PTHREAD(pthread_once, once_control, init_routine); +} + +#define pthread_join strict_pthread_join +#define pthread_mutex_init strict_pthread_mutex_init +#define pthread_mutex_destroy strict_pthread_mutex_destroy +#define pthread_mutex_lock strict_pthread_mutex_lock +#define pthread_mutex_unlock strict_pthread_mutex_unlock +#define pthread_cond_init strict_pthread_cond_init +#define pthread_cond_destroy strict_pthread_cond_destroy +#define pthread_cond_signal strict_pthread_cond_signal +#define pthread_cond_broadcast strict_pthread_cond_broadcast +#define pthread_cond_wait strict_pthread_cond_wait +#define pthread_once strict_pthread_once +#endif + +#elif HAVE_OS2THREADS +#include "compat/os2threads.h" +#else +#include "compat/w32pthreads.h" +#endif + +#define AVMutex pthread_mutex_t +#define AV_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +#define ff_mutex_init pthread_mutex_init +#define ff_mutex_lock pthread_mutex_lock +#define ff_mutex_unlock pthread_mutex_unlock +#define ff_mutex_destroy pthread_mutex_destroy + +#define AVOnce pthread_once_t +#define AV_ONCE_INIT PTHREAD_ONCE_INIT + +#define ff_thread_once(control, routine) pthread_once(control, routine) + +#else + +#define AVMutex char +#define AV_MUTEX_INITIALIZER 0 + +static inline int ff_mutex_init(AVMutex *mutex, const void *attr){ return 0; } +static inline int ff_mutex_lock(AVMutex *mutex){ return 0; } +static inline int ff_mutex_unlock(AVMutex *mutex){ return 0; } +static inline int ff_mutex_destroy(AVMutex *mutex){ return 0; } + +#define AVOnce char +#define AV_ONCE_INIT 0 + +static inline int ff_thread_once(char *control, void (*routine)(void)) +{ + if (!*control) { + routine(); + *control = 1; + } + return 0; +} + +#endif + +#endif /* AVUTIL_THREAD_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/threadmessage.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/threadmessage.c new file mode 100644 index 000000000..764b7fb81 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/threadmessage.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2014 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FFmpeg; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "fifo.h" +#include "threadmessage.h" +#include "thread.h" + +struct AVThreadMessageQueue { +#if HAVE_THREADS + AVFifoBuffer *fifo; + pthread_mutex_t lock; + pthread_cond_t cond_recv; + pthread_cond_t cond_send; + int err_send; + int err_recv; + unsigned elsize; + void (*free_func)(void *msg); +#else + int dummy; +#endif +}; + +int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, + unsigned nelem, + unsigned elsize) +{ +#if HAVE_THREADS + AVThreadMessageQueue *rmq; + int ret = 0; + + if (nelem > INT_MAX / elsize) + return AVERROR(EINVAL); + if (!(rmq = av_mallocz(sizeof(*rmq)))) + return AVERROR(ENOMEM); + if ((ret = pthread_mutex_init(&rmq->lock, NULL))) { + av_free(rmq); + return AVERROR(ret); + } + if ((ret = pthread_cond_init(&rmq->cond_recv, NULL))) { + pthread_mutex_destroy(&rmq->lock); + av_free(rmq); + return AVERROR(ret); + } + if ((ret = pthread_cond_init(&rmq->cond_send, NULL))) { + pthread_cond_destroy(&rmq->cond_recv); + pthread_mutex_destroy(&rmq->lock); + av_free(rmq); + return AVERROR(ret); + } + if (!(rmq->fifo = av_fifo_alloc(elsize * nelem))) { + pthread_cond_destroy(&rmq->cond_send); + pthread_cond_destroy(&rmq->cond_recv); + pthread_mutex_destroy(&rmq->lock); + av_free(rmq); + return AVERROR(ENOMEM); + } + rmq->elsize = elsize; + *mq = rmq; + return 0; +#else + *mq = NULL; + return AVERROR(ENOSYS); +#endif /* HAVE_THREADS */ +} + +void av_thread_message_queue_set_free_func(AVThreadMessageQueue *mq, + void (*free_func)(void *msg)) +{ +#if HAVE_THREADS + mq->free_func = free_func; +#endif +} + +void av_thread_message_queue_free(AVThreadMessageQueue **mq) +{ +#if HAVE_THREADS + if (*mq) { + av_thread_message_flush(*mq); + av_fifo_freep(&(*mq)->fifo); + pthread_cond_destroy(&(*mq)->cond_send); + pthread_cond_destroy(&(*mq)->cond_recv); + pthread_mutex_destroy(&(*mq)->lock); + av_freep(mq); + } +#endif +} + +int av_thread_message_queue_nb_elems(AVThreadMessageQueue *mq) +{ +#if HAVE_THREADS + int ret; + pthread_mutex_lock(&mq->lock); + ret = av_fifo_size(mq->fifo); + pthread_mutex_unlock(&mq->lock); + return ret / mq->elsize; +#else + return AVERROR(ENOSYS); +#endif +} + +#if HAVE_THREADS + +static int av_thread_message_queue_send_locked(AVThreadMessageQueue *mq, + void *msg, + unsigned flags) +{ + while (!mq->err_send && av_fifo_space(mq->fifo) < mq->elsize) { + if ((flags & AV_THREAD_MESSAGE_NONBLOCK)) + return AVERROR(EAGAIN); + pthread_cond_wait(&mq->cond_send, &mq->lock); + } + if (mq->err_send) + return mq->err_send; + av_fifo_generic_write(mq->fifo, msg, mq->elsize, NULL); + /* one message is sent, signal one receiver */ + pthread_cond_signal(&mq->cond_recv); + return 0; +} + +static int av_thread_message_queue_recv_locked(AVThreadMessageQueue *mq, + void *msg, + unsigned flags) +{ + while (!mq->err_recv && av_fifo_size(mq->fifo) < mq->elsize) { + if ((flags & AV_THREAD_MESSAGE_NONBLOCK)) + return AVERROR(EAGAIN); + pthread_cond_wait(&mq->cond_recv, &mq->lock); + } + if (av_fifo_size(mq->fifo) < mq->elsize) + return mq->err_recv; + av_fifo_generic_read(mq->fifo, msg, mq->elsize, NULL); + /* one message space appeared, signal one sender */ + pthread_cond_signal(&mq->cond_send); + return 0; +} + +#endif /* HAVE_THREADS */ + +int av_thread_message_queue_send(AVThreadMessageQueue *mq, + void *msg, + unsigned flags) +{ +#if HAVE_THREADS + int ret; + + pthread_mutex_lock(&mq->lock); + ret = av_thread_message_queue_send_locked(mq, msg, flags); + pthread_mutex_unlock(&mq->lock); + return ret; +#else + return AVERROR(ENOSYS); +#endif /* HAVE_THREADS */ +} + +int av_thread_message_queue_recv(AVThreadMessageQueue *mq, + void *msg, + unsigned flags) +{ +#if HAVE_THREADS + int ret; + + pthread_mutex_lock(&mq->lock); + ret = av_thread_message_queue_recv_locked(mq, msg, flags); + pthread_mutex_unlock(&mq->lock); + return ret; +#else + return AVERROR(ENOSYS); +#endif /* HAVE_THREADS */ +} + +void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, + int err) +{ +#if HAVE_THREADS + pthread_mutex_lock(&mq->lock); + mq->err_send = err; + pthread_cond_broadcast(&mq->cond_send); + pthread_mutex_unlock(&mq->lock); +#endif /* HAVE_THREADS */ +} + +void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, + int err) +{ +#if HAVE_THREADS + pthread_mutex_lock(&mq->lock); + mq->err_recv = err; + pthread_cond_broadcast(&mq->cond_recv); + pthread_mutex_unlock(&mq->lock); +#endif /* HAVE_THREADS */ +} + +#if HAVE_THREADS +static void free_func_wrap(void *arg, void *msg, int size) +{ + AVThreadMessageQueue *mq = arg; + mq->free_func(msg); +} +#endif + +void av_thread_message_flush(AVThreadMessageQueue *mq) +{ +#if HAVE_THREADS + int used, off; + void *free_func = mq->free_func; + + pthread_mutex_lock(&mq->lock); + used = av_fifo_size(mq->fifo); + if (free_func) + for (off = 0; off < used; off += mq->elsize) + av_fifo_generic_peek_at(mq->fifo, mq, off, mq->elsize, free_func_wrap); + av_fifo_drain(mq->fifo, used); + /* only the senders need to be notified since the queue is empty and there + * is nothing to read */ + pthread_cond_broadcast(&mq->cond_send); + pthread_mutex_unlock(&mq->lock); +#endif /* HAVE_THREADS */ +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/threadmessage.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/threadmessage.h new file mode 100644 index 000000000..42ce655f3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/threadmessage.h @@ -0,0 +1,115 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FFmpeg; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_THREADMESSAGE_H +#define AVUTIL_THREADMESSAGE_H + +typedef struct AVThreadMessageQueue AVThreadMessageQueue; + +typedef enum AVThreadMessageFlags { + + /** + * Perform non-blocking operation. + * If this flag is set, send and recv operations are non-blocking and + * return AVERROR(EAGAIN) immediately if they can not proceed. + */ + AV_THREAD_MESSAGE_NONBLOCK = 1, + +} AVThreadMessageFlags; + +/** + * Allocate a new message queue. + * + * @param mq pointer to the message queue + * @param nelem maximum number of elements in the queue + * @param elsize size of each element in the queue + * @return >=0 for success; <0 for error, in particular AVERROR(ENOSYS) if + * lavu was built without thread support + */ +int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, + unsigned nelem, + unsigned elsize); + +/** + * Free a message queue. + * + * The message queue must no longer be in use by another thread. + */ +void av_thread_message_queue_free(AVThreadMessageQueue **mq); + +/** + * Send a message on the queue. + */ +int av_thread_message_queue_send(AVThreadMessageQueue *mq, + void *msg, + unsigned flags); + +/** + * Receive a message from the queue. + */ +int av_thread_message_queue_recv(AVThreadMessageQueue *mq, + void *msg, + unsigned flags); + +/** + * Set the sending error code. + * + * If the error code is set to non-zero, av_thread_message_queue_send() will + * return it immediately. Conventional values, such as AVERROR_EOF or + * AVERROR(EAGAIN), can be used to cause the sending thread to stop or + * suspend its operation. + */ +void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, + int err); + +/** + * Set the receiving error code. + * + * If the error code is set to non-zero, av_thread_message_queue_recv() will + * return it immediately when there are no longer available messages. + * Conventional values, such as AVERROR_EOF or AVERROR(EAGAIN), can be used + * to cause the receiving thread to stop or suspend its operation. + */ +void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, + int err); + +/** + * Set the optional free message callback function which will be called if an + * operation is removing messages from the queue. + */ +void av_thread_message_queue_set_free_func(AVThreadMessageQueue *mq, + void (*free_func)(void *msg)); + +/** + * Return the current number of messages in the queue. + * + * @return the current number of messages or AVERROR(ENOSYS) if lavu was built + * without thread support + */ +int av_thread_message_queue_nb_elems(AVThreadMessageQueue *mq); + +/** + * Flush the message queue + * + * This function is mostly equivalent to reading and free-ing every message + * except that it will be done in a single operation (no lock/unlock between + * reads). + */ +void av_thread_message_flush(AVThreadMessageQueue *mq); + +#endif /* AVUTIL_THREADMESSAGE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time.c new file mode 100644 index 000000000..afa6658aa --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2000-2003 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#if HAVE_GETTIMEOFDAY +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_WINDOWS_H +#include +#endif + +#include "time.h" +#include "error.h" + +int64_t av_gettime(void) +{ +#if HAVE_GETTIMEOFDAY + struct timeval tv; + gettimeofday(&tv, NULL); + return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; +#elif HAVE_GETSYSTEMTIMEASFILETIME + FILETIME ft; + int64_t t; + GetSystemTimeAsFileTime(&ft); + t = (int64_t)ft.dwHighDateTime << 32 | ft.dwLowDateTime; + return t / 10 - 11644473600000000; /* Jan 1, 1601 */ +#else + return -1; +#endif +} + +int64_t av_gettime_relative(void) +{ +#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) +#ifdef __APPLE__ + if (clock_gettime) +#endif + { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (int64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + } +#endif + return av_gettime() + 42 * 60 * 60 * INT64_C(1000000); +} + +int av_gettime_relative_is_monotonic(void) +{ +#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) +#ifdef __APPLE__ + if (!clock_gettime) + return 0; +#endif + return 1; +#else + return 0; +#endif +} + +int av_usleep(unsigned usec) +{ +#if HAVE_NANOSLEEP + struct timespec ts = { usec / 1000000, usec % 1000000 * 1000 }; + while (nanosleep(&ts, &ts) < 0 && errno == EINTR); + return 0; +#elif HAVE_USLEEP + return usleep(usec); +#elif HAVE_SLEEP + Sleep(usec / 1000); + return 0; +#else + return AVERROR(ENOSYS); +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time.h new file mode 100644 index 000000000..dc169b064 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2000-2003 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TIME_H +#define AVUTIL_TIME_H + +#include + +/** + * Get the current time in microseconds. + */ +int64_t av_gettime(void); + +/** + * Get the current time in microseconds since some unspecified starting point. + * On platforms that support it, the time comes from a monotonic clock + * This property makes this time source ideal for measuring relative time. + * The returned values may not be monotonic on platforms where a monotonic + * clock is not available. + */ +int64_t av_gettime_relative(void); + +/** + * Indicates with a boolean result if the av_gettime_relative() time source + * is monotonic. + */ +int av_gettime_relative_is_monotonic(void); + +/** + * Sleep for a period of time. Although the duration is expressed in + * microseconds, the actual delay may be rounded to the precision of the + * system timer. + * + * @param usec Number of microseconds to sleep. + * @return zero on success or (negative) error code. + */ +int av_usleep(unsigned usec); + +#endif /* AVUTIL_TIME_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time_internal.h new file mode 100644 index 000000000..d0f007ab1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/time_internal.h @@ -0,0 +1,49 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TIME_INTERNAL_H +#define AVUTIL_TIME_INTERNAL_H + +#include +#include "config.h" + +#if !HAVE_GMTIME_R && !defined(gmtime_r) +static inline struct tm *ff_gmtime_r(const time_t* clock, struct tm *result) +{ + struct tm *ptr = gmtime(clock); + if (!ptr) + return NULL; + *result = *ptr; + return result; +} +#define gmtime_r ff_gmtime_r +#endif + +#if !HAVE_LOCALTIME_R && !defined(localtime_r) +static inline struct tm *ff_localtime_r(const time_t* clock, struct tm *result) +{ + struct tm *ptr = localtime(clock); + if (!ptr) + return NULL; + *result = *ptr; + return result; +} +#define localtime_r ff_localtime_r +#endif + +#endif /* AVUTIL_TIME_INTERNAL_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timecode.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timecode.c new file mode 100644 index 000000000..60077ba0c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timecode.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier + * Copyright (c) 2011-2012 Smartjog S.A.S, Clément BÅ“sch + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Timecode helpers + * @see https://en.wikipedia.org/wiki/SMPTE_time_code + * @see http://www.dropframetimecode.org + */ + +#include +#include "timecode.h" +#include "log.h" +#include "error.h" + +int av_timecode_adjust_ntsc_framenum2(int framenum, int fps) +{ + /* only works for NTSC 29.97 and 59.94 */ + int drop_frames = 0; + int d, m, frames_per_10mins; + + if (fps == 30) { + drop_frames = 2; + frames_per_10mins = 17982; + } else if (fps == 60) { + drop_frames = 4; + frames_per_10mins = 35964; + } else + return framenum; + + d = framenum / frames_per_10mins; + m = framenum % frames_per_10mins; + + return framenum + 9 * drop_frames * d + drop_frames * ((m - drop_frames) / (frames_per_10mins / 10)); +} + +uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) +{ + unsigned fps = tc->fps; + int drop = !!(tc->flags & AV_TIMECODE_FLAG_DROPFRAME); + int hh, mm, ss, ff; + + framenum += tc->start; + if (drop) + framenum = av_timecode_adjust_ntsc_framenum2(framenum, tc->fps); + ff = framenum % fps; + ss = framenum / fps % 60; + mm = framenum / (fps*60) % 60; + hh = framenum / (fps*3600) % 24; + return 0 << 31 | // color frame flag (0: unsync mode, 1: sync mode) + drop << 30 | // drop frame flag (0: non drop, 1: drop) + (ff / 10) << 28 | // tens of frames + (ff % 10) << 24 | // units of frames + 0 << 23 | // PC (NTSC) or BGF0 (PAL) + (ss / 10) << 20 | // tens of seconds + (ss % 10) << 16 | // units of seconds + 0 << 15 | // BGF0 (NTSC) or BGF2 (PAL) + (mm / 10) << 12 | // tens of minutes + (mm % 10) << 8 | // units of minutes + 0 << 7 | // BGF2 (NTSC) or PC (PAL) + 0 << 6 | // BGF1 + (hh / 10) << 4 | // tens of hours + (hh % 10); // units of hours +} + +char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum) +{ + int fps = tc->fps; + int drop = tc->flags & AV_TIMECODE_FLAG_DROPFRAME; + int hh, mm, ss, ff, neg = 0; + + framenum += tc->start; + if (drop) + framenum = av_timecode_adjust_ntsc_framenum2(framenum, fps); + if (framenum < 0) { + framenum = -framenum; + neg = tc->flags & AV_TIMECODE_FLAG_ALLOWNEGATIVE; + } + ff = framenum % fps; + ss = framenum / fps % 60; + mm = framenum / (fps*60) % 60; + hh = framenum / (fps*3600); + if (tc->flags & AV_TIMECODE_FLAG_24HOURSMAX) + hh = hh % 24; + snprintf(buf, AV_TIMECODE_STR_SIZE, "%s%02d:%02d:%02d%c%02d", + neg ? "-" : "", + hh, mm, ss, drop ? ';' : ':', ff); + return buf; +} + +static unsigned bcd2uint(uint8_t bcd) +{ + unsigned low = bcd & 0xf; + unsigned high = bcd >> 4; + if (low > 9 || high > 9) + return 0; + return low + 10*high; +} + +char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df) +{ + unsigned hh = bcd2uint(tcsmpte & 0x3f); // 6-bit hours + unsigned mm = bcd2uint(tcsmpte>>8 & 0x7f); // 7-bit minutes + unsigned ss = bcd2uint(tcsmpte>>16 & 0x7f); // 7-bit seconds + unsigned ff = bcd2uint(tcsmpte>>24 & 0x3f); // 6-bit frames + unsigned drop = tcsmpte & 1<<30 && !prevent_df; // 1-bit drop if not arbitrary bit + snprintf(buf, AV_TIMECODE_STR_SIZE, "%02u:%02u:%02u%c%02u", + hh, mm, ss, drop ? ';' : ':', ff); + return buf; +} + +char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit) +{ + snprintf(buf, AV_TIMECODE_STR_SIZE, + "%02"PRIu32":%02"PRIu32":%02"PRIu32"%c%02"PRIu32, + tc25bit>>19 & 0x1f, // 5-bit hours + tc25bit>>13 & 0x3f, // 6-bit minutes + tc25bit>>6 & 0x3f, // 6-bit seconds + tc25bit & 1<<24 ? ';' : ':', // 1-bit drop flag + tc25bit & 0x3f); // 6-bit frames + return buf; +} + +static int check_fps(int fps) +{ + int i; + static const int supported_fps[] = { + 24, 25, 30, 48, 50, 60, 100, 120, 150, + }; + + for (i = 0; i < FF_ARRAY_ELEMS(supported_fps); i++) + if (fps == supported_fps[i]) + return 0; + return -1; +} + +static int check_timecode(void *log_ctx, AVTimecode *tc) +{ + if ((int)tc->fps <= 0) { + av_log(log_ctx, AV_LOG_ERROR, "Valid timecode frame rate must be specified. Minimum value is 1\n"); + return AVERROR(EINVAL); + } + if ((tc->flags & AV_TIMECODE_FLAG_DROPFRAME) && tc->fps != 30 && tc->fps != 60) { + av_log(log_ctx, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 or 60000/1001 FPS\n"); + return AVERROR(EINVAL); + } + if (check_fps(tc->fps) < 0) { + av_log(log_ctx, AV_LOG_WARNING, "Using non-standard frame rate %d/%d\n", + tc->rate.num, tc->rate.den); + } + return 0; +} + +static int fps_from_frame_rate(AVRational rate) +{ + if (!rate.den || !rate.num) + return -1; + return (rate.num + rate.den/2) / rate.den; +} + +int av_timecode_check_frame_rate(AVRational rate) +{ + return check_fps(fps_from_frame_rate(rate)); +} + +int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx) +{ + memset(tc, 0, sizeof(*tc)); + tc->start = frame_start; + tc->flags = flags; + tc->rate = rate; + tc->fps = fps_from_frame_rate(rate); + return check_timecode(log_ctx, tc); +} + +int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx) +{ + char c; + int hh, mm, ss, ff, ret; + + if (sscanf(str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) { + av_log(log_ctx, AV_LOG_ERROR, "Unable to parse timecode, " + "syntax: hh:mm:ss[:;.]ff\n"); + return AVERROR_INVALIDDATA; + } + + memset(tc, 0, sizeof(*tc)); + tc->flags = c != ':' ? AV_TIMECODE_FLAG_DROPFRAME : 0; // drop if ';', '.', ... + tc->rate = rate; + tc->fps = fps_from_frame_rate(rate); + + ret = check_timecode(log_ctx, tc); + if (ret < 0) + return ret; + + tc->start = (hh*3600 + mm*60 + ss) * tc->fps + ff; + if (tc->flags & AV_TIMECODE_FLAG_DROPFRAME) { /* adjust frame number */ + int tmins = 60*hh + mm; + tc->start -= (tc->fps == 30 ? 2 : 4) * (tmins - tmins/10); + } + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timecode.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timecode.h new file mode 100644 index 000000000..37c1361bc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timecode.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier + * Copyright (c) 2011-2012 Smartjog S.A.S, Clément BÅ“sch + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Timecode helpers header + */ + +#ifndef AVUTIL_TIMECODE_H +#define AVUTIL_TIMECODE_H + +#include +#include "rational.h" + +#define AV_TIMECODE_STR_SIZE 23 + +enum AVTimecodeFlag { + AV_TIMECODE_FLAG_DROPFRAME = 1<<0, ///< timecode is drop frame + AV_TIMECODE_FLAG_24HOURSMAX = 1<<1, ///< timecode wraps after 24 hours + AV_TIMECODE_FLAG_ALLOWNEGATIVE = 1<<2, ///< negative time values are allowed +}; + +typedef struct { + int start; ///< timecode frame start (first base frame number) + uint32_t flags; ///< flags such as drop frame, +24 hours support, ... + AVRational rate; ///< frame rate in rational form + unsigned fps; ///< frame per second; must be consistent with the rate field +} AVTimecode; + +/** + * Adjust frame number for NTSC drop frame time code. + * + * @param framenum frame number to adjust + * @param fps frame per second, 30 or 60 + * @return adjusted frame number + * @warning adjustment is only valid in NTSC 29.97 and 59.94 + */ +int av_timecode_adjust_ntsc_framenum2(int framenum, int fps); + +/** + * Convert frame number to SMPTE 12M binary representation. + * + * @param tc timecode data correctly initialized + * @param framenum frame number + * @return the SMPTE binary representation + * + * @note Frame number adjustment is automatically done in case of drop timecode, + * you do NOT have to call av_timecode_adjust_ntsc_framenum2(). + * @note The frame number is relative to tc->start. + * @note Color frame (CF), binary group flags (BGF) and biphase mark polarity + * correction (PC) bits are set to zero. + */ +uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum); + +/** + * Load timecode string in buf. + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param tc timecode data correctly initialized + * @param framenum frame number + * @return the buf parameter + * + * @note Timecode representation can be a negative timecode and have more than + * 24 hours, but will only be honored if the flags are correctly set. + * @note The frame number is relative to tc->start. + */ +char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum); + +/** + * Get the timecode string from the SMPTE timecode format. + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param tcsmpte the 32-bit SMPTE timecode + * @param prevent_df prevent the use of a drop flag when it is known the DF bit + * is arbitrary + * @return the buf parameter + */ +char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df); + +/** + * Get the timecode string from the 25-bit timecode format (MPEG GOP format). + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param tc25bit the 25-bits timecode + * @return the buf parameter + */ +char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit); + +/** + * Init a timecode struct with the passed parameters. + * + * @param log_ctx a pointer to an arbitrary struct of which the first field + * is a pointer to an AVClass struct (used for av_log) + * @param tc pointer to an allocated AVTimecode + * @param rate frame rate in rational form + * @param flags miscellaneous flags such as drop frame, +24 hours, ... + * (see AVTimecodeFlag) + * @param frame_start the first frame number + * @return 0 on success, AVERROR otherwise + */ +int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx); + +/** + * Parse timecode representation (hh:mm:ss[:;.]ff). + * + * @param log_ctx a pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct (used for av_log). + * @param tc pointer to an allocated AVTimecode + * @param rate frame rate in rational form + * @param str timecode string which will determine the frame start + * @return 0 on success, AVERROR otherwise + */ +int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx); + +/** + * Check if the timecode feature is available for the given frame rate + * + * @return 0 if supported, <0 otherwise + */ +int av_timecode_check_frame_rate(AVRational rate); + +#endif /* AVUTIL_TIMECODE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timer.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timer.h new file mode 100644 index 000000000..0bb353cfc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timer.h @@ -0,0 +1,141 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * high precision timer, useful to profile code + */ + +#ifndef AVUTIL_TIMER_H +#define AVUTIL_TIMER_H + +#include "config.h" + +#if CONFIG_LINUX_PERF +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# include // read(3) +# include +# include +# include +#endif + +#include +#include +#include + +#if HAVE_MACH_ABSOLUTE_TIME +#include +#endif + +#include "log.h" + +#if ARCH_AARCH64 +# include "aarch64/timer.h" +#elif ARCH_ARM +# include "arm/timer.h" +#elif ARCH_PPC +# include "ppc/timer.h" +#elif ARCH_X86 +# include "x86/timer.h" +#endif + +#if !defined(AV_READ_TIME) +# if HAVE_GETHRTIME +# define AV_READ_TIME gethrtime +# elif HAVE_MACH_ABSOLUTE_TIME +# define AV_READ_TIME mach_absolute_time +# endif +#endif + +#ifndef FF_TIMER_UNITS +# define FF_TIMER_UNITS "UNITS" +#endif + +#define TIMER_REPORT(id, tdiff) \ + { \ + static uint64_t tsum = 0; \ + static int tcount = 0; \ + static int tskip_count = 0; \ + static int thistogram[32] = {0}; \ + thistogram[av_log2(tdiff)]++; \ + if (tcount < 2 || \ + (tdiff) < 8 * tsum / tcount || \ + (tdiff) < 2000) { \ + tsum += (tdiff); \ + tcount++; \ + } else \ + tskip_count++; \ + if (((tcount + tskip_count) & (tcount + tskip_count - 1)) == 0) { \ + int i; \ + av_log(NULL, AV_LOG_ERROR, \ + "%7"PRIu64" " FF_TIMER_UNITS " in %s,%8d runs,%7d skips", \ + tsum * 10 / tcount, id, tcount, tskip_count); \ + for (i = 0; i < 32; i++) \ + av_log(NULL, AV_LOG_VERBOSE, " %2d", av_log2(2*thistogram[i]));\ + av_log(NULL, AV_LOG_ERROR, "\n"); \ + } \ + } + +#if CONFIG_LINUX_PERF + +#define START_TIMER \ + static int linux_perf_fd; \ + uint64_t tperf; \ + if (!linux_perf_fd) { \ + struct perf_event_attr attr = { \ + .type = PERF_TYPE_HARDWARE, \ + .size = sizeof(struct perf_event_attr), \ + .config = PERF_COUNT_HW_CPU_CYCLES, \ + .disabled = 1, \ + .exclude_kernel = 1, \ + .exclude_hv = 1, \ + }; \ + linux_perf_fd = syscall(__NR_perf_event_open, &attr, \ + 0, -1, -1, 0); \ + } \ + if (linux_perf_fd == -1) { \ + av_log(NULL, AV_LOG_ERROR, "perf_event_open failed: %s\n", \ + av_err2str(AVERROR(errno))); \ + } else { \ + ioctl(linux_perf_fd, PERF_EVENT_IOC_RESET, 0); \ + ioctl(linux_perf_fd, PERF_EVENT_IOC_ENABLE, 0); \ + } + +#define STOP_TIMER(id) \ + ioctl(linux_perf_fd, PERF_EVENT_IOC_DISABLE, 0); \ + read(linux_perf_fd, &tperf, sizeof(tperf)); \ + TIMER_REPORT(id, tperf) + +#elif defined(AV_READ_TIME) +#define START_TIMER \ + uint64_t tend; \ + uint64_t tstart = AV_READ_TIME(); \ + +#define STOP_TIMER(id) \ + tend = AV_READ_TIME(); \ + TIMER_REPORT(id, tend - tstart) +#else +#define START_TIMER +#define STOP_TIMER(id) { } +#endif + +#endif /* AVUTIL_TIMER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timestamp.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timestamp.h new file mode 100644 index 000000000..e082f01b4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/timestamp.h @@ -0,0 +1,78 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * timestamp utils, mostly useful for debugging/logging purposes + */ + +#ifndef AVUTIL_TIMESTAMP_H +#define AVUTIL_TIMESTAMP_H + +#include "common.h" + +#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) && !defined(PRId64) +#error missing -D__STDC_FORMAT_MACROS / #define __STDC_FORMAT_MACROS +#endif + +#define AV_TS_MAX_STRING_SIZE 32 + +/** + * Fill the provided buffer with a string containing a timestamp + * representation. + * + * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE + * @param ts the timestamp to represent + * @return the buffer in input + */ +static inline char *av_ts_make_string(char *buf, int64_t ts) +{ + if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS"); + else snprintf(buf, AV_TS_MAX_STRING_SIZE, "%" PRId64, ts); + return buf; +} + +/** + * Convenience macro, the return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_ts2str(ts) av_ts_make_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts) + +/** + * Fill the provided buffer with a string containing a timestamp time + * representation. + * + * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE + * @param ts the timestamp to represent + * @param tb the timebase of the timestamp + * @return the buffer in input + */ +static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb) +{ + if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS"); + else snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.6g", av_q2d(*tb) * ts); + return buf; +} + +/** + * Convenience macro, the return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_ts2timestr(ts, tb) av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts, tb) + +#endif /* AVUTIL_TIMESTAMP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tree.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tree.c new file mode 100644 index 000000000..7b57b2d39 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tree.c @@ -0,0 +1,168 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "error.h" +#include "log.h" +#include "mem.h" +#include "tree.h" + +typedef struct AVTreeNode { + struct AVTreeNode *child[2]; + void *elem; + int state; +} AVTreeNode; + +const int av_tree_node_size = sizeof(AVTreeNode); + +struct AVTreeNode *av_tree_node_alloc(void) +{ + return av_mallocz(sizeof(struct AVTreeNode)); +} + +void *av_tree_find(const AVTreeNode *t, void *key, + int (*cmp)(const void *key, const void *b), void *next[2]) +{ + if (t) { + unsigned int v = cmp(key, t->elem); + if (v) { + if (next) + next[v >> 31] = t->elem; + return av_tree_find(t->child[(v >> 31) ^ 1], key, cmp, next); + } else { + if (next) { + av_tree_find(t->child[0], key, cmp, next); + av_tree_find(t->child[1], key, cmp, next); + } + return t->elem; + } + } + return NULL; +} + +void *av_tree_insert(AVTreeNode **tp, void *key, + int (*cmp)(const void *key, const void *b), AVTreeNode **next) +{ + AVTreeNode *t = *tp; + if (t) { + unsigned int v = cmp(t->elem, key); + void *ret; + if (!v) { + if (*next) + return t->elem; + else if (t->child[0] || t->child[1]) { + int i = !t->child[0]; + void *next_elem[2]; + av_tree_find(t->child[i], key, cmp, next_elem); + key = t->elem = next_elem[i]; + v = -i; + } else { + *next = t; + *tp = NULL; + return NULL; + } + } + ret = av_tree_insert(&t->child[v >> 31], key, cmp, next); + if (!ret) { + int i = (v >> 31) ^ !!*next; + AVTreeNode **child = &t->child[i]; + t->state += 2 * i - 1; + + if (!(t->state & 1)) { + if (t->state) { + /* The following code is equivalent to + * if ((*child)->state * 2 == -t->state) + * rotate(child, i ^ 1); + * rotate(tp, i); + * + * with rotate(): + * static void rotate(AVTreeNode **tp, int i) + * { + * AVTreeNode *t= *tp; + * + * *tp = t->child[i]; + * t->child[i] = t->child[i]->child[i ^ 1]; + * (*tp)->child[i ^ 1] = t; + * i = 4 * t->state + 2 * (*tp)->state + 12; + * t->state = ((0x614586 >> i) & 3) - 1; + * (*tp)->state = ((0x400EEA >> i) & 3) - 1 + + * ((*tp)->state >> 1); + * } + * but such a rotate function is both bigger and slower + */ + if ((*child)->state * 2 == -t->state) { + *tp = (*child)->child[i ^ 1]; + (*child)->child[i ^ 1] = (*tp)->child[i]; + (*tp)->child[i] = *child; + *child = (*tp)->child[i ^ 1]; + (*tp)->child[i ^ 1] = t; + + (*tp)->child[0]->state = -((*tp)->state > 0); + (*tp)->child[1]->state = (*tp)->state < 0; + (*tp)->state = 0; + } else { + *tp = *child; + *child = (*child)->child[i ^ 1]; + (*tp)->child[i ^ 1] = t; + if ((*tp)->state) + t->state = 0; + else + t->state >>= 1; + (*tp)->state = -t->state; + } + } + } + if (!(*tp)->state ^ !!*next) + return key; + } + return ret; + } else { + *tp = *next; + *next = NULL; + if (*tp) { + (*tp)->elem = key; + return NULL; + } else + return key; + } +} + +void av_tree_destroy(AVTreeNode *t) +{ + if (t) { + av_tree_destroy(t->child[0]); + av_tree_destroy(t->child[1]); + av_free(t); + } +} + +void av_tree_enumerate(AVTreeNode *t, void *opaque, + int (*cmp)(void *opaque, void *elem), + int (*enu)(void *opaque, void *elem)) +{ + if (t) { + int v = cmp ? cmp(opaque, t->elem) : 0; + if (v >= 0) + av_tree_enumerate(t->child[0], opaque, cmp, enu); + if (v == 0) + enu(opaque, t->elem); + if (v <= 0) + av_tree_enumerate(t->child[1], opaque, cmp, enu); + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tree.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tree.h new file mode 100644 index 000000000..d5e0aebfb --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tree.h @@ -0,0 +1,138 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * A tree container. + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_TREE_H +#define AVUTIL_TREE_H + +#include "attributes.h" +#include "version.h" + +/** + * @addtogroup lavu_tree AVTree + * @ingroup lavu_data + * + * Low-complexity tree container + * + * Insertion, removal, finding equal, largest which is smaller than and + * smallest which is larger than, all have O(log n) worst-case complexity. + * @{ + */ + + +struct AVTreeNode; +extern const int av_tree_node_size; + +/** + * Allocate an AVTreeNode. + */ +struct AVTreeNode *av_tree_node_alloc(void); + +/** + * Find an element. + * @param root a pointer to the root node of the tree + * @param next If next is not NULL, then next[0] will contain the previous + * element and next[1] the next element. If either does not exist, + * then the corresponding entry in next is unchanged. + * @param cmp compare function used to compare elements in the tree, + * API identical to that of Standard C's qsort + * It is guaranteed that the first and only the first argument to cmp() + * will be the key parameter to av_tree_find(), thus it could if the + * user wants, be a different type (like an opaque context). + * @return An element with cmp(key, elem) == 0 or NULL if no such element + * exists in the tree. + */ +void *av_tree_find(const struct AVTreeNode *root, void *key, + int (*cmp)(const void *key, const void *b), void *next[2]); + +/** + * Insert or remove an element. + * + * If *next is NULL, then the supplied element will be removed if it exists. + * If *next is non-NULL, then the supplied element will be inserted, unless + * it already exists in the tree. + * + * @param rootp A pointer to a pointer to the root node of the tree; note that + * the root node can change during insertions, this is required + * to keep the tree balanced. + * @param key pointer to the element key to insert in the tree + * @param next Used to allocate and free AVTreeNodes. For insertion the user + * must set it to an allocated and zeroed object of at least + * av_tree_node_size bytes size. av_tree_insert() will set it to + * NULL if it has been consumed. + * For deleting elements *next is set to NULL by the user and + * av_tree_insert() will set it to the AVTreeNode which was + * used for the removed element. + * This allows the use of flat arrays, which have + * lower overhead compared to many malloced elements. + * You might want to define a function like: + * @code + * void *tree_insert(struct AVTreeNode **rootp, void *key, + * int (*cmp)(void *key, const void *b), + * AVTreeNode **next) + * { + * if (!*next) + * *next = av_mallocz(av_tree_node_size); + * return av_tree_insert(rootp, key, cmp, next); + * } + * void *tree_remove(struct AVTreeNode **rootp, void *key, + * int (*cmp)(void *key, const void *b, AVTreeNode **next)) + * { + * av_freep(next); + * return av_tree_insert(rootp, key, cmp, next); + * } + * @endcode + * @param cmp compare function used to compare elements in the tree, API identical + * to that of Standard C's qsort + * @return If no insertion happened, the found element; if an insertion or + * removal happened, then either key or NULL will be returned. + * Which one it is depends on the tree state and the implementation. You + * should make no assumptions that it's one or the other in the code. + */ +void *av_tree_insert(struct AVTreeNode **rootp, void *key, + int (*cmp)(const void *key, const void *b), + struct AVTreeNode **next); + +void av_tree_destroy(struct AVTreeNode *t); + +/** + * Apply enu(opaque, &elem) to all the elements in the tree in a given range. + * + * @param cmp a comparison function that returns < 0 for an element below the + * range, > 0 for an element above the range and == 0 for an + * element inside the range + * + * @note The cmp function should use the same ordering used to construct the + * tree. + */ +void av_tree_enumerate(struct AVTreeNode *t, void *opaque, + int (*cmp)(void *opaque, void *elem), + int (*enu)(void *opaque, void *elem)); + +/** + * @} + */ + +#endif /* AVUTIL_TREE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/twofish.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/twofish.c new file mode 100644 index 000000000..d84fa4f36 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/twofish.c @@ -0,0 +1,331 @@ +/* + * An implementation of the TwoFish algorithm + * Copyright (c) 2015 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "twofish.h" +#include "common.h" +#include "intreadwrite.h" +#include "attributes.h" + +#define LR(x, n) ((x) << (n) | (x) >> (32 - (n))) +#define RR(x, n) ((x) >> (n) | (x) << (32 - (n))) + +typedef struct AVTWOFISH { + uint32_t K[40]; + uint32_t S[4]; + int ksize; + uint32_t MDS1[256]; + uint32_t MDS2[256]; + uint32_t MDS3[256]; + uint32_t MDS4[256]; +} AVTWOFISH; + +static const uint8_t MD1[256] = { + 0x00, 0x5b, 0xb6, 0xed, 0x05, 0x5e, 0xb3, 0xe8, 0x0a, 0x51, 0xbc, 0xe7, 0x0f, 0x54, 0xb9, 0xe2, + 0x14, 0x4f, 0xa2, 0xf9, 0x11, 0x4a, 0xa7, 0xfc, 0x1e, 0x45, 0xa8, 0xf3, 0x1b, 0x40, 0xad, 0xf6, + 0x28, 0x73, 0x9e, 0xc5, 0x2d, 0x76, 0x9b, 0xc0, 0x22, 0x79, 0x94, 0xcf, 0x27, 0x7c, 0x91, 0xca, + 0x3c, 0x67, 0x8a, 0xd1, 0x39, 0x62, 0x8f, 0xd4, 0x36, 0x6d, 0x80, 0xdb, 0x33, 0x68, 0x85, 0xde, + 0x50, 0x0b, 0xe6, 0xbd, 0x55, 0x0e, 0xe3, 0xb8, 0x5a, 0x01, 0xec, 0xb7, 0x5f, 0x04, 0xe9, 0xb2, + 0x44, 0x1f, 0xf2, 0xa9, 0x41, 0x1a, 0xf7, 0xac, 0x4e, 0x15, 0xf8, 0xa3, 0x4b, 0x10, 0xfd, 0xa6, + 0x78, 0x23, 0xce, 0x95, 0x7d, 0x26, 0xcb, 0x90, 0x72, 0x29, 0xc4, 0x9f, 0x77, 0x2c, 0xc1, 0x9a, + 0x6c, 0x37, 0xda, 0x81, 0x69, 0x32, 0xdf, 0x84, 0x66, 0x3d, 0xd0, 0x8b, 0x63, 0x38, 0xd5, 0x8e, + 0xa0, 0xfb, 0x16, 0x4d, 0xa5, 0xfe, 0x13, 0x48, 0xaa, 0xf1, 0x1c, 0x47, 0xaf, 0xf4, 0x19, 0x42, + 0xb4, 0xef, 0x02, 0x59, 0xb1, 0xea, 0x07, 0x5c, 0xbe, 0xe5, 0x08, 0x53, 0xbb, 0xe0, 0x0d, 0x56, + 0x88, 0xd3, 0x3e, 0x65, 0x8d, 0xd6, 0x3b, 0x60, 0x82, 0xd9, 0x34, 0x6f, 0x87, 0xdc, 0x31, 0x6a, + 0x9c, 0xc7, 0x2a, 0x71, 0x99, 0xc2, 0x2f, 0x74, 0x96, 0xcd, 0x20, 0x7b, 0x93, 0xc8, 0x25, 0x7e, + 0xf0, 0xab, 0x46, 0x1d, 0xf5, 0xae, 0x43, 0x18, 0xfa, 0xa1, 0x4c, 0x17, 0xff, 0xa4, 0x49, 0x12, + 0xe4, 0xbf, 0x52, 0x09, 0xe1, 0xba, 0x57, 0x0c, 0xee, 0xb5, 0x58, 0x03, 0xeb, 0xb0, 0x5d, 0x06, + 0xd8, 0x83, 0x6e, 0x35, 0xdd, 0x86, 0x6b, 0x30, 0xd2, 0x89, 0x64, 0x3f, 0xd7, 0x8c, 0x61, 0x3a, + 0xcc, 0x97, 0x7a, 0x21, 0xc9, 0x92, 0x7f, 0x24, 0xc6, 0x9d, 0x70, 0x2b, 0xc3, 0x98, 0x75, 0x2e +}; + +static const uint8_t MD2[256] = { + 0x00, 0xef, 0xb7, 0x58, 0x07, 0xe8, 0xb0, 0x5f, 0x0e, 0xe1, 0xb9, 0x56, 0x09, 0xe6, 0xbe, 0x51, + 0x1c, 0xf3, 0xab, 0x44, 0x1b, 0xf4, 0xac, 0x43, 0x12, 0xfd, 0xa5, 0x4a, 0x15, 0xfa, 0xa2, 0x4d, + 0x38, 0xd7, 0x8f, 0x60, 0x3f, 0xd0, 0x88, 0x67, 0x36, 0xd9, 0x81, 0x6e, 0x31, 0xde, 0x86, 0x69, + 0x24, 0xcb, 0x93, 0x7c, 0x23, 0xcc, 0x94, 0x7b, 0x2a, 0xc5, 0x9d, 0x72, 0x2d, 0xc2, 0x9a, 0x75, + 0x70, 0x9f, 0xc7, 0x28, 0x77, 0x98, 0xc0, 0x2f, 0x7e, 0x91, 0xc9, 0x26, 0x79, 0x96, 0xce, 0x21, + 0x6c, 0x83, 0xdb, 0x34, 0x6b, 0x84, 0xdc, 0x33, 0x62, 0x8d, 0xd5, 0x3a, 0x65, 0x8a, 0xd2, 0x3d, + 0x48, 0xa7, 0xff, 0x10, 0x4f, 0xa0, 0xf8, 0x17, 0x46, 0xa9, 0xf1, 0x1e, 0x41, 0xae, 0xf6, 0x19, + 0x54, 0xbb, 0xe3, 0x0c, 0x53, 0xbc, 0xe4, 0x0b, 0x5a, 0xb5, 0xed, 0x02, 0x5d, 0xb2, 0xea, 0x05, + 0xe0, 0x0f, 0x57, 0xb8, 0xe7, 0x08, 0x50, 0xbf, 0xee, 0x01, 0x59, 0xb6, 0xe9, 0x06, 0x5e, 0xb1, + 0xfc, 0x13, 0x4b, 0xa4, 0xfb, 0x14, 0x4c, 0xa3, 0xf2, 0x1d, 0x45, 0xaa, 0xf5, 0x1a, 0x42, 0xad, + 0xd8, 0x37, 0x6f, 0x80, 0xdf, 0x30, 0x68, 0x87, 0xd6, 0x39, 0x61, 0x8e, 0xd1, 0x3e, 0x66, 0x89, + 0xc4, 0x2b, 0x73, 0x9c, 0xc3, 0x2c, 0x74, 0x9b, 0xca, 0x25, 0x7d, 0x92, 0xcd, 0x22, 0x7a, 0x95, + 0x90, 0x7f, 0x27, 0xc8, 0x97, 0x78, 0x20, 0xcf, 0x9e, 0x71, 0x29, 0xc6, 0x99, 0x76, 0x2e, 0xc1, + 0x8c, 0x63, 0x3b, 0xd4, 0x8b, 0x64, 0x3c, 0xd3, 0x82, 0x6d, 0x35, 0xda, 0x85, 0x6a, 0x32, 0xdd, + 0xa8, 0x47, 0x1f, 0xf0, 0xaf, 0x40, 0x18, 0xf7, 0xa6, 0x49, 0x11, 0xfe, 0xa1, 0x4e, 0x16, 0xf9, + 0xb4, 0x5b, 0x03, 0xec, 0xb3, 0x5c, 0x04, 0xeb, 0xba, 0x55, 0x0d, 0xe2, 0xbd, 0x52, 0x0a, 0xe5 +}; + +static const uint8_t q0[256] = { + 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, + 0x0d, 0xc6, 0x35, 0x98, 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, 0x94, 0x48, + 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, + 0x63, 0x01, 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, 0x16, 0x0c, 0xe3, 0x61, + 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1, + 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, + 0xfb, 0xc3, 0x8e, 0xb5, 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, 0x62, 0x71, + 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, + 0xa1, 0x1d, 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, 0x31, 0xc2, 0x27, 0x90, + 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef, + 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, + 0x2a, 0xce, 0xcb, 0x2f, 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, 0xa7, 0x5a, + 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, + 0x57, 0xc7, 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, + 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4, + 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0 +}; + +static const uint8_t q1[256] = { + 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, + 0xd6, 0x32, 0xd8, 0xfd, 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, 0x06, 0x3f, + 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, + 0xa0, 0x84, 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, 0x92, 0x74, 0x36, 0x51, + 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c, + 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, + 0xa6, 0x83, 0x20, 0xff, 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, 0x2b, 0xe2, + 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, + 0x66, 0x94, 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, 0xef, 0xd1, 0x53, 0x3e, + 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9, + 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, + 0x4f, 0xf2, 0x65, 0x8e, 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, 0x05, 0x64, + 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, + 0x29, 0x2e, 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, 0x35, 0x6a, 0xcf, 0xdc, + 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9, + 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91 +}; + +struct AVTWOFISH *av_twofish_alloc(void) +{ + return av_mallocz(sizeof(struct AVTWOFISH)); +} + +const int av_twofish_size = sizeof(AVTWOFISH); + +static uint8_t gfmul(uint8_t a, uint8_t b) +{ + uint8_t r = 0, t; + while (a && b) { + if (a & 1) + r = r ^ b; + t = b & 0x80; + b = b << 1; + if (t) + b = b ^ 0x4d; + a = a >> 1; + } + return r; +} + +static uint32_t tf_RS(uint32_t k0, uint32_t k1) +{ + uint8_t s[4], m[8]; + AV_WL32(m, k0); + AV_WL32(m + 4, k1); + s[0] = gfmul(0x01, m[0]) ^ gfmul(0xa4, m[1]) ^ gfmul(0x55, m[2]) ^ gfmul(0x87, m[3]) ^ gfmul(0x5a, m[4]) ^ gfmul(0x58, m[5]) ^ gfmul(0xdb, m[6]) ^ gfmul(0x9e, m[7]); + s[1] = gfmul(0xa4, m[0]) ^ gfmul(0x56, m[1]) ^ gfmul(0x82, m[2]) ^ gfmul(0xf3, m[3]) ^ gfmul(0x1e, m[4]) ^ gfmul(0xc6, m[5]) ^ gfmul(0x68, m[6]) ^ gfmul(0xe5, m[7]); + s[2] = gfmul(0x02, m[0]) ^ gfmul(0xa1, m[1]) ^ gfmul(0xfc, m[2]) ^ gfmul(0xc1, m[3]) ^ gfmul(0x47, m[4]) ^ gfmul(0xae, m[5]) ^ gfmul(0x3d, m[6]) ^ gfmul(0x19, m[7]); + s[3] = gfmul(0xa4, m[0]) ^ gfmul(0x55, m[1]) ^ gfmul(0x87, m[2]) ^ gfmul(0x5a, m[3]) ^ gfmul(0x58, m[4]) ^ gfmul(0xdb, m[5]) ^ gfmul(0x9e, m[6]) ^ gfmul(0x03, m[7]); + return AV_RL32(s); +} + +static void tf_h0(uint8_t y[4], uint32_t L[4], int k) +{ + uint8_t l[4]; + if (k == 4) { + AV_WL32(l, L[3]); + y[0] = q1[y[0]] ^ l[0]; + y[1] = q0[y[1]] ^ l[1]; + y[2] = q0[y[2]] ^ l[2]; + y[3] = q1[y[3]] ^ l[3]; + } + if (k >= 3) { + AV_WL32(l, L[2]); + y[0] = q1[y[0]] ^ l[0]; + y[1] = q1[y[1]] ^ l[1]; + y[2] = q0[y[2]] ^ l[2]; + y[3] = q0[y[3]] ^ l[3]; + } + AV_WL32(l, L[1]); + y[0] = q1[q0[q0[y[0]] ^ l[0]] ^ (L[0] & 0xff)]; + y[1] = q0[q0[q1[y[1]] ^ l[1]] ^ ((L[0] >> 8) & 0xff)]; + y[2] = q1[q1[q0[y[2]] ^ l[2]] ^ ((L[0] >> 16) & 0xff)]; + y[3] = q0[q1[q1[y[3]] ^ l[3]] ^ (L[0] >> 24)]; +} + +static uint32_t tf_h(uint32_t X, uint32_t L[4], int k) +{ + uint8_t y[4], l[4]; + AV_WL32(y, X); + tf_h0(y, L, k); + + l[0] = y[0] ^ MD2[y[1]] ^ MD1[y[2]] ^ MD1[y[3]]; + l[1] = MD1[y[0]] ^ MD2[y[1]] ^ MD2[y[2]] ^ y[3]; + l[2] = MD2[y[0]] ^ MD1[y[1]] ^ y[2] ^ MD2[y[3]]; + l[3] = MD2[y[0]] ^ y[1] ^ MD2[y[2]] ^ MD1[y[3]]; + + return AV_RL32(l); +} + +static uint32_t MDS_mul(AVTWOFISH *cs, uint32_t X) +{ + return cs->MDS1[(X) & 0xff] ^ cs->MDS2[((X) >> 8) & 0xff] ^ cs->MDS3[((X) >> 16) & 0xff] ^ cs->MDS4[(X) >> 24]; +} + +static void precomputeMDS(AVTWOFISH *cs) +{ + uint8_t y[4]; + int i; + for (i = 0; i < 256; i++) { + y[0] = y[1] = y[2] = y[3] = i; + tf_h0(y, cs->S, cs->ksize); + cs->MDS1[i] = ((uint32_t)y[0]) ^ ((uint32_t)MD1[y[0]] << 8) ^ ((uint32_t)MD2[y[0]] << 16) ^ ((uint32_t)MD2[y[0]] << 24); + cs->MDS2[i] = ((uint32_t)MD2[y[1]]) ^ ((uint32_t)MD2[y[1]] << 8) ^ ((uint32_t)MD1[y[1]] << 16) ^ ((uint32_t)y[1] << 24); + cs->MDS3[i] = ((uint32_t)MD1[y[2]]) ^ ((uint32_t)MD2[y[2]] << 8) ^ ((uint32_t)y[2] << 16) ^ ((uint32_t)MD2[y[2]] << 24); + cs->MDS4[i] = ((uint32_t)MD1[y[3]]) ^ ((uint32_t)y[3] << 8) ^ ((uint32_t)MD2[y[3]] << 16) ^ ((uint32_t)MD1[y[3]] << 24); + } +} + +static void twofish_encrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src) +{ + uint32_t P[4], t0, t1; + int i; + P[0] = AV_RL32(src) ^ cs->K[0]; + P[1] = AV_RL32(src + 4) ^ cs->K[1]; + P[2] = AV_RL32(src + 8) ^ cs->K[2]; + P[3] = AV_RL32(src + 12) ^ cs->K[3]; + for (i = 0; i < 16; i += 2) { + t0 = MDS_mul(cs, P[0]); + t1 = MDS_mul(cs, LR(P[1], 8)); + P[2] = RR(P[2] ^ (t0 + t1 + cs->K[2 * i + 8]), 1); + P[3] = LR(P[3], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 9]); + t0 = MDS_mul(cs, P[2]); + t1 = MDS_mul(cs, LR(P[3], 8)); + P[0] = RR(P[0] ^ (t0 + t1 + cs->K[2 * i + 10]), 1); + P[1] = LR(P[1], 1) ^ (t0 + 2 * t1 + cs->K[2 * i + 11]); + } + P[2] ^= cs->K[4]; + P[3] ^= cs->K[5]; + P[0] ^= cs->K[6]; + P[1] ^= cs->K[7]; + AV_WL32(dst, P[2]); + AV_WL32(dst + 4, P[3]); + AV_WL32(dst + 8, P[0]); + AV_WL32(dst + 12, P[1]); +} + +static void twofish_decrypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv) +{ + uint32_t P[4], t0, t1; + int i; + P[2] = AV_RL32(src) ^ cs->K[4]; + P[3] = AV_RL32(src + 4) ^ cs->K[5]; + P[0] = AV_RL32(src + 8) ^ cs->K[6]; + P[1] = AV_RL32(src + 12) ^ cs->K[7]; + for (i = 15; i >= 0; i -= 2) { + t0 = MDS_mul(cs, P[2]); + t1 = MDS_mul(cs, LR(P[3], 8)); + P[0] = LR(P[0], 1) ^ (t0 + t1 + cs->K[2 * i + 8]); + P[1] = RR(P[1] ^ (t0 + 2 * t1 + cs->K[2 * i + 9]), 1); + t0 = MDS_mul(cs, P[0]); + t1 = MDS_mul(cs, LR(P[1], 8)); + P[2] = LR(P[2], 1) ^ (t0 + t1 + cs->K[2 * i + 6]); + P[3] = RR(P[3] ^ (t0 + 2 * t1 + cs->K[2 * i + 7]), 1); + } + P[0] ^= cs->K[0]; + P[1] ^= cs->K[1]; + P[2] ^= cs->K[2]; + P[3] ^= cs->K[3]; + if (iv) { + P[0] ^= AV_RL32(iv); + P[1] ^= AV_RL32(iv + 4); + P[2] ^= AV_RL32(iv + 8); + P[3] ^= AV_RL32(iv + 12); + memcpy(iv, src, 16); + } + AV_WL32(dst, P[2]); + AV_WL32(dst + 4, P[3]); + AV_WL32(dst + 8, P[0]); + AV_WL32(dst + 12, P[1]); +} + +av_cold int av_twofish_init(AVTWOFISH *cs, const uint8_t *key, int key_bits) +{ + int i; + uint8_t keypad[32]; + uint32_t Key[8], Me[4], Mo[4], A, B; + const uint32_t rho = 0x01010101; + if (key_bits < 0) + return AVERROR(EINVAL); + if (key_bits <= 128) { + cs->ksize = 2; + } else if (key_bits <= 192) { + cs->ksize = 3; + } else { + cs->ksize = 4; + } + memset(keypad, 0, sizeof(keypad)); + if (key_bits <= 256) { + memcpy(keypad, key, key_bits >> 3); + } else { + memcpy(keypad, key, 32); + } + for (i = 0; i < 2 * cs->ksize ; i++) + Key[i] = AV_RL32(keypad + 4 * i); + for (i = 0; i < cs->ksize; i++) { + Me[i] = Key[2 * i]; + Mo[i] = Key[2 * i + 1]; + cs->S[cs->ksize - i - 1] = tf_RS(Me[i], Mo[i]); + } + precomputeMDS(cs); + for (i = 0; i < 20; i++) { + A = tf_h((2 * i) * rho, Me, cs->ksize); + B = tf_h((2 * i + 1) * rho, Mo, cs->ksize); + B = LR(B, 8); + cs->K[2 * i] = A + B; + cs->K[2 * i + 1] = LR((A + (2 * B)), 9); + } + if (cs->ksize << 6 != key_bits) { + return 1; + } else { + return 0; + } +} + +void av_twofish_crypt(AVTWOFISH *cs, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) +{ + int i; + while (count--) { + if (decrypt) { + twofish_decrypt(cs, dst, src, iv); + } else { + if (iv) { + for (i = 0; i < 16; i++) + dst[i] = src[i] ^ iv[i]; + twofish_encrypt(cs, dst, dst); + memcpy(iv, dst, 16); + } else { + twofish_encrypt(cs, dst, src); + } + } + src = src + 16; + dst = dst + 16; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/twofish.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/twofish.h new file mode 100644 index 000000000..813cfecdf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/twofish.h @@ -0,0 +1,70 @@ +/* + * An implementation of the TwoFish algorithm + * Copyright (c) 2015 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TWOFISH_H +#define AVUTIL_TWOFISH_H + +#include + + +/** + * @file + * @brief Public header for libavutil TWOFISH algorithm + * @defgroup lavu_twofish TWOFISH + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_twofish_size; + +struct AVTWOFISH; + +/** + * Allocate an AVTWOFISH context + * To free the struct: av_free(ptr) + */ +struct AVTWOFISH *av_twofish_alloc(void); + +/** + * Initialize an AVTWOFISH context. + * + * @param ctx an AVTWOFISH context + * @param key a key of size ranging from 1 to 32 bytes used for encryption/decryption + * @param key_bits number of keybits: 128, 192, 256 If less than the required, padded with zeroes to nearest valid value; return value is 0 if key_bits is 128/192/256, -1 if less than 0, 1 otherwise + */ +int av_twofish_init(struct AVTWOFISH *ctx, const uint8_t *key, int key_bits); + +/** + * Encrypt or decrypt a buffer using a previously initialized context + * + * @param ctx an AVTWOFISH context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 16 byte blocks + * @paran iv initialization vector for CBC mode, NULL for ECB mode + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_twofish_crypt(struct AVTWOFISH *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t* iv, int decrypt); + +/** + * @} + */ +#endif /* AVUTIL_TWOFISH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.c new file mode 100644 index 000000000..93f6e489d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.c @@ -0,0 +1,803 @@ +/* + * Copyright (c) 2019 Lynne + * Power of two FFT: + * Copyright (c) 2008 Loren Merritt + * Copyright (c) 2002 Fabrice Bellard + * Partly based on libdjbfft by D. J. Bernstein + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "tx.h" +#include "thread.h" +#include "mem.h" +#include "avassert.h" + +typedef float FFTSample; +typedef AVComplexFloat FFTComplex; + +struct AVTXContext { + int n; /* Nptwo part */ + int m; /* Ptwo part */ + + FFTComplex *exptab; /* MDCT exptab */ + FFTComplex *tmp; /* Temporary buffer needed for all compound transforms */ + int *pfatab; /* Input/Output mapping for compound transforms */ + int *revtab; /* Input mapping for power of two transforms */ +}; + +#define FFT_NAME(x) x + +#define COSTABLE(size) \ + static DECLARE_ALIGNED(32, FFTSample, FFT_NAME(ff_cos_##size))[size/2] + +static FFTSample * const FFT_NAME(ff_cos_tabs)[18]; + +COSTABLE(16); +COSTABLE(32); +COSTABLE(64); +COSTABLE(128); +COSTABLE(256); +COSTABLE(512); +COSTABLE(1024); +COSTABLE(2048); +COSTABLE(4096); +COSTABLE(8192); +COSTABLE(16384); +COSTABLE(32768); +COSTABLE(65536); +COSTABLE(131072); + +static av_cold void init_ff_cos_tabs(int index) +{ + int m = 1 << index; + double freq = 2*M_PI/m; + FFTSample *tab = FFT_NAME(ff_cos_tabs)[index]; + for(int i = 0; i <= m/4; i++) + tab[i] = cos(i*freq); + for(int i = 1; i < m/4; i++) + tab[m/2 - i] = tab[i]; +} + +typedef struct CosTabsInitOnce { + void (*func)(void); + AVOnce control; +} CosTabsInitOnce; + +#define INIT_FF_COS_TABS_FUNC(index, size) \ +static av_cold void init_ff_cos_tabs_ ## size (void) \ +{ \ + init_ff_cos_tabs(index); \ +} + +INIT_FF_COS_TABS_FUNC(4, 16) +INIT_FF_COS_TABS_FUNC(5, 32) +INIT_FF_COS_TABS_FUNC(6, 64) +INIT_FF_COS_TABS_FUNC(7, 128) +INIT_FF_COS_TABS_FUNC(8, 256) +INIT_FF_COS_TABS_FUNC(9, 512) +INIT_FF_COS_TABS_FUNC(10, 1024) +INIT_FF_COS_TABS_FUNC(11, 2048) +INIT_FF_COS_TABS_FUNC(12, 4096) +INIT_FF_COS_TABS_FUNC(13, 8192) +INIT_FF_COS_TABS_FUNC(14, 16384) +INIT_FF_COS_TABS_FUNC(15, 32768) +INIT_FF_COS_TABS_FUNC(16, 65536) +INIT_FF_COS_TABS_FUNC(17, 131072) + +static CosTabsInitOnce cos_tabs_init_once[] = { + { NULL }, + { NULL }, + { NULL }, + { NULL }, + { init_ff_cos_tabs_16, AV_ONCE_INIT }, + { init_ff_cos_tabs_32, AV_ONCE_INIT }, + { init_ff_cos_tabs_64, AV_ONCE_INIT }, + { init_ff_cos_tabs_128, AV_ONCE_INIT }, + { init_ff_cos_tabs_256, AV_ONCE_INIT }, + { init_ff_cos_tabs_512, AV_ONCE_INIT }, + { init_ff_cos_tabs_1024, AV_ONCE_INIT }, + { init_ff_cos_tabs_2048, AV_ONCE_INIT }, + { init_ff_cos_tabs_4096, AV_ONCE_INIT }, + { init_ff_cos_tabs_8192, AV_ONCE_INIT }, + { init_ff_cos_tabs_16384, AV_ONCE_INIT }, + { init_ff_cos_tabs_32768, AV_ONCE_INIT }, + { init_ff_cos_tabs_65536, AV_ONCE_INIT }, + { init_ff_cos_tabs_131072, AV_ONCE_INIT }, +}; + +static FFTSample * const FFT_NAME(ff_cos_tabs)[] = { + NULL, NULL, NULL, NULL, + FFT_NAME(ff_cos_16), + FFT_NAME(ff_cos_32), + FFT_NAME(ff_cos_64), + FFT_NAME(ff_cos_128), + FFT_NAME(ff_cos_256), + FFT_NAME(ff_cos_512), + FFT_NAME(ff_cos_1024), + FFT_NAME(ff_cos_2048), + FFT_NAME(ff_cos_4096), + FFT_NAME(ff_cos_8192), + FFT_NAME(ff_cos_16384), + FFT_NAME(ff_cos_32768), + FFT_NAME(ff_cos_65536), + FFT_NAME(ff_cos_131072), +}; + +static av_cold void ff_init_ff_cos_tabs(int index) +{ + ff_thread_once(&cos_tabs_init_once[index].control, + cos_tabs_init_once[index].func); +} + +static AVOnce tabs_53_once = AV_ONCE_INIT; +static DECLARE_ALIGNED(32, FFTComplex, FFT_NAME(ff_53_tabs))[4]; + +static av_cold void ff_init_53_tabs(void) +{ + ff_53_tabs[0] = (FFTComplex){ cos(2 * M_PI / 12), cos(2 * M_PI / 12) }; + ff_53_tabs[1] = (FFTComplex){ 0.5, 0.5 }; + ff_53_tabs[2] = (FFTComplex){ cos(2 * M_PI / 5), sin(2 * M_PI / 5) }; + ff_53_tabs[3] = (FFTComplex){ cos(2 * M_PI / 10), sin(2 * M_PI / 10) }; +} + +#define BF(x, y, a, b) do { \ + x = (a) - (b); \ + y = (a) + (b); \ + } while (0) + +#define CMUL(dre, dim, are, aim, bre, bim) do { \ + (dre) = (are) * (bre) - (aim) * (bim); \ + (dim) = (are) * (bim) + (aim) * (bre); \ + } while (0) + +#define CMUL3(c, a, b) CMUL((c).re, (c).im, (a).re, (a).im, (b).re, (b).im) + +static av_always_inline void fft3(FFTComplex *out, FFTComplex *in, + ptrdiff_t stride) +{ + FFTComplex tmp[2]; + + tmp[0].re = in[1].im - in[2].im; + tmp[0].im = in[1].re - in[2].re; + tmp[1].re = in[1].re + in[2].re; + tmp[1].im = in[1].im + in[2].im; + + out[0*stride].re = in[0].re + tmp[1].re; + out[0*stride].im = in[0].im + tmp[1].im; + + tmp[0].re *= ff_53_tabs[0].re; + tmp[0].im *= ff_53_tabs[0].im; + tmp[1].re *= ff_53_tabs[1].re; + tmp[1].im *= ff_53_tabs[1].re; + + out[1*stride].re = in[0].re - tmp[1].re + tmp[0].re; + out[1*stride].im = in[0].im - tmp[1].im - tmp[0].im; + out[2*stride].re = in[0].re - tmp[1].re - tmp[0].re; + out[2*stride].im = in[0].im - tmp[1].im + tmp[0].im; +} + +#define DECL_FFT5(NAME, D0, D1, D2, D3, D4) \ +static av_always_inline void NAME(FFTComplex *out, FFTComplex *in, \ + ptrdiff_t stride) \ +{ \ + FFTComplex z0[4], t[6]; \ + \ + t[0].re = in[1].re + in[4].re; \ + t[0].im = in[1].im + in[4].im; \ + t[1].im = in[1].re - in[4].re; \ + t[1].re = in[1].im - in[4].im; \ + t[2].re = in[2].re + in[3].re; \ + t[2].im = in[2].im + in[3].im; \ + t[3].im = in[2].re - in[3].re; \ + t[3].re = in[2].im - in[3].im; \ + \ + out[D0*stride].re = in[0].re + in[1].re + in[2].re + \ + in[3].re + in[4].re; \ + out[D0*stride].im = in[0].im + in[1].im + in[2].im + \ + in[3].im + in[4].im; \ + \ + t[4].re = ff_53_tabs[2].re * t[2].re - ff_53_tabs[3].re * t[0].re; \ + t[4].im = ff_53_tabs[2].re * t[2].im - ff_53_tabs[3].re * t[0].im; \ + t[0].re = ff_53_tabs[2].re * t[0].re - ff_53_tabs[3].re * t[2].re; \ + t[0].im = ff_53_tabs[2].re * t[0].im - ff_53_tabs[3].re * t[2].im; \ + t[5].re = ff_53_tabs[2].im * t[3].re - ff_53_tabs[3].im * t[1].re; \ + t[5].im = ff_53_tabs[2].im * t[3].im - ff_53_tabs[3].im * t[1].im; \ + t[1].re = ff_53_tabs[2].im * t[1].re + ff_53_tabs[3].im * t[3].re; \ + t[1].im = ff_53_tabs[2].im * t[1].im + ff_53_tabs[3].im * t[3].im; \ + \ + z0[0].re = t[0].re - t[1].re; \ + z0[0].im = t[0].im - t[1].im; \ + z0[1].re = t[4].re + t[5].re; \ + z0[1].im = t[4].im + t[5].im; \ + \ + z0[2].re = t[4].re - t[5].re; \ + z0[2].im = t[4].im - t[5].im; \ + z0[3].re = t[0].re + t[1].re; \ + z0[3].im = t[0].im + t[1].im; \ + \ + out[D1*stride].re = in[0].re + z0[3].re; \ + out[D1*stride].im = in[0].im + z0[0].im; \ + out[D2*stride].re = in[0].re + z0[2].re; \ + out[D2*stride].im = in[0].im + z0[1].im; \ + out[D3*stride].re = in[0].re + z0[1].re; \ + out[D3*stride].im = in[0].im + z0[2].im; \ + out[D4*stride].re = in[0].re + z0[0].re; \ + out[D4*stride].im = in[0].im + z0[3].im; \ +} + +DECL_FFT5(fft5, 0, 1, 2, 3, 4) +DECL_FFT5(fft5_m1, 0, 6, 12, 3, 9) +DECL_FFT5(fft5_m2, 10, 1, 7, 13, 4) +DECL_FFT5(fft5_m3, 5, 11, 2, 8, 14) + +static av_always_inline void fft15(FFTComplex *out, FFTComplex *in, + ptrdiff_t stride) +{ + FFTComplex tmp[15]; + + for (int i = 0; i < 5; i++) + fft3(tmp + i, in + i*3, 5); + + fft5_m1(out, tmp + 0, stride); + fft5_m2(out, tmp + 5, stride); + fft5_m3(out, tmp + 10, stride); +} + +#define BUTTERFLIES(a0,a1,a2,a3) {\ + BF(t3, t5, t5, t1);\ + BF(a2.re, a0.re, a0.re, t5);\ + BF(a3.im, a1.im, a1.im, t3);\ + BF(t4, t6, t2, t6);\ + BF(a3.re, a1.re, a1.re, t4);\ + BF(a2.im, a0.im, a0.im, t6);\ +} + +// force loading all the inputs before storing any. +// this is slightly slower for small data, but avoids store->load aliasing +// for addresses separated by large powers of 2. +#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\ + FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\ + BF(t3, t5, t5, t1);\ + BF(a2.re, a0.re, r0, t5);\ + BF(a3.im, a1.im, i1, t3);\ + BF(t4, t6, t2, t6);\ + BF(a3.re, a1.re, r1, t4);\ + BF(a2.im, a0.im, i0, t6);\ +} + +#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\ + CMUL(t1, t2, a2.re, a2.im, wre, -wim);\ + CMUL(t5, t6, a3.re, a3.im, wre, wim);\ + BUTTERFLIES(a0,a1,a2,a3)\ +} + +#define TRANSFORM_ZERO(a0,a1,a2,a3) {\ + t1 = a2.re;\ + t2 = a2.im;\ + t5 = a3.re;\ + t6 = a3.im;\ + BUTTERFLIES(a0,a1,a2,a3)\ +} + +/* z[0...8n-1], w[1...2n-1] */ +#define PASS(name)\ +static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\ +{\ + FFTSample t1, t2, t3, t4, t5, t6;\ + int o1 = 2*n;\ + int o2 = 4*n;\ + int o3 = 6*n;\ + const FFTSample *wim = wre+o1;\ + n--;\ +\ + TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\ + TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ + do {\ + z += 2;\ + wre += 2;\ + wim -= 2;\ + TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\ + TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ + } while(--n);\ +} + +PASS(pass) +#undef BUTTERFLIES +#define BUTTERFLIES BUTTERFLIES_BIG +PASS(pass_big) + +#define DECL_FFT(n,n2,n4)\ +static void fft##n(FFTComplex *z)\ +{\ + fft##n2(z);\ + fft##n4(z+n4*2);\ + fft##n4(z+n4*3);\ + pass(z,FFT_NAME(ff_cos_##n),n4/2);\ +} + +static void fft4(FFTComplex *z) +{ + FFTSample t1, t2, t3, t4, t5, t6, t7, t8; + + BF(t3, t1, z[0].re, z[1].re); + BF(t8, t6, z[3].re, z[2].re); + BF(z[2].re, z[0].re, t1, t6); + BF(t4, t2, z[0].im, z[1].im); + BF(t7, t5, z[2].im, z[3].im); + BF(z[3].im, z[1].im, t4, t8); + BF(z[3].re, z[1].re, t3, t7); + BF(z[2].im, z[0].im, t2, t5); +} + +static void fft8(FFTComplex *z) +{ + FFTSample t1, t2, t3, t4, t5, t6; + + fft4(z); + + BF(t1, z[5].re, z[4].re, -z[5].re); + BF(t2, z[5].im, z[4].im, -z[5].im); + BF(t5, z[7].re, z[6].re, -z[7].re); + BF(t6, z[7].im, z[6].im, -z[7].im); + + BUTTERFLIES(z[0],z[2],z[4],z[6]); + TRANSFORM(z[1],z[3],z[5],z[7],M_SQRT1_2,M_SQRT1_2); +} + +static void fft16(FFTComplex *z) +{ + FFTSample t1, t2, t3, t4, t5, t6; + FFTSample cos_16_1 = FFT_NAME(ff_cos_16)[1]; + FFTSample cos_16_3 = FFT_NAME(ff_cos_16)[3]; + + fft8(z); + fft4(z+8); + fft4(z+12); + + TRANSFORM_ZERO(z[0],z[4],z[8],z[12]); + TRANSFORM(z[2],z[6],z[10],z[14],M_SQRT1_2,M_SQRT1_2); + TRANSFORM(z[1],z[5],z[9],z[13],cos_16_1,cos_16_3); + TRANSFORM(z[3],z[7],z[11],z[15],cos_16_3,cos_16_1); +} + +DECL_FFT(32,16,8) +DECL_FFT(64,32,16) +DECL_FFT(128,64,32) +DECL_FFT(256,128,64) +DECL_FFT(512,256,128) +#define pass pass_big +DECL_FFT(1024,512,256) +DECL_FFT(2048,1024,512) +DECL_FFT(4096,2048,1024) +DECL_FFT(8192,4096,2048) +DECL_FFT(16384,8192,4096) +DECL_FFT(32768,16384,8192) +DECL_FFT(65536,32768,16384) +DECL_FFT(131072,65536,32768) + +static void (* const fft_dispatch[])(FFTComplex*) = { + fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, + fft2048, fft4096, fft8192, fft16384, fft32768, fft65536, fft131072 +}; + +#define DECL_COMP_FFT(N) \ +static void compound_fft_##N##xM(AVTXContext *s, void *_out, \ + void *_in, ptrdiff_t stride) \ +{ \ + const int m = s->m, *in_map = s->pfatab, *out_map = in_map + N*m; \ + FFTComplex *in = _in; \ + FFTComplex *out = _out; \ + FFTComplex fft##N##in[N]; \ + void (*fftp)(FFTComplex *z) = fft_dispatch[av_log2(m) - 2]; \ + \ + for (int i = 0; i < m; i++) { \ + for (int j = 0; j < N; j++) \ + fft##N##in[j] = in[in_map[i*N + j]]; \ + fft##N(s->tmp + s->revtab[i], fft##N##in, m); \ + } \ + \ + for (int i = 0; i < N; i++) \ + fftp(s->tmp + m*i); \ + \ + for (int i = 0; i < N*m; i++) \ + out[i] = s->tmp[out_map[i]]; \ +} + +DECL_COMP_FFT(3) +DECL_COMP_FFT(5) +DECL_COMP_FFT(15) + +static void monolithic_fft(AVTXContext *s, void *_out, void *_in, + ptrdiff_t stride) +{ + FFTComplex *in = _in; + FFTComplex *out = _out; + int m = s->m, mb = av_log2(m) - 2; + for (int i = 0; i < m; i++) + out[s->revtab[i]] = in[i]; + fft_dispatch[mb](out); +} + +#define DECL_COMP_IMDCT(N) \ +static void compound_imdct_##N##xM(AVTXContext *s, void *_dst, void *_src, \ + ptrdiff_t stride) \ +{ \ + FFTComplex fft##N##in[N]; \ + FFTComplex *z = _dst, *exp = s->exptab; \ + const int m = s->m, len8 = N*m >> 1; \ + const int *in_map = s->pfatab, *out_map = in_map + N*m; \ + const float *src = _src, *in1, *in2; \ + void (*fftp)(FFTComplex *) = fft_dispatch[av_log2(m) - 2]; \ + \ + stride /= sizeof(*src); /* To convert it from bytes */ \ + in1 = src; \ + in2 = src + ((N*m*2) - 1) * stride; \ + \ + for (int i = 0; i < m; i++) { \ + for (int j = 0; j < N; j++) { \ + const int k = in_map[i*N + j]; \ + FFTComplex tmp = { in2[-k*stride], in1[k*stride] }; \ + CMUL3(fft##N##in[j], tmp, exp[k >> 1]); \ + } \ + fft##N(s->tmp + s->revtab[i], fft##N##in, m); \ + } \ + \ + for (int i = 0; i < N; i++) \ + fftp(s->tmp + m*i); \ + \ + for (int i = 0; i < len8; i++) { \ + const int i0 = len8 + i, i1 = len8 - i - 1; \ + const int s0 = out_map[i0], s1 = out_map[i1]; \ + FFTComplex src1 = { s->tmp[s1].im, s->tmp[s1].re }; \ + FFTComplex src0 = { s->tmp[s0].im, s->tmp[s0].re }; \ + \ + CMUL(z[i1].re, z[i0].im, src1.re, src1.im, exp[i1].im, exp[i1].re); \ + CMUL(z[i0].re, z[i1].im, src0.re, src0.im, exp[i0].im, exp[i0].re); \ + } \ +} + +DECL_COMP_IMDCT(3) +DECL_COMP_IMDCT(5) +DECL_COMP_IMDCT(15) + +#define DECL_COMP_MDCT(N) \ +static void compound_mdct_##N##xM(AVTXContext *s, void *_dst, void *_src, \ + ptrdiff_t stride) \ +{ \ + float *src = _src, *dst = _dst; \ + FFTComplex *exp = s->exptab, tmp, fft##N##in[N]; \ + const int m = s->m, len4 = N*m, len3 = len4 * 3, len8 = len4 >> 1; \ + const int *in_map = s->pfatab, *out_map = in_map + N*m; \ + void (*fftp)(FFTComplex *) = fft_dispatch[av_log2(m) - 2]; \ + \ + stride /= sizeof(*dst); \ + \ + for (int i = 0; i < m; i++) { /* Folding and pre-reindexing */ \ + for (int j = 0; j < N; j++) { \ + const int k = in_map[i*N + j]; \ + if (k < len4) { \ + tmp.re = -src[ len4 + k] + src[1*len4 - 1 - k]; \ + tmp.im = -src[ len3 + k] - src[1*len3 - 1 - k]; \ + } else { \ + tmp.re = -src[ len4 + k] - src[5*len4 - 1 - k]; \ + tmp.im = src[-len4 + k] - src[1*len3 - 1 - k]; \ + } \ + CMUL(fft##N##in[j].im, fft##N##in[j].re, tmp.re, tmp.im, \ + exp[k >> 1].re, exp[k >> 1].im); \ + } \ + fft##N(s->tmp + s->revtab[i], fft##N##in, m); \ + } \ + \ + for (int i = 0; i < N; i++) \ + fftp(s->tmp + m*i); \ + \ + for (int i = 0; i < len8; i++) { \ + const int i0 = len8 + i, i1 = len8 - i - 1; \ + const int s0 = out_map[i0], s1 = out_map[i1]; \ + FFTComplex src1 = { s->tmp[s1].re, s->tmp[s1].im }; \ + FFTComplex src0 = { s->tmp[s0].re, s->tmp[s0].im }; \ + \ + CMUL(dst[2*i1*stride + stride], dst[2*i0*stride], src0.re, src0.im, \ + exp[i0].im, exp[i0].re); \ + CMUL(dst[2*i0*stride + stride], dst[2*i1*stride], src1.re, src1.im, \ + exp[i1].im, exp[i1].re); \ + } \ +} + +DECL_COMP_MDCT(3) +DECL_COMP_MDCT(5) +DECL_COMP_MDCT(15) + +static void monolithic_imdct(AVTXContext *s, void *_dst, void *_src, + ptrdiff_t stride) +{ + FFTComplex *z = _dst, *exp = s->exptab; + const int m = s->m, len8 = m >> 1; + const float *src = _src, *in1, *in2; + void (*fftp)(FFTComplex *) = fft_dispatch[av_log2(m) - 2]; + + stride /= sizeof(*src); + in1 = src; + in2 = src + ((m*2) - 1) * stride; + + for (int i = 0; i < m; i++) { + FFTComplex tmp = { in2[-2*i*stride], in1[2*i*stride] }; + CMUL3(z[s->revtab[i]], tmp, exp[i]); + } + + fftp(z); + + for (int i = 0; i < len8; i++) { + const int i0 = len8 + i, i1 = len8 - i - 1; + FFTComplex src1 = { z[i1].im, z[i1].re }; + FFTComplex src0 = { z[i0].im, z[i0].re }; + + CMUL(z[i1].re, z[i0].im, src1.re, src1.im, exp[i1].im, exp[i1].re); + CMUL(z[i0].re, z[i1].im, src0.re, src0.im, exp[i0].im, exp[i0].re); + } +} + +static void monolithic_mdct(AVTXContext *s, void *_dst, void *_src, + ptrdiff_t stride) +{ + float *src = _src, *dst = _dst; + FFTComplex *exp = s->exptab, tmp, *z = _dst; + const int m = s->m, len4 = m, len3 = len4 * 3, len8 = len4 >> 1; + void (*fftp)(FFTComplex *) = fft_dispatch[av_log2(m) - 2]; + + stride /= sizeof(*dst); + + for (int i = 0; i < m; i++) { /* Folding and pre-reindexing */ + const int k = 2*i; + if (k < len4) { + tmp.re = -src[ len4 + k] + src[1*len4 - 1 - k]; + tmp.im = -src[ len3 + k] - src[1*len3 - 1 - k]; + } else { + tmp.re = -src[ len4 + k] - src[5*len4 - 1 - k]; + tmp.im = src[-len4 + k] - src[1*len3 - 1 - k]; + } + CMUL(z[s->revtab[i]].im, z[s->revtab[i]].re, tmp.re, tmp.im, + exp[i].re, exp[i].im); + } + + fftp(z); + + for (int i = 0; i < len8; i++) { + const int i0 = len8 + i, i1 = len8 - i - 1; + FFTComplex src1 = { z[i1].re, z[i1].im }; + FFTComplex src0 = { z[i0].re, z[i0].im }; + + CMUL(dst[2*i1*stride + stride], dst[2*i0*stride], src0.re, src0.im, + exp[i0].im, exp[i0].re); + CMUL(dst[2*i0*stride + stride], dst[2*i1*stride], src1.re, src1.im, + exp[i1].im, exp[i1].re); + } +} + +/* Calculates the modular multiplicative inverse, not fast, replace */ +static int mulinv(int n, int m) +{ + n = n % m; + for (int x = 1; x < m; x++) + if (((n * x) % m) == 1) + return x; + av_assert0(0); /* Never reached */ +} + +/* Guaranteed to work for any n, m where gcd(n, m) == 1 */ +static int gen_compound_mapping(AVTXContext *s, int n, int m, int inv, + enum AVTXType type) +{ + int *in_map, *out_map; + const int len = n*m; + const int m_inv = mulinv(m, n); + const int n_inv = mulinv(n, m); + const int mdct = type == AV_TX_FLOAT_MDCT; + + if (!(s->pfatab = av_malloc(2*len*sizeof(*s->pfatab)))) + return AVERROR(ENOMEM); + + in_map = s->pfatab; + out_map = s->pfatab + n*m; + + /* Ruritanian map for input, CRT map for output, can be swapped */ + for (int j = 0; j < m; j++) { + for (int i = 0; i < n; i++) { + /* Shifted by 1 to simplify forward MDCTs */ + in_map[j*n + i] = ((i*m + j*n) % len) << mdct; + out_map[(i*m*m_inv + j*n*n_inv) % len] = i*m + j; + } + } + + /* Change transform direction by reversing all ACs */ + if (inv) { + for (int i = 0; i < m; i++) { + int *in = &in_map[i*n + 1]; /* Skip the DC */ + for (int j = 0; j < ((n - 1) >> 1); j++) + FFSWAP(int, in[j], in[n - j - 2]); + } + } + + /* Our 15-point transform is also a compound one, so embed its input map */ + if (n == 15) { + for (int k = 0; k < m; k++) { + int tmp[15]; + memcpy(tmp, &in_map[k*15], 15*sizeof(*tmp)); + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 3; j++) + in_map[k*15 + i*3 + j] = tmp[(i*3 + j*5) % 15]; + } + } + } + + return 0; +} + +static int split_radix_permutation(int i, int n, int inverse) +{ + int m; + if (n <= 2) + return i & 1; + m = n >> 1; + if (!(i & m)) + return split_radix_permutation(i, m, inverse)*2; + m >>= 1; + if (inverse == !(i & m)) + return split_radix_permutation(i, m, inverse)*4 + 1; + else + return split_radix_permutation(i, m, inverse)*4 - 1; +} + +static int get_ptwo_revtab(AVTXContext *s, int m, int inv) +{ + if (!(s->revtab = av_malloc(m*sizeof(*s->revtab)))) + return AVERROR(ENOMEM); + + /* Default */ + for (int i = 0; i < m; i++) { + int k = -split_radix_permutation(i, m, inv) & (m - 1); + s->revtab[k] = i; + } + + return 0; +} + +static int gen_mdct_exptab(AVTXContext *s, int len4, double scale) +{ + const double theta = (scale < 0 ? len4 : 0) + 1.0/8.0; + + if (!(s->exptab = av_malloc_array(len4, sizeof(*s->exptab)))) + return AVERROR(ENOMEM); + + scale = sqrt(fabs(scale)); + for (int i = 0; i < len4; i++) { + const double alpha = M_PI_2 * (i + theta) / len4; + s->exptab[i].re = cos(alpha) * scale; + s->exptab[i].im = sin(alpha) * scale; + } + + return 0; +} + +av_cold void av_tx_uninit(AVTXContext **ctx) +{ + if (!(*ctx)) + return; + + av_free((*ctx)->pfatab); + av_free((*ctx)->exptab); + av_free((*ctx)->revtab); + av_free((*ctx)->tmp); + + av_freep(ctx); +} + +static int init_mdct_fft(AVTXContext *s, av_tx_fn *tx, enum AVTXType type, + int inv, int len, const void *scale, uint64_t flags) +{ + int err, n = 1, m = 1, max_ptwo = 1 << (FF_ARRAY_ELEMS(fft_dispatch) + 1); + + if (type == AV_TX_FLOAT_MDCT) + len >>= 1; + +#define CHECK_FACTOR(DST, FACTOR, SRC) \ + if (DST == 1 && !(SRC % FACTOR)) { \ + DST = FACTOR; \ + SRC /= FACTOR; \ + } + CHECK_FACTOR(n, 15, len) + CHECK_FACTOR(n, 5, len) + CHECK_FACTOR(n, 3, len) +#undef CHECK_NPTWO_FACTOR + + /* len must be a power of two now */ + if (!(len & (len - 1)) && len >= 4 && len <= max_ptwo) { + m = len; + len = 1; + } + + /* Filter out direct 3, 5 and 15 transforms, too niche */ + if (len > 1 || m == 1) { + av_log(NULL, AV_LOG_ERROR, "Unsupported transform size: n = %i, " + "m = %i, residual = %i!\n", n, m, len); + return AVERROR(EINVAL); + } else if (n > 1 && m > 1) { /* 2D transform case */ + if ((err = gen_compound_mapping(s, n, m, inv, type))) + return err; + if (!(s->tmp = av_malloc(n*m*sizeof(*s->tmp)))) + return AVERROR(ENOMEM); + *tx = n == 3 ? compound_fft_3xM : + n == 5 ? compound_fft_5xM : + compound_fft_15xM; + if (type == AV_TX_FLOAT_MDCT) + *tx = n == 3 ? inv ? compound_imdct_3xM : compound_mdct_3xM : + n == 5 ? inv ? compound_imdct_5xM : compound_mdct_5xM : + inv ? compound_imdct_15xM : compound_mdct_15xM; + } else { /* Direct transform case */ + *tx = monolithic_fft; + if (type == AV_TX_FLOAT_MDCT) + *tx = inv ? monolithic_imdct : monolithic_mdct; + } + + if (n != 1) + ff_thread_once(&tabs_53_once, ff_init_53_tabs); + if (m != 1) { + get_ptwo_revtab(s, m, inv); + for (int i = 4; i <= av_log2(m); i++) + ff_init_ff_cos_tabs(i); + } + + if (type == AV_TX_FLOAT_MDCT) + if ((err = gen_mdct_exptab(s, n*m, *((float *)scale)))) + return err; + + s->n = n; + s->m = m; + + return 0; +} + +av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, + int inv, int len, const void *scale, uint64_t flags) +{ + int err; + AVTXContext *s = av_mallocz(sizeof(*s)); + if (!s) + return AVERROR(ENOMEM); + + switch (type) { + case AV_TX_FLOAT_FFT: + case AV_TX_FLOAT_MDCT: + if ((err = init_mdct_fft(s, tx, type, inv, len, scale, flags))) + goto fail; + break; + default: + err = AVERROR(EINVAL); + goto fail; + } + + *ctx = s; + + return 0; + +fail: + av_tx_uninit(&s); + *tx = NULL; + return err; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.h new file mode 100644 index 000000000..b1f2d9635 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/tx.h @@ -0,0 +1,81 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TX_H +#define AVUTIL_TX_H + +#include +#include + +typedef struct AVTXContext AVTXContext; + +typedef struct AVComplexFloat { + float re, im; +} AVComplexFloat; + +enum AVTXType { + /** + * Standard complex to complex FFT with sample data type AVComplexFloat. + * Scaling currently unsupported + */ + AV_TX_FLOAT_FFT = 0, + /** + * Standard MDCT with sample data type of float and a scale type of + * float. Length is the frame size, not the window size (which is 2x frame) + */ + AV_TX_FLOAT_MDCT = 1, +}; + +/** + * Function pointer to a function to perform the transform. + * + * @note Using a different context than the one allocated during av_tx_init() + * is not allowed. + * + * @param s the transform context + * @param out the output array + * @param in the input array + * @param stride the input or output stride (depending on transform direction) + * in bytes, currently implemented for all MDCT transforms + */ +typedef void (*av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride); + +/** + * Initialize a transform context with the given configuration + * Currently power of two lengths from 4 to 131072 are supported, along with + * any length decomposable to a power of two and either 3, 5 or 15. + * + * @param ctx the context to allocate, will be NULL on error + * @param tx pointer to the transform function pointer to set + * @param type type the type of transform + * @param inv whether to do an inverse or a forward transform + * @param len the size of the transform in samples + * @param scale pointer to the value to scale the output if supported by type + * @param flags currently unused + * + * @return 0 on success, negative error code on failure + */ +int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, + int inv, int len, const void *scale, uint64_t flags); + +/** + * Frees a context and sets ctx to NULL, does nothing when ctx == NULL + */ +void av_tx_uninit(AVTXContext **ctx); + +#endif /* AVUTIL_TX_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/utils.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/utils.c new file mode 100644 index 000000000..230081ea4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/utils.c @@ -0,0 +1,160 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "avutil.h" +#include "avassert.h" +#include "samplefmt.h" +#include "internal.h" + +/** + * @file + * various utility functions + */ + +#include "libavutil/ffversion.h" +const char av_util_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + +const char *av_version_info(void) +{ + return FFMPEG_VERSION; +} + +unsigned avutil_version(void) +{ + static int checks_done; + if (checks_done) + return LIBAVUTIL_VERSION_INT; + + av_assert0(AV_SAMPLE_FMT_DBLP == 9); + av_assert0(AVMEDIA_TYPE_ATTACHMENT == 4); + av_assert0(AV_PICTURE_TYPE_BI == 7); + av_assert0(LIBAVUTIL_VERSION_MICRO >= 100); + av_assert0(HAVE_MMX2 == HAVE_MMXEXT); + + av_assert0(((size_t)-1) > 0); // C guarantees this but if false on a platform we care about revert at least b284e1ffe343d6697fb950d1ee517bafda8a9844 + + if (av_sat_dadd32(1, 2) != 5) { + av_log(NULL, AV_LOG_FATAL, "Libavutil has been built with a broken binutils, please upgrade binutils and rebuild\n"); + abort(); + } + + if (llrint(1LL<<60) != 1LL<<60) { + av_log(NULL, AV_LOG_ERROR, "Libavutil has been linked to a broken llrint()\n"); + } + + checks_done = 1; + return LIBAVUTIL_VERSION_INT; +} + +const char *avutil_configuration(void) +{ + return FFMPEG_CONFIGURATION; +} + +const char *avutil_license(void) +{ +#define LICENSE_PREFIX "libavutil license: " + return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; +} + +const char *av_get_media_type_string(enum AVMediaType media_type) +{ + switch (media_type) { + case AVMEDIA_TYPE_VIDEO: return "video"; + case AVMEDIA_TYPE_AUDIO: return "audio"; + case AVMEDIA_TYPE_DATA: return "data"; + case AVMEDIA_TYPE_SUBTITLE: return "subtitle"; + case AVMEDIA_TYPE_ATTACHMENT: return "attachment"; + default: return NULL; + } +} + +char av_get_picture_type_char(enum AVPictureType pict_type) +{ + switch (pict_type) { + case AV_PICTURE_TYPE_I: return 'I'; + case AV_PICTURE_TYPE_P: return 'P'; + case AV_PICTURE_TYPE_B: return 'B'; + case AV_PICTURE_TYPE_S: return 'S'; + case AV_PICTURE_TYPE_SI: return 'i'; + case AV_PICTURE_TYPE_SP: return 'p'; + case AV_PICTURE_TYPE_BI: return 'b'; + default: return '?'; + } +} + +unsigned av_int_list_length_for_size(unsigned elsize, + const void *list, uint64_t term) +{ + unsigned i; + + if (!list) + return 0; +#define LIST_LENGTH(type) \ + { type t = term, *l = (type *)list; for (i = 0; l[i] != t; i++); } + switch (elsize) { + case 1: LIST_LENGTH(uint8_t); break; + case 2: LIST_LENGTH(uint16_t); break; + case 4: LIST_LENGTH(uint32_t); break; + case 8: LIST_LENGTH(uint64_t); break; + default: av_assert0(!"valid element size"); + } + return i; +} + +char *av_fourcc_make_string(char *buf, uint32_t fourcc) +{ + int i; + char *orig_buf = buf; + size_t buf_size = AV_FOURCC_MAX_STRING_SIZE; + + for (i = 0; i < 4; i++) { + const int c = fourcc & 0xff; + const int print_chr = (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c && strchr(". -_", c)); + const int len = snprintf(buf, buf_size, print_chr ? "%c" : "[%d]", c); + if (len < 0) + break; + buf += len; + buf_size = buf_size > len ? buf_size - len : 0; + fourcc >>= 8; + } + + return orig_buf; +} + +AVRational av_get_time_base_q(void) +{ + return (AVRational){1, AV_TIME_BASE}; +} + +void av_assert0_fpu(void) { +#if HAVE_MMX_INLINE + uint16_t state[14]; + __asm__ volatile ( + "fstenv %0 \n\t" + : "+m" (state) + : + : "memory" + ); + av_assert0((state[4] & 3) == 3); +#endif +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/version.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/version.h new file mode 100644 index 000000000..24ca8ab7d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/version.h @@ -0,0 +1,139 @@ +/* + * copyright (c) 2003 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu + * Libavutil version macros + */ + +#ifndef AVUTIL_VERSION_H +#define AVUTIL_VERSION_H + +#include "macros.h" + +/** + * @addtogroup version_utils + * + * Useful to check and match library version in order to maintain + * backward compatibility. + * + * The FFmpeg libraries follow a versioning sheme very similar to + * Semantic Versioning (http://semver.org/) + * The difference is that the component called PATCH is called MICRO in FFmpeg + * and its value is reset to 100 instead of 0 to keep it above or equal to 100. + * Also we do not increase MICRO for every bugfix or change in git master. + * + * Prior to FFmpeg 3.2 point releases did not change any lib version number to + * avoid aliassing different git master checkouts. + * Starting with FFmpeg 3.2, the released library versions will occupy + * a separate MAJOR.MINOR that is not used on the master development branch. + * That is if we branch a release of master 55.10.123 we will bump to 55.11.100 + * for the release and master will continue at 55.12.100 after it. Each new + * point release will then bump the MICRO improving the usefulness of the lib + * versions. + * + * @{ + */ + +#define AV_VERSION_INT(a, b, c) ((a)<<16 | (b)<<8 | (c)) +#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c +#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) + +/** + * Extract version components from the full ::AV_VERSION_INT int as returned + * by functions like ::avformat_version() and ::avcodec_version() + */ +#define AV_VERSION_MAJOR(a) ((a) >> 16) +#define AV_VERSION_MINOR(a) (((a) & 0x00FF00) >> 8) +#define AV_VERSION_MICRO(a) ((a) & 0xFF) + +/** + * @} + */ + +/** + * @defgroup lavu_ver Version and Build diagnostics + * + * Macros and function useful to check at compiletime and at runtime + * which version of libavutil is in use. + * + * @{ + */ + +#define LIBAVUTIL_VERSION_MAJOR 56 +#define LIBAVUTIL_VERSION_MINOR 31 +#define LIBAVUTIL_VERSION_MICRO 100 + +#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT + +#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) + +/** + * @defgroup lavu_depr_guards Deprecation Guards + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + * + * @note, when bumping the major version it is recommended to manually + * disable each FF_API_* in its own commit instead of disabling them all + * at once through the bump. This improves the git bisect-ability of the change. + * + * @{ + */ + +#ifndef FF_API_VAAPI +#define FF_API_VAAPI (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_FRAME_QP +#define FF_API_FRAME_QP (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_PLUS1_MINUS1 +#define FF_API_PLUS1_MINUS1 (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_ERROR_FRAME +#define FF_API_ERROR_FRAME (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_PKT_PTS +#define FF_API_PKT_PTS (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_CRYPTO_SIZE_T +#define FF_API_CRYPTO_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_FRAME_GET_SET +#define FF_API_FRAME_GET_SET (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_PSEUDOPAL +#define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) +#endif + + +/** + * @} + * @} + */ + +#endif /* AVUTIL_VERSION_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/asm.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/asm.h new file mode 100644 index 000000000..9bff42d62 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/asm.h @@ -0,0 +1,154 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_ASM_H +#define AVUTIL_X86_ASM_H + +#include +#include "config.h" + +typedef struct xmm_reg { uint64_t a, b; } xmm_reg; +typedef struct ymm_reg { uint64_t a, b, c, d; } ymm_reg; + +#if ARCH_X86_64 +# define FF_OPSIZE "q" +# define FF_REG_a "rax" +# define FF_REG_b "rbx" +# define FF_REG_c "rcx" +# define FF_REG_d "rdx" +# define FF_REG_D "rdi" +# define FF_REG_S "rsi" +# define FF_PTR_SIZE "8" +typedef int64_t x86_reg; + +/* FF_REG_SP is defined in Solaris sys headers, so use FF_REG_sp */ +# define FF_REG_sp "rsp" +# define FF_REG_BP "rbp" +# define FF_REGBP rbp +# define FF_REGa rax +# define FF_REGb rbx +# define FF_REGc rcx +# define FF_REGd rdx +# define FF_REGSP rsp + +#elif ARCH_X86_32 + +# define FF_OPSIZE "l" +# define FF_REG_a "eax" +# define FF_REG_b "ebx" +# define FF_REG_c "ecx" +# define FF_REG_d "edx" +# define FF_REG_D "edi" +# define FF_REG_S "esi" +# define FF_PTR_SIZE "4" +typedef int32_t x86_reg; + +# define FF_REG_sp "esp" +# define FF_REG_BP "ebp" +# define FF_REGBP ebp +# define FF_REGa eax +# define FF_REGb ebx +# define FF_REGc ecx +# define FF_REGd edx +# define FF_REGSP esp +#else +typedef int x86_reg; +#endif + +#define HAVE_7REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE && HAVE_EBP_AVAILABLE)) +#define HAVE_6REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE || HAVE_EBP_AVAILABLE)) + +#if ARCH_X86_64 && defined(PIC) +# define BROKEN_RELOCATIONS 1 +#endif + +/* + * If gcc is not set to support sse (-msse) it will not accept xmm registers + * in the clobber list for inline asm. XMM_CLOBBERS takes a list of xmm + * registers to be marked as clobbered and evaluates to nothing if they are + * not supported, or to the list itself if they are supported. Since a clobber + * list may not be empty, XMM_CLOBBERS_ONLY should be used if the xmm + * registers are the only in the clobber list. + * For example a list with "eax" and "xmm0" as clobbers should become: + * : XMM_CLOBBERS("xmm0",) "eax" + * and a list with only "xmm0" should become: + * XMM_CLOBBERS_ONLY("xmm0") + */ +#if HAVE_XMM_CLOBBERS +# define XMM_CLOBBERS(...) __VA_ARGS__ +# define XMM_CLOBBERS_ONLY(...) : __VA_ARGS__ +#else +# define XMM_CLOBBERS(...) +# define XMM_CLOBBERS_ONLY(...) +#endif + +/* Use to export labels from asm. */ +#define LABEL_MANGLE(a) EXTERN_PREFIX #a + +// Use rip-relative addressing if compiling PIC code on x86-64. +#if ARCH_X86_64 && defined(PIC) +# define LOCAL_MANGLE(a) #a "(%%rip)" +#else +# define LOCAL_MANGLE(a) #a +#endif + +#if HAVE_INLINE_ASM_DIRECT_SYMBOL_REFS +# define MANGLE(a) EXTERN_PREFIX LOCAL_MANGLE(a) +# define NAMED_CONSTRAINTS_ADD(...) +# define NAMED_CONSTRAINTS(...) +# define NAMED_CONSTRAINTS_ARRAY_ADD(...) +# define NAMED_CONSTRAINTS_ARRAY(...) +#else + /* When direct symbol references are used in code passed to a compiler that does not support them + * then these references need to be converted to named asm constraints instead. + * Instead of returning a direct symbol MANGLE now returns a named constraint for that specific symbol. + * In order for this to work there must also be a corresponding entry in the asm-interface. To add this + * entry use the macro NAMED_CONSTRAINTS() and pass in a list of each symbol reference used in the + * corresponding block of code. (e.g. NAMED_CONSTRAINTS(var1,var2,var3) where var1 is the first symbol etc. ). + * If there are already existing constraints then use NAMED_CONSTRAINTS_ADD to add to the existing constraint list. + */ +# define MANGLE(a) "%["#a"]" + // Intel/MSVC does not correctly expand va-args so we need a rather ugly hack in order to get it to work +# define FE_0(P,X) P(X) +# define FE_1(P,X,X1) P(X), FE_0(P,X1) +# define FE_2(P,X,X1,X2) P(X), FE_1(P,X1,X2) +# define FE_3(P,X,X1,X2,X3) P(X), FE_2(P,X1,X2,X3) +# define FE_4(P,X,X1,X2,X3,X4) P(X), FE_3(P,X1,X2,X3,X4) +# define FE_5(P,X,X1,X2,X3,X4,X5) P(X), FE_4(P,X1,X2,X3,X4,X5) +# define FE_6(P,X,X1,X2,X3,X4,X5,X6) P(X), FE_5(P,X1,X2,X3,X4,X5,X6) +# define FE_7(P,X,X1,X2,X3,X4,X5,X6,X7) P(X), FE_6(P,X1,X2,X3,X4,X5,X6,X7) +# define FE_8(P,X,X1,X2,X3,X4,X5,X6,X7,X8) P(X), FE_7(P,X1,X2,X3,X4,X5,X6,X7,X8) +# define FE_9(P,X,X1,X2,X3,X4,X5,X6,X7,X8,X9) P(X), FE_8(P,X1,X2,X3,X4,X5,X6,X7,X8,X9) +# define GET_FE_IMPL(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,NAME,...) NAME +# define GET_FE(A) GET_FE_IMPL A +# define GET_FE_GLUE(x, y) x y +# define FOR_EACH_VA(P,...) GET_FE_GLUE(GET_FE((__VA_ARGS__,FE_9,FE_8,FE_7,FE_6,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)), (P,__VA_ARGS__)) +# define NAME_CONSTRAINT(x) [x] "m"(x) + // Parameters are a list of each symbol reference required +# define NAMED_CONSTRAINTS_ADD(...) , FOR_EACH_VA(NAME_CONSTRAINT,__VA_ARGS__) + // Same but without comma for when there are no previously defined constraints +# define NAMED_CONSTRAINTS(...) FOR_EACH_VA(NAME_CONSTRAINT,__VA_ARGS__) + // Same as above NAMED_CONSTRAINTS except used for passing arrays/pointers instead of normal variables +# define NAME_CONSTRAINT_ARRAY(x) [x] "m"(*x) +# define NAMED_CONSTRAINTS_ARRAY_ADD(...) , FOR_EACH_VA(NAME_CONSTRAINT_ARRAY,__VA_ARGS__) +# define NAMED_CONSTRAINTS_ARRAY(...) FOR_EACH_VA(NAME_CONSTRAINT_ARRAY,__VA_ARGS__) +#endif + +#endif /* AVUTIL_X86_ASM_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/bswap.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/bswap.h new file mode 100644 index 000000000..ffa59e4c8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/bswap.h @@ -0,0 +1,87 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * byte swapping routines + */ + +#ifndef AVUTIL_X86_BSWAP_H +#define AVUTIL_X86_BSWAP_H + +#include +#if defined(_MSC_VER) +#include +#endif +#include "config.h" +#include "libavutil/attributes.h" + +#if defined(_MSC_VER) + +#define av_bswap16 av_bswap16 +static av_always_inline av_const uint16_t av_bswap16(uint16_t x) +{ + return _rotr16(x, 8); +} + +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + return _byteswap_ulong(x); +} + +#if ARCH_X86_64 +#define av_bswap64 av_bswap64 +static inline uint64_t av_const av_bswap64(uint64_t x) +{ + return _byteswap_uint64(x); +} +#endif + + +#elif HAVE_INLINE_ASM + +#if AV_GCC_VERSION_AT_MOST(4,0) +#define av_bswap16 av_bswap16 +static av_always_inline av_const unsigned av_bswap16(unsigned x) +{ + __asm__("rorw $8, %w0" : "+r"(x)); + return x; +} +#endif /* AV_GCC_VERSION_AT_MOST(4,0) */ + +#if AV_GCC_VERSION_AT_MOST(4,4) || defined(__INTEL_COMPILER) +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + __asm__("bswap %0" : "+r" (x)); + return x; +} + +#if ARCH_X86_64 +#define av_bswap64 av_bswap64 +static inline uint64_t av_const av_bswap64(uint64_t x) +{ + __asm__("bswap %0": "=r" (x) : "0" (x)); + return x; +} +#endif +#endif /* AV_GCC_VERSION_AT_MOST(4,4) */ + +#endif /* HAVE_INLINE_ASM */ +#endif /* AVUTIL_X86_BSWAP_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpu.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpu.c new file mode 100644 index 000000000..bcd41a50a --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpu.c @@ -0,0 +1,272 @@ +/* + * CPU detection code, extracted from mmx.h + * (c)1997-99 by H. Dietz and R. Fisher + * Converted to C and improved by Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#if HAVE_X86ASM + +#define cpuid(index, eax, ebx, ecx, edx) \ + ff_cpu_cpuid(index, &eax, &ebx, &ecx, &edx) + +#define xgetbv(index, eax, edx) \ + ff_cpu_xgetbv(index, &eax, &edx) + +#elif HAVE_INLINE_ASM + +/* ebx saving is necessary for PIC. gcc seems unable to see it alone */ +#define cpuid(index, eax, ebx, ecx, edx) \ + __asm__ volatile ( \ + "mov %%"FF_REG_b", %%"FF_REG_S" \n\t" \ + "cpuid \n\t" \ + "xchg %%"FF_REG_b", %%"FF_REG_S \ + : "=a" (eax), "=S" (ebx), "=c" (ecx), "=d" (edx) \ + : "0" (index), "2"(0)) + +#define xgetbv(index, eax, edx) \ + __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (index)) + +#define get_eflags(x) \ + __asm__ volatile ("pushfl \n" \ + "pop %0 \n" \ + : "=r"(x)) + +#define set_eflags(x) \ + __asm__ volatile ("push %0 \n" \ + "popfl \n" \ + :: "r"(x)) + +#endif /* HAVE_INLINE_ASM */ + +#if ARCH_X86_64 + +#define cpuid_test() 1 + +#elif HAVE_X86ASM + +#define cpuid_test ff_cpu_cpuid_test + +#elif HAVE_INLINE_ASM + +static int cpuid_test(void) +{ + x86_reg a, c; + + /* Check if CPUID is supported by attempting to toggle the ID bit in + * the EFLAGS register. */ + get_eflags(a); + set_eflags(a ^ 0x200000); + get_eflags(c); + + return a != c; +} +#endif + +/* Function to test if multimedia instructions are supported... */ +int ff_get_cpu_flags_x86(void) +{ + int rval = 0; + +#ifdef cpuid + + int eax, ebx, ecx, edx; + int max_std_level, max_ext_level, std_caps = 0, ext_caps = 0; + int family = 0, model = 0; + union { int i[3]; char c[12]; } vendor; + int xcr0_lo = 0, xcr0_hi = 0; + + if (!cpuid_test()) + return 0; /* CPUID not supported */ + + cpuid(0, max_std_level, vendor.i[0], vendor.i[2], vendor.i[1]); + + if (max_std_level >= 1) { + cpuid(1, eax, ebx, ecx, std_caps); + family = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); + model = ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0); + if (std_caps & (1 << 15)) + rval |= AV_CPU_FLAG_CMOV; + if (std_caps & (1 << 23)) + rval |= AV_CPU_FLAG_MMX; + if (std_caps & (1 << 25)) + rval |= AV_CPU_FLAG_MMXEXT; +#if HAVE_SSE + if (std_caps & (1 << 25)) + rval |= AV_CPU_FLAG_SSE; + if (std_caps & (1 << 26)) + rval |= AV_CPU_FLAG_SSE2; + if (ecx & 1) + rval |= AV_CPU_FLAG_SSE3; + if (ecx & 0x00000200 ) + rval |= AV_CPU_FLAG_SSSE3; + if (ecx & 0x00080000 ) + rval |= AV_CPU_FLAG_SSE4; + if (ecx & 0x00100000 ) + rval |= AV_CPU_FLAG_SSE42; + if (ecx & 0x02000000 ) + rval |= AV_CPU_FLAG_AESNI; +#if HAVE_AVX + /* Check OXSAVE and AVX bits */ + if ((ecx & 0x18000000) == 0x18000000) { + /* Check for OS support */ + xgetbv(0, xcr0_lo, xcr0_hi); + if ((xcr0_lo & 0x6) == 0x6) { + rval |= AV_CPU_FLAG_AVX; + if (ecx & 0x00001000) + rval |= AV_CPU_FLAG_FMA3; + } + } +#endif /* HAVE_AVX */ +#endif /* HAVE_SSE */ + } + if (max_std_level >= 7) { + cpuid(7, eax, ebx, ecx, edx); +#if HAVE_AVX2 + if ((rval & AV_CPU_FLAG_AVX) && (ebx & 0x00000020)) + rval |= AV_CPU_FLAG_AVX2; +#if HAVE_AVX512 /* F, CD, BW, DQ, VL */ + if ((xcr0_lo & 0xe0) == 0xe0) { /* OPMASK/ZMM state */ + if ((rval & AV_CPU_FLAG_AVX2) && (ebx & 0xd0030000) == 0xd0030000) + rval |= AV_CPU_FLAG_AVX512; + + } +#endif /* HAVE_AVX512 */ +#endif /* HAVE_AVX2 */ + /* BMI1/2 don't need OS support */ + if (ebx & 0x00000008) { + rval |= AV_CPU_FLAG_BMI1; + if (ebx & 0x00000100) + rval |= AV_CPU_FLAG_BMI2; + } + } + + cpuid(0x80000000, max_ext_level, ebx, ecx, edx); + + if (max_ext_level >= 0x80000001) { + cpuid(0x80000001, eax, ebx, ecx, ext_caps); + if (ext_caps & (1U << 31)) + rval |= AV_CPU_FLAG_3DNOW; + if (ext_caps & (1 << 30)) + rval |= AV_CPU_FLAG_3DNOWEXT; + if (ext_caps & (1 << 23)) + rval |= AV_CPU_FLAG_MMX; + if (ext_caps & (1 << 22)) + rval |= AV_CPU_FLAG_MMXEXT; + + if (!strncmp(vendor.c, "AuthenticAMD", 12)) { + /* Allow for selectively disabling SSE2 functions on AMD processors + with SSE2 support but not SSE4a. This includes Athlon64, some + Opteron, and some Sempron processors. MMX, SSE, or 3DNow! are faster + than SSE2 often enough to utilize this special-case flag. + AV_CPU_FLAG_SSE2 and AV_CPU_FLAG_SSE2SLOW are both set in this case + so that SSE2 is used unless explicitly disabled by checking + AV_CPU_FLAG_SSE2SLOW. */ + if (rval & AV_CPU_FLAG_SSE2 && !(ecx & 0x00000040)) + rval |= AV_CPU_FLAG_SSE2SLOW; + + /* Similar to the above but for AVX functions on AMD processors. + This is necessary only for functions using YMM registers on Bulldozer + and Jaguar based CPUs as they lack 256-bit execution units. SSE/AVX + functions using XMM registers are always faster on them. + AV_CPU_FLAG_AVX and AV_CPU_FLAG_AVXSLOW are both set so that AVX is + used unless explicitly disabled by checking AV_CPU_FLAG_AVXSLOW. */ + if ((family == 0x15 || family == 0x16) && (rval & AV_CPU_FLAG_AVX)) + rval |= AV_CPU_FLAG_AVXSLOW; + } + + /* XOP and FMA4 use the AVX instruction coding scheme, so they can't be + * used unless the OS has AVX support. */ + if (rval & AV_CPU_FLAG_AVX) { + if (ecx & 0x00000800) + rval |= AV_CPU_FLAG_XOP; + if (ecx & 0x00010000) + rval |= AV_CPU_FLAG_FMA4; + } + } + + if (!strncmp(vendor.c, "GenuineIntel", 12)) { + if (family == 6 && (model == 9 || model == 13 || model == 14)) { + /* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and + * 6/14 (core1 "yonah") theoretically support sse2, but it's + * usually slower than mmx, so let's just pretend they don't. + * AV_CPU_FLAG_SSE2 is disabled and AV_CPU_FLAG_SSE2SLOW is + * enabled so that SSE2 is not used unless explicitly enabled + * by checking AV_CPU_FLAG_SSE2SLOW. The same situation + * applies for AV_CPU_FLAG_SSE3 and AV_CPU_FLAG_SSE3SLOW. */ + if (rval & AV_CPU_FLAG_SSE2) + rval ^= AV_CPU_FLAG_SSE2SLOW | AV_CPU_FLAG_SSE2; + if (rval & AV_CPU_FLAG_SSE3) + rval ^= AV_CPU_FLAG_SSE3SLOW | AV_CPU_FLAG_SSE3; + } + /* The Atom processor has SSSE3 support, which is useful in many cases, + * but sometimes the SSSE3 version is slower than the SSE2 equivalent + * on the Atom, but is generally faster on other processors supporting + * SSSE3. This flag allows for selectively disabling certain SSSE3 + * functions on the Atom. */ + if (family == 6 && model == 28) + rval |= AV_CPU_FLAG_ATOM; + + /* Conroe has a slow shuffle unit. Check the model number to ensure not + * to include crippled low-end Penryns and Nehalems that lack SSE4. */ + if ((rval & AV_CPU_FLAG_SSSE3) && !(rval & AV_CPU_FLAG_SSE4) && + family == 6 && model < 23) + rval |= AV_CPU_FLAG_SSSE3SLOW; + } + +#endif /* cpuid */ + + return rval; +} + +size_t ff_get_cpu_max_align_x86(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_AVX512) + return 64; + if (flags & (AV_CPU_FLAG_AVX2 | + AV_CPU_FLAG_AVX | + AV_CPU_FLAG_XOP | + AV_CPU_FLAG_FMA4 | + AV_CPU_FLAG_FMA3 | + AV_CPU_FLAG_AVXSLOW)) + return 32; + if (flags & (AV_CPU_FLAG_AESNI | + AV_CPU_FLAG_SSE42 | + AV_CPU_FLAG_SSE4 | + AV_CPU_FLAG_SSSE3 | + AV_CPU_FLAG_SSE3 | + AV_CPU_FLAG_SSE2 | + AV_CPU_FLAG_SSE | + AV_CPU_FLAG_ATOM | + AV_CPU_FLAG_SSSE3SLOW | + AV_CPU_FLAG_SSE3SLOW | + AV_CPU_FLAG_SSE2SLOW)) + return 16; + + return 8; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpu.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpu.h new file mode 100644 index 000000000..937c697fa --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpu.h @@ -0,0 +1,113 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_CPU_H +#define AVUTIL_X86_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define AV_CPU_FLAG_AMD3DNOW AV_CPU_FLAG_3DNOW +#define AV_CPU_FLAG_AMD3DNOWEXT AV_CPU_FLAG_3DNOWEXT + +#define X86_AMD3DNOW(flags) CPUEXT(flags, AMD3DNOW) +#define X86_AMD3DNOWEXT(flags) CPUEXT(flags, AMD3DNOWEXT) +#define X86_MMX(flags) CPUEXT(flags, MMX) +#define X86_MMXEXT(flags) CPUEXT(flags, MMXEXT) +#define X86_SSE(flags) CPUEXT(flags, SSE) +#define X86_SSE2(flags) CPUEXT(flags, SSE2) +#define X86_SSE2_FAST(flags) CPUEXT_FAST(flags, SSE2) +#define X86_SSE2_SLOW(flags) CPUEXT_SLOW(flags, SSE2) +#define X86_SSE3(flags) CPUEXT(flags, SSE3) +#define X86_SSE3_FAST(flags) CPUEXT_FAST(flags, SSE3) +#define X86_SSE3_SLOW(flags) CPUEXT_SLOW(flags, SSE3) +#define X86_SSSE3(flags) CPUEXT(flags, SSSE3) +#define X86_SSSE3_FAST(flags) CPUEXT_FAST(flags, SSSE3) +#define X86_SSSE3_SLOW(flags) CPUEXT_SLOW(flags, SSSE3) +#define X86_SSE4(flags) CPUEXT(flags, SSE4) +#define X86_SSE42(flags) CPUEXT(flags, SSE42) +#define X86_AVX(flags) CPUEXT(flags, AVX) +#define X86_AVX_FAST(flags) CPUEXT_FAST(flags, AVX) +#define X86_AVX_SLOW(flags) CPUEXT_SLOW(flags, AVX) +#define X86_XOP(flags) CPUEXT(flags, XOP) +#define X86_FMA3(flags) CPUEXT(flags, FMA3) +#define X86_FMA4(flags) CPUEXT(flags, FMA4) +#define X86_AVX2(flags) CPUEXT(flags, AVX2) +#define X86_AESNI(flags) CPUEXT(flags, AESNI) +#define X86_AVX512(flags) CPUEXT(flags, AVX512) + +#define EXTERNAL_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOW) +#define EXTERNAL_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOWEXT) +#define EXTERNAL_MMX(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, MMX) +#define EXTERNAL_MMXEXT(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, MMXEXT) +#define EXTERNAL_SSE(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE) +#define EXTERNAL_SSE2(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE2) +#define EXTERNAL_SSE2_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, SSE2) +#define EXTERNAL_SSE2_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, SSE2) +#define EXTERNAL_SSE3(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE3) +#define EXTERNAL_SSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, SSE3) +#define EXTERNAL_SSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, SSE3) +#define EXTERNAL_SSSE3(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSSE3) +#define EXTERNAL_SSSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, SSSE3) +#define EXTERNAL_SSSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, SSSE3) +#define EXTERNAL_SSE4(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE4) +#define EXTERNAL_SSE42(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE42) +#define EXTERNAL_AVX(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX) +#define EXTERNAL_AVX_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, AVX) +#define EXTERNAL_AVX_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, AVX) +#define EXTERNAL_XOP(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, XOP) +#define EXTERNAL_FMA3(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, FMA3) +#define EXTERNAL_FMA3_FAST(flags) CPUEXT_SUFFIX_FAST2(flags, _EXTERNAL, FMA3, AVX) +#define EXTERNAL_FMA3_SLOW(flags) CPUEXT_SUFFIX_SLOW2(flags, _EXTERNAL, FMA3, AVX) +#define EXTERNAL_FMA4(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, FMA4) +#define EXTERNAL_AVX2(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX2) +#define EXTERNAL_AVX2_FAST(flags) CPUEXT_SUFFIX_FAST2(flags, _EXTERNAL, AVX2, AVX) +#define EXTERNAL_AVX2_SLOW(flags) CPUEXT_SUFFIX_SLOW2(flags, _EXTERNAL, AVX2, AVX) +#define EXTERNAL_AESNI(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AESNI) +#define EXTERNAL_AVX512(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX512) + +#define INLINE_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOW) +#define INLINE_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOWEXT) +#define INLINE_MMX(flags) CPUEXT_SUFFIX(flags, _INLINE, MMX) +#define INLINE_MMXEXT(flags) CPUEXT_SUFFIX(flags, _INLINE, MMXEXT) +#define INLINE_SSE(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE) +#define INLINE_SSE2(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE2) +#define INLINE_SSE2_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, SSE2) +#define INLINE_SSE2_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, SSE2) +#define INLINE_SSE3(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE3) +#define INLINE_SSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, SSE3) +#define INLINE_SSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, SSE3) +#define INLINE_SSSE3(flags) CPUEXT_SUFFIX(flags, _INLINE, SSSE3) +#define INLINE_SSSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, SSSE3) +#define INLINE_SSSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, SSSE3) +#define INLINE_SSE4(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE4) +#define INLINE_SSE42(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE42) +#define INLINE_AVX(flags) CPUEXT_SUFFIX(flags, _INLINE, AVX) +#define INLINE_AVX_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, AVX) +#define INLINE_AVX_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, AVX) +#define INLINE_XOP(flags) CPUEXT_SUFFIX(flags, _INLINE, XOP) +#define INLINE_FMA3(flags) CPUEXT_SUFFIX(flags, _INLINE, FMA3) +#define INLINE_FMA4(flags) CPUEXT_SUFFIX(flags, _INLINE, FMA4) +#define INLINE_AVX2(flags) CPUEXT_SUFFIX(flags, _INLINE, AVX2) +#define INLINE_AESNI(flags) CPUEXT_SUFFIX(flags, _INLINE, AESNI) + +void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx); +void ff_cpu_xgetbv(int op, int *eax, int *edx); +int ff_cpu_cpuid_test(void); + +#endif /* AVUTIL_X86_CPU_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/emms.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/emms.h new file mode 100644 index 000000000..c21e34b45 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/emms.h @@ -0,0 +1,55 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_EMMS_H +#define AVUTIL_X86_EMMS_H + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" + +void avpriv_emms_asm(void); + +#if HAVE_MMX_INLINE +# define emms_c emms_c +/** + * Empty mmx state. + * this must be called between any dsp function and float/double code. + * for example sin(); dsp->idct_put(); emms_c(); cos() + * Note, *alloc() and *free() also use float code in some libc implementations + * thus this also applies to them or any function using them. + */ +static av_always_inline void emms_c(void) +{ +/* Some inlined functions may also use mmx instructions regardless of + * runtime cpuflags. With that in mind, we unconditionally empty the + * mmx state if the target cpu chosen at configure time supports it. + */ +#if !defined(__MMX__) + if(av_get_cpu_flags() & AV_CPU_FLAG_MMX) +#endif + __asm__ volatile ("emms" ::: "memory"); +} +#elif HAVE_MMX && HAVE_MM_EMPTY +# include +# define emms_c _mm_empty +#elif HAVE_MMX_EXTERNAL +# define emms_c avpriv_emms_asm +#endif /* HAVE_MMX_INLINE */ + +#endif /* AVUTIL_X86_EMMS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/fixed_dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/fixed_dsp_init.c new file mode 100644 index 000000000..303a2eb92 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/fixed_dsp_init.c @@ -0,0 +1,35 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/fixed_dsp.h" +#include "cpu.h" + +void ff_butterflies_fixed_sse2(int *src0, int *src1, int len); + +av_cold void ff_fixed_dsp_init_x86(AVFixedDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + fdsp->butterflies_fixed = ff_butterflies_fixed_sse2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/float_dsp_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/float_dsp_init.c new file mode 100644 index 000000000..8826e4e2c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/float_dsp_init.c @@ -0,0 +1,121 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/float_dsp.h" +#include "cpu.h" +#include "asm.h" + +void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1, + int len); +void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1, + int len); + +void ff_vector_dmul_sse2(double *dst, const double *src0, const double *src1, + int len); +void ff_vector_dmul_avx(double *dst, const double *src0, const double *src1, + int len); + +void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul, + int len); +void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul, + int len); +void ff_vector_fmac_scalar_fma3(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_scalar_sse(float *dst, const float *src, float mul, + int len); + +void ff_vector_dmac_scalar_sse2(double *dst, const double *src, double mul, + int len); +void ff_vector_dmac_scalar_avx(double *dst, const double *src, double mul, + int len); +void ff_vector_dmac_scalar_fma3(double *dst, const double *src, double mul, + int len); + +void ff_vector_dmul_scalar_sse2(double *dst, const double *src, + double mul, int len); +void ff_vector_dmul_scalar_avx(double *dst, const double *src, + double mul, int len); + +void ff_vector_fmul_window_3dnowext(float *dst, const float *src0, + const float *src1, const float *win, int len); +void ff_vector_fmul_window_sse(float *dst, const float *src0, + const float *src1, const float *win, int len); + +void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1, + const float *src2, int len); +void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1, + const float *src2, int len); +void ff_vector_fmul_add_fma3(float *dst, const float *src0, const float *src1, + const float *src2, int len); + +void ff_vector_fmul_reverse_sse(float *dst, const float *src0, + const float *src1, int len); +void ff_vector_fmul_reverse_avx(float *dst, const float *src0, + const float *src1, int len); +void ff_vector_fmul_reverse_avx2(float *dst, const float *src0, + const float *src1, int len); + +float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order); + +void ff_butterflies_float_sse(float *av_restrict src0, float *av_restrict src1, int len); + +av_cold void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) { + fdsp->vector_fmul_window = ff_vector_fmul_window_3dnowext; + } + if (EXTERNAL_SSE(cpu_flags)) { + fdsp->vector_fmul = ff_vector_fmul_sse; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse; + fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse; + fdsp->vector_fmul_window = ff_vector_fmul_window_sse; + fdsp->vector_fmul_add = ff_vector_fmul_add_sse; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_sse; + fdsp->scalarproduct_float = ff_scalarproduct_float_sse; + fdsp->butterflies_float = ff_butterflies_float_sse; + } + if (EXTERNAL_SSE2(cpu_flags)) { + fdsp->vector_dmul = ff_vector_dmul_sse2; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_sse2; + fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + fdsp->vector_fmul = ff_vector_fmul_avx; + fdsp->vector_dmul = ff_vector_dmul_avx; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx; + fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_avx; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_avx; + fdsp->vector_fmul_add = ff_vector_fmul_add_avx; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_avx; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_avx2; + } + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_fma3; + fdsp->vector_fmul_add = ff_vector_fmul_add_fma3; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_fma3; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/imgutils_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/imgutils_init.c new file mode 100644 index 000000000..4ea398205 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/imgutils_init.c @@ -0,0 +1,49 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "libavutil/cpu.h" +#include "libavutil/error.h" +#include "libavutil/imgutils.h" +#include "libavutil/imgutils_internal.h" +#include "libavutil/internal.h" + +#include "cpu.h" + +void ff_image_copy_plane_uc_from_sse4(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height); + +int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) +{ + int cpu_flags = av_get_cpu_flags(); + ptrdiff_t bw_aligned = FFALIGN(bytewidth, 64); + + if (EXTERNAL_SSE4(cpu_flags) && + bw_aligned <= dst_linesize && bw_aligned <= src_linesize) + ff_image_copy_plane_uc_from_sse4(dst, dst_linesize, src, src_linesize, + bw_aligned, height); + else + return AVERROR(ENOSYS); + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/intmath.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/intmath.h new file mode 100644 index 000000000..40743fd13 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/intmath.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_INTMATH_H +#define AVUTIL_X86_INTMATH_H + +#include +#include +#if HAVE_FAST_CLZ +#if defined(_MSC_VER) +#include +#elif defined(__INTEL_COMPILER) +#include +#endif +#endif +#include "config.h" + +#if HAVE_FAST_CLZ +#if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER>=1216)) || defined(_MSC_VER) +# if defined(__INTEL_COMPILER) +# define ff_log2(x) (_bit_scan_reverse((x)|1)) +# else +# define ff_log2 ff_log2_x86 +static av_always_inline av_const int ff_log2_x86(unsigned int v) +{ + unsigned long n; + _BitScanReverse(&n, v|1); + return n; +} +# endif +# define ff_log2_16bit av_log2 + +#if defined(__INTEL_COMPILER) || (defined(_MSC_VER) && (_MSC_VER >= 1700) && \ + (defined(__BMI__) || !defined(__clang__))) +# define ff_ctz(v) _tzcnt_u32(v) + +# if ARCH_X86_64 +# define ff_ctzll(v) _tzcnt_u64(v) +# else +# define ff_ctzll ff_ctzll_x86 +static av_always_inline av_const int ff_ctzll_x86(long long v) +{ + return ((uint32_t)v == 0) ? _tzcnt_u32((uint32_t)(v >> 32)) + 32 : _tzcnt_u32((uint32_t)v); +} +# endif +#endif /* _MSC_VER */ + +#endif /* __INTEL_COMPILER */ + +#endif /* HAVE_FAST_CLZ */ + +#if defined(__GNUC__) + +/* Our generic version of av_popcount is faster than GCC's built-in on + * CPUs that don't support the popcnt instruction. + */ +#if defined(__POPCNT__) + #define av_popcount __builtin_popcount +#if ARCH_X86_64 + #define av_popcount64 __builtin_popcountll +#endif + +#endif /* __POPCNT__ */ + +#if defined(__BMI2__) + +#if AV_GCC_VERSION_AT_LEAST(5,1) +#define av_mod_uintp2 __builtin_ia32_bzhi_si +#elif HAVE_INLINE_ASM +/* GCC releases before 5.1.0 have a broken bzhi builtin, so for those we + * implement it using inline assembly + */ +#define av_mod_uintp2 av_mod_uintp2_bmi2 +static av_always_inline av_const unsigned av_mod_uintp2_bmi2(unsigned a, unsigned p) +{ + if (av_builtin_constant_p(p)) + return a & ((1 << p) - 1); + else { + unsigned x; + __asm__ ("bzhi %2, %1, %0 \n\t" : "=r"(x) : "rm"(a), "r"(p)); + return x; + } +} +#endif /* AV_GCC_VERSION_AT_LEAST */ + +#endif /* __BMI2__ */ + +#if defined(__SSE2__) && !defined(__INTEL_COMPILER) + +#define av_clipd av_clipd_sse2 +static av_always_inline av_const double av_clipd_sse2(double a, double amin, double amax) +{ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + __asm__ ("minsd %2, %0 \n\t" + "maxsd %1, %0 \n\t" + : "+&x"(a) : "xm"(amin), "xm"(amax)); + return a; +} + +#endif /* __SSE2__ */ + +#if defined(__SSE__) && !defined(__INTEL_COMPILER) + +#define av_clipf av_clipf_sse +static av_always_inline av_const float av_clipf_sse(float a, float amin, float amax) +{ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + __asm__ ("minss %2, %0 \n\t" + "maxss %1, %0 \n\t" + : "+&x"(a) : "xm"(amin), "xm"(amax)); + return a; +} + +#endif /* __SSE__ */ + +#endif /* __GNUC__ */ + +#endif /* AVUTIL_X86_INTMATH_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/intreadwrite.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/intreadwrite.h new file mode 100644 index 000000000..4061d1923 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/intreadwrite.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2010 Alexander Strange + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_INTREADWRITE_H +#define AVUTIL_X86_INTREADWRITE_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_MMX + +#if !HAVE_FAST_64BIT && defined(__MMX__) + +#define AV_COPY64 AV_COPY64 +static av_always_inline void AV_COPY64(void *d, const void *s) +{ + __asm__("movq %1, %%mm0 \n\t" + "movq %%mm0, %0 \n\t" + : "=m"(*(uint64_t*)d) + : "m" (*(const uint64_t*)s) + : "mm0"); +} + +#define AV_SWAP64 AV_SWAP64 +static av_always_inline void AV_SWAP64(void *a, void *b) +{ + __asm__("movq %1, %%mm0 \n\t" + "movq %0, %%mm1 \n\t" + "movq %%mm0, %0 \n\t" + "movq %%mm1, %1 \n\t" + : "+m"(*(uint64_t*)a), "+m"(*(uint64_t*)b) + ::"mm0", "mm1"); +} + +#define AV_ZERO64 AV_ZERO64 +static av_always_inline void AV_ZERO64(void *d) +{ + __asm__("pxor %%mm0, %%mm0 \n\t" + "movq %%mm0, %0 \n\t" + : "=m"(*(uint64_t*)d) + :: "mm0"); +} + +#endif /* !HAVE_FAST_64BIT && defined(__MMX__) */ + +#ifdef __SSE__ + +#define AV_COPY128 AV_COPY128 +static av_always_inline void AV_COPY128(void *d, const void *s) +{ + struct v {uint64_t v[2];}; + + __asm__("movaps %1, %%xmm0 \n\t" + "movaps %%xmm0, %0 \n\t" + : "=m"(*(struct v*)d) + : "m" (*(const struct v*)s) + : "xmm0"); +} + +#endif /* __SSE__ */ + +#ifdef __SSE2__ + +#define AV_ZERO128 AV_ZERO128 +static av_always_inline void AV_ZERO128(void *d) +{ + struct v {uint64_t v[2];}; + + __asm__("pxor %%xmm0, %%xmm0 \n\t" + "movdqa %%xmm0, %0 \n\t" + : "=m"(*(struct v*)d) + :: "xmm0"); +} + +#endif /* __SSE2__ */ + +#endif /* HAVE_MMX */ + +#endif /* AVUTIL_X86_INTREADWRITE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/lls_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/lls_init.c new file mode 100644 index 000000000..1c5dca42d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/lls_init.c @@ -0,0 +1,45 @@ +/* + * linear least squares model + * + * Copyright (c) 2013 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/lls.h" +#include "libavutil/x86/cpu.h" + +void ff_update_lls_sse2(LLSModel *m, const double *var); +void ff_update_lls_avx(LLSModel *m, const double *var); +void ff_update_lls_fma3(LLSModel *m, const double *var); +double ff_evaluate_lls_sse2(LLSModel *m, const double *var, int order); + +av_cold void ff_init_lls_x86(LLSModel *m) +{ + int cpu_flags = av_get_cpu_flags(); + if (EXTERNAL_SSE2(cpu_flags)) { + m->update_lls = ff_update_lls_sse2; + if (m->indep_count >= 4) + m->evaluate_lls = ff_evaluate_lls_sse2; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + m->update_lls = ff_update_lls_avx; + } + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + m->update_lls = ff_update_lls_fma3; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/pixelutils.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/pixelutils.h new file mode 100644 index 000000000..876cf4605 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/pixelutils.h @@ -0,0 +1,26 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_PIXELUTILS_H +#define AVUTIL_X86_PIXELUTILS_H + +#include "libavutil/pixelutils.h" + +void ff_pixelutils_sad_init_x86(av_pixelutils_sad_fn *sad, int aligned); + +#endif /* AVUTIL_X86_PIXELUTILS_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/pixelutils_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/pixelutils_init.c new file mode 100644 index 000000000..184a3a4a9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/pixelutils_init.c @@ -0,0 +1,94 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "pixelutils.h" +#include "cpu.h" + +int ff_pixelutils_sad_8x8_mmx(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_8x8_mmxext(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +int ff_pixelutils_sad_16x16_mmxext(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_a_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_u_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +int ff_pixelutils_sad_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_a_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_u_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +int ff_pixelutils_sad_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_a_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_u_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +void ff_pixelutils_sad_init_x86(av_pixelutils_sad_fn *sad, int aligned) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + sad[2] = ff_pixelutils_sad_8x8_mmx; + } + + // The best way to use SSE2 would be to do 2 SADs in parallel, + // but we'd have to modify the pixelutils API to return SIMD functions. + + // It's probably not faster to shuffle data around + // to get two lines of 8 pixels into a single 16byte register, + // so just use the MMX 8x8 version even when SSE2 is available. + if (EXTERNAL_MMXEXT(cpu_flags)) { + sad[2] = ff_pixelutils_sad_8x8_mmxext; + sad[3] = ff_pixelutils_sad_16x16_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + switch (aligned) { + case 0: sad[3] = ff_pixelutils_sad_16x16_sse2; break; // src1 unaligned, src2 unaligned + case 1: sad[3] = ff_pixelutils_sad_u_16x16_sse2; break; // src1 aligned, src2 unaligned + case 2: sad[3] = ff_pixelutils_sad_a_16x16_sse2; break; // src1 aligned, src2 aligned + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + switch (aligned) { + case 0: sad[4] = ff_pixelutils_sad_32x32_sse2; break; // src1 unaligned, src2 unaligned + case 1: sad[4] = ff_pixelutils_sad_u_32x32_sse2; break; // src1 aligned, src2 unaligned + case 2: sad[4] = ff_pixelutils_sad_a_32x32_sse2; break; // src1 aligned, src2 aligned + } + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + switch (aligned) { + case 0: sad[4] = ff_pixelutils_sad_32x32_avx2; break; // src1 unaligned, src2 unaligned + case 1: sad[4] = ff_pixelutils_sad_u_32x32_avx2; break; // src1 aligned, src2 unaligned + case 2: sad[4] = ff_pixelutils_sad_a_32x32_avx2; break; // src1 aligned, src2 aligned + } + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/timer.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/timer.h new file mode 100644 index 000000000..4d1e88def --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/timer.h @@ -0,0 +1,50 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_TIMER_H +#define AVUTIL_X86_TIMER_H + +#include + +#if HAVE_INLINE_ASM + +#define FF_TIMER_UNITS "decicycles" +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + uint32_t a, d; + __asm__ volatile( +#if ARCH_X86_64 || defined(__SSE2__) + "lfence \n\t" +#endif + "rdtsc \n\t" + : "=a" (a), "=d" (d)); + return ((uint64_t)d << 32) + a; +} + +#elif HAVE_RDTSC + +#include +#define AV_READ_TIME __rdtsc + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_X86_TIMER_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/w64xmmtest.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/w64xmmtest.h new file mode 100644 index 000000000..a4a05b041 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/w64xmmtest.h @@ -0,0 +1,78 @@ +/* + * check XMM registers for clobbers on Win64 + * Copyright (c) 2008 Ramiro Polla + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_X86_W64XMMTEST_H +#define AVUTIL_X86_W64XMMTEST_H + +#include +#include +#include +#include +#include + +#include "libavutil/bswap.h" + +#define storexmmregs(mem) \ + __asm__ volatile( \ + "movups %%xmm6 , 0x00(%0)\n\t" \ + "movups %%xmm7 , 0x10(%0)\n\t" \ + "movups %%xmm8 , 0x20(%0)\n\t" \ + "movups %%xmm9 , 0x30(%0)\n\t" \ + "movups %%xmm10, 0x40(%0)\n\t" \ + "movups %%xmm11, 0x50(%0)\n\t" \ + "movups %%xmm12, 0x60(%0)\n\t" \ + "movups %%xmm13, 0x70(%0)\n\t" \ + "movups %%xmm14, 0x80(%0)\n\t" \ + "movups %%xmm15, 0x90(%0)\n\t" \ + :: "r"(mem) : "memory") + +#define testxmmclobbers(func, ctx, ...) \ + uint64_t xmm[2][10][2]; \ + int ret; \ + storexmmregs(xmm[0]); \ + ret = __real_ ## func(ctx, __VA_ARGS__); \ + storexmmregs(xmm[1]); \ + if (memcmp(xmm[0], xmm[1], sizeof(xmm[0]))) { \ + int i; \ + av_log(ctx, AV_LOG_ERROR, \ + "XMM REGS CLOBBERED IN %s!\n", #func); \ + for (i = 0; i < 10; i ++) \ + if (xmm[0][i][0] != xmm[1][i][0] || \ + xmm[0][i][1] != xmm[1][i][1]) { \ + av_log(ctx, AV_LOG_ERROR, \ + "xmm%-2d = %016"PRIx64"%016"PRIx64"\n", \ + 6 + i, av_bswap64(xmm[0][i][0]), \ + av_bswap64(xmm[0][i][1])); \ + av_log(ctx, AV_LOG_ERROR, \ + " -> %016"PRIx64"%016"PRIx64"\n", \ + av_bswap64(xmm[1][i][0]), \ + av_bswap64(xmm[1][i][1])); \ + } \ + abort(); \ + } \ + return ret + +#define wrap(func) \ +int __real_ ## func; \ +int __wrap_ ## func; \ +int __wrap_ ## func + +#endif /* AVUTIL_X86_W64XMMTEST_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xga_font_data.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xga_font_data.c new file mode 100644 index 000000000..3aed3142c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xga_font_data.c @@ -0,0 +1,417 @@ +/* + * CGA/EGA/VGA ROM font data + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * CGA/EGA/VGA ROM font data + */ + +#include +#include "xga_font_data.h" + +const uint8_t avpriv_cga_font[2048] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, + 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, + 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, + 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, + 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, + 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, + 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, + 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, + 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, + 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, + 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, + 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, + 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, + 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, + 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, + 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, + 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, + 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, + 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, + 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, + 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, + 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, + 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, + 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, + 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, + 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, + 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, + 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, + 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, + 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, + 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, + 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, + 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, + 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, + 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, + 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, + 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, + 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, + 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, + 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, + 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, + 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, + 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, + 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, + 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const uint8_t avpriv_vga16_font[4096] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xga_font_data.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xga_font_data.h new file mode 100644 index 000000000..69dc33712 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xga_font_data.h @@ -0,0 +1,35 @@ +/* + * CGA/EGA/VGA ROM font data + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * CGA/EGA/VGA ROM font data + */ + +#ifndef AVUTIL_XGA_FONT_DATA_H +#define AVUTIL_XGA_FONT_DATA_H + +#include +#include "internal.h" + +extern av_export_avutil const uint8_t avpriv_cga_font[2048]; +extern av_export_avutil const uint8_t avpriv_vga16_font[4096]; + +#endif /* AVUTIL_XGA_FONT_DATA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xtea.c b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xtea.c new file mode 100644 index 000000000..f7892af9f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xtea.c @@ -0,0 +1,253 @@ +/* + * A 32-bit implementation of the XTEA algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * loosely based on the implementation of David Wheeler and Roger Needham + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief XTEA 32-bit implementation + * @author Samuel Pitoiset + * @ingroup lavu_xtea + */ + +#include "avutil.h" +#include "common.h" +#include "intreadwrite.h" +#include "mem.h" +#include "xtea.h" + +AVXTEA *av_xtea_alloc(void) +{ + return av_mallocz(sizeof(struct AVXTEA)); +} + +void av_xtea_init(AVXTEA *ctx, const uint8_t key[16]) +{ + int i; + + for (i = 0; i < 4; i++) + ctx->key[i] = AV_RB32(key + (i << 2)); +} + +void av_xtea_le_init(AVXTEA *ctx, const uint8_t key[16]) +{ + int i; + + for (i = 0; i < 4; i++) + ctx->key[i] = AV_RL32(key + (i << 2)); +} + +static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int decrypt, uint8_t *iv) +{ + uint32_t v0, v1; +#if !CONFIG_SMALL + uint32_t k0 = ctx->key[0]; + uint32_t k1 = ctx->key[1]; + uint32_t k2 = ctx->key[2]; + uint32_t k3 = ctx->key[3]; +#endif + + v0 = AV_RB32(src); + v1 = AV_RB32(src + 4); + + if (decrypt) { +#if CONFIG_SMALL + int i; + uint32_t delta = 0x9E3779B9U, sum = delta * 32; + + for (i = 0; i < 32; i++) { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); + } +#else +#define DSTEP(SUM, K0, K1) \ + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + K0); \ + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM - 0x9E3779B9U + K1) + + DSTEP(0xC6EF3720U, k2, k3); + DSTEP(0x28B7BD67U, k3, k2); + DSTEP(0x8A8043AEU, k0, k1); + DSTEP(0xEC48C9F5U, k1, k0); + DSTEP(0x4E11503CU, k2, k3); + DSTEP(0xAFD9D683U, k2, k2); + DSTEP(0x11A25CCAU, k3, k1); + DSTEP(0x736AE311U, k0, k0); + DSTEP(0xD5336958U, k1, k3); + DSTEP(0x36FBEF9FU, k1, k2); + DSTEP(0x98C475E6U, k2, k1); + DSTEP(0xFA8CFC2DU, k3, k0); + DSTEP(0x5C558274U, k0, k3); + DSTEP(0xBE1E08BBU, k1, k2); + DSTEP(0x1FE68F02U, k1, k1); + DSTEP(0x81AF1549U, k2, k0); + DSTEP(0xE3779B90U, k3, k3); + DSTEP(0x454021D7U, k0, k2); + DSTEP(0xA708A81EU, k1, k1); + DSTEP(0x08D12E65U, k1, k0); + DSTEP(0x6A99B4ACU, k2, k3); + DSTEP(0xCC623AF3U, k3, k2); + DSTEP(0x2E2AC13AU, k0, k1); + DSTEP(0x8FF34781U, k0, k0); + DSTEP(0xF1BBCDC8U, k1, k3); + DSTEP(0x5384540FU, k2, k2); + DSTEP(0xB54CDA56U, k3, k1); + DSTEP(0x1715609DU, k0, k0); + DSTEP(0x78DDE6E4U, k0, k3); + DSTEP(0xDAA66D2BU, k1, k2); + DSTEP(0x3C6EF372U, k2, k1); + DSTEP(0x9E3779B9U, k3, k0); +#endif + if (iv) { + v0 ^= AV_RB32(iv); + v1 ^= AV_RB32(iv + 4); + memcpy(iv, src, 8); + } + } else { +#if CONFIG_SMALL + int i; + uint32_t sum = 0, delta = 0x9E3779B9U; + + for (i = 0; i < 32; i++) { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); + } +#else +#define ESTEP(SUM, K0, K1) \ + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM + K0);\ + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + 0x9E3779B9U + K1) + ESTEP(0x00000000U, k0, k3); + ESTEP(0x9E3779B9U, k1, k2); + ESTEP(0x3C6EF372U, k2, k1); + ESTEP(0xDAA66D2BU, k3, k0); + ESTEP(0x78DDE6E4U, k0, k0); + ESTEP(0x1715609DU, k1, k3); + ESTEP(0xB54CDA56U, k2, k2); + ESTEP(0x5384540FU, k3, k1); + ESTEP(0xF1BBCDC8U, k0, k0); + ESTEP(0x8FF34781U, k1, k0); + ESTEP(0x2E2AC13AU, k2, k3); + ESTEP(0xCC623AF3U, k3, k2); + ESTEP(0x6A99B4ACU, k0, k1); + ESTEP(0x08D12E65U, k1, k1); + ESTEP(0xA708A81EU, k2, k0); + ESTEP(0x454021D7U, k3, k3); + ESTEP(0xE3779B90U, k0, k2); + ESTEP(0x81AF1549U, k1, k1); + ESTEP(0x1FE68F02U, k2, k1); + ESTEP(0xBE1E08BBU, k3, k0); + ESTEP(0x5C558274U, k0, k3); + ESTEP(0xFA8CFC2DU, k1, k2); + ESTEP(0x98C475E6U, k2, k1); + ESTEP(0x36FBEF9FU, k3, k1); + ESTEP(0xD5336958U, k0, k0); + ESTEP(0x736AE311U, k1, k3); + ESTEP(0x11A25CCAU, k2, k2); + ESTEP(0xAFD9D683U, k3, k2); + ESTEP(0x4E11503CU, k0, k1); + ESTEP(0xEC48C9F5U, k1, k0); + ESTEP(0x8A8043AEU, k2, k3); + ESTEP(0x28B7BD67U, k3, k2); +#endif + } + + AV_WB32(dst, v0); + AV_WB32(dst + 4, v1); +} + +static void xtea_le_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int decrypt, uint8_t *iv) +{ + uint32_t v0, v1; + int i; + + v0 = AV_RL32(src); + v1 = AV_RL32(src + 4); + + if (decrypt) { + uint32_t delta = 0x9E3779B9, sum = delta * 32; + + for (i = 0; i < 32; i++) { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); + } + if (iv) { + v0 ^= AV_RL32(iv); + v1 ^= AV_RL32(iv + 4); + memcpy(iv, src, 8); + } + } else { + uint32_t sum = 0, delta = 0x9E3779B9; + + for (i = 0; i < 32; i++) { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]); + } + } + + AV_WL32(dst, v0); + AV_WL32(dst + 4, v1); +} + +static void xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, + uint8_t *iv, int decrypt, + void (*crypt)(AVXTEA *, uint8_t *, const uint8_t *, int, uint8_t *)) +{ + int i; + + if (decrypt) { + while (count--) { + crypt(ctx, dst, src, decrypt, iv); + + src += 8; + dst += 8; + } + } else { + while (count--) { + if (iv) { + for (i = 0; i < 8; i++) + dst[i] = src[i] ^ iv[i]; + crypt(ctx, dst, dst, decrypt, NULL); + memcpy(iv, dst, 8); + } else { + crypt(ctx, dst, src, decrypt, NULL); + } + src += 8; + dst += 8; + } + } +} + +void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, + uint8_t *iv, int decrypt) +{ + xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_crypt_ecb); +} + +void av_xtea_le_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, + uint8_t *iv, int decrypt) +{ + xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_le_crypt_ecb); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xtea.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xtea.h new file mode 100644 index 000000000..735427c10 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/xtea.h @@ -0,0 +1,94 @@ +/* + * A 32-bit implementation of the XTEA algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_XTEA_H +#define AVUTIL_XTEA_H + +#include + +/** + * @file + * @brief Public header for libavutil XTEA algorithm + * @defgroup lavu_xtea XTEA + * @ingroup lavu_crypto + * @{ + */ + +typedef struct AVXTEA { + uint32_t key[16]; +} AVXTEA; + +/** + * Allocate an AVXTEA context. + */ +AVXTEA *av_xtea_alloc(void); + +/** + * Initialize an AVXTEA context. + * + * @param ctx an AVXTEA context + * @param key a key of 16 bytes used for encryption/decryption, + * interpreted as big endian 32 bit numbers + */ +void av_xtea_init(struct AVXTEA *ctx, const uint8_t key[16]); + +/** + * Initialize an AVXTEA context. + * + * @param ctx an AVXTEA context + * @param key a key of 16 bytes used for encryption/decryption, + * interpreted as little endian 32 bit numbers + */ +void av_xtea_le_init(struct AVXTEA *ctx, const uint8_t key[16]); + +/** + * Encrypt or decrypt a buffer using a previously initialized context, + * in big endian format. + * + * @param ctx an AVXTEA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_xtea_crypt(struct AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context, + * in little endian format. + * + * @param ctx an AVXTEA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_xtea_le_crypt(struct AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_XTEA_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/Makefile new file mode 100644 index 000000000..42666e4dd --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/Makefile @@ -0,0 +1,23 @@ +NAME = swresample +DESC = FFmpeg audio resampling library +FFLIBS = avutil + +HEADERS = swresample.h \ + version.h \ + +OBJS = audioconvert.o \ + dither.o \ + options.o \ + rematrix.o \ + resample.o \ + resample_dsp.o \ + swresample.o \ + swresample_frame.o \ + +OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o +OBJS-$(CONFIG_SHARED) += log2_tab.o + +# Windows resource file +SLIBOBJS-$(HAVE_GNU_WINDRES) += swresampleres.o + +TESTPROGS = swresample diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/audio_convert_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/audio_convert_init.c new file mode 100644 index 000000000..60e24adb1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/audio_convert_init.c @@ -0,0 +1,67 @@ +/* + * This file is part of libswresample. + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/aarch64/cpu.h" +#include "libavutil/samplefmt.h" +#include "libswresample/swresample_internal.h" +#include "libswresample/audioconvert.h" + +void swri_oldapi_conv_flt_to_s16_neon(int16_t *dst, const float *src, int len); +void swri_oldapi_conv_fltp_to_s16_2ch_neon(int16_t *dst, float *const *src, int len, int channels); +void swri_oldapi_conv_fltp_to_s16_nch_neon(int16_t *dst, float *const *src, int len, int channels); + +static void conv_flt_to_s16_neon(uint8_t **dst, const uint8_t **src, int len){ + swri_oldapi_conv_flt_to_s16_neon((int16_t*)*dst, (const float*)*src, len); +} + +static void conv_fltp_to_s16_2ch_neon(uint8_t **dst, const uint8_t **src, int len){ + swri_oldapi_conv_fltp_to_s16_2ch_neon((int16_t*)*dst, (float *const*)src, len, 2); +} + +static void conv_fltp_to_s16_nch_neon(uint8_t **dst, const uint8_t **src, int len){ + int channels; + for(channels=3; channelssimd_f= NULL; + + if (have_neon(cpu_flags)) { + if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = conv_flt_to_s16_neon; + if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP && channels == 2) + ac->simd_f = conv_fltp_to_s16_2ch_neon; + if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP && channels > 2) + ac->simd_f = conv_fltp_to_s16_nch_neon; + if(ac->simd_f) + ac->in_simd_align_mask = ac->out_simd_align_mask = 15; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/resample_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/resample_init.c new file mode 100644 index 000000000..d01ec1875 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/resample_init.c @@ -0,0 +1,120 @@ +/* + * Audio resampling + * + * Copyright (c) 2004-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/cpu.h" +#include "libavutil/avassert.h" + +#include "libavutil/aarch64/cpu.h" +#include "libswresample/resample.h" + +#define DECLARE_RESAMPLE_COMMON_TEMPLATE(TYPE, DELEM, FELEM, FELEM2, OUT) \ + \ +void ff_resample_common_apply_filter_x4_##TYPE##_neon(FELEM2 *acc, const DELEM *src, \ + const FELEM *filter, int length); \ + \ +void ff_resample_common_apply_filter_x8_##TYPE##_neon(FELEM2 *acc, const DELEM *src, \ + const FELEM *filter, int length); \ + \ +static int ff_resample_common_##TYPE##_neon(ResampleContext *c, void *dest, const void *source, \ + int n, int update_ctx) \ +{ \ + DELEM *dst = dest; \ + const DELEM *src = source; \ + int dst_index; \ + int index = c->index; \ + int frac = c->frac; \ + int sample_index = 0; \ + int x4_aligned_filter_length = c->filter_length & ~3; \ + int x8_aligned_filter_length = c->filter_length & ~7; \ + \ + while (index >= c->phase_count) { \ + sample_index++; \ + index -= c->phase_count; \ + } \ + \ + for (dst_index = 0; dst_index < n; dst_index++) { \ + FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; \ + \ + FELEM2 val = 0; \ + int i = 0; \ + if (x8_aligned_filter_length >= 8) { \ + ff_resample_common_apply_filter_x8_##TYPE##_neon(&val, &src[sample_index], \ + filter, x8_aligned_filter_length); \ + i += x8_aligned_filter_length; \ + \ + } else if (x4_aligned_filter_length >= 4) { \ + ff_resample_common_apply_filter_x4_##TYPE##_neon(&val, &src[sample_index], \ + filter, x4_aligned_filter_length); \ + i += x4_aligned_filter_length; \ + } \ + for (; i < c->filter_length; i++) { \ + val += src[sample_index + i] * (FELEM2)filter[i]; \ + } \ + OUT(dst[dst_index], val); \ + \ + frac += c->dst_incr_mod; \ + index += c->dst_incr_div; \ + if (frac >= c->src_incr) { \ + frac -= c->src_incr; \ + index++; \ + } \ + \ + while (index >= c->phase_count) { \ + sample_index++; \ + index -= c->phase_count; \ + } \ + } \ + \ + if (update_ctx) { \ + c->frac = frac; \ + c->index = index; \ + } \ + \ + return sample_index; \ +} \ + +#define OUT(d, v) d = v +DECLARE_RESAMPLE_COMMON_TEMPLATE(float, float, float, float, OUT) +#undef OUT + +#define OUT(d, v) (v) = ((v) + (1<<(14)))>>15; (d) = av_clip_int16(v) +DECLARE_RESAMPLE_COMMON_TEMPLATE(s16, int16_t, int16_t, int32_t, OUT) +#undef OUT + +av_cold void swri_resample_dsp_aarch64_init(ResampleContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (!have_neon(cpu_flags)) + return; + + switch(c->format) { + case AV_SAMPLE_FMT_FLTP: + c->dsp.resample_common = ff_resample_common_float_neon; + break; + case AV_SAMPLE_FMT_S16P: + c->dsp.resample_common = ff_resample_common_s16_neon; + break; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/audio_convert_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/audio_convert_init.c new file mode 100644 index 000000000..ec9e62ede --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/audio_convert_init.c @@ -0,0 +1,67 @@ +/* + * This file is part of libswresample. + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/arm/cpu.h" +#include "libavutil/samplefmt.h" +#include "libswresample/swresample_internal.h" +#include "libswresample/audioconvert.h" + +void swri_oldapi_conv_flt_to_s16_neon(int16_t *dst, const float *src, int len); +void swri_oldapi_conv_fltp_to_s16_2ch_neon(int16_t *dst, float *const *src, int len, int channels); +void swri_oldapi_conv_fltp_to_s16_nch_neon(int16_t *dst, float *const *src, int len, int channels); + +static void conv_flt_to_s16_neon(uint8_t **dst, const uint8_t **src, int len){ + swri_oldapi_conv_flt_to_s16_neon((int16_t*)*dst, (const float*)*src, len); +} + +static void conv_fltp_to_s16_2ch_neon(uint8_t **dst, const uint8_t **src, int len){ + swri_oldapi_conv_fltp_to_s16_2ch_neon((int16_t*)*dst, (float *const*)src, len, 2); +} + +static void conv_fltp_to_s16_nch_neon(uint8_t **dst, const uint8_t **src, int len){ + int channels; + for(channels=3; channelssimd_f= NULL; + + if (have_neon(cpu_flags)) { + if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = conv_flt_to_s16_neon; + if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP && channels == 2) + ac->simd_f = conv_fltp_to_s16_2ch_neon; + if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP && channels > 2) + ac->simd_f = conv_fltp_to_s16_nch_neon; + if(ac->simd_f) + ac->in_simd_align_mask = ac->out_simd_align_mask = 15; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/resample_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/resample_init.c new file mode 100644 index 000000000..09b9766ff --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/resample_init.c @@ -0,0 +1,120 @@ +/* + * Audio resampling + * + * Copyright (c) 2004-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "libavutil/cpu.h" +#include "libavutil/avassert.h" + +#include "libavutil/arm/cpu.h" +#include "libswresample/resample.h" + +#define DECLARE_RESAMPLE_COMMON_TEMPLATE(TYPE, DELEM, FELEM, FELEM2, OUT) \ + \ +void ff_resample_common_apply_filter_x4_##TYPE##_neon(FELEM2 *acc, const DELEM *src, \ + const FELEM *filter, int length); \ + \ +void ff_resample_common_apply_filter_x8_##TYPE##_neon(FELEM2 *acc, const DELEM *src, \ + const FELEM *filter, int length); \ + \ +static int ff_resample_common_##TYPE##_neon(ResampleContext *c, void *dest, const void *source, \ + int n, int update_ctx) \ +{ \ + DELEM *dst = dest; \ + const DELEM *src = source; \ + int dst_index; \ + int index = c->index; \ + int frac = c->frac; \ + int sample_index = 0; \ + int x4_aligned_filter_length = c->filter_length & ~3; \ + int x8_aligned_filter_length = c->filter_length & ~7; \ + \ + while (index >= c->phase_count) { \ + sample_index++; \ + index -= c->phase_count; \ + } \ + \ + for (dst_index = 0; dst_index < n; dst_index++) { \ + FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; \ + \ + FELEM2 val = 0; \ + int i = 0; \ + if (x8_aligned_filter_length >= 8) { \ + ff_resample_common_apply_filter_x8_##TYPE##_neon(&val, &src[sample_index], \ + filter, x8_aligned_filter_length); \ + i += x8_aligned_filter_length; \ + \ + } else if (x4_aligned_filter_length >= 4) { \ + ff_resample_common_apply_filter_x4_##TYPE##_neon(&val, &src[sample_index], \ + filter, x4_aligned_filter_length); \ + i += x4_aligned_filter_length; \ + } \ + for (; i < c->filter_length; i++) { \ + val += src[sample_index + i] * (FELEM2)filter[i]; \ + } \ + OUT(dst[dst_index], val); \ + \ + frac += c->dst_incr_mod; \ + index += c->dst_incr_div; \ + if (frac >= c->src_incr) { \ + frac -= c->src_incr; \ + index++; \ + } \ + \ + while (index >= c->phase_count) { \ + sample_index++; \ + index -= c->phase_count; \ + } \ + } \ + \ + if (update_ctx) { \ + c->frac = frac; \ + c->index = index; \ + } \ + \ + return sample_index; \ +} \ + +#define OUT(d, v) d = v +DECLARE_RESAMPLE_COMMON_TEMPLATE(float, float, float, float, OUT) +#undef OUT + +#define OUT(d, v) (v) = ((v) + (1<<(14)))>>15; (d) = av_clip_int16(v) +DECLARE_RESAMPLE_COMMON_TEMPLATE(s16, int16_t, int16_t, int32_t, OUT) +#undef OUT + +av_cold void swri_resample_dsp_arm_init(ResampleContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (!have_neon(cpu_flags)) + return; + + switch(c->format) { + case AV_SAMPLE_FMT_FLTP: + c->dsp.resample_common = ff_resample_common_float_neon; + break; + case AV_SAMPLE_FMT_S16P: + c->dsp.resample_common = ff_resample_common_s16_neon; + break; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/audioconvert.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/audioconvert.c new file mode 100644 index 000000000..96ce84ac4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/audioconvert.c @@ -0,0 +1,247 @@ +/* + * audio conversion + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio conversion + * @author Michael Niedermayer + */ + +#include "libavutil/avstring.h" +#include "libavutil/avassert.h" +#include "libavutil/libm.h" +#include "libavutil/samplefmt.h" +#include "audioconvert.h" + + +#define CONV_FUNC_NAME(dst_fmt, src_fmt) conv_ ## src_fmt ## _to_ ## dst_fmt + +//FIXME rounding ? +#define CONV_FUNC(ofmt, otype, ifmt, expr)\ +static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *po, const uint8_t *pi, int is, int os, uint8_t *end)\ +{\ + uint8_t *end2 = end - 3*os;\ + while(po < end2){\ + *(otype*)po = expr; pi += is; po += os;\ + *(otype*)po = expr; pi += is; po += os;\ + *(otype*)po = expr; pi += is; po += os;\ + *(otype*)po = expr; pi += is; po += os;\ + }\ + while(po < end){\ + *(otype*)po = expr; pi += is; po += os;\ + }\ +} + +//FIXME put things below under ifdefs so we do not waste space for cases no codec will need +CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi) +CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80U)<<8) +CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80U)<<24) +CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8 , (uint64_t)((*(const uint8_t*)pi - 0x80U))<<56) +CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0f/ (1<<7))) +CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) +CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80) +CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi) +CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16) +CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16, (uint64_t)(*(const int16_t*)pi)<<48) +CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0f/ (1<<15))) +CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) +CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80) +CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16) +CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi) +CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32, (uint64_t)(*(const int32_t*)pi)<<32) +CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0f/ (1U<<31))) +CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31))) +CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S64, (*(const int64_t*)pi>>56) + 0x80) +CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S64, *(const int64_t*)pi>>48) +CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S64, *(const int64_t*)pi>>32) +CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S64, *(const int64_t*)pi) +CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S64, *(const int64_t*)pi*(1.0f/ (INT64_C(1)<<63))) +CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S64, *(const int64_t*)pi*(1.0 / (INT64_C(1)<<63))) +CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80)) +CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15)))) +CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31)))) +CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float*)pi * (INT64_C(1)<<63))) +CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi) +CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi) +CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80)) +CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15)))) +CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31)))) +CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double*)pi * (INT64_C(1)<<63))) +CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi) +CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi) + +#define FMT_PAIR_FUNC(out, in) [(out) + AV_SAMPLE_FMT_NB*(in)] = CONV_FUNC_NAME(out, in) + +static conv_func_type * const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB*AV_SAMPLE_FMT_NB] = { + FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_U8 ), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8 ), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8 ), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8 ), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8 ), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8 ), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_S16), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_S32), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_FLT), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_DBL), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_S64), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), + FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), +}; + +static void cpy1(uint8_t **dst, const uint8_t **src, int len){ + memcpy(*dst, *src, len); +} +static void cpy2(uint8_t **dst, const uint8_t **src, int len){ + memcpy(*dst, *src, 2*len); +} +static void cpy4(uint8_t **dst, const uint8_t **src, int len){ + memcpy(*dst, *src, 4*len); +} +static void cpy8(uint8_t **dst, const uint8_t **src, int len){ + memcpy(*dst, *src, 8*len); +} + +AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, + enum AVSampleFormat in_fmt, + int channels, const int *ch_map, + int flags) +{ + AudioConvert *ctx; + conv_func_type *f = fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt) + AV_SAMPLE_FMT_NB*av_get_packed_sample_fmt(in_fmt)]; + + if (!f) + return NULL; + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return NULL; + + if(channels == 1){ + in_fmt = av_get_planar_sample_fmt( in_fmt); + out_fmt = av_get_planar_sample_fmt(out_fmt); + } + + ctx->channels = channels; + ctx->conv_f = f; + ctx->ch_map = ch_map; + if (in_fmt == AV_SAMPLE_FMT_U8 || in_fmt == AV_SAMPLE_FMT_U8P) + memset(ctx->silence, 0x80, sizeof(ctx->silence)); + + if(out_fmt == in_fmt && !ch_map) { + switch(av_get_bytes_per_sample(in_fmt)){ + case 1:ctx->simd_f = cpy1; break; + case 2:ctx->simd_f = cpy2; break; + case 4:ctx->simd_f = cpy4; break; + case 8:ctx->simd_f = cpy8; break; + } + } + + if(HAVE_X86ASM && HAVE_MMX) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels); + if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels); + if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels); + + return ctx; +} + +void swri_audio_convert_free(AudioConvert **ctx) +{ + av_freep(ctx); +} + +int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) +{ + int ch; + int off=0; + const int os= (out->planar ? 1 :out->ch_count) *out->bps; + unsigned misaligned = 0; + + av_assert0(ctx->channels == out->ch_count); + + if (ctx->in_simd_align_mask) { + int planes = in->planar ? in->ch_count : 1; + unsigned m = 0; + for (ch = 0; ch < planes; ch++) + m |= (intptr_t)in->ch[ch]; + misaligned |= m & ctx->in_simd_align_mask; + } + if (ctx->out_simd_align_mask) { + int planes = out->planar ? out->ch_count : 1; + unsigned m = 0; + for (ch = 0; ch < planes; ch++) + m |= (intptr_t)out->ch[ch]; + misaligned |= m & ctx->out_simd_align_mask; + } + + //FIXME optimize common cases + + if(ctx->simd_f && !ctx->ch_map && !misaligned){ + off = len&~15; + av_assert1(off>=0); + av_assert1(off<=len); + av_assert2(ctx->channels == SWR_CH_MAX || !in->ch[ctx->channels]); + if(off>0){ + if(out->planar == in->planar){ + int planes = out->planar ? out->ch_count : 1; + for(ch=0; chsimd_f(out->ch+ch, (const uint8_t **)in->ch+ch, off * (out->planar ? 1 :out->ch_count)); + } + }else{ + ctx->simd_f(out->ch, (const uint8_t **)in->ch, off); + } + } + if(off == len) + return 0; + } + + for(ch=0; chchannels; ch++){ + const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch; + const int is= ich < 0 ? 0 : (in->planar ? 1 : in->ch_count) * in->bps; + const uint8_t *pi= ich < 0 ? ctx->silence : in->ch[ich]; + uint8_t *po= out->ch[ch]; + uint8_t *end= po + os*len; + if(!po) + continue; + ctx->conv_f(po+off*os, pi+off*is, is, os, end); + } + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/audioconvert.h b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/audioconvert.h new file mode 100644 index 000000000..1ca30c2a6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/audioconvert.h @@ -0,0 +1,78 @@ +/* + * audio conversion + * Copyright (c) 2006 Michael Niedermayer + * Copyright (c) 2008 Peter Ross + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWRESAMPLE_AUDIOCONVERT_H +#define SWRESAMPLE_AUDIOCONVERT_H + +/** + * @file + * Audio format conversion routines + */ + + +#include "swresample_internal.h" +#include "libavutil/cpu.h" + + +typedef void (conv_func_type)(uint8_t *po, const uint8_t *pi, int is, int os, uint8_t *end); +typedef void (simd_func_type)(uint8_t **dst, const uint8_t **src, int len); + +typedef struct AudioConvert { + int channels; + int in_simd_align_mask; + int out_simd_align_mask; + conv_func_type *conv_f; + simd_func_type *simd_f; + const int *ch_map; + uint8_t silence[8]; ///< silence input sample +}AudioConvert; + +/** + * Create an audio sample format converter context + * @param out_fmt Output sample format + * @param in_fmt Input sample format + * @param channels Number of channels + * @param flags See AV_CPU_FLAG_xx + * @param ch_map list of the channels id to pick from the source stream, NULL + * if all channels must be selected + * @return NULL on error + */ +AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, + enum AVSampleFormat in_fmt, + int channels, const int *ch_map, + int flags); + +/** + * Free audio sample format converter context. + * and set the pointer to NULL + */ +void swri_audio_convert_free(AudioConvert **ctx); + +/** + * Convert between audio sample formats + * @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel. + * @param[in] in array of input buffers for each channel + * @param len length of audio frame size (measured in samples) + */ +int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len); + +#endif /* SWRESAMPLE_AUDIOCONVERT_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/dither.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/dither.c new file mode 100644 index 000000000..64068d35b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/dither.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2012-2013 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/avassert.h" +#include "swresample_internal.h" + +#include "noise_shaping_data.c" + +int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt) { + double scale = s->dither.noise_scale; +#define TMP_EXTRA 2 + double *tmp = av_malloc_array(len + TMP_EXTRA, sizeof(double)); + int i; + + if (!tmp) + return AVERROR(ENOMEM); + + for(i=0; idither.method){ + case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break; + default: + av_assert0(s->dither.method < SWR_DITHER_NB); + v = ((double)seed) / UINT_MAX; + seed = seed*1664525 + 1013904223; + v-= ((double)seed) / UINT_MAX; + break; + } + tmp[i] = v; + } + + for(i=0; idither.method){ + default: + av_assert0(s->dither.method < SWR_DITHER_NB); + v = tmp[i]; + break; + case SWR_DITHER_TRIANGULAR_HIGHPASS : + v = (- tmp[i] + 2*tmp[i+1] - tmp[i+2]) / sqrt(6); + break; + } + + v*= scale; + + switch(noise_fmt){ + case AV_SAMPLE_FMT_S16P: ((int16_t*)dst)[i] = v; break; + case AV_SAMPLE_FMT_S32P: ((int32_t*)dst)[i] = v; break; + case AV_SAMPLE_FMT_FLTP: ((float *)dst)[i] = v; break; + case AV_SAMPLE_FMT_DBLP: ((double *)dst)[i] = v; break; + default: av_assert0(0); + } + } + + av_free(tmp); + return 0; +} + +av_cold int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt) +{ + int i; + double scale = 0; + + if (s->dither.method > SWR_DITHER_TRIANGULAR_HIGHPASS && s->dither.method <= SWR_DITHER_NS) + return AVERROR(EINVAL); + + out_fmt = av_get_packed_sample_fmt(out_fmt); + in_fmt = av_get_packed_sample_fmt( in_fmt); + + if(in_fmt == AV_SAMPLE_FMT_FLT || in_fmt == AV_SAMPLE_FMT_DBL){ + if(out_fmt == AV_SAMPLE_FMT_S32) scale = 1.0/(1LL<<31); + if(out_fmt == AV_SAMPLE_FMT_S16) scale = 1.0/(1LL<<15); + if(out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1.0/(1LL<< 7); + } + if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S32 && (s->dither.output_sample_bits&31)) scale = 1; + if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1<<16; + if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1<<24; + if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1<<8; + + scale *= s->dither.scale; + + if (out_fmt == AV_SAMPLE_FMT_S32 && s->dither.output_sample_bits) + scale *= 1<<(32-s->dither.output_sample_bits); + + if (scale == 0) { + s->dither.method = 0; + return 0; + } + + s->dither.ns_pos = 0; + s->dither.noise_scale= scale; + s->dither.ns_scale = scale; + s->dither.ns_scale_1 = scale ? 1/scale : 0; + memset(s->dither.ns_errors, 0, sizeof(s->dither.ns_errors)); + for (i=0; filters[i].coefs; i++) { + const filter_t *f = &filters[i]; + if (llabs(s->out_sample_rate - f->rate)*20 <= f->rate && f->name == s->dither.method) { + int j; + s->dither.ns_taps = f->len; + for (j=0; jlen; j++) + s->dither.ns_coeffs[j] = f->coefs[j]; + s->dither.ns_scale_1 *= 1 - exp(f->gain_cB * M_LN10 * 0.005) * 2 / (1<<(8*av_get_bytes_per_sample(out_fmt))); + break; + } + } + if (!filters[i].coefs && s->dither.method > SWR_DITHER_NS) { + av_log(s, AV_LOG_WARNING, "Requested noise shaping dither not available at this sampling rate, using triangular hp dither\n"); + s->dither.method = SWR_DITHER_TRIANGULAR_HIGHPASS; + } + + return 0; +} + +#define TEMPLATE_DITHER_S16 +#include "dither_template.c" +#undef TEMPLATE_DITHER_S16 + +#define TEMPLATE_DITHER_S32 +#include "dither_template.c" +#undef TEMPLATE_DITHER_S32 + +#define TEMPLATE_DITHER_FLT +#include "dither_template.c" +#undef TEMPLATE_DITHER_FLT + +#define TEMPLATE_DITHER_DBL +#include "dither_template.c" +#undef TEMPLATE_DITHER_DBL diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/dither_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/dither_template.c new file mode 100644 index 000000000..1f535de3d --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/dither_template.c @@ -0,0 +1,84 @@ +/* + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if defined(TEMPLATE_DITHER_DBL) +# define RENAME(N) N ## _double +# define DELEM double +# define CLIP(v) while(0) + +#elif defined(TEMPLATE_DITHER_FLT) +# define RENAME(N) N ## _float +# define DELEM float +# define CLIP(v) while(0) + +#elif defined(TEMPLATE_DITHER_S32) +# define RENAME(N) N ## _int32 +# define DELEM int32_t +# define CLIP(v) v = FFMAX(FFMIN(v, INT32_MAX), INT32_MIN) + +#elif defined(TEMPLATE_DITHER_S16) +# define RENAME(N) N ## _int16 +# define DELEM int16_t +# define CLIP(v) v = FFMAX(FFMIN(v, INT16_MAX), INT16_MIN) + +#else +ERROR +#endif + +void RENAME(swri_noise_shaping)(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count){ + int pos = s->dither.ns_pos; + int i, j, ch; + int taps = s->dither.ns_taps; + float S = s->dither.ns_scale; + float S_1 = s->dither.ns_scale_1; + + av_assert2((taps&3) != 2); + av_assert2((taps&3) != 3 || s->dither.ns_coeffs[taps] == 0); + + for (ch=0; chch_count; ch++) { + const float *noise = ((const float *)noises->ch[ch]) + s->dither.noise_pos; + const DELEM *src = (const DELEM*)srcs->ch[ch]; + DELEM *dst = (DELEM*)dsts->ch[ch]; + float *ns_errors = s->dither.ns_errors[ch]; + const float *ns_coeffs = s->dither.ns_coeffs; + pos = s->dither.ns_pos; + for (i=0; idither.ns_pos = pos; +} + +#undef RENAME +#undef DELEM +#undef CLIP diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/noise_shaping_data.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/noise_shaping_data.c new file mode 100644 index 000000000..77e0f2eaf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/noise_shaping_data.c @@ -0,0 +1,224 @@ +/* Effect: dither/noise-shape Copyright (c) 2008-9 robs@users.sourceforge.net + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. + * + * This library 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 Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +typedef struct { + int rate; + enum {fir, iir} type; + size_t len; + int gain_cB; /* Chosen so clips are few if any, but not guaranteed none. */ + double const * coefs; + enum SwrDitherType name; +} filter_t; + +static double const lip44[] = {2.033, -2.165, 1.959, -1.590, .6149}; +static double const fwe44[] = { + 2.412, -3.370, 3.937, -4.174, 3.353, -2.205, 1.281, -.569, .0847}; +static double const mew44[] = { + 1.662, -1.263, .4827, -.2913, .1268, -.1124, .03252, -.01265, -.03524}; +static double const iew44[] = { + 2.847, -4.685, 6.214, -7.184, 6.639, -5.032, 3.263, -1.632, .4191}; +static double const ges44[] = { + 2.2061, -.4706, -.2534, -.6214, 1.0587, .0676, -.6054, -.2738}; +static double const ges48[] = { + 2.2374, -.7339, -.1251, -.6033, .903, .0116, -.5853, -.2571}; + +static double const shi48[] = { + 2.8720729351043701172, -5.0413231849670410156, 6.2442994117736816406, + -5.8483986854553222656, 3.7067542076110839844, -1.0495119094848632812, + -1.1830236911773681641, 2.1126792430877685547, -1.9094531536102294922, + 0.99913084506988525391, -0.17090806365013122559, -0.32615602016448974609, + 0.39127644896507263184, -0.26876461505889892578, 0.097676105797290802002, + -0.023473845794796943665, +}; +static double const shi44[] = { + 2.6773197650909423828, -4.8308925628662109375, 6.570110321044921875, + -7.4572014808654785156, 6.7263274192810058594, -4.8481650352478027344, + 2.0412089824676513672, 0.7006359100341796875, -2.9537565708160400391, + 4.0800385475158691406, -4.1845216751098632812, 3.3311812877655029297, + -2.1179926395416259766, 0.879302978515625, -0.031759146600961685181, + -0.42382788658142089844, 0.47882103919982910156, -0.35490813851356506348, + 0.17496839165687561035, -0.060908168554306030273, +}; +static double const shi38[] = { + 1.6335992813110351562, -2.2615492343902587891, 2.4077029228210449219, + -2.6341717243194580078, 2.1440362930297851562, -1.8153258562088012695, + 1.0816224813461303711, -0.70302653312683105469, 0.15991993248462677002, + 0.041549518704414367676, -0.29416576027870178223, 0.2518316805362701416, + -0.27766478061676025391, 0.15785403549671173096, -0.10165894031524658203, + 0.016833892092108726501, +}; +static double const shi32[] = +{ /* dmaker 32000: bestmax=4.99659 (inverted) */ +0.82118552923202515, +-1.0063692331314087, +0.62341964244842529, +-1.0447187423706055, +0.64532512426376343, +-0.87615132331848145, +0.52219754457473755, +-0.67434263229370117, +0.44954317808151245, +-0.52557498216629028, +0.34567299485206604, +-0.39618203043937683, +0.26791760325431824, +-0.28936097025871277, +0.1883765310049057, +-0.19097308814525604, +0.10431359708309174, +-0.10633844882249832, +0.046832218766212463, +-0.039653312414884567, +}; +static double const shi22[] = +{ /* dmaker 22050: bestmax=5.77762 (inverted) */ +0.056581053882837296, +-0.56956905126571655, +-0.40727734565734863, +-0.33870288729667664, +-0.29810553789138794, +-0.19039161503314972, +-0.16510021686553955, +-0.13468159735202789, +-0.096633769571781158, +-0.081049129366874695, +-0.064953058958053589, +-0.054459091275930405, +-0.043378707021474838, +-0.03660014271736145, +-0.026256965473294258, +-0.018786206841468811, +-0.013387725688517094, +-0.0090983230620622635, +-0.0026585909072309732, +-0.00042083300650119781, +}; +static double const shi16[] = +{ /* dmaker 16000: bestmax=5.97128 (inverted) */ +-0.37251132726669312, +-0.81423574686050415, +-0.55010956525802612, +-0.47405767440795898, +-0.32624706625938416, +-0.3161766529083252, +-0.2286367267370224, +-0.22916607558727264, +-0.19565616548061371, +-0.18160104751586914, +-0.15423151850700378, +-0.14104481041431427, +-0.11844276636838913, +-0.097583092749118805, +-0.076493598520755768, +-0.068106919527053833, +-0.041881654411554337, +-0.036922425031661987, +-0.019364040344953537, +-0.014994367957115173, +}; +static double const shi11[] = +{ /* dmaker 11025: bestmax=5.9406 (inverted) */ +-0.9264228343963623, +-0.98695987462997437, +-0.631156325340271, +-0.51966935396194458, +-0.39738872647285461, +-0.35679301619529724, +-0.29720726609230042, +-0.26310476660728455, +-0.21719355881214142, +-0.18561814725399017, +-0.15404847264289856, +-0.12687471508979797, +-0.10339745879173279, +-0.083688631653785706, +-0.05875682458281517, +-0.046893671154975891, +-0.027950936928391457, +-0.020740609616041183, +-0.009366452693939209, +-0.0060260160826146603, +}; +static double const shi08[] = +{ /* dmaker 8000: bestmax=5.56234 (inverted) */ +-1.202863335609436, +-0.94103097915649414, +-0.67878556251525879, +-0.57650017738342285, +-0.50004476308822632, +-0.44349345564842224, +-0.37833768129348755, +-0.34028723835945129, +-0.29413089156150818, +-0.24994957447052002, +-0.21715600788593292, +-0.18792112171649933, +-0.15268312394618988, +-0.12135542929172516, +-0.099610626697540283, +-0.075273610651493073, +-0.048787496984004974, +-0.042586319148540497, +-0.028991291299462318, +-0.011869125068187714, +}; +static double const shl48[] = { + 2.3925774097442626953, -3.4350297451019287109, 3.1853709220886230469, + -1.8117271661758422852, -0.20124770700931549072, 1.4759907722473144531, + -1.7210904359817504883, 0.97746700048446655273, -0.13790138065814971924, + -0.38185903429985046387, 0.27421241998672485352, 0.066584214568138122559, + -0.35223302245140075684, 0.37672343850135803223, -0.23964276909828186035, + 0.068674825131893157959, +}; +static double const shl44[] = { + 2.0833916664123535156, -3.0418450832366943359, 3.2047898769378662109, + -2.7571926116943359375, 1.4978630542755126953, -0.3427594602108001709, + -0.71733748912811279297, 1.0737057924270629883, -1.0225815773010253906, + 0.56649994850158691406, -0.20968692004680633545, -0.065378531813621520996, + 0.10322438180446624756, -0.067442022264003753662, -0.00495197344571352005, + 0, +}; +static double const shh44[] = { + 3.0259189605712890625, -6.0268716812133789062, 9.195003509521484375, + -11.824929237365722656, 12.767142295837402344, -11.917946815490722656, + 9.1739168167114257812, -5.3712320327758789062, 1.1393624544143676758, + 2.4484779834747314453, -4.9719839096069335938, 6.0392003059387207031, + -5.9359521865844726562, 4.903278350830078125, -3.5527443885803222656, + 2.1909697055816650391, -1.1672389507293701172, 0.4903914332389831543, + -0.16519790887832641602, 0.023217858746647834778, +}; + +static const filter_t filters[] = { + {44100, fir, 5, 210, lip44, SWR_DITHER_NS_LIPSHITZ}, + {46000, fir, 9, 276, fwe44, SWR_DITHER_NS_F_WEIGHTED}, + {46000, fir, 9, 160, mew44, SWR_DITHER_NS_MODIFIED_E_WEIGHTED}, + {46000, fir, 9, 321, iew44, SWR_DITHER_NS_IMPROVED_E_WEIGHTED}, +// {48000, iir, 4, 220, ges48, SWR_DITHER_NS_GESEMANN}, +// {44100, iir, 4, 230, ges44, SWR_DITHER_NS_GESEMANN}, + {48000, fir, 16, 301, shi48, SWR_DITHER_NS_SHIBATA}, + {44100, fir, 20, 333, shi44, SWR_DITHER_NS_SHIBATA}, + {37800, fir, 16, 240, shi38, SWR_DITHER_NS_SHIBATA}, + {32000, fir, 20, 240/*TBD*/, shi32, SWR_DITHER_NS_SHIBATA}, + {22050, fir, 20, 240/*TBD*/, shi22, SWR_DITHER_NS_SHIBATA}, + {16000, fir, 20, 240/*TBD*/, shi16, SWR_DITHER_NS_SHIBATA}, + {11025, fir, 20, 240/*TBD*/, shi11, SWR_DITHER_NS_SHIBATA}, + { 8000, fir, 20, 240/*TBD*/, shi08, SWR_DITHER_NS_SHIBATA}, + {48000, fir, 16, 250, shl48, SWR_DITHER_NS_LOW_SHIBATA}, + {44100, fir, 15, 250, shl44, SWR_DITHER_NS_LOW_SHIBATA}, + {44100, fir, 20, 383, shh44, SWR_DITHER_NS_HIGH_SHIBATA}, + { 0, fir, 0, 0, NULL, SWR_DITHER_NONE}, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/options.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/options.c new file mode 100644 index 000000000..00d4f7c1c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/options.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/opt.h" +#include "swresample_internal.h" + +#include + +#define C30DB M_SQRT2 +#define C15DB 1.189207115 +#define C__0DB 1.0 +#define C_15DB 0.840896415 +#define C_30DB M_SQRT1_2 +#define C_45DB 0.594603558 +#define C_60DB 0.5 + +#define OFFSET(x) offsetof(SwrContext,x) +#define PARAM AV_OPT_FLAG_AUDIO_PARAM + +static const AVOption options[]={ +{"ich" , "set input channel count" , OFFSET(user_in_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"in_channel_count" , "set input channel count" , OFFSET(user_in_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"och" , "set output channel count" , OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"out_channel_count" , "set output channel count" , OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"uch" , "set used channel count" , OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"used_channel_count" , "set used channel count" , OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"isr" , "set input sample rate" , OFFSET( in_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM}, +{"in_sample_rate" , "set input sample rate" , OFFSET( in_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM}, +{"osr" , "set output sample rate" , OFFSET(out_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM}, +{"out_sample_rate" , "set output sample rate" , OFFSET(out_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM}, +{"isf" , "set input sample format" , OFFSET( in_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"in_sample_fmt" , "set input sample format" , OFFSET( in_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"osf" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"out_sample_fmt" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"tsf" , "set internal sample format" , OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"internal_sample_fmt" , "set internal sample format" , OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"icl" , "set input channel layout" , OFFSET(user_in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, INT64_MIN, INT64_MAX , PARAM, "channel_layout"}, +{"in_channel_layout" , "set input channel layout" , OFFSET(user_in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, INT64_MIN, INT64_MAX , PARAM, "channel_layout"}, +{"ocl" , "set output channel layout" , OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, INT64_MIN, INT64_MAX , PARAM, "channel_layout"}, +{"out_channel_layout" , "set output channel layout" , OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, INT64_MIN, INT64_MAX , PARAM, "channel_layout"}, +{"clev" , "set center mix level" , OFFSET(clev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM}, +{"center_mix_level" , "set center mix level" , OFFSET(clev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM}, +{"slev" , "set surround mix level" , OFFSET(slev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM}, +{"surround_mix_level" , "set surround mix Level" , OFFSET(slev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM}, +{"lfe_mix_level" , "set LFE mix level" , OFFSET(lfe_mix_level ), AV_OPT_TYPE_FLOAT, {.dbl=0 }, -32 , 32 , PARAM}, +{"rmvol" , "set rematrix volume" , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0 }, -1000 , 1000 , PARAM}, +{"rematrix_volume" , "set rematrix volume" , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0 }, -1000 , 1000 , PARAM}, +{"rematrix_maxval" , "set rematrix maxval" , OFFSET(rematrix_maxval), AV_OPT_TYPE_FLOAT, {.dbl=0.0 }, 0 , 1000 , PARAM}, + +{"flags" , "set flags" , OFFSET(flags ), AV_OPT_TYPE_FLAGS, {.i64=0 }, 0 , UINT_MAX , PARAM, "flags"}, +{"swr_flags" , "set flags" , OFFSET(flags ), AV_OPT_TYPE_FLAGS, {.i64=0 }, 0 , UINT_MAX , PARAM, "flags"}, +{"res" , "force resampling" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_FLAG_RESAMPLE }, INT_MIN, INT_MAX , PARAM, "flags"}, + +{"dither_scale" , "set dither scale" , OFFSET(dither.scale ), AV_OPT_TYPE_FLOAT, {.dbl=1 }, 0 , INT_MAX , PARAM}, + +{"dither_method" , "set dither method" , OFFSET(user_dither_method),AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_DITHER_NB-1, PARAM, "dither_method"}, +{"rectangular" , "select rectangular dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_RECTANGULAR}, INT_MIN, INT_MAX , PARAM, "dither_method"}, +{"triangular" , "select triangular dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR }, INT_MIN, INT_MAX , PARAM, "dither_method"}, +{"triangular_hp" , "select triangular dither with high pass" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR_HIGHPASS }, INT_MIN, INT_MAX, PARAM, "dither_method"}, +{"lipshitz" , "select Lipshitz noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_LIPSHITZ}, INT_MIN, INT_MAX, PARAM, "dither_method"}, +{"shibata" , "select Shibata noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_SHIBATA }, INT_MIN, INT_MAX, PARAM, "dither_method"}, +{"low_shibata" , "select low Shibata noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_LOW_SHIBATA }, INT_MIN, INT_MAX, PARAM, "dither_method"}, +{"high_shibata" , "select high Shibata noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_HIGH_SHIBATA }, INT_MIN, INT_MAX, PARAM, "dither_method"}, +{"f_weighted" , "select f-weighted noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_F_WEIGHTED }, INT_MIN, INT_MAX, PARAM, "dither_method"}, +{"modified_e_weighted" , "select modified-e-weighted noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_MODIFIED_E_WEIGHTED }, INT_MIN, INT_MAX, PARAM, "dither_method"}, +{"improved_e_weighted" , "select improved-e-weighted noise shaping dither" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_NS_IMPROVED_E_WEIGHTED }, INT_MIN, INT_MAX, PARAM, "dither_method"}, + +{"filter_size" , "set swr resampling filter size", OFFSET(filter_size) , AV_OPT_TYPE_INT , {.i64=32 }, 0 , INT_MAX , PARAM }, +{"phase_shift" , "set swr resampling phase shift", OFFSET(phase_shift) , AV_OPT_TYPE_INT , {.i64=10 }, 0 , 24 , PARAM }, +{"linear_interp" , "enable linear interpolation" , OFFSET(linear_interp) , AV_OPT_TYPE_BOOL , {.i64=1 }, 0 , 1 , PARAM }, +{"exact_rational" , "enable exact rational" , OFFSET(exact_rational) , AV_OPT_TYPE_BOOL , {.i64=1 }, 0 , 1 , PARAM }, +{"cutoff" , "set cutoff frequency ratio" , OFFSET(cutoff) , AV_OPT_TYPE_DOUBLE,{.dbl=0. }, 0 , 1 , PARAM }, + +/* duplicate option in order to work with avconv */ +{"resample_cutoff" , "set cutoff frequency ratio" , OFFSET(cutoff) , AV_OPT_TYPE_DOUBLE,{.dbl=0. }, 0 , 1 , PARAM }, + +{"resampler" , "set resampling Engine" , OFFSET(engine) , AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_ENGINE_NB-1, PARAM, "resampler"}, +{"swr" , "select SW Resampler" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_ENGINE_SWR }, INT_MIN, INT_MAX , PARAM, "resampler"}, +{"soxr" , "select SoX Resampler" , 0 , AV_OPT_TYPE_CONST, {.i64=SWR_ENGINE_SOXR }, INT_MIN, INT_MAX , PARAM, "resampler"}, +{"precision" , "set soxr resampling precision (in bits)" + , OFFSET(precision) , AV_OPT_TYPE_DOUBLE,{.dbl=20.0 }, 15.0 , 33.0 , PARAM }, +{"cheby" , "enable soxr Chebyshev passband & higher-precision irrational ratio approximation" + , OFFSET(cheby) , AV_OPT_TYPE_BOOL , {.i64=0 }, 0 , 1 , PARAM }, +{"min_comp" , "set minimum difference between timestamps and audio data (in seconds) below which no timestamp compensation of either kind is applied" + , OFFSET(min_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=FLT_MAX }, 0 , FLT_MAX , PARAM }, +{"min_hard_comp" , "set minimum difference between timestamps and audio data (in seconds) to trigger padding/trimming the data." + , OFFSET(min_hard_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0.1 }, 0 , INT_MAX , PARAM }, +{"comp_duration" , "set duration (in seconds) over which data is stretched/squeezed to make it match the timestamps." + , OFFSET(soft_compensation_duration),AV_OPT_TYPE_FLOAT ,{.dbl=1 }, 0 , INT_MAX , PARAM }, +{"max_soft_comp" , "set maximum factor by which data is stretched/squeezed to make it match the timestamps." + , OFFSET(max_soft_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0 }, INT_MIN, INT_MAX , PARAM }, +{"async" , "simplified 1 parameter audio timestamp matching, 0(disabled), 1(filling and trimming), >1(maximum stretch/squeeze in samples per second)" + , OFFSET(async) , AV_OPT_TYPE_FLOAT ,{.dbl=0 }, INT_MIN, INT_MAX , PARAM }, +{"first_pts" , "Assume the first pts should be this value (in samples)." + , OFFSET(firstpts_in_samples), AV_OPT_TYPE_INT64 ,{.i64=AV_NOPTS_VALUE }, INT64_MIN,INT64_MAX, PARAM }, + +{ "matrix_encoding" , "set matrixed stereo encoding" , OFFSET(matrix_encoding), AV_OPT_TYPE_INT ,{.i64 = AV_MATRIX_ENCODING_NONE}, AV_MATRIX_ENCODING_NONE, AV_MATRIX_ENCODING_NB-1, PARAM, "matrix_encoding" }, + { "none", "select none", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_NONE }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" }, + { "dolby", "select Dolby", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" }, + { "dplii", "select Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" }, + +{ "filter_type" , "select swr filter type" , OFFSET(filter_type) , AV_OPT_TYPE_INT , { .i64 = SWR_FILTER_TYPE_KAISER }, SWR_FILTER_TYPE_CUBIC, SWR_FILTER_TYPE_KAISER, PARAM, "filter_type" }, + { "cubic" , "select cubic" , 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_CUBIC }, INT_MIN, INT_MAX, PARAM, "filter_type" }, + { "blackman_nuttall", "select Blackman Nuttall windowed sinc", 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" }, + { "kaiser" , "select Kaiser windowed sinc" , 0 , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_KAISER }, INT_MIN, INT_MAX, PARAM, "filter_type" }, + +{ "kaiser_beta" , "set swr Kaiser window beta" , OFFSET(kaiser_beta) , AV_OPT_TYPE_DOUBLE , {.dbl=9 }, 2 , 16 , PARAM }, + +{ "output_sample_bits" , "set swr number of output sample bits", OFFSET(dither.output_sample_bits), AV_OPT_TYPE_INT , {.i64=0 }, 0 , 64 , PARAM }, +{0} +}; + +static const char* context_to_name(void* ptr) { + return "SWR"; +} + +static const AVClass av_class = { + .class_name = "SWResampler", + .item_name = context_to_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .log_level_offset_offset = OFFSET(log_level_offset), + .parent_log_context_offset = OFFSET(log_ctx), + .category = AV_CLASS_CATEGORY_SWRESAMPLER, +}; + +const AVClass *swr_get_class(void) +{ + return &av_class; +} + +av_cold struct SwrContext *swr_alloc(void){ + SwrContext *s= av_mallocz(sizeof(SwrContext)); + if(s){ + s->av_class= &av_class; + av_opt_set_defaults(s); + } + return s; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/rematrix.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/rematrix.c new file mode 100644 index 000000000..6b5feaa07 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/rematrix.c @@ -0,0 +1,576 @@ +/* + * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "swresample_internal.h" +#include "libavutil/avassert.h" +#include "libavutil/channel_layout.h" + +#define TEMPLATE_REMATRIX_FLT +#include "rematrix_template.c" +#undef TEMPLATE_REMATRIX_FLT + +#define TEMPLATE_REMATRIX_DBL +#include "rematrix_template.c" +#undef TEMPLATE_REMATRIX_DBL + +#define TEMPLATE_REMATRIX_S16 +#include "rematrix_template.c" +#define TEMPLATE_CLIP +#include "rematrix_template.c" +#undef TEMPLATE_CLIP +#undef TEMPLATE_REMATRIX_S16 + +#define TEMPLATE_REMATRIX_S32 +#include "rematrix_template.c" +#undef TEMPLATE_REMATRIX_S32 + +#define FRONT_LEFT 0 +#define FRONT_RIGHT 1 +#define FRONT_CENTER 2 +#define LOW_FREQUENCY 3 +#define BACK_LEFT 4 +#define BACK_RIGHT 5 +#define FRONT_LEFT_OF_CENTER 6 +#define FRONT_RIGHT_OF_CENTER 7 +#define BACK_CENTER 8 +#define SIDE_LEFT 9 +#define SIDE_RIGHT 10 +#define TOP_CENTER 11 +#define TOP_FRONT_LEFT 12 +#define TOP_FRONT_CENTER 13 +#define TOP_FRONT_RIGHT 14 +#define TOP_BACK_LEFT 15 +#define TOP_BACK_CENTER 16 +#define TOP_BACK_RIGHT 17 +#define NUM_NAMED_CHANNELS 18 + +int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride) +{ + int nb_in, nb_out, in, out; + + if (!s || s->in_convert) // s needs to be allocated but not initialized + return AVERROR(EINVAL); + memset(s->matrix, 0, sizeof(s->matrix)); + memset(s->matrix_flt, 0, sizeof(s->matrix_flt)); + nb_in = (s->user_in_ch_count > 0) ? s->user_in_ch_count : + av_get_channel_layout_nb_channels(s->user_in_ch_layout); + nb_out = (s->user_out_ch_count > 0) ? s->user_out_ch_count : + av_get_channel_layout_nb_channels(s->user_out_ch_layout); + for (out = 0; out < nb_out; out++) { + for (in = 0; in < nb_in; in++) + s->matrix_flt[out][in] = s->matrix[out][in] = matrix[in]; + matrix += stride; + } + s->rematrix_custom = 1; + return 0; +} + +static int even(int64_t layout){ + if(!layout) return 1; + if(layout&(layout-1)) return 1; + return 0; +} + +static int clean_layout(void *s, int64_t layout){ + if(layout && layout != AV_CH_FRONT_CENTER && !(layout&(layout-1))) { + char buf[128]; + av_get_channel_layout_string(buf, sizeof(buf), -1, layout); + av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf); + return AV_CH_FRONT_CENTER; + } + + return layout; +} + +static int sane_layout(int64_t layout){ + if(!(layout & AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker + return 0; + if(!even(layout & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT))) // no asymetric front + return 0; + if(!even(layout & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT))) // no asymetric side + return 0; + if(!even(layout & (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT))) + return 0; + if(!even(layout & (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER))) + return 0; + if(av_get_channel_layout_nb_channels(layout) >= SWR_CH_MAX) + return 0; + + return 1; +} + +av_cold int swr_build_matrix(uint64_t in_ch_layout_param, uint64_t out_ch_layout_param, + double center_mix_level, double surround_mix_level, + double lfe_mix_level, double maxval, + double rematrix_volume, double *matrix_param, + int stride, enum AVMatrixEncoding matrix_encoding, void *log_context) +{ + int i, j, out_i; + double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}}; + int64_t unaccounted, in_ch_layout, out_ch_layout; + double maxcoef=0; + char buf[128]; + + in_ch_layout = clean_layout(log_context, in_ch_layout_param); + out_ch_layout = clean_layout(log_context, out_ch_layout_param); + + if( out_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX + && (in_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0 + ) + out_ch_layout = AV_CH_LAYOUT_STEREO; + + if( in_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX + && (out_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0 + ) + in_ch_layout = AV_CH_LAYOUT_STEREO; + + if(!sane_layout(in_ch_layout)){ + av_get_channel_layout_string(buf, sizeof(buf), -1, in_ch_layout_param); + av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf); + return AVERROR(EINVAL); + } + + if(!sane_layout(out_ch_layout)){ + av_get_channel_layout_string(buf, sizeof(buf), -1, out_ch_layout_param); + av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf); + return AVERROR(EINVAL); + } + + for(i=0; i maxval || rematrix_volume < 0){ + maxcoef /= maxval; + for(i=0; i 0){ + for(i=0; irematrix_maxval > 0) { + maxval = s->rematrix_maxval; + } else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT + || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) { + maxval = 1.0; + } else + maxval = INT_MAX; + + memset(s->matrix, 0, sizeof(s->matrix)); + ret = swr_build_matrix(s->in_ch_layout, s->out_ch_layout, + s->clev, s->slev, s->lfe_mix_level, + maxval, s->rematrix_volume, (double*)s->matrix, + s->matrix[1] - s->matrix[0], s->matrix_encoding, s); + + if (ret >= 0 && s->int_sample_fmt == AV_SAMPLE_FMT_FLTP) { + int i, j; + for (i = 0; i < FF_ARRAY_ELEMS(s->matrix[0]); i++) + for (j = 0; j < FF_ARRAY_ELEMS(s->matrix[0]); j++) + s->matrix_flt[i][j] = s->matrix[i][j]; + } + + return ret; +} + +av_cold int swri_rematrix_init(SwrContext *s){ + int i, j; + int nb_in = s->used_ch_count; + int nb_out = s->out.ch_count; + + s->mix_any_f = NULL; + + if (!s->rematrix_custom) { + int r = auto_matrix(s); + if (r) + return r; + } + if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){ + int maxsum = 0; + s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int)); + s->native_one = av_mallocz(sizeof(int)); + if (!s->native_matrix || !s->native_one) + return AVERROR(ENOMEM); + for (i = 0; i < nb_out; i++) { + double rem = 0; + int sum = 0; + + for (j = 0; j < nb_in; j++) { + double target = s->matrix[i][j] * 32768 + rem; + ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target); + rem += target - ((int*)s->native_matrix)[i * nb_in + j]; + sum += FFABS(((int*)s->native_matrix)[i * nb_in + j]); + } + maxsum = FFMAX(maxsum, sum); + } + *((int*)s->native_one) = 32768; + if (maxsum <= 32768) { + s->mix_1_1_f = (mix_1_1_func_type*)copy_s16; + s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16; + s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s); + } else { + s->mix_1_1_f = (mix_1_1_func_type*)copy_clip_s16; + s->mix_2_1_f = (mix_2_1_func_type*)sum2_clip_s16; + s->mix_any_f = (mix_any_func_type*)get_mix_any_func_clip_s16(s); + } + }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){ + s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float)); + s->native_one = av_mallocz(sizeof(float)); + if (!s->native_matrix || !s->native_one) + return AVERROR(ENOMEM); + for (i = 0; i < nb_out; i++) + for (j = 0; j < nb_in; j++) + ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; + *((float*)s->native_one) = 1.0; + s->mix_1_1_f = (mix_1_1_func_type*)copy_float; + s->mix_2_1_f = (mix_2_1_func_type*)sum2_float; + s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s); + }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){ + s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double)); + s->native_one = av_mallocz(sizeof(double)); + if (!s->native_matrix || !s->native_one) + return AVERROR(ENOMEM); + for (i = 0; i < nb_out; i++) + for (j = 0; j < nb_in; j++) + ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; + *((double*)s->native_one) = 1.0; + s->mix_1_1_f = (mix_1_1_func_type*)copy_double; + s->mix_2_1_f = (mix_2_1_func_type*)sum2_double; + s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s); + }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){ + s->native_one = av_mallocz(sizeof(int)); + if (!s->native_one) + return AVERROR(ENOMEM); + s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int)); + if (!s->native_matrix) { + av_freep(&s->native_one); + return AVERROR(ENOMEM); + } + for (i = 0; i < nb_out; i++) { + double rem = 0; + + for (j = 0; j < nb_in; j++) { + double target = s->matrix[i][j] * 32768 + rem; + ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target); + rem += target - ((int*)s->native_matrix)[i * nb_in + j]; + } + } + *((int*)s->native_one) = 32768; + s->mix_1_1_f = (mix_1_1_func_type*)copy_s32; + s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32; + s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s); + }else + av_assert0(0); + //FIXME quantize for integeres + for (i = 0; i < SWR_CH_MAX; i++) { + int ch_in=0; + for (j = 0; j < SWR_CH_MAX; j++) { + s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768); + if(s->matrix[i][j]) + s->matrix_ch[i][++ch_in]= j; + } + s->matrix_ch[i][0]= ch_in; + } + + if(HAVE_X86ASM && HAVE_MMX) + return swri_rematrix_init_x86(s); + + return 0; +} + +av_cold void swri_rematrix_free(SwrContext *s){ + av_freep(&s->native_matrix); + av_freep(&s->native_one); + av_freep(&s->native_simd_matrix); + av_freep(&s->native_simd_one); +} + +int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){ + int out_i, in_i, i, j; + int len1 = 0; + int off = 0; + + if(s->mix_any_f) { + s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len); + return 0; + } + + if(s->mix_2_1_simd || s->mix_1_1_simd){ + len1= len&~15; + off = len1 * out->bps; + } + + av_assert0(!s->out_ch_layout || out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout)); + av_assert0(!s-> in_ch_layout || in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout)); + + for(out_i=0; out_ich_count; out_i++){ + switch(s->matrix_ch[out_i][0]){ + case 0: + if(mustcopy) + memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt)); + break; + case 1: + in_i= s->matrix_ch[out_i][1]; + if(s->matrix[out_i][in_i]!=1.0){ + if(s->mix_1_1_simd && len1) + s->mix_1_1_simd(out->ch[out_i] , in->ch[in_i] , s->native_simd_matrix, in->ch_count*out_i + in_i, len1); + if(len != len1) + s->mix_1_1_f (out->ch[out_i]+off, in->ch[in_i]+off, s->native_matrix, in->ch_count*out_i + in_i, len-len1); + }else if(mustcopy){ + memcpy(out->ch[out_i], in->ch[in_i], len*out->bps); + }else{ + out->ch[out_i]= in->ch[in_i]; + } + break; + case 2: { + int in_i1 = s->matrix_ch[out_i][1]; + int in_i2 = s->matrix_ch[out_i][2]; + if(s->mix_2_1_simd && len1) + s->mix_2_1_simd(out->ch[out_i] , in->ch[in_i1] , in->ch[in_i2] , s->native_simd_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1); + else + s->mix_2_1_f (out->ch[out_i] , in->ch[in_i1] , in->ch[in_i2] , s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1); + if(len != len1) + s->mix_2_1_f (out->ch[out_i]+off, in->ch[in_i1]+off, in->ch[in_i2]+off, s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len-len1); + break;} + default: + if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){ + for(i=0; imatrix_ch[out_i][0]; j++){ + in_i= s->matrix_ch[out_i][1+j]; + v+= ((float*)in->ch[in_i])[i] * s->matrix_flt[out_i][in_i]; + } + ((float*)out->ch[out_i])[i]= v; + } + }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){ + for(i=0; imatrix_ch[out_i][0]; j++){ + in_i= s->matrix_ch[out_i][1+j]; + v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i]; + } + ((double*)out->ch[out_i])[i]= v; + } + }else{ + for(i=0; imatrix_ch[out_i][0]; j++){ + in_i= s->matrix_ch[out_i][1+j]; + v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i]; + } + ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15; + } + } + } + } + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/rematrix_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/rematrix_template.c new file mode 100644 index 000000000..add65e315 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/rematrix_template.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if defined(TEMPLATE_REMATRIX_FLT) +# define R(x) x +# define SAMPLE float +# define COEFF float +# define INTER float +# define RENAME(x) x ## _float +#elif defined(TEMPLATE_REMATRIX_DBL) +# define R(x) x +# define SAMPLE double +# define COEFF double +# define INTER double +# define RENAME(x) x ## _double +#elif defined(TEMPLATE_REMATRIX_S16) +# define SAMPLE int16_t +# define COEFF int +# define INTER int +# ifdef TEMPLATE_CLIP +# define R(x) av_clip_int16(((x) + 16384)>>15) +# define RENAME(x) x ## _clip_s16 +# else +# define R(x) (((x) + 16384)>>15) +# define RENAME(x) x ## _s16 +# endif +#elif defined(TEMPLATE_REMATRIX_S32) +# define R(x) (((x) + 16384)>>15) +# define SAMPLE int32_t +# define COEFF int +# define INTER int64_t +# define RENAME(x) x ## _s32 +#endif + +typedef void (RENAME(mix_any_func_type))(SAMPLE **out, const SAMPLE **in1, COEFF *coeffp, integer len); + +static void RENAME(sum2)(SAMPLE *out, const SAMPLE *in1, const SAMPLE *in2, COEFF *coeffp, integer index1, integer index2, integer len){ + int i; + INTER coeff1 = coeffp[index1]; + INTER coeff2 = coeffp[index2]; + + for(i=0; iout_ch_layout == AV_CH_LAYOUT_STEREO && (s->in_ch_layout == AV_CH_LAYOUT_5POINT1 || s->in_ch_layout == AV_CH_LAYOUT_5POINT1_BACK) + && s->matrix[0][2] == s->matrix[1][2] && s->matrix[0][3] == s->matrix[1][3] + && !s->matrix[0][1] && !s->matrix[0][5] && !s->matrix[1][0] && !s->matrix[1][4] + ) + return RENAME(mix6to2); + + if( s->out_ch_layout == AV_CH_LAYOUT_STEREO && s->in_ch_layout == AV_CH_LAYOUT_7POINT1 + && s->matrix[0][2] == s->matrix[1][2] && s->matrix[0][3] == s->matrix[1][3] + && !s->matrix[0][1] && !s->matrix[0][5] && !s->matrix[1][0] && !s->matrix[1][4] + && !s->matrix[0][7] && !s->matrix[1][6] + ) + return RENAME(mix8to2); + + return NULL; +} + +#undef R +#undef SAMPLE +#undef COEFF +#undef INTER +#undef RENAME diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample.c new file mode 100644 index 000000000..df49505bf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample.c @@ -0,0 +1,622 @@ +/* + * audio resampling + * Copyright (c) 2004-2012 Michael Niedermayer + * bessel function: Copyright (c) 2006 Xiaogang Zhang + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio resampling + * @author Michael Niedermayer + */ + +#include "libavutil/avassert.h" +#include "resample.h" + +static inline double eval_poly(const double *coeff, int size, double x) { + double sum = coeff[size-1]; + int i; + for (i = size-2; i >= 0; --i) { + sum *= x; + sum += coeff[i]; + } + return sum; +} + +/** + * 0th order modified bessel function of the first kind. + * Algorithm taken from the Boost project, source: + * https://searchcode.com/codesearch/view/14918379/ + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0 (see notice below). + * Boost Software License - Version 1.0 - August 17th, 2003 +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + */ + +static double bessel(double x) { +// Modified Bessel function of the first kind of order zero +// minimax rational approximations on intervals, see +// Blair and Edwards, Chalk River Report AECL-4928, 1974 + static const double p1[] = { + -2.2335582639474375249e+15, + -5.5050369673018427753e+14, + -3.2940087627407749166e+13, + -8.4925101247114157499e+11, + -1.1912746104985237192e+10, + -1.0313066708737980747e+08, + -5.9545626019847898221e+05, + -2.4125195876041896775e+03, + -7.0935347449210549190e+00, + -1.5453977791786851041e-02, + -2.5172644670688975051e-05, + -3.0517226450451067446e-08, + -2.6843448573468483278e-11, + -1.5982226675653184646e-14, + -5.2487866627945699800e-18, + }; + static const double q1[] = { + -2.2335582639474375245e+15, + 7.8858692566751002988e+12, + -1.2207067397808979846e+10, + 1.0377081058062166144e+07, + -4.8527560179962773045e+03, + 1.0, + }; + static const double p2[] = { + -2.2210262233306573296e-04, + 1.3067392038106924055e-02, + -4.4700805721174453923e-01, + 5.5674518371240761397e+00, + -2.3517945679239481621e+01, + 3.1611322818701131207e+01, + -9.6090021968656180000e+00, + }; + static const double q2[] = { + -5.5194330231005480228e-04, + 3.2547697594819615062e-02, + -1.1151759188741312645e+00, + 1.3982595353892851542e+01, + -6.0228002066743340583e+01, + 8.5539563258012929600e+01, + -3.1446690275135491500e+01, + 1.0, + }; + double y, r, factor; + if (x == 0) + return 1.0; + x = fabs(x); + if (x <= 15) { + y = x * x; + return eval_poly(p1, FF_ARRAY_ELEMS(p1), y) / eval_poly(q1, FF_ARRAY_ELEMS(q1), y); + } + else { + y = 1 / x - 1.0 / 15; + r = eval_poly(p2, FF_ARRAY_ELEMS(p2), y) / eval_poly(q2, FF_ARRAY_ELEMS(q2), y); + factor = exp(x) / sqrt(x); + return factor * r; + } +} + +/** + * builds a polyphase filterbank. + * @param factor resampling factor + * @param scale wanted sum of coefficients for each filter + * @param filter_type filter type + * @param kaiser_beta kaiser window beta + * @return 0 on success, negative on error + */ +static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale, + int filter_type, double kaiser_beta){ + int ph, i; + int ph_nb = phase_count % 2 ? phase_count : phase_count / 2 + 1; + double x, y, w, t, s; + double *tab = av_malloc_array(tap_count+1, sizeof(*tab)); + double *sin_lut = av_malloc_array(ph_nb, sizeof(*sin_lut)); + const int center= (tap_count-1)/2; + double norm = 0; + int ret = AVERROR(ENOMEM); + + if (!tab || !sin_lut) + goto fail; + + av_assert0(tap_count == 1 || tap_count % 2 == 0); + + /* if upsampling, only need to interpolate, no filter */ + if (factor > 1.0) + factor = 1.0; + + if (factor == 1.0) { + for (ph = 0; ph < ph_nb; ph++) + sin_lut[ph] = sin(M_PI * ph / phase_count) * (center & 1 ? 1 : -1); + } + for(ph = 0; ph < ph_nb; ph++) { + s = sin_lut[ph]; + for(i=0;iformat){ + case AV_SAMPLE_FMT_S16P: + for(i=0;ifilter_bank); + av_freep(cc); +} + +static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear, + double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta, + double precision, int cheby, int exact_rational) +{ + double cutoff = cutoff0? cutoff0 : 0.97; + double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); + int phase_count= 1< 1) + filter_length = FFALIGN(filter_length, 2); + + if (exact_rational) { + int phase_count_exact, phase_count_exact_den; + + av_reduce(&phase_count_exact, &phase_count_exact_den, out_rate, in_rate, INT_MAX); + if (phase_count_exact <= phase_count) { + phase_count_compensation = phase_count_exact * (phase_count / phase_count_exact); + phase_count = phase_count_exact; + } + } + + if (!c || c->phase_count != phase_count || c->linear!=linear || c->factor != factor + || c->filter_length != filter_length || c->format != format + || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) { + resample_free(&c); + c = av_mallocz(sizeof(*c)); + if (!c) + return NULL; + + c->format= format; + + c->felem_size= av_get_bytes_per_sample(c->format); + + switch(c->format){ + case AV_SAMPLE_FMT_S16P: + c->filter_shift = 15; + break; + case AV_SAMPLE_FMT_S32P: + c->filter_shift = 30; + break; + case AV_SAMPLE_FMT_FLTP: + case AV_SAMPLE_FMT_DBLP: + c->filter_shift = 0; + break; + default: + av_log(NULL, AV_LOG_ERROR, "Unsupported sample format\n"); + av_assert0(0); + } + + if (filter_size/factor > INT32_MAX/256) { + av_log(NULL, AV_LOG_ERROR, "Filter length too large\n"); + goto error; + } + + c->phase_count = phase_count; + c->linear = linear; + c->factor = factor; + c->filter_length = filter_length; + c->filter_alloc = FFALIGN(c->filter_length, 8); + c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size); + c->filter_type = filter_type; + c->kaiser_beta = kaiser_beta; + c->phase_count_compensation = phase_count_compensation; + if (!c->filter_bank) + goto error; + if (build_filter(c, (void*)c->filter_bank, factor, c->filter_length, c->filter_alloc, phase_count, 1<filter_shift, filter_type, kaiser_beta)) + goto error; + memcpy(c->filter_bank + (c->filter_alloc*phase_count+1)*c->felem_size, c->filter_bank, (c->filter_alloc-1)*c->felem_size); + memcpy(c->filter_bank + (c->filter_alloc*phase_count )*c->felem_size, c->filter_bank + (c->filter_alloc - 1)*c->felem_size, c->felem_size); + } + + c->compensation_distance= 0; + if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2)) + goto error; + while (c->dst_incr < (1<<20) && c->src_incr < (1<<20)) { + c->dst_incr *= 2; + c->src_incr *= 2; + } + c->ideal_dst_incr = c->dst_incr; + c->dst_incr_div = c->dst_incr / c->src_incr; + c->dst_incr_mod = c->dst_incr % c->src_incr; + + c->index= -phase_count*((c->filter_length-1)/2); + c->frac= 0; + + swri_resample_dsp_init(c); + + return c; +error: + av_freep(&c->filter_bank); + av_free(c); + return NULL; +} + +static int rebuild_filter_bank_with_compensation(ResampleContext *c) +{ + uint8_t *new_filter_bank; + int new_src_incr, new_dst_incr; + int phase_count = c->phase_count_compensation; + int ret; + + if (phase_count == c->phase_count) + return 0; + + av_assert0(!c->frac && !c->dst_incr_mod); + + new_filter_bank = av_calloc(c->filter_alloc, (phase_count + 1) * c->felem_size); + if (!new_filter_bank) + return AVERROR(ENOMEM); + + ret = build_filter(c, new_filter_bank, c->factor, c->filter_length, c->filter_alloc, + phase_count, 1 << c->filter_shift, c->filter_type, c->kaiser_beta); + if (ret < 0) { + av_freep(&new_filter_bank); + return ret; + } + memcpy(new_filter_bank + (c->filter_alloc*phase_count+1)*c->felem_size, new_filter_bank, (c->filter_alloc-1)*c->felem_size); + memcpy(new_filter_bank + (c->filter_alloc*phase_count )*c->felem_size, new_filter_bank + (c->filter_alloc - 1)*c->felem_size, c->felem_size); + + if (!av_reduce(&new_src_incr, &new_dst_incr, c->src_incr, + c->dst_incr * (int64_t)(phase_count/c->phase_count), INT32_MAX/2)) + { + av_freep(&new_filter_bank); + return AVERROR(EINVAL); + } + + c->src_incr = new_src_incr; + c->dst_incr = new_dst_incr; + while (c->dst_incr < (1<<20) && c->src_incr < (1<<20)) { + c->dst_incr *= 2; + c->src_incr *= 2; + } + c->ideal_dst_incr = c->dst_incr; + c->dst_incr_div = c->dst_incr / c->src_incr; + c->dst_incr_mod = c->dst_incr % c->src_incr; + c->index *= phase_count / c->phase_count; + c->phase_count = phase_count; + av_freep(&c->filter_bank); + c->filter_bank = new_filter_bank; + return 0; +} + +static int set_compensation(ResampleContext *c, int sample_delta, int compensation_distance){ + int ret; + + if (compensation_distance && sample_delta) { + ret = rebuild_filter_bank_with_compensation(c); + if (ret < 0) + return ret; + } + + c->compensation_distance= compensation_distance; + if (compensation_distance) + c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance; + else + c->dst_incr = c->ideal_dst_incr; + + c->dst_incr_div = c->dst_incr / c->src_incr; + c->dst_incr_mod = c->dst_incr % c->src_incr; + + return 0; +} + +static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){ + int i; + int av_unused mm_flags = av_get_cpu_flags(); + int need_emms = c->format == AV_SAMPLE_FMT_S16P && ARCH_X86_32 && + (mm_flags & (AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE2)) == AV_CPU_FLAG_MMX2; + int64_t max_src_size = (INT64_MAX/2 / c->phase_count) / c->src_incr; + + if (c->compensation_distance) + dst_size = FFMIN(dst_size, c->compensation_distance); + src_size = FFMIN(src_size, max_src_size); + + *consumed = 0; + + if (c->filter_length == 1 && c->phase_count == 1) { + int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*c->index; + int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; + int new_size = (src_size * (int64_t)c->src_incr - c->frac + c->dst_incr - 1) / c->dst_incr; + + dst_size = FFMAX(FFMIN(dst_size, new_size), 0); + if (dst_size > 0) { + for (i = 0; i < dst->ch_count; i++) { + c->dsp.resample_one(dst->ch[i], src->ch[i], dst_size, index2, incr); + if (i+1 == dst->ch_count) { + c->index += dst_size * c->dst_incr_div; + c->index += (c->frac + dst_size * (int64_t)c->dst_incr_mod) / c->src_incr; + av_assert2(c->index >= 0); + *consumed = c->index; + c->frac = (c->frac + dst_size * (int64_t)c->dst_incr_mod) % c->src_incr; + c->index = 0; + } + } + } + } else { + int64_t end_index = (1LL + src_size - c->filter_length) * c->phase_count; + int64_t delta_frac = (end_index - c->index) * c->src_incr - c->frac; + int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr; + int (*resample_func)(struct ResampleContext *c, void *dst, + const void *src, int n, int update_ctx); + + dst_size = FFMAX(FFMIN(dst_size, delta_n), 0); + if (dst_size > 0) { + /* resample_linear and resample_common should have same behavior + * when frac and dst_incr_mod are zero */ + resample_func = (c->linear && (c->frac || c->dst_incr_mod)) ? + c->dsp.resample_linear : c->dsp.resample_common; + for (i = 0; i < dst->ch_count; i++) + *consumed = resample_func(c, dst->ch[i], src->ch[i], dst_size, i+1 == dst->ch_count); + } + } + + if(need_emms) + emms_c(); + + if (c->compensation_distance) { + c->compensation_distance -= dst_size; + if (!c->compensation_distance) { + c->dst_incr = c->ideal_dst_incr; + c->dst_incr_div = c->dst_incr / c->src_incr; + c->dst_incr_mod = c->dst_incr % c->src_incr; + } + } + + return dst_size; +} + +static int64_t get_delay(struct SwrContext *s, int64_t base){ + ResampleContext *c = s->resample; + int64_t num = s->in_buffer_count - (c->filter_length-1)/2; + num *= c->phase_count; + num -= c->index; + num *= c->src_incr; + num -= c->frac; + return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr * c->phase_count); +} + +static int64_t get_out_samples(struct SwrContext *s, int in_samples) { + ResampleContext *c = s->resample; + // The + 2 are added to allow implementations to be slightly inaccurate, they should not be needed currently. + // They also make it easier to proof that changes and optimizations do not + // break the upper bound. + int64_t num = s->in_buffer_count + 2LL + in_samples; + num *= c->phase_count; + num -= c->index; + num = av_rescale_rnd(num, s->out_sample_rate, ((int64_t)s->in_sample_rate) * c->phase_count, AV_ROUND_UP) + 2; + + if (c->compensation_distance) { + if (num > INT_MAX) + return AVERROR(EINVAL); + + num = FFMAX(num, (num * c->ideal_dst_incr - 1) / c->dst_incr + 1); + } + return num; +} + +static int resample_flush(struct SwrContext *s) { + ResampleContext *c = s->resample; + AudioData *a= &s->in_buffer; + int i, j, ret; + int reflection = (FFMIN(s->in_buffer_count, c->filter_length) + 1) / 2; + + if((ret = swri_realloc_audio(a, s->in_buffer_index + s->in_buffer_count + reflection)) < 0) + return ret; + av_assert0(a->planar); + for(i=0; ich_count; i++){ + for(j=0; jch[i] + (s->in_buffer_index+s->in_buffer_count+j )*a->bps, + a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps); + } + } + s->in_buffer_count += reflection; + return 0; +} + +// in fact the whole handle multiple ridiculously small buffers might need more thinking... +static int invert_initial_buffer(ResampleContext *c, AudioData *dst, const AudioData *src, + int in_count, int *out_idx, int *out_sz) +{ + int n, ch, num = FFMIN(in_count + *out_sz, c->filter_length + 1), res; + + if (c->index >= 0) + return 0; + + if ((res = swri_realloc_audio(dst, c->filter_length * 2 + 1)) < 0) + return res; + + // copy + for (n = *out_sz; n < num; n++) { + for (ch = 0; ch < src->ch_count; ch++) { + memcpy(dst->ch[ch] + ((c->filter_length + n) * c->felem_size), + src->ch[ch] + ((n - *out_sz) * c->felem_size), c->felem_size); + } + } + + // if not enough data is in, return and wait for more + if (num < c->filter_length + 1) { + *out_sz = num; + *out_idx = c->filter_length; + return INT_MAX; + } + + // else invert + for (n = 1; n <= c->filter_length; n++) { + for (ch = 0; ch < src->ch_count; ch++) { + memcpy(dst->ch[ch] + ((c->filter_length - n) * c->felem_size), + dst->ch[ch] + ((c->filter_length + n) * c->felem_size), + c->felem_size); + } + } + + res = num - *out_sz; + *out_idx = c->filter_length; + while (c->index < 0) { + --*out_idx; + c->index += c->phase_count; + } + *out_sz = FFMAX(*out_sz + c->filter_length, + 1 + c->filter_length * 2) - *out_idx; + + return FFMAX(res, 0); +} + +struct Resampler const swri_resampler={ + resample_init, + resample_free, + multiple_resample, + resample_flush, + set_compensation, + get_delay, + invert_initial_buffer, + get_out_samples, +}; diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample.h b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample.h new file mode 100644 index 000000000..1731dad3c --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample.h @@ -0,0 +1,68 @@ +/* + * audio resampling + * Copyright (c) 2004-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWRESAMPLE_RESAMPLE_H +#define SWRESAMPLE_RESAMPLE_H + +#include "libavutil/log.h" +#include "libavutil/samplefmt.h" + +#include "swresample_internal.h" + +typedef struct ResampleContext { + const AVClass *av_class; + uint8_t *filter_bank; + int filter_length; + int filter_alloc; + int ideal_dst_incr; + int dst_incr; + int dst_incr_div; + int dst_incr_mod; + int index; + int frac; + int src_incr; + int compensation_distance; + int phase_count; + int linear; + enum SwrFilterType filter_type; + double kaiser_beta; + double factor; + enum AVSampleFormat format; + int felem_size; + int filter_shift; + int phase_count_compensation; /* desired phase_count when compensation is enabled */ + + struct { + void (*resample_one)(void *dst, const void *src, + int n, int64_t index, int64_t incr); + int (*resample_common)(struct ResampleContext *c, void *dst, + const void *src, int n, int update_ctx); + int (*resample_linear)(struct ResampleContext *c, void *dst, + const void *src, int n, int update_ctx); + } dsp; +} ResampleContext; + +void swri_resample_dsp_init(ResampleContext *c); +void swri_resample_dsp_x86_init(ResampleContext *c); +void swri_resample_dsp_arm_init(ResampleContext *c); +void swri_resample_dsp_aarch64_init(ResampleContext *c); + +#endif /* SWRESAMPLE_RESAMPLE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample_dsp.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample_dsp.c new file mode 100644 index 000000000..b2424eb6f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample_dsp.c @@ -0,0 +1,74 @@ +/* + * audio resampling + * Copyright (c) 2004-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio resampling + * @author Michael Niedermayer + */ + +#include "resample.h" + +#define TEMPLATE_RESAMPLE_S16 +#include "resample_template.c" +#undef TEMPLATE_RESAMPLE_S16 + +#define TEMPLATE_RESAMPLE_S32 +#include "resample_template.c" +#undef TEMPLATE_RESAMPLE_S32 + +#define TEMPLATE_RESAMPLE_FLT +#include "resample_template.c" +#undef TEMPLATE_RESAMPLE_FLT + +#define TEMPLATE_RESAMPLE_DBL +#include "resample_template.c" +#undef TEMPLATE_RESAMPLE_DBL + +void swri_resample_dsp_init(ResampleContext *c) +{ + switch(c->format){ + case AV_SAMPLE_FMT_S16P: + c->dsp.resample_one = resample_one_int16; + c->dsp.resample_common = resample_common_int16; + c->dsp.resample_linear = resample_linear_int16; + break; + case AV_SAMPLE_FMT_S32P: + c->dsp.resample_one = resample_one_int32; + c->dsp.resample_common = resample_common_int32; + c->dsp.resample_linear = resample_linear_int32; + break; + case AV_SAMPLE_FMT_FLTP: + c->dsp.resample_one = resample_one_float; + c->dsp.resample_common = resample_common_float; + c->dsp.resample_linear = resample_linear_float; + break; + case AV_SAMPLE_FMT_DBLP: + c->dsp.resample_one = resample_one_double; + c->dsp.resample_common = resample_common_double; + c->dsp.resample_linear = resample_linear_double; + break; + } + + if (ARCH_X86) swri_resample_dsp_x86_init(c); + else if (ARCH_ARM) swri_resample_dsp_arm_init(c); + else if (ARCH_AARCH64) swri_resample_dsp_aarch64_init(c); +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample_template.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample_template.c new file mode 100644 index 000000000..4c227b994 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/resample_template.c @@ -0,0 +1,212 @@ +/* + * audio resampling + * Copyright (c) 2004-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio resampling + * @author Michael Niedermayer + */ + +#if defined(TEMPLATE_RESAMPLE_DBL) + +# define RENAME(N) N ## _double +# define FILTER_SHIFT 0 +# define DELEM double +# define FELEM double +# define FELEM2 double +# define FOFFSET 0 +# define OUT(d, v) d = v + +#elif defined(TEMPLATE_RESAMPLE_FLT) + +# define RENAME(N) N ## _float +# define FILTER_SHIFT 0 +# define DELEM float +# define FELEM float +# define FELEM2 float +# define FOFFSET 0 +# define OUT(d, v) d = v + +#elif defined(TEMPLATE_RESAMPLE_S32) + +# define RENAME(N) N ## _int32 +# define FILTER_SHIFT 30 +# define DELEM int32_t +# define FELEM int32_t +# define FELEM2 int64_t +# define FELEM_MAX INT32_MAX +# define FELEM_MIN INT32_MIN +# define FOFFSET (1<<(FILTER_SHIFT-1)) +# define OUT(d, v) (d) = av_clipl_int32((v)>>FILTER_SHIFT) + +#elif defined(TEMPLATE_RESAMPLE_S16) + +# define RENAME(N) N ## _int16 +# define FILTER_SHIFT 15 +# define DELEM int16_t +# define FELEM int16_t +# define FELEM2 int32_t +# define FELEML int64_t +# define FELEM_MAX INT16_MAX +# define FELEM_MIN INT16_MIN +# define FOFFSET (1<<(FILTER_SHIFT-1)) +# define OUT(d, v) (d) = av_clip_int16((v)>>FILTER_SHIFT) + +#endif + +static void RENAME(resample_one)(void *dest, const void *source, + int dst_size, int64_t index2, int64_t incr) +{ + DELEM *dst = dest; + const DELEM *src = source; + int dst_index; + + for (dst_index = 0; dst_index < dst_size; dst_index++) { + dst[dst_index] = src[index2 >> 32]; + index2 += incr; + } +} + +static int RENAME(resample_common)(ResampleContext *c, + void *dest, const void *source, + int n, int update_ctx) +{ + DELEM *dst = dest; + const DELEM *src = source; + int dst_index; + int index= c->index; + int frac= c->frac; + int sample_index = 0; + + while (index >= c->phase_count) { + sample_index++; + index -= c->phase_count; + } + + for (dst_index = 0; dst_index < n; dst_index++) { + FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; + + FELEM2 val = FOFFSET; + FELEM2 val2= 0; + int i; + for (i = 0; i + 1 < c->filter_length; i+=2) { + val += src[sample_index + i ] * (FELEM2)filter[i ]; + val2 += src[sample_index + i + 1] * (FELEM2)filter[i + 1]; + } + if (i < c->filter_length) + val += src[sample_index + i ] * (FELEM2)filter[i ]; +#ifdef FELEML + OUT(dst[dst_index], val + (FELEML)val2); +#else + OUT(dst[dst_index], val + val2); +#endif + + frac += c->dst_incr_mod; + index += c->dst_incr_div; + if (frac >= c->src_incr) { + frac -= c->src_incr; + index++; + } + + while (index >= c->phase_count) { + sample_index++; + index -= c->phase_count; + } + } + + if(update_ctx){ + c->frac= frac; + c->index= index; + } + + return sample_index; +} + +static int RENAME(resample_linear)(ResampleContext *c, + void *dest, const void *source, + int n, int update_ctx) +{ + DELEM *dst = dest; + const DELEM *src = source; + int dst_index; + int index= c->index; + int frac= c->frac; + int sample_index = 0; +#if FILTER_SHIFT == 0 + double inv_src_incr = 1.0 / c->src_incr; +#endif + + while (index >= c->phase_count) { + sample_index++; + index -= c->phase_count; + } + + for (dst_index = 0; dst_index < n; dst_index++) { + FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; + FELEM2 val = FOFFSET, v2 = FOFFSET; + + int i; + for (i = 0; i < c->filter_length; i++) { + val += src[sample_index + i] * (FELEM2)filter[i]; + v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc]; + } +#ifdef FELEML + val += (v2 - val) * (FELEML) frac / c->src_incr; +#else +# if FILTER_SHIFT == 0 + val += (v2 - val) * inv_src_incr * frac; +# else + val += (v2 - val) / c->src_incr * frac; +# endif +#endif + OUT(dst[dst_index], val); + + frac += c->dst_incr_mod; + index += c->dst_incr_div; + if (frac >= c->src_incr) { + frac -= c->src_incr; + index++; + } + + while (index >= c->phase_count) { + sample_index++; + index -= c->phase_count; + } + } + + if(update_ctx){ + c->frac= frac; + c->index= index; + } + + return sample_index; +} + +#undef RENAME +#undef FILTER_SHIFT +#undef DELEM +#undef FELEM +#undef FELEM2 +#undef FELEML +#undef FELEM_MAX +#undef FELEM_MIN +#undef OUT +#undef FOFFSET diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample.c new file mode 100644 index 000000000..1ac5ef9a3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample.c @@ -0,0 +1,949 @@ +/* + * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/opt.h" +#include "swresample_internal.h" +#include "audioconvert.h" +#include "libavutil/avassert.h" +#include "libavutil/channel_layout.h" +#include "libavutil/internal.h" + +#include + +#define ALIGN 32 + +#include "libavutil/ffversion.h" +const char swr_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + +unsigned swresample_version(void) +{ + av_assert0(LIBSWRESAMPLE_VERSION_MICRO >= 100); + return LIBSWRESAMPLE_VERSION_INT; +} + +const char *swresample_configuration(void) +{ + return FFMPEG_CONFIGURATION; +} + +const char *swresample_license(void) +{ +#define LICENSE_PREFIX "libswresample license: " + return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; +} + +int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){ + if(!s || s->in_convert) // s needs to be allocated but not initialized + return AVERROR(EINVAL); + s->channel_map = channel_map; + return 0; +} + +struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, + int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, + int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, + int log_offset, void *log_ctx){ + if(!s) s= swr_alloc(); + if(!s) return NULL; + + s->log_level_offset= log_offset; + s->log_ctx= log_ctx; + + if (av_opt_set_int(s, "ocl", out_ch_layout, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "osf", out_sample_fmt, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "osr", out_sample_rate, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "icl", in_ch_layout, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "isf", in_sample_fmt, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "isr", in_sample_rate, 0) < 0) + goto fail; + + if (av_opt_set_int(s, "ich", av_get_channel_layout_nb_channels(s-> user_in_ch_layout), 0) < 0) + goto fail; + + if (av_opt_set_int(s, "och", av_get_channel_layout_nb_channels(s->user_out_ch_layout), 0) < 0) + goto fail; + + av_opt_set_int(s, "uch", 0, 0); + return s; +fail: + av_log(s, AV_LOG_ERROR, "Failed to set option\n"); + swr_free(&s); + return NULL; +} + +static void set_audiodata_fmt(AudioData *a, enum AVSampleFormat fmt){ + a->fmt = fmt; + a->bps = av_get_bytes_per_sample(fmt); + a->planar= av_sample_fmt_is_planar(fmt); + if (a->ch_count == 1) + a->planar = 1; +} + +static void free_temp(AudioData *a){ + av_free(a->data); + memset(a, 0, sizeof(*a)); +} + +static void clear_context(SwrContext *s){ + s->in_buffer_index= 0; + s->in_buffer_count= 0; + s->resample_in_constraint= 0; + memset(s->in.ch, 0, sizeof(s->in.ch)); + memset(s->out.ch, 0, sizeof(s->out.ch)); + free_temp(&s->postin); + free_temp(&s->midbuf); + free_temp(&s->preout); + free_temp(&s->in_buffer); + free_temp(&s->silence); + free_temp(&s->drop_temp); + free_temp(&s->dither.noise); + free_temp(&s->dither.temp); + swri_audio_convert_free(&s-> in_convert); + swri_audio_convert_free(&s->out_convert); + swri_audio_convert_free(&s->full_convert); + swri_rematrix_free(s); + + s->delayed_samples_fixup = 0; + s->flushed = 0; +} + +av_cold void swr_free(SwrContext **ss){ + SwrContext *s= *ss; + if(s){ + clear_context(s); + if (s->resampler) + s->resampler->free(&s->resample); + } + + av_freep(ss); +} + +av_cold void swr_close(SwrContext *s){ + clear_context(s); +} + +av_cold int swr_init(struct SwrContext *s){ + int ret; + char l1[1024], l2[1024]; + + clear_context(s); + + if(s-> in_sample_fmt >= AV_SAMPLE_FMT_NB){ + av_log(s, AV_LOG_ERROR, "Requested input sample format %d is invalid\n", s->in_sample_fmt); + return AVERROR(EINVAL); + } + if(s->out_sample_fmt >= AV_SAMPLE_FMT_NB){ + av_log(s, AV_LOG_ERROR, "Requested output sample format %d is invalid\n", s->out_sample_fmt); + return AVERROR(EINVAL); + } + + if(s-> in_sample_rate <= 0){ + av_log(s, AV_LOG_ERROR, "Requested input sample rate %d is invalid\n", s->in_sample_rate); + return AVERROR(EINVAL); + } + if(s->out_sample_rate <= 0){ + av_log(s, AV_LOG_ERROR, "Requested output sample rate %d is invalid\n", s->out_sample_rate); + return AVERROR(EINVAL); + } + s->out.ch_count = s-> user_out_ch_count; + s-> in.ch_count = s-> user_in_ch_count; + s->used_ch_count = s->user_used_ch_count; + + s-> in_ch_layout = s-> user_in_ch_layout; + s->out_ch_layout = s->user_out_ch_layout; + + s->int_sample_fmt= s->user_int_sample_fmt; + + s->dither.method = s->user_dither_method; + + if(av_get_channel_layout_nb_channels(s-> in_ch_layout) > SWR_CH_MAX) { + av_log(s, AV_LOG_WARNING, "Input channel layout 0x%"PRIx64" is invalid or unsupported.\n", s-> in_ch_layout); + s->in_ch_layout = 0; + } + + if(av_get_channel_layout_nb_channels(s->out_ch_layout) > SWR_CH_MAX) { + av_log(s, AV_LOG_WARNING, "Output channel layout 0x%"PRIx64" is invalid or unsupported.\n", s->out_ch_layout); + s->out_ch_layout = 0; + } + + switch(s->engine){ +#if CONFIG_LIBSOXR + case SWR_ENGINE_SOXR: s->resampler = &swri_soxr_resampler; break; +#endif + case SWR_ENGINE_SWR : s->resampler = &swri_resampler; break; + default: + av_log(s, AV_LOG_ERROR, "Requested resampling engine is unavailable\n"); + return AVERROR(EINVAL); + } + + if(!s->used_ch_count) + s->used_ch_count= s->in.ch_count; + + if(s->used_ch_count && s-> in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s-> in_ch_layout)){ + av_log(s, AV_LOG_WARNING, "Input channel layout has a different number of channels than the number of used channels, ignoring layout\n"); + s-> in_ch_layout= 0; + } + + if(!s-> in_ch_layout) + s-> in_ch_layout= av_get_default_channel_layout(s->used_ch_count); + if(!s->out_ch_layout) + s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count); + + s->rematrix= s->out_ch_layout !=s->in_ch_layout || s->rematrix_volume!=1.0 || + s->rematrix_custom; + + if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){ + if( av_get_bytes_per_sample(s-> in_sample_fmt) <= 2 + && av_get_bytes_per_sample(s->out_sample_fmt) <= 2){ + s->int_sample_fmt= AV_SAMPLE_FMT_S16P; + }else if( av_get_bytes_per_sample(s-> in_sample_fmt) <= 2 + && !s->rematrix + && s->out_sample_rate==s->in_sample_rate + && !(s->flags & SWR_FLAG_RESAMPLE)){ + s->int_sample_fmt= AV_SAMPLE_FMT_S16P; + }else if( av_get_planar_sample_fmt(s-> in_sample_fmt) == AV_SAMPLE_FMT_S32P + && av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P + && !s->rematrix + && s->out_sample_rate == s->in_sample_rate + && !(s->flags & SWR_FLAG_RESAMPLE) + && s->engine != SWR_ENGINE_SOXR){ + s->int_sample_fmt= AV_SAMPLE_FMT_S32P; + }else if(av_get_bytes_per_sample(s->in_sample_fmt) <= 4){ + s->int_sample_fmt= AV_SAMPLE_FMT_FLTP; + }else{ + s->int_sample_fmt= AV_SAMPLE_FMT_DBLP; + } + } + av_log(s, AV_LOG_DEBUG, "Using %s internally between filters\n", av_get_sample_fmt_name(s->int_sample_fmt)); + + if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P + &&s->int_sample_fmt != AV_SAMPLE_FMT_S32P + &&s->int_sample_fmt != AV_SAMPLE_FMT_S64P + &&s->int_sample_fmt != AV_SAMPLE_FMT_FLTP + &&s->int_sample_fmt != AV_SAMPLE_FMT_DBLP){ + av_log(s, AV_LOG_ERROR, "Requested sample format %s is not supported internally, s16p/s32p/s64p/fltp/dblp are supported\n", av_get_sample_fmt_name(s->int_sample_fmt)); + return AVERROR(EINVAL); + } + + set_audiodata_fmt(&s-> in, s-> in_sample_fmt); + set_audiodata_fmt(&s->out, s->out_sample_fmt); + + if (s->firstpts_in_samples != AV_NOPTS_VALUE) { + if (!s->async && s->min_compensation >= FLT_MAX/2) + s->async = 1; + s->firstpts = + s->outpts = s->firstpts_in_samples * s->out_sample_rate; + } else + s->firstpts = AV_NOPTS_VALUE; + + if (s->async) { + if (s->min_compensation >= FLT_MAX/2) + s->min_compensation = 0.001; + if (s->async > 1.0001) { + s->max_soft_compensation = s->async / (double) s->in_sample_rate; + } + } + + if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){ + s->resample = s->resampler->init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta, s->precision, s->cheby, s->exact_rational); + if (!s->resample) { + av_log(s, AV_LOG_ERROR, "Failed to initialize resampler\n"); + return AVERROR(ENOMEM); + } + }else + s->resampler->free(&s->resample); + if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P + && s->int_sample_fmt != AV_SAMPLE_FMT_S32P + && s->int_sample_fmt != AV_SAMPLE_FMT_FLTP + && s->int_sample_fmt != AV_SAMPLE_FMT_DBLP + && s->resample){ + av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16p/s32p/fltp/dblp\n"); + ret = AVERROR(EINVAL); + goto fail; + } + +#define RSC 1 //FIXME finetune + if(!s-> in.ch_count) + s-> in.ch_count= av_get_channel_layout_nb_channels(s-> in_ch_layout); + if(!s->used_ch_count) + s->used_ch_count= s->in.ch_count; + if(!s->out.ch_count) + s->out.ch_count= av_get_channel_layout_nb_channels(s->out_ch_layout); + + if(!s-> in.ch_count){ + av_assert0(!s->in_ch_layout); + av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n"); + ret = AVERROR(EINVAL); + goto fail; + } + + av_get_channel_layout_string(l1, sizeof(l1), s-> in.ch_count, s-> in_ch_layout); + av_get_channel_layout_string(l2, sizeof(l2), s->out.ch_count, s->out_ch_layout); + if (s->out_ch_layout && s->out.ch_count != av_get_channel_layout_nb_channels(s->out_ch_layout)) { + av_log(s, AV_LOG_ERROR, "Output channel layout %s mismatches specified channel count %d\n", l2, s->out.ch_count); + ret = AVERROR(EINVAL); + goto fail; + } + if (s->in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s->in_ch_layout)) { + av_log(s, AV_LOG_ERROR, "Input channel layout %s mismatches specified channel count %d\n", l1, s->used_ch_count); + ret = AVERROR(EINVAL); + goto fail; + } + + if ((!s->out_ch_layout || !s->in_ch_layout) && s->used_ch_count != s->out.ch_count && !s->rematrix_custom) { + av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s " + "but there is not enough information to do it\n", l1, l2); + ret = AVERROR(EINVAL); + goto fail; + } + +av_assert0(s->used_ch_count); +av_assert0(s->out.ch_count); + s->resample_first= RSC*s->out.ch_count/s->used_ch_count - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0; + + s->in_buffer= s->in; + s->silence = s->in; + s->drop_temp= s->out; + + if ((ret = swri_dither_init(s, s->out_sample_fmt, s->int_sample_fmt)) < 0) + goto fail; + + if(!s->resample && !s->rematrix && !s->channel_map && !s->dither.method){ + s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt, + s-> in_sample_fmt, s-> in.ch_count, NULL, 0); + return 0; + } + + s->in_convert = swri_audio_convert_alloc(s->int_sample_fmt, + s-> in_sample_fmt, s->used_ch_count, s->channel_map, 0); + s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt, + s->int_sample_fmt, s->out.ch_count, NULL, 0); + + if (!s->in_convert || !s->out_convert) { + ret = AVERROR(ENOMEM); + goto fail; + } + + s->postin= s->in; + s->preout= s->out; + s->midbuf= s->in; + + if(s->channel_map){ + s->postin.ch_count= + s->midbuf.ch_count= s->used_ch_count; + if(s->resample) + s->in_buffer.ch_count= s->used_ch_count; + } + if(!s->resample_first){ + s->midbuf.ch_count= s->out.ch_count; + if(s->resample) + s->in_buffer.ch_count = s->out.ch_count; + } + + set_audiodata_fmt(&s->postin, s->int_sample_fmt); + set_audiodata_fmt(&s->midbuf, s->int_sample_fmt); + set_audiodata_fmt(&s->preout, s->int_sample_fmt); + + if(s->resample){ + set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt); + } + + av_assert0(!s->preout.count); + s->dither.noise = s->preout; + s->dither.temp = s->preout; + if (s->dither.method > SWR_DITHER_NS) { + s->dither.noise.bps = 4; + s->dither.noise.fmt = AV_SAMPLE_FMT_FLTP; + s->dither.noise_scale = 1; + } + + if(s->rematrix || s->dither.method) { + ret = swri_rematrix_init(s); + if (ret < 0) + goto fail; + } + + return 0; +fail: + swr_close(s); + return ret; + +} + +int swri_realloc_audio(AudioData *a, int count){ + int i, countb; + AudioData old; + + if(count < 0 || count > INT_MAX/2/a->bps/a->ch_count) + return AVERROR(EINVAL); + + if(a->count >= count) + return 0; + + count*=2; + + countb= FFALIGN(count*a->bps, ALIGN); + old= *a; + + av_assert0(a->bps); + av_assert0(a->ch_count); + + a->data= av_mallocz_array(countb, a->ch_count); + if(!a->data) + return AVERROR(ENOMEM); + for(i=0; ich_count; i++){ + a->ch[i]= a->data + i*(a->planar ? countb : a->bps); + if(a->count && a->planar) memcpy(a->ch[i], old.ch[i], a->count*a->bps); + } + if(a->count && !a->planar) memcpy(a->ch[0], old.ch[0], a->count*a->ch_count*a->bps); + av_freep(&old.data); + a->count= count; + + return 1; +} + +static void copy(AudioData *out, AudioData *in, + int count){ + av_assert0(out->planar == in->planar); + av_assert0(out->bps == in->bps); + av_assert0(out->ch_count == in->ch_count); + if(out->planar){ + int ch; + for(ch=0; chch_count; ch++) + memcpy(out->ch[ch], in->ch[ch], count*out->bps); + }else + memcpy(out->ch[0], in->ch[0], count*out->ch_count*out->bps); +} + +static void fill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){ + int i; + if(!in_arg){ + memset(out->ch, 0, sizeof(out->ch)); + }else if(out->planar){ + for(i=0; ich_count; i++) + out->ch[i]= in_arg[i]; + }else{ + for(i=0; ich_count; i++) + out->ch[i]= in_arg[0] + i*out->bps; + } +} + +static void reversefill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){ + int i; + if(out->planar){ + for(i=0; ich_count; i++) + in_arg[i]= out->ch[i]; + }else{ + in_arg[0]= out->ch[0]; + } +} + +/** + * + * out may be equal in. + */ +static void buf_set(AudioData *out, AudioData *in, int count){ + int ch; + if(in->planar){ + for(ch=0; chch_count; ch++) + out->ch[ch]= in->ch[ch] + count*out->bps; + }else{ + for(ch=out->ch_count-1; ch>=0; ch--) + out->ch[ch]= in->ch[0] + (ch + count*out->ch_count) * out->bps; + } +} + +/** + * + * @return number of samples output per channel + */ +static int resample(SwrContext *s, AudioData *out_param, int out_count, + const AudioData * in_param, int in_count){ + AudioData in, out, tmp; + int ret_sum=0; + int border=0; + int padless = ARCH_X86 && s->engine == SWR_ENGINE_SWR ? 7 : 0; + + av_assert1(s->in_buffer.ch_count == in_param->ch_count); + av_assert1(s->in_buffer.planar == in_param->planar); + av_assert1(s->in_buffer.fmt == in_param->fmt); + + tmp=out=*out_param; + in = *in_param; + + border = s->resampler->invert_initial_buffer(s->resample, &s->in_buffer, + &in, in_count, &s->in_buffer_index, &s->in_buffer_count); + if (border == INT_MAX) { + return 0; + } else if (border < 0) { + return border; + } else if (border) { + buf_set(&in, &in, border); + in_count -= border; + s->resample_in_constraint = 0; + } + + do{ + int ret, size, consumed; + if(!s->resample_in_constraint && s->in_buffer_count){ + buf_set(&tmp, &s->in_buffer, s->in_buffer_index); + ret= s->resampler->multiple_resample(s->resample, &out, out_count, &tmp, s->in_buffer_count, &consumed); + out_count -= ret; + ret_sum += ret; + buf_set(&out, &out, ret); + s->in_buffer_count -= consumed; + s->in_buffer_index += consumed; + + if(!in_count) + break; + if(s->in_buffer_count <= border){ + buf_set(&in, &in, -s->in_buffer_count); + in_count += s->in_buffer_count; + s->in_buffer_count=0; + s->in_buffer_index=0; + border = 0; + } + } + + if((s->flushed || in_count > padless) && !s->in_buffer_count){ + s->in_buffer_index=0; + ret= s->resampler->multiple_resample(s->resample, &out, out_count, &in, FFMAX(in_count-padless, 0), &consumed); + out_count -= ret; + ret_sum += ret; + buf_set(&out, &out, ret); + in_count -= consumed; + buf_set(&in, &in, consumed); + } + + //TODO is this check sane considering the advanced copy avoidance below + size= s->in_buffer_index + s->in_buffer_count + in_count; + if( size > s->in_buffer.count + && s->in_buffer_count + in_count <= s->in_buffer_index){ + buf_set(&tmp, &s->in_buffer, s->in_buffer_index); + copy(&s->in_buffer, &tmp, s->in_buffer_count); + s->in_buffer_index=0; + }else + if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0) + return ret; + + if(in_count){ + int count= in_count; + if(s->in_buffer_count && s->in_buffer_count+2 < count && out_count) count= s->in_buffer_count+2; + + buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count); + copy(&tmp, &in, /*in_*/count); + s->in_buffer_count += count; + in_count -= count; + border += count; + buf_set(&in, &in, count); + s->resample_in_constraint= 0; + if(s->in_buffer_count != count || in_count) + continue; + if (padless) { + padless = 0; + continue; + } + } + break; + }while(1); + + s->resample_in_constraint= !!out_count; + + return ret_sum; +} + +static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count, + AudioData *in , int in_count){ + AudioData *postin, *midbuf, *preout; + int ret/*, in_max*/; + AudioData preout_tmp, midbuf_tmp; + + if(s->full_convert){ + av_assert0(!s->resample); + swri_audio_convert(s->full_convert, out, in, in_count); + return out_count; + } + +// in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps; +// in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count); + + if((ret=swri_realloc_audio(&s->postin, in_count))<0) + return ret; + if(s->resample_first){ + av_assert0(s->midbuf.ch_count == s->used_ch_count); + if((ret=swri_realloc_audio(&s->midbuf, out_count))<0) + return ret; + }else{ + av_assert0(s->midbuf.ch_count == s->out.ch_count); + if((ret=swri_realloc_audio(&s->midbuf, in_count))<0) + return ret; + } + if((ret=swri_realloc_audio(&s->preout, out_count))<0) + return ret; + + postin= &s->postin; + + midbuf_tmp= s->midbuf; + midbuf= &midbuf_tmp; + preout_tmp= s->preout; + preout= &preout_tmp; + + if(s->int_sample_fmt == s-> in_sample_fmt && s->in.planar && !s->channel_map) + postin= in; + + if(s->resample_first ? !s->resample : !s->rematrix) + midbuf= postin; + + if(s->resample_first ? !s->rematrix : !s->resample) + preout= midbuf; + + if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar + && !(s->out_sample_fmt==AV_SAMPLE_FMT_S32P && (s->dither.output_sample_bits&31))){ + if(preout==in){ + out_count= FFMIN(out_count, in_count); //TODO check at the end if this is needed or redundant + av_assert0(s->in.planar); //we only support planar internally so it has to be, we support copying non planar though + copy(out, in, out_count); + return out_count; + } + else if(preout==postin) preout= midbuf= postin= out; + else if(preout==midbuf) preout= midbuf= out; + else preout= out; + } + + if(in != postin){ + swri_audio_convert(s->in_convert, postin, in, in_count); + } + + if(s->resample_first){ + if(postin != midbuf) + out_count= resample(s, midbuf, out_count, postin, in_count); + if(midbuf != preout) + swri_rematrix(s, preout, midbuf, out_count, preout==out); + }else{ + if(postin != midbuf) + swri_rematrix(s, midbuf, postin, in_count, midbuf==out); + if(midbuf != preout) + out_count= resample(s, preout, out_count, midbuf, in_count); + } + + if(preout != out && out_count){ + AudioData *conv_src = preout; + if(s->dither.method){ + int ch; + int dither_count= FFMAX(out_count, 1<<16); + + if (preout == in) { + conv_src = &s->dither.temp; + if((ret=swri_realloc_audio(&s->dither.temp, dither_count))<0) + return ret; + } + + if((ret=swri_realloc_audio(&s->dither.noise, dither_count))<0) + return ret; + if(ret) + for(ch=0; chdither.noise.ch_count; ch++) + if((ret=swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, (12345678913579ULL*ch + 3141592) % 2718281828U, s->dither.noise.fmt))<0) + return ret; + av_assert0(s->dither.noise.ch_count == preout->ch_count); + + if(s->dither.noise_pos + out_count > s->dither.noise.count) + s->dither.noise_pos = 0; + + if (s->dither.method < SWR_DITHER_NS){ + if (s->mix_2_1_simd) { + int len1= out_count&~15; + int off = len1 * preout->bps; + + if(len1) + for(ch=0; chch_count; ch++) + s->mix_2_1_simd(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_simd_one, 0, 0, len1); + if(out_count != len1) + for(ch=0; chch_count; ch++) + s->mix_2_1_f(conv_src->ch[ch] + off, preout->ch[ch] + off, s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos + off, s->native_one, 0, 0, out_count - len1); + } else { + for(ch=0; chch_count; ch++) + s->mix_2_1_f(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_one, 0, 0, out_count); + } + } else { + switch(s->int_sample_fmt) { + case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, conv_src, preout, &s->dither.noise, out_count); break; + case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, conv_src, preout, &s->dither.noise, out_count); break; + case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, conv_src, preout, &s->dither.noise, out_count); break; + case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,conv_src, preout, &s->dither.noise, out_count); break; + } + } + s->dither.noise_pos += out_count; + } +//FIXME packed doesn't need more than 1 chan here! + swri_audio_convert(s->out_convert, out, conv_src, out_count); + } + return out_count; +} + +int swr_is_initialized(struct SwrContext *s) { + return !!s->in_buffer.ch_count; +} + +int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count, + const uint8_t *in_arg [SWR_CH_MAX], int in_count){ + AudioData * in= &s->in; + AudioData *out= &s->out; + int av_unused max_output; + + if (!swr_is_initialized(s)) { + av_log(s, AV_LOG_ERROR, "Context has not been initialized\n"); + return AVERROR(EINVAL); + } +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >1 + max_output = swr_get_out_samples(s, in_count); +#endif + + while(s->drop_output > 0){ + int ret; + uint8_t *tmp_arg[SWR_CH_MAX]; +#define MAX_DROP_STEP 16384 + if((ret=swri_realloc_audio(&s->drop_temp, FFMIN(s->drop_output, MAX_DROP_STEP)))<0) + return ret; + + reversefill_audiodata(&s->drop_temp, tmp_arg); + s->drop_output *= -1; //FIXME find a less hackish solution + ret = swr_convert(s, tmp_arg, FFMIN(-s->drop_output, MAX_DROP_STEP), in_arg, in_count); //FIXME optimize but this is as good as never called so maybe it doesn't matter + s->drop_output *= -1; + in_count = 0; + if(ret>0) { + s->drop_output -= ret; + if (!s->drop_output && !out_arg) + return 0; + continue; + } + + av_assert0(s->drop_output); + return 0; + } + + if(!in_arg){ + if(s->resample){ + if (!s->flushed) + s->resampler->flush(s); + s->resample_in_constraint = 0; + s->flushed = 1; + }else if(!s->in_buffer_count){ + return 0; + } + }else + fill_audiodata(in , (void*)in_arg); + + fill_audiodata(out, out_arg); + + if(s->resample){ + int ret = swr_convert_internal(s, out, out_count, in, in_count); + if(ret>0 && !s->drop_output) + s->outpts += ret * (int64_t)s->in_sample_rate; + + av_assert2(max_output < 0 || ret < 0 || ret <= max_output); + + return ret; + }else{ + AudioData tmp= *in; + int ret2=0; + int ret, size; + size = FFMIN(out_count, s->in_buffer_count); + if(size){ + buf_set(&tmp, &s->in_buffer, s->in_buffer_index); + ret= swr_convert_internal(s, out, size, &tmp, size); + if(ret<0) + return ret; + ret2= ret; + s->in_buffer_count -= ret; + s->in_buffer_index += ret; + buf_set(out, out, ret); + out_count -= ret; + if(!s->in_buffer_count) + s->in_buffer_index = 0; + } + + if(in_count){ + size= s->in_buffer_index + s->in_buffer_count + in_count - out_count; + + if(in_count > out_count) { //FIXME move after swr_convert_internal + if( size > s->in_buffer.count + && s->in_buffer_count + in_count - out_count <= s->in_buffer_index){ + buf_set(&tmp, &s->in_buffer, s->in_buffer_index); + copy(&s->in_buffer, &tmp, s->in_buffer_count); + s->in_buffer_index=0; + }else + if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0) + return ret; + } + + if(out_count){ + size = FFMIN(in_count, out_count); + ret= swr_convert_internal(s, out, size, in, size); + if(ret<0) + return ret; + buf_set(in, in, ret); + in_count -= ret; + ret2 += ret; + } + if(in_count){ + buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count); + copy(&tmp, in, in_count); + s->in_buffer_count += in_count; + } + } + if(ret2>0 && !s->drop_output) + s->outpts += ret2 * (int64_t)s->in_sample_rate; + av_assert2(max_output < 0 || ret2 < 0 || ret2 <= max_output); + return ret2; + } +} + +int swr_drop_output(struct SwrContext *s, int count){ + const uint8_t *tmp_arg[SWR_CH_MAX]; + s->drop_output += count; + + if(s->drop_output <= 0) + return 0; + + av_log(s, AV_LOG_VERBOSE, "discarding %d audio samples\n", count); + return swr_convert(s, NULL, s->drop_output, tmp_arg, 0); +} + +int swr_inject_silence(struct SwrContext *s, int count){ + int ret, i; + uint8_t *tmp_arg[SWR_CH_MAX]; + + if(count <= 0) + return 0; + +#define MAX_SILENCE_STEP 16384 + while (count > MAX_SILENCE_STEP) { + if ((ret = swr_inject_silence(s, MAX_SILENCE_STEP)) < 0) + return ret; + count -= MAX_SILENCE_STEP; + } + + if((ret=swri_realloc_audio(&s->silence, count))<0) + return ret; + + if(s->silence.planar) for(i=0; isilence.ch_count; i++) { + memset(s->silence.ch[i], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps); + } else + memset(s->silence.ch[0], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps*s->silence.ch_count); + + reversefill_audiodata(&s->silence, tmp_arg); + av_log(s, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", count); + ret = swr_convert(s, NULL, 0, (const uint8_t**)tmp_arg, count); + return ret; +} + +int64_t swr_get_delay(struct SwrContext *s, int64_t base){ + if (s->resampler && s->resample){ + return s->resampler->get_delay(s, base); + }else{ + return (s->in_buffer_count*base + (s->in_sample_rate>>1))/ s->in_sample_rate; + } +} + +int swr_get_out_samples(struct SwrContext *s, int in_samples) +{ + int64_t out_samples; + + if (in_samples < 0) + return AVERROR(EINVAL); + + if (s->resampler && s->resample) { + if (!s->resampler->get_out_samples) + return AVERROR(ENOSYS); + out_samples = s->resampler->get_out_samples(s, in_samples); + } else { + out_samples = s->in_buffer_count + in_samples; + av_assert0(s->out_sample_rate == s->in_sample_rate); + } + + if (out_samples > INT_MAX) + return AVERROR(EINVAL); + + return out_samples; +} + +int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance){ + int ret; + + if (!s || compensation_distance < 0) + return AVERROR(EINVAL); + if (!compensation_distance && sample_delta) + return AVERROR(EINVAL); + if (!s->resample) { + s->flags |= SWR_FLAG_RESAMPLE; + ret = swr_init(s); + if (ret < 0) + return ret; + } + if (!s->resampler->set_compensation){ + return AVERROR(EINVAL); + }else{ + return s->resampler->set_compensation(s->resample, sample_delta, compensation_distance); + } +} + +int64_t swr_next_pts(struct SwrContext *s, int64_t pts){ + if(pts == INT64_MIN) + return s->outpts; + + if (s->firstpts == AV_NOPTS_VALUE) + s->outpts = s->firstpts = pts; + + if(s->min_compensation >= FLT_MAX) { + return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate)); + } else { + int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts + s->drop_output*(int64_t)s->in_sample_rate; + double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate); + + if(fabs(fdelta) > s->min_compensation) { + if(s->outpts == s->firstpts || fabs(fdelta) > s->min_hard_compensation){ + int ret; + if(delta > 0) ret = swr_inject_silence(s, delta / s->out_sample_rate); + else ret = swr_drop_output (s, -delta / s-> in_sample_rate); + if(ret<0){ + av_log(s, AV_LOG_ERROR, "Failed to compensate for timestamp delta of %f\n", fdelta); + } + } else if(s->soft_compensation_duration && s->max_soft_compensation) { + int duration = s->out_sample_rate * s->soft_compensation_duration; + double max_soft_compensation = s->max_soft_compensation / (s->max_soft_compensation < 0 ? -s->in_sample_rate : 1); + int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) * duration ; + av_log(s, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration); + swr_set_compensation(s, comp, duration); + } + } + + return s->outpts; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample.h b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample.h new file mode 100644 index 000000000..c7b84fbca --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample.h @@ -0,0 +1,579 @@ +/* + * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWRESAMPLE_SWRESAMPLE_H +#define SWRESAMPLE_SWRESAMPLE_H + +/** + * @file + * @ingroup lswr + * libswresample public header + */ + +/** + * @defgroup lswr libswresample + * @{ + * + * Audio resampling, sample format conversion and mixing library. + * + * Interaction with lswr is done through SwrContext, which is + * allocated with swr_alloc() or swr_alloc_set_opts(). It is opaque, so all parameters + * must be set with the @ref avoptions API. + * + * The first thing you will need to do in order to use lswr is to allocate + * SwrContext. This can be done with swr_alloc() or swr_alloc_set_opts(). If you + * are using the former, you must set options through the @ref avoptions API. + * The latter function provides the same feature, but it allows you to set some + * common options in the same statement. + * + * For example the following code will setup conversion from planar float sample + * format to interleaved signed 16-bit integer, downsampling from 48kHz to + * 44.1kHz and downmixing from 5.1 channels to stereo (using the default mixing + * matrix). This is using the swr_alloc() function. + * @code + * SwrContext *swr = swr_alloc(); + * av_opt_set_channel_layout(swr, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); + * av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); + * av_opt_set_int(swr, "in_sample_rate", 48000, 0); + * av_opt_set_int(swr, "out_sample_rate", 44100, 0); + * av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0); + * av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); + * @endcode + * + * The same job can be done using swr_alloc_set_opts() as well: + * @code + * SwrContext *swr = swr_alloc_set_opts(NULL, // we're allocating a new context + * AV_CH_LAYOUT_STEREO, // out_ch_layout + * AV_SAMPLE_FMT_S16, // out_sample_fmt + * 44100, // out_sample_rate + * AV_CH_LAYOUT_5POINT1, // in_ch_layout + * AV_SAMPLE_FMT_FLTP, // in_sample_fmt + * 48000, // in_sample_rate + * 0, // log_offset + * NULL); // log_ctx + * @endcode + * + * Once all values have been set, it must be initialized with swr_init(). If + * you need to change the conversion parameters, you can change the parameters + * using @ref AVOptions, as described above in the first example; or by using + * swr_alloc_set_opts(), but with the first argument the allocated context. + * You must then call swr_init() again. + * + * The conversion itself is done by repeatedly calling swr_convert(). + * Note that the samples may get buffered in swr if you provide insufficient + * output space or if sample rate conversion is done, which requires "future" + * samples. Samples that do not require future input can be retrieved at any + * time by using swr_convert() (in_count can be set to 0). + * At the end of conversion the resampling buffer can be flushed by calling + * swr_convert() with NULL in and 0 in_count. + * + * The samples used in the conversion process can be managed with the libavutil + * @ref lavu_sampmanip "samples manipulation" API, including av_samples_alloc() + * function used in the following example. + * + * The delay between input and output, can at any time be found by using + * swr_get_delay(). + * + * The following code demonstrates the conversion loop assuming the parameters + * from above and caller-defined functions get_input() and handle_output(): + * @code + * uint8_t **input; + * int in_samples; + * + * while (get_input(&input, &in_samples)) { + * uint8_t *output; + * int out_samples = av_rescale_rnd(swr_get_delay(swr, 48000) + + * in_samples, 44100, 48000, AV_ROUND_UP); + * av_samples_alloc(&output, NULL, 2, out_samples, + * AV_SAMPLE_FMT_S16, 0); + * out_samples = swr_convert(swr, &output, out_samples, + * input, in_samples); + * handle_output(output, out_samples); + * av_freep(&output); + * } + * @endcode + * + * When the conversion is finished, the conversion + * context and everything associated with it must be freed with swr_free(). + * A swr_close() function is also available, but it exists mainly for + * compatibility with libavresample, and is not required to be called. + * + * There will be no memory leak if the data is not completely flushed before + * swr_free(). + */ + +#include +#include "libavutil/channel_layout.h" +#include "libavutil/frame.h" +#include "libavutil/samplefmt.h" + +#include "libswresample/version.h" + +/** + * @name Option constants + * These constants are used for the @ref avoptions interface for lswr. + * @{ + * + */ + +#define SWR_FLAG_RESAMPLE 1 ///< Force resampling even if equal sample rate +//TODO use int resample ? +//long term TODO can we enable this dynamically? + +/** Dithering algorithms */ +enum SwrDitherType { + SWR_DITHER_NONE = 0, + SWR_DITHER_RECTANGULAR, + SWR_DITHER_TRIANGULAR, + SWR_DITHER_TRIANGULAR_HIGHPASS, + + SWR_DITHER_NS = 64, ///< not part of API/ABI + SWR_DITHER_NS_LIPSHITZ, + SWR_DITHER_NS_F_WEIGHTED, + SWR_DITHER_NS_MODIFIED_E_WEIGHTED, + SWR_DITHER_NS_IMPROVED_E_WEIGHTED, + SWR_DITHER_NS_SHIBATA, + SWR_DITHER_NS_LOW_SHIBATA, + SWR_DITHER_NS_HIGH_SHIBATA, + SWR_DITHER_NB, ///< not part of API/ABI +}; + +/** Resampling Engines */ +enum SwrEngine { + SWR_ENGINE_SWR, /**< SW Resampler */ + SWR_ENGINE_SOXR, /**< SoX Resampler */ + SWR_ENGINE_NB, ///< not part of API/ABI +}; + +/** Resampling Filter Types */ +enum SwrFilterType { + SWR_FILTER_TYPE_CUBIC, /**< Cubic */ + SWR_FILTER_TYPE_BLACKMAN_NUTTALL, /**< Blackman Nuttall windowed sinc */ + SWR_FILTER_TYPE_KAISER, /**< Kaiser windowed sinc */ +}; + +/** + * @} + */ + +/** + * The libswresample context. Unlike libavcodec and libavformat, this structure + * is opaque. This means that if you would like to set options, you must use + * the @ref avoptions API and cannot directly set values to members of the + * structure. + */ +typedef struct SwrContext SwrContext; + +/** + * Get the AVClass for SwrContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + * @return the AVClass of SwrContext + */ +const AVClass *swr_get_class(void); + +/** + * @name SwrContext constructor functions + * @{ + */ + +/** + * Allocate SwrContext. + * + * If you use this function you will need to set the parameters (manually or + * with swr_alloc_set_opts()) before calling swr_init(). + * + * @see swr_alloc_set_opts(), swr_init(), swr_free() + * @return NULL on error, allocated context otherwise + */ +struct SwrContext *swr_alloc(void); + +/** + * Initialize context after user parameters have been set. + * @note The context must be configured using the AVOption API. + * + * @see av_opt_set_int() + * @see av_opt_set_dict() + * + * @param[in,out] s Swr context to initialize + * @return AVERROR error code in case of failure. + */ +int swr_init(struct SwrContext *s); + +/** + * Check whether an swr context has been initialized or not. + * + * @param[in] s Swr context to check + * @see swr_init() + * @return positive if it has been initialized, 0 if not initialized + */ +int swr_is_initialized(struct SwrContext *s); + +/** + * Allocate SwrContext if needed and set/reset common parameters. + * + * This function does not require s to be allocated with swr_alloc(). On the + * other hand, swr_alloc() can use swr_alloc_set_opts() to set the parameters + * on the allocated context. + * + * @param s existing Swr context if available, or NULL if not + * @param out_ch_layout output channel layout (AV_CH_LAYOUT_*) + * @param out_sample_fmt output sample format (AV_SAMPLE_FMT_*). + * @param out_sample_rate output sample rate (frequency in Hz) + * @param in_ch_layout input channel layout (AV_CH_LAYOUT_*) + * @param in_sample_fmt input sample format (AV_SAMPLE_FMT_*). + * @param in_sample_rate input sample rate (frequency in Hz) + * @param log_offset logging level offset + * @param log_ctx parent logging context, can be NULL + * + * @see swr_init(), swr_free() + * @return NULL on error, allocated context otherwise + */ +struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, + int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, + int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, + int log_offset, void *log_ctx); + +/** + * @} + * + * @name SwrContext destructor functions + * @{ + */ + +/** + * Free the given SwrContext and set the pointer to NULL. + * + * @param[in] s a pointer to a pointer to Swr context + */ +void swr_free(struct SwrContext **s); + +/** + * Closes the context so that swr_is_initialized() returns 0. + * + * The context can be brought back to life by running swr_init(), + * swr_init() can also be used without swr_close(). + * This function is mainly provided for simplifying the usecase + * where one tries to support libavresample and libswresample. + * + * @param[in,out] s Swr context to be closed + */ +void swr_close(struct SwrContext *s); + +/** + * @} + * + * @name Core conversion functions + * @{ + */ + +/** Convert audio. + * + * in and in_count can be set to 0 to flush the last few samples out at the + * end. + * + * If more input is provided than output space, then the input will be buffered. + * You can avoid this buffering by using swr_get_out_samples() to retrieve an + * upper bound on the required number of output samples for the given number of + * input samples. Conversion will run directly without copying whenever possible. + * + * @param s allocated Swr context, with parameters set + * @param out output buffers, only the first one need be set in case of packed audio + * @param out_count amount of space available for output in samples per channel + * @param in input buffers, only the first one need to be set in case of packed audio + * @param in_count number of input samples available in one channel + * + * @return number of samples output per channel, negative value on error + */ +int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, + const uint8_t **in , int in_count); + +/** + * Convert the next timestamp from input to output + * timestamps are in 1/(in_sample_rate * out_sample_rate) units. + * + * @note There are 2 slightly differently behaving modes. + * @li When automatic timestamp compensation is not used, (min_compensation >= FLT_MAX) + * in this case timestamps will be passed through with delays compensated + * @li When automatic timestamp compensation is used, (min_compensation < FLT_MAX) + * in this case the output timestamps will match output sample numbers. + * See ffmpeg-resampler(1) for the two modes of compensation. + * + * @param s[in] initialized Swr context + * @param pts[in] timestamp for the next input sample, INT64_MIN if unknown + * @see swr_set_compensation(), swr_drop_output(), and swr_inject_silence() are + * function used internally for timestamp compensation. + * @return the output timestamp for the next output sample + */ +int64_t swr_next_pts(struct SwrContext *s, int64_t pts); + +/** + * @} + * + * @name Low-level option setting functions + * These functons provide a means to set low-level options that is not possible + * with the AVOption API. + * @{ + */ + +/** + * Activate resampling compensation ("soft" compensation). This function is + * internally called when needed in swr_next_pts(). + * + * @param[in,out] s allocated Swr context. If it is not initialized, + * or SWR_FLAG_RESAMPLE is not set, swr_init() is + * called with the flag set. + * @param[in] sample_delta delta in PTS per sample + * @param[in] compensation_distance number of samples to compensate for + * @return >= 0 on success, AVERROR error codes if: + * @li @c s is NULL, + * @li @c compensation_distance is less than 0, + * @li @c compensation_distance is 0 but sample_delta is not, + * @li compensation unsupported by resampler, or + * @li swr_init() fails when called. + */ +int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance); + +/** + * Set a customized input channel mapping. + * + * @param[in,out] s allocated Swr context, not yet initialized + * @param[in] channel_map customized input channel mapping (array of channel + * indexes, -1 for a muted channel) + * @return >= 0 on success, or AVERROR error code in case of failure. + */ +int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map); + +/** + * Generate a channel mixing matrix. + * + * This function is the one used internally by libswresample for building the + * default mixing matrix. It is made public just as a utility function for + * building custom matrices. + * + * @param in_layout input channel layout + * @param out_layout output channel layout + * @param center_mix_level mix level for the center channel + * @param surround_mix_level mix level for the surround channel(s) + * @param lfe_mix_level mix level for the low-frequency effects channel + * @param rematrix_maxval if 1.0, coefficients will be normalized to prevent + * overflow. if INT_MAX, coefficients will not be + * normalized. + * @param[out] matrix mixing coefficients; matrix[i + stride * o] is + * the weight of input channel i in output channel o. + * @param stride distance between adjacent input channels in the + * matrix array + * @param matrix_encoding matrixed stereo downmix mode (e.g. dplii) + * @param log_ctx parent logging context, can be NULL + * @return 0 on success, negative AVERROR code on failure + */ +int swr_build_matrix(uint64_t in_layout, uint64_t out_layout, + double center_mix_level, double surround_mix_level, + double lfe_mix_level, double rematrix_maxval, + double rematrix_volume, double *matrix, + int stride, enum AVMatrixEncoding matrix_encoding, + void *log_ctx); + +/** + * Set a customized remix matrix. + * + * @param s allocated Swr context, not yet initialized + * @param matrix remix coefficients; matrix[i + stride * o] is + * the weight of input channel i in output channel o + * @param stride offset between lines of the matrix + * @return >= 0 on success, or AVERROR error code in case of failure. + */ +int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride); + +/** + * @} + * + * @name Sample handling functions + * @{ + */ + +/** + * Drops the specified number of output samples. + * + * This function, along with swr_inject_silence(), is called by swr_next_pts() + * if needed for "hard" compensation. + * + * @param s allocated Swr context + * @param count number of samples to be dropped + * + * @return >= 0 on success, or a negative AVERROR code on failure + */ +int swr_drop_output(struct SwrContext *s, int count); + +/** + * Injects the specified number of silence samples. + * + * This function, along with swr_drop_output(), is called by swr_next_pts() + * if needed for "hard" compensation. + * + * @param s allocated Swr context + * @param count number of samples to be dropped + * + * @return >= 0 on success, or a negative AVERROR code on failure + */ +int swr_inject_silence(struct SwrContext *s, int count); + +/** + * Gets the delay the next input sample will experience relative to the next output sample. + * + * Swresample can buffer data if more input has been provided than available + * output space, also converting between sample rates needs a delay. + * This function returns the sum of all such delays. + * The exact delay is not necessarily an integer value in either input or + * output sample rate. Especially when downsampling by a large value, the + * output sample rate may be a poor choice to represent the delay, similarly + * for upsampling and the input sample rate. + * + * @param s swr context + * @param base timebase in which the returned delay will be: + * @li if it's set to 1 the returned delay is in seconds + * @li if it's set to 1000 the returned delay is in milliseconds + * @li if it's set to the input sample rate then the returned + * delay is in input samples + * @li if it's set to the output sample rate then the returned + * delay is in output samples + * @li if it's the least common multiple of in_sample_rate and + * out_sample_rate then an exact rounding-free delay will be + * returned + * @returns the delay in 1 / @c base units. + */ +int64_t swr_get_delay(struct SwrContext *s, int64_t base); + +/** + * Find an upper bound on the number of samples that the next swr_convert + * call will output, if called with in_samples of input samples. This + * depends on the internal state, and anything changing the internal state + * (like further swr_convert() calls) will may change the number of samples + * swr_get_out_samples() returns for the same number of input samples. + * + * @param in_samples number of input samples. + * @note any call to swr_inject_silence(), swr_convert(), swr_next_pts() + * or swr_set_compensation() invalidates this limit + * @note it is recommended to pass the correct available buffer size + * to all functions like swr_convert() even if swr_get_out_samples() + * indicates that less would be used. + * @returns an upper bound on the number of samples that the next swr_convert + * will output or a negative value to indicate an error + */ +int swr_get_out_samples(struct SwrContext *s, int in_samples); + +/** + * @} + * + * @name Configuration accessors + * @{ + */ + +/** + * Return the @ref LIBSWRESAMPLE_VERSION_INT constant. + * + * This is useful to check if the build-time libswresample has the same version + * as the run-time one. + * + * @returns the unsigned int-typed version + */ +unsigned swresample_version(void); + +/** + * Return the swr build-time configuration. + * + * @returns the build-time @c ./configure flags + */ +const char *swresample_configuration(void); + +/** + * Return the swr license. + * + * @returns the license of libswresample, determined at build-time + */ +const char *swresample_license(void); + +/** + * @} + * + * @name AVFrame based API + * @{ + */ + +/** + * Convert the samples in the input AVFrame and write them to the output AVFrame. + * + * Input and output AVFrames must have channel_layout, sample_rate and format set. + * + * If the output AVFrame does not have the data pointers allocated the nb_samples + * field will be set using av_frame_get_buffer() + * is called to allocate the frame. + * + * The output AVFrame can be NULL or have fewer allocated samples than required. + * In this case, any remaining samples not written to the output will be added + * to an internal FIFO buffer, to be returned at the next call to this function + * or to swr_convert(). + * + * If converting sample rate, there may be data remaining in the internal + * resampling delay buffer. swr_get_delay() tells the number of + * remaining samples. To get this data as output, call this function or + * swr_convert() with NULL input. + * + * If the SwrContext configuration does not match the output and + * input AVFrame settings the conversion does not take place and depending on + * which AVFrame is not matching AVERROR_OUTPUT_CHANGED, AVERROR_INPUT_CHANGED + * or the result of a bitwise-OR of them is returned. + * + * @see swr_delay() + * @see swr_convert() + * @see swr_get_delay() + * + * @param swr audio resample context + * @param output output AVFrame + * @param input input AVFrame + * @return 0 on success, AVERROR on failure or nonmatching + * configuration. + */ +int swr_convert_frame(SwrContext *swr, + AVFrame *output, const AVFrame *input); + +/** + * Configure or reconfigure the SwrContext using the information + * provided by the AVFrames. + * + * The original resampling context is reset even on failure. + * The function calls swr_close() internally if the context is open. + * + * @see swr_close(); + * + * @param swr audio resample context + * @param output output AVFrame + * @param input input AVFrame + * @return 0 on success, AVERROR on failure. + */ +int swr_config_frame(SwrContext *swr, const AVFrame *out, const AVFrame *in); + +/** + * @} + * @} + */ + +#endif /* SWRESAMPLE_SWRESAMPLE_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample_frame.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample_frame.c new file mode 100644 index 000000000..2853266d6 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample_frame.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2014 Luca Barbato + * Copyright (c) 2014 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "swresample_internal.h" +#include "libavutil/frame.h" +#include "libavutil/opt.h" + +int swr_config_frame(SwrContext *s, const AVFrame *out, const AVFrame *in) +{ + swr_close(s); + + if (in) { + if (av_opt_set_int(s, "icl", in->channel_layout, 0) < 0) + goto fail; + if (av_opt_set_int(s, "isf", in->format, 0) < 0) + goto fail; + if (av_opt_set_int(s, "isr", in->sample_rate, 0) < 0) + goto fail; + } + + if (out) { + if (av_opt_set_int(s, "ocl", out->channel_layout, 0) < 0) + goto fail; + if (av_opt_set_int(s, "osf", out->format, 0) < 0) + goto fail; + if (av_opt_set_int(s, "osr", out->sample_rate, 0) < 0) + goto fail; + } + + return 0; +fail: + av_log(s, AV_LOG_ERROR, "Failed to set option\n"); + return AVERROR(EINVAL); +} + +static int config_changed(SwrContext *s, + const AVFrame *out, const AVFrame *in) +{ + int ret = 0; + + if (in) { + if (s->in_ch_layout != in->channel_layout || + s->in_sample_rate != in->sample_rate || + s->in_sample_fmt != in->format) { + ret |= AVERROR_INPUT_CHANGED; + } + } + + if (out) { + if (s->out_ch_layout != out->channel_layout || + s->out_sample_rate != out->sample_rate || + s->out_sample_fmt != out->format) { + ret |= AVERROR_OUTPUT_CHANGED; + } + } + + return ret; +} + +static inline int convert_frame(SwrContext *s, + AVFrame *out, const AVFrame *in) +{ + int ret; + uint8_t **out_data = NULL; + const uint8_t **in_data = NULL; + int out_nb_samples = 0, in_nb_samples = 0; + + if (out) { + out_data = out->extended_data; + out_nb_samples = out->nb_samples; + } + + if (in) { + in_data = (const uint8_t **)in->extended_data; + in_nb_samples = in->nb_samples; + } + + ret = swr_convert(s, out_data, out_nb_samples, in_data, in_nb_samples); + + if (ret < 0) { + if (out) + out->nb_samples = 0; + return ret; + } + + if (out) + out->nb_samples = ret; + + return 0; +} + +static inline int available_samples(AVFrame *out) +{ + int bytes_per_sample = av_get_bytes_per_sample(out->format); + int samples = out->linesize[0] / bytes_per_sample; + + if (av_sample_fmt_is_planar(out->format)) { + return samples; + } else { + int channels = av_get_channel_layout_nb_channels(out->channel_layout); + return samples / channels; + } +} + +int swr_convert_frame(SwrContext *s, + AVFrame *out, const AVFrame *in) +{ + int ret, setup = 0; + + if (!swr_is_initialized(s)) { + if ((ret = swr_config_frame(s, out, in)) < 0) + return ret; + if ((ret = swr_init(s)) < 0) + return ret; + setup = 1; + } else { + // return as is or reconfigure for input changes? + if ((ret = config_changed(s, out, in))) + return ret; + } + + if (out) { + if (!out->linesize[0]) { + out->nb_samples = swr_get_delay(s, s->out_sample_rate) + 3; + if (in) { + out->nb_samples += in->nb_samples*(int64_t)s->out_sample_rate / s->in_sample_rate; + } + if ((ret = av_frame_get_buffer(out, 0)) < 0) { + if (setup) + swr_close(s); + return ret; + } + } else { + if (!out->nb_samples) + out->nb_samples = available_samples(out); + } + } + + return convert_frame(s, out, in); +} + diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample_internal.h b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample_internal.h new file mode 100644 index 000000000..f2ea5a226 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresample_internal.h @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWRESAMPLE_SWRESAMPLE_INTERNAL_H +#define SWRESAMPLE_SWRESAMPLE_INTERNAL_H + +#include "swresample.h" +#include "libavutil/channel_layout.h" +#include "config.h" + +#define SWR_CH_MAX 64 + +#define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */ + +#define NS_TAPS 20 + +#if ARCH_X86_64 +typedef int64_t integer; +#else +typedef int integer; +#endif + +typedef void (mix_1_1_func_type)(void *out, const void *in, void *coeffp, integer index, integer len); +typedef void (mix_2_1_func_type)(void *out, const void *in1, const void *in2, void *coeffp, integer index1, integer index2, integer len); + +typedef void (mix_any_func_type)(uint8_t **out, const uint8_t **in1, void *coeffp, integer len); + +typedef struct AudioData{ + uint8_t *ch[SWR_CH_MAX]; ///< samples buffer per channel + uint8_t *data; ///< samples buffer + int ch_count; ///< number of channels + int bps; ///< bytes per sample + int count; ///< number of samples + int planar; ///< 1 if planar audio, 0 otherwise + enum AVSampleFormat fmt; ///< sample format +} AudioData; + +struct DitherContext { + int method; + int noise_pos; + float scale; + float noise_scale; ///< Noise scale + int ns_taps; ///< Noise shaping dither taps + float ns_scale; ///< Noise shaping dither scale + float ns_scale_1; ///< Noise shaping dither scale^-1 + int ns_pos; ///< Noise shaping dither position + float ns_coeffs[NS_TAPS]; ///< Noise shaping filter coefficients + float ns_errors[SWR_CH_MAX][2*NS_TAPS]; + AudioData noise; ///< noise used for dithering + AudioData temp; ///< temporary storage when writing into the input buffer isn't possible + int output_sample_bits; ///< the number of used output bits, needed to scale dither correctly +}; + +typedef struct ResampleContext * (* resample_init_func)(struct ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear, + double cutoff, enum AVSampleFormat format, enum SwrFilterType filter_type, double kaiser_beta, double precision, int cheby, int exact_rational); +typedef void (* resample_free_func)(struct ResampleContext **c); +typedef int (* multiple_resample_func)(struct ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed); +typedef int (* resample_flush_func)(struct SwrContext *c); +typedef int (* set_compensation_func)(struct ResampleContext *c, int sample_delta, int compensation_distance); +typedef int64_t (* get_delay_func)(struct SwrContext *s, int64_t base); +typedef int (* invert_initial_buffer_func)(struct ResampleContext *c, AudioData *dst, const AudioData *src, int src_size, int *dst_idx, int *dst_count); +typedef int64_t (* get_out_samples_func)(struct SwrContext *s, int in_samples); + +struct Resampler { + resample_init_func init; + resample_free_func free; + multiple_resample_func multiple_resample; + resample_flush_func flush; + set_compensation_func set_compensation; + get_delay_func get_delay; + invert_initial_buffer_func invert_initial_buffer; + get_out_samples_func get_out_samples; +}; + +extern struct Resampler const swri_resampler; +extern struct Resampler const swri_soxr_resampler; + +struct SwrContext { + const AVClass *av_class; ///< AVClass used for AVOption and av_log() + int log_level_offset; ///< logging level offset + void *log_ctx; ///< parent logging context + enum AVSampleFormat in_sample_fmt; ///< input sample format + enum AVSampleFormat int_sample_fmt; ///< internal sample format (AV_SAMPLE_FMT_FLTP or AV_SAMPLE_FMT_S16P) + enum AVSampleFormat out_sample_fmt; ///< output sample format + int64_t in_ch_layout; ///< input channel layout + int64_t out_ch_layout; ///< output channel layout + int in_sample_rate; ///< input sample rate + int out_sample_rate; ///< output sample rate + int flags; ///< miscellaneous flags such as SWR_FLAG_RESAMPLE + float slev; ///< surround mixing level + float clev; ///< center mixing level + float lfe_mix_level; ///< LFE mixing level + float rematrix_volume; ///< rematrixing volume coefficient + float rematrix_maxval; ///< maximum value for rematrixing output + int matrix_encoding; /**< matrixed stereo encoding */ + const int *channel_map; ///< channel index (or -1 if muted channel) map + int used_ch_count; ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count) + int engine; + + int user_in_ch_count; ///< User set input channel count + int user_out_ch_count; ///< User set output channel count + int user_used_ch_count; ///< User set used channel count + int64_t user_in_ch_layout; ///< User set input channel layout + int64_t user_out_ch_layout; ///< User set output channel layout + enum AVSampleFormat user_int_sample_fmt; ///< User set internal sample format + int user_dither_method; ///< User set dither method + + struct DitherContext dither; + + int filter_size; /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */ + int phase_shift; /**< log2 of the number of entries in the resampling polyphase filterbank */ + int linear_interp; /**< if 1 then the resampling FIR filter will be linearly interpolated */ + int exact_rational; /**< if 1 then enable non power of 2 phase_count */ + double cutoff; /**< resampling cutoff frequency (swr: 6dB point; soxr: 0dB point). 1.0 corresponds to half the output sample rate */ + int filter_type; /**< swr resampling filter type */ + double kaiser_beta; /**< swr beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */ + double precision; /**< soxr resampling precision (in bits) */ + int cheby; /**< soxr: if 1 then passband rolloff will be none (Chebyshev) & irrational ratio approximation precision will be higher */ + + float min_compensation; ///< swr minimum below which no compensation will happen + float min_hard_compensation; ///< swr minimum below which no silence inject / sample drop will happen + float soft_compensation_duration; ///< swr duration over which soft compensation is applied + float max_soft_compensation; ///< swr maximum soft compensation in seconds over soft_compensation_duration + float async; ///< swr simple 1 parameter async, similar to ffmpegs -async + int64_t firstpts_in_samples; ///< swr first pts in samples + + int resample_first; ///< 1 if resampling must come first, 0 if rematrixing + int rematrix; ///< flag to indicate if rematrixing is needed (basically if input and output layouts mismatch) + int rematrix_custom; ///< flag to indicate that a custom matrix has been defined + + AudioData in; ///< input audio data + AudioData postin; ///< post-input audio data: used for rematrix/resample + AudioData midbuf; ///< intermediate audio data (postin/preout) + AudioData preout; ///< pre-output audio data: used for rematrix/resample + AudioData out; ///< converted output audio data + AudioData in_buffer; ///< cached audio data (convert and resample purpose) + AudioData silence; ///< temporary with silence + AudioData drop_temp; ///< temporary used to discard output + int in_buffer_index; ///< cached buffer position + int in_buffer_count; ///< cached buffer length + int resample_in_constraint; ///< 1 if the input end was reach before the output end, 0 otherwise + int flushed; ///< 1 if data is to be flushed and no further input is expected + int64_t outpts; ///< output PTS + int64_t firstpts; ///< first PTS + int drop_output; ///< number of output samples to drop + double delayed_samples_fixup; ///< soxr 0.1.1: needed to fixup delayed_samples after flush has been called. + + struct AudioConvert *in_convert; ///< input conversion context + struct AudioConvert *out_convert; ///< output conversion context + struct AudioConvert *full_convert; ///< full conversion context (single conversion for input and output) + struct ResampleContext *resample; ///< resampling context + struct Resampler const *resampler; ///< resampler virtual function table + + double matrix[SWR_CH_MAX][SWR_CH_MAX]; ///< floating point rematrixing coefficients + float matrix_flt[SWR_CH_MAX][SWR_CH_MAX]; ///< single precision floating point rematrixing coefficients + uint8_t *native_matrix; + uint8_t *native_one; + uint8_t *native_simd_one; + uint8_t *native_simd_matrix; + int32_t matrix32[SWR_CH_MAX][SWR_CH_MAX]; ///< 17.15 fixed point rematrixing coefficients + uint8_t matrix_ch[SWR_CH_MAX][SWR_CH_MAX+1]; ///< Lists of input channels per output channel that have non zero rematrixing coefficients + mix_1_1_func_type *mix_1_1_f; + mix_1_1_func_type *mix_1_1_simd; + + mix_2_1_func_type *mix_2_1_f; + mix_2_1_func_type *mix_2_1_simd; + + mix_any_func_type *mix_any_f; + + /* TODO: callbacks for ASM optimizations */ +}; + +av_warn_unused_result +int swri_realloc_audio(AudioData *a, int count); + +void swri_noise_shaping_int16 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count); +void swri_noise_shaping_int32 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count); +void swri_noise_shaping_float (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count); +void swri_noise_shaping_double(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count); + +av_warn_unused_result +int swri_rematrix_init(SwrContext *s); +void swri_rematrix_free(SwrContext *s); +int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy); +int swri_rematrix_init_x86(struct SwrContext *s); + +av_warn_unused_result +int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt); +av_warn_unused_result +int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt); + +void swri_audio_convert_init_aarch64(struct AudioConvert *ac, + enum AVSampleFormat out_fmt, + enum AVSampleFormat in_fmt, + int channels); +void swri_audio_convert_init_arm(struct AudioConvert *ac, + enum AVSampleFormat out_fmt, + enum AVSampleFormat in_fmt, + int channels); +void swri_audio_convert_init_x86(struct AudioConvert *ac, + enum AVSampleFormat out_fmt, + enum AVSampleFormat in_fmt, + int channels); + +#endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresampleres.rc b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresampleres.rc new file mode 100644 index 000000000..1320f78b9 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/swresampleres.rc @@ -0,0 +1,55 @@ +/* + * Windows resource file for libswresample + * + * Copyright (C) 2012 James Almer + * Copyright (C) 2013 Tiancheng "Timothy" Gu + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "libswresample/version.h" +#include "libavutil/ffversion.h" +#include "config.h" + +1 VERSIONINFO +FILEVERSION LIBSWRESAMPLE_VERSION_MAJOR, LIBSWRESAMPLE_VERSION_MINOR, LIBSWRESAMPLE_VERSION_MICRO, 0 +PRODUCTVERSION LIBSWRESAMPLE_VERSION_MAJOR, LIBSWRESAMPLE_VERSION_MINOR, LIBSWRESAMPLE_VERSION_MICRO, 0 +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_DLL +{ + BLOCK "StringFileInfo" + { + BLOCK "040904B0" + { + VALUE "CompanyName", "FFmpeg Project" + VALUE "FileDescription", "FFmpeg audio resampling library" + VALUE "FileVersion", AV_STRINGIFY(LIBSWRESAMPLE_VERSION) + VALUE "InternalName", "libswresample" + VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project" + VALUE "OriginalFilename", "swresample" BUILDSUF "-" AV_STRINGIFY(LIBSWRESAMPLE_VERSION_MAJOR) SLIBSUF + VALUE "ProductName", "FFmpeg" + VALUE "ProductVersion", FFMPEG_VERSION + } + } + + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 0x04B0 + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/version.h b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/version.h new file mode 100644 index 000000000..a0b361bc1 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/version.h @@ -0,0 +1,45 @@ +/* + * Version macros. + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWRESAMPLE_VERSION_H +#define SWRESAMPLE_VERSION_H + +/** + * @file + * Libswresample version macros + */ + +#include "libavutil/avutil.h" + +#define LIBSWRESAMPLE_VERSION_MAJOR 3 +#define LIBSWRESAMPLE_VERSION_MINOR 5 +#define LIBSWRESAMPLE_VERSION_MICRO 100 + +#define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ + LIBSWRESAMPLE_VERSION_MINOR, \ + LIBSWRESAMPLE_VERSION_MICRO) +#define LIBSWRESAMPLE_VERSION AV_VERSION(LIBSWRESAMPLE_VERSION_MAJOR, \ + LIBSWRESAMPLE_VERSION_MINOR, \ + LIBSWRESAMPLE_VERSION_MICRO) +#define LIBSWRESAMPLE_BUILD LIBSWRESAMPLE_VERSION_INT + +#define LIBSWRESAMPLE_IDENT "SwR" AV_STRINGIFY(LIBSWRESAMPLE_VERSION) + +#endif /* SWRESAMPLE_VERSION_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/audio_convert_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/audio_convert_init.c new file mode 100644 index 000000000..bb89cf604 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/audio_convert_init.c @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/x86/cpu.h" +#include "libswresample/swresample_internal.h" +#include "libswresample/audioconvert.h" + +#define PROTO(pre, in, out, cap) void ff ## pre ## in## _to_ ##out## _a_ ##cap(uint8_t **dst, const uint8_t **src, int len); +#define PROTO2(pre, out, cap) PROTO(pre, int16, out, cap) PROTO(pre, int32, out, cap) PROTO(pre, float, out, cap) +#define PROTO3(pre, cap) PROTO2(pre, int16, cap) PROTO2(pre, int32, cap) PROTO2(pre, float, cap) +#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, sse4) PROTO3(pre, avx) PROTO3(pre, avx2) +PROTO4(_) +PROTO4(_pack_2ch_) +PROTO4(_pack_6ch_) +PROTO4(_pack_8ch_) +PROTO4(_unpack_2ch_) +PROTO4(_unpack_6ch_) + +av_cold void swri_audio_convert_init_x86(struct AudioConvert *ac, + enum AVSampleFormat out_fmt, + enum AVSampleFormat in_fmt, + int channels){ + int mm_flags = av_get_cpu_flags(); + + ac->simd_f= NULL; + +//FIXME add memcpy case + +#define MULTI_CAPS_FUNC(flag, cap) \ + if (EXTERNAL_##flag(mm_flags)) {\ + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16P)\ + ac->simd_f = ff_int16_to_int32_a_ ## cap;\ + if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S32P)\ + ac->simd_f = ff_int32_to_int16_a_ ## cap;\ + } + +MULTI_CAPS_FUNC(MMX, mmx) +MULTI_CAPS_FUNC(SSE2, sse2) + + if(EXTERNAL_MMX(mm_flags)) { + if(channels == 6) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_6ch_float_to_float_a_mmx; + } + } + if(EXTERNAL_SSE(mm_flags)) { + if(channels == 6) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_6ch_float_to_float_a_sse; + + if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S32) + ac->simd_f = ff_unpack_6ch_float_to_float_a_sse; + } + } + if(EXTERNAL_SSE2(mm_flags)) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_int32_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16P) + ac->simd_f = ff_int16_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = ff_float_to_int32_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = ff_float_to_int16_a_sse2; + + if(channels == 2) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_2ch_int32_to_int32_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S16P) + ac->simd_f = ff_pack_2ch_int16_to_int16_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S16P) + ac->simd_f = ff_pack_2ch_int16_to_int32_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_2ch_int32_to_int16_a_sse2; + + if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S32) + ac->simd_f = ff_unpack_2ch_int32_to_int32_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S16) + ac->simd_f = ff_unpack_2ch_int16_to_int16_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16) + ac->simd_f = ff_unpack_2ch_int16_to_int32_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S32) + ac->simd_f = ff_unpack_2ch_int32_to_int16_a_sse2; + + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_2ch_int32_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = ff_pack_2ch_float_to_int32_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S16P) + ac->simd_f = ff_pack_2ch_int16_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = ff_pack_2ch_float_to_int16_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32) + ac->simd_f = ff_unpack_2ch_int32_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLT) + ac->simd_f = ff_unpack_2ch_float_to_int32_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16) + ac->simd_f = ff_unpack_2ch_int16_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLT) + ac->simd_f = ff_unpack_2ch_float_to_int16_a_sse2; + } + if(channels == 6) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_6ch_int32_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = ff_pack_6ch_float_to_int32_a_sse2; + + if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32) + ac->simd_f = ff_unpack_6ch_int32_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLT) + ac->simd_f = ff_unpack_6ch_float_to_int32_a_sse2; + } + if(channels == 8) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_8ch_float_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_8ch_int32_to_float_a_sse2; + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = ff_pack_8ch_float_to_int32_a_sse2; + } + } + if(EXTERNAL_SSSE3(mm_flags)) { + if(channels == 2) { + if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S16) + ac->simd_f = ff_unpack_2ch_int16_to_int16_a_ssse3; + if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16) + ac->simd_f = ff_unpack_2ch_int16_to_int32_a_ssse3; + if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16) + ac->simd_f = ff_unpack_2ch_int16_to_float_a_ssse3; + } + } + if(EXTERNAL_AVX_FAST(mm_flags)) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_int32_to_float_a_avx; + } + if(EXTERNAL_AVX(mm_flags)) { + if(channels == 6) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_6ch_float_to_float_a_avx; + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_6ch_int32_to_float_a_avx; + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = ff_pack_6ch_float_to_int32_a_avx; + + if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S32) + ac->simd_f = ff_unpack_6ch_float_to_float_a_avx; + if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32) + ac->simd_f = ff_unpack_6ch_int32_to_float_a_avx; + if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLT) + ac->simd_f = ff_unpack_6ch_float_to_int32_a_avx; + } + if(channels == 8) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_8ch_float_to_float_a_avx; + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_8ch_int32_to_float_a_avx; + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = ff_pack_8ch_float_to_int32_a_avx; + } + } + if(EXTERNAL_AVX2_FAST(mm_flags)) { + if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLTP) + ac->simd_f = ff_float_to_int32_a_avx2; + } +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/rematrix_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/rematrix_init.c new file mode 100644 index 000000000..d6616f83b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/rematrix_init.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/x86/cpu.h" +#include "libswresample/swresample_internal.h" + +#define D(type, simd) \ +mix_1_1_func_type ff_mix_1_1_a_## type ## _ ## simd;\ +mix_2_1_func_type ff_mix_2_1_a_## type ## _ ## simd; + +D(float, sse) +D(float, avx) +D(int16, mmx) +D(int16, sse2) + +av_cold int swri_rematrix_init_x86(struct SwrContext *s){ +#if HAVE_X86ASM + int mm_flags = av_get_cpu_flags(); + int nb_in = s->used_ch_count; + int nb_out = s->out.ch_count; + int num = nb_in * nb_out; + int i,j; + + s->mix_1_1_simd = NULL; + s->mix_2_1_simd = NULL; + + if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){ + if(EXTERNAL_MMX(mm_flags)) { + s->mix_1_1_simd = ff_mix_1_1_a_int16_mmx; + s->mix_2_1_simd = ff_mix_2_1_a_int16_mmx; + } + if(EXTERNAL_SSE2(mm_flags)) { + s->mix_1_1_simd = ff_mix_1_1_a_int16_sse2; + s->mix_2_1_simd = ff_mix_2_1_a_int16_sse2; + } + s->native_simd_matrix = av_mallocz_array(num, 2 * sizeof(int16_t)); + s->native_simd_one = av_mallocz(2 * sizeof(int16_t)); + if (!s->native_simd_matrix || !s->native_simd_one) + return AVERROR(ENOMEM); + + for(i=0; inative_matrix)[i * nb_in + j])); + sh = FFMAX(av_log2(sh) - 14, 0); + for(j=0; jnative_simd_matrix)[2*(i * nb_in + j)+1] = 15 - sh; + ((int16_t*)s->native_simd_matrix)[2*(i * nb_in + j)] = + ((((int*)s->native_matrix)[i * nb_in + j]) + (1<>1)) >> sh; + } + } + ((int16_t*)s->native_simd_one)[1] = 14; + ((int16_t*)s->native_simd_one)[0] = 16384; + } else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){ + if(EXTERNAL_SSE(mm_flags)) { + s->mix_1_1_simd = ff_mix_1_1_a_float_sse; + s->mix_2_1_simd = ff_mix_2_1_a_float_sse; + } + if(EXTERNAL_AVX_FAST(mm_flags)) { + s->mix_1_1_simd = ff_mix_1_1_a_float_avx; + s->mix_2_1_simd = ff_mix_2_1_a_float_avx; + } + s->native_simd_matrix = av_mallocz_array(num, sizeof(float)); + s->native_simd_one = av_mallocz(sizeof(float)); + if (!s->native_simd_matrix || !s->native_simd_one) + return AVERROR(ENOMEM); + memcpy(s->native_simd_matrix, s->native_matrix, num * sizeof(float)); + memcpy(s->native_simd_one, s->native_one, sizeof(float)); + } +#endif + + return 0; +} diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/resample_init.c b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/resample_init.c new file mode 100644 index 000000000..c6b2a3606 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/resample_init.c @@ -0,0 +1,100 @@ +/* + * audio resampling + * Copyright (c) 2004-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * audio resampling + * @author Michael Niedermayer + */ + +#include "libavutil/x86/cpu.h" +#include "libswresample/resample.h" + +#define RESAMPLE_FUNCS(type, opt) \ +int ff_resample_common_##type##_##opt(ResampleContext *c, void *dst, \ + const void *src, int sz, int upd); \ +int ff_resample_linear_##type##_##opt(ResampleContext *c, void *dst, \ + const void *src, int sz, int upd) + +RESAMPLE_FUNCS(int16, mmxext); +RESAMPLE_FUNCS(int16, sse2); +RESAMPLE_FUNCS(int16, xop); +RESAMPLE_FUNCS(float, sse); +RESAMPLE_FUNCS(float, avx); +RESAMPLE_FUNCS(float, fma3); +RESAMPLE_FUNCS(float, fma4); +RESAMPLE_FUNCS(double, sse2); +RESAMPLE_FUNCS(double, avx); +RESAMPLE_FUNCS(double, fma3); + +av_cold void swri_resample_dsp_x86_init(ResampleContext *c) +{ + int av_unused mm_flags = av_get_cpu_flags(); + + switch(c->format){ + case AV_SAMPLE_FMT_S16P: + if (ARCH_X86_32 && EXTERNAL_MMXEXT(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_int16_mmxext; + c->dsp.resample_common = ff_resample_common_int16_mmxext; + } + if (EXTERNAL_SSE2(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_int16_sse2; + c->dsp.resample_common = ff_resample_common_int16_sse2; + } + if (EXTERNAL_XOP(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_int16_xop; + c->dsp.resample_common = ff_resample_common_int16_xop; + } + break; + case AV_SAMPLE_FMT_FLTP: + if (EXTERNAL_SSE(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_float_sse; + c->dsp.resample_common = ff_resample_common_float_sse; + } + if (EXTERNAL_AVX_FAST(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_float_avx; + c->dsp.resample_common = ff_resample_common_float_avx; + } + if (EXTERNAL_FMA3_FAST(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_float_fma3; + c->dsp.resample_common = ff_resample_common_float_fma3; + } + if (EXTERNAL_FMA4(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_float_fma4; + c->dsp.resample_common = ff_resample_common_float_fma4; + } + break; + case AV_SAMPLE_FMT_DBLP: + if (EXTERNAL_SSE2(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_double_sse2; + c->dsp.resample_common = ff_resample_common_double_sse2; + } + if (EXTERNAL_AVX_FAST(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_double_avx; + c->dsp.resample_common = ff_resample_common_double_avx; + } + if (EXTERNAL_FMA3_FAST(mm_flags)) { + c->dsp.resample_linear = ff_resample_linear_double_fma3; + c->dsp.resample_common = ff_resample_common_double_fma3; + } + break; + } +} diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh index 786c8aef8..29834e44f 100755 --- a/trunk/auto/depends.sh +++ b/trunk/auto/depends.sh @@ -400,7 +400,6 @@ fi # libopus, for WebRTC to transcode AAC with Opus. ##################################################################################### if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then - # cross build not specified, if exists flag, need to rebuild for no-arm platform. if [[ -f ${SRS_OBJS}/opus/lib/libopus.a ]]; then echo "The opus-1.3.1 is ok."; else @@ -417,6 +416,70 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then if [ ! -f ${SRS_OBJS}/opus/lib/libopus.a ]; then echo "Build opus-1.3.1 failed."; exit -1; fi fi +##################################################################################### +# ffmpeg-fix, for WebRTC to transcode AAC with Opus. +##################################################################################### +if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then + if [[ -f ${SRS_OBJS}/ffmpeg/lib/libavcodec.a ]]; then + echo "The ffmpeg-4.2-fit is ok."; + else + echo "Building ffmpeg-4.2-fit."; + ( + rm -rf ${SRS_OBJS}/ffmpeg-4.2-fit && cd ${SRS_OBJS} && ABS_OBJS=`pwd` && + ln -sf ../3rdparty/ffmpeg-4.2-fit && cd ffmpeg-4.2-fit && + PKG_CONFIG_PATH=$ABS_OBJS/opus/lib/pkgconfig ./configure \ + --prefix=`pwd`/_release \ + --pkg-config-flags="--static" \ + --extra-libs=-lpthread \ + --extra-libs=-lm \ + --disable-programs \ + --disable-doc \ + --disable-htmlpages \ + --disable-manpages \ + --disable-podpages \ + --disable-txtpages \ + --disable-avdevice \ + --disable-avformat \ + --disable-swscale \ + --disable-postproc \ + --disable-avfilter \ + --disable-network \ + --disable-dct \ + --disable-dwt \ + --disable-error-resilience \ + --disable-lsp \ + --disable-lzo \ + --disable-faan \ + --disable-pixelutils \ + --disable-hwaccels \ + --disable-devices \ + --disable-audiotoolbox \ + --disable-videotoolbox \ + --disable-appkit \ + --disable-coreimage \ + --disable-avfoundation \ + --disable-securetransport \ + --disable-iconv \ + --disable-lzma \ + --disable-sdl2 \ + --disable-everything \ + --enable-decoder=aac \ + --enable-decoder=aac_fixed \ + --enable-decoder=aac_latm \ + --enable-decoder=libopus \ + --enable-encoder=aac \ + --enable-encoder=opus \ + --enable-encoder=libopus \ + --enable-libopus && + make ${SRS_JOBS} && make install + cd .. && rm -rf ffmpeg && ln -sf ffmpeg-4.2-fit/_release ffmpeg + ) + fi + # check status + ret=$?; if [[ $ret -ne 0 ]]; then echo "Build ffmpeg-4.2-fit failed, ret=$ret"; exit $ret; fi + if [ ! -f ${SRS_OBJS}/ffmpeg/lib/libavcodec.a ]; then echo "Build ffmpeg-4.2-fit failed."; exit -1; fi +fi + ##################################################################################### # live transcoding, ffmpeg-4.1, x264-core157, lame-3.99.5, libaacplus-2.0.2. ##################################################################################### From 37c84eccc02181c3466b52ad634b5f1a3a16ae0a Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 22 Mar 2020 17:14:07 +0800 Subject: [PATCH 3/4] For #1659, #307, add x86 asm for ffmpeg for rtc --- trunk/3rdparty/ffmpeg-4.2-fit/.gitignore | 3 +- .../libavcodec/aarch64/Makefile | 60 + .../ffmpeg-4.2-fit/libavcodec/x86/Makefile | 199 ++ .../libavcodec/x86/aacencdsp.asm | 86 + .../libavcodec/x86/aacpsdsp.asm | 487 +++++ .../libavcodec/x86/celt_pvq_search.asm | 385 ++++ .../ffmpeg-4.2-fit/libavcodec/x86/fft.asm | 1085 +++++++++++ .../ffmpeg-4.2-fit/libavcodec/x86/mdct15.asm | 221 +++ .../ffmpeg-4.2-fit/libavcodec/x86/sbrdsp.asm | 548 ++++++ .../ffmpeg-4.2-fit/libavutil/aarch64/Makefile | 4 + .../ffmpeg-4.2-fit/libavutil/arm/Makefile | 8 + .../ffmpeg-4.2-fit/libavutil/ffversion.h | 5 - .../ffmpeg-4.2-fit/libavutil/x86/Makefile | 18 + .../ffmpeg-4.2-fit/libavutil/x86/cpuid.asm | 91 + .../libavutil/x86/fixed_dsp.asm | 48 + .../libavutil/x86/float_dsp.asm | 484 +++++ .../ffmpeg-4.2-fit/libavutil/x86/imgutils.asm | 53 + .../ffmpeg-4.2-fit/libavutil/x86/lls.asm | 290 +++ .../ffmpeg-4.2-fit/libavutil/x86/x86inc.asm | 1701 +++++++++++++++++ .../ffmpeg-4.2-fit/libavutil/x86/x86util.asm | 1028 ++++++++++ .../libswresample/aarch64/Makefile | 7 + .../ffmpeg-4.2-fit/libswresample/arm/Makefile | 8 + .../ffmpeg-4.2-fit/libswresample/x86/Makefile | 9 + .../libswresample/x86/audio_convert.asm | 739 +++++++ .../libswresample/x86/rematrix.asm | 250 +++ .../libswresample/x86/resample.asm | 619 ++++++ trunk/auto/depends.sh | 50 +- trunk/configure | 5 +- 28 files changed, 8441 insertions(+), 50 deletions(-) create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacencdsp.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacpsdsp.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/celt_pvq_search.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mdct15.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbrdsp.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/Makefile delete mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffversion.h create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpuid.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/fixed_dsp.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/float_dsp.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/imgutils.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/lls.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/x86inc.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/x86util.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/Makefile create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/audio_convert.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/rematrix.asm create mode 100644 trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/resample.asm diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/.gitignore b/trunk/3rdparty/ffmpeg-4.2-fit/.gitignore index c348b5e28..9ce1b69cd 100644 --- a/trunk/3rdparty/ffmpeg-4.2-fit/.gitignore +++ b/trunk/3rdparty/ffmpeg-4.2-fit/.gitignore @@ -14,4 +14,5 @@ ffbuild/.config libavutil/lib.version libavcodec/libavcodec.version libavutil/libavutil.version -libswresample/libswresample.version \ No newline at end of file +libswresample/libswresample.version +libavutil/ffversion.h \ No newline at end of file diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/Makefile new file mode 100644 index 000000000..00f93bf59 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/aarch64/Makefile @@ -0,0 +1,60 @@ +# subsystems +OBJS-$(CONFIG_FFT) += aarch64/fft_init_aarch64.o +OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_init.o +OBJS-$(CONFIG_H264CHROMA) += aarch64/h264chroma_init_aarch64.o +OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_init_aarch64.o +OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_init.o +OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_init_aarch64.o +OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_init_aarch64.o +OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_init.o +OBJS-$(CONFIG_NEON_CLOBBER_TEST) += aarch64/neontest.o +OBJS-$(CONFIG_VIDEODSP) += aarch64/videodsp_init.o +OBJS-$(CONFIG_VP8DSP) += aarch64/vp8dsp_init_aarch64.o + +# decoders/encoders +OBJS-$(CONFIG_AAC_DECODER) += aarch64/aacpsdsp_init_aarch64.o \ + aarch64/sbrdsp_init_aarch64.o +OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_init.o +OBJS-$(CONFIG_OPUS_DECODER) += aarch64/opusdsp_init.o +OBJS-$(CONFIG_RV40_DECODER) += aarch64/rv40dsp_init_aarch64.o +OBJS-$(CONFIG_VC1DSP) += aarch64/vc1dsp_init_aarch64.o +OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_init.o +OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9dsp_init_10bpp_aarch64.o \ + aarch64/vp9dsp_init_12bpp_aarch64.o \ + aarch64/vp9dsp_init_aarch64.o + +# ARMv8 optimizations + +# subsystems +ARMV8-OBJS-$(CONFIG_VIDEODSP) += aarch64/videodsp.o + +# NEON optimizations + +# subsystems +NEON-OBJS-$(CONFIG_AAC_DECODER) += aarch64/sbrdsp_neon.o +NEON-OBJS-$(CONFIG_FFT) += aarch64/fft_neon.o +NEON-OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_neon.o +NEON-OBJS-$(CONFIG_H264CHROMA) += aarch64/h264cmc_neon.o +NEON-OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_neon.o \ + aarch64/h264idct_neon.o +NEON-OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_neon.o +NEON-OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_neon.o \ + aarch64/hpeldsp_neon.o +NEON-OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_neon.o +NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/idctdsp_init_aarch64.o \ + aarch64/simple_idct_neon.o +NEON-OBJS-$(CONFIG_MDCT) += aarch64/mdct_neon.o +NEON-OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_neon.o +NEON-OBJS-$(CONFIG_VP8DSP) += aarch64/vp8dsp_neon.o + +# decoders/encoders +NEON-OBJS-$(CONFIG_AAC_DECODER) += aarch64/aacpsdsp_neon.o +NEON-OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_neon.o +NEON-OBJS-$(CONFIG_OPUS_DECODER) += aarch64/opusdsp_neon.o +NEON-OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_neon.o +NEON-OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9itxfm_16bpp_neon.o \ + aarch64/vp9itxfm_neon.o \ + aarch64/vp9lpf_16bpp_neon.o \ + aarch64/vp9lpf_neon.o \ + aarch64/vp9mc_16bpp_neon.o \ + aarch64/vp9mc_neon.o diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/Makefile new file mode 100644 index 000000000..194135daf --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/Makefile @@ -0,0 +1,199 @@ +OBJS += x86/constants.o \ + +# subsystems +OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp_init.o +OBJS-$(CONFIG_AUDIODSP) += x86/audiodsp_init.o +OBJS-$(CONFIG_BLOCKDSP) += x86/blockdsp_init.o +OBJS-$(CONFIG_BSWAPDSP) += x86/bswapdsp_init.o +OBJS-$(CONFIG_DCT) += x86/dct_init.o +OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp_init.o \ + x86/dirac_dwt_init.o +OBJS-$(CONFIG_FDCTDSP) += x86/fdctdsp_init.o +OBJS-$(CONFIG_FFT) += x86/fft_init.o +OBJS-$(CONFIG_FLACDSP) += x86/flacdsp_init.o +OBJS-$(CONFIG_FMTCONVERT) += x86/fmtconvert_init.o +OBJS-$(CONFIG_H263DSP) += x86/h263dsp_init.o +OBJS-$(CONFIG_H264CHROMA) += x86/h264chroma_init.o +OBJS-$(CONFIG_H264DSP) += x86/h264dsp_init.o +OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o +OBJS-$(CONFIG_H264QPEL) += x86/h264_qpel.o +OBJS-$(CONFIG_HPELDSP) += x86/hpeldsp_init.o +OBJS-$(CONFIG_LLAUDDSP) += x86/lossless_audiodsp_init.o +OBJS-$(CONFIG_LLVIDDSP) += x86/lossless_videodsp_init.o +OBJS-$(CONFIG_LLVIDENCDSP) += x86/lossless_videoencdsp_init.o +OBJS-$(CONFIG_HUFFYUVDSP) += x86/huffyuvdsp_init.o +OBJS-$(CONFIG_HUFFYUVENCDSP) += x86/huffyuvencdsp_init.o +OBJS-$(CONFIG_IDCTDSP) += x86/idctdsp_init.o +OBJS-$(CONFIG_LPC) += x86/lpc.o +OBJS-$(CONFIG_MDCT15) += x86/mdct15_init.o +OBJS-$(CONFIG_ME_CMP) += x86/me_cmp_init.o +OBJS-$(CONFIG_MPEGAUDIODSP) += x86/mpegaudiodsp.o +OBJS-$(CONFIG_MPEGVIDEO) += x86/mpegvideo.o \ + x86/mpegvideodsp.o +OBJS-$(CONFIG_MPEGVIDEOENC) += x86/mpegvideoenc.o \ + x86/mpegvideoencdsp_init.o +OBJS-$(CONFIG_PIXBLOCKDSP) += x86/pixblockdsp_init.o +OBJS-$(CONFIG_QPELDSP) += x86/qpeldsp_init.o +OBJS-$(CONFIG_RV34DSP) += x86/rv34dsp_init.o +OBJS-$(CONFIG_VC1DSP) += x86/vc1dsp_init.o +OBJS-$(CONFIG_VIDEODSP) += x86/videodsp_init.o +OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp_init.o +OBJS-$(CONFIG_VP8DSP) += x86/vp8dsp_init.o +OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o + +# decoders/encoders +OBJS-$(CONFIG_AAC_DECODER) += x86/aacpsdsp_init.o \ + x86/sbrdsp_init.o +OBJS-$(CONFIG_AAC_ENCODER) += x86/aacencdsp_init.o +OBJS-$(CONFIG_ADPCM_G722_DECODER) += x86/g722dsp_init.o +OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp_init.o +OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp_init.o +OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp_init.o +OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp.o +OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp_init.o x86/synth_filter_init.o +OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc_init.o +OBJS-$(CONFIG_EXR_DECODER) += x86/exrdsp_init.o +OBJS-$(CONFIG_OPUS_DECODER) += x86/opusdsp_init.o +OBJS-$(CONFIG_OPUS_ENCODER) += x86/celt_pvq_init.o +OBJS-$(CONFIG_HEVC_DECODER) += x86/hevcdsp_init.o +OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp_init.o +OBJS-$(CONFIG_LSCR_DECODER) += x86/pngdsp_init.o +OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp_init.o +OBJS-$(CONFIG_MPEG4_DECODER) += x86/xvididct_init.o +OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp_init.o +OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp_init.o +OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp_init.o +OBJS-$(CONFIG_RV40_DECODER) += x86/rv40dsp_init.o +OBJS-$(CONFIG_SBC_ENCODER) += x86/sbcdsp_init.o +OBJS-$(CONFIG_SVQ1_ENCODER) += x86/svq1enc_init.o +OBJS-$(CONFIG_TAK_DECODER) += x86/takdsp_init.o +OBJS-$(CONFIG_TRUEHD_DECODER) += x86/mlpdsp_init.o +OBJS-$(CONFIG_TTA_DECODER) += x86/ttadsp_init.o +OBJS-$(CONFIG_TTA_ENCODER) += x86/ttaencdsp_init.o +OBJS-$(CONFIG_UTVIDEO_DECODER) += x86/utvideodsp_init.o +OBJS-$(CONFIG_V210_DECODER) += x86/v210-init.o +OBJS-$(CONFIG_V210_ENCODER) += x86/v210enc_init.o +OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp_init.o +OBJS-$(CONFIG_VP3_DECODER) += x86/hpeldsp_vp3_init.o +OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp_init.o +OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp_init.o \ + x86/vp9dsp_init_10bpp.o \ + x86/vp9dsp_init_12bpp.o \ + x86/vp9dsp_init_16bpp.o +OBJS-$(CONFIG_WEBP_DECODER) += x86/vp8dsp_init.o + + +# GCC inline assembly optimizations +# subsystems +MMX-OBJS-$(CONFIG_FDCTDSP) += x86/fdct.o +MMX-OBJS-$(CONFIG_VC1DSP) += x86/vc1dsp_mmx.o + +# decoders/encoders +MMX-OBJS-$(CONFIG_SNOW_DECODER) += x86/snowdsp.o +MMX-OBJS-$(CONFIG_SNOW_ENCODER) += x86/snowdsp.o + +# subsystems +X86ASM-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp.o \ + x86/ac3dsp_downmix.o +X86ASM-OBJS-$(CONFIG_AUDIODSP) += x86/audiodsp.o +X86ASM-OBJS-$(CONFIG_BLOCKDSP) += x86/blockdsp.o +X86ASM-OBJS-$(CONFIG_BSWAPDSP) += x86/bswapdsp.o +X86ASM-OBJS-$(CONFIG_DCT) += x86/dct32.o +X86ASM-OBJS-$(CONFIG_FFT) += x86/fft.o +X86ASM-OBJS-$(CONFIG_FMTCONVERT) += x86/fmtconvert.o +X86ASM-OBJS-$(CONFIG_H263DSP) += x86/h263_loopfilter.o +X86ASM-OBJS-$(CONFIG_H264CHROMA) += x86/h264_chromamc.o \ + x86/h264_chromamc_10bit.o +X86ASM-OBJS-$(CONFIG_H264DSP) += x86/h264_deblock.o \ + x86/h264_deblock_10bit.o \ + x86/h264_idct.o \ + x86/h264_idct_10bit.o \ + x86/h264_weight.o \ + x86/h264_weight_10bit.o +X86ASM-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred.o \ + x86/h264_intrapred_10bit.o +X86ASM-OBJS-$(CONFIG_H264QPEL) += x86/h264_qpel_8bit.o \ + x86/h264_qpel_10bit.o \ + x86/fpel.o \ + x86/qpel.o +X86ASM-OBJS-$(CONFIG_HPELDSP) += x86/fpel.o \ + x86/hpeldsp.o +X86ASM-OBJS-$(CONFIG_HUFFYUVDSP) += x86/huffyuvdsp.o +X86ASM-OBJS-$(CONFIG_HUFFYUVENCDSP) += x86/huffyuvencdsp.o +X86ASM-OBJS-$(CONFIG_IDCTDSP) += x86/idctdsp.o +X86ASM-OBJS-$(CONFIG_LLAUDDSP) += x86/lossless_audiodsp.o +X86ASM-OBJS-$(CONFIG_LLVIDDSP) += x86/lossless_videodsp.o +X86ASM-OBJS-$(CONFIG_LLVIDENCDSP) += x86/lossless_videoencdsp.o +X86ASM-OBJS-$(CONFIG_MDCT15) += x86/mdct15.o +X86ASM-OBJS-$(CONFIG_ME_CMP) += x86/me_cmp.o +X86ASM-OBJS-$(CONFIG_MPEGAUDIODSP) += x86/imdct36.o +X86ASM-OBJS-$(CONFIG_MPEGVIDEOENC) += x86/mpegvideoencdsp.o +X86ASM-OBJS-$(CONFIG_OPUS_DECODER) += x86/opusdsp.o +X86ASM-OBJS-$(CONFIG_OPUS_ENCODER) += x86/celt_pvq_search.o +X86ASM-OBJS-$(CONFIG_PIXBLOCKDSP) += x86/pixblockdsp.o +X86ASM-OBJS-$(CONFIG_QPELDSP) += x86/qpeldsp.o \ + x86/fpel.o \ + x86/qpel.o +X86ASM-OBJS-$(CONFIG_RV34DSP) += x86/rv34dsp.o +X86ASM-OBJS-$(CONFIG_VC1DSP) += x86/vc1dsp_loopfilter.o \ + x86/vc1dsp_mc.o +X86ASM-OBJS-$(CONFIG_IDCTDSP) += x86/simple_idct10.o \ + x86/simple_idct.o +X86ASM-OBJS-$(CONFIG_VIDEODSP) += x86/videodsp.o +X86ASM-OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp.o +X86ASM-OBJS-$(CONFIG_VP8DSP) += x86/vp8dsp.o \ + x86/vp8dsp_loopfilter.o + +# decoders/encoders +X86ASM-OBJS-$(CONFIG_AAC_DECODER) += x86/aacpsdsp.o \ + x86/sbrdsp.o +X86ASM-OBJS-$(CONFIG_AAC_ENCODER) += x86/aacencdsp.o +X86ASM-OBJS-$(CONFIG_ADPCM_G722_DECODER) += x86/g722dsp.o +X86ASM-OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp.o +X86ASM-OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp.o +X86ASM-OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp.o +X86ASM-OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsidct.o +X86ASM-OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp.o x86/synth_filter.o +X86ASM-OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp.o \ + x86/dirac_dwt.o +X86ASM-OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc.o +X86ASM-OBJS-$(CONFIG_EXR_DECODER) += x86/exrdsp.o +X86ASM-OBJS-$(CONFIG_FLAC_DECODER) += x86/flacdsp.o +ifdef CONFIG_GPL +X86ASM-OBJS-$(CONFIG_FLAC_ENCODER) += x86/flac_dsp_gpl.o +endif +X86ASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc_add_res.o \ + x86/hevc_deblock.o \ + x86/hevc_idct.o \ + x86/hevc_mc.o \ + x86/hevc_sao.o \ + x86/hevc_sao_10bit.o +X86ASM-OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp.o +X86ASM-OBJS-$(CONFIG_LSCR_DECODER) += x86/pngdsp.o +X86ASM-OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp.o +X86ASM-OBJS-$(CONFIG_MPEG4_DECODER) += x86/xvididct.o +X86ASM-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp.o +X86ASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o +X86ASM-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp.o +X86ASM-OBJS-$(CONFIG_RV40_DECODER) += x86/rv40dsp.o +X86ASM-OBJS-$(CONFIG_SBC_ENCODER) += x86/sbcdsp.o +X86ASM-OBJS-$(CONFIG_SVQ1_ENCODER) += x86/svq1enc.o +X86ASM-OBJS-$(CONFIG_TAK_DECODER) += x86/takdsp.o +X86ASM-OBJS-$(CONFIG_TRUEHD_DECODER) += x86/mlpdsp.o +X86ASM-OBJS-$(CONFIG_TTA_DECODER) += x86/ttadsp.o +X86ASM-OBJS-$(CONFIG_TTA_ENCODER) += x86/ttaencdsp.o +X86ASM-OBJS-$(CONFIG_UTVIDEO_DECODER) += x86/utvideodsp.o +X86ASM-OBJS-$(CONFIG_V210_ENCODER) += x86/v210enc.o +X86ASM-OBJS-$(CONFIG_V210_DECODER) += x86/v210.o +X86ASM-OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp.o +X86ASM-OBJS-$(CONFIG_VP3_DECODER) += x86/hpeldsp_vp3.o +X86ASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp.o +X86ASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9intrapred.o \ + x86/vp9intrapred_16bpp.o \ + x86/vp9itxfm.o \ + x86/vp9itxfm_16bpp.o \ + x86/vp9lpf.o \ + x86/vp9lpf_16bpp.o \ + x86/vp9mc.o \ + x86/vp9mc_16bpp.o +X86ASM-OBJS-$(CONFIG_WEBP_DECODER) += x86/vp8dsp.o diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacencdsp.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacencdsp.asm new file mode 100644 index 000000000..97af571ec --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacencdsp.asm @@ -0,0 +1,86 @@ +;****************************************************************************** +;* SIMD optimized AAC encoder DSP functions +;* +;* Copyright (C) 2016 Rostislav Pehlivanov +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA + +float_abs_mask: times 4 dd 0x7fffffff + +SECTION .text + +;******************************************************************* +;void ff_abs_pow34(float *out, const float *in, const int size); +;******************************************************************* +INIT_XMM sse +cglobal abs_pow34, 3, 3, 3, out, in, size + mova m2, [float_abs_mask] + shl sizeq, 2 + add inq, sizeq + add outq, sizeq + neg sizeq +.loop: + andps m0, m2, [inq+sizeq] + sqrtps m1, m0 + mulps m0, m1 + sqrtps m0, m0 + mova [outq+sizeq], m0 + add sizeq, mmsize + jl .loop + RET + +;******************************************************************* +;void ff_aac_quantize_bands(int *out, const float *in, const float *scaled, +; int size, int is_signed, int maxval, const float Q34, +; const float rounding) +;******************************************************************* +INIT_XMM sse2 +cglobal aac_quantize_bands, 5, 5, 6, out, in, scaled, size, is_signed, maxval, Q34, rounding +%if UNIX64 == 0 + movss m0, Q34m + movss m1, roundingm + cvtsi2ss m3, dword maxvalm +%else + cvtsi2ss m3, maxvald +%endif + shufps m0, m0, 0 + shufps m1, m1, 0 + shufps m3, m3, 0 + shl is_signedd, 31 + movd m4, is_signedd + shufps m4, m4, 0 + shl sized, 2 + add inq, sizeq + add outq, sizeq + add scaledq, sizeq + neg sizeq +.loop: + mulps m2, m0, [scaledq+sizeq] + addps m2, m1 + minps m2, m3 + andps m5, m4, [inq+sizeq] + orps m2, m5 + cvttps2dq m2, m2 + mova [outq+sizeq], m2 + add sizeq, mmsize + jl .loop + RET diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacpsdsp.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacpsdsp.asm new file mode 100644 index 000000000..4acd087c8 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/aacpsdsp.asm @@ -0,0 +1,487 @@ +;****************************************************************************** +;* SIMD optimized MPEG-4 Parametric Stereo decoding functions +;* +;* Copyright (C) 2015 James Almer +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA + +ps_p1m1p1m1: dd 0, 0x80000000, 0, 0x80000000 + +SECTION .text + +;************************************************************************* +;void ff_ps_add_squares_(float *dst, const float (*src)[2], int n); +;************************************************************************* +%macro PS_ADD_SQUARES 1 +cglobal ps_add_squares, 3, 3, %1, dst, src, n + shl nd, 3 + add srcq, nq + neg nq + +align 16 +.loop: + movaps m0, [srcq+nq] + movaps m1, [srcq+nq+mmsize] + mulps m0, m0 + mulps m1, m1 + HADDPS m0, m1, m2 + addps m0, [dstq] + movaps [dstq], m0 + add dstq, mmsize + add nq, mmsize*2 + jl .loop + REP_RET +%endmacro + +INIT_XMM sse +PS_ADD_SQUARES 2 +INIT_XMM sse3 +PS_ADD_SQUARES 3 + +;******************************************************************* +;void ff_ps_mul_pair_single_sse(float (*dst)[2], float (*src0)[2], +; float *src1, int n); +;******************************************************************* +INIT_XMM sse +cglobal ps_mul_pair_single, 4, 4, 4, dst, src1, src2, n + shl nd, 3 + add src1q, nq + add dstq, nq + neg nq + +align 16 +.loop: + movu m0, [src1q+nq] + movu m1, [src1q+nq+mmsize] + mova m2, [src2q] + mova m3, m2 + unpcklps m2, m2 + unpckhps m3, m3 + mulps m0, m2 + mulps m1, m3 + mova [dstq+nq], m0 + mova [dstq+nq+mmsize], m1 + add src2q, mmsize + add nq, mmsize*2 + jl .loop + REP_RET + +;*********************************************************************** +;void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2], +; float h[2][4], float h_step[2][4], +; int len); +;*********************************************************************** +INIT_XMM sse3 +cglobal ps_stereo_interpolate, 5, 5, 6, l, r, h, h_step, n + movaps m0, [hq] + movaps m1, [h_stepq] + unpcklps m4, m0, m0 + unpckhps m0, m0 + unpcklps m5, m1, m1 + unpckhps m1, m1 + shl nd, 3 + add lq, nq + add rq, nq + neg nq + +align 16 +.loop: + addps m4, m5 + addps m0, m1 + movddup m2, [lq+nq] + movddup m3, [rq+nq] + mulps m2, m4 + mulps m3, m0 + addps m2, m3 + movsd [lq+nq], m2 + movhps [rq+nq], m2 + add nq, 8 + jl .loop + REP_RET + +;*************************************************************************** +;void ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2], +; float h[2][4], float h_step[2][4], +; int len); +;*************************************************************************** +INIT_XMM sse3 +cglobal ps_stereo_interpolate_ipdopd, 5, 5, 10, l, r, h, h_step, n + movaps m0, [hq] + movaps m1, [hq+mmsize] +%if ARCH_X86_64 + movaps m8, [h_stepq] + movaps m9, [h_stepq+mmsize] + %define H_STEP0 m8 + %define H_STEP1 m9 +%else + %define H_STEP0 [h_stepq] + %define H_STEP1 [h_stepq+mmsize] +%endif + shl nd, 3 + add lq, nq + add rq, nq + neg nq + +align 16 +.loop: + addps m0, H_STEP0 + addps m1, H_STEP1 + movddup m2, [lq+nq] + movddup m3, [rq+nq] + shufps m4, m2, m2, q2301 + shufps m5, m3, m3, q2301 + unpcklps m6, m0, m0 + unpckhps m7, m0, m0 + mulps m2, m6 + mulps m3, m7 + unpcklps m6, m1, m1 + unpckhps m7, m1, m1 + mulps m4, m6 + mulps m5, m7 + addps m2, m3 + addsubps m2, m4 + addsubps m2, m5 + movsd [lq+nq], m2 + movhps [rq+nq], m2 + add nq, 8 + jl .loop + REP_RET + +;********************************************************** +;void ps_hybrid_analysis_ileave_sse(float out[2][38][64], +; float (*in)[32][2], +; int i, int len) +;********************************************************** +INIT_XMM sse +cglobal ps_hybrid_analysis_ileave, 3, 7, 5, out, in, i, len, in0, in1, tmp + movsxdifnidn iq, id + mov lend, 32 << 3 + lea inq, [inq+iq*4] + mov tmpd, id + shl tmpd, 8 + add outq, tmpq + mov tmpd, 64 + sub tmpd, id + mov id, tmpd + + test id, 1 + jne .loop4 + test id, 2 + jne .loop8 + +align 16 +.loop16: + mov in0q, inq + mov in1q, 38*64*4 + add in1q, in0q + mov tmpd, lend + +.inner_loop16: + movaps m0, [in0q] + movaps m1, [in1q] + movaps m2, [in0q+lenq] + movaps m3, [in1q+lenq] + TRANSPOSE4x4PS 0, 1, 2, 3, 4 + movaps [outq], m0 + movaps [outq+lenq], m1 + movaps [outq+lenq*2], m2 + movaps [outq+3*32*2*4], m3 + lea in0q, [in0q+lenq*2] + lea in1q, [in1q+lenq*2] + add outq, mmsize + sub tmpd, mmsize + jg .inner_loop16 + add inq, 16 + add outq, 3*32*2*4 + sub id, 4 + jg .loop16 + RET + +align 16 +.loop8: + mov in0q, inq + mov in1q, 38*64*4 + add in1q, in0q + mov tmpd, lend + +.inner_loop8: + movlps m0, [in0q] + movlps m1, [in1q] + movhps m0, [in0q+lenq] + movhps m1, [in1q+lenq] + SBUTTERFLYPS 0, 1, 2 + SBUTTERFLYPD 0, 1, 2 + movaps [outq], m0 + movaps [outq+lenq], m1 + lea in0q, [in0q+lenq*2] + lea in1q, [in1q+lenq*2] + add outq, mmsize + sub tmpd, mmsize + jg .inner_loop8 + add inq, 8 + add outq, lenq + sub id, 2 + jg .loop16 + RET + +align 16 +.loop4: + mov in0q, inq + mov in1q, 38*64*4 + add in1q, in0q + mov tmpd, lend + +.inner_loop4: + movss m0, [in0q] + movss m1, [in1q] + movss m2, [in0q+lenq] + movss m3, [in1q+lenq] + movlhps m0, m1 + movlhps m2, m3 + shufps m0, m2, q2020 + movaps [outq], m0 + lea in0q, [in0q+lenq*2] + lea in1q, [in1q+lenq*2] + add outq, mmsize + sub tmpd, mmsize + jg .inner_loop4 + add inq, 4 + sub id, 1 + test id, 2 + jne .loop8 + cmp id, 4 + jge .loop16 + RET + +;*********************************************************** +;void ps_hybrid_synthesis_deint_sse4(float out[2][38][64], +; float (*in)[32][2], +; int i, int len) +;*********************************************************** +%macro HYBRID_SYNTHESIS_DEINT 0 +cglobal ps_hybrid_synthesis_deint, 3, 7, 5, out, in, i, len, out0, out1, tmp +%if cpuflag(sse4) +%define MOVH movsd +%else +%define MOVH movlps +%endif + movsxdifnidn iq, id + mov lend, 32 << 3 + lea outq, [outq+iq*4] + mov tmpd, id + shl tmpd, 8 + add inq, tmpq + mov tmpd, 64 + sub tmpd, id + mov id, tmpd + + test id, 1 + jne .loop4 + test id, 2 + jne .loop8 + +align 16 +.loop16: + mov out0q, outq + mov out1q, 38*64*4 + add out1q, out0q + mov tmpd, lend + +.inner_loop16: + movaps m0, [inq] + movaps m1, [inq+lenq] + movaps m2, [inq+lenq*2] + movaps m3, [inq+3*32*2*4] + TRANSPOSE4x4PS 0, 1, 2, 3, 4 + movaps [out0q], m0 + movaps [out1q], m1 + movaps [out0q+lenq], m2 + movaps [out1q+lenq], m3 + lea out0q, [out0q+lenq*2] + lea out1q, [out1q+lenq*2] + add inq, mmsize + sub tmpd, mmsize + jg .inner_loop16 + add outq, 16 + add inq, 3*32*2*4 + sub id, 4 + jg .loop16 + RET + +align 16 +.loop8: + mov out0q, outq + mov out1q, 38*64*4 + add out1q, out0q + mov tmpd, lend + +.inner_loop8: + movaps m0, [inq] + movaps m1, [inq+lenq] + SBUTTERFLYPS 0, 1, 2 + SBUTTERFLYPD 0, 1, 2 + MOVH [out0q], m0 + MOVH [out1q], m1 + movhps [out0q+lenq], m0 + movhps [out1q+lenq], m1 + lea out0q, [out0q+lenq*2] + lea out1q, [out1q+lenq*2] + add inq, mmsize + sub tmpd, mmsize + jg .inner_loop8 + add outq, 8 + add inq, lenq + sub id, 2 + jg .loop16 + RET + +align 16 +.loop4: + mov out0q, outq + mov out1q, 38*64*4 + add out1q, out0q + mov tmpd, lend + +.inner_loop4: + movaps m0, [inq] + movss [out0q], m0 +%if cpuflag(sse4) + extractps [out1q], m0, 1 + extractps [out0q+lenq], m0, 2 + extractps [out1q+lenq], m0, 3 +%else + movhlps m1, m0 + movss [out0q+lenq], m1 + shufps m0, m0, 0xb1 + movss [out1q], m0 + movhlps m1, m0 + movss [out1q+lenq], m1 +%endif + lea out0q, [out0q+lenq*2] + lea out1q, [out1q+lenq*2] + add inq, mmsize + sub tmpd, mmsize + jg .inner_loop4 + add outq, 4 + sub id, 1 + test id, 2 + jne .loop8 + cmp id, 4 + jge .loop16 + RET +%endmacro + +INIT_XMM sse +HYBRID_SYNTHESIS_DEINT +INIT_XMM sse4 +HYBRID_SYNTHESIS_DEINT + +;******************************************************************* +;void ff_ps_hybrid_analysis_(float (*out)[2], float (*in)[2], +; const float (*filter)[8][2], +; ptrdiff_t stride, int n); +;******************************************************************* +%macro PS_HYBRID_ANALYSIS_LOOP 3 + movu %1, [inq+mmsize*%3] + movu m1, [inq+mmsize*(5-%3)+8] +%if cpuflag(sse3) + pshufd %2, %1, q2301 + pshufd m4, m1, q0123 + pshufd m1, m1, q1032 + pshufd m2, [filterq+nq+mmsize*%3], q2301 + addsubps %2, m4 + addsubps %1, m1 +%else + mova m2, [filterq+nq+mmsize*%3] + mova %2, %1 + mova m4, m1 + shufps %2, %2, q2301 + shufps m4, m4, q0123 + shufps m1, m1, q1032 + shufps m2, m2, q2301 + xorps m4, m7 + xorps m1, m7 + subps %2, m4 + subps %1, m1 +%endif + mulps %2, m2 + mulps %1, m2 +%if %3 + addps m3, %2 + addps m0, %1 +%endif +%endmacro + +%macro PS_HYBRID_ANALYSIS 0 +cglobal ps_hybrid_analysis, 5, 5, 8, out, in, filter, stride, n +%if cpuflag(sse3) +%define MOVH movsd +%else +%define MOVH movlps +%endif + shl strideq, 3 + shl nd, 6 + add filterq, nq + neg nq + mova m7, [ps_p1m1p1m1] + +align 16 +.loop: + PS_HYBRID_ANALYSIS_LOOP m0, m3, 0 + PS_HYBRID_ANALYSIS_LOOP m5, m6, 1 + PS_HYBRID_ANALYSIS_LOOP m5, m6, 2 + +%if cpuflag(sse3) + pshufd m3, m3, q2301 + xorps m0, m7 + hsubps m3, m0 + pshufd m1, m3, q0020 + pshufd m3, m3, q0031 + addps m1, m3 + movsd m2, [inq+6*8] +%else + mova m1, m3 + mova m2, m0 + shufps m1, m1, q2301 + shufps m2, m2, q2301 + subps m1, m3 + addps m2, m0 + unpcklps m3, m1, m2 + unpckhps m1, m2 + addps m1, m3 + movu m2, [inq+6*8] ; faster than movlps and no risk of overread +%endif + movss m3, [filterq+nq+8*6] + SPLATD m3 + mulps m2, m3 + addps m1, m2 + MOVH [outq], m1 + add outq, strideq + add nq, 64 + jl .loop + REP_RET +%endmacro + +INIT_XMM sse +PS_HYBRID_ANALYSIS +INIT_XMM sse3 +PS_HYBRID_ANALYSIS diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/celt_pvq_search.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/celt_pvq_search.asm new file mode 100644 index 000000000..5c1e6d617 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/celt_pvq_search.asm @@ -0,0 +1,385 @@ +;****************************************************************************** +;* SIMD optimized Opus encoder DSP function +;* +;* Copyright (C) 2017 Ivan Kalvachev +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "config.asm" +%include "libavutil/x86/x86util.asm" + +%ifdef __NASM_VER__ +%use "smartalign" +ALIGNMODE p6 +%endif + +SECTION_RODATA 64 + +const_float_abs_mask: times 8 dd 0x7fffffff +const_align_abs_edge: times 8 dd 0 + +const_float_0_5: times 8 dd 0.5 +const_float_1: times 8 dd 1.0 +const_float_sign_mask: times 8 dd 0x80000000 + +const_int32_offsets: + %rep 8 + dd $-const_int32_offsets + %endrep +SECTION .text + +; +; Setup High Register to be used +; for holding memory constants +; +; %1 - the register to be used, assmues it is >= mm8 +; %2 - name of the constant. +; +; Subsequent opcodes are going to use the constant in the form +; "addps m0, mm_const_name" and it would be turned into: +; "addps m0, [const_name]" on 32 bit arch or +; "addps m0, m8" on 64 bit arch +%macro SET_HI_REG_MM_CONSTANT 3 ; movop, reg, const_name +%if num_mmregs > 8 + %define mm_%3 %2 + %{1} %2, [%3] ; movaps m8, [const_name] +%else + %define mm_%3 [%3] +%endif +%endmacro + +; +; Set Position Independent Code +; Base address of a constant +; %1 - the register to be used, if PIC is set +; %2 - name of the constant. +; +; Subsequent opcode are going to use the base address in the form +; "movaps m0, [pic_base_constant_name+r4]" and it would be turned into +; "movaps m0, [r5 + r4]" if PIC is enabled +; "movaps m0, [constant_name + r4]" if texrel are used +%macro SET_PIC_BASE 3; reg, const_label +%ifdef PIC + %{1} %2, [%3] ; lea r5, [rip+const] + %define pic_base_%3 %2 +%else + %define pic_base_%3 %3 +%endif +%endmacro + +%macro PULSES_SEARCH 1 +; m6 Syy_norm +; m7 Sxy_norm + addps m6, mm_const_float_0_5 ; Syy_norm += 1.0/2 + pxor m1, m1 ; max_idx + xorps m3, m3 ; p_max + xor r4d, r4d +align 16 +%%distortion_search: + movd xm2, dword r4d ; movd zero extends +%ifidn %1,add + movaps m4, [tmpY + r4] ; y[i] + movaps m5, [tmpX + r4] ; X[i] + + %if USE_APPROXIMATION == 1 + xorps m0, m0 + cmpps m0, m0, m5, 4 ; m0 = (X[i] != 0.0) + %endif + + addps m4, m6 ; m4 = Syy_new = y[i] + Syy_norm + addps m5, m7 ; m5 = Sxy_new = X[i] + Sxy_norm + + %if USE_APPROXIMATION == 1 + andps m5, m0 ; if(X[i] == 0) Sxy_new = 0; Prevent aproximation error from setting pulses in array padding. + %endif + +%else + movaps m5, [tmpY + r4] ; m5 = y[i] + + xorps m0, m0 ; m0 = 0; + cmpps m0, m0, m5, 1 ; m0 = (0 p_max) + maxps m3, m5 ; m3=max(p_max,p) + ; maxps here is faster than blendvps, despite blend having lower latency. + + pand m2, m0 ; This version seems faster than sse41 pblendvb + pmaxsw m1, m2 ; SSE2 signed word, so it would work for N < 32768/4 + + add r4d, mmsize + cmp r4d, Nd + jb %%distortion_search + + por m1, mm_const_int32_offsets ; max_idx offsets per individual lane (skipped in the inner loop) + movdqa m4, m1 ; needed for the aligned y[max_idx]+=1; processing + +%if mmsize >= 32 +; Merge parallel maximums round 8 (4 vs 4) + + vextractf128 xm5, ym3, 1 ; xmm5 = ymm3[1x128] = ymm3[255..128b] + cmpps xm0, xm3, xm5, 1 ; m0 = (m3 < m5) = ( p[0x128] < p[1x128] ) + + vextracti128 xm2, ym1, 1 ; xmm2 = ymm1[1x128] = ymm1[255..128b] + BLENDVPS xm3, xm5, xm0 ; max_idx = m0 ? max_idx[1x128] : max_idx[0x128] + PBLENDVB xm1, xm2, xm0 ; p = m0 ? p[1x128] : p[0x128] +%endif + +; Merge parallel maximums round 4 (2 vs 2) + ; m3=p[3210] + movhlps xm5, xm3 ; m5=p[xx32] + cmpps xm0, xm3, xm5, 1 ; m0 = (m3 < m5) = ( p[1,0] < p[3,2] ) + + pshufd xm2, xm1, q3232 + BLENDVPS xm3, xm5, xm0 ; max_idx = m0 ? max_idx[3,2] : max_idx[1,0] + PBLENDVB xm1, xm2, xm0 ; p = m0 ? p[3,2] : p[1,0] + +; Merge parallel maximums final round (1 vs 1) + shufps xm0, xm3, xm3, q1111 ; m0 = m3[1] = p[1] + cmpss xm0, xm3, 5 ; m0 = !(m0 >= m3) = !( p[1] >= p[0] ) + + pshufd xm2, xm1, q1111 + PBLENDVB xm1, xm2, xm0 + + movd dword r4d, xm1 ; zero extends to the rest of r4q + + VBROADCASTSS m3, [tmpX + r4] + %{1}ps m7, m3 ; Sxy += X[max_idx] + + VBROADCASTSS m5, [tmpY + r4] + %{1}ps m6, m5 ; Syy += Y[max_idx] + + ; We have to update a single element in Y[i] + ; However writing 4 bytes and then doing 16 byte load in the inner loop + ; could cause a stall due to breaking write forwarding. + VPBROADCASTD m1, xm1 + pcmpeqd m1, m1, m4 ; exactly 1 element matches max_idx and this finds it + + and r4d, ~(mmsize-1) ; align address down, so the value pointed by max_idx is inside a mmsize load + movaps m5, [tmpY + r4] ; m5 = Y[y3...ym...y0] + andps m1, mm_const_float_1 ; m1 = [ 0...1.0...0] + %{1}ps m5, m1 ; m5 = Y[y3...ym...y0] +/- [0...1.0...0] + movaps [tmpY + r4], m5 ; Y[max_idx] +-= 1.0; +%endmacro + +; +; We need one more register for +; PIC relative addressing. Use this +; to count it in cglobal +; +%ifdef PIC + %define num_pic_regs 1 +%else + %define num_pic_regs 0 +%endif + +; +; Pyramid Vector Quantization Search implementation +; +; float * inX - Unaligned (SIMD) access, it will be overread, +; but extra data is masked away. +; int32 * outY - Should be aligned and padded buffer. +; It is used as temp buffer. +; uint32 K - Number of pulses to have after quantizations. +; uint32 N - Number of vector elements. Must be 0 < N < 256 +; +%macro PVQ_FAST_SEARCH 1 +cglobal pvq_search%1, 4, 5+num_pic_regs, 11, 256*4, inX, outY, K, N +%define tmpX rsp +%define tmpY outYq + + movaps m0, [const_float_abs_mask] + shl Nd, 2 ; N *= sizeof(float); also 32 bit operation zeroes the high 32 bits in 64 bit mode. + mov r4d, Nd + + neg r4d + and r4d, mmsize-1 + + SET_PIC_BASE lea, r5, const_align_abs_edge ; rip+const + movups m2, [pic_base_const_align_abs_edge + r4 - mmsize] + + add Nd, r4d ; N = align(N, mmsize) + + lea r4d, [Nd - mmsize] ; N is rounded up (aligned up) to mmsize, so r4 can't become negative here, unless N=0. + movups m1, [inXq + r4] + andps m1, m2 + movaps [tmpX + r4], m1 ; Sx = abs( X[N-1] ) + +align 16 +%%loop_abs_sum: + sub r4d, mmsize + jc %%end_loop_abs_sum + + movups m2, [inXq + r4] + andps m2, m0 + + movaps [tmpX + r4], m2 ; tmpX[i]=abs(X[i]) + addps m1, m2 ; Sx += abs(X[i]) + jmp %%loop_abs_sum + +align 16 +%%end_loop_abs_sum: + + HSUMPS m1, m2 ; m1 = Sx + + xorps m0, m0 + comiss xm0, xm1 ; + jz %%zero_input ; if (Sx==0) goto zero_input + + cvtsi2ss xm0, dword Kd ; m0 = K +%if USE_APPROXIMATION == 1 + rcpss xm1, xm1 ; m1 = approx(1/Sx) + mulss xm0, xm1 ; m0 = K*(1/Sx) +%else + divss xm0, xm1 ; b = K/Sx + ; b = K/max_x +%endif + + VBROADCASTSS m0, xm0 + + lea r4d, [Nd - mmsize] + pxor m5, m5 ; Sy ( Sum of abs( y[i]) ) + xorps m6, m6 ; Syy ( Sum of y[i]*y[i] ) + xorps m7, m7 ; Sxy ( Sum of X[i]*y[i] ) +align 16 +%%loop_guess: + movaps m1, [tmpX + r4] ; m1 = X[i] + mulps m2, m0, m1 ; m2 = res*X[i] + cvtps2dq m2, m2 ; yt = (int)lrintf( res*X[i] ) + paddd m5, m2 ; Sy += yt + cvtdq2ps m2, m2 ; yt = (float)yt + mulps m1, m2 ; m1 = X[i]*yt + movaps [tmpY + r4], m2 ; y[i] = m2 + addps m7, m1 ; Sxy += m1; + mulps m2, m2 ; m2 = yt*yt + addps m6, m2 ; Syy += m2 + + sub r4d, mmsize + jnc %%loop_guess + + HSUMPS m6, m1 ; Syy_norm + HADDD m5, m4 ; pulses + + movd dword r4d, xm5 ; zero extends to the rest of r4q + + sub Kd, r4d ; K -= pulses , also 32 bit operation zeroes high 32 bit in 64 bit mode. + jz %%finish ; K - pulses == 0 + + SET_HI_REG_MM_CONSTANT movaps, m8, const_float_0_5 + SET_HI_REG_MM_CONSTANT movaps, m9, const_float_1 + SET_HI_REG_MM_CONSTANT movdqa, m10, const_int32_offsets + ; Use Syy/2 in distortion parameter calculations. + ; Saves pre and post-caclulation to correct Y[] values. + ; Same precision, since float mantisa is normalized. + ; The SQRT approximation does differ. + HSUMPS m7, m0 ; Sxy_norm + mulps m6, mm_const_float_0_5 + + jc %%remove_pulses_loop ; K - pulses < 0 + +align 16 ; K - pulses > 0 +%%add_pulses_loop: + + PULSES_SEARCH add ; m6 Syy_norm ; m7 Sxy_norm + + sub Kd, 1 + jnz %%add_pulses_loop + + addps m6, m6 ; Syy*=2 + + jmp %%finish + +align 16 +%%remove_pulses_loop: + + PULSES_SEARCH sub ; m6 Syy_norm ; m7 Sxy_norm + + add Kd, 1 + jnz %%remove_pulses_loop + + addps m6, m6 ; Syy*=2 + +align 16 +%%finish: + lea r4d, [Nd - mmsize] + movaps m2, [const_float_sign_mask] + +align 16 +%%restore_sign_loop: + movaps m0, [tmpY + r4] ; m0 = Y[i] + movups m1, [inXq + r4] ; m1 = X[i] + andps m1, m2 ; m1 = sign(X[i]) + orps m0, m1 ; m0 = Y[i]*sign + cvtps2dq m3, m0 ; m3 = (int)m0 + movaps [outYq + r4], m3 + + sub r4d, mmsize + jnc %%restore_sign_loop +%%return: + +%if ARCH_X86_64 == 0 ; sbrdsp + movss r0m, xm6 ; return (float)Syy_norm + fld dword r0m +%else + movaps m0, m6 ; return (float)Syy_norm +%endif + + RET + +align 16 +%%zero_input: + lea r4d, [Nd - mmsize] + xorps m0, m0 +%%zero_loop: + movaps [outYq + r4], m0 + sub r4d, mmsize + jnc %%zero_loop + + movaps m6, [const_float_1] + jmp %%return +%endmacro + +; if 1, use a float op that give half precision but execute for around 3 cycles. +; On Skylake & Ryzen the division is much faster (around 11c/3), +; that makes the full precision code about 2% slower. +; Opus also does use rsqrt approximation in their intrinsics code. +%define USE_APPROXIMATION 1 + +INIT_XMM sse2 +PVQ_FAST_SEARCH _approx + +INIT_XMM sse4 +PVQ_FAST_SEARCH _approx + +%define USE_APPROXIMATION 0 + +INIT_XMM avx +PVQ_FAST_SEARCH _exact diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft.asm new file mode 100644 index 000000000..a671e8f48 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/fft.asm @@ -0,0 +1,1085 @@ +;****************************************************************************** +;* FFT transform with SSE/3DNow optimizations +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2011 Vitor Sessak +;* +;* This algorithm (though not any of the implementation details) is +;* based on libdjbfft by D. J. Bernstein. +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +; These functions are not individually interchangeable with the C versions. +; While C takes arrays of FFTComplex, SSE/3DNow leave intermediate results +; in blocks as conventient to the vector size. +; i.e. {4x real, 4x imaginary, 4x real, ...} (or 2x respectively) + +%include "libavutil/x86/x86util.asm" + +%if ARCH_X86_64 +%define pointer resq +%else +%define pointer resd +%endif + +struc FFTContext + .nbits: resd 1 + .reverse: resd 1 + .revtab: pointer 1 + .tmpbuf: pointer 1 + .mdctsize: resd 1 + .mdctbits: resd 1 + .tcos: pointer 1 + .tsin: pointer 1 + .fftperm: pointer 1 + .fftcalc: pointer 1 + .imdctcalc:pointer 1 + .imdcthalf:pointer 1 +endstruc + +SECTION_RODATA 32 + +%define M_SQRT1_2 0.70710678118654752440 +%define M_COS_PI_1_8 0.923879532511287 +%define M_COS_PI_3_8 0.38268343236509 + +ps_cos16_1: dd 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8, 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8 +ps_cos16_2: dd 0, M_COS_PI_3_8, M_SQRT1_2, M_COS_PI_1_8, 0, -M_COS_PI_3_8, -M_SQRT1_2, -M_COS_PI_1_8 + +ps_root2: times 8 dd M_SQRT1_2 +ps_root2mppm: dd -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2 +ps_p1p1m1p1: dd 0, 0, 1<<31, 0, 0, 0, 1<<31, 0 + +perm1: dd 0x00, 0x02, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01 +perm2: dd 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x02, 0x03 +ps_p1p1m1p1root2: dd 1.0, 1.0, -1.0, 1.0, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2 +ps_m1m1p1m1p1m1m1m1: dd 1<<31, 1<<31, 0, 1<<31, 0, 1<<31, 1<<31, 1<<31 +ps_m1p1: dd 1<<31, 0 + +cextern ps_neg + +%assign i 16 +%rep 14 +cextern cos_ %+ i +%assign i i<<1 +%endrep + +%if ARCH_X86_64 + %define pointer dq +%else + %define pointer dd +%endif + +%macro IF0 1+ +%endmacro +%macro IF1 1+ + %1 +%endmacro + +SECTION .text + +%macro T2_3DNOW 4 ; z0, z1, mem0, mem1 + mova %1, %3 + mova %2, %1 + pfadd %1, %4 + pfsub %2, %4 +%endmacro + +%macro T4_3DNOW 6 ; z0, z1, z2, z3, tmp0, tmp1 + mova %5, %3 + pfsub %3, %4 + pfadd %5, %4 ; {t6,t5} + pxor %3, [ps_m1p1] ; {t8,t7} + mova %6, %1 + movd [r0+12], %3 + punpckhdq %3, [r0+8] + pfadd %1, %5 ; {r0,i0} + pfsub %6, %5 ; {r2,i2} + mova %4, %2 + pfadd %2, %3 ; {r1,i1} + pfsub %4, %3 ; {r3,i3} + SWAP %3, %6 +%endmacro + +; in: %1 = {r0,i0,r2,i2,r4,i4,r6,i6} +; %2 = {r1,i1,r3,i3,r5,i5,r7,i7} +; %3, %4, %5 tmp +; out: %1 = {r0,r1,r2,r3,i0,i1,i2,i3} +; %2 = {r4,r5,r6,r7,i4,i5,i6,i7} +%macro T8_AVX 5 + vsubps %5, %1, %2 ; v = %1 - %2 + vaddps %3, %1, %2 ; w = %1 + %2 + vmulps %2, %5, [ps_p1p1m1p1root2] ; v *= vals1 + vpermilps %2, %2, [perm1] + vblendps %1, %2, %3, 0x33 ; q = {w1,w2,v4,v2,w5,w6,v7,v6} + vshufps %5, %3, %2, 0x4e ; r = {w3,w4,v1,v3,w7,w8,v8,v5} + vsubps %4, %5, %1 ; s = r - q + vaddps %1, %5, %1 ; u = r + q + vpermilps %1, %1, [perm2] ; k = {u1,u2,u3,u4,u6,u5,u7,u8} + vshufps %5, %4, %1, 0xbb + vshufps %3, %4, %1, 0xee + vperm2f128 %3, %3, %5, 0x13 + vxorps %4, %4, [ps_m1m1p1m1p1m1m1m1] ; s *= {1,1,-1,-1,1,-1,-1,-1} + vshufps %2, %1, %4, 0xdd + vshufps %1, %1, %4, 0x88 + vperm2f128 %4, %2, %1, 0x02 ; v = {k1,k3,s1,s3,k2,k4,s2,s4} + vperm2f128 %1, %1, %2, 0x13 ; w = {k6,k8,s6,s8,k5,k7,s5,s7} + vsubps %5, %1, %3 + vblendps %1, %5, %1, 0x55 ; w -= {0,s7,0,k7,0,s8,0,k8} + vsubps %2, %4, %1 ; %2 = v - w + vaddps %1, %4, %1 ; %1 = v + w +%endmacro + +; In SSE mode do one fft4 transforms +; in: %1={r0,i0,r2,i2} %2={r1,i1,r3,i3} +; out: %1={r0,r1,r2,r3} %2={i0,i1,i2,i3} +; +; In AVX mode do two fft4 transforms +; in: %1={r0,i0,r2,i2,r4,i4,r6,i6} %2={r1,i1,r3,i3,r5,i5,r7,i7} +; out: %1={r0,r1,r2,r3,r4,r5,r6,r7} %2={i0,i1,i2,i3,i4,i5,i6,i7} +%macro T4_SSE 3 + subps %3, %1, %2 ; {t3,t4,-t8,t7} + addps %1, %1, %2 ; {t1,t2,t6,t5} + xorps %3, %3, [ps_p1p1m1p1] + shufps %2, %1, %3, 0xbe ; {t6,t5,t7,t8} + shufps %1, %1, %3, 0x44 ; {t1,t2,t3,t4} + subps %3, %1, %2 ; {r2,i2,r3,i3} + addps %1, %1, %2 ; {r0,i0,r1,i1} + shufps %2, %1, %3, 0xdd ; {i0,i1,i2,i3} + shufps %1, %1, %3, 0x88 ; {r0,r1,r2,r3} +%endmacro + +; In SSE mode do one FFT8 +; in: %1={r0,r1,r2,r3} %2={i0,i1,i2,i3} %3={r4,i4,r6,i6} %4={r5,i5,r7,i7} +; out: %1={r0,r1,r2,r3} %2={i0,i1,i2,i3} %1={r4,r5,r6,r7} %2={i4,i5,i6,i7} +; +; In AVX mode do two FFT8 +; in: %1={r0,i0,r2,i2,r8, i8, r10,i10} %2={r1,i1,r3,i3,r9, i9, r11,i11} +; %3={r4,i4,r6,i6,r12,i12,r14,i14} %4={r5,i5,r7,i7,r13,i13,r15,i15} +; out: %1={r0,r1,r2,r3,r8, r9, r10,r11} %2={i0,i1,i2,i3,i8, i9, i10,i11} +; %3={r4,r5,r6,r7,r12,r13,r14,r15} %4={i4,i5,i6,i7,i12,i13,i14,i15} +%macro T8_SSE 6 + addps %6, %3, %4 ; {t1,t2,t3,t4} + subps %3, %3, %4 ; {r5,i5,r7,i7} + shufps %4, %3, %3, 0xb1 ; {i5,r5,i7,r7} + mulps %3, %3, [ps_root2mppm] ; {-r5,i5,r7,-i7} + mulps %4, %4, [ps_root2] + addps %3, %3, %4 ; {t8,t7,ta,t9} + shufps %4, %6, %3, 0x9c ; {t1,t4,t7,ta} + shufps %6, %6, %3, 0x36 ; {t3,t2,t9,t8} + subps %3, %6, %4 ; {t6,t5,tc,tb} + addps %6, %6, %4 ; {t1,t2,t9,ta} + shufps %5, %6, %3, 0x8d ; {t2,ta,t6,tc} + shufps %6, %6, %3, 0xd8 ; {t1,t9,t5,tb} + subps %3, %1, %6 ; {r4,r5,r6,r7} + addps %1, %1, %6 ; {r0,r1,r2,r3} + subps %4, %2, %5 ; {i4,i5,i6,i7} + addps %2, %2, %5 ; {i0,i1,i2,i3} +%endmacro + +%macro INTERL 5 +%if cpuflag(avx) + vunpckhps %3, %2, %1 + vunpcklps %2, %2, %1 + vextractf128 %4(%5), %2, 0 + vextractf128 %4 %+ H(%5), %3, 0 + vextractf128 %4(%5 + 1), %2, 1 + vextractf128 %4 %+ H(%5 + 1), %3, 1 +%elif cpuflag(sse) || cpuflag(3dnow) + mova %3, %2 + unpcklps %2, %1 + unpckhps %3, %1 + mova %4(%5), %2 + mova %4(%5+1), %3 +%endif +%endmacro + +; scheduled for cpu-bound sizes +%macro PASS_SMALL 3 ; (to load m4-m7), wre, wim +IF%1 mova m4, Z(4) +IF%1 mova m5, Z(5) + mova m0, %2 ; wre + mova m1, %3 ; wim + mulps m2, m4, m0 ; r2*wre +IF%1 mova m6, Z2(6) + mulps m3, m5, m1 ; i2*wim +IF%1 mova m7, Z2(7) + mulps m4, m4, m1 ; r2*wim + mulps m5, m5, m0 ; i2*wre + addps m2, m2, m3 ; r2*wre + i2*wim + mulps m3, m1, m7 ; i3*wim + subps m5, m5, m4 ; i2*wre - r2*wim + mulps m1, m1, m6 ; r3*wim + mulps m4, m0, m6 ; r3*wre + mulps m0, m0, m7 ; i3*wre + subps m4, m4, m3 ; r3*wre - i3*wim + mova m3, Z(0) + addps m0, m0, m1 ; i3*wre + r3*wim + subps m1, m4, m2 ; t3 + addps m4, m4, m2 ; t5 + subps m3, m3, m4 ; r2 + addps m4, m4, Z(0) ; r0 + mova m6, Z(2) + mova Z(4), m3 + mova Z(0), m4 + subps m3, m5, m0 ; t4 + subps m4, m6, m3 ; r3 + addps m3, m3, m6 ; r1 + mova Z2(6), m4 + mova Z(2), m3 + mova m2, Z(3) + addps m3, m5, m0 ; t6 + subps m2, m2, m1 ; i3 + mova m7, Z(1) + addps m1, m1, Z(3) ; i1 + mova Z2(7), m2 + mova Z(3), m1 + subps m4, m7, m3 ; i2 + addps m3, m3, m7 ; i0 + mova Z(5), m4 + mova Z(1), m3 +%endmacro + +; scheduled to avoid store->load aliasing +%macro PASS_BIG 1 ; (!interleave) + mova m4, Z(4) ; r2 + mova m5, Z(5) ; i2 + mova m0, [wq] ; wre + mova m1, [wq+o1q] ; wim + mulps m2, m4, m0 ; r2*wre + mova m6, Z2(6) ; r3 + mulps m3, m5, m1 ; i2*wim + mova m7, Z2(7) ; i3 + mulps m4, m4, m1 ; r2*wim + mulps m5, m5, m0 ; i2*wre + addps m2, m2, m3 ; r2*wre + i2*wim + mulps m3, m1, m7 ; i3*wim + mulps m1, m1, m6 ; r3*wim + subps m5, m5, m4 ; i2*wre - r2*wim + mulps m4, m0, m6 ; r3*wre + mulps m0, m0, m7 ; i3*wre + subps m4, m4, m3 ; r3*wre - i3*wim + mova m3, Z(0) + addps m0, m0, m1 ; i3*wre + r3*wim + subps m1, m4, m2 ; t3 + addps m4, m4, m2 ; t5 + subps m3, m3, m4 ; r2 + addps m4, m4, Z(0) ; r0 + mova m6, Z(2) + mova Z(4), m3 + mova Z(0), m4 + subps m3, m5, m0 ; t4 + subps m4, m6, m3 ; r3 + addps m3, m3, m6 ; r1 +IF%1 mova Z2(6), m4 +IF%1 mova Z(2), m3 + mova m2, Z(3) + addps m5, m5, m0 ; t6 + subps m2, m2, m1 ; i3 + mova m7, Z(1) + addps m1, m1, Z(3) ; i1 +IF%1 mova Z2(7), m2 +IF%1 mova Z(3), m1 + subps m6, m7, m5 ; i2 + addps m5, m5, m7 ; i0 +IF%1 mova Z(5), m6 +IF%1 mova Z(1), m5 +%if %1==0 + INTERL m1, m3, m7, Z, 2 + INTERL m2, m4, m0, Z2, 6 + + mova m1, Z(0) + mova m2, Z(4) + + INTERL m5, m1, m3, Z, 0 + INTERL m6, m2, m7, Z, 4 +%endif +%endmacro + +%macro PUNPCK 3 + mova %3, %1 + punpckldq %1, %2 + punpckhdq %3, %2 +%endmacro + +%define Z(x) [r0+mmsize*x] +%define Z2(x) [r0+mmsize*x] +%define ZH(x) [r0+mmsize*x+mmsize/2] + +INIT_YMM avx + +%if HAVE_AVX_EXTERNAL +align 16 +fft8_avx: + mova m0, Z(0) + mova m1, Z(1) + T8_AVX m0, m1, m2, m3, m4 + mova Z(0), m0 + mova Z(1), m1 + ret + + +align 16 +fft16_avx: + mova m2, Z(2) + mova m3, Z(3) + T4_SSE m2, m3, m7 + + mova m0, Z(0) + mova m1, Z(1) + T8_AVX m0, m1, m4, m5, m7 + + mova m4, [ps_cos16_1] + mova m5, [ps_cos16_2] + vmulps m6, m2, m4 + vmulps m7, m3, m5 + vaddps m7, m7, m6 + vmulps m2, m2, m5 + vmulps m3, m3, m4 + vsubps m3, m3, m2 + vblendps m2, m7, m3, 0xf0 + vperm2f128 m3, m7, m3, 0x21 + vaddps m4, m2, m3 + vsubps m2, m3, m2 + vperm2f128 m2, m2, m2, 0x01 + vsubps m3, m1, m2 + vaddps m1, m1, m2 + vsubps m5, m0, m4 + vaddps m0, m0, m4 + vextractf128 Z(0), m0, 0 + vextractf128 ZH(0), m1, 0 + vextractf128 Z(1), m0, 1 + vextractf128 ZH(1), m1, 1 + vextractf128 Z(2), m5, 0 + vextractf128 ZH(2), m3, 0 + vextractf128 Z(3), m5, 1 + vextractf128 ZH(3), m3, 1 + ret + +align 16 +fft32_avx: + call fft16_avx + + mova m0, Z(4) + mova m1, Z(5) + + T4_SSE m0, m1, m4 + + mova m2, Z(6) + mova m3, Z(7) + + T8_SSE m0, m1, m2, m3, m4, m6 + ; m0={r0,r1,r2,r3,r8, r9, r10,r11} m1={i0,i1,i2,i3,i8, i9, i10,i11} + ; m2={r4,r5,r6,r7,r12,r13,r14,r15} m3={i4,i5,i6,i7,i12,i13,i14,i15} + + vperm2f128 m4, m0, m2, 0x20 + vperm2f128 m5, m1, m3, 0x20 + vperm2f128 m6, m0, m2, 0x31 + vperm2f128 m7, m1, m3, 0x31 + + PASS_SMALL 0, [cos_32], [cos_32+32] + + ret + +fft32_interleave_avx: + call fft32_avx + mov r2d, 32 +.deint_loop: + mova m2, Z(0) + mova m3, Z(1) + vunpcklps m0, m2, m3 + vunpckhps m1, m2, m3 + vextractf128 Z(0), m0, 0 + vextractf128 ZH(0), m1, 0 + vextractf128 Z(1), m0, 1 + vextractf128 ZH(1), m1, 1 + add r0, mmsize*2 + sub r2d, mmsize/4 + jg .deint_loop + ret + +%endif + +INIT_XMM sse + +align 16 +fft4_avx: +fft4_sse: + mova m0, Z(0) + mova m1, Z(1) + T4_SSE m0, m1, m2 + mova Z(0), m0 + mova Z(1), m1 + ret + +align 16 +fft8_sse: + mova m0, Z(0) + mova m1, Z(1) + T4_SSE m0, m1, m2 + mova m2, Z(2) + mova m3, Z(3) + T8_SSE m0, m1, m2, m3, m4, m5 + mova Z(0), m0 + mova Z(1), m1 + mova Z(2), m2 + mova Z(3), m3 + ret + +align 16 +fft16_sse: + mova m0, Z(0) + mova m1, Z(1) + T4_SSE m0, m1, m2 + mova m2, Z(2) + mova m3, Z(3) + T8_SSE m0, m1, m2, m3, m4, m5 + mova m4, Z(4) + mova m5, Z(5) + mova Z(0), m0 + mova Z(1), m1 + mova Z(2), m2 + mova Z(3), m3 + T4_SSE m4, m5, m6 + mova m6, Z2(6) + mova m7, Z2(7) + T4_SSE m6, m7, m0 + PASS_SMALL 0, [cos_16], [cos_16+16] + ret + + +%macro FFT48_3DNOW 0 +align 16 +fft4 %+ SUFFIX: + T2_3DNOW m0, m1, Z(0), Z(1) + mova m2, Z(2) + mova m3, Z(3) + T4_3DNOW m0, m1, m2, m3, m4, m5 + PUNPCK m0, m1, m4 + PUNPCK m2, m3, m5 + mova Z(0), m0 + mova Z(1), m4 + mova Z(2), m2 + mova Z(3), m5 + ret + +align 16 +fft8 %+ SUFFIX: + T2_3DNOW m0, m1, Z(0), Z(1) + mova m2, Z(2) + mova m3, Z(3) + T4_3DNOW m0, m1, m2, m3, m4, m5 + mova Z(0), m0 + mova Z(2), m2 + T2_3DNOW m4, m5, Z(4), Z(5) + T2_3DNOW m6, m7, Z2(6), Z2(7) + PSWAPD m0, m5 + PSWAPD m2, m7 + pxor m0, [ps_m1p1] + pxor m2, [ps_m1p1] + pfsub m5, m0 + pfadd m7, m2 + pfmul m5, [ps_root2] + pfmul m7, [ps_root2] + T4_3DNOW m1, m3, m5, m7, m0, m2 + mova Z(5), m5 + mova Z2(7), m7 + mova m0, Z(0) + mova m2, Z(2) + T4_3DNOW m0, m2, m4, m6, m5, m7 + PUNPCK m0, m1, m5 + PUNPCK m2, m3, m7 + mova Z(0), m0 + mova Z(1), m5 + mova Z(2), m2 + mova Z(3), m7 + PUNPCK m4, Z(5), m5 + PUNPCK m6, Z2(7), m7 + mova Z(4), m4 + mova Z(5), m5 + mova Z2(6), m6 + mova Z2(7), m7 + ret +%endmacro + +%if ARCH_X86_32 +INIT_MMX 3dnowext +FFT48_3DNOW + +INIT_MMX 3dnow +FFT48_3DNOW +%endif + +%define Z(x) [zcq + o1q*(x&6) + mmsize*(x&1)] +%define Z2(x) [zcq + o3q + mmsize*(x&1)] +%define ZH(x) [zcq + o1q*(x&6) + mmsize*(x&1) + mmsize/2] +%define Z2H(x) [zcq + o3q + mmsize*(x&1) + mmsize/2] + +%macro DECL_PASS 2+ ; name, payload +align 16 +%1: +DEFINE_ARGS zc, w, n, o1, o3 + lea o3q, [nq*3] + lea o1q, [nq*8] + shl o3q, 4 +.loop: + %2 + add zcq, mmsize*2 + add wq, mmsize + sub nd, mmsize/8 + jg .loop + rep ret +%endmacro + +%macro FFT_DISPATCH 2; clobbers 5 GPRs, 8 XMMs + lea r2, [dispatch_tab%1] + mov r2, [r2 + (%2q-2)*gprsize] +%ifdef PIC + lea r3, [$$] + add r2, r3 +%endif + call r2 +%endmacro ; FFT_DISPATCH + +INIT_YMM avx + +%if HAVE_AVX_EXTERNAL +DECL_PASS pass_avx, PASS_BIG 1 +DECL_PASS pass_interleave_avx, PASS_BIG 0 + +cglobal fft_calc, 2,5,8 + mov r3d, [r0 + FFTContext.nbits] + mov r0, r1 + mov r1, r3 + FFT_DISPATCH _interleave %+ SUFFIX, r1 + REP_RET + +%endif + +INIT_XMM sse + +DECL_PASS pass_sse, PASS_BIG 1 +DECL_PASS pass_interleave_sse, PASS_BIG 0 + +%macro FFT_CALC_FUNC 0 +cglobal fft_calc, 2,5,8 + mov r3d, [r0 + FFTContext.nbits] + PUSH r1 + PUSH r3 + mov r0, r1 + mov r1, r3 + FFT_DISPATCH _interleave %+ SUFFIX, r1 + POP rcx + POP r4 + cmp rcx, 3+(mmsize/16) + jg .end + mov r2, -1 + add rcx, 3 + shl r2, cl + sub r4, r2 +.loop: +%if mmsize == 8 + PSWAPD m0, [r4 + r2 + 4] + mova [r4 + r2 + 4], m0 +%else + movaps xmm0, [r4 + r2] + movaps xmm1, xmm0 + unpcklps xmm0, [r4 + r2 + 16] + unpckhps xmm1, [r4 + r2 + 16] + movaps [r4 + r2], xmm0 + movaps [r4 + r2 + 16], xmm1 +%endif + add r2, mmsize*2 + jl .loop +.end: +%if cpuflag(3dnow) + femms + RET +%else + REP_RET +%endif +%endmacro + +%if ARCH_X86_32 +INIT_MMX 3dnow +FFT_CALC_FUNC +INIT_MMX 3dnowext +FFT_CALC_FUNC +%endif +INIT_XMM sse +FFT_CALC_FUNC + +cglobal fft_permute, 2,7,1 + mov r4, [r0 + FFTContext.revtab] + mov r5, [r0 + FFTContext.tmpbuf] + mov ecx, [r0 + FFTContext.nbits] + mov r2, 1 + shl r2, cl + xor r0, r0 +%if ARCH_X86_32 + mov r1, r1m +%endif +.loop: + movaps xmm0, [r1 + 8*r0] + movzx r6, word [r4 + 2*r0] + movzx r3, word [r4 + 2*r0 + 2] + movlps [r5 + 8*r6], xmm0 + movhps [r5 + 8*r3], xmm0 + add r0, 2 + cmp r0, r2 + jl .loop + shl r2, 3 + add r1, r2 + add r5, r2 + neg r2 +; nbits >= 2 (FFT4) and sizeof(FFTComplex)=8 => at least 32B +.loopcopy: + movaps xmm0, [r5 + r2] + movaps xmm1, [r5 + r2 + 16] + movaps [r1 + r2], xmm0 + movaps [r1 + r2 + 16], xmm1 + add r2, 32 + jl .loopcopy + REP_RET + +%macro IMDCT_CALC_FUNC 0 +cglobal imdct_calc, 3,5,3 + mov r3d, [r0 + FFTContext.mdctsize] + mov r4, [r0 + FFTContext.imdcthalf] + add r1, r3 + PUSH r3 + PUSH r1 +%if ARCH_X86_32 + push r2 + push r1 + push r0 +%else + sub rsp, 8+32*WIN64 ; allocate win64 shadow space +%endif + call r4 +%if ARCH_X86_32 + add esp, 12 +%else + add rsp, 8+32*WIN64 +%endif + POP r1 + POP r3 + lea r0, [r1 + 2*r3] + mov r2, r3 + sub r3, mmsize + neg r2 + mova m2, [ps_neg] +.loop: +%if mmsize == 8 + PSWAPD m0, [r1 + r3] + PSWAPD m1, [r0 + r2] + pxor m0, m2 +%else + mova m0, [r1 + r3] + mova m1, [r0 + r2] + shufps m0, m0, 0x1b + shufps m1, m1, 0x1b + xorps m0, m2 +%endif + mova [r0 + r3], m1 + mova [r1 + r2], m0 + sub r3, mmsize + add r2, mmsize + jl .loop +%if cpuflag(3dnow) + femms + RET +%else + REP_RET +%endif +%endmacro + +%if ARCH_X86_32 +INIT_MMX 3dnow +IMDCT_CALC_FUNC +INIT_MMX 3dnowext +IMDCT_CALC_FUNC +%endif + +INIT_XMM sse +IMDCT_CALC_FUNC + +%if ARCH_X86_32 +INIT_MMX 3dnow +%define mulps pfmul +%define addps pfadd +%define subps pfsub +%define unpcklps punpckldq +%define unpckhps punpckhdq +DECL_PASS pass_3dnow, PASS_SMALL 1, [wq], [wq+o1q] +DECL_PASS pass_interleave_3dnow, PASS_BIG 0 +%define pass_3dnowext pass_3dnow +%define pass_interleave_3dnowext pass_interleave_3dnow +%endif + +%ifdef PIC +%define SECTION_REL - $$ +%else +%define SECTION_REL +%endif + +%macro DECL_FFT 1-2 ; nbits, suffix +%ifidn %0, 1 +%xdefine fullsuffix SUFFIX +%else +%xdefine fullsuffix %2 %+ SUFFIX +%endif +%xdefine list_of_fft fft4 %+ SUFFIX SECTION_REL, fft8 %+ SUFFIX SECTION_REL +%if %1>=5 +%xdefine list_of_fft list_of_fft, fft16 %+ SUFFIX SECTION_REL +%endif +%if %1>=6 +%xdefine list_of_fft list_of_fft, fft32 %+ fullsuffix SECTION_REL +%endif + +%assign n 1<<%1 +%rep 18-%1 +%assign n2 n/2 +%assign n4 n/4 +%xdefine list_of_fft list_of_fft, fft %+ n %+ fullsuffix SECTION_REL + +align 16 +fft %+ n %+ fullsuffix: + call fft %+ n2 %+ SUFFIX + add r0, n*4 - (n&(-2<<%1)) + call fft %+ n4 %+ SUFFIX + add r0, n*2 - (n2&(-2<<%1)) + call fft %+ n4 %+ SUFFIX + sub r0, n*6 + (n2&(-2<<%1)) + lea r1, [cos_ %+ n] + mov r2d, n4/2 + jmp pass %+ fullsuffix + +%assign n n*2 +%endrep +%undef n + +align 8 +dispatch_tab %+ fullsuffix: pointer list_of_fft +%endmacro ; DECL_FFT + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +DECL_FFT 6 +DECL_FFT 6, _interleave +%endif +INIT_XMM sse +DECL_FFT 5 +DECL_FFT 5, _interleave +%if ARCH_X86_32 +INIT_MMX 3dnow +DECL_FFT 4 +DECL_FFT 4, _interleave +INIT_MMX 3dnowext +DECL_FFT 4 +DECL_FFT 4, _interleave +%endif + +INIT_XMM sse +%undef mulps +%undef addps +%undef subps +%undef unpcklps +%undef unpckhps + +%macro PREROTATER 5 ;-2*k, 2*k, input+n4, tcos+n8, tsin+n8 +%if mmsize == 8 ; j*2+2-n4, n4-2-j*2, input+n4, tcos+n8, tsin+n8 + PSWAPD m0, [%3+%2*4] + movq m2, [%3+%1*4-8] + movq m3, m0 + punpckldq m0, m2 + punpckhdq m2, m3 + movd m1, [%4+%1*2-4] ; tcos[j] + movd m3, [%4+%2*2] ; tcos[n4-j-1] + punpckldq m1, [%5+%1*2-4] ; tsin[j] + punpckldq m3, [%5+%2*2] ; tsin[n4-j-1] + + mova m4, m0 + PSWAPD m5, m1 + pfmul m0, m1 + pfmul m4, m5 + mova m6, m2 + PSWAPD m5, m3 + pfmul m2, m3 + pfmul m6, m5 +%if cpuflag(3dnowext) + pfpnacc m0, m4 + pfpnacc m2, m6 +%else + SBUTTERFLY dq, 0, 4, 1 + SBUTTERFLY dq, 2, 6, 3 + pxor m4, m7 + pxor m6, m7 + pfadd m0, m4 + pfadd m2, m6 +%endif +%else + movaps xmm0, [%3+%2*4] + movaps xmm1, [%3+%1*4-0x10] + movaps xmm2, xmm0 + shufps xmm0, xmm1, 0x88 + shufps xmm1, xmm2, 0x77 + movlps xmm4, [%4+%2*2] + movlps xmm5, [%5+%2*2+0x0] + movhps xmm4, [%4+%1*2-0x8] + movhps xmm5, [%5+%1*2-0x8] + movaps xmm2, xmm0 + movaps xmm3, xmm1 + mulps xmm0, xmm5 + mulps xmm1, xmm4 + mulps xmm2, xmm4 + mulps xmm3, xmm5 + subps xmm1, xmm0 + addps xmm2, xmm3 + movaps xmm0, xmm1 + unpcklps xmm1, xmm2 + unpckhps xmm0, xmm2 +%endif +%endmacro + +%macro CMUL 6 ;j, xmm0, xmm1, 3, 4, 5 +%if cpuflag(sse) + mulps m6, %3, [%5+%1] + mulps m7, %2, [%5+%1] + mulps %2, %2, [%6+%1] + mulps %3, %3, [%6+%1] + subps %2, %2, m6 + addps %3, %3, m7 +%elif cpuflag(3dnow) + mova m6, [%1+%2*2] + mova %3, [%1+%2*2+8] + mova %4, m6 + mova m7, %3 + pfmul m6, [%5+%2] + pfmul %3, [%6+%2] + pfmul %4, [%6+%2] + pfmul m7, [%5+%2] + pfsub %3, m6 + pfadd %4, m7 +%endif +%endmacro + +%macro POSROTATESHUF 5 ;j, k, z+n8, tcos+n8, tsin+n8 +.post: +%if cpuflag(avx) + vmovaps ymm1, [%3+%1*2] + vmovaps ymm0, [%3+%1*2+0x20] + vmovaps ymm3, [%3+%2*2] + vmovaps ymm2, [%3+%2*2+0x20] + + CMUL %1, ymm0, ymm1, %3, %4, %5 + CMUL %2, ymm2, ymm3, %3, %4, %5 + vshufps ymm1, ymm1, ymm1, 0x1b + vshufps ymm3, ymm3, ymm3, 0x1b + vperm2f128 ymm1, ymm1, ymm1, 0x01 + vperm2f128 ymm3, ymm3, ymm3, 0x01 + vunpcklps ymm6, ymm2, ymm1 + vunpckhps ymm4, ymm2, ymm1 + vunpcklps ymm7, ymm0, ymm3 + vunpckhps ymm5, ymm0, ymm3 + + vextractf128 [%3+%1*2], ymm7, 0 + vextractf128 [%3+%1*2+0x10], ymm5, 0 + vextractf128 [%3+%1*2+0x20], ymm7, 1 + vextractf128 [%3+%1*2+0x30], ymm5, 1 + + vextractf128 [%3+%2*2], ymm6, 0 + vextractf128 [%3+%2*2+0x10], ymm4, 0 + vextractf128 [%3+%2*2+0x20], ymm6, 1 + vextractf128 [%3+%2*2+0x30], ymm4, 1 + sub %2, 0x20 + add %1, 0x20 + jl .post +%elif cpuflag(sse) + movaps xmm1, [%3+%1*2] + movaps xmm0, [%3+%1*2+0x10] + CMUL %1, xmm0, xmm1, %3, %4, %5 + movaps xmm5, [%3+%2*2] + movaps xmm4, [%3+%2*2+0x10] + CMUL %2, xmm4, xmm5, %3, %4, %5 + shufps xmm1, xmm1, 0x1b + shufps xmm5, xmm5, 0x1b + movaps xmm6, xmm4 + unpckhps xmm4, xmm1 + unpcklps xmm6, xmm1 + movaps xmm2, xmm0 + unpcklps xmm0, xmm5 + unpckhps xmm2, xmm5 + movaps [%3+%2*2], xmm6 + movaps [%3+%2*2+0x10], xmm4 + movaps [%3+%1*2], xmm0 + movaps [%3+%1*2+0x10], xmm2 + sub %2, 0x10 + add %1, 0x10 + jl .post +%elif cpuflag(3dnow) + CMUL %3, %1, m0, m1, %4, %5 + CMUL %3, %2, m2, m3, %4, %5 + movd [%3+%1*2+ 0], m0 + movd [%3+%2*2+12], m1 + movd [%3+%2*2+ 0], m2 + movd [%3+%1*2+12], m3 + psrlq m0, 32 + psrlq m1, 32 + psrlq m2, 32 + psrlq m3, 32 + movd [%3+%1*2+ 8], m0 + movd [%3+%2*2+ 4], m1 + movd [%3+%2*2+ 8], m2 + movd [%3+%1*2+ 4], m3 + sub %2, 8 + add %1, 8 + jl .post +%endif +%endmacro + +%macro DECL_IMDCT 0 +cglobal imdct_half, 3,12,8; FFTContext *s, FFTSample *output, const FFTSample *input +%if ARCH_X86_64 +%define rrevtab r7 +%define rtcos r8 +%define rtsin r9 +%else +%define rrevtab r6 +%define rtsin r6 +%define rtcos r5 +%endif + mov r3d, [r0+FFTContext.mdctsize] + add r2, r3 + shr r3, 1 + mov rtcos, [r0+FFTContext.tcos] + mov rtsin, [r0+FFTContext.tsin] + add rtcos, r3 + add rtsin, r3 +%if ARCH_X86_64 == 0 + push rtcos + push rtsin +%endif + shr r3, 1 + mov rrevtab, [r0+FFTContext.revtab] + add rrevtab, r3 +%if ARCH_X86_64 == 0 + push rrevtab +%endif + +%if mmsize == 8 + sub r3, 2 +%else + sub r3, 4 +%endif +%if ARCH_X86_64 || mmsize == 8 + xor r4, r4 + sub r4, r3 +%endif +%if notcpuflag(3dnowext) && mmsize == 8 + movd m7, [ps_neg] +%endif +.pre: +%if ARCH_X86_64 == 0 +;unspill +%if mmsize != 8 + xor r4, r4 + sub r4, r3 +%endif + mov rtcos, [esp+8] + mov rtsin, [esp+4] +%endif + + PREROTATER r4, r3, r2, rtcos, rtsin +%if mmsize == 8 + mov r6, [esp] ; rrevtab = ptr+n8 + movzx r5, word [rrevtab+r4-2] ; rrevtab[j] + movzx r6, word [rrevtab+r3] ; rrevtab[n4-j-1] + mova [r1+r5*8], m0 + mova [r1+r6*8], m2 + add r4, 2 + sub r3, 2 +%else +%if ARCH_X86_64 + movzx r5, word [rrevtab+r4-4] + movzx r6, word [rrevtab+r4-2] + movzx r10, word [rrevtab+r3] + movzx r11, word [rrevtab+r3+2] + movlps [r1+r5 *8], xmm0 + movhps [r1+r6 *8], xmm0 + movlps [r1+r10*8], xmm1 + movhps [r1+r11*8], xmm1 + add r4, 4 +%else + mov r6, [esp] + movzx r5, word [r6+r4-4] + movzx r4, word [r6+r4-2] + movlps [r1+r5*8], xmm0 + movhps [r1+r4*8], xmm0 + movzx r5, word [r6+r3] + movzx r4, word [r6+r3+2] + movlps [r1+r5*8], xmm1 + movhps [r1+r4*8], xmm1 +%endif + sub r3, 4 +%endif + jns .pre + + mov r5, r0 + mov r6, r1 + mov r0, r1 + mov r1d, [r5+FFTContext.nbits] + + FFT_DISPATCH SUFFIX, r1 + + mov r0d, [r5+FFTContext.mdctsize] + add r6, r0 + shr r0, 1 +%if ARCH_X86_64 == 0 +%define rtcos r2 +%define rtsin r3 + mov rtcos, [esp+8] + mov rtsin, [esp+4] +%endif + neg r0 + mov r1, -mmsize + sub r1, r0 + POSROTATESHUF r0, r1, r6, rtcos, rtsin +%if ARCH_X86_64 == 0 + add esp, 12 +%endif +%if mmsize == 8 + femms +%endif + RET +%endmacro + +DECL_IMDCT + +%if ARCH_X86_32 +INIT_MMX 3dnow +DECL_IMDCT + +INIT_MMX 3dnowext +DECL_IMDCT +%endif + +INIT_YMM avx + +%if HAVE_AVX_EXTERNAL +DECL_IMDCT +%endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mdct15.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mdct15.asm new file mode 100644 index 000000000..2a2cdbd21 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/mdct15.asm @@ -0,0 +1,221 @@ +;****************************************************************************** +;* SIMD optimized non-power-of-two MDCT functions +;* +;* Copyright (C) 2017 Rostislav Pehlivanov +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +perm_neg: dd 2, 5, 3, 4, 6, 1, 7, 0 +perm_pos: dd 0, 7, 1, 6, 4, 3, 5, 2 +sign_adjust_r: times 4 dd 0x80000000, 0x00000000 + +sign_adjust_5: dd 0x00000000, 0x80000000, 0x80000000, 0x00000000 + +SECTION .text + +%if ARCH_X86_64 + +;***************************************************************************************** +;void ff_fft15_avx(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); +;***************************************************************************************** +%macro FFT5 3 ; %1 - in_offset, %2 - dst1 (64bit used), %3 - dst2 + VBROADCASTSD m0, [inq + %1] ; in[ 0].re, in[ 0].im, in[ 0].re, in[ 0].im + movsd xm1, [inq + 1*16 + 8 + %1] ; in[ 3].re, in[ 3].im, 0, 0 + movsd xm4, [inq + 6*16 + 0 + %1] ; in[12].re, in[12].im, 0, 0 + movhps xm1, [inq + 3*16 + 0 + %1] ; in[ 3].re, in[ 3].im, in[ 6].re, in[ 6].im + movhps xm4, [inq + 4*16 + 8 + %1] ; in[12].re, in[12].im, in[ 9].re, in[ 9].im + + subps xm2, xm1, xm4 ; t[2].im, t[2].re, t[3].im, t[3].re + addps xm1, xm4 ; t[0].re, t[0].im, t[1].re, t[1].im + + movhlps %2, xm1 ; t[0].re, t[1].re, t[0].im, t[1].im + addps %2, xm1 + addps %2, xm0 ; DC[0].re, DC[0].im, junk... + movlhps %2, %2 ; DC[0].re, DC[0].im, DC[0].re, DC[0].im + + shufps xm3, xm1, xm2, q0110 ; t[0].re, t[0].im, t[2].re, t[2].im + shufps xm1, xm2, q2332 ; t[1].re, t[1].im, t[3].re, t[3].im + + mulps xm%3, xm1, xm5 + mulps xm4, xm3, xm6 + mulps xm1, xm6 + + xorps xm1, xm7 + mulps xm3, xm5 + addsubps xm3, xm1 ; t[0].re, t[0].im, t[2].re, t[2].im + subps xm%3, xm4 ; t[4].re, t[4].im, t[5].re, t[5].im + + movhlps xm2, xm%3, xm3 ; t[2].re, t[2].im, t[5].re, t[5].im + movlhps xm3, xm%3 ; t[0].re, t[0].im, t[4].re, t[4].im + + xorps xm2, xm7 + addps xm%3, xm2, xm3 + subps xm3, xm2 + + shufps xm3, xm3, q1032 + vinsertf128 m%3, m%3, xm3, 1 ; All ACs (tmp[1] through to tmp[4]) + addps m%3, m%3, m0 ; Finally offset with DCs +%endmacro + +%macro BUTTERFLIES_DC 1 ; %1 - exptab_offset + mulps xm0, xm9, [exptabq + %1 + 16*0] + mulps xm1, xm10, [exptabq + %1 + 16*1] + + haddps xm0, xm1 + movhlps xm1, xm0 ; t[0].re, t[1].re, t[0].im, t[1].im + + addps xm0, xm1 + addps xm0, xm8 + + movsd [outq], xm0 +%endmacro + +%macro BUTTERFLIES_AC 1 ; %1 - exptab_offset + mulps m0, m12, [exptabq + 64*0 + 0*mmsize + %1] + mulps m1, m12, [exptabq + 64*0 + 1*mmsize + %1] + mulps m2, m13, [exptabq + 64*1 + 0*mmsize + %1] + mulps m3, m13, [exptabq + 64*1 + 1*mmsize + %1] + + addps m0, m0, m2 + addps m1, m1, m3 + addps m0, m0, m11 + + shufps m1, m1, m1, q2301 + addps m0, m0, m1 + + vextractf128 xm1, m0, 1 + + movlps [outq + strideq*1], xm0 + movhps [outq + strideq*2], xm0 + movlps [outq + stride3q], xm1 + movhps [outq + strideq*4], xm1 +%endmacro + +INIT_YMM avx +cglobal fft15, 4, 5, 14, out, in, exptab, stride, stride5 + shl strideq, 3 + + movaps xm5, [exptabq + 480 + 16*0] + movaps xm6, [exptabq + 480 + 16*1] + movaps xm7, [sign_adjust_5] + + FFT5 0, xm8, 11 + FFT5 8, xm9, 12 + FFT5 16, xm10, 13 + +%define stride3q inq + lea stride3q, [strideq + strideq*2] + lea stride5q, [strideq + strideq*4] + + BUTTERFLIES_DC (8*6 + 4*0)*2*4 + BUTTERFLIES_AC (8*0 + 0*0)*2*4 + + add outq, stride5q + BUTTERFLIES_DC (8*6 + 4*1)*2*4 + BUTTERFLIES_AC (8*2 + 0*0)*2*4 + + add outq, stride5q + BUTTERFLIES_DC (8*6 + 4*2)*2*4 + BUTTERFLIES_AC (8*4 + 0*0)*2*4 + + RET + +%endif ; ARCH_X86_64 + +;******************************************************************************************************* +;void ff_mdct15_postreindex(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); +;******************************************************************************************************* +%macro LUT_LOAD_4D 3 + mov r4d, [lutq + %3q*4 + 0] + movsd xmm%1, [inq + r4q*8] + mov r4d, [lutq + %3q*4 + 4] + movhps xmm%1, [inq + r4q*8] +%if cpuflag(avx2) + mov r4d, [lutq + %3q*4 + 8] + movsd %2, [inq + r4q*8] + mov r4d, [lutq + %3q*4 + 12] + movhps %2, [inq + r4q*8] + vinsertf128 %1, %1, %2, 1 +%endif +%endmacro + +%macro POSTROTATE_FN 1 +cglobal mdct15_postreindex, 5, 7, 8 + cpuflag(avx2)*2, out, in, exp, lut, len8, offset_p, offset_n + + xor offset_nq, offset_nq + lea offset_pq, [len8q*2 - %1] + + movaps m7, [sign_adjust_r] + +%if cpuflag(avx2) + movaps m8, [perm_pos] + movaps m9, [perm_neg] +%endif + +.loop: + movups m0, [expq + offset_pq*8] ; exp[p0].re, exp[p0].im, exp[p1].re, exp[p1].im, exp[p2].re, exp[p2].im, exp[p3].re, exp[p3].im + movups m1, [expq + offset_nq*8] ; exp[n3].re, exp[n3].im, exp[n2].re, exp[n2].im, exp[n1].re, exp[n1].im, exp[n0].re, exp[n0].im + + LUT_LOAD_4D m3, xm4, offset_p ; in[p0].re, in[p0].im, in[p1].re, in[p1].im, in[p2].re, in[p2].im, in[p3].re, in[p3].im + LUT_LOAD_4D m4, xm5, offset_n ; in[n3].re, in[n3].im, in[n2].re, in[n2].im, in[n1].re, in[n1].im, in[n0].re, in[n0].im + + mulps m5, m3, m0 ; in[p].reim * exp[p].reim + mulps m6, m4, m1 ; in[n].reim * exp[n].reim + + xorps m5, m7 ; in[p].re *= -1, in[p].im *= 1 + xorps m6, m7 ; in[n].re *= -1, in[n].im *= 1 + + shufps m3, m3, m3, q2301 ; in[p].imre + shufps m4, m4, m4, q2301 ; in[n].imre + + mulps m3, m0 ; in[p].imre * exp[p].reim + mulps m4, m1 ; in[n].imre * exp[n].reim + + haddps m3, m6 ; out[n0].im, out[n1].im, out[n3].re, out[n2].re, out[n2].im, out[n3].im, out[n1].re, out[n0].re + haddps m5, m4 ; out[p0].re, out[p1].re, out[p3].im, out[p2].im, out[p2].re, out[p3].re, out[p1].im, out[p0].im + +%if cpuflag(avx2) + vpermps m3, m9, m3 ; out[n3].im, out[n3].re, out[n2].im, out[n2].re, out[n1].im, out[n1].re, out[n0].im, out[n0].re + vpermps m5, m8, m5 ; out[p0].re, out[p0].im, out[p1].re, out[p1].im, out[p2].re, out[p2].im, out[p3].re, out[p3].im +%else + shufps m3, m3, m3, q0312 + shufps m5, m5, m5, q2130 +%endif + + movups [outq + offset_nq*8], m3 + movups [outq + offset_pq*8], m5 + + sub offset_pq, %1 + add offset_nq, %1 + cmp offset_nq, offset_pq + jle .loop + + REP_RET +%endmacro + +INIT_XMM sse3 +POSTROTATE_FN 2 + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +POSTROTATE_FN 4 +%endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbrdsp.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbrdsp.asm new file mode 100644 index 000000000..62bbe512e --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavcodec/x86/sbrdsp.asm @@ -0,0 +1,548 @@ +;****************************************************************************** +;* AAC Spectral Band Replication decoding functions +;* Copyright (C) 2012 Christophe Gisquet +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA +; mask equivalent for multiply by -1.0 1.0 +ps_mask times 2 dd 1<<31, 0 +ps_mask2 times 2 dd 0, 1<<31 +ps_mask3 dd 0, 0, 0, 1<<31 +ps_noise0 times 2 dd 1.0, 0.0, +ps_noise2 times 2 dd -1.0, 0.0 +ps_noise13 dd 0.0, 1.0, 0.0, -1.0 + dd 0.0, -1.0, 0.0, 1.0 + dd 0.0, 1.0, 0.0, -1.0 +cextern sbr_noise_table +cextern ps_neg + +SECTION .text + +INIT_XMM sse +cglobal sbr_sum_square, 2, 3, 6 + mov r2d, r1d + xorps m0, m0 + xorps m1, m1 + sar r2, 3 + jz .prepare +.loop: + movu m2, [r0 + 0] + movu m3, [r0 + 16] + movu m4, [r0 + 32] + movu m5, [r0 + 48] + mulps m2, m2 + mulps m3, m3 + mulps m4, m4 + mulps m5, m5 + addps m0, m2 + addps m1, m3 + addps m0, m4 + addps m1, m5 + add r0, 64 + dec r2 + jnz .loop +.prepare: + and r1, 7 + sar r1, 1 + jz .end +; len is a multiple of 2, thus there are at least 4 elements to process +.endloop: + movu m2, [r0] + add r0, 16 + mulps m2, m2 + dec r1 + addps m0, m2 + jnz .endloop +.end: + addps m0, m1 + movhlps m2, m0 + addps m0, m2 + movss m1, m0 + shufps m0, m0, 1 + addss m0, m1 +%if ARCH_X86_64 == 0 + movss r0m, m0 + fld dword r0m +%endif + RET + +%define STEP 40*4*2 +cglobal sbr_hf_g_filt, 5, 6, 5 + lea r1, [r1 + 8*r4] ; offset by ixh elements into X_high + mov r5, r3 + and r3, 0xFC + lea r2, [r2 + r3*4] + lea r0, [r0 + r3*8] + neg r3 + jz .loop1 +.loop4: + movlps m0, [r2 + 4*r3 + 0] + movlps m1, [r2 + 4*r3 + 8] + movlps m2, [r1 + 0*STEP] + movlps m3, [r1 + 2*STEP] + movhps m2, [r1 + 1*STEP] + movhps m3, [r1 + 3*STEP] + unpcklps m0, m0 + unpcklps m1, m1 + mulps m0, m2 + mulps m1, m3 + movu [r0 + 8*r3 + 0], m0 + movu [r0 + 8*r3 + 16], m1 + add r1, 4*STEP + add r3, 4 + jnz .loop4 + and r5, 3 ; number of single element loops + jz .end +.loop1: ; element 0 and 1 can be computed at the same time + movss m0, [r2] + movlps m2, [r1] + unpcklps m0, m0 + mulps m2, m0 + movlps [r0], m2 + add r0, 8 + add r2, 4 + add r1, STEP + dec r5 + jnz .loop1 +.end: + RET + +; void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2], +; const float alpha0[2], const float alpha1[2], +; float bw, int start, int end) +; +cglobal sbr_hf_gen, 4,4,8, X_high, X_low, alpha0, alpha1, BW, S, E + ; load alpha factors +%define bw m0 +%if ARCH_X86_64 == 0 || WIN64 + movss bw, BWm +%endif + movlps m2, [alpha1q] + movlps m1, [alpha0q] + shufps bw, bw, 0 + mulps m2, bw ; (a1[0] a1[1])*bw + mulps m1, bw ; (a0[0] a0[1])*bw = (a2 a3) + mulps m2, bw ; (a1[0] a1[1])*bw*bw = (a0 a1) + mova m3, m1 + mova m4, m2 + + ; Set pointers +%if ARCH_X86_64 == 0 || WIN64 + ; start and end 6th and 7th args on stack + mov r2d, Sm + mov r3d, Em + DEFINE_ARGS X_high, X_low, start, end +%else +; BW does not actually occupy a register, so shift by 1 + DEFINE_ARGS X_high, X_low, alpha0, alpha1, start, end + movsxd startq, startd + movsxd endq, endd +%endif + sub startq, endq ; neg num of loops + lea X_highq, [X_highq + endq*2*4] + lea X_lowq, [X_lowq + endq*2*4 - 2*2*4] + shl startq, 3 ; offset from num loops + + mova m0, [X_lowq + startq] + shufps m3, m3, q1111 + shufps m4, m4, q1111 + xorps m3, [ps_mask] + shufps m1, m1, q0000 + shufps m2, m2, q0000 + xorps m4, [ps_mask] +.loop2: + movu m7, [X_lowq + startq + 8] ; BbCc + mova m6, m0 + mova m5, m7 + shufps m0, m0, q2301 ; aAbB + shufps m7, m7, q2301 ; bBcC + mulps m0, m4 + mulps m7, m3 + mulps m6, m2 + mulps m5, m1 + addps m7, m0 + mova m0, [X_lowq + startq + 16] ; CcDd + addps m7, m0 + addps m6, m5 + addps m7, m6 + mova [X_highq + startq], m7 + add startq, 16 + jnz .loop2 + RET + +cglobal sbr_sum64x5, 1,2,4,z + lea r1q, [zq+ 256] +.loop: + mova m0, [zq+ 0] + mova m2, [zq+ 16] + mova m1, [zq+ 256] + mova m3, [zq+ 272] + addps m0, [zq+ 512] + addps m2, [zq+ 528] + addps m1, [zq+ 768] + addps m3, [zq+ 784] + addps m0, [zq+1024] + addps m2, [zq+1040] + addps m0, m1 + addps m2, m3 + mova [zq], m0 + mova [zq+16], m2 + add zq, 32 + cmp zq, r1q + jne .loop + REP_RET + +INIT_XMM sse +cglobal sbr_qmf_post_shuffle, 2,3,4,W,z + lea r2q, [zq + (64-4)*4] + mova m3, [ps_neg] +.loop: + mova m1, [zq] + xorps m0, m3, [r2q] + shufps m0, m0, m0, q0123 + unpcklps m2, m0, m1 + unpckhps m0, m0, m1 + mova [Wq + 0], m2 + mova [Wq + 16], m0 + add Wq, 32 + sub r2q, 16 + add zq, 16 + cmp zq, r2q + jl .loop + REP_RET + +INIT_XMM sse +cglobal sbr_neg_odd_64, 1,2,4,z + lea r1q, [zq+256] +.loop: + mova m0, [zq+ 0] + mova m1, [zq+16] + mova m2, [zq+32] + mova m3, [zq+48] + xorps m0, [ps_mask2] + xorps m1, [ps_mask2] + xorps m2, [ps_mask2] + xorps m3, [ps_mask2] + mova [zq+ 0], m0 + mova [zq+16], m1 + mova [zq+32], m2 + mova [zq+48], m3 + add zq, 64 + cmp zq, r1q + jne .loop + REP_RET + +; void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1) +%macro SBR_QMF_DEINT_BFLY 0 +cglobal sbr_qmf_deint_bfly, 3,5,8, v,src0,src1,vrev,c + mov cq, 64*4-2*mmsize + lea vrevq, [vq + 64*4] +.loop: + mova m0, [src0q+cq] + mova m1, [src1q] + mova m4, [src0q+cq+mmsize] + mova m5, [src1q+mmsize] +%if cpuflag(sse2) + pshufd m2, m0, q0123 + pshufd m3, m1, q0123 + pshufd m6, m4, q0123 + pshufd m7, m5, q0123 +%else + shufps m2, m0, m0, q0123 + shufps m3, m1, m1, q0123 + shufps m6, m4, m4, q0123 + shufps m7, m5, m5, q0123 +%endif + addps m5, m2 + subps m0, m7 + addps m1, m6 + subps m4, m3 + mova [vrevq], m1 + mova [vrevq+mmsize], m5 + mova [vq+cq], m0 + mova [vq+cq+mmsize], m4 + add src1q, 2*mmsize + add vrevq, 2*mmsize + sub cq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +SBR_QMF_DEINT_BFLY + +INIT_XMM sse2 +SBR_QMF_DEINT_BFLY + +INIT_XMM sse2 +cglobal sbr_qmf_pre_shuffle, 1,4,6,z +%define OFFSET (32*4-2*mmsize) + mov r3q, OFFSET + lea r1q, [zq + (32+1)*4] + lea r2q, [zq + 64*4] + mova m5, [ps_neg] +.loop: + movu m0, [r1q] + movu m2, [r1q + mmsize] + movu m1, [zq + r3q + 4 + mmsize] + movu m3, [zq + r3q + 4] + + pxor m2, m5 + pxor m0, m5 + pshufd m2, m2, q0123 + pshufd m0, m0, q0123 + SBUTTERFLY dq, 2, 3, 4 + SBUTTERFLY dq, 0, 1, 4 + mova [r2q + 2*r3q + 0*mmsize], m2 + mova [r2q + 2*r3q + 1*mmsize], m3 + mova [r2q + 2*r3q + 2*mmsize], m0 + mova [r2q + 2*r3q + 3*mmsize], m1 + add r1q, 2*mmsize + sub r3q, 2*mmsize + jge .loop + movq m2, [zq] + movq [r2q], m2 + REP_RET + +%ifdef PIC +%define NREGS 1 +%if UNIX64 +%define NOISE_TABLE r6q ; r5q is m_max +%else +%define NOISE_TABLE r5q +%endif +%else +%define NREGS 0 +%define NOISE_TABLE sbr_noise_table +%endif + +%macro LOAD_NST 1 +%ifdef PIC + lea NOISE_TABLE, [%1] + mova m0, [kxq + NOISE_TABLE] +%else + mova m0, [kxq + %1] +%endif +%endmacro + +INIT_XMM sse2 +; sbr_hf_apply_noise_0(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_0, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + mova m0, [ps_noise0] + jmp apply_noise_main + +; sbr_hf_apply_noise_1(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_1, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + and kxq, 1 + shl kxq, 4 + LOAD_NST ps_noise13 + jmp apply_noise_main + +; sbr_hf_apply_noise_2(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_2, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + mova m0, [ps_noise2] + jmp apply_noise_main + +; sbr_hf_apply_noise_3(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_3, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + and kxq, 1 + shl kxq, 4 + LOAD_NST ps_noise13+16 + +apply_noise_main: +%if ARCH_X86_64 == 0 || WIN64 + mov kxd, m_maxm + DEFINE_ARGS Y, s_m, q_filt, noise, count +%else + DEFINE_ARGS Y, s_m, q_filt, noise, kx, count +%endif + movsxdifnidn noiseq, noised + dec noiseq + shl countd, 2 +%ifdef PIC + lea NOISE_TABLE, [sbr_noise_table] +%endif + lea Yq, [Yq + 2*countq] + add s_mq, countq + add q_filtq, countq + shl noiseq, 3 + pxor m5, m5 + neg countq +.loop: + mova m1, [q_filtq + countq] + movu m3, [noiseq + NOISE_TABLE + 1*mmsize] + movu m4, [noiseq + NOISE_TABLE + 2*mmsize] + add noiseq, 2*mmsize + and noiseq, 0x1ff<<3 + punpckhdq m2, m1, m1 + punpckldq m1, m1 + mulps m1, m3 ; m2 = q_filt[m] * ff_sbr_noise_table[noise] + mulps m2, m4 ; m2 = q_filt[m] * ff_sbr_noise_table[noise] + mova m3, [s_mq + countq] + ; TODO: replace by a vpermd in AVX2 + punpckhdq m4, m3, m3 + punpckldq m3, m3 + pcmpeqd m6, m3, m5 ; m6 == 0 + pcmpeqd m7, m4, m5 ; m7 == 0 + mulps m3, m0 ; s_m[m] * phi_sign + mulps m4, m0 ; s_m[m] * phi_sign + pand m1, m6 + pand m2, m7 + movu m6, [Yq + 2*countq] + movu m7, [Yq + 2*countq + mmsize] + addps m3, m1 + addps m4, m2 + addps m6, m3 + addps m7, m4 + movu [Yq + 2*countq], m6 + movu [Yq + 2*countq + mmsize], m7 + add countq, mmsize + jl .loop + RET + +INIT_XMM sse +cglobal sbr_qmf_deint_neg, 2,4,4,v,src,vrev,c +%define COUNT 32*4 +%define OFFSET 32*4 + mov cq, -COUNT + lea vrevq, [vq + OFFSET + COUNT] + add vq, OFFSET-mmsize + add srcq, 2*COUNT + mova m3, [ps_neg] +.loop: + mova m0, [srcq + 2*cq + 0*mmsize] + mova m1, [srcq + 2*cq + 1*mmsize] + shufps m2, m0, m1, q2020 + shufps m1, m0, q1313 + xorps m2, m3 + mova [vq], m1 + mova [vrevq + cq], m2 + sub vq, mmsize + add cq, mmsize + jl .loop + REP_RET + +%macro SBR_AUTOCORRELATE 0 +cglobal sbr_autocorrelate, 2,3,8,32, x, phi, cnt + mov cntq, 37*8 + add xq, cntq + neg cntq + +%if cpuflag(sse3) +%define MOVH movsd + movddup m5, [xq+cntq] +%else +%define MOVH movlps + movlps m5, [xq+cntq] + movlhps m5, m5 +%endif + MOVH m7, [xq+cntq+8 ] + MOVH m1, [xq+cntq+16] + shufps m7, m7, q0110 + shufps m1, m1, q0110 + mulps m3, m5, m7 ; x[0][0] * x[1][0], x[0][1] * x[1][1], x[0][0] * x[1][1], x[0][1] * x[1][0] + mulps m4, m5, m5 ; x[0][0] * x[0][0], x[0][1] * x[0][1]; + mulps m5, m1 ; real_sum2 = x[0][0] * x[2][0], x[0][1] * x[2][1]; imag_sum2 = x[0][0] * x[2][1], x[0][1] * x[2][0] + movaps [rsp ], m3 + movaps [rsp+16], m4 + add cntq, 8 + + MOVH m2, [xq+cntq+16] + movlhps m7, m7 + shufps m2, m2, q0110 + mulps m6, m7, m1 ; real_sum1 = x[1][0] * x[2][0], x[1][1] * x[2][1]; imag_sum1 += x[1][0] * x[2][1], x[1][1] * x[2][0] + mulps m4, m7, m2 + mulps m7, m7 ; real_sum0 = x[1][0] * x[1][0], x[1][1] * x[1][1]; + addps m5, m4 ; real_sum2 += x[1][0] * x[3][0], x[1][1] * x[3][1]; imag_sum2 += x[1][0] * x[3][1], x[1][1] * x[3][0] + +align 16 +.loop: + add cntq, 8 + MOVH m0, [xq+cntq+16] + movlhps m1, m1 + shufps m0, m0, q0110 + mulps m3, m1, m2 + mulps m4, m1, m0 + mulps m1, m1 + addps m6, m3 ; real_sum1 += x[i][0] * x[i + 1][0], x[i][1] * x[i + 1][1]; imag_sum1 += x[i][0] * x[i + 1][1], x[i][1] * x[i + 1][0]; + addps m5, m4 ; real_sum2 += x[i][0] * x[i + 2][0], x[i][1] * x[i + 2][1]; imag_sum2 += x[i][0] * x[i + 2][1], x[i][1] * x[i + 2][0]; + addps m7, m1 ; real_sum0 += x[i][0] * x[i][0], x[i][1] * x[i][1]; + add cntq, 8 + MOVH m1, [xq+cntq+16] + movlhps m2, m2 + shufps m1, m1, q0110 + mulps m3, m2, m0 + mulps m4, m2, m1 + mulps m2, m2 + addps m6, m3 ; real_sum1 += x[i][0] * x[i + 1][0], x[i][1] * x[i + 1][1]; imag_sum1 += x[i][0] * x[i + 1][1], x[i][1] * x[i + 1][0]; + addps m5, m4 ; real_sum2 += x[i][0] * x[i + 2][0], x[i][1] * x[i + 2][1]; imag_sum2 += x[i][0] * x[i + 2][1], x[i][1] * x[i + 2][0]; + addps m7, m2 ; real_sum0 += x[i][0] * x[i][0], x[i][1] * x[i][1]; + add cntq, 8 + MOVH m2, [xq+cntq+16] + movlhps m0, m0 + shufps m2, m2, q0110 + mulps m3, m0, m1 + mulps m4, m0, m2 + mulps m0, m0 + addps m6, m3 ; real_sum1 += x[i][0] * x[i + 1][0], x[i][1] * x[i + 1][1]; imag_sum1 += x[i][0] * x[i + 1][1], x[i][1] * x[i + 1][0]; + addps m5, m4 ; real_sum2 += x[i][0] * x[i + 2][0], x[i][1] * x[i + 2][1]; imag_sum2 += x[i][0] * x[i + 2][1], x[i][1] * x[i + 2][0]; + addps m7, m0 ; real_sum0 += x[i][0] * x[i][0], x[i][1] * x[i][1]; + jl .loop + + movlhps m1, m1 + mulps m2, m1 + mulps m1, m1 + addps m2, m6 ; real_sum1 + x[38][0] * x[39][0], x[38][1] * x[39][1]; imag_sum1 + x[38][0] * x[39][1], x[38][1] * x[39][0]; + addps m1, m7 ; real_sum0 + x[38][0] * x[38][0], x[38][1] * x[38][1]; + addps m6, [rsp ] ; real_sum1 + x[ 0][0] * x[ 1][0], x[ 0][1] * x[ 1][1]; imag_sum1 + x[ 0][0] * x[ 1][1], x[ 0][1] * x[ 1][0]; + addps m7, [rsp+16] ; real_sum0 + x[ 0][0] * x[ 0][0], x[ 0][1] * x[ 0][1]; + + xorps m2, [ps_mask3] + xorps m5, [ps_mask3] + xorps m6, [ps_mask3] + HADDPS m2, m5, m3 + HADDPS m7, m6, m4 +%if cpuflag(sse3) + movshdup m0, m1 +%else + movss m0, m1 + shufps m1, m1, q0001 +%endif + addss m1, m0 + movaps [phiq ], m2 + movhps [phiq+0x18], m7 + movss [phiq+0x28], m7 + movss [phiq+0x10], m1 + RET +%endmacro + +INIT_XMM sse +SBR_AUTOCORRELATE +INIT_XMM sse3 +SBR_AUTOCORRELATE diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/Makefile new file mode 100644 index 000000000..5613813ba --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/aarch64/Makefile @@ -0,0 +1,4 @@ +OBJS += aarch64/cpu.o \ + aarch64/float_dsp_init.o \ + +NEON-OBJS += aarch64/float_dsp_neon.o diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/Makefile new file mode 100644 index 000000000..5da44b054 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/arm/Makefile @@ -0,0 +1,8 @@ +OBJS += arm/cpu.o \ + arm/float_dsp_init_arm.o \ + +VFP-OBJS += arm/float_dsp_init_vfp.o \ + arm/float_dsp_vfp.o \ + +NEON-OBJS += arm/float_dsp_init_neon.o \ + arm/float_dsp_neon.o \ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffversion.h b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffversion.h deleted file mode 100644 index 723c7d424..000000000 --- a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/ffversion.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Automatically generated by version.sh, do not manually edit! */ -#ifndef AVUTIL_FFVERSION_H -#define AVUTIL_FFVERSION_H -#define FFMPEG_VERSION "" -#endif /* AVUTIL_FFVERSION_H */ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/Makefile new file mode 100644 index 000000000..5f5242b5b --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/Makefile @@ -0,0 +1,18 @@ +OBJS += x86/cpu.o \ + x86/fixed_dsp_init.o \ + x86/float_dsp_init.o \ + x86/imgutils_init.o \ + x86/lls_init.o \ + +OBJS-$(CONFIG_PIXELUTILS) += x86/pixelutils_init.o \ + +EMMS_OBJS_$(HAVE_MMX_INLINE)_$(HAVE_MMX_EXTERNAL)_$(HAVE_MM_EMPTY) = x86/emms.o + +X86ASM-OBJS += x86/cpuid.o \ + $(EMMS_OBJS__yes_) \ + x86/fixed_dsp.o \ + x86/float_dsp.o \ + x86/imgutils.o \ + x86/lls.o \ + +X86ASM-OBJS-$(CONFIG_PIXELUTILS) += x86/pixelutils.o \ diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpuid.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpuid.asm new file mode 100644 index 000000000..c3f7866ec --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/cpuid.asm @@ -0,0 +1,91 @@ +;***************************************************************************** +;* Copyright (C) 2005-2010 x264 project +;* +;* Authors: Loren Merritt +;* Fiona Glaser +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx) +;----------------------------------------------------------------------------- +cglobal cpu_cpuid, 5,7 + push rbx + push r4 + push r3 + push r2 + push r1 + mov eax, r0d + xor ecx, ecx + cpuid + pop r4 + mov [r4], eax + pop r4 + mov [r4], ebx + pop r4 + mov [r4], ecx + pop r4 + mov [r4], edx + pop rbx + RET + +;----------------------------------------------------------------------------- +; void ff_cpu_xgetbv(int op, int *eax, int *edx) +;----------------------------------------------------------------------------- +cglobal cpu_xgetbv, 3,7 + push r2 + push r1 + mov ecx, r0d + xgetbv + pop r4 + mov [r4], eax + pop r4 + mov [r4], edx + RET + +%if ARCH_X86_64 == 0 +;----------------------------------------------------------------------------- +; int ff_cpu_cpuid_test(void) +; return 0 if unsupported +;----------------------------------------------------------------------------- +cglobal cpu_cpuid_test + pushfd + push ebx + push ebp + push esi + push edi + pushfd + pop eax + mov ebx, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ebx + pop edi + pop esi + pop ebp + pop ebx + popfd + ret +%endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/fixed_dsp.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/fixed_dsp.asm new file mode 100644 index 000000000..979dd5c33 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/fixed_dsp.asm @@ -0,0 +1,48 @@ +;***************************************************************************** +;* x86-optimized Float DSP functions +;* +;* Copyright 2016 James Almer +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_butterflies_fixed(float *src0, float *src1, int len); +;----------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal butterflies_fixed, 3,3,3, src0, src1, len + shl lend, 2 + add src0q, lenq + add src1q, lenq + neg lenq + +align 16 +.loop: + mova m0, [src0q + lenq] + mova m1, [src1q + lenq] + mova m2, m0 + paddd m0, m1 + psubd m2, m1 + mova [src0q + lenq], m0 + mova [src1q + lenq], m2 + add lenq, mmsize + jl .loop + RET diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/float_dsp.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/float_dsp.asm new file mode 100644 index 000000000..517fd6363 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/float_dsp.asm @@ -0,0 +1,484 @@ +;***************************************************************************** +;* x86-optimized Float DSP functions +;* +;* Copyright 2006 Loren Merritt +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "x86util.asm" + +SECTION_RODATA 32 +pd_reverse: dd 7, 6, 5, 4, 3, 2, 1, 0 + +SECTION .text + +;----------------------------------------------------------------------------- +; void vector_fmul(float *dst, const float *src0, const float *src1, int len) +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL 0 +cglobal vector_fmul, 4,4,2, dst, src0, src1, len + lea lenq, [lend*4 - 64] +ALIGN 16 +.loop: +%assign a 0 +%rep 32/mmsize + mova m0, [src0q + lenq + (a+0)*mmsize] + mova m1, [src0q + lenq + (a+1)*mmsize] + mulps m0, m0, [src1q + lenq + (a+0)*mmsize] + mulps m1, m1, [src1q + lenq + (a+1)*mmsize] + mova [dstq + lenq + (a+0)*mmsize], m0 + mova [dstq + lenq + (a+1)*mmsize], m1 +%assign a a+2 +%endrep + + sub lenq, 64 + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMUL +%endif + +;----------------------------------------------------------------------------- +; void vector_dmul(double *dst, const double *src0, const double *src1, int len) +;----------------------------------------------------------------------------- +%macro VECTOR_DMUL 0 +cglobal vector_dmul, 4,4,4, dst, src0, src1, len + lea lend, [lenq*8 - mmsize*4] +ALIGN 16 +.loop: + movaps m0, [src0q + lenq + 0*mmsize] + movaps m1, [src0q + lenq + 1*mmsize] + movaps m2, [src0q + lenq + 2*mmsize] + movaps m3, [src0q + lenq + 3*mmsize] + mulpd m0, m0, [src1q + lenq + 0*mmsize] + mulpd m1, m1, [src1q + lenq + 1*mmsize] + mulpd m2, m2, [src1q + lenq + 2*mmsize] + mulpd m3, m3, [src1q + lenq + 3*mmsize] + movaps [dstq + lenq + 0*mmsize], m0 + movaps [dstq + lenq + 1*mmsize], m1 + movaps [dstq + lenq + 2*mmsize], m2 + movaps [dstq + lenq + 3*mmsize], m3 + + sub lenq, mmsize*4 + jge .loop + RET +%endmacro + +INIT_XMM sse2 +VECTOR_DMUL +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_DMUL +%endif + +;------------------------------------------------------------------------------ +; void ff_vector_fmac_scalar(float *dst, const float *src, float mul, int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_FMAC_SCALAR 0 +%if UNIX64 +cglobal vector_fmac_scalar, 3,3,5, dst, src, len +%else +cglobal vector_fmac_scalar, 4,4,5, dst, src, mul, len +%endif +%if ARCH_X86_32 + VBROADCASTSS m0, mulm +%else +%if WIN64 + SWAP 0, 2 +%endif + shufps xm0, xm0, 0 +%if cpuflag(avx) + vinsertf128 m0, m0, xm0, 1 +%endif +%endif + lea lenq, [lend*4-64] +.loop: +%if cpuflag(fma3) + mova m1, [dstq+lenq] + mova m2, [dstq+lenq+1*mmsize] + fmaddps m1, m0, [srcq+lenq], m1 + fmaddps m2, m0, [srcq+lenq+1*mmsize], m2 +%else ; cpuflag + mulps m1, m0, [srcq+lenq] + mulps m2, m0, [srcq+lenq+1*mmsize] +%if mmsize < 32 + mulps m3, m0, [srcq+lenq+2*mmsize] + mulps m4, m0, [srcq+lenq+3*mmsize] +%endif ; mmsize + addps m1, m1, [dstq+lenq] + addps m2, m2, [dstq+lenq+1*mmsize] +%if mmsize < 32 + addps m3, m3, [dstq+lenq+2*mmsize] + addps m4, m4, [dstq+lenq+3*mmsize] +%endif ; mmsize +%endif ; cpuflag + mova [dstq+lenq], m1 + mova [dstq+lenq+1*mmsize], m2 +%if mmsize < 32 + mova [dstq+lenq+2*mmsize], m3 + mova [dstq+lenq+3*mmsize], m4 +%endif ; mmsize + sub lenq, 64 + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMAC_SCALAR +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMAC_SCALAR +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +VECTOR_FMAC_SCALAR +%endif + +;------------------------------------------------------------------------------ +; void ff_vector_fmul_scalar(float *dst, const float *src, float mul, int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_FMUL_SCALAR 0 +%if UNIX64 +cglobal vector_fmul_scalar, 3,3,2, dst, src, len +%else +cglobal vector_fmul_scalar, 4,4,3, dst, src, mul, len +%endif +%if ARCH_X86_32 + movss m0, mulm +%elif WIN64 + SWAP 0, 2 +%endif + shufps m0, m0, 0 + lea lenq, [lend*4-mmsize] +.loop: + mova m1, [srcq+lenq] + mulps m1, m0 + mova [dstq+lenq], m1 + sub lenq, mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL_SCALAR + +;------------------------------------------------------------------------------ +; void ff_vector_dmac_scalar(double *dst, const double *src, double mul, +; int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_DMAC_SCALAR 0 +%if ARCH_X86_32 +cglobal vector_dmac_scalar, 2,4,5, dst, src, mul, len, lenaddr + mov lenq, lenaddrm + VBROADCASTSD m0, mulm +%else +%if UNIX64 +cglobal vector_dmac_scalar, 3,3,5, dst, src, len +%else +cglobal vector_dmac_scalar, 4,4,5, dst, src, mul, len + SWAP 0, 2 +%endif + movlhps xm0, xm0 +%if cpuflag(avx) + vinsertf128 m0, m0, xm0, 1 +%endif +%endif + lea lenq, [lend*8-mmsize*4] +.loop: +%if cpuflag(fma3) + movaps m1, [dstq+lenq] + movaps m2, [dstq+lenq+1*mmsize] + movaps m3, [dstq+lenq+2*mmsize] + movaps m4, [dstq+lenq+3*mmsize] + fmaddpd m1, m0, [srcq+lenq], m1 + fmaddpd m2, m0, [srcq+lenq+1*mmsize], m2 + fmaddpd m3, m0, [srcq+lenq+2*mmsize], m3 + fmaddpd m4, m0, [srcq+lenq+3*mmsize], m4 +%else ; cpuflag + mulpd m1, m0, [srcq+lenq] + mulpd m2, m0, [srcq+lenq+1*mmsize] + mulpd m3, m0, [srcq+lenq+2*mmsize] + mulpd m4, m0, [srcq+lenq+3*mmsize] + addpd m1, m1, [dstq+lenq] + addpd m2, m2, [dstq+lenq+1*mmsize] + addpd m3, m3, [dstq+lenq+2*mmsize] + addpd m4, m4, [dstq+lenq+3*mmsize] +%endif ; cpuflag + movaps [dstq+lenq], m1 + movaps [dstq+lenq+1*mmsize], m2 + movaps [dstq+lenq+2*mmsize], m3 + movaps [dstq+lenq+3*mmsize], m4 + sub lenq, mmsize*4 + jge .loop + REP_RET +%endmacro + +INIT_XMM sse2 +VECTOR_DMAC_SCALAR +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_DMAC_SCALAR +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +VECTOR_DMAC_SCALAR +%endif + +;------------------------------------------------------------------------------ +; void ff_vector_dmul_scalar(double *dst, const double *src, double mul, +; int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_DMUL_SCALAR 0 +%if ARCH_X86_32 +cglobal vector_dmul_scalar, 3,4,3, dst, src, mul, len, lenaddr + mov lenq, lenaddrm +%elif UNIX64 +cglobal vector_dmul_scalar, 3,3,3, dst, src, len +%else +cglobal vector_dmul_scalar, 4,4,3, dst, src, mul, len +%endif +%if ARCH_X86_32 + VBROADCASTSD m0, mulm +%else +%if WIN64 + SWAP 0, 2 +%endif + movlhps xm0, xm0 +%if cpuflag(avx) + vinsertf128 ym0, ym0, xm0, 1 +%endif +%endif + lea lenq, [lend*8-2*mmsize] +.loop: + mulpd m1, m0, [srcq+lenq ] + mulpd m2, m0, [srcq+lenq+mmsize] + movaps [dstq+lenq ], m1 + movaps [dstq+lenq+mmsize], m2 + sub lenq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse2 +VECTOR_DMUL_SCALAR +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_DMUL_SCALAR +%endif + +;----------------------------------------------------------------------------- +; vector_fmul_window(float *dst, const float *src0, +; const float *src1, const float *win, int len); +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL_WINDOW 0 +cglobal vector_fmul_window, 5, 6, 6, dst, src0, src1, win, len, len1 + shl lend, 2 + lea len1q, [lenq - mmsize] + add src0q, lenq + add dstq, lenq + add winq, lenq + neg lenq +.loop: + mova m0, [winq + lenq] + mova m4, [src0q + lenq] +%if cpuflag(sse) + mova m1, [winq + len1q] + mova m5, [src1q + len1q] + shufps m1, m1, 0x1b + shufps m5, m5, 0x1b + mova m2, m0 + mova m3, m1 + mulps m2, m4 + mulps m3, m5 + mulps m1, m4 + mulps m0, m5 + addps m2, m3 + subps m1, m0 + shufps m2, m2, 0x1b +%else + pswapd m1, [winq + len1q] + pswapd m5, [src1q + len1q] + mova m2, m0 + mova m3, m1 + pfmul m2, m4 + pfmul m3, m5 + pfmul m1, m4 + pfmul m0, m5 + pfadd m2, m3 + pfsub m1, m0 + pswapd m2, m2 +%endif + mova [dstq + lenq], m1 + mova [dstq + len1q], m2 + sub len1q, mmsize + add lenq, mmsize + jl .loop +%if mmsize == 8 + femms +%endif + REP_RET +%endmacro + +INIT_MMX 3dnowext +VECTOR_FMUL_WINDOW +INIT_XMM sse +VECTOR_FMUL_WINDOW + +;----------------------------------------------------------------------------- +; vector_fmul_add(float *dst, const float *src0, const float *src1, +; const float *src2, int len) +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL_ADD 0 +cglobal vector_fmul_add, 5,5,4, dst, src0, src1, src2, len + lea lenq, [lend*4 - 2*mmsize] +ALIGN 16 +.loop: + mova m0, [src0q + lenq] + mova m1, [src0q + lenq + mmsize] +%if cpuflag(fma3) + mova m2, [src2q + lenq] + mova m3, [src2q + lenq + mmsize] + fmaddps m0, m0, [src1q + lenq], m2 + fmaddps m1, m1, [src1q + lenq + mmsize], m3 +%else + mulps m0, m0, [src1q + lenq] + mulps m1, m1, [src1q + lenq + mmsize] + addps m0, m0, [src2q + lenq] + addps m1, m1, [src2q + lenq + mmsize] +%endif + mova [dstq + lenq], m0 + mova [dstq + lenq + mmsize], m1 + + sub lenq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL_ADD +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMUL_ADD +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +VECTOR_FMUL_ADD +%endif + +;----------------------------------------------------------------------------- +; void vector_fmul_reverse(float *dst, const float *src0, const float *src1, +; int len) +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL_REVERSE 0 +cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len +%if cpuflag(avx2) + movaps m2, [pd_reverse] +%endif + lea lenq, [lend*4 - 2*mmsize] +ALIGN 16 +.loop: +%if cpuflag(avx2) + vpermps m0, m2, [src1q] + vpermps m1, m2, [src1q+mmsize] +%elif cpuflag(avx) + vmovaps xmm0, [src1q + 16] + vinsertf128 m0, m0, [src1q], 1 + vshufps m0, m0, m0, q0123 + vmovaps xmm1, [src1q + mmsize + 16] + vinsertf128 m1, m1, [src1q + mmsize], 1 + vshufps m1, m1, m1, q0123 +%else + mova m0, [src1q] + mova m1, [src1q + mmsize] + shufps m0, m0, q0123 + shufps m1, m1, q0123 +%endif + mulps m0, m0, [src0q + lenq + mmsize] + mulps m1, m1, [src0q + lenq] + movaps [dstq + lenq + mmsize], m0 + movaps [dstq + lenq], m1 + add src1q, 2*mmsize + sub lenq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL_REVERSE +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMUL_REVERSE +%endif +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +VECTOR_FMUL_REVERSE +%endif + +; float scalarproduct_float_sse(const float *v1, const float *v2, int len) +INIT_XMM sse +cglobal scalarproduct_float, 3,3,2, v1, v2, offset + shl offsetd, 2 + add v1q, offsetq + add v2q, offsetq + neg offsetq + xorps xmm0, xmm0 +.loop: + movaps xmm1, [v1q+offsetq] + mulps xmm1, [v2q+offsetq] + addps xmm0, xmm1 + add offsetq, 16 + js .loop + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movss xmm1, xmm0 + shufps xmm0, xmm0, 1 + addss xmm0, xmm1 +%if ARCH_X86_64 == 0 + movss r0m, xmm0 + fld dword r0m +%endif + RET + +;----------------------------------------------------------------------------- +; void ff_butterflies_float(float *src0, float *src1, int len); +;----------------------------------------------------------------------------- +INIT_XMM sse +cglobal butterflies_float, 3,3,3, src0, src1, len + shl lend, 2 + add src0q, lenq + add src1q, lenq + neg lenq +.loop: + mova m0, [src0q + lenq] + mova m1, [src1q + lenq] + subps m2, m0, m1 + addps m0, m0, m1 + mova [src1q + lenq], m2 + mova [src0q + lenq], m0 + add lenq, mmsize + jl .loop + REP_RET diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/imgutils.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/imgutils.asm new file mode 100644 index 000000000..3cca56cdc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/imgutils.asm @@ -0,0 +1,53 @@ +;***************************************************************************** +;* Copyright 2016 Anton Khirnov +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +INIT_XMM sse4 +cglobal image_copy_plane_uc_from, 6, 7, 4, dst, dst_linesize, src, src_linesize, bw, height, rowpos + add dstq, bwq + add srcq, bwq + neg bwq + +.row_start: + mov rowposq, bwq + +.loop: + movntdqa m0, [srcq + rowposq + 0 * mmsize] + movntdqa m1, [srcq + rowposq + 1 * mmsize] + movntdqa m2, [srcq + rowposq + 2 * mmsize] + movntdqa m3, [srcq + rowposq + 3 * mmsize] + + mova [dstq + rowposq + 0 * mmsize], m0 + mova [dstq + rowposq + 1 * mmsize], m1 + mova [dstq + rowposq + 2 * mmsize], m2 + mova [dstq + rowposq + 3 * mmsize], m3 + + add rowposq, 4 * mmsize + jnz .loop + + add srcq, src_linesizeq + add dstq, dst_linesizeq + dec heightd + jnz .row_start + + RET diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/lls.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/lls.asm new file mode 100644 index 000000000..317fba6fc --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/lls.asm @@ -0,0 +1,290 @@ +;****************************************************************************** +;* linear least squares model +;* +;* Copyright (c) 2013 Loren Merritt +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "x86util.asm" + +SECTION .text + +%define MAX_VARS 32 +%define MAX_VARS_ALIGN (MAX_VARS+4) +%define COVAR_STRIDE MAX_VARS_ALIGN*8 +%define COVAR(x,y) [covarq + (x)*8 + (y)*COVAR_STRIDE] + +struc LLSModel + .covariance: resq MAX_VARS_ALIGN*MAX_VARS_ALIGN + .coeff: resq MAX_VARS*MAX_VARS + .variance: resq MAX_VARS + .indep_count: resd 1 +endstruc + +%macro ADDPD_MEM 2 +%if cpuflag(avx) + vaddpd %2, %2, %1 +%else + addpd %2, %1 +%endif + mova %1, %2 +%endmacro + +INIT_XMM sse2 +%define movdqa movaps +cglobal update_lls, 2,5,8, ctx, var, i, j, covar2 + %define covarq ctxq + mov id, [ctxq + LLSModel.indep_count] + lea varq, [varq + iq*8] + neg iq + mov covar2q, covarq +.loopi: + ; Compute all 3 pairwise products of a 2x2 block that lies on the diagonal + mova m1, [varq + iq*8] + mova m3, [varq + iq*8 + 16] + pshufd m4, m1, q1010 + pshufd m5, m1, q3232 + pshufd m6, m3, q1010 + pshufd m7, m3, q3232 + mulpd m0, m1, m4 + mulpd m1, m1, m5 + lea covarq, [covar2q + 16] + ADDPD_MEM COVAR(-2,0), m0 + ADDPD_MEM COVAR(-2,1), m1 + lea jq, [iq + 2] + cmp jd, -2 + jg .skip4x4 +.loop4x4: + ; Compute all 16 pairwise products of a 4x4 block + mulpd m0, m4, m3 + mulpd m1, m5, m3 + mulpd m2, m6, m3 + mulpd m3, m3, m7 + ADDPD_MEM COVAR(0,0), m0 + ADDPD_MEM COVAR(0,1), m1 + ADDPD_MEM COVAR(0,2), m2 + ADDPD_MEM COVAR(0,3), m3 + mova m3, [varq + jq*8 + 16] + mulpd m0, m4, m3 + mulpd m1, m5, m3 + mulpd m2, m6, m3 + mulpd m3, m3, m7 + ADDPD_MEM COVAR(2,0), m0 + ADDPD_MEM COVAR(2,1), m1 + ADDPD_MEM COVAR(2,2), m2 + ADDPD_MEM COVAR(2,3), m3 + mova m3, [varq + jq*8 + 32] + add covarq, 32 + add jq, 4 + cmp jd, -2 + jle .loop4x4 +.skip4x4: + test jd, jd + jg .skip2x4 + mulpd m4, m3 + mulpd m5, m3 + mulpd m6, m3 + mulpd m7, m3 + ADDPD_MEM COVAR(0,0), m4 + ADDPD_MEM COVAR(0,1), m5 + ADDPD_MEM COVAR(0,2), m6 + ADDPD_MEM COVAR(0,3), m7 +.skip2x4: + add iq, 4 + add covar2q, 4*COVAR_STRIDE+32 + cmp id, -2 + jle .loopi + test id, id + jg .ret + mov jq, iq + %define covarq covar2q +.loop2x1: + movsd m0, [varq + iq*8] + movlhps m0, m0 + mulpd m0, [varq + jq*8] + ADDPD_MEM COVAR(0,0), m0 + inc iq + add covarq, COVAR_STRIDE + test id, id + jle .loop2x1 +.ret: + REP_RET + +%macro UPDATE_LLS 0 +cglobal update_lls, 3,6,8, ctx, var, count, i, j, count2 + %define covarq ctxq + mov countd, [ctxq + LLSModel.indep_count] + lea count2d, [countq-2] + xor id, id +.loopi: + ; Compute all 10 pairwise products of a 4x4 block that lies on the diagonal + mova ymm1, [varq + iq*8] + vbroadcastsd ymm4, [varq + iq*8] + vbroadcastsd ymm5, [varq + iq*8 + 8] + vbroadcastsd ymm6, [varq + iq*8 + 16] + vbroadcastsd ymm7, [varq + iq*8 + 24] + vextractf128 xmm3, ymm1, 1 +%if cpuflag(fma3) + mova ymm0, COVAR(iq ,0) + mova xmm2, COVAR(iq+2,2) + fmaddpd ymm0, ymm1, ymm4, ymm0 + fmaddpd xmm2, xmm3, xmm6, xmm2 + fmaddpd ymm1, ymm5, ymm1, COVAR(iq ,1) + fmaddpd xmm3, xmm7, xmm3, COVAR(iq+2,3) + mova COVAR(iq ,0), ymm0 + mova COVAR(iq ,1), ymm1 + mova COVAR(iq+2,2), xmm2 + mova COVAR(iq+2,3), xmm3 +%else + vmulpd ymm0, ymm1, ymm4 + vmulpd ymm1, ymm1, ymm5 + vmulpd xmm2, xmm3, xmm6 + vmulpd xmm3, xmm3, xmm7 + ADDPD_MEM COVAR(iq ,0), ymm0 + ADDPD_MEM COVAR(iq ,1), ymm1 + ADDPD_MEM COVAR(iq+2,2), xmm2 + ADDPD_MEM COVAR(iq+2,3), xmm3 +%endif ; cpuflag(fma3) + lea jd, [iq + 4] + cmp jd, count2d + jg .skip4x4 +.loop4x4: + ; Compute all 16 pairwise products of a 4x4 block + mova ymm3, [varq + jq*8] +%if cpuflag(fma3) + mova ymm0, COVAR(jq, 0) + mova ymm1, COVAR(jq, 1) + mova ymm2, COVAR(jq, 2) + fmaddpd ymm0, ymm3, ymm4, ymm0 + fmaddpd ymm1, ymm3, ymm5, ymm1 + fmaddpd ymm2, ymm3, ymm6, ymm2 + fmaddpd ymm3, ymm7, ymm3, COVAR(jq,3) + mova COVAR(jq, 0), ymm0 + mova COVAR(jq, 1), ymm1 + mova COVAR(jq, 2), ymm2 + mova COVAR(jq, 3), ymm3 +%else + vmulpd ymm0, ymm3, ymm4 + vmulpd ymm1, ymm3, ymm5 + vmulpd ymm2, ymm3, ymm6 + vmulpd ymm3, ymm3, ymm7 + ADDPD_MEM COVAR(jq,0), ymm0 + ADDPD_MEM COVAR(jq,1), ymm1 + ADDPD_MEM COVAR(jq,2), ymm2 + ADDPD_MEM COVAR(jq,3), ymm3 +%endif ; cpuflag(fma3) + add jd, 4 + cmp jd, count2d + jle .loop4x4 +.skip4x4: + cmp jd, countd + jg .skip2x4 + mova xmm3, [varq + jq*8] +%if cpuflag(fma3) + mova xmm0, COVAR(jq, 0) + mova xmm1, COVAR(jq, 1) + mova xmm2, COVAR(jq, 2) + fmaddpd xmm0, xmm3, xmm4, xmm0 + fmaddpd xmm1, xmm3, xmm5, xmm1 + fmaddpd xmm2, xmm3, xmm6, xmm2 + fmaddpd xmm3, xmm7, xmm3, COVAR(jq,3) + mova COVAR(jq, 0), xmm0 + mova COVAR(jq, 1), xmm1 + mova COVAR(jq, 2), xmm2 + mova COVAR(jq, 3), xmm3 +%else + vmulpd xmm0, xmm3, xmm4 + vmulpd xmm1, xmm3, xmm5 + vmulpd xmm2, xmm3, xmm6 + vmulpd xmm3, xmm3, xmm7 + ADDPD_MEM COVAR(jq,0), xmm0 + ADDPD_MEM COVAR(jq,1), xmm1 + ADDPD_MEM COVAR(jq,2), xmm2 + ADDPD_MEM COVAR(jq,3), xmm3 +%endif ; cpuflag(fma3) +.skip2x4: + add id, 4 + add covarq, 4*COVAR_STRIDE + cmp id, count2d + jle .loopi + cmp id, countd + jg .ret + mov jd, id +.loop2x1: + vmovddup xmm0, [varq + iq*8] +%if cpuflag(fma3) + mova xmm1, [varq + jq*8] + fmaddpd xmm0, xmm1, xmm0, COVAR(jq,0) + mova COVAR(jq,0), xmm0 +%else + vmulpd xmm0, [varq + jq*8] + ADDPD_MEM COVAR(jq,0), xmm0 +%endif ; cpuflag(fma3) + inc id + add covarq, COVAR_STRIDE + cmp id, countd + jle .loop2x1 +.ret: + REP_RET +%endmacro ; UPDATE_LLS + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +UPDATE_LLS +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +UPDATE_LLS +%endif + +INIT_XMM sse2 +cglobal evaluate_lls, 3,4,2, ctx, var, order, i + ; This function is often called on the same buffer as update_lls, but with + ; an offset. They can't both be aligned. + ; Load halves rather than movu to avoid store-forwarding stalls, since the + ; input was initialized immediately prior to this function using scalar math. + %define coefsq ctxq + mov id, orderd + imul orderd, MAX_VARS + lea coefsq, [ctxq + LLSModel.coeff + orderq*8] + movsd m0, [varq] + movhpd m0, [varq + 8] + mulpd m0, [coefsq] + lea coefsq, [coefsq + iq*8] + lea varq, [varq + iq*8] + neg iq + add iq, 2 +.loop: + movsd m1, [varq + iq*8] + movhpd m1, [varq + iq*8 + 8] + mulpd m1, [coefsq + iq*8] + addpd m0, m1 + add iq, 2 + jl .loop + jg .skip1 + movsd m1, [varq + iq*8] + mulsd m1, [coefsq + iq*8] + addpd m0, m1 +.skip1: + movhlps m1, m0 + addsd m0, m1 +%if ARCH_X86_32 + movsd r0m, m0 + fld qword r0m +%endif + RET diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/x86inc.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/x86inc.asm new file mode 100644 index 000000000..5044ee86f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/x86inc.asm @@ -0,0 +1,1701 @@ +;***************************************************************************** +;* x86inc.asm: x264asm abstraction layer +;***************************************************************************** +;* Copyright (C) 2005-2018 x264 project +;* +;* Authors: Loren Merritt +;* Henrik Gramner +;* Anton Mitrofanov +;* Fiona Glaser +;* +;* Permission to use, copy, modify, and/or distribute this software for any +;* purpose with or without fee is hereby granted, provided that the above +;* copyright notice and this permission notice appear in all copies. +;* +;* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +;* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +;* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +;* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +;* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +;* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +;***************************************************************************** + +; This is a header file for the x264ASM assembly language, which uses +; NASM/YASM syntax combined with a large number of macros to provide easy +; abstraction between different calling conventions (x86_32, win64, linux64). +; It also has various other useful features to simplify writing the kind of +; DSP functions that are most often used in x264. + +; Unlike the rest of x264, this file is available under an ISC license, as it +; has significant usefulness outside of x264 and we want it to be available +; to the largest audience possible. Of course, if you modify it for your own +; purposes to add a new feature, we strongly encourage contributing a patch +; as this feature might be useful for others as well. Send patches or ideas +; to x264-devel@videolan.org . + +%ifndef private_prefix + %define private_prefix x264 +%endif + +%ifndef public_prefix + %define public_prefix private_prefix +%endif + +%if HAVE_ALIGNED_STACK + %define STACK_ALIGNMENT 16 +%endif +%ifndef STACK_ALIGNMENT + %if ARCH_X86_64 + %define STACK_ALIGNMENT 16 + %else + %define STACK_ALIGNMENT 4 + %endif +%endif + +%define WIN64 0 +%define UNIX64 0 +%if ARCH_X86_64 + %ifidn __OUTPUT_FORMAT__,win32 + %define WIN64 1 + %elifidn __OUTPUT_FORMAT__,win64 + %define WIN64 1 + %elifidn __OUTPUT_FORMAT__,x64 + %define WIN64 1 + %else + %define UNIX64 1 + %endif +%endif + +%define FORMAT_ELF 0 +%ifidn __OUTPUT_FORMAT__,elf + %define FORMAT_ELF 1 +%elifidn __OUTPUT_FORMAT__,elf32 + %define FORMAT_ELF 1 +%elifidn __OUTPUT_FORMAT__,elf64 + %define FORMAT_ELF 1 +%endif + +%ifdef PREFIX + %define mangle(x) _ %+ x +%else + %define mangle(x) x +%endif + +; aout does not support align= +; NOTE: This section is out of sync with x264, in order to +; keep supporting OS/2. +%macro SECTION_RODATA 0-1 16 + %ifidn __OUTPUT_FORMAT__,aout + SECTION .text + %elifidn __OUTPUT_FORMAT__,coff + SECTION .text + %elifidn __OUTPUT_FORMAT__,win32 + SECTION .rdata align=%1 + %elif WIN64 + SECTION .rdata align=%1 + %else + SECTION .rodata align=%1 + %endif +%endmacro + +%if WIN64 + %define PIC +%elif ARCH_X86_64 == 0 +; x86_32 doesn't require PIC. +; Some distros prefer shared objects to be PIC, but nothing breaks if +; the code contains a few textrels, so we'll skip that complexity. + %undef PIC +%endif +%ifdef PIC + default rel +%endif + +%macro CPUNOP 1 + %if HAVE_CPUNOP + CPU %1 + %endif +%endmacro + +; Macros to eliminate most code duplication between x86_32 and x86_64: +; Currently this works only for leaf functions which load all their arguments +; into registers at the start, and make no other use of the stack. Luckily that +; covers most of x264's asm. + +; PROLOGUE: +; %1 = number of arguments. loads them from stack if needed. +; %2 = number of registers used. pushes callee-saved regs if needed. +; %3 = number of xmm registers used. pushes callee-saved xmm regs if needed. +; %4 = (optional) stack size to be allocated. The stack will be aligned before +; allocating the specified stack size. If the required stack alignment is +; larger than the known stack alignment the stack will be manually aligned +; and an extra register will be allocated to hold the original stack +; pointer (to not invalidate r0m etc.). To prevent the use of an extra +; register as stack pointer, request a negative stack size. +; %4+/%5+ = list of names to define to registers +; PROLOGUE can also be invoked by adding the same options to cglobal + +; e.g. +; cglobal foo, 2,3,7,0x40, dst, src, tmp +; declares a function (foo) that automatically loads two arguments (dst and +; src) into registers, uses one additional register (tmp) plus 7 vector +; registers (m0-m6) and allocates 0x40 bytes of stack space. + +; TODO Some functions can use some args directly from the stack. If they're the +; last args then you can just not declare them, but if they're in the middle +; we need more flexible macro. + +; RET: +; Pops anything that was pushed by PROLOGUE, and returns. + +; REP_RET: +; Use this instead of RET if it's a branch target. + +; registers: +; rN and rNq are the native-size register holding function argument N +; rNd, rNw, rNb are dword, word, and byte size +; rNh is the high 8 bits of the word size +; rNm is the original location of arg N (a register or on the stack), dword +; rNmp is native size + +%macro DECLARE_REG 2-3 + %define r%1q %2 + %define r%1d %2d + %define r%1w %2w + %define r%1b %2b + %define r%1h %2h + %define %2q %2 + %if %0 == 2 + %define r%1m %2d + %define r%1mp %2 + %elif ARCH_X86_64 ; memory + %define r%1m [rstk + stack_offset + %3] + %define r%1mp qword r %+ %1 %+ m + %else + %define r%1m [rstk + stack_offset + %3] + %define r%1mp dword r %+ %1 %+ m + %endif + %define r%1 %2 +%endmacro + +%macro DECLARE_REG_SIZE 3 + %define r%1q r%1 + %define e%1q r%1 + %define r%1d e%1 + %define e%1d e%1 + %define r%1w %1 + %define e%1w %1 + %define r%1h %3 + %define e%1h %3 + %define r%1b %2 + %define e%1b %2 + %if ARCH_X86_64 == 0 + %define r%1 e%1 + %endif +%endmacro + +DECLARE_REG_SIZE ax, al, ah +DECLARE_REG_SIZE bx, bl, bh +DECLARE_REG_SIZE cx, cl, ch +DECLARE_REG_SIZE dx, dl, dh +DECLARE_REG_SIZE si, sil, null +DECLARE_REG_SIZE di, dil, null +DECLARE_REG_SIZE bp, bpl, null + +; t# defines for when per-arch register allocation is more complex than just function arguments + +%macro DECLARE_REG_TMP 1-* + %assign %%i 0 + %rep %0 + CAT_XDEFINE t, %%i, r%1 + %assign %%i %%i+1 + %rotate 1 + %endrep +%endmacro + +%macro DECLARE_REG_TMP_SIZE 0-* + %rep %0 + %define t%1q t%1 %+ q + %define t%1d t%1 %+ d + %define t%1w t%1 %+ w + %define t%1h t%1 %+ h + %define t%1b t%1 %+ b + %rotate 1 + %endrep +%endmacro + +DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 + +%if ARCH_X86_64 + %define gprsize 8 +%else + %define gprsize 4 +%endif + +%macro PUSH 1 + push %1 + %ifidn rstk, rsp + %assign stack_offset stack_offset+gprsize + %endif +%endmacro + +%macro POP 1 + pop %1 + %ifidn rstk, rsp + %assign stack_offset stack_offset-gprsize + %endif +%endmacro + +%macro PUSH_IF_USED 1-* + %rep %0 + %if %1 < regs_used + PUSH r%1 + %endif + %rotate 1 + %endrep +%endmacro + +%macro POP_IF_USED 1-* + %rep %0 + %if %1 < regs_used + pop r%1 + %endif + %rotate 1 + %endrep +%endmacro + +%macro LOAD_IF_USED 1-* + %rep %0 + %if %1 < num_args + mov r%1, r %+ %1 %+ mp + %endif + %rotate 1 + %endrep +%endmacro + +%macro SUB 2 + sub %1, %2 + %ifidn %1, rstk + %assign stack_offset stack_offset+(%2) + %endif +%endmacro + +%macro ADD 2 + add %1, %2 + %ifidn %1, rstk + %assign stack_offset stack_offset-(%2) + %endif +%endmacro + +%macro movifnidn 2 + %ifnidn %1, %2 + mov %1, %2 + %endif +%endmacro + +%macro movsxdifnidn 2 + %ifnidn %1, %2 + movsxd %1, %2 + %endif +%endmacro + +%macro ASSERT 1 + %if (%1) == 0 + %error assertion ``%1'' failed + %endif +%endmacro + +%macro DEFINE_ARGS 0-* + %ifdef n_arg_names + %assign %%i 0 + %rep n_arg_names + CAT_UNDEF arg_name %+ %%i, q + CAT_UNDEF arg_name %+ %%i, d + CAT_UNDEF arg_name %+ %%i, w + CAT_UNDEF arg_name %+ %%i, h + CAT_UNDEF arg_name %+ %%i, b + CAT_UNDEF arg_name %+ %%i, m + CAT_UNDEF arg_name %+ %%i, mp + CAT_UNDEF arg_name, %%i + %assign %%i %%i+1 + %endrep + %endif + + %xdefine %%stack_offset stack_offset + %undef stack_offset ; so that the current value of stack_offset doesn't get baked in by xdefine + %assign %%i 0 + %rep %0 + %xdefine %1q r %+ %%i %+ q + %xdefine %1d r %+ %%i %+ d + %xdefine %1w r %+ %%i %+ w + %xdefine %1h r %+ %%i %+ h + %xdefine %1b r %+ %%i %+ b + %xdefine %1m r %+ %%i %+ m + %xdefine %1mp r %+ %%i %+ mp + CAT_XDEFINE arg_name, %%i, %1 + %assign %%i %%i+1 + %rotate 1 + %endrep + %xdefine stack_offset %%stack_offset + %assign n_arg_names %0 +%endmacro + +%define required_stack_alignment ((mmsize + 15) & ~15) +%define vzeroupper_required (mmsize > 16 && (ARCH_X86_64 == 0 || xmm_regs_used > 16 || notcpuflag(avx512))) +%define high_mm_regs (16*cpuflag(avx512)) + +%macro ALLOC_STACK 1-2 0 ; stack_size, n_xmm_regs (for win64 only) + %ifnum %1 + %if %1 != 0 + %assign %%pad 0 + %assign stack_size %1 + %if stack_size < 0 + %assign stack_size -stack_size + %endif + %if WIN64 + %assign %%pad %%pad + 32 ; shadow space + %if mmsize != 8 + %assign xmm_regs_used %2 + %if xmm_regs_used > 8 + %assign %%pad %%pad + (xmm_regs_used-8)*16 ; callee-saved xmm registers + %endif + %endif + %endif + %if required_stack_alignment <= STACK_ALIGNMENT + ; maintain the current stack alignment + %assign stack_size_padded stack_size + %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) + SUB rsp, stack_size_padded + %else + %assign %%reg_num (regs_used - 1) + %xdefine rstk r %+ %%reg_num + ; align stack, and save original stack location directly above + ; it, i.e. in [rsp+stack_size_padded], so we can restore the + ; stack in a single instruction (i.e. mov rsp, rstk or mov + ; rsp, [rsp+stack_size_padded]) + %if %1 < 0 ; need to store rsp on stack + %xdefine rstkm [rsp + stack_size + %%pad] + %assign %%pad %%pad + gprsize + %else ; can keep rsp in rstk during whole function + %xdefine rstkm rstk + %endif + %assign stack_size_padded stack_size + ((%%pad + required_stack_alignment-1) & ~(required_stack_alignment-1)) + mov rstk, rsp + and rsp, ~(required_stack_alignment-1) + sub rsp, stack_size_padded + movifnidn rstkm, rstk + %endif + WIN64_PUSH_XMM + %endif + %endif +%endmacro + +%macro SETUP_STACK_POINTER 1 + %ifnum %1 + %if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT + %if %1 > 0 + ; Reserve an additional register for storing the original stack pointer, but avoid using + ; eax/rax for this purpose since it can potentially get overwritten as a return value. + %assign regs_used (regs_used + 1) + %if ARCH_X86_64 && regs_used == 7 + %assign regs_used 8 + %elif ARCH_X86_64 == 0 && regs_used == 1 + %assign regs_used 2 + %endif + %endif + %if ARCH_X86_64 && regs_used < 5 + UNIX64 * 3 + ; Ensure that we don't clobber any registers containing arguments. For UNIX64 we also preserve r6 (rax) + ; since it's used as a hidden argument in vararg functions to specify the number of vector registers used. + %assign regs_used 5 + UNIX64 * 3 + %endif + %endif + %endif +%endmacro + +%macro DEFINE_ARGS_INTERNAL 3+ + %ifnum %2 + DEFINE_ARGS %3 + %elif %1 == 4 + DEFINE_ARGS %2 + %elif %1 > 4 + DEFINE_ARGS %2, %3 + %endif +%endmacro + +%if WIN64 ; Windows x64 ;================================================= + +DECLARE_REG 0, rcx +DECLARE_REG 1, rdx +DECLARE_REG 2, R8 +DECLARE_REG 3, R9 +DECLARE_REG 4, R10, 40 +DECLARE_REG 5, R11, 48 +DECLARE_REG 6, rax, 56 +DECLARE_REG 7, rdi, 64 +DECLARE_REG 8, rsi, 72 +DECLARE_REG 9, rbx, 80 +DECLARE_REG 10, rbp, 88 +DECLARE_REG 11, R14, 96 +DECLARE_REG 12, R15, 104 +DECLARE_REG 13, R12, 112 +DECLARE_REG 14, R13, 120 + +%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... + %assign num_args %1 + %assign regs_used %2 + ASSERT regs_used >= num_args + SETUP_STACK_POINTER %4 + ASSERT regs_used <= 15 + PUSH_IF_USED 7, 8, 9, 10, 11, 12, 13, 14 + ALLOC_STACK %4, %3 + %if mmsize != 8 && stack_size == 0 + WIN64_SPILL_XMM %3 + %endif + LOAD_IF_USED 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + DEFINE_ARGS_INTERNAL %0, %4, %5 +%endmacro + +%macro WIN64_PUSH_XMM 0 + ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated. + %if xmm_regs_used > 6 + high_mm_regs + movaps [rstk + stack_offset + 8], xmm6 + %endif + %if xmm_regs_used > 7 + high_mm_regs + movaps [rstk + stack_offset + 24], xmm7 + %endif + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + %assign %%i 8 + %rep %%xmm_regs_on_stack + movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i + %assign %%i %%i+1 + %endrep + %endif +%endmacro + +%macro WIN64_SPILL_XMM 1 + %assign xmm_regs_used %1 + ASSERT xmm_regs_used <= 16 + high_mm_regs + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + ; Allocate stack space for callee-saved xmm registers plus shadow space and align the stack. + %assign %%pad %%xmm_regs_on_stack*16 + 32 + %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) + SUB rsp, stack_size_padded + %endif + WIN64_PUSH_XMM +%endmacro + +%macro WIN64_RESTORE_XMM_INTERNAL 0 + %assign %%pad_size 0 + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + %assign %%i xmm_regs_used - high_mm_regs + %rep %%xmm_regs_on_stack + %assign %%i %%i-1 + movaps xmm %+ %%i, [rsp + (%%i-8)*16 + stack_size + 32] + %endrep + %endif + %if stack_size_padded > 0 + %if stack_size > 0 && required_stack_alignment > STACK_ALIGNMENT + mov rsp, rstkm + %else + add rsp, stack_size_padded + %assign %%pad_size stack_size_padded + %endif + %endif + %if xmm_regs_used > 7 + high_mm_regs + movaps xmm7, [rsp + stack_offset - %%pad_size + 24] + %endif + %if xmm_regs_used > 6 + high_mm_regs + movaps xmm6, [rsp + stack_offset - %%pad_size + 8] + %endif +%endmacro + +%macro WIN64_RESTORE_XMM 0 + WIN64_RESTORE_XMM_INTERNAL + %assign stack_offset (stack_offset-stack_size_padded) + %assign stack_size_padded 0 + %assign xmm_regs_used 0 +%endmacro + +%define has_epilogue regs_used > 7 || stack_size > 0 || vzeroupper_required || xmm_regs_used > 6+high_mm_regs + +%macro RET 0 + WIN64_RESTORE_XMM_INTERNAL + POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7 + %if vzeroupper_required + vzeroupper + %endif + AUTO_REP_RET +%endmacro + +%elif ARCH_X86_64 ; *nix x64 ;============================================= + +DECLARE_REG 0, rdi +DECLARE_REG 1, rsi +DECLARE_REG 2, rdx +DECLARE_REG 3, rcx +DECLARE_REG 4, R8 +DECLARE_REG 5, R9 +DECLARE_REG 6, rax, 8 +DECLARE_REG 7, R10, 16 +DECLARE_REG 8, R11, 24 +DECLARE_REG 9, rbx, 32 +DECLARE_REG 10, rbp, 40 +DECLARE_REG 11, R14, 48 +DECLARE_REG 12, R15, 56 +DECLARE_REG 13, R12, 64 +DECLARE_REG 14, R13, 72 + +%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... + %assign num_args %1 + %assign regs_used %2 + %assign xmm_regs_used %3 + ASSERT regs_used >= num_args + SETUP_STACK_POINTER %4 + ASSERT regs_used <= 15 + PUSH_IF_USED 9, 10, 11, 12, 13, 14 + ALLOC_STACK %4 + LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14 + DEFINE_ARGS_INTERNAL %0, %4, %5 +%endmacro + +%define has_epilogue regs_used > 9 || stack_size > 0 || vzeroupper_required + +%macro RET 0 + %if stack_size_padded > 0 + %if required_stack_alignment > STACK_ALIGNMENT + mov rsp, rstkm + %else + add rsp, stack_size_padded + %endif + %endif + POP_IF_USED 14, 13, 12, 11, 10, 9 + %if vzeroupper_required + vzeroupper + %endif + AUTO_REP_RET +%endmacro + +%else ; X86_32 ;============================================================== + +DECLARE_REG 0, eax, 4 +DECLARE_REG 1, ecx, 8 +DECLARE_REG 2, edx, 12 +DECLARE_REG 3, ebx, 16 +DECLARE_REG 4, esi, 20 +DECLARE_REG 5, edi, 24 +DECLARE_REG 6, ebp, 28 +%define rsp esp + +%macro DECLARE_ARG 1-* + %rep %0 + %define r%1m [rstk + stack_offset + 4*%1 + 4] + %define r%1mp dword r%1m + %rotate 1 + %endrep +%endmacro + +DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 + +%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, [stack_size,] arg_names... + %assign num_args %1 + %assign regs_used %2 + ASSERT regs_used >= num_args + %if num_args > 7 + %assign num_args 7 + %endif + %if regs_used > 7 + %assign regs_used 7 + %endif + SETUP_STACK_POINTER %4 + ASSERT regs_used <= 7 + PUSH_IF_USED 3, 4, 5, 6 + ALLOC_STACK %4 + LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6 + DEFINE_ARGS_INTERNAL %0, %4, %5 +%endmacro + +%define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required + +%macro RET 0 + %if stack_size_padded > 0 + %if required_stack_alignment > STACK_ALIGNMENT + mov rsp, rstkm + %else + add rsp, stack_size_padded + %endif + %endif + POP_IF_USED 6, 5, 4, 3 + %if vzeroupper_required + vzeroupper + %endif + AUTO_REP_RET +%endmacro + +%endif ;====================================================================== + +%if WIN64 == 0 + %macro WIN64_SPILL_XMM 1 + %endmacro + %macro WIN64_RESTORE_XMM 0 + %endmacro + %macro WIN64_PUSH_XMM 0 + %endmacro +%endif + +; On AMD cpus <=K10, an ordinary ret is slow if it immediately follows either +; a branch or a branch target. So switch to a 2-byte form of ret in that case. +; We can automatically detect "follows a branch", but not a branch target. +; (SSSE3 is a sufficient condition to know that your cpu doesn't have this problem.) +%macro REP_RET 0 + %if has_epilogue || cpuflag(ssse3) + RET + %else + rep ret + %endif + annotate_function_size +%endmacro + +%define last_branch_adr $$ +%macro AUTO_REP_RET 0 + %if notcpuflag(ssse3) + times ((last_branch_adr-$)>>31)+1 rep ; times 1 iff $ == last_branch_adr. + %endif + ret + annotate_function_size +%endmacro + +%macro BRANCH_INSTR 0-* + %rep %0 + %macro %1 1-2 %1 + %2 %1 + %if notcpuflag(ssse3) + %%branch_instr equ $ + %xdefine last_branch_adr %%branch_instr + %endif + %endmacro + %rotate 1 + %endrep +%endmacro + +BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, jna, jnae, jb, jbe, jnb, jnbe, jc, jnc, js, jns, jo, jno, jp, jnp + +%macro TAIL_CALL 2 ; callee, is_nonadjacent + %if has_epilogue + call %1 + RET + %elif %2 + jmp %1 + %endif + annotate_function_size +%endmacro + +;============================================================================= +; arch-independent part +;============================================================================= + +%assign function_align 16 + +; Begin a function. +; Applies any symbol mangling needed for C linkage, and sets up a define such that +; subsequent uses of the function name automatically refer to the mangled version. +; Appends cpuflags to the function name if cpuflags has been specified. +; The "" empty default parameter is a workaround for nasm, which fails if SUFFIX +; is empty and we call cglobal_internal with just %1 %+ SUFFIX (without %2). +%macro cglobal 1-2+ "" ; name, [PROLOGUE args] + cglobal_internal 1, %1 %+ SUFFIX, %2 +%endmacro +%macro cvisible 1-2+ "" ; name, [PROLOGUE args] + cglobal_internal 0, %1 %+ SUFFIX, %2 +%endmacro +%macro cglobal_internal 2-3+ + annotate_function_size + %if %1 + %xdefine %%FUNCTION_PREFIX private_prefix + %xdefine %%VISIBILITY hidden + %else + %xdefine %%FUNCTION_PREFIX public_prefix + %xdefine %%VISIBILITY + %endif + %ifndef cglobaled_%2 + %xdefine %2 mangle(%%FUNCTION_PREFIX %+ _ %+ %2) + %xdefine %2.skip_prologue %2 %+ .skip_prologue + CAT_XDEFINE cglobaled_, %2, 1 + %endif + %xdefine current_function %2 + %xdefine current_function_section __SECT__ + %if FORMAT_ELF + global %2:function %%VISIBILITY + %else + global %2 + %endif + align function_align + %2: + RESET_MM_PERMUTATION ; needed for x86-64, also makes disassembly somewhat nicer + %xdefine rstk rsp ; copy of the original stack pointer, used when greater alignment than the known stack alignment is required + %assign stack_offset 0 ; stack pointer offset relative to the return address + %assign stack_size 0 ; amount of stack space that can be freely used inside a function + %assign stack_size_padded 0 ; total amount of allocated stack space, including space for callee-saved xmm registers on WIN64 and alignment padding + %assign xmm_regs_used 0 ; number of XMM registers requested, used for dealing with callee-saved registers on WIN64 and vzeroupper + %ifnidn %3, "" + PROLOGUE %3 + %endif +%endmacro + +; Create a global symbol from a local label with the correct name mangling and type +%macro cglobal_label 1 + %if FORMAT_ELF + global current_function %+ %1:function hidden + %else + global current_function %+ %1 + %endif + %1: +%endmacro + +%macro cextern 1 + %xdefine %1 mangle(private_prefix %+ _ %+ %1) + CAT_XDEFINE cglobaled_, %1, 1 + extern %1 +%endmacro + +; like cextern, but without the prefix +%macro cextern_naked 1 + %ifdef PREFIX + %xdefine %1 mangle(%1) + %endif + CAT_XDEFINE cglobaled_, %1, 1 + extern %1 +%endmacro + +%macro const 1-2+ + %xdefine %1 mangle(private_prefix %+ _ %+ %1) + %if FORMAT_ELF + global %1:data hidden + %else + global %1 + %endif + %1: %2 +%endmacro + +; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default. +%if FORMAT_ELF + [SECTION .note.GNU-stack noalloc noexec nowrite progbits] +%endif + +; Tell debuggers how large the function was. +; This may be invoked multiple times per function; we rely on later instances overriding earlier ones. +; This is invoked by RET and similar macros, and also cglobal does it for the previous function, +; but if the last function in a source file doesn't use any of the standard macros for its epilogue, +; then its size might be unspecified. +%macro annotate_function_size 0 + %ifdef __YASM_VER__ + %ifdef current_function + %if FORMAT_ELF + current_function_section + %%ecf equ $ + size current_function %%ecf - current_function + __SECT__ + %endif + %endif + %endif +%endmacro + +; cpuflags + +%assign cpuflags_mmx (1<<0) +%assign cpuflags_mmx2 (1<<1) | cpuflags_mmx +%assign cpuflags_3dnow (1<<2) | cpuflags_mmx +%assign cpuflags_3dnowext (1<<3) | cpuflags_3dnow +%assign cpuflags_sse (1<<4) | cpuflags_mmx2 +%assign cpuflags_sse2 (1<<5) | cpuflags_sse +%assign cpuflags_sse2slow (1<<6) | cpuflags_sse2 +%assign cpuflags_lzcnt (1<<7) | cpuflags_sse2 +%assign cpuflags_sse3 (1<<8) | cpuflags_sse2 +%assign cpuflags_ssse3 (1<<9) | cpuflags_sse3 +%assign cpuflags_sse4 (1<<10)| cpuflags_ssse3 +%assign cpuflags_sse42 (1<<11)| cpuflags_sse4 +%assign cpuflags_aesni (1<<12)| cpuflags_sse42 +%assign cpuflags_avx (1<<13)| cpuflags_sse42 +%assign cpuflags_xop (1<<14)| cpuflags_avx +%assign cpuflags_fma4 (1<<15)| cpuflags_avx +%assign cpuflags_fma3 (1<<16)| cpuflags_avx +%assign cpuflags_bmi1 (1<<17)| cpuflags_avx|cpuflags_lzcnt +%assign cpuflags_bmi2 (1<<18)| cpuflags_bmi1 +%assign cpuflags_avx2 (1<<19)| cpuflags_fma3|cpuflags_bmi2 +%assign cpuflags_avx512 (1<<20)| cpuflags_avx2 ; F, CD, BW, DQ, VL + +%assign cpuflags_cache32 (1<<21) +%assign cpuflags_cache64 (1<<22) +%assign cpuflags_aligned (1<<23) ; not a cpu feature, but a function variant +%assign cpuflags_atom (1<<24) + +; Returns a boolean value expressing whether or not the specified cpuflag is enabled. +%define cpuflag(x) (((((cpuflags & (cpuflags_ %+ x)) ^ (cpuflags_ %+ x)) - 1) >> 31) & 1) +%define notcpuflag(x) (cpuflag(x) ^ 1) + +; Takes an arbitrary number of cpuflags from the above list. +; All subsequent functions (up to the next INIT_CPUFLAGS) is built for the specified cpu. +; You shouldn't need to invoke this macro directly, it's a subroutine for INIT_MMX &co. +%macro INIT_CPUFLAGS 0-* + %xdefine SUFFIX + %undef cpuname + %assign cpuflags 0 + + %if %0 >= 1 + %rep %0 + %ifdef cpuname + %xdefine cpuname cpuname %+ _%1 + %else + %xdefine cpuname %1 + %endif + %assign cpuflags cpuflags | cpuflags_%1 + %rotate 1 + %endrep + %xdefine SUFFIX _ %+ cpuname + + %if cpuflag(avx) + %assign avx_enabled 1 + %endif + %if (mmsize == 16 && notcpuflag(sse2)) || (mmsize == 32 && notcpuflag(avx2)) + %define mova movaps + %define movu movups + %define movnta movntps + %endif + %if cpuflag(aligned) + %define movu mova + %elif cpuflag(sse3) && notcpuflag(ssse3) + %define movu lddqu + %endif + %endif + + %if ARCH_X86_64 || cpuflag(sse2) + CPUNOP amdnop + %else + CPUNOP basicnop + %endif +%endmacro + +; Merge mmx, sse*, and avx* +; m# is a simd register of the currently selected size +; xm# is the corresponding xmm register if mmsize >= 16, otherwise the same as m# +; ym# is the corresponding ymm register if mmsize >= 32, otherwise the same as m# +; zm# is the corresponding zmm register if mmsize >= 64, otherwise the same as m# +; (All 4 remain in sync through SWAP.) + +%macro CAT_XDEFINE 3 + %xdefine %1%2 %3 +%endmacro + +%macro CAT_UNDEF 2 + %undef %1%2 +%endmacro + +%macro DEFINE_MMREGS 1 ; mmtype + %assign %%prev_mmregs 0 + %ifdef num_mmregs + %assign %%prev_mmregs num_mmregs + %endif + + %assign num_mmregs 8 + %if ARCH_X86_64 && mmsize >= 16 + %assign num_mmregs 16 + %if cpuflag(avx512) || mmsize == 64 + %assign num_mmregs 32 + %endif + %endif + + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE m, %%i, %1 %+ %%i + CAT_XDEFINE nn%1, %%i, %%i + %assign %%i %%i+1 + %endrep + %if %%prev_mmregs > num_mmregs + %rep %%prev_mmregs - num_mmregs + CAT_UNDEF m, %%i + CAT_UNDEF nn %+ mmtype, %%i + %assign %%i %%i+1 + %endrep + %endif + %xdefine mmtype %1 +%endmacro + +; Prefer registers 16-31 over 0-15 to avoid having to use vzeroupper +%macro AVX512_MM_PERMUTATION 0-1 0 ; start_reg + %if ARCH_X86_64 && cpuflag(avx512) + %assign %%i %1 + %rep 16-%1 + %assign %%i_high %%i+16 + SWAP %%i, %%i_high + %assign %%i %%i+1 + %endrep + %endif +%endmacro + +%macro INIT_MMX 0-1+ + %assign avx_enabled 0 + %define RESET_MM_PERMUTATION INIT_MMX %1 + %define mmsize 8 + %define mova movq + %define movu movq + %define movh movd + %define movnta movntq + INIT_CPUFLAGS %1 + DEFINE_MMREGS mm +%endmacro + +%macro INIT_XMM 0-1+ + %assign avx_enabled 0 + %define RESET_MM_PERMUTATION INIT_XMM %1 + %define mmsize 16 + %define mova movdqa + %define movu movdqu + %define movh movq + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS xmm + %if WIN64 + AVX512_MM_PERMUTATION 6 ; Swap callee-saved registers with volatile registers + %endif +%endmacro + +%macro INIT_YMM 0-1+ + %assign avx_enabled 1 + %define RESET_MM_PERMUTATION INIT_YMM %1 + %define mmsize 32 + %define mova movdqa + %define movu movdqu + %undef movh + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS ymm + AVX512_MM_PERMUTATION +%endmacro + +%macro INIT_ZMM 0-1+ + %assign avx_enabled 1 + %define RESET_MM_PERMUTATION INIT_ZMM %1 + %define mmsize 64 + %define mova movdqa + %define movu movdqu + %undef movh + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS zmm + AVX512_MM_PERMUTATION +%endmacro + +INIT_XMM + +%macro DECLARE_MMCAST 1 + %define mmmm%1 mm%1 + %define mmxmm%1 mm%1 + %define mmymm%1 mm%1 + %define mmzmm%1 mm%1 + %define xmmmm%1 mm%1 + %define xmmxmm%1 xmm%1 + %define xmmymm%1 xmm%1 + %define xmmzmm%1 xmm%1 + %define ymmmm%1 mm%1 + %define ymmxmm%1 xmm%1 + %define ymmymm%1 ymm%1 + %define ymmzmm%1 ymm%1 + %define zmmmm%1 mm%1 + %define zmmxmm%1 xmm%1 + %define zmmymm%1 ymm%1 + %define zmmzmm%1 zmm%1 + %define xm%1 xmm %+ m%1 + %define ym%1 ymm %+ m%1 + %define zm%1 zmm %+ m%1 +%endmacro + +%assign i 0 +%rep 32 + DECLARE_MMCAST i + %assign i i+1 +%endrep + +; I often want to use macros that permute their arguments. e.g. there's no +; efficient way to implement butterfly or transpose or dct without swapping some +; arguments. +; +; I would like to not have to manually keep track of the permutations: +; If I insert a permutation in the middle of a function, it should automatically +; change everything that follows. For more complex macros I may also have multiple +; implementations, e.g. the SSE2 and SSSE3 versions may have different permutations. +; +; Hence these macros. Insert a PERMUTE or some SWAPs at the end of a macro that +; permutes its arguments. It's equivalent to exchanging the contents of the +; registers, except that this way you exchange the register names instead, so it +; doesn't cost any cycles. + +%macro PERMUTE 2-* ; takes a list of pairs to swap + %rep %0/2 + %xdefine %%tmp%2 m%2 + %rotate 2 + %endrep + %rep %0/2 + %xdefine m%1 %%tmp%2 + CAT_XDEFINE nn, m%1, %1 + %rotate 2 + %endrep +%endmacro + +%macro SWAP 2+ ; swaps a single chain (sometimes more concise than pairs) + %ifnum %1 ; SWAP 0, 1, ... + SWAP_INTERNAL_NUM %1, %2 + %else ; SWAP m0, m1, ... + SWAP_INTERNAL_NAME %1, %2 + %endif +%endmacro + +%macro SWAP_INTERNAL_NUM 2-* + %rep %0-1 + %xdefine %%tmp m%1 + %xdefine m%1 m%2 + %xdefine m%2 %%tmp + CAT_XDEFINE nn, m%1, %1 + CAT_XDEFINE nn, m%2, %2 + %rotate 1 + %endrep +%endmacro + +%macro SWAP_INTERNAL_NAME 2-* + %xdefine %%args nn %+ %1 + %rep %0-1 + %xdefine %%args %%args, nn %+ %2 + %rotate 1 + %endrep + SWAP_INTERNAL_NUM %%args +%endmacro + +; If SAVE_MM_PERMUTATION is placed at the end of a function, then any later +; calls to that function will automatically load the permutation, so values can +; be returned in mmregs. +%macro SAVE_MM_PERMUTATION 0-1 + %if %0 + %xdefine %%f %1_m + %else + %xdefine %%f current_function %+ _m + %endif + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE %%f, %%i, m %+ %%i + %assign %%i %%i+1 + %endrep +%endmacro + +%macro LOAD_MM_PERMUTATION 1 ; name to load from + %ifdef %1_m0 + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE m, %%i, %1_m %+ %%i + CAT_XDEFINE nn, m %+ %%i, %%i + %assign %%i %%i+1 + %endrep + %endif +%endmacro + +; Append cpuflags to the callee's name iff the appended name is known and the plain name isn't +%macro call 1 + %ifid %1 + call_internal %1 %+ SUFFIX, %1 + %else + call %1 + %endif +%endmacro +%macro call_internal 2 + %xdefine %%i %2 + %ifndef cglobaled_%2 + %ifdef cglobaled_%1 + %xdefine %%i %1 + %endif + %endif + call %%i + LOAD_MM_PERMUTATION %%i +%endmacro + +; Substitutions that reduce instruction size but are functionally equivalent +%macro add 2 + %ifnum %2 + %if %2==128 + sub %1, -128 + %else + add %1, %2 + %endif + %else + add %1, %2 + %endif +%endmacro + +%macro sub 2 + %ifnum %2 + %if %2==128 + add %1, -128 + %else + sub %1, %2 + %endif + %else + sub %1, %2 + %endif +%endmacro + +;============================================================================= +; AVX abstraction layer +;============================================================================= + +%assign i 0 +%rep 32 + %if i < 8 + CAT_XDEFINE sizeofmm, i, 8 + CAT_XDEFINE regnumofmm, i, i + %endif + CAT_XDEFINE sizeofxmm, i, 16 + CAT_XDEFINE sizeofymm, i, 32 + CAT_XDEFINE sizeofzmm, i, 64 + CAT_XDEFINE regnumofxmm, i, i + CAT_XDEFINE regnumofymm, i, i + CAT_XDEFINE regnumofzmm, i, i + %assign i i+1 +%endrep +%undef i + +%macro CHECK_AVX_INSTR_EMU 3-* + %xdefine %%opcode %1 + %xdefine %%dst %2 + %rep %0-2 + %ifidn %%dst, %3 + %error non-avx emulation of ``%%opcode'' is not supported + %endif + %rotate 1 + %endrep +%endmacro + +;%1 == instruction +;%2 == minimal instruction set +;%3 == 1 if float, 0 if int +;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) +;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not +;%6+: operands +%macro RUN_AVX_INSTR 6-9+ + %ifnum sizeof%7 + %assign __sizeofreg sizeof%7 + %elifnum sizeof%6 + %assign __sizeofreg sizeof%6 + %else + %assign __sizeofreg mmsize + %endif + %assign __emulate_avx 0 + %if avx_enabled && __sizeofreg >= 16 + %xdefine __instr v%1 + %else + %xdefine __instr %1 + %if %0 >= 8+%4 + %assign __emulate_avx 1 + %endif + %endif + %ifnidn %2, fnord + %ifdef cpuname + %if notcpuflag(%2) + %error use of ``%1'' %2 instruction in cpuname function: current_function + %elif cpuflags_%2 < cpuflags_sse && notcpuflag(sse2) && __sizeofreg > 8 + %error use of ``%1'' sse2 instruction in cpuname function: current_function + %endif + %endif + %endif + + %if __emulate_avx + %xdefine __src1 %7 + %xdefine __src2 %8 + %if %5 && %4 == 0 + %ifnidn %6, %7 + %ifidn %6, %8 + %xdefine __src1 %8 + %xdefine __src2 %7 + %elifnnum sizeof%8 + ; 3-operand AVX instructions with a memory arg can only have it in src2, + ; whereas SSE emulation prefers to have it in src1 (i.e. the mov). + ; So, if the instruction is commutative with a memory arg, swap them. + %xdefine __src1 %8 + %xdefine __src2 %7 + %endif + %endif + %endif + %ifnidn %6, __src1 + %if %0 >= 9 + CHECK_AVX_INSTR_EMU {%1 %6, %7, %8, %9}, %6, __src2, %9 + %else + CHECK_AVX_INSTR_EMU {%1 %6, %7, %8}, %6, __src2 + %endif + %if __sizeofreg == 8 + MOVQ %6, __src1 + %elif %3 + MOVAPS %6, __src1 + %else + MOVDQA %6, __src1 + %endif + %endif + %if %0 >= 9 + %1 %6, __src2, %9 + %else + %1 %6, __src2 + %endif + %elif %0 >= 9 + __instr %6, %7, %8, %9 + %elif %0 == 8 + __instr %6, %7, %8 + %elif %0 == 7 + __instr %6, %7 + %else + __instr %6 + %endif +%endmacro + +;%1 == instruction +;%2 == minimal instruction set +;%3 == 1 if float, 0 if int +;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) +;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not +%macro AVX_INSTR 1-5 fnord, 0, 255, 0 + %macro %1 1-10 fnord, fnord, fnord, fnord, %1, %2, %3, %4, %5 + %ifidn %2, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1 + %elifidn %3, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2 + %elifidn %4, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3 + %elifidn %5, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3, %4 + %else + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3, %4, %5 + %endif + %endmacro +%endmacro + +; Instructions with both VEX/EVEX and legacy encodings +; Non-destructive instructions are written without parameters +AVX_INSTR addpd, sse2, 1, 0, 1 +AVX_INSTR addps, sse, 1, 0, 1 +AVX_INSTR addsd, sse2, 1, 0, 0 +AVX_INSTR addss, sse, 1, 0, 0 +AVX_INSTR addsubpd, sse3, 1, 0, 0 +AVX_INSTR addsubps, sse3, 1, 0, 0 +AVX_INSTR aesdec, aesni, 0, 0, 0 +AVX_INSTR aesdeclast, aesni, 0, 0, 0 +AVX_INSTR aesenc, aesni, 0, 0, 0 +AVX_INSTR aesenclast, aesni, 0, 0, 0 +AVX_INSTR aesimc, aesni +AVX_INSTR aeskeygenassist, aesni +AVX_INSTR andnpd, sse2, 1, 0, 0 +AVX_INSTR andnps, sse, 1, 0, 0 +AVX_INSTR andpd, sse2, 1, 0, 1 +AVX_INSTR andps, sse, 1, 0, 1 +AVX_INSTR blendpd, sse4, 1, 1, 0 +AVX_INSTR blendps, sse4, 1, 1, 0 +AVX_INSTR blendvpd, sse4 ; can't be emulated +AVX_INSTR blendvps, sse4 ; can't be emulated +AVX_INSTR cmpeqpd, sse2, 1, 0, 1 +AVX_INSTR cmpeqps, sse, 1, 0, 1 +AVX_INSTR cmpeqsd, sse2, 1, 0, 0 +AVX_INSTR cmpeqss, sse, 1, 0, 0 +AVX_INSTR cmplepd, sse2, 1, 0, 0 +AVX_INSTR cmpleps, sse, 1, 0, 0 +AVX_INSTR cmplesd, sse2, 1, 0, 0 +AVX_INSTR cmpless, sse, 1, 0, 0 +AVX_INSTR cmpltpd, sse2, 1, 0, 0 +AVX_INSTR cmpltps, sse, 1, 0, 0 +AVX_INSTR cmpltsd, sse2, 1, 0, 0 +AVX_INSTR cmpltss, sse, 1, 0, 0 +AVX_INSTR cmpneqpd, sse2, 1, 0, 1 +AVX_INSTR cmpneqps, sse, 1, 0, 1 +AVX_INSTR cmpneqsd, sse2, 1, 0, 0 +AVX_INSTR cmpneqss, sse, 1, 0, 0 +AVX_INSTR cmpnlepd, sse2, 1, 0, 0 +AVX_INSTR cmpnleps, sse, 1, 0, 0 +AVX_INSTR cmpnlesd, sse2, 1, 0, 0 +AVX_INSTR cmpnless, sse, 1, 0, 0 +AVX_INSTR cmpnltpd, sse2, 1, 0, 0 +AVX_INSTR cmpnltps, sse, 1, 0, 0 +AVX_INSTR cmpnltsd, sse2, 1, 0, 0 +AVX_INSTR cmpnltss, sse, 1, 0, 0 +AVX_INSTR cmpordpd, sse2 1, 0, 1 +AVX_INSTR cmpordps, sse 1, 0, 1 +AVX_INSTR cmpordsd, sse2 1, 0, 0 +AVX_INSTR cmpordss, sse 1, 0, 0 +AVX_INSTR cmppd, sse2, 1, 1, 0 +AVX_INSTR cmpps, sse, 1, 1, 0 +AVX_INSTR cmpsd, sse2, 1, 1, 0 +AVX_INSTR cmpss, sse, 1, 1, 0 +AVX_INSTR cmpunordpd, sse2, 1, 0, 1 +AVX_INSTR cmpunordps, sse, 1, 0, 1 +AVX_INSTR cmpunordsd, sse2, 1, 0, 0 +AVX_INSTR cmpunordss, sse, 1, 0, 0 +AVX_INSTR comisd, sse2 +AVX_INSTR comiss, sse +AVX_INSTR cvtdq2pd, sse2 +AVX_INSTR cvtdq2ps, sse2 +AVX_INSTR cvtpd2dq, sse2 +AVX_INSTR cvtpd2ps, sse2 +AVX_INSTR cvtps2dq, sse2 +AVX_INSTR cvtps2pd, sse2 +AVX_INSTR cvtsd2si, sse2 +AVX_INSTR cvtsd2ss, sse2, 1, 0, 0 +AVX_INSTR cvtsi2sd, sse2, 1, 0, 0 +AVX_INSTR cvtsi2ss, sse, 1, 0, 0 +AVX_INSTR cvtss2sd, sse2, 1, 0, 0 +AVX_INSTR cvtss2si, sse +AVX_INSTR cvttpd2dq, sse2 +AVX_INSTR cvttps2dq, sse2 +AVX_INSTR cvttsd2si, sse2 +AVX_INSTR cvttss2si, sse +AVX_INSTR divpd, sse2, 1, 0, 0 +AVX_INSTR divps, sse, 1, 0, 0 +AVX_INSTR divsd, sse2, 1, 0, 0 +AVX_INSTR divss, sse, 1, 0, 0 +AVX_INSTR dppd, sse4, 1, 1, 0 +AVX_INSTR dpps, sse4, 1, 1, 0 +AVX_INSTR extractps, sse4 +AVX_INSTR haddpd, sse3, 1, 0, 0 +AVX_INSTR haddps, sse3, 1, 0, 0 +AVX_INSTR hsubpd, sse3, 1, 0, 0 +AVX_INSTR hsubps, sse3, 1, 0, 0 +AVX_INSTR insertps, sse4, 1, 1, 0 +AVX_INSTR lddqu, sse3 +AVX_INSTR ldmxcsr, sse +AVX_INSTR maskmovdqu, sse2 +AVX_INSTR maxpd, sse2, 1, 0, 1 +AVX_INSTR maxps, sse, 1, 0, 1 +AVX_INSTR maxsd, sse2, 1, 0, 0 +AVX_INSTR maxss, sse, 1, 0, 0 +AVX_INSTR minpd, sse2, 1, 0, 1 +AVX_INSTR minps, sse, 1, 0, 1 +AVX_INSTR minsd, sse2, 1, 0, 0 +AVX_INSTR minss, sse, 1, 0, 0 +AVX_INSTR movapd, sse2 +AVX_INSTR movaps, sse +AVX_INSTR movd, mmx +AVX_INSTR movddup, sse3 +AVX_INSTR movdqa, sse2 +AVX_INSTR movdqu, sse2 +AVX_INSTR movhlps, sse, 1, 0, 0 +AVX_INSTR movhpd, sse2, 1, 0, 0 +AVX_INSTR movhps, sse, 1, 0, 0 +AVX_INSTR movlhps, sse, 1, 0, 0 +AVX_INSTR movlpd, sse2, 1, 0, 0 +AVX_INSTR movlps, sse, 1, 0, 0 +AVX_INSTR movmskpd, sse2 +AVX_INSTR movmskps, sse +AVX_INSTR movntdq, sse2 +AVX_INSTR movntdqa, sse4 +AVX_INSTR movntpd, sse2 +AVX_INSTR movntps, sse +AVX_INSTR movq, mmx +AVX_INSTR movsd, sse2, 1, 0, 0 +AVX_INSTR movshdup, sse3 +AVX_INSTR movsldup, sse3 +AVX_INSTR movss, sse, 1, 0, 0 +AVX_INSTR movupd, sse2 +AVX_INSTR movups, sse +AVX_INSTR mpsadbw, sse4, 0, 1, 0 +AVX_INSTR mulpd, sse2, 1, 0, 1 +AVX_INSTR mulps, sse, 1, 0, 1 +AVX_INSTR mulsd, sse2, 1, 0, 0 +AVX_INSTR mulss, sse, 1, 0, 0 +AVX_INSTR orpd, sse2, 1, 0, 1 +AVX_INSTR orps, sse, 1, 0, 1 +AVX_INSTR pabsb, ssse3 +AVX_INSTR pabsd, ssse3 +AVX_INSTR pabsw, ssse3 +AVX_INSTR packsswb, mmx, 0, 0, 0 +AVX_INSTR packssdw, mmx, 0, 0, 0 +AVX_INSTR packuswb, mmx, 0, 0, 0 +AVX_INSTR packusdw, sse4, 0, 0, 0 +AVX_INSTR paddb, mmx, 0, 0, 1 +AVX_INSTR paddw, mmx, 0, 0, 1 +AVX_INSTR paddd, mmx, 0, 0, 1 +AVX_INSTR paddq, sse2, 0, 0, 1 +AVX_INSTR paddsb, mmx, 0, 0, 1 +AVX_INSTR paddsw, mmx, 0, 0, 1 +AVX_INSTR paddusb, mmx, 0, 0, 1 +AVX_INSTR paddusw, mmx, 0, 0, 1 +AVX_INSTR palignr, ssse3, 0, 1, 0 +AVX_INSTR pand, mmx, 0, 0, 1 +AVX_INSTR pandn, mmx, 0, 0, 0 +AVX_INSTR pavgb, mmx2, 0, 0, 1 +AVX_INSTR pavgw, mmx2, 0, 0, 1 +AVX_INSTR pblendvb, sse4 ; can't be emulated +AVX_INSTR pblendw, sse4, 0, 1, 0 +AVX_INSTR pclmulqdq, fnord, 0, 1, 0 +AVX_INSTR pclmulhqhqdq, fnord, 0, 0, 0 +AVX_INSTR pclmulhqlqdq, fnord, 0, 0, 0 +AVX_INSTR pclmullqhqdq, fnord, 0, 0, 0 +AVX_INSTR pclmullqlqdq, fnord, 0, 0, 0 +AVX_INSTR pcmpestri, sse42 +AVX_INSTR pcmpestrm, sse42 +AVX_INSTR pcmpistri, sse42 +AVX_INSTR pcmpistrm, sse42 +AVX_INSTR pcmpeqb, mmx, 0, 0, 1 +AVX_INSTR pcmpeqw, mmx, 0, 0, 1 +AVX_INSTR pcmpeqd, mmx, 0, 0, 1 +AVX_INSTR pcmpeqq, sse4, 0, 0, 1 +AVX_INSTR pcmpgtb, mmx, 0, 0, 0 +AVX_INSTR pcmpgtw, mmx, 0, 0, 0 +AVX_INSTR pcmpgtd, mmx, 0, 0, 0 +AVX_INSTR pcmpgtq, sse42, 0, 0, 0 +AVX_INSTR pextrb, sse4 +AVX_INSTR pextrd, sse4 +AVX_INSTR pextrq, sse4 +AVX_INSTR pextrw, mmx2 +AVX_INSTR phaddw, ssse3, 0, 0, 0 +AVX_INSTR phaddd, ssse3, 0, 0, 0 +AVX_INSTR phaddsw, ssse3, 0, 0, 0 +AVX_INSTR phminposuw, sse4 +AVX_INSTR phsubw, ssse3, 0, 0, 0 +AVX_INSTR phsubd, ssse3, 0, 0, 0 +AVX_INSTR phsubsw, ssse3, 0, 0, 0 +AVX_INSTR pinsrb, sse4, 0, 1, 0 +AVX_INSTR pinsrd, sse4, 0, 1, 0 +AVX_INSTR pinsrq, sse4, 0, 1, 0 +AVX_INSTR pinsrw, mmx2, 0, 1, 0 +AVX_INSTR pmaddwd, mmx, 0, 0, 1 +AVX_INSTR pmaddubsw, ssse3, 0, 0, 0 +AVX_INSTR pmaxsb, sse4, 0, 0, 1 +AVX_INSTR pmaxsw, mmx2, 0, 0, 1 +AVX_INSTR pmaxsd, sse4, 0, 0, 1 +AVX_INSTR pmaxub, mmx2, 0, 0, 1 +AVX_INSTR pmaxuw, sse4, 0, 0, 1 +AVX_INSTR pmaxud, sse4, 0, 0, 1 +AVX_INSTR pminsb, sse4, 0, 0, 1 +AVX_INSTR pminsw, mmx2, 0, 0, 1 +AVX_INSTR pminsd, sse4, 0, 0, 1 +AVX_INSTR pminub, mmx2, 0, 0, 1 +AVX_INSTR pminuw, sse4, 0, 0, 1 +AVX_INSTR pminud, sse4, 0, 0, 1 +AVX_INSTR pmovmskb, mmx2 +AVX_INSTR pmovsxbw, sse4 +AVX_INSTR pmovsxbd, sse4 +AVX_INSTR pmovsxbq, sse4 +AVX_INSTR pmovsxwd, sse4 +AVX_INSTR pmovsxwq, sse4 +AVX_INSTR pmovsxdq, sse4 +AVX_INSTR pmovzxbw, sse4 +AVX_INSTR pmovzxbd, sse4 +AVX_INSTR pmovzxbq, sse4 +AVX_INSTR pmovzxwd, sse4 +AVX_INSTR pmovzxwq, sse4 +AVX_INSTR pmovzxdq, sse4 +AVX_INSTR pmuldq, sse4, 0, 0, 1 +AVX_INSTR pmulhrsw, ssse3, 0, 0, 1 +AVX_INSTR pmulhuw, mmx2, 0, 0, 1 +AVX_INSTR pmulhw, mmx, 0, 0, 1 +AVX_INSTR pmullw, mmx, 0, 0, 1 +AVX_INSTR pmulld, sse4, 0, 0, 1 +AVX_INSTR pmuludq, sse2, 0, 0, 1 +AVX_INSTR por, mmx, 0, 0, 1 +AVX_INSTR psadbw, mmx2, 0, 0, 1 +AVX_INSTR pshufb, ssse3, 0, 0, 0 +AVX_INSTR pshufd, sse2 +AVX_INSTR pshufhw, sse2 +AVX_INSTR pshuflw, sse2 +AVX_INSTR psignb, ssse3, 0, 0, 0 +AVX_INSTR psignw, ssse3, 0, 0, 0 +AVX_INSTR psignd, ssse3, 0, 0, 0 +AVX_INSTR psllw, mmx, 0, 0, 0 +AVX_INSTR pslld, mmx, 0, 0, 0 +AVX_INSTR psllq, mmx, 0, 0, 0 +AVX_INSTR pslldq, sse2, 0, 0, 0 +AVX_INSTR psraw, mmx, 0, 0, 0 +AVX_INSTR psrad, mmx, 0, 0, 0 +AVX_INSTR psrlw, mmx, 0, 0, 0 +AVX_INSTR psrld, mmx, 0, 0, 0 +AVX_INSTR psrlq, mmx, 0, 0, 0 +AVX_INSTR psrldq, sse2, 0, 0, 0 +AVX_INSTR psubb, mmx, 0, 0, 0 +AVX_INSTR psubw, mmx, 0, 0, 0 +AVX_INSTR psubd, mmx, 0, 0, 0 +AVX_INSTR psubq, sse2, 0, 0, 0 +AVX_INSTR psubsb, mmx, 0, 0, 0 +AVX_INSTR psubsw, mmx, 0, 0, 0 +AVX_INSTR psubusb, mmx, 0, 0, 0 +AVX_INSTR psubusw, mmx, 0, 0, 0 +AVX_INSTR ptest, sse4 +AVX_INSTR punpckhbw, mmx, 0, 0, 0 +AVX_INSTR punpckhwd, mmx, 0, 0, 0 +AVX_INSTR punpckhdq, mmx, 0, 0, 0 +AVX_INSTR punpckhqdq, sse2, 0, 0, 0 +AVX_INSTR punpcklbw, mmx, 0, 0, 0 +AVX_INSTR punpcklwd, mmx, 0, 0, 0 +AVX_INSTR punpckldq, mmx, 0, 0, 0 +AVX_INSTR punpcklqdq, sse2, 0, 0, 0 +AVX_INSTR pxor, mmx, 0, 0, 1 +AVX_INSTR rcpps, sse +AVX_INSTR rcpss, sse, 1, 0, 0 +AVX_INSTR roundpd, sse4 +AVX_INSTR roundps, sse4 +AVX_INSTR roundsd, sse4, 1, 1, 0 +AVX_INSTR roundss, sse4, 1, 1, 0 +AVX_INSTR rsqrtps, sse +AVX_INSTR rsqrtss, sse, 1, 0, 0 +AVX_INSTR shufpd, sse2, 1, 1, 0 +AVX_INSTR shufps, sse, 1, 1, 0 +AVX_INSTR sqrtpd, sse2 +AVX_INSTR sqrtps, sse +AVX_INSTR sqrtsd, sse2, 1, 0, 0 +AVX_INSTR sqrtss, sse, 1, 0, 0 +AVX_INSTR stmxcsr, sse +AVX_INSTR subpd, sse2, 1, 0, 0 +AVX_INSTR subps, sse, 1, 0, 0 +AVX_INSTR subsd, sse2, 1, 0, 0 +AVX_INSTR subss, sse, 1, 0, 0 +AVX_INSTR ucomisd, sse2 +AVX_INSTR ucomiss, sse +AVX_INSTR unpckhpd, sse2, 1, 0, 0 +AVX_INSTR unpckhps, sse, 1, 0, 0 +AVX_INSTR unpcklpd, sse2, 1, 0, 0 +AVX_INSTR unpcklps, sse, 1, 0, 0 +AVX_INSTR xorpd, sse2, 1, 0, 1 +AVX_INSTR xorps, sse, 1, 0, 1 + +; 3DNow instructions, for sharing code between AVX, SSE and 3DN +AVX_INSTR pfadd, 3dnow, 1, 0, 1 +AVX_INSTR pfsub, 3dnow, 1, 0, 0 +AVX_INSTR pfmul, 3dnow, 1, 0, 1 + +; base-4 constants for shuffles +%assign i 0 +%rep 256 + %assign j ((i>>6)&3)*1000 + ((i>>4)&3)*100 + ((i>>2)&3)*10 + (i&3) + %if j < 10 + CAT_XDEFINE q000, j, i + %elif j < 100 + CAT_XDEFINE q00, j, i + %elif j < 1000 + CAT_XDEFINE q0, j, i + %else + CAT_XDEFINE q, j, i + %endif + %assign i i+1 +%endrep +%undef i +%undef j + +%macro FMA_INSTR 3 + %macro %1 4-7 %1, %2, %3 + %if cpuflag(xop) + v%5 %1, %2, %3, %4 + %elifnidn %1, %4 + %6 %1, %2, %3 + %7 %1, %4 + %else + %error non-xop emulation of ``%5 %1, %2, %3, %4'' is not supported + %endif + %endmacro +%endmacro + +FMA_INSTR pmacsww, pmullw, paddw +FMA_INSTR pmacsdd, pmulld, paddd ; sse4 emulation +FMA_INSTR pmacsdql, pmuldq, paddq ; sse4 emulation +FMA_INSTR pmadcswd, pmaddwd, paddd + +; tzcnt is equivalent to "rep bsf" and is backwards-compatible with bsf. +; This lets us use tzcnt without bumping the yasm version requirement yet. +%define tzcnt rep bsf + +; Macros for consolidating FMA3 and FMA4 using 4-operand (dst, src1, src2, src3) syntax. +; FMA3 is only possible if dst is the same as one of the src registers. +; Either src2 or src3 can be a memory operand. +%macro FMA4_INSTR 2-* + %push fma4_instr + %xdefine %$prefix %1 + %rep %0 - 1 + %macro %$prefix%2 4-6 %$prefix, %2 + %if notcpuflag(fma3) && notcpuflag(fma4) + %error use of ``%5%6'' fma instruction in cpuname function: current_function + %elif cpuflag(fma4) + v%5%6 %1, %2, %3, %4 + %elifidn %1, %2 + ; If %3 or %4 is a memory operand it needs to be encoded as the last operand. + %ifnum sizeof%3 + v%{5}213%6 %2, %3, %4 + %else + v%{5}132%6 %2, %4, %3 + %endif + %elifidn %1, %3 + v%{5}213%6 %3, %2, %4 + %elifidn %1, %4 + v%{5}231%6 %4, %2, %3 + %else + %error fma3 emulation of ``%5%6 %1, %2, %3, %4'' is not supported + %endif + %endmacro + %rotate 1 + %endrep + %pop +%endmacro + +FMA4_INSTR fmadd, pd, ps, sd, ss +FMA4_INSTR fmaddsub, pd, ps +FMA4_INSTR fmsub, pd, ps, sd, ss +FMA4_INSTR fmsubadd, pd, ps +FMA4_INSTR fnmadd, pd, ps, sd, ss +FMA4_INSTR fnmsub, pd, ps, sd, ss + +; Macros for converting VEX instructions to equivalent EVEX ones. +%macro EVEX_INSTR 2-3 0 ; vex, evex, prefer_evex + %macro %1 2-7 fnord, fnord, %1, %2, %3 + %ifidn %3, fnord + %define %%args %1, %2 + %elifidn %4, fnord + %define %%args %1, %2, %3 + %else + %define %%args %1, %2, %3, %4 + %endif + %assign %%evex_required cpuflag(avx512) & %7 + %ifnum regnumof%1 + %if regnumof%1 >= 16 || sizeof%1 > 32 + %assign %%evex_required 1 + %endif + %endif + %ifnum regnumof%2 + %if regnumof%2 >= 16 || sizeof%2 > 32 + %assign %%evex_required 1 + %endif + %endif + %if %%evex_required + %6 %%args + %else + %5 %%args ; Prefer VEX over EVEX due to shorter instruction length + %endif + %endmacro +%endmacro + +EVEX_INSTR vbroadcastf128, vbroadcastf32x4 +EVEX_INSTR vbroadcasti128, vbroadcasti32x4 +EVEX_INSTR vextractf128, vextractf32x4 +EVEX_INSTR vextracti128, vextracti32x4 +EVEX_INSTR vinsertf128, vinsertf32x4 +EVEX_INSTR vinserti128, vinserti32x4 +EVEX_INSTR vmovdqa, vmovdqa32 +EVEX_INSTR vmovdqu, vmovdqu32 +EVEX_INSTR vpand, vpandd +EVEX_INSTR vpandn, vpandnd +EVEX_INSTR vpor, vpord +EVEX_INSTR vpxor, vpxord +EVEX_INSTR vrcpps, vrcp14ps, 1 ; EVEX versions have higher precision +EVEX_INSTR vrcpss, vrcp14ss, 1 +EVEX_INSTR vrsqrtps, vrsqrt14ps, 1 +EVEX_INSTR vrsqrtss, vrsqrt14ss, 1 + +; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug (fixed in 1.3.0) +%ifdef __YASM_VER__ + %if __YASM_VERSION_ID__ < 0x01030000 && ARCH_X86_64 == 0 + %macro vpbroadcastq 2 + %if sizeof%1 == 16 + movddup %1, %2 + %else + vbroadcastsd %1, %2 + %endif + %endmacro + %endif +%endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/x86util.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/x86util.asm new file mode 100644 index 000000000..d7cd99684 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libavutil/x86/x86util.asm @@ -0,0 +1,1028 @@ +;***************************************************************************** +;* x86util.asm +;***************************************************************************** +;* Copyright (C) 2008-2010 x264 project +;* +;* Authors: Loren Merritt +;* Holger Lubitz +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%define private_prefix ff +%define public_prefix avpriv +%define cpuflags_mmxext cpuflags_mmx2 + +%include "libavutil/x86/x86inc.asm" + +; expands to [base],...,[base+7*stride] +%define PASS8ROWS(base, base3, stride, stride3) \ + [base], [base + stride], [base + 2*stride], [base3], \ + [base3 + stride], [base3 + 2*stride], [base3 + stride3], [base3 + stride*4] + +; Interleave low src0 with low src1 and store in src0, +; interleave high src0 with high src1 and store in src1. +; %1 - types +; %2 - index of the register with src0 +; %3 - index of the register with src1 +; %4 - index of the register for intermediate results +; example for %1 - wd: input: src0: x0 x1 x2 x3 z0 z1 z2 z3 +; src1: y0 y1 y2 y3 q0 q1 q2 q3 +; output: src0: x0 y0 x1 y1 x2 y2 x3 y3 +; src1: z0 q0 z1 q1 z2 q2 z3 q3 +%macro SBUTTERFLY 4 +%ifidn %1, dqqq + vperm2i128 m%4, m%2, m%3, q0301 + vinserti128 m%2, m%2, xm%3, 1 +%elif avx_enabled == 0 + mova m%4, m%2 + punpckl%1 m%2, m%3 + punpckh%1 m%4, m%3 +%else + punpckh%1 m%4, m%2, m%3 + punpckl%1 m%2, m%3 +%endif + SWAP %3, %4 +%endmacro + +%macro SBUTTERFLY2 4 + punpckl%1 m%4, m%2, m%3 + punpckh%1 m%2, m%2, m%3 + SWAP %2, %4, %3 +%endmacro + +%macro SBUTTERFLYPS 3 + unpcklps m%3, m%1, m%2 + unpckhps m%1, m%1, m%2 + SWAP %1, %3, %2 +%endmacro + +%macro SBUTTERFLYPD 3 + movlhps m%3, m%1, m%2 + movhlps m%2, m%2, m%1 + SWAP %1, %3 +%endmacro + +%macro TRANSPOSE4x4B 5 + SBUTTERFLY bw, %1, %2, %5 + SBUTTERFLY bw, %3, %4, %5 + SBUTTERFLY wd, %1, %3, %5 + SBUTTERFLY wd, %2, %4, %5 + SWAP %2, %3 +%endmacro + +%macro TRANSPOSE4x4W 5 + SBUTTERFLY wd, %1, %2, %5 + SBUTTERFLY wd, %3, %4, %5 + SBUTTERFLY dq, %1, %3, %5 + SBUTTERFLY dq, %2, %4, %5 + SWAP %2, %3 +%endmacro + +%macro TRANSPOSE2x4x4B 5 + SBUTTERFLY bw, %1, %2, %5 + SBUTTERFLY bw, %3, %4, %5 + SBUTTERFLY wd, %1, %3, %5 + SBUTTERFLY wd, %2, %4, %5 + SBUTTERFLY dq, %1, %2, %5 + SBUTTERFLY dq, %3, %4, %5 +%endmacro + +%macro TRANSPOSE2x4x4W 5 + SBUTTERFLY wd, %1, %2, %5 + SBUTTERFLY wd, %3, %4, %5 + SBUTTERFLY dq, %1, %3, %5 + SBUTTERFLY dq, %2, %4, %5 + SBUTTERFLY qdq, %1, %2, %5 + SBUTTERFLY qdq, %3, %4, %5 +%endmacro + +%macro TRANSPOSE4x4D 5 + SBUTTERFLY dq, %1, %2, %5 + SBUTTERFLY dq, %3, %4, %5 + SBUTTERFLY qdq, %1, %3, %5 + SBUTTERFLY qdq, %2, %4, %5 + SWAP %2, %3 +%endmacro + +; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops +%macro TRANSPOSE4x4PS 5 + SBUTTERFLYPS %1, %2, %5 + SBUTTERFLYPS %3, %4, %5 + SBUTTERFLYPD %1, %3, %5 + SBUTTERFLYPD %2, %4, %5 + SWAP %2, %3 +%endmacro + +%macro TRANSPOSE8x4D 9-11 +%if ARCH_X86_64 + SBUTTERFLY dq, %1, %2, %9 + SBUTTERFLY dq, %3, %4, %9 + SBUTTERFLY dq, %5, %6, %9 + SBUTTERFLY dq, %7, %8, %9 + SBUTTERFLY qdq, %1, %3, %9 + SBUTTERFLY qdq, %2, %4, %9 + SBUTTERFLY qdq, %5, %7, %9 + SBUTTERFLY qdq, %6, %8, %9 + SWAP %2, %5 + SWAP %4, %7 +%else +; in: m0..m7 +; out: m0..m7, unless %11 in which case m2 is in %9 +; spills into %9 and %10 + movdqa %9, m%7 + SBUTTERFLY dq, %1, %2, %7 + movdqa %10, m%2 + movdqa m%7, %9 + SBUTTERFLY dq, %3, %4, %2 + SBUTTERFLY dq, %5, %6, %2 + SBUTTERFLY dq, %7, %8, %2 + SBUTTERFLY qdq, %1, %3, %2 + movdqa %9, m%3 + movdqa m%2, %10 + SBUTTERFLY qdq, %2, %4, %3 + SBUTTERFLY qdq, %5, %7, %3 + SBUTTERFLY qdq, %6, %8, %3 + SWAP %2, %5 + SWAP %4, %7 +%if %0<11 + movdqa m%3, %9 +%endif +%endif +%endmacro + +%macro TRANSPOSE8x8W 9-11 +%if ARCH_X86_64 + SBUTTERFLY wd, %1, %2, %9 + SBUTTERFLY wd, %3, %4, %9 + SBUTTERFLY wd, %5, %6, %9 + SBUTTERFLY wd, %7, %8, %9 + SBUTTERFLY dq, %1, %3, %9 + SBUTTERFLY dq, %2, %4, %9 + SBUTTERFLY dq, %5, %7, %9 + SBUTTERFLY dq, %6, %8, %9 + SBUTTERFLY qdq, %1, %5, %9 + SBUTTERFLY qdq, %2, %6, %9 + SBUTTERFLY qdq, %3, %7, %9 + SBUTTERFLY qdq, %4, %8, %9 + SWAP %2, %5 + SWAP %4, %7 +%else +; in: m0..m7, unless %11 in which case m6 is in %9 +; out: m0..m7, unless %11 in which case m4 is in %10 +; spills into %9 and %10 +%if %0<11 + movdqa %9, m%7 +%endif + SBUTTERFLY wd, %1, %2, %7 + movdqa %10, m%2 + movdqa m%7, %9 + SBUTTERFLY wd, %3, %4, %2 + SBUTTERFLY wd, %5, %6, %2 + SBUTTERFLY wd, %7, %8, %2 + SBUTTERFLY dq, %1, %3, %2 + movdqa %9, m%3 + movdqa m%2, %10 + SBUTTERFLY dq, %2, %4, %3 + SBUTTERFLY dq, %5, %7, %3 + SBUTTERFLY dq, %6, %8, %3 + SBUTTERFLY qdq, %1, %5, %3 + SBUTTERFLY qdq, %2, %6, %3 + movdqa %10, m%2 + movdqa m%3, %9 + SBUTTERFLY qdq, %3, %7, %2 + SBUTTERFLY qdq, %4, %8, %2 + SWAP %2, %5 + SWAP %4, %7 +%if %0<11 + movdqa m%5, %10 +%endif +%endif +%endmacro + +%macro TRANSPOSE16x16W 18-19 +; in: m0..m15, unless %19 in which case m6 is in %17 +; out: m0..m15, unless %19 in which case m4 is in %18 +; spills into %17 and %18 +%if %0 < 19 + mova %17, m%7 +%endif + + SBUTTERFLY dqqq, %1, %9, %7 + SBUTTERFLY dqqq, %2, %10, %7 + SBUTTERFLY dqqq, %3, %11, %7 + SBUTTERFLY dqqq, %4, %12, %7 + SBUTTERFLY dqqq, %5, %13, %7 + SBUTTERFLY dqqq, %6, %14, %7 + mova %18, m%14 + mova m%7, %17 + SBUTTERFLY dqqq, %7, %15, %14 + SBUTTERFLY dqqq, %8, %16, %14 + + SBUTTERFLY wd, %1, %2, %14 + SBUTTERFLY wd, %3, %4, %14 + SBUTTERFLY wd, %5, %6, %14 + SBUTTERFLY wd, %7, %8, %14 + SBUTTERFLY wd, %9, %10, %14 + SBUTTERFLY wd, %11, %12, %14 + mova %17, m%12 + mova m%14, %18 + SBUTTERFLY wd, %13, %14, %12 + SBUTTERFLY wd, %15, %16, %12 + + SBUTTERFLY dq, %1, %3, %12 + SBUTTERFLY dq, %2, %4, %12 + SBUTTERFLY dq, %5, %7, %12 + SBUTTERFLY dq, %6, %8, %12 + SBUTTERFLY dq, %9, %11, %12 + mova %18, m%11 + mova m%12, %17 + SBUTTERFLY dq, %10, %12, %11 + SBUTTERFLY dq, %13, %15, %11 + SBUTTERFLY dq, %14, %16, %11 + + SBUTTERFLY qdq, %1, %5, %11 + SBUTTERFLY qdq, %2, %6, %11 + SBUTTERFLY qdq, %3, %7, %11 + SBUTTERFLY qdq, %4, %8, %11 + + SWAP %2, %5 + SWAP %4, %7 + + SBUTTERFLY qdq, %9, %13, %11 + SBUTTERFLY qdq, %10, %14, %11 + mova m%11, %18 + mova %18, m%5 + SBUTTERFLY qdq, %11, %15, %5 + SBUTTERFLY qdq, %12, %16, %5 + +%if %0 < 19 + mova m%5, %18 +%endif + + SWAP %10, %13 + SWAP %12, %15 +%endmacro + +%macro TRANSPOSE_8X8B 8 + %if mmsize == 8 + %error "This macro does not support mmsize == 8" + %endif + punpcklbw m%1, m%2 + punpcklbw m%3, m%4 + punpcklbw m%5, m%6 + punpcklbw m%7, m%8 + TRANSPOSE4x4W %1, %3, %5, %7, %2 + MOVHL m%2, m%1 + MOVHL m%4, m%3 + MOVHL m%6, m%5 + MOVHL m%8, m%7 +%endmacro + +; PABSW macro assumes %1 != %2, while ABS1/2 macros work in-place +%macro PABSW 2 +%if cpuflag(ssse3) + pabsw %1, %2 +%elif cpuflag(mmxext) + pxor %1, %1 + psubw %1, %2 + pmaxsw %1, %2 +%else + pxor %1, %1 + pcmpgtw %1, %2 + pxor %2, %1 + psubw %2, %1 + SWAP %1, %2 +%endif +%endmacro + +%macro PSIGNW 2 +%if cpuflag(ssse3) + psignw %1, %2 +%else + pxor %1, %2 + psubw %1, %2 +%endif +%endmacro + +%macro ABS1 2 +%if cpuflag(ssse3) + pabsw %1, %1 +%elif cpuflag(mmxext) ; a, tmp + pxor %2, %2 + psubw %2, %1 + pmaxsw %1, %2 +%else ; a, tmp + pxor %2, %2 + pcmpgtw %2, %1 + pxor %1, %2 + psubw %1, %2 +%endif +%endmacro + +%macro ABS2 4 +%if cpuflag(ssse3) + pabsw %1, %1 + pabsw %2, %2 +%elif cpuflag(mmxext) ; a, b, tmp0, tmp1 + pxor %3, %3 + pxor %4, %4 + psubw %3, %1 + psubw %4, %2 + pmaxsw %1, %3 + pmaxsw %2, %4 +%else ; a, b, tmp0, tmp1 + pxor %3, %3 + pxor %4, %4 + pcmpgtw %3, %1 + pcmpgtw %4, %2 + pxor %1, %3 + pxor %2, %4 + psubw %1, %3 + psubw %2, %4 +%endif +%endmacro + +%macro ABSB 2 ; source mmreg, temp mmreg (unused for SSSE3) +%if cpuflag(ssse3) + pabsb %1, %1 +%else + pxor %2, %2 + psubb %2, %1 + pminub %1, %2 +%endif +%endmacro + +%macro ABSB2 4 ; src1, src2, tmp1, tmp2 (tmp1/2 unused for SSSE3) +%if cpuflag(ssse3) + pabsb %1, %1 + pabsb %2, %2 +%else + pxor %3, %3 + pxor %4, %4 + psubb %3, %1 + psubb %4, %2 + pminub %1, %3 + pminub %2, %4 +%endif +%endmacro + +%macro ABSD2 4 + pxor %3, %3 + pxor %4, %4 + pcmpgtd %3, %1 + pcmpgtd %4, %2 + pxor %1, %3 + pxor %2, %4 + psubd %1, %3 + psubd %2, %4 +%endmacro + +%macro ABS4 6 + ABS2 %1, %2, %5, %6 + ABS2 %3, %4, %5, %6 +%endmacro + +%macro SPLATB_LOAD 3 +%if cpuflag(ssse3) + movd %1, [%2-3] + pshufb %1, %3 +%else + movd %1, [%2-3] ;to avoid crossing a cacheline + punpcklbw %1, %1 + SPLATW %1, %1, 3 +%endif +%endmacro + +%macro SPLATB_REG 3 +%if cpuflag(ssse3) + movd %1, %2d + pshufb %1, %3 +%else + movd %1, %2d + punpcklbw %1, %1 + SPLATW %1, %1, 0 +%endif +%endmacro + +%macro HADDD 2 ; sum junk +%if sizeof%1 == 32 +%define %2 xmm%2 + vextracti128 %2, %1, 1 +%define %1 xmm%1 + paddd %1, %2 +%endif +%if mmsize >= 16 +%if cpuflag(xop) && sizeof%1 == 16 + vphadddq %1, %1 +%endif + movhlps %2, %1 + paddd %1, %2 +%endif +%if notcpuflag(xop) || sizeof%1 != 16 +%if cpuflag(mmxext) + PSHUFLW %2, %1, q0032 +%else ; mmx + mova %2, %1 + psrlq %2, 32 +%endif + paddd %1, %2 +%endif +%undef %1 +%undef %2 +%endmacro + +%macro HADDW 2 ; reg, tmp +%if cpuflag(xop) && sizeof%1 == 16 + vphaddwq %1, %1 + movhlps %2, %1 + paddd %1, %2 +%else + pmaddwd %1, [pw_1] + HADDD %1, %2 +%endif +%endmacro + +%macro HADDPS 3 ; dst, src, tmp +%if cpuflag(sse3) + haddps %1, %1, %2 +%else + movaps %3, %1 + shufps %1, %2, q2020 + shufps %3, %2, q3131 + addps %1, %3 +%endif +%endmacro + +%macro PALIGNR 4-5 +%if cpuflag(ssse3) +%if %0==5 + palignr %1, %2, %3, %4 +%else + palignr %1, %2, %3 +%endif +%else ; [dst,] src1, src2, imm, tmp + %define %%dst %1 +%if %0==5 +%ifnidn %1, %2 + mova %%dst, %2 +%endif + %rotate 1 +%endif +%ifnidn %4, %2 + mova %4, %2 +%endif +%if mmsize==8 + psllq %%dst, (8-%3)*8 + psrlq %4, %3*8 +%else + pslldq %%dst, 16-%3 + psrldq %4, %3 +%endif + por %%dst, %4 +%endif +%endmacro + +%macro PAVGB 2-4 +%if cpuflag(mmxext) + pavgb %1, %2 +%elif cpuflag(3dnow) + pavgusb %1, %2 +%elif cpuflag(mmx) + movu %3, %2 + por %3, %1 + pxor %1, %2 + pand %1, %4 + psrlq %1, 1 + psubb %3, %1 + SWAP %1, %3 +%endif +%endmacro + +%macro PSHUFLW 1+ + %if mmsize == 8 + pshufw %1 + %else + pshuflw %1 + %endif +%endmacro + +%macro PSWAPD 2 +%if cpuflag(mmxext) + pshufw %1, %2, q1032 +%elif cpuflag(3dnowext) + pswapd %1, %2 +%elif cpuflag(3dnow) + movq %1, %2 + psrlq %1, 32 + punpckldq %1, %2 +%endif +%endmacro + +%macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from +%ifnum %5 + pand m%3, m%5, m%4 ; src .. y6 .. y4 + pand m%1, m%5, m%2 ; dst .. y6 .. y4 +%else + mova m%1, %5 + pand m%3, m%1, m%4 ; src .. y6 .. y4 + pand m%1, m%1, m%2 ; dst .. y6 .. y4 +%endif + psrlw m%2, 8 ; dst .. y7 .. y5 + psrlw m%4, 8 ; src .. y7 .. y5 +%endmacro + +%macro SUMSUB_BA 3-4 +%if %0==3 + padd%1 m%2, m%3 + padd%1 m%3, m%3 + psub%1 m%3, m%2 +%else +%if avx_enabled == 0 + mova m%4, m%2 + padd%1 m%2, m%3 + psub%1 m%3, m%4 +%else + padd%1 m%4, m%2, m%3 + psub%1 m%3, m%2 + SWAP %2, %4 +%endif +%endif +%endmacro + +%macro SUMSUB_BADC 5-6 +%if %0==6 + SUMSUB_BA %1, %2, %3, %6 + SUMSUB_BA %1, %4, %5, %6 +%else + padd%1 m%2, m%3 + padd%1 m%4, m%5 + padd%1 m%3, m%3 + padd%1 m%5, m%5 + psub%1 m%3, m%2 + psub%1 m%5, m%4 +%endif +%endmacro + +%macro SUMSUB2_AB 4 +%ifnum %3 + psub%1 m%4, m%2, m%3 + psub%1 m%4, m%3 + padd%1 m%2, m%2 + padd%1 m%2, m%3 +%else + mova m%4, m%2 + padd%1 m%2, m%2 + padd%1 m%2, %3 + psub%1 m%4, %3 + psub%1 m%4, %3 +%endif +%endmacro + +%macro SUMSUB2_BA 4 +%if avx_enabled == 0 + mova m%4, m%2 + padd%1 m%2, m%3 + padd%1 m%2, m%3 + psub%1 m%3, m%4 + psub%1 m%3, m%4 +%else + padd%1 m%4, m%2, m%3 + padd%1 m%4, m%3 + psub%1 m%3, m%2 + psub%1 m%3, m%2 + SWAP %2, %4 +%endif +%endmacro + +%macro SUMSUBD2_AB 5 +%ifnum %4 + psra%1 m%5, m%2, 1 ; %3: %3>>1 + psra%1 m%4, m%3, 1 ; %2: %2>>1 + padd%1 m%4, m%2 ; %3: %3>>1+%2 + psub%1 m%5, m%3 ; %2: %2>>1-%3 + SWAP %2, %5 + SWAP %3, %4 +%else + mova %5, m%2 + mova %4, m%3 + psra%1 m%3, 1 ; %3: %3>>1 + psra%1 m%2, 1 ; %2: %2>>1 + padd%1 m%3, %5 ; %3: %3>>1+%2 + psub%1 m%2, %4 ; %2: %2>>1-%3 +%endif +%endmacro + +%macro DCT4_1D 5 +%ifnum %5 + SUMSUB_BADC w, %4, %1, %3, %2, %5 + SUMSUB_BA w, %3, %4, %5 + SUMSUB2_AB w, %1, %2, %5 + SWAP %1, %3, %4, %5, %2 +%else + SUMSUB_BADC w, %4, %1, %3, %2 + SUMSUB_BA w, %3, %4 + mova [%5], m%2 + SUMSUB2_AB w, %1, [%5], %2 + SWAP %1, %3, %4, %2 +%endif +%endmacro + +%macro IDCT4_1D 6-7 +%ifnum %6 + SUMSUBD2_AB %1, %3, %5, %7, %6 + ; %3: %3>>1-%5 %5: %3+%5>>1 + SUMSUB_BA %1, %4, %2, %7 + ; %4: %2+%4 %2: %2-%4 + SUMSUB_BADC %1, %5, %4, %3, %2, %7 + ; %5: %2+%4 + (%3+%5>>1) + ; %4: %2+%4 - (%3+%5>>1) + ; %3: %2-%4 + (%3>>1-%5) + ; %2: %2-%4 - (%3>>1-%5) +%else +%ifidn %1, w + SUMSUBD2_AB %1, %3, %5, [%6], [%6+16] +%else + SUMSUBD2_AB %1, %3, %5, [%6], [%6+32] +%endif + SUMSUB_BA %1, %4, %2 + SUMSUB_BADC %1, %5, %4, %3, %2 +%endif + SWAP %2, %5, %4 + ; %2: %2+%4 + (%3+%5>>1) row0 + ; %3: %2-%4 + (%3>>1-%5) row1 + ; %4: %2-%4 - (%3>>1-%5) row2 + ; %5: %2+%4 - (%3+%5>>1) row3 +%endmacro + + +%macro LOAD_DIFF 5 +%ifidn %3, none + movh %1, %4 + movh %2, %5 + punpcklbw %1, %2 + punpcklbw %2, %2 + psubw %1, %2 +%else + movh %1, %4 + punpcklbw %1, %3 + movh %2, %5 + punpcklbw %2, %3 + psubw %1, %2 +%endif +%endmacro + +%macro STORE_DCT 6 + movq [%5+%6+ 0], m%1 + movq [%5+%6+ 8], m%2 + movq [%5+%6+16], m%3 + movq [%5+%6+24], m%4 + movhps [%5+%6+32], m%1 + movhps [%5+%6+40], m%2 + movhps [%5+%6+48], m%3 + movhps [%5+%6+56], m%4 +%endmacro + +%macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment? + LOAD_DIFF m%1, m%5, m%7, [%8], [%9] + LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3] + LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3] + LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5] +%if %10 + lea %8, [%8+4*r1] + lea %9, [%9+4*r3] +%endif +%endmacro + +%macro DIFFx2 6-7 + movh %3, %5 + punpcklbw %3, %4 + psraw %1, 6 + paddsw %1, %3 + movh %3, %6 + punpcklbw %3, %4 + psraw %2, 6 + paddsw %2, %3 + packuswb %2, %1 +%endmacro + +%macro STORE_DIFF 4 + movh %2, %4 + punpcklbw %2, %3 + psraw %1, 6 + paddsw %1, %2 + packuswb %1, %1 + movh %4, %1 +%endmacro + +%macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride + movh %3, [%7] + movh %4, [%7+%8] + psraw %1, %6 + psraw %2, %6 + punpcklbw %3, %5 + punpcklbw %4, %5 + paddw %3, %1 + paddw %4, %2 + packuswb %3, %5 + packuswb %4, %5 + movh [%7], %3 + movh [%7+%8], %4 +%endmacro + +%macro PMINUB 3 ; dst, src, ignored +%if cpuflag(mmxext) + pminub %1, %2 +%else ; dst, src, tmp + mova %3, %1 + psubusb %3, %2 + psubb %1, %3 +%endif +%endmacro + +%macro SPLATW 2-3 0 +%if cpuflag(avx2) && %3 == 0 + vpbroadcastw %1, %2 +%elif mmsize == 16 + pshuflw %1, %2, (%3)*0x55 + punpcklqdq %1, %1 +%elif cpuflag(mmxext) + pshufw %1, %2, (%3)*0x55 +%else + %ifnidn %1, %2 + mova %1, %2 + %endif + %if %3 & 2 + punpckhwd %1, %1 + %else + punpcklwd %1, %1 + %endif + %if %3 & 1 + punpckhwd %1, %1 + %else + punpcklwd %1, %1 + %endif +%endif +%endmacro + +%macro SPLATD 1 +%if mmsize == 8 + punpckldq %1, %1 +%elif cpuflag(sse2) + pshufd %1, %1, 0 +%elif cpuflag(sse) + shufps %1, %1, 0 +%endif +%endmacro + +%macro CLIPUB 3 ;(dst, min, max) + pmaxub %1, %2 + pminub %1, %3 +%endmacro + +%macro CLIPW 3 ;(dst, min, max) + pmaxsw %1, %2 + pminsw %1, %3 +%endmacro + +%macro PMINSD 3 ; dst, src, tmp/unused +%if cpuflag(sse4) + pminsd %1, %2 +%elif cpuflag(sse2) + cvtdq2ps %1, %1 + minps %1, %2 + cvtps2dq %1, %1 +%else + mova %3, %2 + pcmpgtd %3, %1 + pxor %1, %2 + pand %1, %3 + pxor %1, %2 +%endif +%endmacro + +%macro PMAXSD 3 ; dst, src, tmp/unused +%if cpuflag(sse4) + pmaxsd %1, %2 +%else + mova %3, %1 + pcmpgtd %3, %2 + pand %1, %3 + pandn %3, %2 + por %1, %3 +%endif +%endmacro + +%macro CLIPD 3-4 +%if cpuflag(sse4); src/dst, min, max, unused + pminsd %1, %3 + pmaxsd %1, %2 +%elif cpuflag(sse2) ; src/dst, min (float), max (float), unused + cvtdq2ps %1, %1 + minps %1, %3 + maxps %1, %2 + cvtps2dq %1, %1 +%else ; src/dst, min, max, tmp + PMINSD %1, %3, %4 + PMAXSD %1, %2, %4 +%endif +%endmacro + +%macro VBROADCASTSS 2 ; dst xmm/ymm, src m32/xmm +%if cpuflag(avx2) + vbroadcastss %1, %2 +%elif cpuflag(avx) + %ifnum sizeof%2 ; avx1 register + shufps xmm%1, xmm%2, xmm%2, q0000 + %if sizeof%1 >= 32 ; mmsize>=32 + vinsertf128 %1, %1, xmm%1, 1 + %endif + %else ; avx1 memory + vbroadcastss %1, %2 + %endif +%else + %ifnum sizeof%2 ; sse register + shufps %1, %2, %2, q0000 + %else ; sse memory + movss %1, %2 + shufps %1, %1, 0 + %endif +%endif +%endmacro + +%macro VBROADCASTSD 2 ; dst xmm/ymm, src m64 +%if cpuflag(avx) && mmsize == 32 + vbroadcastsd %1, %2 +%elif cpuflag(sse3) + movddup %1, %2 +%else ; sse2 + movsd %1, %2 + movlhps %1, %1 +%endif +%endmacro + +%macro VPBROADCASTD 2 ; dst xmm/ymm, src m32/xmm +%if cpuflag(avx2) + vpbroadcastd %1, %2 +%elif cpuflag(avx) && sizeof%1 >= 32 + %error vpbroadcastd not possible with ymm on avx1. try vbroadcastss +%else + %ifnum sizeof%2 ; sse2 register + pshufd %1, %2, q0000 + %else ; sse memory + movd %1, %2 + pshufd %1, %1, 0 + %endif +%endif +%endmacro + +%macro VBROADCASTI128 2 ; dst xmm/ymm, src : 128bits val +%if mmsize > 16 + vbroadcasti128 %1, %2 +%else + mova %1, %2 +%endif +%endmacro + +%macro SHUFFLE_MASK_W 8 + %rep 8 + %if %1>=0x80 + db %1, %1 + %else + db %1*2 + db %1*2+1 + %endif + %rotate 1 + %endrep +%endmacro + +%macro PMOVSXWD 2; dst, src +%if cpuflag(sse4) + pmovsxwd %1, %2 +%else + %ifnidn %1, %2 + mova %1, %2 + %endif + punpcklwd %1, %1 + psrad %1, 16 +%endif +%endmacro + +; Wrapper for non-FMA version of fmaddps +%macro FMULADD_PS 5 + %if cpuflag(fma3) || cpuflag(fma4) + fmaddps %1, %2, %3, %4 + %elifidn %1, %4 + mulps %5, %2, %3 + addps %1, %4, %5 + %else + mulps %1, %2, %3 + addps %1, %4 + %endif +%endmacro + +%macro LSHIFT 2 +%if mmsize > 8 + pslldq %1, %2 +%else + psllq %1, 8*(%2) +%endif +%endmacro + +%macro RSHIFT 2 +%if mmsize > 8 + psrldq %1, %2 +%else + psrlq %1, 8*(%2) +%endif +%endmacro + +%macro MOVHL 2 ; dst, src +%ifidn %1, %2 + punpckhqdq %1, %2 +%elif cpuflag(avx) + punpckhqdq %1, %2, %2 +%elif cpuflag(sse4) + pshufd %1, %2, q3232 ; pshufd is slow on some older CPUs, so only use it on more modern ones +%else + movhlps %1, %2 ; may cause an int/float domain transition and has a dependency on dst +%endif +%endmacro + +; Horizontal Sum of Packed Single precision floats +; The resulting sum is in all elements. +%macro HSUMPS 2 ; dst/src, tmp +%if cpuflag(avx) + %if sizeof%1>=32 ; avx + vperm2f128 %2, %1, %1, (0)*16+(1) + addps %1, %2 + %endif + shufps %2, %1, %1, q1032 + addps %1, %2 + shufps %2, %1, %1, q0321 + addps %1, %2 +%else ; this form is a bit faster than the short avx-like emulation. + movaps %2, %1 + shufps %1, %1, q1032 + addps %1, %2 + movaps %2, %1 + shufps %1, %1, q0321 + addps %1, %2 + ; all %1 members should be equal for as long as float a+b==b+a +%endif +%endmacro + +; Emulate blendvps if not available +; +; src_b is destroyed when using emulation with logical operands +; SSE41 blendv instruction is hard coded to use xmm0 as mask +%macro BLENDVPS 3 ; dst/src_a, src_b, mask +%if cpuflag(avx) + blendvps %1, %1, %2, %3 +%elif cpuflag(sse4) + %ifnidn %3,xmm0 + %error sse41 blendvps uses xmm0 as default 3d operand, you used %3 + %endif + blendvps %1, %2, %3 +%else + xorps %2, %1 + andps %2, %3 + xorps %1, %2 +%endif +%endmacro + +; Emulate pblendvb if not available +; +; src_b is destroyed when using emulation with logical operands +; SSE41 blendv instruction is hard coded to use xmm0 as mask +%macro PBLENDVB 3 ; dst/src_a, src_b, mask +%if cpuflag(avx) + %if cpuflag(avx) && notcpuflag(avx2) && sizeof%1 >= 32 + %error pblendb not possible with ymm on avx1, try blendvps. + %endif + pblendvb %1, %1, %2, %3 +%elif cpuflag(sse4) + %ifnidn %3,xmm0 + %error sse41 pblendvd uses xmm0 as default 3d operand, you used %3 + %endif + pblendvb %1, %2, %3 +%else + pxor %2, %1 + pand %2, %3 + pxor %1, %2 +%endif +%endmacro diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/Makefile new file mode 100644 index 000000000..5c34f8d94 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/aarch64/Makefile @@ -0,0 +1,7 @@ +OBJS += aarch64/audio_convert_init.o \ + aarch64/resample_init.o + +OBJS-$(CONFIG_NEON_CLOBBER_TEST) += aarch64/neontest.o + +NEON-OBJS += aarch64/audio_convert_neon.o \ + aarch64/resample.o diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/Makefile new file mode 100644 index 000000000..53ab4626f --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/arm/Makefile @@ -0,0 +1,8 @@ +OBJS += arm/audio_convert_init.o \ + arm/resample_init.o + + +OBJS-$(CONFIG_NEON_CLOBBER_TEST) += arm/neontest.o + +NEON-OBJS += arm/audio_convert_neon.o \ + arm/resample.o diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/Makefile b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/Makefile new file mode 100644 index 000000000..fa0641f03 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/Makefile @@ -0,0 +1,9 @@ +X86ASM-OBJS += x86/audio_convert.o\ + x86/rematrix.o\ + x86/resample.o\ + +OBJS += x86/audio_convert_init.o\ + x86/rematrix_init.o\ + x86/resample_init.o\ + +OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/audio_convert.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/audio_convert.asm new file mode 100644 index 000000000..d441636d3 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/audio_convert.asm @@ -0,0 +1,739 @@ +;****************************************************************************** +;* Copyright (c) 2012 Michael Niedermayer +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 +flt2pm31: times 8 dd 4.6566129e-10 +flt2p31 : times 8 dd 2147483648.0 +flt2p15 : times 8 dd 32768.0 + +word_unpack_shuf : db 0, 1, 4, 5, 8, 9,12,13, 2, 3, 6, 7,10,11,14,15 + +SECTION .text + + +;to, from, a/u, log2_outsize, log_intsize, const +%macro PACK_2CH 5-7 +cglobal pack_2ch_%2_to_%1_%3, 3, 4, 6, dst, src, len, src2 + mov src2q , [srcq+gprsize] + mov srcq , [srcq] + mov dstq , [dstq] +%ifidn %3, a + test dstq, mmsize-1 + jne pack_2ch_%2_to_%1_u_int %+ SUFFIX + test srcq, mmsize-1 + jne pack_2ch_%2_to_%1_u_int %+ SUFFIX + test src2q, mmsize-1 + jne pack_2ch_%2_to_%1_u_int %+ SUFFIX +%else +pack_2ch_%2_to_%1_u_int %+ SUFFIX: +%endif + lea srcq , [srcq + (1<<%5)*lenq] + lea src2q, [src2q + (1<<%5)*lenq] + lea dstq , [dstq + (2<<%4)*lenq] + neg lenq + %7 m0,m1,m2,m3,m4,m5 +.next: +%if %4 >= %5 + mov%3 m0, [ srcq +(1<<%5)*lenq] + mova m1, m0 + mov%3 m2, [ src2q+(1<<%5)*lenq] +%if %5 == 1 + punpcklwd m0, m2 + punpckhwd m1, m2 +%else + punpckldq m0, m2 + punpckhdq m1, m2 +%endif + %6 m0,m1,m2,m3,m4,m5 +%else + mov%3 m0, [ srcq +(1<<%5)*lenq] + mov%3 m1, [mmsize + srcq +(1<<%5)*lenq] + mov%3 m2, [ src2q+(1<<%5)*lenq] + mov%3 m3, [mmsize + src2q+(1<<%5)*lenq] + %6 m0,m1,m2,m3,m4,m5 + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + SWAP 1,2 +%endif + mov%3 [ dstq+(2<<%4)*lenq], m0 + mov%3 [ mmsize + dstq+(2<<%4)*lenq], m1 +%if %4 > %5 + mov%3 [2*mmsize + dstq+(2<<%4)*lenq], m2 + mov%3 [3*mmsize + dstq+(2<<%4)*lenq], m3 + add lenq, 4*mmsize/(2<<%4) +%else + add lenq, 2*mmsize/(2<<%4) +%endif + jl .next + REP_RET +%endmacro + +%macro UNPACK_2CH 5-7 +cglobal unpack_2ch_%2_to_%1_%3, 3, 4, 7, dst, src, len, dst2 + mov dst2q , [dstq+gprsize] + mov srcq , [srcq] + mov dstq , [dstq] +%ifidn %3, a + test dstq, mmsize-1 + jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX + test srcq, mmsize-1 + jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX + test dst2q, mmsize-1 + jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX +%else +unpack_2ch_%2_to_%1_u_int %+ SUFFIX: +%endif + lea srcq , [srcq + (2<<%5)*lenq] + lea dstq , [dstq + (1<<%4)*lenq] + lea dst2q, [dst2q + (1<<%4)*lenq] + neg lenq + %7 m0,m1,m2,m3,m4,m5 + mova m6, [word_unpack_shuf] +.next: + mov%3 m0, [ srcq +(2<<%5)*lenq] + mov%3 m2, [ mmsize + srcq +(2<<%5)*lenq] +%if %5 == 1 +%ifidn SUFFIX, _ssse3 + pshufb m0, m6 + mova m1, m0 + pshufb m2, m6 + punpcklqdq m0,m2 + punpckhqdq m1,m2 +%else + mova m1, m0 + punpcklwd m0,m2 + punpckhwd m1,m2 + + mova m2, m0 + punpcklwd m0,m1 + punpckhwd m2,m1 + + mova m1, m0 + punpcklwd m0,m2 + punpckhwd m1,m2 +%endif +%else + mova m1, m0 + shufps m0, m2, 10001000b + shufps m1, m2, 11011101b +%endif +%if %4 < %5 + mov%3 m2, [2*mmsize + srcq +(2<<%5)*lenq] + mova m3, m2 + mov%3 m4, [3*mmsize + srcq +(2<<%5)*lenq] + shufps m2, m4, 10001000b + shufps m3, m4, 11011101b + SWAP 1,2 +%endif + %6 m0,m1,m2,m3,m4,m5 + mov%3 [ dstq+(1<<%4)*lenq], m0 +%if %4 > %5 + mov%3 [ dst2q+(1<<%4)*lenq], m2 + mov%3 [ mmsize + dstq+(1<<%4)*lenq], m1 + mov%3 [ mmsize + dst2q+(1<<%4)*lenq], m3 + add lenq, 2*mmsize/(1<<%4) +%else + mov%3 [ dst2q+(1<<%4)*lenq], m1 + add lenq, mmsize/(1<<%4) +%endif + jl .next + REP_RET +%endmacro + +%macro CONV 5-7 +cglobal %2_to_%1_%3, 3, 3, 6, dst, src, len + mov srcq , [srcq] + mov dstq , [dstq] +%ifidn %3, a + test dstq, mmsize-1 + jne %2_to_%1_u_int %+ SUFFIX + test srcq, mmsize-1 + jne %2_to_%1_u_int %+ SUFFIX +%else +%2_to_%1_u_int %+ SUFFIX: +%endif + lea srcq , [srcq + (1<<%5)*lenq] + lea dstq , [dstq + (1<<%4)*lenq] + neg lenq + %7 m0,m1,m2,m3,m4,m5 +.next: + mov%3 m0, [ srcq +(1<<%5)*lenq] + mov%3 m1, [ mmsize + srcq +(1<<%5)*lenq] +%if %4 < %5 + mov%3 m2, [2*mmsize + srcq +(1<<%5)*lenq] + mov%3 m3, [3*mmsize + srcq +(1<<%5)*lenq] +%endif + %6 m0,m1,m2,m3,m4,m5 + mov%3 [ dstq+(1<<%4)*lenq], m0 + mov%3 [ mmsize + dstq+(1<<%4)*lenq], m1 +%if %4 > %5 + mov%3 [2*mmsize + dstq+(1<<%4)*lenq], m2 + mov%3 [3*mmsize + dstq+(1<<%4)*lenq], m3 + add lenq, 4*mmsize/(1<<%4) +%else + add lenq, 2*mmsize/(1<<%4) +%endif + jl .next +%if mmsize == 8 + emms + RET +%else + REP_RET +%endif +%endmacro + +%macro PACK_6CH 8 +cglobal pack_6ch_%2_to_%1_%3, 2, 8, %6, dst, src, src1, src2, src3, src4, src5, len +%if ARCH_X86_64 + mov lend, r2d +%else + %define lend dword r2m +%endif + mov src1q, [srcq+1*gprsize] + mov src2q, [srcq+2*gprsize] + mov src3q, [srcq+3*gprsize] + mov src4q, [srcq+4*gprsize] + mov src5q, [srcq+5*gprsize] + mov srcq, [srcq] + mov dstq, [dstq] +%ifidn %3, a + test dstq, mmsize-1 + jne pack_6ch_%2_to_%1_u_int %+ SUFFIX + test srcq, mmsize-1 + jne pack_6ch_%2_to_%1_u_int %+ SUFFIX + test src1q, mmsize-1 + jne pack_6ch_%2_to_%1_u_int %+ SUFFIX + test src2q, mmsize-1 + jne pack_6ch_%2_to_%1_u_int %+ SUFFIX + test src3q, mmsize-1 + jne pack_6ch_%2_to_%1_u_int %+ SUFFIX + test src4q, mmsize-1 + jne pack_6ch_%2_to_%1_u_int %+ SUFFIX + test src5q, mmsize-1 + jne pack_6ch_%2_to_%1_u_int %+ SUFFIX +%else +pack_6ch_%2_to_%1_u_int %+ SUFFIX: +%endif + sub src1q, srcq + sub src2q, srcq + sub src3q, srcq + sub src4q, srcq + sub src5q, srcq + %8 x,x,x,x,m7,x +.loop: + mov%3 m0, [srcq ] + mov%3 m1, [srcq+src1q] + mov%3 m2, [srcq+src2q] + mov%3 m3, [srcq+src3q] + mov%3 m4, [srcq+src4q] + mov%3 m5, [srcq+src5q] +%if cpuflag(sse) + SBUTTERFLYPS 0, 1, 6 + SBUTTERFLYPS 2, 3, 6 + SBUTTERFLYPS 4, 5, 6 + +%if cpuflag(avx) + blendps m6, m4, m0, 1100b +%else + movaps m6, m4 + shufps m4, m0, q3210 + SWAP 4,6 +%endif + movlhps m0, m2 + movhlps m4, m2 +%if cpuflag(avx) + blendps m2, m5, m1, 1100b +%else + movaps m2, m5 + shufps m5, m1, q3210 + SWAP 2,5 +%endif + movlhps m1, m3 + movhlps m5, m3 + + %7 m0,m6,x,x,m7,m3 + %7 m4,m1,x,x,m7,m3 + %7 m2,m5,x,x,m7,m3 + + mov %+ %3 %+ ps [dstq ], m0 + mov %+ %3 %+ ps [dstq+16], m6 + mov %+ %3 %+ ps [dstq+32], m4 + mov %+ %3 %+ ps [dstq+48], m1 + mov %+ %3 %+ ps [dstq+64], m2 + mov %+ %3 %+ ps [dstq+80], m5 +%else ; mmx + SBUTTERFLY dq, 0, 1, 6 + SBUTTERFLY dq, 2, 3, 6 + SBUTTERFLY dq, 4, 5, 6 + + movq [dstq ], m0 + movq [dstq+ 8], m2 + movq [dstq+16], m4 + movq [dstq+24], m1 + movq [dstq+32], m3 + movq [dstq+40], m5 +%endif + add srcq, mmsize + add dstq, mmsize*6 + sub lend, mmsize/4 + jg .loop +%if mmsize == 8 + emms + RET +%else + REP_RET +%endif +%endmacro + +%macro UNPACK_6CH 8 +cglobal unpack_6ch_%2_to_%1_%3, 2, 8, %6, dst, src, dst1, dst2, dst3, dst4, dst5, len +%if ARCH_X86_64 + mov lend, r2d +%else + %define lend dword r2m +%endif + mov dst1q, [dstq+1*gprsize] + mov dst2q, [dstq+2*gprsize] + mov dst3q, [dstq+3*gprsize] + mov dst4q, [dstq+4*gprsize] + mov dst5q, [dstq+5*gprsize] + mov dstq, [dstq] + mov srcq, [srcq] +%ifidn %3, a + test dstq, mmsize-1 + jne unpack_6ch_%2_to_%1_u_int %+ SUFFIX + test srcq, mmsize-1 + jne unpack_6ch_%2_to_%1_u_int %+ SUFFIX + test dst1q, mmsize-1 + jne unpack_6ch_%2_to_%1_u_int %+ SUFFIX + test dst2q, mmsize-1 + jne unpack_6ch_%2_to_%1_u_int %+ SUFFIX + test dst3q, mmsize-1 + jne unpack_6ch_%2_to_%1_u_int %+ SUFFIX + test dst4q, mmsize-1 + jne unpack_6ch_%2_to_%1_u_int %+ SUFFIX + test dst5q, mmsize-1 + jne unpack_6ch_%2_to_%1_u_int %+ SUFFIX +%else +unpack_6ch_%2_to_%1_u_int %+ SUFFIX: +%endif + sub dst1q, dstq + sub dst2q, dstq + sub dst3q, dstq + sub dst4q, dstq + sub dst5q, dstq + %8 x,x,x,x,m7,x +.loop: + mov%3 m0, [srcq ] + mov%3 m1, [srcq+16] + mov%3 m2, [srcq+32] + mov%3 m3, [srcq+48] + mov%3 m4, [srcq+64] + mov%3 m5, [srcq+80] + + SBUTTERFLYPS 0, 3, 6 + SBUTTERFLYPS 1, 4, 6 + SBUTTERFLYPS 2, 5, 6 + SBUTTERFLYPS 0, 4, 6 + SBUTTERFLYPS 3, 2, 6 + SBUTTERFLYPS 1, 5, 6 + SWAP 1, 4 + SWAP 2, 3 + + %7 m0,m1,x,x,m7,m6 + %7 m2,m3,x,x,m7,m6 + %7 m4,m5,x,x,m7,m6 + + mov %+ %3 %+ ps [dstq ], m0 + mov %+ %3 %+ ps [dstq+dst1q], m1 + mov %+ %3 %+ ps [dstq+dst2q], m2 + mov %+ %3 %+ ps [dstq+dst3q], m3 + mov %+ %3 %+ ps [dstq+dst4q], m4 + mov %+ %3 %+ ps [dstq+dst5q], m5 + + add srcq, mmsize*6 + add dstq, mmsize + sub lend, mmsize/4 + jg .loop + REP_RET +%endmacro + +%define PACK_8CH_GPRS (10 * ARCH_X86_64) + ((6 + HAVE_ALIGNED_STACK) * ARCH_X86_32) + +%macro PACK_8CH 8 +cglobal pack_8ch_%2_to_%1_%3, 2, PACK_8CH_GPRS, %6, ARCH_X86_32*48, dst, src, len, src1, src2, src3, src4, src5, src6, src7 + mov dstq, [dstq] +%if ARCH_X86_32 + DEFINE_ARGS dst, src, src2, src3, src4, src5, src6 + %define lend dword r2m + %define src1q r0q + %define src1m dword [rsp+32] +%if HAVE_ALIGNED_STACK == 0 + DEFINE_ARGS dst, src, src2, src3, src5, src6 + %define src4q r0q + %define src4m dword [rsp+36] +%endif + %define src7q r0q + %define src7m dword [rsp+40] + mov dstm, dstq +%endif + mov src7q, [srcq+7*gprsize] + mov src6q, [srcq+6*gprsize] +%if ARCH_X86_32 + mov src7m, src7q +%endif + mov src5q, [srcq+5*gprsize] + mov src4q, [srcq+4*gprsize] + mov src3q, [srcq+3*gprsize] +%if ARCH_X86_32 && HAVE_ALIGNED_STACK == 0 + mov src4m, src4q +%endif + mov src2q, [srcq+2*gprsize] + mov src1q, [srcq+1*gprsize] + mov srcq, [srcq] +%ifidn %3, a +%if ARCH_X86_32 + test dstmp, mmsize-1 +%else + test dstq, mmsize-1 +%endif + jne pack_8ch_%2_to_%1_u_int %+ SUFFIX + test srcq, mmsize-1 + jne pack_8ch_%2_to_%1_u_int %+ SUFFIX + test src1q, mmsize-1 + jne pack_8ch_%2_to_%1_u_int %+ SUFFIX + test src2q, mmsize-1 + jne pack_8ch_%2_to_%1_u_int %+ SUFFIX + test src3q, mmsize-1 + jne pack_8ch_%2_to_%1_u_int %+ SUFFIX +%if ARCH_X86_32 && HAVE_ALIGNED_STACK == 0 + test src4m, mmsize-1 +%else + test src4q, mmsize-1 +%endif + jne pack_8ch_%2_to_%1_u_int %+ SUFFIX + test src5q, mmsize-1 + jne pack_8ch_%2_to_%1_u_int %+ SUFFIX + test src6q, mmsize-1 + jne pack_8ch_%2_to_%1_u_int %+ SUFFIX +%if ARCH_X86_32 + test src7m, mmsize-1 +%else + test src7q, mmsize-1 +%endif + jne pack_8ch_%2_to_%1_u_int %+ SUFFIX +%else +pack_8ch_%2_to_%1_u_int %+ SUFFIX: +%endif + sub src1q, srcq + sub src2q, srcq + sub src3q, srcq +%if ARCH_X86_64 || HAVE_ALIGNED_STACK + sub src4q, srcq +%else + sub src4m, srcq +%endif + sub src5q, srcq + sub src6q, srcq +%if ARCH_X86_64 + sub src7q, srcq +%else + mov src1m, src1q + sub src7m, srcq +%endif + +%if ARCH_X86_64 + %8 x,x,x,x,m9,x +%elifidn %1, int32 + %define m9 [flt2p31] +%else + %define m9 [flt2pm31] +%endif + +.loop: + mov%3 m0, [srcq ] + mov%3 m1, [srcq+src1q] + mov%3 m2, [srcq+src2q] +%if ARCH_X86_32 && HAVE_ALIGNED_STACK == 0 + mov src4q, src4m +%endif + mov%3 m3, [srcq+src3q] + mov%3 m4, [srcq+src4q] + mov%3 m5, [srcq+src5q] +%if ARCH_X86_32 + mov src7q, src7m +%endif + mov%3 m6, [srcq+src6q] + mov%3 m7, [srcq+src7q] + +%if ARCH_X86_64 + TRANSPOSE8x4D 0, 1, 2, 3, 4, 5, 6, 7, 8 + + %7 m0,m1,x,x,m9,m8 + %7 m2,m3,x,x,m9,m8 + %7 m4,m5,x,x,m9,m8 + %7 m6,m7,x,x,m9,m8 + + mov%3 [dstq], m0 +%else + mov dstq, dstm + + TRANSPOSE8x4D 0, 1, 2, 3, 4, 5, 6, 7, [rsp], [rsp+16], 1 + + %7 m0,m1,x,x,m9,m2 + mova m2, [rsp] + mov%3 [dstq], m0 + %7 m2,m3,x,x,m9,m0 + %7 m4,m5,x,x,m9,m0 + %7 m6,m7,x,x,m9,m0 + +%endif + + mov%3 [dstq+16], m1 + mov%3 [dstq+32], m2 + mov%3 [dstq+48], m3 + mov%3 [dstq+64], m4 + mov%3 [dstq+80], m5 + mov%3 [dstq+96], m6 + mov%3 [dstq+112], m7 + + add srcq, mmsize + add dstq, mmsize*8 +%if ARCH_X86_32 + mov dstm, dstq + mov src1q, src1m +%endif + sub lend, mmsize/4 + jg .loop + REP_RET +%endmacro + +%macro INT16_TO_INT32_N 6 + pxor m2, m2 + pxor m3, m3 + punpcklwd m2, m1 + punpckhwd m3, m1 + SWAP 4,0 + pxor m0, m0 + pxor m1, m1 + punpcklwd m0, m4 + punpckhwd m1, m4 +%endmacro + +%macro INT32_TO_INT16_N 6 + psrad m0, 16 + psrad m1, 16 + psrad m2, 16 + psrad m3, 16 + packssdw m0, m1 + packssdw m2, m3 + SWAP 1,2 +%endmacro + +%macro INT32_TO_FLOAT_INIT 6 + mova %5, [flt2pm31] +%endmacro +%macro INT32_TO_FLOAT_N 6 + cvtdq2ps %1, %1 + cvtdq2ps %2, %2 + mulps %1, %1, %5 + mulps %2, %2, %5 +%endmacro + +%macro FLOAT_TO_INT32_INIT 6 + mova %5, [flt2p31] +%endmacro +%macro FLOAT_TO_INT32_N 6 + mulps %1, %5 + mulps %2, %5 + cvtps2dq %6, %1 + cmpps %1, %1, %5, 5 + paddd %1, %6 + cvtps2dq %6, %2 + cmpps %2, %2, %5, 5 + paddd %2, %6 +%endmacro + +%macro INT16_TO_FLOAT_INIT 6 + mova m5, [flt2pm31] +%endmacro +%macro INT16_TO_FLOAT_N 6 + INT16_TO_INT32_N %1,%2,%3,%4,%5,%6 + cvtdq2ps m0, m0 + cvtdq2ps m1, m1 + cvtdq2ps m2, m2 + cvtdq2ps m3, m3 + mulps m0, m0, m5 + mulps m1, m1, m5 + mulps m2, m2, m5 + mulps m3, m3, m5 +%endmacro + +%macro FLOAT_TO_INT16_INIT 6 + mova m5, [flt2p15] +%endmacro +%macro FLOAT_TO_INT16_N 6 + mulps m0, m5 + mulps m1, m5 + mulps m2, m5 + mulps m3, m5 + cvtps2dq m0, m0 + cvtps2dq m1, m1 + packssdw m0, m1 + cvtps2dq m1, m2 + cvtps2dq m3, m3 + packssdw m1, m3 +%endmacro + +%macro NOP_N 0-6 +%endmacro + +INIT_MMX mmx +CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N +CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N +CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N +CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N + +PACK_6CH float, float, u, 2, 2, 0, NOP_N, NOP_N +PACK_6CH float, float, a, 2, 2, 0, NOP_N, NOP_N + +INIT_XMM sse +PACK_6CH float, float, u, 2, 2, 7, NOP_N, NOP_N +PACK_6CH float, float, a, 2, 2, 7, NOP_N, NOP_N + +UNPACK_6CH float, float, u, 2, 2, 7, NOP_N, NOP_N +UNPACK_6CH float, float, a, 2, 2, 7, NOP_N, NOP_N + +INIT_XMM sse2 +CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N +CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N +CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N +CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N + +PACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N +PACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N +PACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N +PACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N +PACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N +PACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N +PACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N +PACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N + +UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N +UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N +UNPACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N +UNPACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N +UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N +UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N +UNPACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N +UNPACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N + +CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +CONV int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +CONV int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +CONV float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT +CONV float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT +CONV int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT +CONV int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT + +PACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +PACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +PACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT +PACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT +PACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT +PACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT + +UNPACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +UNPACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +UNPACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +UNPACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT +UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT +UNPACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT +UNPACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT + +PACK_6CH float, int32, u, 2, 2, 8, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_6CH float, int32, a, 2, 2, 8, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_6CH int32, float, u, 2, 2, 8, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +PACK_6CH int32, float, a, 2, 2, 8, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT + +UNPACK_6CH float, int32, u, 2, 2, 8, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +UNPACK_6CH float, int32, a, 2, 2, 8, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +UNPACK_6CH int32, float, u, 2, 2, 8, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +UNPACK_6CH int32, float, a, 2, 2, 8, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT + +PACK_8CH float, float, u, 2, 2, 9, NOP_N, NOP_N +PACK_8CH float, float, a, 2, 2, 9, NOP_N, NOP_N + +PACK_8CH float, int32, u, 2, 2, 10, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_8CH float, int32, a, 2, 2, 10, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_8CH int32, float, u, 2, 2, 10, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +PACK_8CH int32, float, a, 2, 2, 10, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT + +INIT_XMM ssse3 +UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N +UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N +UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N +UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N +UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT +UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT + +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PACK_6CH float, float, u, 2, 2, 8, NOP_N, NOP_N +PACK_6CH float, float, a, 2, 2, 8, NOP_N, NOP_N + +UNPACK_6CH float, float, u, 2, 2, 8, NOP_N, NOP_N +UNPACK_6CH float, float, a, 2, 2, 8, NOP_N, NOP_N + +PACK_6CH float, int32, u, 2, 2, 8, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_6CH float, int32, a, 2, 2, 8, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_6CH int32, float, u, 2, 2, 8, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +PACK_6CH int32, float, a, 2, 2, 8, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT + +UNPACK_6CH float, int32, u, 2, 2, 8, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +UNPACK_6CH float, int32, a, 2, 2, 8, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +UNPACK_6CH int32, float, u, 2, 2, 8, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +UNPACK_6CH int32, float, a, 2, 2, 8, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT + +PACK_8CH float, float, u, 2, 2, 9, NOP_N, NOP_N +PACK_8CH float, float, a, 2, 2, 9, NOP_N, NOP_N + +PACK_8CH float, int32, u, 2, 2, 10, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_8CH float, int32, a, 2, 2, 10, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +PACK_8CH int32, float, u, 2, 2, 10, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +PACK_8CH int32, float, a, 2, 2, 10, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT + +INIT_YMM avx +CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT +%endif + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +CONV int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +CONV int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT +%endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/rematrix.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/rematrix.asm new file mode 100644 index 000000000..7984b9a72 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/rematrix.asm @@ -0,0 +1,250 @@ +;****************************************************************************** +;* Copyright (c) 2012 Michael Niedermayer +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + + +SECTION_RODATA 32 +dw1: times 8 dd 1 +w1 : times 16 dw 1 + +SECTION .text + +%macro MIX2_FLT 1 +cglobal mix_2_1_%1_float, 7, 7, 6, out, in1, in2, coeffp, index1, index2, len +%ifidn %1, a + test in1q, mmsize-1 + jne mix_2_1_float_u_int %+ SUFFIX + test in2q, mmsize-1 + jne mix_2_1_float_u_int %+ SUFFIX + test outq, mmsize-1 + jne mix_2_1_float_u_int %+ SUFFIX +%else +mix_2_1_float_u_int %+ SUFFIX: +%endif + VBROADCASTSS m4, [coeffpq + 4*index1q] + VBROADCASTSS m5, [coeffpq + 4*index2q] + shl lend , 2 + add in1q , lenq + add in2q , lenq + add outq , lenq + neg lenq +.next: +%ifidn %1, a + mulps m0, m4, [in1q + lenq ] + mulps m1, m5, [in2q + lenq ] + mulps m2, m4, [in1q + lenq + mmsize] + mulps m3, m5, [in2q + lenq + mmsize] +%else + movu m0, [in1q + lenq ] + movu m1, [in2q + lenq ] + movu m2, [in1q + lenq + mmsize] + movu m3, [in2q + lenq + mmsize] + mulps m0, m0, m4 + mulps m1, m1, m5 + mulps m2, m2, m4 + mulps m3, m3, m5 +%endif + addps m0, m0, m1 + addps m2, m2, m3 + mov%1 [outq + lenq ], m0 + mov%1 [outq + lenq + mmsize], m2 + add lenq, mmsize*2 + jl .next + REP_RET +%endmacro + +%macro MIX1_FLT 1 +cglobal mix_1_1_%1_float, 5, 5, 3, out, in, coeffp, index, len +%ifidn %1, a + test inq, mmsize-1 + jne mix_1_1_float_u_int %+ SUFFIX + test outq, mmsize-1 + jne mix_1_1_float_u_int %+ SUFFIX +%else +mix_1_1_float_u_int %+ SUFFIX: +%endif + VBROADCASTSS m2, [coeffpq + 4*indexq] + shl lenq , 2 + add inq , lenq + add outq , lenq + neg lenq +.next: +%ifidn %1, a + mulps m0, m2, [inq + lenq ] + mulps m1, m2, [inq + lenq + mmsize] +%else + movu m0, [inq + lenq ] + movu m1, [inq + lenq + mmsize] + mulps m0, m0, m2 + mulps m1, m1, m2 +%endif + mov%1 [outq + lenq ], m0 + mov%1 [outq + lenq + mmsize], m1 + add lenq, mmsize*2 + jl .next + REP_RET +%endmacro + +%macro MIX1_INT16 1 +cglobal mix_1_1_%1_int16, 5, 5, 6, out, in, coeffp, index, len +%ifidn %1, a + test inq, mmsize-1 + jne mix_1_1_int16_u_int %+ SUFFIX + test outq, mmsize-1 + jne mix_1_1_int16_u_int %+ SUFFIX +%else +mix_1_1_int16_u_int %+ SUFFIX: +%endif + movd m4, [coeffpq + 4*indexq] + SPLATW m5, m4 + psllq m4, 32 + psrlq m4, 48 + mova m0, [w1] + psllw m0, m4 + psrlw m0, 1 + punpcklwd m5, m0 + add lenq , lenq + add inq , lenq + add outq , lenq + neg lenq +.next: + mov%1 m0, [inq + lenq ] + mov%1 m2, [inq + lenq + mmsize] + mova m1, m0 + mova m3, m2 + punpcklwd m0, [w1] + punpckhwd m1, [w1] + punpcklwd m2, [w1] + punpckhwd m3, [w1] + pmaddwd m0, m5 + pmaddwd m1, m5 + pmaddwd m2, m5 + pmaddwd m3, m5 + psrad m0, m4 + psrad m1, m4 + psrad m2, m4 + psrad m3, m4 + packssdw m0, m1 + packssdw m2, m3 + mov%1 [outq + lenq ], m0 + mov%1 [outq + lenq + mmsize], m2 + add lenq, mmsize*2 + jl .next +%if mmsize == 8 + emms + RET +%else + REP_RET +%endif +%endmacro + +%macro MIX2_INT16 1 +cglobal mix_2_1_%1_int16, 7, 7, 8, out, in1, in2, coeffp, index1, index2, len +%ifidn %1, a + test in1q, mmsize-1 + jne mix_2_1_int16_u_int %+ SUFFIX + test in2q, mmsize-1 + jne mix_2_1_int16_u_int %+ SUFFIX + test outq, mmsize-1 + jne mix_2_1_int16_u_int %+ SUFFIX +%else +mix_2_1_int16_u_int %+ SUFFIX: +%endif + movd m4, [coeffpq + 4*index1q] + movd m6, [coeffpq + 4*index2q] + SPLATW m5, m4 + SPLATW m6, m6 + psllq m4, 32 + psrlq m4, 48 + mova m7, [dw1] + pslld m7, m4 + psrld m7, 1 + punpcklwd m5, m6 + add lend , lend + add in1q , lenq + add in2q , lenq + add outq , lenq + neg lenq +.next: + mov%1 m0, [in1q + lenq ] + mov%1 m2, [in2q + lenq ] + mova m1, m0 + punpcklwd m0, m2 + punpckhwd m1, m2 + + mov%1 m2, [in1q + lenq + mmsize] + mov%1 m6, [in2q + lenq + mmsize] + mova m3, m2 + punpcklwd m2, m6 + punpckhwd m3, m6 + + pmaddwd m0, m5 + pmaddwd m1, m5 + pmaddwd m2, m5 + pmaddwd m3, m5 + paddd m0, m7 + paddd m1, m7 + paddd m2, m7 + paddd m3, m7 + psrad m0, m4 + psrad m1, m4 + psrad m2, m4 + psrad m3, m4 + packssdw m0, m1 + packssdw m2, m3 + mov%1 [outq + lenq ], m0 + mov%1 [outq + lenq + mmsize], m2 + add lenq, mmsize*2 + jl .next +%if mmsize == 8 + emms + RET +%else + REP_RET +%endif +%endmacro + + +INIT_MMX mmx +MIX1_INT16 u +MIX1_INT16 a +MIX2_INT16 u +MIX2_INT16 a + +INIT_XMM sse +MIX2_FLT u +MIX2_FLT a +MIX1_FLT u +MIX1_FLT a + +INIT_XMM sse2 +MIX1_INT16 u +MIX1_INT16 a +MIX2_INT16 u +MIX2_INT16 a + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +MIX2_FLT u +MIX2_FLT a +MIX1_FLT u +MIX1_FLT a +%endif diff --git a/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/resample.asm b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/resample.asm new file mode 100644 index 000000000..7107cf9d4 --- /dev/null +++ b/trunk/3rdparty/ffmpeg-4.2-fit/libswresample/x86/resample.asm @@ -0,0 +1,619 @@ +;****************************************************************************** +;* Copyright (c) 2012 Michael Niedermayer +;* Copyright (c) 2014 James Almer gmail.com> +;* Copyright (c) 2014 Ronald S. Bultje +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg is free software; you can redistribute it and/or +;* modify it under the terms of the GNU Lesser General Public +;* License as published by the Free Software Foundation; either +;* version 2.1 of the License, or (at your option) any later version. +;* +;* FFmpeg 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 +;* Lesser General Public License for more details. +;* +;* You should have received a copy of the GNU Lesser General Public +;* License along with FFmpeg; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +%if ARCH_X86_64 +%define pointer resq +%else +%define pointer resd +%endif + +struc ResampleContext + .av_class: pointer 1 + .filter_bank: pointer 1 + .filter_length: resd 1 + .filter_alloc: resd 1 + .ideal_dst_incr: resd 1 + .dst_incr: resd 1 + .dst_incr_div: resd 1 + .dst_incr_mod: resd 1 + .index: resd 1 + .frac: resd 1 + .src_incr: resd 1 + .compensation_distance: resd 1 + .phase_count: resd 1 + + ; there's a few more here but we only care about the first few +endstruc + +SECTION_RODATA + +pf_1: dd 1.0 +pdbl_1: dq 1.0 +pd_0x4000: dd 0x4000 + +SECTION .text + +; FIXME remove unneeded variables (index_incr, phase_mask) +%macro RESAMPLE_FNS 3-5 ; format [float or int16], bps, log2_bps, float op suffix [s or d], 1.0 constant +; int resample_common_$format(ResampleContext *ctx, $format *dst, +; const $format *src, int size, int update_ctx) +%if ARCH_X86_64 ; unix64 and win64 +cglobal resample_common_%1, 0, 15, 2, ctx, dst, src, phase_count, index, frac, \ + dst_incr_mod, size, min_filter_count_x4, \ + min_filter_len_x4, dst_incr_div, src_incr, \ + phase_mask, dst_end, filter_bank + + ; use red-zone for variable storage +%define ctx_stackq [rsp-0x8] +%define src_stackq [rsp-0x10] +%if WIN64 +%define update_context_stackd r4m +%else ; unix64 +%define update_context_stackd [rsp-0x14] +%endif + + ; load as many variables in registers as possible; for the rest, store + ; on stack so that we have 'ctx' available as one extra register + mov sized, r3d +%if UNIX64 + mov update_context_stackd, r4d +%endif + mov indexd, [ctxq+ResampleContext.index] + mov fracd, [ctxq+ResampleContext.frac] + mov dst_incr_modd, [ctxq+ResampleContext.dst_incr_mod] + mov filter_bankq, [ctxq+ResampleContext.filter_bank] + mov src_incrd, [ctxq+ResampleContext.src_incr] + mov ctx_stackq, ctxq + mov min_filter_len_x4d, [ctxq+ResampleContext.filter_length] + mov dst_incr_divd, [ctxq+ResampleContext.dst_incr_div] + shl min_filter_len_x4d, %3 + lea dst_endq, [dstq+sizeq*%2] + +%if UNIX64 + mov ecx, [ctxq+ResampleContext.phase_count] + mov edi, [ctxq+ResampleContext.filter_alloc] + + DEFINE_ARGS filter_alloc, dst, src, phase_count, index, frac, dst_incr_mod, \ + filter, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \ + src_incr, phase_mask, dst_end, filter_bank +%elif WIN64 + mov R9d, [ctxq+ResampleContext.filter_alloc] + mov ecx, [ctxq+ResampleContext.phase_count] + + DEFINE_ARGS phase_count, dst, src, filter_alloc, index, frac, dst_incr_mod, \ + filter, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \ + src_incr, phase_mask, dst_end, filter_bank +%endif + + neg min_filter_len_x4q + sub filter_bankq, min_filter_len_x4q + sub srcq, min_filter_len_x4q + mov src_stackq, srcq +%else ; x86-32 +cglobal resample_common_%1, 1, 7, 2, ctx, phase_count, dst, frac, \ + index, min_filter_length_x4, filter_bank + + ; push temp variables to stack +%define ctx_stackq r0mp +%define src_stackq r2mp +%define update_context_stackd r4m + + mov dstq, r1mp + mov r3, r3mp + lea r3, [dstq+r3*%2] + PUSH dword [ctxq+ResampleContext.dst_incr_div] + PUSH dword [ctxq+ResampleContext.dst_incr_mod] + PUSH dword [ctxq+ResampleContext.filter_alloc] + PUSH r3 + PUSH dword [ctxq+ResampleContext.phase_count] ; unneeded replacement for phase_mask + PUSH dword [ctxq+ResampleContext.src_incr] + mov min_filter_length_x4d, [ctxq+ResampleContext.filter_length] + mov indexd, [ctxq+ResampleContext.index] + shl min_filter_length_x4d, %3 + mov fracd, [ctxq+ResampleContext.frac] + neg min_filter_length_x4q + mov filter_bankq, [ctxq+ResampleContext.filter_bank] + sub r2mp, min_filter_length_x4q + sub filter_bankq, min_filter_length_x4q + PUSH min_filter_length_x4q + PUSH filter_bankq + mov phase_countd, [ctxq+ResampleContext.phase_count] + + DEFINE_ARGS src, phase_count, dst, frac, index, min_filter_count_x4, filter + +%define filter_bankq dword [rsp+0x0] +%define min_filter_length_x4q dword [rsp+0x4] +%define src_incrd dword [rsp+0x8] +%define phase_maskd dword [rsp+0xc] +%define dst_endq dword [rsp+0x10] +%define filter_allocd dword [rsp+0x14] +%define dst_incr_modd dword [rsp+0x18] +%define dst_incr_divd dword [rsp+0x1c] + + mov srcq, r2mp +%endif + +.loop: + mov filterd, filter_allocd + imul filterd, indexd +%if ARCH_X86_64 + mov min_filter_count_x4q, min_filter_len_x4q + lea filterq, [filter_bankq+filterq*%2] +%else ; x86-32 + mov min_filter_count_x4q, filter_bankq + lea filterq, [min_filter_count_x4q+filterq*%2] + mov min_filter_count_x4q, min_filter_length_x4q +%endif +%ifidn %1, int16 + movd m0, [pd_0x4000] +%else ; float/double + xorps m0, m0, m0 +%endif + + align 16 +.inner_loop: + movu m1, [srcq+min_filter_count_x4q*1] +%ifidn %1, int16 +%if cpuflag(xop) + vpmadcswd m0, m1, [filterq+min_filter_count_x4q*1], m0 +%else + pmaddwd m1, [filterq+min_filter_count_x4q*1] + paddd m0, m1 +%endif +%else ; float/double +%if cpuflag(fma4) || cpuflag(fma3) + fmaddp%4 m0, m1, [filterq+min_filter_count_x4q*1], m0 +%else + mulp%4 m1, m1, [filterq+min_filter_count_x4q*1] + addp%4 m0, m0, m1 +%endif ; cpuflag +%endif + add min_filter_count_x4q, mmsize + js .inner_loop + +%ifidn %1, int16 + HADDD m0, m1 + psrad m0, 15 + add fracd, dst_incr_modd + packssdw m0, m0 + add indexd, dst_incr_divd + movd [dstq], m0 +%else ; float/double + ; horizontal sum & store +%if mmsize == 32 + vextractf128 xm1, m0, 0x1 + addp%4 xm0, xm1 +%endif + movhlps xm1, xm0 +%ifidn %1, float + addps xm0, xm1 + shufps xm1, xm0, xm0, q0001 +%endif + add fracd, dst_incr_modd + addp%4 xm0, xm1 + add indexd, dst_incr_divd + movs%4 [dstq], xm0 +%endif + cmp fracd, src_incrd + jl .skip + sub fracd, src_incrd + inc indexd + +%if UNIX64 + DEFINE_ARGS filter_alloc, dst, src, phase_count, index, frac, dst_incr_mod, \ + index_incr, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \ + src_incr, phase_mask, dst_end, filter_bank +%elif WIN64 + DEFINE_ARGS phase_count, dst, src, filter_alloc, index, frac, dst_incr_mod, \ + index_incr, min_filter_count_x4, min_filter_len_x4, dst_incr_div, \ + src_incr, phase_mask, dst_end, filter_bank +%else ; x86-32 + DEFINE_ARGS src, phase_count, dst, frac, index, index_incr +%endif + +.skip: + add dstq, %2 + cmp indexd, phase_countd + jb .index_skip +.index_while: + sub indexd, phase_countd + lea srcq, [srcq+%2] + cmp indexd, phase_countd + jnb .index_while +.index_skip: + cmp dstq, dst_endq + jne .loop + +%if ARCH_X86_64 + DEFINE_ARGS ctx, dst, src, phase_count, index, frac +%else ; x86-32 + DEFINE_ARGS src, ctx, update_context, frac, index +%endif + + cmp dword update_context_stackd, 0 + jz .skip_store + ; strictly speaking, the function should always return the consumed + ; number of bytes; however, we only use the value if update_context + ; is true, so let's just leave it uninitialized otherwise + mov ctxq, ctx_stackq + movifnidn rax, srcq + mov [ctxq+ResampleContext.frac ], fracd + sub rax, src_stackq + mov [ctxq+ResampleContext.index], indexd + shr rax, %3 + +.skip_store: +%if ARCH_X86_32 + ADD rsp, 0x20 +%endif + RET + +; int resample_linear_$format(ResampleContext *ctx, float *dst, +; const float *src, int size, int update_ctx) +%if ARCH_X86_64 ; unix64 and win64 +%if UNIX64 +cglobal resample_linear_%1, 0, 15, 5, ctx, dst, phase_mask, phase_count, index, frac, \ + size, dst_incr_mod, min_filter_count_x4, \ + min_filter_len_x4, dst_incr_div, src_incr, \ + src, dst_end, filter_bank + + mov srcq, r2mp +%else ; win64 +cglobal resample_linear_%1, 0, 15, 5, ctx, phase_mask, src, phase_count, index, frac, \ + size, dst_incr_mod, min_filter_count_x4, \ + min_filter_len_x4, dst_incr_div, src_incr, \ + dst, dst_end, filter_bank + + mov dstq, r1mp +%endif + + ; use red-zone for variable storage +%define ctx_stackq [rsp-0x8] +%define src_stackq [rsp-0x10] +%define phase_mask_stackd [rsp-0x14] +%if WIN64 +%define update_context_stackd r4m +%else ; unix64 +%define update_context_stackd [rsp-0x18] +%endif + + ; load as many variables in registers as possible; for the rest, store + ; on stack so that we have 'ctx' available as one extra register + mov sized, r3d +%if UNIX64 + mov update_context_stackd, r4d +%endif + mov indexd, [ctxq+ResampleContext.index] + mov fracd, [ctxq+ResampleContext.frac] + mov dst_incr_modd, [ctxq+ResampleContext.dst_incr_mod] + mov filter_bankq, [ctxq+ResampleContext.filter_bank] + mov src_incrd, [ctxq+ResampleContext.src_incr] + mov ctx_stackq, ctxq + mov min_filter_len_x4d, [ctxq+ResampleContext.filter_length] +%ifidn %1, int16 + movd m4, [pd_0x4000] +%else ; float/double + cvtsi2s%4 xm0, src_incrd + movs%4 xm4, [%5] + divs%4 xm4, xm0 +%endif + mov dst_incr_divd, [ctxq+ResampleContext.dst_incr_div] + shl min_filter_len_x4d, %3 + lea dst_endq, [dstq+sizeq*%2] + +%if UNIX64 + mov ecx, [ctxq+ResampleContext.phase_count] + mov edi, [ctxq+ResampleContext.filter_alloc] + + DEFINE_ARGS filter_alloc, dst, filter2, phase_count, index, frac, filter1, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, src, dst_end, filter_bank +%elif WIN64 + mov R9d, [ctxq+ResampleContext.filter_alloc] + mov ecx, [ctxq+ResampleContext.phase_count] + + DEFINE_ARGS phase_count, filter2, src, filter_alloc, index, frac, filter1, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, dst, dst_end, filter_bank +%endif + + neg min_filter_len_x4q + sub filter_bankq, min_filter_len_x4q + sub srcq, min_filter_len_x4q + mov src_stackq, srcq +%else ; x86-32 +cglobal resample_linear_%1, 1, 7, 5, ctx, min_filter_length_x4, filter2, \ + frac, index, dst, filter_bank + + ; push temp variables to stack +%define ctx_stackq r0mp +%define src_stackq r2mp +%define update_context_stackd r4m + + mov dstq, r1mp + mov r3, r3mp + lea r3, [dstq+r3*%2] + PUSH dword [ctxq+ResampleContext.dst_incr_div] + PUSH r3 + mov r3, dword [ctxq+ResampleContext.filter_alloc] + PUSH dword [ctxq+ResampleContext.dst_incr_mod] + PUSH r3 + shl r3, %3 + PUSH r3 + mov r3, dword [ctxq+ResampleContext.src_incr] + PUSH dword [ctxq+ResampleContext.phase_count] ; unneeded replacement of phase_mask + PUSH r3d +%ifidn %1, int16 + movd m4, [pd_0x4000] +%else ; float/double + cvtsi2s%4 xm0, r3d + movs%4 xm4, [%5] + divs%4 xm4, xm0 +%endif + mov min_filter_length_x4d, [ctxq+ResampleContext.filter_length] + mov indexd, [ctxq+ResampleContext.index] + shl min_filter_length_x4d, %3 + mov fracd, [ctxq+ResampleContext.frac] + neg min_filter_length_x4q + mov filter_bankq, [ctxq+ResampleContext.filter_bank] + sub r2mp, min_filter_length_x4q + sub filter_bankq, min_filter_length_x4q + PUSH min_filter_length_x4q + PUSH filter_bankq + PUSH dword [ctxq+ResampleContext.phase_count] + + DEFINE_ARGS filter1, min_filter_count_x4, filter2, frac, index, dst, src + +%define phase_count_stackd dword [rsp+0x0] +%define filter_bankq dword [rsp+0x4] +%define min_filter_length_x4q dword [rsp+0x8] +%define src_incrd dword [rsp+0xc] +%define phase_mask_stackd dword [rsp+0x10] +%define filter_alloc_x4q dword [rsp+0x14] +%define filter_allocd dword [rsp+0x18] +%define dst_incr_modd dword [rsp+0x1c] +%define dst_endq dword [rsp+0x20] +%define dst_incr_divd dword [rsp+0x24] + + mov srcq, r2mp +%endif + +.loop: + mov filter1d, filter_allocd + imul filter1d, indexd +%if ARCH_X86_64 + mov min_filter_count_x4q, min_filter_len_x4q + lea filter1q, [filter_bankq+filter1q*%2] + lea filter2q, [filter1q+filter_allocq*%2] +%else ; x86-32 + mov min_filter_count_x4q, filter_bankq + lea filter1q, [min_filter_count_x4q+filter1q*%2] + mov min_filter_count_x4q, min_filter_length_x4q + mov filter2q, filter1q + add filter2q, filter_alloc_x4q +%endif +%ifidn %1, int16 + mova m0, m4 + mova m2, m4 +%else ; float/double + xorps m0, m0, m0 + xorps m2, m2, m2 +%endif + + align 16 +.inner_loop: + movu m1, [srcq+min_filter_count_x4q*1] +%ifidn %1, int16 +%if cpuflag(xop) + vpmadcswd m2, m1, [filter2q+min_filter_count_x4q*1], m2 + vpmadcswd m0, m1, [filter1q+min_filter_count_x4q*1], m0 +%else + pmaddwd m3, m1, [filter2q+min_filter_count_x4q*1] + pmaddwd m1, [filter1q+min_filter_count_x4q*1] + paddd m2, m3 + paddd m0, m1 +%endif ; cpuflag +%else ; float/double +%if cpuflag(fma4) || cpuflag(fma3) + fmaddp%4 m2, m1, [filter2q+min_filter_count_x4q*1], m2 + fmaddp%4 m0, m1, [filter1q+min_filter_count_x4q*1], m0 +%else + mulp%4 m3, m1, [filter2q+min_filter_count_x4q*1] + mulp%4 m1, m1, [filter1q+min_filter_count_x4q*1] + addp%4 m2, m2, m3 + addp%4 m0, m0, m1 +%endif ; cpuflag +%endif + add min_filter_count_x4q, mmsize + js .inner_loop + +%ifidn %1, int16 +%if mmsize == 16 +%if cpuflag(xop) + vphadddq m2, m2 + vphadddq m0, m0 +%endif + pshufd m3, m2, q0032 + pshufd m1, m0, q0032 + paddd m2, m3 + paddd m0, m1 +%endif +%if notcpuflag(xop) + PSHUFLW m3, m2, q0032 + PSHUFLW m1, m0, q0032 + paddd m2, m3 + paddd m0, m1 +%endif + psubd m2, m0 + ; This is probably a really bad idea on atom and other machines with a + ; long transfer latency between GPRs and XMMs (atom). However, it does + ; make the clip a lot simpler... + movd eax, m2 + add indexd, dst_incr_divd + imul fracd + idiv src_incrd + movd m1, eax + add fracd, dst_incr_modd + paddd m0, m1 + psrad m0, 15 + packssdw m0, m0 + movd [dstq], m0 + + ; note that for imul/idiv, I need to move filter to edx/eax for each: + ; - 32bit: eax=r0[filter1], edx=r2[filter2] + ; - win64: eax=r6[filter1], edx=r1[todo] + ; - unix64: eax=r6[filter1], edx=r2[todo] +%else ; float/double + ; val += (v2 - val) * (FELEML) frac / c->src_incr; +%if mmsize == 32 + vextractf128 xm1, m0, 0x1 + vextractf128 xm3, m2, 0x1 + addp%4 xm0, xm1 + addp%4 xm2, xm3 +%endif + cvtsi2s%4 xm1, fracd + subp%4 xm2, xm0 + mulp%4 xm1, xm4 + shufp%4 xm1, xm1, q0000 +%if cpuflag(fma4) || cpuflag(fma3) + fmaddp%4 xm0, xm2, xm1, xm0 +%else + mulp%4 xm2, xm1 + addp%4 xm0, xm2 +%endif ; cpuflag + + ; horizontal sum & store + movhlps xm1, xm0 +%ifidn %1, float + addps xm0, xm1 + shufps xm1, xm0, xm0, q0001 +%endif + add fracd, dst_incr_modd + addp%4 xm0, xm1 + add indexd, dst_incr_divd + movs%4 [dstq], xm0 +%endif + cmp fracd, src_incrd + jl .skip + sub fracd, src_incrd + inc indexd + +%if UNIX64 + DEFINE_ARGS filter_alloc, dst, filter2, phase_count, index, frac, index_incr, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, src, dst_end, filter_bank +%elif WIN64 + DEFINE_ARGS phase_count, filter2, src, filter_alloc, index, frac, index_incr, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, dst, dst_end, filter_bank +%else ; x86-32 + DEFINE_ARGS filter1, phase_count, index_incr, frac, index, dst, src +%endif + +.skip: +%if ARCH_X86_32 + mov phase_countd, phase_count_stackd +%endif + add dstq, %2 + cmp indexd, phase_countd + jb .index_skip +.index_while: + sub indexd, phase_countd + lea srcq, [srcq+%2] + cmp indexd, phase_countd + jnb .index_while +.index_skip: + cmp dstq, dst_endq + jne .loop + +%if UNIX64 + DEFINE_ARGS ctx, dst, filter2, phase_count, index, frac, index_incr, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, src, dst_end, filter_bank +%elif WIN64 + DEFINE_ARGS ctx, filter2, src, phase_count, index, frac, index_incr, \ + dst_incr_mod, min_filter_count_x4, min_filter_len_x4, \ + dst_incr_div, src_incr, dst, dst_end, filter_bank +%else ; x86-32 + DEFINE_ARGS filter1, ctx, update_context, frac, index, dst, src +%endif + + cmp dword update_context_stackd, 0 + jz .skip_store + ; strictly speaking, the function should always return the consumed + ; number of bytes; however, we only use the value if update_context + ; is true, so let's just leave it uninitialized otherwise + mov ctxq, ctx_stackq + movifnidn rax, srcq + mov [ctxq+ResampleContext.frac ], fracd + sub rax, src_stackq + mov [ctxq+ResampleContext.index], indexd + shr rax, %3 + +.skip_store: +%if ARCH_X86_32 + ADD rsp, 0x28 +%endif + RET +%endmacro + +INIT_XMM sse +RESAMPLE_FNS float, 4, 2, s, pf_1 + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +RESAMPLE_FNS float, 4, 2, s, pf_1 +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +RESAMPLE_FNS float, 4, 2, s, pf_1 +%endif +%if HAVE_FMA4_EXTERNAL +INIT_XMM fma4 +RESAMPLE_FNS float, 4, 2, s, pf_1 +%endif + +%if ARCH_X86_32 +INIT_MMX mmxext +RESAMPLE_FNS int16, 2, 1 +%endif + +INIT_XMM sse2 +RESAMPLE_FNS int16, 2, 1 +%if HAVE_XOP_EXTERNAL +INIT_XMM xop +RESAMPLE_FNS int16, 2, 1 +%endif + +INIT_XMM sse2 +RESAMPLE_FNS double, 8, 3, d, pdbl_1 + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +RESAMPLE_FNS double, 8, 3, d, pdbl_1 +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +RESAMPLE_FNS double, 8, 3, d, pdbl_1 +%endif diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh index 29834e44f..e66a257ca 100755 --- a/trunk/auto/depends.sh +++ b/trunk/auto/depends.sh @@ -429,48 +429,14 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then ln -sf ../3rdparty/ffmpeg-4.2-fit && cd ffmpeg-4.2-fit && PKG_CONFIG_PATH=$ABS_OBJS/opus/lib/pkgconfig ./configure \ --prefix=`pwd`/_release \ - --pkg-config-flags="--static" \ - --extra-libs=-lpthread \ - --extra-libs=-lm \ - --disable-programs \ - --disable-doc \ - --disable-htmlpages \ - --disable-manpages \ - --disable-podpages \ - --disable-txtpages \ - --disable-avdevice \ - --disable-avformat \ - --disable-swscale \ - --disable-postproc \ - --disable-avfilter \ - --disable-network \ - --disable-dct \ - --disable-dwt \ - --disable-error-resilience \ - --disable-lsp \ - --disable-lzo \ - --disable-faan \ - --disable-pixelutils \ - --disable-hwaccels \ - --disable-devices \ - --disable-audiotoolbox \ - --disable-videotoolbox \ - --disable-appkit \ - --disable-coreimage \ - --disable-avfoundation \ - --disable-securetransport \ - --disable-iconv \ - --disable-lzma \ - --disable-sdl2 \ - --disable-everything \ - --enable-decoder=aac \ - --enable-decoder=aac_fixed \ - --enable-decoder=aac_latm \ - --enable-decoder=libopus \ - --enable-encoder=aac \ - --enable-encoder=opus \ - --enable-encoder=libopus \ - --enable-libopus && + --pkg-config-flags="--static" --extra-libs=-lpthread --extra-libs=-lm \ + --disable-programs --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages \ + --disable-avdevice --disable-avformat --disable-swscale --disable-postproc --disable-avfilter --disable-network \ + --disable-dct --disable-dwt --disable-error-resilience --disable-lsp --disable-lzo --disable-faan --disable-pixelutils \ + --disable-hwaccels --disable-devices --disable-audiotoolbox --disable-videotoolbox --disable-appkit --disable-coreimage \ + --disable-avfoundation --disable-securetransport --disable-iconv --disable-lzma --disable-sdl2 --disable-everything \ + --enable-decoder=aac --enable-decoder=aac_fixed --enable-decoder=aac_latm --enable-decoder=libopus --enable-encoder=aac \ + --enable-encoder=opus --enable-encoder=libopus --enable-libopus && make ${SRS_JOBS} && make install cd .. && rm -rf ffmpeg && ln -sf ffmpeg-4.2-fit/_release ffmpeg ) diff --git a/trunk/configure b/trunk/configure index 4e710d183..f7efe2d58 100755 --- a/trunk/configure +++ b/trunk/configure @@ -151,7 +151,8 @@ if [[ $SRS_SHARED_ST == YES ]]; then LibSTfile="-lst"; fi # srtp LibSrtpRoot="${SRS_OBJS_DIR}/srtp2/include"; LibSrtpFile="${SRS_OBJS_DIR}/srtp2/lib/libsrtp2.a" # ffmpeg -LibFfmpegRoot="${SRS_OBJS_DIR}/ffmpeg/include"; LibFfmpegFile="${SRS_OBJS_DIR}/ffmpeg/lib/libavcodec.a ${SRS_OBJS_DIR}/ffmpeg/lib/libswresample.a ${SRS_OBJS_DIR}/ffmpeg/lib/libavutil.a ${SRS_OBJS_DIR}/ffmpeg/lib/libopus.a -lpthread" +LibFfmpegRoot="${SRS_OBJS_DIR}/ffmpeg/include"; LibFfmpegFile="${SRS_OBJS_DIR}/ffmpeg/lib/libavcodec.a ${SRS_OBJS_DIR}/ffmpeg/lib/libswresample.a ${SRS_OBJS_DIR}/ffmpeg/lib/libavutil.a -lpthread" +LibFfmpegRoot="${LibFfmpegRoot} ${SRS_OBJS_DIR}/opus/include"; LibFfmpegFile="${LibFfmpegFile} ${SRS_OBJS_DIR}/opus/lib/libopus.a" # openssl-1.1.0e, for the RTMP complex handshake. LibSSLRoot="";LibSSLfile="" if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == NO ]]; then @@ -173,7 +174,7 @@ fi # the link options, always use static link SrsLinkOptions="-ldl"; if [[ $SRS_SRT == YES ]]; then - SrsLinkOptions="${SrsLinkOptions} -pthread"; + SrsLinkOptions="${SrsLinkOptions} -lpthread"; fi if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == YES ]]; then SrsLinkOptions="${SrsLinkOptions} -lssl -lcrypto"; From 602a478e1bb55f6b1d9421afb62b7aa4e112fef1 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 22 Mar 2020 18:17:05 +0800 Subject: [PATCH 4/4] For #1659, #307, add switch to disable rtc --- .circleci/config.yml | 2 +- trunk/auto/auto_headers.sh | 6 +++ trunk/auto/depends.sh | 4 +- trunk/auto/options.sh | 12 +++-- trunk/configure | 76 ++++++++++++++++++++++------- trunk/src/app/srs_app_http_api.cpp | 4 ++ trunk/src/app/srs_app_http_api.hpp | 2 + trunk/src/app/srs_app_source.cpp | 28 +++++++++-- trunk/src/app/srs_app_source.hpp | 8 +++ trunk/src/kernel/srs_kernel_flv.cpp | 10 +++- trunk/src/kernel/srs_kernel_flv.hpp | 5 ++ trunk/src/main/srs_main_server.cpp | 4 ++ 12 files changed, 133 insertions(+), 28 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9fa2e06e3..cd14797ec 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ jobs: - image: ossrs/srs:dev steps: - checkout - - run: cd trunk && ./configure && make + - run: cd trunk && ./configure --without-rtc && make && ./configure && make test: docker: - image: ossrs/srs:dev diff --git a/trunk/auto/auto_headers.sh b/trunk/auto/auto_headers.sh index b4c04545c..71e9d4818 100755 --- a/trunk/auto/auto_headers.sh +++ b/trunk/auto/auto_headers.sh @@ -73,6 +73,12 @@ else srs_undefine_macro "SRS_AUTO_SRT" $SRS_AUTO_HEADERS_H fi +if [ $SRS_RTC = YES ]; then + srs_define_macro "SRS_AUTO_RTC" $SRS_AUTO_HEADERS_H +else + srs_undefine_macro "SRS_AUTO_RTC" $SRS_AUTO_HEADERS_H +fi + if [ $SRS_MEM_WATCH = YES ]; then srs_define_macro "SRS_AUTO_MEM_WATCH" $SRS_AUTO_HEADERS_H else diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh index e66a257ca..81e6f1f4b 100755 --- a/trunk/auto/depends.sh +++ b/trunk/auto/depends.sh @@ -399,7 +399,7 @@ fi ##################################################################################### # libopus, for WebRTC to transcode AAC with Opus. ##################################################################################### -if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then +if [[ $SRS_EXPORT_LIBRTMP_PROJECT == NO && $SRS_RTC == YES ]]; then if [[ -f ${SRS_OBJS}/opus/lib/libopus.a ]]; then echo "The opus-1.3.1 is ok."; else @@ -419,7 +419,7 @@ fi ##################################################################################### # ffmpeg-fix, for WebRTC to transcode AAC with Opus. ##################################################################################### -if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then +if [[ $SRS_EXPORT_LIBRTMP_PROJECT == NO && $SRS_RTC == YES ]]; then if [[ -f ${SRS_OBJS}/ffmpeg/lib/libavcodec.a ]]; then echo "The ffmpeg-4.2-fit is ok."; else diff --git a/trunk/auto/options.sh b/trunk/auto/options.sh index ad89f882d..3f142b4a8 100755 --- a/trunk/auto/options.sh +++ b/trunk/auto/options.sh @@ -17,6 +17,7 @@ help=no # feature options SRS_HDS=NO SRS_SRT=NO +SRS_RTC=YES SRS_NGINX=NO SRS_FFMPEG_TOOL=NO SRS_LIBRTMP=NO @@ -130,7 +131,8 @@ Features: --with-librtmp Enable srs-librtmp, library for client. --with-research Build the research tools. --with-utest Build the utest for SRS. - --with-srt Build the srt for SRS. + --with-srt Build the SRT support for SRS. + --with-rtc Build the WebRTC support for SRS. --without-ssl Disable rtmp complex handshake. --without-hds Disable hds, the adobe http dynamic streaming. @@ -139,7 +141,8 @@ Features: --without-librtmp Disable srs-librtmp, library for client. --without-research Do not build the research tools. --without-utest Do not build the utest for SRS. - --without-srt Do not build the srt for SRS. + --without-srt Do not build the SRT support for SRS. + --without-rtc Do not build the WebRTC support for SRS. --prefix= The absolute installation path for srs. Default: $SRS_PREFIX --static Whether add '-static' to link options. @@ -225,6 +228,7 @@ function parse_user_option() { --with-research) SRS_RESEARCH=YES ;; --with-utest) SRS_UTEST=YES ;; --with-srt) SRS_SRT=YES ;; + --with-rtc) SRS_RTC=YES ;; --with-gperf) SRS_GPERF=YES ;; --with-gmc) SRS_GPERF_MC=YES ;; --with-gmd) SRS_GPERF_MD=YES ;; @@ -240,7 +244,8 @@ function parse_user_option() { --without-librtmp) SRS_LIBRTMP=NO ;; --without-research) SRS_RESEARCH=NO ;; --without-utest) SRS_UTEST=NO ;; - --without-srt) SRS_SRT=NO ;; + --without-srt) SRS_SRT=NO ;; + --without-rtc) SRS_RTC=NO ;; --without-gperf) SRS_GPERF=NO ;; --without-gmc) SRS_GPERF_MC=NO ;; --without-gmd) SRS_GPERF_MD=NO ;; @@ -539,6 +544,7 @@ function regenerate_options() { if [ $SRS_RESEARCH = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-research"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-research"; fi if [ $SRS_UTEST = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-utest"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-utest"; fi if [ $SRS_SRT = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-srt"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-srt"; fi + if [ $SRS_RTC = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-rtc"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-rtc"; fi if [ $SRS_GPERF = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gperf"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gperf"; fi if [ $SRS_GPERF_MC = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gmc"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gmc"; fi if [ $SRS_GPERF_MD = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gmd"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gmd"; fi diff --git a/trunk/configure b/trunk/configure index f7efe2d58..30757bdc3 100755 --- a/trunk/configure +++ b/trunk/configure @@ -149,10 +149,14 @@ END LibSTRoot="${SRS_OBJS_DIR}/st"; LibSTfile="${LibSTRoot}/libst.a" if [[ $SRS_SHARED_ST == YES ]]; then LibSTfile="-lst"; fi # srtp -LibSrtpRoot="${SRS_OBJS_DIR}/srtp2/include"; LibSrtpFile="${SRS_OBJS_DIR}/srtp2/lib/libsrtp2.a" -# ffmpeg -LibFfmpegRoot="${SRS_OBJS_DIR}/ffmpeg/include"; LibFfmpegFile="${SRS_OBJS_DIR}/ffmpeg/lib/libavcodec.a ${SRS_OBJS_DIR}/ffmpeg/lib/libswresample.a ${SRS_OBJS_DIR}/ffmpeg/lib/libavutil.a -lpthread" -LibFfmpegRoot="${LibFfmpegRoot} ${SRS_OBJS_DIR}/opus/include"; LibFfmpegFile="${LibFfmpegFile} ${SRS_OBJS_DIR}/opus/lib/libopus.a" +if [[ $SRS_RTC == YES ]]; then + LibSrtpRoot="${SRS_OBJS_DIR}/srtp2/include"; LibSrtpFile="${SRS_OBJS_DIR}/srtp2/lib/libsrtp2.a" +fi +# FFMPEG for WebRTC transcoding, such as aac to opus. +if [[ $SRS_RTC == YES ]]; then + LibFfmpegRoot="${SRS_OBJS_DIR}/ffmpeg/include"; LibFfmpegFile="${SRS_OBJS_DIR}/ffmpeg/lib/libavcodec.a ${SRS_OBJS_DIR}/ffmpeg/lib/libswresample.a ${SRS_OBJS_DIR}/ffmpeg/lib/libavutil.a" + LibFfmpegRoot="${LibFfmpegRoot} ${SRS_OBJS_DIR}/opus/include"; LibFfmpegFile="${LibFfmpegFile} ${SRS_OBJS_DIR}/opus/lib/libopus.a" +fi # openssl-1.1.0e, for the RTMP complex handshake. LibSSLRoot="";LibSSLfile="" if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == NO ]]; then @@ -173,7 +177,7 @@ if [[ $SRS_SRT == YES ]]; then fi # the link options, always use static link SrsLinkOptions="-ldl"; -if [[ $SRS_SRT == YES ]]; then +if [[ $SRS_SRT == YES || $SRS_RTC == YES ]]; then SrsLinkOptions="${SrsLinkOptions} -lpthread"; fi if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == YES ]]; then @@ -206,9 +210,12 @@ MODULE_ID="KERNEL" MODULE_DEPENDS=("CORE") ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot}) MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_buffer" - "srs_kernel_utility" "srs_kernel_flv" "srs_kernel_rtp" "srs_kernel_codec" "srs_kernel_io" + "srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_io" "srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts" "srs_kernel_stream" "srs_kernel_balance" "srs_kernel_mp4" "srs_kernel_file") +if [[ $SRS_RTC == YES ]]; then + MODULE_FILES+=("srs_kernel_rtp") +fi KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh KERNEL_OBJS="${MODULE_OBJS[@]}" # @@ -219,7 +226,10 @@ ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot}) MODULE_FILES=("srs_protocol_amf0" "srs_protocol_io" "srs_rtmp_stack" "srs_rtmp_handshake" "srs_protocol_utility" "srs_rtmp_msg_array" "srs_protocol_stream" "srs_raw_avc" "srs_rtsp_stack" "srs_http_stack" "srs_protocol_kbps" "srs_protocol_json" - "srs_stun_stack" "srs_protocol_format") + "srs_protocol_format") +if [[ $SRS_RTC == YES ]]; then + MODULE_FILES+=("srs_stun_stack") +fi PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh PROTOCOL_OBJS="${MODULE_OBJS[@]}" # @@ -238,7 +248,10 @@ fi if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then MODULE_ID="SERVICE" MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL") - ModuleLibIncs=(${LibSTRoot} ${LibSrtpRoot} ${LibFfmpegRoot} ${SRS_OBJS_DIR} ${LibSSLRoot}) + ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibSSLRoot}) + if [[ $SRS_RTC == YES ]]; then + ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot}) + fi MODULE_FILES=("srs_service_log" "srs_service_st" "srs_service_http_client" "srs_service_http_conn" "srs_service_rtmp_conn" "srs_service_utility" "srs_service_conn") @@ -251,7 +264,10 @@ fi if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then MODULE_ID="APP" MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE") - ModuleLibIncs=(${LibSTRoot} ${LibSrtpRoot} ${LibFfmpegRoot} ${SRS_OBJS_DIR} ${LibSSLRoot}) + ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibSSLRoot}) + if [[ $SRS_RTC == YES ]]; then + ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot}) + fi MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_source" "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream" "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" @@ -259,10 +275,13 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_edge" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static" "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds" - "srs_app_mpegts_udp" "srs_app_rtc" "srs_app_rtc_conn" "srs_app_dtls" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" + "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" "srs_app_caster_flv" "srs_app_process" "srs_app_ng_exec" "srs_app_hourglass" "srs_app_dash" "srs_app_fragment" "srs_app_dvr" - "srs_app_coworkers" "srs_app_hybrid" "srs_app_audio_recode") + "srs_app_coworkers" "srs_app_hybrid") + if [[ $SRS_RTC == YES ]]; then + MODULE_FILES+=("srs_app_rtc" "srs_app_rtc_conn" "srs_app_dtls" "srs_app_audio_recode") + fi DEFINES="" # add each modules for app for SRS_MODULE in ${SRS_MODULES[*]}; do @@ -289,7 +308,10 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then if [[ $SRS_SRT == YES ]]; then MODULE_DEPENDS+=("SRT") fi - ModuleLibIncs=(${LibSTRoot} ${LibSrtpRoot} ${LibFfmpegRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot}) + ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot}) + if [[ $SRS_RTC == YES ]]; then + ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot}) + fi if [[ $SRS_SRT == YES ]]; then ModuleLibIncs+=("${LibSRTRoot[*]}") fi @@ -302,7 +324,10 @@ fi if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then MODULE_ID="MAIN" MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE") - ModuleLibIncs=(${LibSTRoot} ${LibSrtpRoot} ${LibFfmpegRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot}) + ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot}) + if [[ $SRS_RTC == YES ]]; then + ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot}) + fi MODULE_FILES=() DEFINES="" # add each modules for main @@ -329,13 +354,19 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then done # # all depends libraries - ModuleLibFiles=(${LibSTfile} ${LibSrtpFile} ${LibFfmpegFile} ${LibSSLfile} ${LibGperfFile}) + ModuleLibFiles=(${LibSTfile} ${LibSSLfile} ${LibGperfFile}) + if [[ $SRS_RTC == YES ]]; then + ModuleLibFiles+=("${LibFfmpegFile[*]}" ${LibSrtpFile}) + fi if [[ $SRS_SRT == YES ]]; then ModuleLibFiles+=("${LibSRTfile[*]}") fi # all depends objects MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${SERVICE_OBJS[@]} ${APP_OBJS[@]} ${SERVER_OBJS[@]}" - ModuleLibIncs=(${LibSTRoot} ${LibSrtpRoot} ${LibFfmpegRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot}) + ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot}) + if [[ $SRS_RTC == YES ]]; then + ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot}) + fi if [[ $SRS_SRT == YES ]]; then MODULE_OBJS="${MODULE_OBJS} ${SRT_OBJS[@]}" fi @@ -346,7 +377,10 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then # # For modules, without the app module. MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${SERVICE_OBJS[@]} ${MAIN_OBJS[@]}" - ModuleLibFiles=(${LibSTfile} ${LibSrtpFile} ${LibFfmpegFile} ${LibSSLfile} ${LibGperfFile}) + ModuleLibFiles=(${LibSTfile} ${LibSSLfile} ${LibGperfFile}) + if [[ $SRS_RTC == YES ]]; then + ModuleLibFiles+=("${LibFfmpegFile[*]}" ${LibSrtpFile}) + fi # for SRS_MODULE in ${SRS_MODULES[*]}; do . $SRS_MODULE/config @@ -366,11 +400,17 @@ if [ $SRS_UTEST = YES ]; then MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_protocol" "srs_utest_kernel" "srs_utest_core" "srs_utest_config" "srs_utest_rtmp" "srs_utest_http" "srs_utest_avc" "srs_utest_reload" "srs_utest_mp4" "srs_utest_service" "srs_utest_app") - ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSrtpRoot} ${LibFfmpegRoot} ${LibSSLRoot}) + ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot}) + if [[ $SRS_RTC == YES ]]; then + ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot}) + fi if [[ $SRS_SRT == YES ]]; then ModuleLibIncs+=("${LibSRTRoot[*]}") fi - ModuleLibFiles=(${LibSTfile} ${LibSrtpFile} ${LibFfmpegFile} ${LibSSLfile}) + ModuleLibFiles=(${LibSTfile} ${LibSSLfile}) + if [[ $SRS_RTC == YES ]]; then + ModuleLibFiles+=("${LibFfmpegFile[*]}" ${LibSrtpFile}) + fi if [[ $SRS_SRT == YES ]]; then ModuleLibFiles+=("${LibSRTfile[*]}") fi diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 2ea98230a..ab755df2f 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -46,7 +46,9 @@ using namespace std; #include #include #include +#ifdef SRS_AUTO_RTC #include +#endif srs_error_t srs_api_response_jsonp(ISrsHttpResponseWriter* w, string callback, string data) { @@ -781,6 +783,7 @@ srs_error_t SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa return srs_api_response(w, r, obj->dumps()); } +#ifdef SRS_AUTO_RTC SrsGoApiSdp::SrsGoApiSdp(SrsRtcServer* rtc_svr) { rtc_server = rtc_svr; @@ -907,6 +910,7 @@ srs_error_t SrsGoApiSdp::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessag return err; } +#endif SrsGoApiClients::SrsGoApiClients() { diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index 7b55eaf52..4caee1de8 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -166,6 +166,7 @@ public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); }; +#ifdef SRS_AUTO_RTC class SrsGoApiSdp : public ISrsHttpHandler { private: @@ -178,6 +179,7 @@ public: private: virtual srs_error_t do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, SrsJsonObject* res); }; +#endif class SrsGoApiClients : public ISrsHttpHandler { diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 3ba15a621..94d24e250 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -33,7 +33,6 @@ using namespace std; #include #include #include -#include #include #include #include @@ -51,6 +50,9 @@ using namespace std; #include #include #include +#ifdef SRS_AUTO_RTC +#include +#endif #define CONST_MAX_JITTER_MS 250 #define CONST_MAX_JITTER_MS_NEG -250 @@ -816,6 +818,7 @@ SrsSharedPtrMessage* SrsMixQueue::pop() return msg; } +#ifdef SRS_AUTO_RTC SrsRtpPacketQueue::SrsRtpPacketQueue() { } @@ -864,6 +867,7 @@ SrsRtpSharedPacket* SrsRtpPacketQueue::find(const uint16_t& sequence) return pkt; } +#endif SrsOriginHub::SrsOriginHub() { @@ -875,7 +879,9 @@ SrsOriginHub::SrsOriginHub() dash = new SrsDash(); dvr = new SrsDvr(); encoder = new SrsEncoder(); +#ifdef SRS_AUTO_RTC rtc = new SrsRtc(); +#endif #ifdef SRS_AUTO_HDS hds = new SrsHds(); #endif @@ -919,10 +925,12 @@ srs_error_t SrsOriginHub::initialize(SrsSource* s, SrsRequest* r) if ((err = format->initialize()) != srs_success) { return srs_error_wrap(err, "format initialize"); } - + +#ifdef SRS_AUTO_RTC if ((err = rtc->initialize(this, req)) != srs_success) { return srs_error_wrap(err, "rtc initialize"); } +#endif if ((err = hls->initialize(this, req)) != srs_success) { return srs_error_wrap(err, "hls initialize"); @@ -1022,11 +1030,13 @@ srs_error_t SrsOriginHub::on_audio(SrsSharedPtrMessage* shared_audio) srs_flv_srates[c->sound_rate]); } +#ifdef SRS_AUTO_RTC if ((err = rtc->on_audio(msg, format)) != srs_success) { srs_warn("rtc: ignore audio error %s", srs_error_desc(err).c_str()); srs_error_reset(err); rtc->on_unpublish(); } +#endif if ((err = hls->on_audio(msg, format)) != srs_success) { // apply the error strategy for hls. @@ -1121,6 +1131,7 @@ srs_error_t SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_se return err; } +#ifdef SRS_AUTO_RTC // Parse RTMP message to RTP packets, in FU-A if too large. if ((err = rtc->on_video(msg, format)) != srs_success) { // TODO: We should support more strategies. @@ -1132,6 +1143,7 @@ srs_error_t SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_se // TODO: FIXME: Refactor to move to rtp? // Save the RTP packets for find_rtp_packet() to rtx or restore it. source->rtp_queue->push(msg->rtp_packets); +#endif if ((err = hls->on_video(msg, format)) != srs_success) { // TODO: We should support more strategies. @@ -1200,10 +1212,12 @@ srs_error_t SrsOriginHub::on_publish() if ((err = encoder->on_publish(req)) != srs_success) { return srs_error_wrap(err, "encoder publish"); } - + +#ifdef SRS_AUTO_RTC if ((err = rtc->on_publish()) != srs_success) { return srs_error_wrap(err, "rtc publish"); } +#endif if ((err = hls->on_publish()) != srs_success) { return srs_error_wrap(err, "hls publish"); @@ -1242,7 +1256,9 @@ void SrsOriginHub::on_unpublish() destroy_forwarders(); encoder->on_unpublish(); +#ifdef SRS_AUTO_RTC rtc->on_unpublish(); +#endif hls->on_unpublish(); dash->on_unpublish(); dvr->on_unpublish(); @@ -1904,7 +1920,9 @@ SrsSource::SrsSource() jitter_algorithm = SrsRtmpJitterAlgorithmOFF; mix_correct = false; mix_queue = new SrsMixQueue(); +#ifdef SRS_AUTO_RTC rtp_queue = new SrsRtpPacketQueue(); +#endif _can_publish = true; _pre_source_id = _source_id = -1; @@ -1934,7 +1952,9 @@ SrsSource::~SrsSource() srs_freep(hub); srs_freep(meta); srs_freep(mix_queue); +#ifdef SRS_AUTO_RTC srs_freep(rtp_queue); +#endif srs_freep(play_edge); srs_freep(publish_edge); @@ -2692,7 +2712,9 @@ string SrsSource::get_curr_origin() return play_edge->get_curr_origin(); } +#ifdef SRS_AUTO_RTC SrsRtpSharedPacket* SrsSource::find_rtp_packet(const uint16_t& seq) { return rtp_queue->find(seq); } +#endif diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index 01005d96b..ac04f5a05 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -325,6 +325,7 @@ public: virtual SrsSharedPtrMessage* pop(); }; +#ifdef SRS_AUTO_RTC // To find the RTP packet for RTX or restore. class SrsRtpPacketQueue { @@ -347,6 +348,7 @@ public: void insert(const uint16_t& sequence, SrsRtpSharedPacket* pkt); SrsRtpSharedPacket* find(const uint16_t& sequence); }; +#endif // The hub for origin is a collection of utilities for origin only, // For example, DVR, HLS, Forward and Transcode are only available for origin, @@ -360,8 +362,10 @@ private: private: // The format, codec information. SrsRtmpFormat* format; +#ifdef SRS_AUTO_RTC // rtc handler SrsRtc* rtc; +#endif // hls handler. SrsHls* hls; // The DASH encoder. @@ -534,8 +538,10 @@ private: bool mix_correct; // The mix queue to implements the mix correct algorithm. SrsMixQueue* mix_queue; +#ifdef SRS_AUTO_RTC // rtp packet queue SrsRtpPacketQueue* rtp_queue; +#endif // For play, whether enabled atc. // The atc(use absolute time and donot adjust time), // directly use msg time and donot adjust if atc is true, @@ -625,8 +631,10 @@ public: public: virtual std::string get_curr_origin(); public: +#ifdef SRS_AUTO_RTC // Find rtp packet by sequence SrsRtpSharedPacket* find_rtp_packet(const uint16_t& seq); +#endif }; #endif diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp index be4e808e2..f24dc2047 100644 --- a/trunk/src/kernel/srs_kernel_flv.cpp +++ b/trunk/src/kernel/srs_kernel_flv.cpp @@ -36,11 +36,13 @@ using namespace std; #include #include #include -#include #include #include #include #include +#ifdef SRS_AUTO_RTC +#include +#endif SrsMessageHeader::SrsMessageHeader() { @@ -230,9 +232,11 @@ SrsSharedPtrMessage::~SrsSharedPtrMessage() } } +#ifdef SRS_AUTO_RTC for (int i = 0; i < (int)rtp_packets.size(); ++i) { srs_freep(rtp_packets[i]); } +#endif } srs_error_t SrsSharedPtrMessage::create(SrsCommonMessage* msg) @@ -351,17 +355,21 @@ SrsSharedPtrMessage* SrsSharedPtrMessage::copy() copy->payload = ptr->payload; copy->size = ptr->size; +#ifdef SRS_AUTO_RTC for (int i = 0; i < (int)rtp_packets.size(); ++i) { copy->rtp_packets.push_back(rtp_packets[i]->copy()); } +#endif return copy; } +#ifdef SRS_AUTO_RTC void SrsSharedPtrMessage::set_rtp_packets(const std::vector& pkts) { rtp_packets = pkts; } +#endif SrsFlvTransmuxer::SrsFlvTransmuxer() { diff --git a/trunk/src/kernel/srs_kernel_flv.hpp b/trunk/src/kernel/srs_kernel_flv.hpp index ec4545d96..23fa0baf0 100644 --- a/trunk/src/kernel/srs_kernel_flv.hpp +++ b/trunk/src/kernel/srs_kernel_flv.hpp @@ -288,7 +288,10 @@ public: // video/audio packet use raw bytes, no video/audio packet. char* payload; +#ifdef SRS_AUTO_RTC std::vector rtp_packets; +#endif + private: class SrsSharedPtrPayload { @@ -344,7 +347,9 @@ public: // @remark, assert object is created. virtual SrsSharedPtrMessage* copy(); public: +#ifdef SRS_AUTO_RTC virtual void set_rtp_packets(const std::vector& pkts); +#endif }; // Transmux RTMP packets to FLV stream. diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index 1bec4c0ad..d8415e76f 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -50,7 +50,9 @@ using namespace std; #include #include #include +#ifdef SRS_AUTO_RTC #include +#endif #ifdef SRS_AUTO_SRT #include @@ -449,7 +451,9 @@ srs_error_t run_hybrid_server() _srs_hybrid->register_server(new SrtServerAdapter()); #endif +#ifdef SRS_AUTO_RTC _srs_hybrid->register_server(new RtcServerAdapter()); +#endif // Do some system initialize. if ((err = _srs_hybrid->initialize()) != srs_success) {

    w-3|QaTl-(@bee_o&5nfia5I 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